NEST main@caf0ae8
 
Loading...
Searching...
No Matches
rate_neuron_opn_impl.h
Go to the documentation of this file.
1/*
2 * rate_neuron_opn_impl.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef RATE_NEURON_OPN_IMPL_H
24#define RATE_NEURON_OPN_IMPL_H
25
26#include "rate_neuron_opn.h"
27
28// C++ includes:
29#include <cmath> // in case we need isnan() // fabs
30#include <cstdio>
31#include <iomanip>
32#include <iostream>
33#include <limits>
34#include <string>
35
36// Includes from libnestutil:
37#include "numerics.h"
38
39// Includes from nestkernel:
40#include "exceptions.h"
41#include "kernel_manager.h"
43
44
45namespace nest
46{
47
48/* ----------------------------------------------------------------
49 * Recordables map
50 * ---------------------------------------------------------------- */
51
52template < class TNonlinearities >
53RecordablesMap< rate_neuron_opn< TNonlinearities > > rate_neuron_opn< TNonlinearities >::recordablesMap_;
54
55
56/* ----------------------------------------------------------------
57 * Default constructors defining default parameters and state
58 * ---------------------------------------------------------------- */
59
60template < class TNonlinearities >
62 : tau_( 10.0 ) // ms
63 , sigma_( 1.0 )
64 , mu_( 0.0 )
65 , linear_summation_( true )
66 , mult_coupling_( false )
67{
68 recordablesMap_.create();
69}
70
71template < class TNonlinearities >
73 : rate_( 0.0 )
74 , noise_( 0.0 )
75 , noisy_rate_( 0.0 )
76{
77}
78
79/* ----------------------------------------------------------------
80 * Parameter and state extractions and manipulation functions
81 * ---------------------------------------------------------------- */
82
83template < class TNonlinearities >
84void
86{
87 d[ names::tau ] = tau_;
88 d[ names::sigma ] = sigma_;
89 d[ names::mu ] = mu_;
90 d[ names::linear_summation ] = linear_summation_;
91 d[ names::mult_coupling ] = mult_coupling_;
92
93 // Also allow old names (to not break old scripts)
94 d[ names::std ] = sigma_;
95 d[ names::mean ] = mu_;
96}
97
98template < class TNonlinearities >
99void
101{
102 update_value_param( d, names::tau, tau_, node );
103 update_value_param( d, names::mu, mu_, node );
104 update_value_param( d, names::sigma, sigma_, node );
105 update_value_param( d, names::linear_summation, linear_summation_, node );
106 update_value_param( d, names::mult_coupling, mult_coupling_, node );
107
108 // Check for old names
109 if ( update_value_param( d, names::mean, mu_, node ) )
110 {
112 "rate_neuron_opn< TNonlinearities >::Parameters_::set",
113 "The parameter mean has been renamed to mu. Please use the new "
114 "name from now on." );
115 }
116
117 if ( update_value_param( d, names::std, sigma_, node ) )
118 {
120 "rate_neuron_opn< TNonlinearities >::Parameters_::set",
121 "The parameter std has been renamed to sigma. Please use the new "
122 "name from now on." );
123 }
124
125 // Check for invalid parameters
126 if ( tau_ <= 0 )
127 {
128 throw BadProperty( "Time constant must be > 0." );
129 }
130 if ( sigma_ < 0 )
131 {
132 throw BadProperty( "Noise parameter must not be negative." );
133 }
134}
135
136template < class TNonlinearities >
137void
139{
140 d[ names::rate ] = rate_; // Rate
141 d[ names::noise ] = noise_; // Noise
142 d[ names::noisy_rate ] = noisy_rate_; // Noisy rate
143}
144
145template < class TNonlinearities >
146void
148{
149 update_value_param( d, names::rate, rate_, node ); // Rate
150}
151
152template < class TNonlinearities >
157
158template < class TNonlinearities >
163
164/* ----------------------------------------------------------------
165 * Default and copy constructor for node
166 * ---------------------------------------------------------------- */
167
168template < class TNonlinearities >
170 : ArchivingNode()
171 , P_()
172 , S_()
173 , B_( *this )
174{
175 recordablesMap_.create();
176 Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() );
177}
178
179template < class TNonlinearities >
181 : ArchivingNode( n )
182 , P_( n.P_ )
183 , S_( n.S_ )
184 , B_( n.B_, *this )
185{
186 Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() );
187}
188
189/* ----------------------------------------------------------------
190 * Node initialization functions
191 * ---------------------------------------------------------------- */
192
193template < class TNonlinearities >
194void
196{
197 B_.delayed_rates_ex_.clear(); // includes resize
198 B_.delayed_rates_in_.clear(); // includes resize
199
200 // resize buffers
201 const size_t buffer_size = kernel().connection_manager.get_min_delay();
202 B_.instant_rates_ex_.resize( buffer_size, 0.0 );
203 B_.instant_rates_in_.resize( buffer_size, 0.0 );
204 B_.last_y_values.resize( buffer_size, 0.0 );
205 B_.random_numbers.resize( buffer_size, numerics::nan );
206
207 // initialize random numbers
208 for ( unsigned int i = 0; i < buffer_size; i++ )
209 {
210 B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) );
211 }
212
213 B_.logger_.reset(); // includes resize
215}
216
217template < class TNonlinearities >
218void
220{
221 B_.logger_.init(); // ensures initialization in case mm connected after Simulate
222
223 const double h = Time::get_resolution().get_ms();
224
225 // propagators
226 V_.P1_ = std::exp( -h / P_.tau_ );
227 V_.P2_ = -numerics::expm1( -h / P_.tau_ );
228
229 // Gaussian white noise approximated by piecewise constant value
230 V_.output_noise_factor_ = std::sqrt( P_.tau_ / h );
231}
232
233/* ----------------------------------------------------------------
234 * Update and event handling functions
235 */
236
237template < class TNonlinearities >
238bool
240 const long from,
241 const long to,
242 const bool called_from_wfr_update )
243{
244 const size_t buffer_size = kernel().connection_manager.get_min_delay();
245 const double wfr_tol = kernel().simulation_manager.get_wfr_tol();
246 bool wfr_tol_exceeded = false;
247
248 // allocate memory to store rates to be sent by rate events
249 std::vector< double > new_rates( buffer_size, 0.0 );
250
251 for ( long lag = from; lag < to; ++lag )
252 {
253 // get noise
254 S_.noise_ = P_.sigma_ * B_.random_numbers[ lag ];
255 // the noise is added to the noisy_rate variable
256 S_.noisy_rate_ = S_.rate_ + V_.output_noise_factor_ * S_.noise_;
257 // store rate
258 new_rates[ lag ] = S_.noisy_rate_;
259 // propagate rate to new time step (exponential integration)
260 S_.rate_ = V_.P1_ * S_.rate_ + V_.P2_ * P_.mu_;
261
262 double delayed_rates_in = 0;
263 double delayed_rates_ex = 0;
264 if ( called_from_wfr_update )
265 {
266 // use get_value_wfr_update to keep values in buffer
267 delayed_rates_in = B_.delayed_rates_in_.get_value_wfr_update( lag );
268 delayed_rates_ex = B_.delayed_rates_ex_.get_value_wfr_update( lag );
269 }
270 else
271 {
272 // use get_value to clear values in buffer after reading
273 delayed_rates_in = B_.delayed_rates_in_.get_value( lag );
274 delayed_rates_ex = B_.delayed_rates_ex_.get_value( lag );
275 }
276 double instant_rates_in = B_.instant_rates_in_[ lag ];
277 double instant_rates_ex = B_.instant_rates_ex_[ lag ];
278 double H_ex = 1.; // valid value for non-multiplicative coupling
279 double H_in = 1.; // valid value for non-multiplicative coupling
280 if ( P_.mult_coupling_ )
281 {
282 H_ex = nonlinearities_.mult_coupling_ex( new_rates[ lag ] );
283 H_in = nonlinearities_.mult_coupling_in( new_rates[ lag ] );
284 }
285
286 if ( P_.linear_summation_ )
287 {
288 // In this case we explicitly need to distinguish the cases of
289 // multiplicative coupling and non-multiplicative coupling in
290 // order to compute input( ex + in ) instead of input(ex) + input(in) in
291 // the non-multiplicative case.
292 if ( P_.mult_coupling_ )
293 {
294 S_.rate_ += V_.P2_ * H_ex * nonlinearities_.input( delayed_rates_ex + instant_rates_ex );
295 S_.rate_ += V_.P2_ * H_in * nonlinearities_.input( delayed_rates_in + instant_rates_in );
296 }
297 else
298 {
299 S_.rate_ +=
300 V_.P2_ * nonlinearities_.input( delayed_rates_ex + instant_rates_ex + delayed_rates_in + instant_rates_in );
301 }
302 }
303 else
304 {
305 // In this case multiplicative and non-multiplicative coupling
306 // can be handled with the same code.
307 S_.rate_ += V_.P2_ * H_ex * ( delayed_rates_ex + instant_rates_ex );
308 S_.rate_ += V_.P2_ * H_in * ( delayed_rates_in + instant_rates_in );
309 }
310
311 if ( called_from_wfr_update )
312 {
313 // check if deviation from last iteration exceeds wfr_tol
314 wfr_tol_exceeded = wfr_tol_exceeded or fabs( S_.rate_ - B_.last_y_values[ lag ] ) > wfr_tol;
315 // update last_y_values for next wfr iteration
316 B_.last_y_values[ lag ] = S_.rate_;
317 }
318 else
319 {
320 // rate logging
321 B_.logger_.record_data( origin.get_steps() + lag );
322 }
323 }
324
325 if ( not called_from_wfr_update )
326 {
327 // Send delay-rate-neuron-event. This only happens in the final iteration
328 // to avoid accumulation in the buffers of the receiving neurons.
330 drve.set_coeffarray( new_rates );
332
333 // clear last_y_values
334 std::vector< double >( buffer_size, 0.0 ).swap( B_.last_y_values );
335
336 // modify new_rates for rate-neuron-event as proxy for next min_delay
337 for ( long temp = from; temp < to; ++temp )
338 {
339 new_rates[ temp ] = S_.noisy_rate_;
340 }
341
342 // create new random numbers
343 B_.random_numbers.resize( buffer_size, numerics::nan );
344 for ( unsigned int i = 0; i < buffer_size; i++ )
345 {
346 B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) );
347 }
348 }
349
350 // Send rate-neuron-event
352 rve.set_coeffarray( new_rates );
354
355 // Reset variables
356 std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_ex_ );
357 std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_in_ );
358
359 return wfr_tol_exceeded;
360}
361
362
363template < class TNonlinearities >
364void
366{
367 const double weight = e.get_weight();
368
369 size_t i = 0;
370 std::vector< unsigned int >::iterator it = e.begin();
371 // The call to get_coeffvalue( it ) in this loop also advances the iterator it
372 while ( it != e.end() )
373 {
374 if ( P_.linear_summation_ )
375 {
376 if ( weight >= 0.0 )
377 {
378 B_.instant_rates_ex_[ i ] += weight * e.get_coeffvalue( it );
379 }
380 else
381 {
382 B_.instant_rates_in_[ i ] += weight * e.get_coeffvalue( it );
383 }
384 }
385 else
386 {
387 if ( weight >= 0.0 )
388 {
389 B_.instant_rates_ex_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) );
390 }
391 else
392 {
393 B_.instant_rates_in_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) );
394 }
395 }
396 i++;
397 }
398}
399
400template < class TNonlinearities >
401void
403{
404 const double weight = e.get_weight();
405 const long delay = e.get_delay_steps() - kernel().connection_manager.get_min_delay();
406
407 size_t i = 0;
408 std::vector< unsigned int >::iterator it = e.begin();
409 // The call to get_coeffvalue( it ) in this loop also advances the iterator it
410 while ( it != e.end() )
411 {
412 if ( P_.linear_summation_ )
413 {
414 if ( weight >= 0.0 )
415 {
416 B_.delayed_rates_ex_.add_value( delay + i, weight * e.get_coeffvalue( it ) );
417 }
418 else
419 {
420 B_.delayed_rates_in_.add_value( delay + i, weight * e.get_coeffvalue( it ) );
421 }
422 }
423 else
424 {
425 if ( weight >= 0.0 )
426 {
427 B_.delayed_rates_ex_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) );
428 }
429 else
430 {
431 B_.delayed_rates_in_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) );
432 }
433 }
434 ++i;
435 }
436}
437
438template < class TNonlinearities >
439void
441{
442 B_.logger_.handle( e );
443}
444
445} // namespace
446
447#endif /* #ifndef RATE_NEURON_OPN_IMPL_H */
Dictionary class for interface to Python and C++ API.
Definition dictionary.h:213
A node which archives spike history for the purposes of spike-timing dependent plasticity (STDP)
Definition archiving_node.h:49
void clear_history()
Clear spike history.
Definition archiving_node.cpp:269
Exception to be thrown if a status parameter is incomplete or inconsistent.
Definition exceptions.h:680
long get_min_delay() const
Return minimal connection delay, which is precomputed by update_delay_extrema_().
Definition connection_manager.h:728
Request data to be logged/logged data to be sent.
Definition event.h:636
void set_coeffarray(std::vector< DataType > &ca)
Definition secondary_event.h:224
Event for rate model connections with delay.
Definition secondary_event.h:331
void send_secondary(Node &source, SecondaryEvent &e)
Send a secondary event remote.
Definition event_delivery_manager_impl.h:138
Event for rate model connections without delay.
Definition secondary_event.h:315
Base class for all NEST network objects.
Definition node.h:99
void set_node_uses_wfr(const bool)
Sets node_uses_wfr_ member variable (to be able to set it to "true" for any class derived from Node)
Definition node.h:1158
double get_wfr_tol() const
Get the convergence tolerance of the waveform relaxation method.
Definition simulation_manager.h:331
Definition nest_time.h:135
static Time get_resolution()
Definition nest_time.h:325
double get_ms() const
Definition nest_time.h:490
Definition rate_neuron_opn.h:113
State_ S_
Definition rate_neuron_opn.h:289
Parameters_ P_
Definition rate_neuron_opn.h:288
Buffers_ B_
Definition rate_neuron_opn.h:291
rate_neuron_opn()
Definition rate_neuron_opn_impl.h:169
void handle(InstantaneousRateConnectionEvent &) override
Handler for rate neuron events.
Definition rate_neuron_opn_impl.h:365
bool update_(Time const &, const long, const long, const bool)
This is the actual update function.
Definition rate_neuron_opn_impl.h:239
void pre_run_hook() override
Re-calculate dependent parameters of the node.
Definition rate_neuron_opn_impl.h:219
static RecordablesMap< rate_neuron_opn< TNonlinearities > > recordablesMap_
Mapping of recordables names to access functions.
Definition rate_neuron_opn.h:294
void init_buffers_() override
Configure persistent internal data structures.
Definition rate_neuron_opn_impl.h:195
ConnectionManager connection_manager
Definition kernel_manager.h:239
EventDeliveryManager event_delivery_manager
Definition kernel_manager.h:241
SimulationManager simulation_manager
Definition kernel_manager.h:237
#define LOG(s, fctn, msg)
Definition logging.h:29
const std::string std("std")
const std::string tau("tau")
const std::string mult_coupling("mult_coupling")
const std::string noisy_rate("noisy_rate")
const std::string linear_summation("linear_summation")
const std::string rate("rate")
const std::string mean("mean")
const std::string noise("noise")
const std::string sigma("sigma")
const std::string mu("mu")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
RngPtr get_vp_specific_rng(size_t tid)
Definition kernel_manager.h:298
KernelManager & kernel()
Definition kernel_manager.h:311
bool update_value_param(Dictionary const &d, const std::string &key, T &value, nest::Node *node)
Obtain value from parameter dictionary including evaluation of random or spatial parameters.
Definition dict_util.h:42
const double nan
Definition numerics.cpp:36
double expm1(double x)
Definition numerics.h:44
Buffers of the model.
Definition rate_neuron_opn.h:229
Buffers_(rate_neuron_opn &)
Definition rate_neuron_opn_impl.h:153
void get(Dictionary &) const
Store current values in dictionary.
Definition rate_neuron_opn_impl.h:85
Parameters_()
Sets default parameter values.
Definition rate_neuron_opn_impl.h:61
void set(const Dictionary &, Node *node)
Definition rate_neuron_opn_impl.h:100
void get(Dictionary &) const
Definition rate_neuron_opn_impl.h:138
State_()
Default initialization.
Definition rate_neuron_opn_impl.h:72
void set(const Dictionary &, Node *node)
Set values from dictionary.
Definition rate_neuron_opn_impl.h:147