NEST main@caf0ae8
 
Loading...
Searching...
No Matches
iaf_bw_2001_exact.h
Go to the documentation of this file.
1/*
2 * iaf_bw_2001_exact.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 IAF_BW_2001_EXACT
24#define IAF_BW_2001_EXACT
25
26// Generated includes:
27#include "config.h"
28
29#ifdef HAVE_GSL
30
31// C includes:
32#include <gsl/gsl_errno.h>
33#include <gsl/gsl_matrix.h>
34#include <gsl/gsl_odeiv.h>
35
36// Includes from nestkernel:
37#include "archiving_node.h"
38#include "connection.h"
39#include "event.h"
40#include "nest_types.h"
41#include "ring_buffer.h"
43
44namespace nest
45{
56extern "C" inline int iaf_bw_2001_exact_dynamics( double, const double y[], double f[], void* pnode );
57
58// clang-format off
59/* BeginUserDocs: neuron, integrate-and-fire, conductance-based, hard threshold
60
61Short description
62+++++++++++++++++
63
64Leaky integrate-and-fire-neuron model with conductance-based synapses and additional NMDA receptors.
65
66Description
67+++++++++++
68
69``iaf_bw_2001_exact`` is a leaky integrate-and-fire neuron model with
70
71* an exact implementation of the neuron model described in :footcite:p:`Wang1999`.
72* exponential conductance-based AMPA and GABA-synapses
73* NMDA synapses with slow nonlinear dynamics
74* a fixed refractory period
75* no adaptation mechanisms
76
77Neuron and synaptic dynamics
78..................................................
79
80The membrane potential and synaptic variables evolve according to
81
82.. math::
83
84 C_\mathrm{m} \frac{dV(t)}{dt} &= -g_\mathrm{L} (V(t) - V_\mathrm{L}) - I_\mathrm{syn} (t) \\[3ex]
85 I_\mathrm{syn}(t) &= I_\mathrm{AMPA}(t) + I_\mathrm{NMDA}(t) + I_\mathrm{GABA}(t) (t) \\[3ex]
86 I_\mathrm{AMPA} &= (V(t) - V_E)\sum_{j \in \Gamma_\mathrm{ex}}^{N_E}w_jS_{j,\mathrm{AMPA}}(t) \\[3ex]
87 I_\mathrm{NMDA} &= \frac{(V(t) - V_E)}{1+[\mathrm{Mg^{2+}}]\mathrm{exp}(-0.062V(t))/3.57}\sum_{j \in
88 \Gamma_\mathrm{ex}}^{N_E}w_jS_{j,\mathrm{NMDA}}(t) \\[3ex]
89 I_\mathrm{GABA} &= (V(t) - V_I)\sum_{j \in \Gamma_\mathrm{in}}^{N_E}w_jS_{j,\mathrm{GABA}}(t) \\[5ex]
90 \frac{dS_{j,\mathrm{AMPA}}}{dt} &=-\frac{j,S_{\mathrm{AMPA}}}{\tau_\mathrm{AMPA}}+\sum_{k \in \Delta_j} \delta (t - t_j^k) \\[3ex]
91 \frac{dS_{j,\mathrm{GABA}}}{dt} &= -\frac{S_{j,\mathrm{GABA}}}{\tau_\mathrm{GABA}} + \sum_{k \in \Delta_j} \delta (t - t_j^k) \\[3ex]
92 \frac{dS_{j,\mathrm{NMDA}}}{dt} &= -\frac{S_{j,\mathrm{NMDA}}}{\tau_\mathrm{NMDA,decay}}+ \alpha x_j (1 - S_{j,\mathrm{NMDA}})\\[3ex]
93 \frac{dx_j}{dt} &= -\frac{x_j}{\tau_\mathrm{NMDA,rise}} + \sum_{k \in \Delta_j} \delta (t - t_j^k)
94
95where :math:`\Gamma_\mathrm{ex}` and :math:`\Gamma_\mathrm{in}` are index sets for presynaptic excitatory and inhibitory
96neurons respectively, and :math:`\Delta_j` is an index set for the spike times of neuron :math:`j`.
97
98Since :math:`S_{j,\mathrm{AMPA}}` and :math:`S_{j,\mathrm{GABA}}` are piecewise exponential functions, the sums are also
99a piecewise exponential function, and can be stored in a single synaptic variable each, :math:`S_{\mathrm{AMPA}}` and
100:math:`S_{\mathrm{GABA}}` respectively. The sum over :math:`S_{j,\mathrm{NMDA}}` does not have a simple expression, and
101cannot be simplified. Therefore, for each synapse, we need to integrate separate state variables, which makes the model
102slow.
103
104The specification of this model differs slightly from the one in :footcite:p:`Wang1999`. The parameters :math:`g_\mathrm{AMPA}`,
105:math:`g_\mathrm{GABA}`, and :math:`g_\mathrm{NMDA}` have been absorbed into the respective synaptic weights.
106Additionally, the synapses from the external population is not separated from the recurrent AMPA-synapses.
107This model is slow to simulate when there are many neurons with NMDA-synapses, since each post-synaptic neuron simulates each pre-synaptic connection explicitly. The model :doc:`iaf_bw_2001 </models/iaf_bw_2001>` is an approximation to this model which is significantly faster.
108
109See also :footcite:p:`Brunel2001`, :footcite:p:`Wang2002`
110
111Parameters
112++++++++++
113
114The following parameters can be set in the status Dictionary.
115
116=================== ================== ================================= ========================================================================
117**Parameter** **Default** **Math equivalent** **Description**
118=================== ================== ================================= ========================================================================
119``E_L`` -70.0 mV :math:`E_\mathrm{L}` Leak reversal potential
120``E_ex`` 0.0 mV :math:`E_\mathrm{ex}` Excitatory reversal potential
121``E_in`` -70.0 mV :math:`E_\mathrm{in}` Inhibitory reversal potential
122``V_th`` -55.0 mV :math:`V_\mathrm{th}` Spike threshold
123``V_reset`` -60.0 mV :math:`V_\mathrm{reset}` Reset potential of the membrane
124``C_m`` 250.0 pF :math:`C_\mathrm{m}` Capacitance of the membrane
125``g_L`` 25.0 nS :math:`g_\mathrm{L}` Leak conductance
126``t_ref`` 2.0 ms :math:`t_\mathrm{ref}` Duration of refractory period
127``tau_AMPA`` 2.0 ms :math:`\tau_\mathrm{AMPA}` Time constant of AMPA synapse
128``tau_GABA`` 5.0 ms :math:`\tau_\mathrm{GABA}` Time constant of GABA synapse
129``tau_rise_NMDA`` 2.0 ms :math:`\tau_\mathrm{NMDA,rise}` Rise time constant of NMDA synapse
130``tau_decay_NMDA`` 100.0 ms :math:`\tau_\mathrm{NMDA,decay}` Decay time constant of NMDA synapse
131``alpha`` 0.5 ms^{-1} :math:`\alpha` Rise-time coupling strength for NMDA synapse
132``conc_Mg2`` 1.0 mM :math:`[\mathrm{Mg}^+]` Extracellular magnesium concentration
133``gsl_error_tol`` 1e-3 Error tolerance for GSL RKF45-solver
134=================== ================== ================================= ========================================================================
135
136The following state variables evolve during simulation and are available either as neuron properties or as recordables.
137
138================== ================= ========================== =================================
139**State variable** **Initial value** **Math equivalent** **Description**
140================== ================= ========================== =================================
141``V_m`` -70 mV :math:`V_{\mathrm{m}}` Membrane potential
142``s_AMPA`` 0 :math:`s_\mathrm{AMPA}` AMPA gating variable
143``s_GABA`` 0 :math:`s_\mathrm{GABA}` GABA gating variable
144``s_NMDA`` 0 :math:`s_\mathrm{NMDA}` NMDA gating variable
145``I_NMDA`` 0 pA :math:`I_\mathrm{NMDA}` NMDA current
146``I_AMPA`` 0 pA :math:`I_\mathrm{AMPA}` AMPA current
147``I_GABA`` 0 pA :math:`I_\mathrm{GABA}` GABA current
148================== ================= ========================== =================================
149
150.. note::
151 It is possible to set values for :math:`V_\mathrm{m}`, :math:`S_\mathrm{AMPA}` and :math:`S_\mathrm{GABA}` when creating the model, while the different :math:`s_{j,\mathrm{NMDA}}` (`j` represents presynaptic neuron `j`) can not be set by the user.
152
153.. note::
154 :math:`g_{\mathrm{\{\{rec,AMPA\}, \{ext,AMPA\}, GABA, NMBA}\}}` from :footcite:p:`Wang1999` is built into the weights in this NEST model, so these variables are set by changing the weights.
155
156Sends
157+++++
158
159SpikeEvent
160
161Receives
162++++++++
163
164SpikeEvent, CurrentEvent, DataLoggingRequest
165
166References
167++++++++++
168
169.. footbibliography::
170
171See also
172++++++++
173
174iaf_bw_2001
175
176Examples using this model
177+++++++++++++++++++++++++
178
179.. listexamples:: iaf_bw_2001_exact
180
181EndUserDocs */
182// clang-format on
183
184void register_iaf_bw_2001_exact( const std::string& name );
185
186class iaf_bw_2001_exact : public ArchivingNode
187{
188public:
189 iaf_bw_2001_exact();
190 iaf_bw_2001_exact( const iaf_bw_2001_exact& );
191 ~iaf_bw_2001_exact() override;
192
193 /*
194 * Import all overloaded virtual functions that we
195 * override in this class. For background information,
196 * see http://www.gotw.ca/gotw/005.htm.
197 */
198
199 using Node::handle;
200 using Node::handles_test_event;
201
205 size_t send_test_event( Node& target, size_t receptor_type, synindex, bool ) override;
206
207 void handle( SpikeEvent& ) override;
208 void handle( CurrentEvent& e ) override;
209 void handle( DataLoggingRequest& ) override;
210
211 size_t handles_test_event( SpikeEvent&, size_t ) override;
212 size_t handles_test_event( CurrentEvent&, size_t ) override;
213 size_t handles_test_event( DataLoggingRequest&, size_t ) override;
214
215 /* -------------------------------------------------------------------------
216 * Functions for getting/setting parameters and state values.
217 * ------------------------------------------------------------------------- */
218
219 void get_status( Dictionary& ) const override;
220 void set_status( const Dictionary& ) override;
221
222private:
223 void init_state_() override;
224 void pre_run_hook() override;
225 void init_buffers_() override;
226 void update( Time const&, const long, const long ) override;
227
231 enum SynapseTypes
232 {
233 INF_SPIKE_RECEPTOR = 0,
234 AMPA,
235 GABA,
236 NMDA,
237 SUP_SPIKE_RECEPTOR
238 };
239
240 // make dynamics function quasi-member
241 friend int iaf_bw_2001_exact_dynamics( double, const double y[], double f[], void* pnode );
242
243 // The next two classes need to be friends to access the State_ class/member
244 friend class RecordablesMap< iaf_bw_2001_exact >;
245 friend class UniversalDataLogger< iaf_bw_2001_exact >;
246
247 struct Parameters_
248 {
249 double E_L;
250 double E_ex;
251 double E_in;
252 double V_th;
253 double V_reset;
254 double C_m;
255 double g_L;
256 double t_ref;
257 double tau_AMPA;
258 double tau_GABA;
259 double tau_rise_NMDA;
260 double tau_decay_NMDA;
261 double alpha;
262 double conc_Mg2;
263
264 double gsl_error_tol;
265
269 Parameters_();
270
271 void get( Dictionary& ) const;
272 void set( const Dictionary&, Node* node );
273 };
274
275public:
276 // State variables class --------------------------------------------
277
287 struct State_
288 {
293 enum StateVecElems
294 {
295 V_m = 0,
296 s_AMPA,
297 s_GABA,
298 s_NMDA_base,
299 };
300
301 size_t state_vec_size;
302
303 double* ode_state_;
304 long num_ports_;
305 int r_;
306
307 double s_NMDA_sum; // For recording NMDA gating variables
308 double I_NMDA_; // For recording NMDA currents
309 double I_AMPA_; // For recording NMDA currents
310 double I_GABA_; // For recording NMDA currents
311
312 State_( const Parameters_& );
313 State_( const State_& );
314 State_& operator=( const State_& ) = default;
315
316 void get( Dictionary& ) const;
317 void set( const Dictionary&, const Parameters_&, Node* );
318 };
319
320private:
321 // Buffers class --------------------------------------------------------
322
329 struct Buffers_
330 {
331 Buffers_( iaf_bw_2001_exact& );
332 Buffers_( const Buffers_&, iaf_bw_2001_exact& );
333
337 UniversalDataLogger< iaf_bw_2001_exact > logger_;
338
339 // -----------------------------------------------------------------------
340 // Buffers and sums of incoming spikes and currents per timestep
341 // -----------------------------------------------------------------------
342 std::vector< RingBuffer > spikes_;
343 RingBuffer currents_;
344
348 std::vector< double > weights_;
349
350 // -----------------------------------------------------------------------
351 // GSL ODE solver data structures
352 // -----------------------------------------------------------------------
353
354 gsl_odeiv_step* s_;
355 gsl_odeiv_control* c_;
356 gsl_odeiv_evolve* e_;
357 gsl_odeiv_system sys_;
358
359 /*
360 * integration_step_ should be reset with the neuron on ResetNetwork,
361 * but remain unchanged during calibration. Since it is initialized with
362 * step_, and the resolution cannot change after nodes have been created,
363 * it is safe to place both here.
364 */
365 double step_;
366 double integration_step_;
367
375 double I_stim_;
376 };
377
378 // Variables class -------------------------------------------------------
379
384 struct Variables_
385 {
387 long RefractoryCounts;
388 };
389
390 // Access functions for UniversalDataLogger -------------------------------
391
393 template < State_::StateVecElems elem >
394 double
395 get_ode_state_elem_() const
396 {
397 return S_.ode_state_[ elem ];
398 }
399
401 double
402 get_s_NMDA_() const
403 {
404 return S_.s_NMDA_sum;
405 }
406 double
407 get_I_NMDA_() const
408 {
409 return S_.I_NMDA_;
410 }
411 double
412 get_I_AMPA_() const
413 {
414 return S_.I_AMPA_;
415 }
416 double
417 get_I_GABA_() const
418 {
419 return S_.I_GABA_;
420 }
421
422
423 // Data members -----------------------------------------------------------
424
425 // keep the order of these lines, seems to give best performance
426 Parameters_ P_;
427 State_ S_;
428 Variables_ V_;
429 Buffers_ B_;
430
432 static RecordablesMap< iaf_bw_2001_exact > recordablesMap_;
433
434
435}; /* neuron iaf_bw_2001_exact */
436
437inline size_t
438iaf_bw_2001_exact::send_test_event( Node& target, size_t receptor_type, synindex, bool )
439{
440 SpikeEvent e;
441 e.set_sender( *this );
442 return target.handles_test_event( e, receptor_type );
443}
444
445inline size_t
446iaf_bw_2001_exact::handles_test_event( SpikeEvent&, size_t receptor_type )
447{
448 if ( not( INF_SPIKE_RECEPTOR < receptor_type and receptor_type < SUP_SPIKE_RECEPTOR ) )
449 {
450 throw UnknownReceptorType( receptor_type, get_name() );
451 return 0;
452 }
453 else
454 {
455 if ( receptor_type == SynapseTypes::NMDA )
456 {
457 // after the buffers are initialized, new synapses cannot be added since the buffers would have
458 // to be expanded
459 if ( B_.e_ != nullptr )
460 {
461 throw IllegalConnection(
462 "NMDA connections to this model can only be made before the first call to nest.Simulate()" );
463 }
464 // give each NMDA synapse a unique rport, starting from 3 (num_ports_ is initialized to 3)
465 ++S_.num_ports_;
466 return S_.num_ports_;
467 }
468 else
469 {
470 return receptor_type;
471 }
472 }
473}
474
475inline size_t
476iaf_bw_2001_exact::handles_test_event( CurrentEvent&, size_t receptor_type )
477{
478 if ( receptor_type != 0 )
479 {
480 throw UnknownReceptorType( receptor_type, get_name() );
481 }
482 return 0;
483}
484
485inline size_t
486iaf_bw_2001_exact::handles_test_event( DataLoggingRequest& dlr, size_t receptor_type )
487{
488 /*
489 * You should usually not change the code in this function.
490 * It confirms to the connection management system that we are able
491 * to handle @c DataLoggingRequest on port 0.
492 * The function also tells the built-in UniversalDataLogger that this node
493 * is recorded from and that it thus needs to collect data during simulation.
494 */
495 if ( receptor_type != 0 )
496 {
497 throw UnknownReceptorType( receptor_type, get_name() );
498 }
499
500 return B_.logger_.connect_logging_device( dlr, recordablesMap_ );
501}
502
503inline void
504iaf_bw_2001_exact::get_status( Dictionary& d ) const
505{
506 P_.get( d );
507 S_.get( d );
509
511
512 receptor_type[ names::AMPA ] = static_cast< long >( AMPA );
513 receptor_type[ names::GABA ] = static_cast< long >( GABA );
514 receptor_type[ names::NMDA ] = static_cast< long >( NMDA );
515
517
518 d[ names::recordables ] = recordablesMap_.get_list();
519}
520
521inline void
522iaf_bw_2001_exact::set_status( const Dictionary& d )
523{
524 Parameters_ ptmp = P_; // temporary copy in case of errors
525 ptmp.set( d, this ); // throws if BadProperty
526 State_ stmp = S_; // temporary copy in case of errors
527 stmp.set( d, ptmp, this ); // throws if BadProperty
528
529 /*
530 * We now know that (ptmp, stmp) are consistent. We do not
531 * write them back to (P_, S_) before we are also sure that
532 * the properties to be set in the parent class are internally
533 * consistent.
534 */
536
537 // if we get here, temporaries contain consistent set of properties
538 P_ = ptmp;
539 S_ = stmp;
540};
541} // namespace
542
543#endif // HAVE_GSL
544#endif // IAF_BW_2001
Dictionary class for interface to Python and C++ API.
Definition dictionary.h:213
void get_status(Dictionary &d) const override
Export properties of the node by setting entries in the status dictionary.
Definition archiving_node.cpp:220
void set_status(const Dictionary &d) override
Change properties of the node according to the entries in the dictionary.
Definition archiving_node.cpp:236
const std::string AMPA("AMPA")
const std::string t_ref("t_ref")
const std::string tau_AMPA("tau_AMPA")
const std::string E_L("E_L")
const std::string s_GABA("s_GABA")
const std::string V_reset("V_reset")
const std::string NMDA("NMDA")
const std::string recordables("recordables")
const std::string C_m("C_m")
const std::string d("d")
const std::string gsl_error_tol("gsl_error_tol")
const std::string V_th("V_th")
const std::string receptor_types("receptor_types")
const std::string s_AMPA("s_AMPA")
const std::string tau_rise_NMDA("tau_rise_NMDA")
const std::string conc_Mg2("conc_Mg2")
const std::string receptor_type("receptor_type")
const std::string tau_decay_NMDA("tau_decay_NMDA")
const std::string E_in("E_in")
const std::string alpha("alpha")
const std::string GABA("GABA")
const std::string tau_GABA("tau_GABA")
const std::string target("target")
const std::string V_m("V_m")
const std::string E_ex("E_ex")
const std::string g_L("g_L")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
size_t synindex
For enumerations of synapse types.
Definition nest_types.h:115
const double e
Definition numerics.cpp:32