NEST main@caf0ae8
 
Loading...
Searching...
No Matches
iaf_bw_2001.h
Go to the documentation of this file.
1/*
2 * iaf_bw_2001.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_H
24#define IAF_BW_2001_H
25
26// Generated includes:
27#include "config.h"
28
29#ifdef HAVE_GSL
30#ifdef HAVE_BOOST
31
32// C includes:
33#include <gsl/gsl_errno.h>
34#include <gsl/gsl_matrix.h>
35#include <gsl/gsl_odeiv.h>
36
37// Includes from nestkernel:
38#include "archiving_node.h"
39#include "connection.h"
40#include "event.h"
41#include "nest_types.h"
42#include "ring_buffer.h"
44
45namespace nest
46{
57extern "C" inline int iaf_bw_2001_dynamics( double, const double*, double*, void* );
58
59// clang-format off
60/* BeginUserDocs: neuron, integrate-and-fire, conductance-based
61
62Short description
63+++++++++++++++++
64
65Leaky integrate-and-fire-neuron model with conductance-based synapses and additional NMDA receptors with simplified dynamics.
66
67Description
68+++++++++++
69
70``iaf_bw_2001`` is a leaky integrate-and-fire neuron model with
71
72* an approximate version of the neuron model described in :footcite:p:`Wang1999`, :footcite:p:`Brunel2001`, :footcite:p:`Wang2002`.
73* exponential conductance-based AMPA and GABA-synapses
74* exponential conductance-based NMDA-synapses weighted such that it approximates the original non-linear dynamics
75* a fixed refractory period
76* no adaptation mechanisms
77
78Neuron and synaptic dynamics
79..................................................
80
81The membrane potential and synaptic variables evolve according to
82
83.. math::
84
85 C_\mathrm{m} \frac{dV(t)}{dt} &= -g_\mathrm{L} (V(t) - V_\mathrm{L}) - I_\mathrm{syn} (t) \\[3ex]
86 I_\mathrm{syn}(t) &= I_\mathrm{AMPA}(t) + I_\mathrm{NMDA}(t) + I_\mathrm{GABA}(t) (t) \\[3ex]
87 I_\mathrm{AMPA} &= (V(t) - V_E)\sum_{j \in \Gamma_\mathrm{ex}}^{N_E}w_jS_{j,\mathrm{AMPA}}(t) \\[3ex]
88 I_\mathrm{NMDA} &= \frac{(V(t) - V_E)}{1+[\mathrm{Mg^{2+}}]\mathrm{exp}(-0.062V(t))/3.57}\sum_{j \in \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}} + \sum_{k \in \Delta_j} (k_0 + k_1 S(t)) \delta (t - t_j^k) \\[3ex]
93
94where :math:`\Gamma_\mathrm{ex}` and :math:`\Gamma_\mathrm{in}` are index sets for presynaptic excitatory and inhibitory neurons respectively, and :math:`\Delta_j` is an index set for the spike times of neuron :math:`j`.
95
96.. math::
97
98 k_0 &= (\alpha \tau_r)^{\frac{\tau_r}{\tau_d}} \gamma \big[1 - \frac{\tau_r}{\tau_d}, \alpha \tau_r \big] \\[3ex]
99 k_1 &= \mathrm{exp}(-\alpha \tau_\mathrm{r}) - 1
100
101where :math:`\gamma` is the `lower incomplete gamma function
102<https://en.wikipedia.org/wiki/Incomplete_gamma_function>`_. For these values of :math:`k_0` and :math:`k_1`, the approximate model will approach the exact model for large `t`.
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 are not separated from the recurrent AMPA-synapses.
107
108See also :footcite:p:`Brunel2001` and :footcite:p:`Wang2002`.
109
110For more implementation details and a comparison to the exact version, see:
111
112- `Brunel_Wang_2001_Model_Approximation <../model_details/Brunel_Wang_2001_Model_Approximation.ipynb>`_
113
114Parameters
115++++++++++
116
117The following parameters can be set in the status Dictionary.
118
119=================== ================== ================================= ========================================================================
120**Parameter** **Default** **Math equivalent** **Description**
121=================== ================== ================================= ========================================================================
122``E_L`` -70.0 mV :math:`E_\mathrm{L}` Leak reversal potential
123``E_ex`` 0.0 mV :math:`E_\mathrm{ex}` Excitatory reversal potential
124``E_in`` -70.0 mV :math:`E_\mathrm{in}` Inhibitory reversal potential
125``V_th`` -55.0 mV :math:`V_\mathrm{th}` Spike threshold
126``V_reset`` -60.0 mV :math:`V_\mathrm{reset}` Reset potential of the membrane
127``C_m`` 250.0 pF :math:`C_\mathrm{m}` Capacitance of the membrane
128``g_L`` 25.0 nS :math:`g_\mathrm{L}` Leak conductance
129``t_ref`` 2.0 ms :math:`t_\mathrm{ref}` Duration of refractory period
130``tau_AMPA`` 2.0 ms :math:`\tau_\mathrm{AMPA}` Time constant of AMPA synapse
131``tau_GABA`` 5.0 ms :math:`\tau_\mathrm{GABA}` Time constant of GABA synapse
132``tau_rise_NMDA`` 2.0 ms :math:`\tau_\mathrm{NMDA,rise}` Rise time constant of NMDA synapse
133``tau_decay_NMDA`` 100.0 ms :math:`\tau_\mathrm{NMDA,decay}` Decay time constant of NMDA synapse
134``alpha`` 0.5 ms^{-1} :math:`\alpha` Rise-time coupling strength for NMDA synapse
135``conc_Mg2`` 1.0 mM :math:`[\mathrm{Mg}^+]` Extracellular magnesium concentration
136``gsl_error_tol`` 1e-3 Error tolerance for GSL RKF45-solver
137=================== ================== ================================= ========================================================================
138
139The following state variables evolve during simulation and are available either as neuron properties or as recordables.
140
141================== ================= ========================== =================================
142**State variable** **Initial value** **Math equivalent** **Description**
143================== ================= ========================== =================================
144``V_m`` -70 mV :math:`V_{\mathrm{m}}` Membrane potential
145``s_AMPA`` 0 :math:`s_\mathrm{AMPA}` AMPA gating variable
146``s_GABA`` 0 :math:`s_\mathrm{GABA}` GABA gating variable
147``s_NMDA`` 0 :math:`s_\mathrm{NMDA}` NMDA gating variable
148``I_NMDA`` 0 pA :math:`I_\mathrm{NMDA}` NMDA current
149``I_AMPA`` 0 pA :math:`I_\mathrm{AMPA}` AMPA current
150``I_GABA`` 0 pA :math:`I_\mathrm{GABA}` GABA current
151================== ================= ========================== =================================
152
153.. note::
154 :math:`g_{\mathrm{\{\{rec,AMPA\}, \{ext,AMPA\}, GABA, NMBA}\}}` from :footcite:p:`Wang1999` are built into the weights in this NEST model, so these variables are set by changing the weights.
155
156.. note::
157 For the NMDA dynamics to work, both pre-synaptic and post-synaptic neurons must be of type ``iaf_bw_2001``. For AMPA/GABA synapses, any pre-synaptic neuron can be used.
158
159.. note::
160 For technical reasons, spikes from ``iaf_bw_2001`` neurons must be recorded with ``time_in_steps: True`` set in the spike recorder, ignoring the offset value. We hope to correct this in a future version of NEST.
161
162Sends
163+++++
164
165SpikeEvent
166
167Receives
168++++++++
169
170SpikeEvent, CurrentEvent, DataLoggingRequest
171
172References
173++++++++++
174
175.. footbibliography::
176
177See also
178++++++++
179
180iaf_bw_2001_exact
181
182Examples using this model
183+++++++++++++++++++++++++
184
185.. listexamples:: iaf_bw_2001
186
187EndUserDocs */
188// clang-format on
189
190void register_iaf_bw_2001( const std::string& name );
191
192class iaf_bw_2001 : public ArchivingNode
193{
194public:
195 iaf_bw_2001();
196 iaf_bw_2001( const iaf_bw_2001& );
197 ~iaf_bw_2001() override;
198
205 using Node::handle;
206 using Node::handles_test_event;
207
209 size_t send_test_event( Node&, size_t, synindex, bool ) override;
210
211 void handle( SpikeEvent& ) override;
212 void handle( CurrentEvent& ) override;
213 void handle( DataLoggingRequest& ) override;
214
215 size_t handles_test_event( SpikeEvent&, size_t ) override;
216 size_t handles_test_event( CurrentEvent&, size_t ) override;
217 size_t handles_test_event( DataLoggingRequest&, size_t ) override;
218
219 /* -------------------------------------------------------------------------
220 * Functions for getting/setting parameters and state values.
221 * ------------------------------------------------------------------------- */
222
223 void get_status( Dictionary& ) const override;
224 void set_status( const Dictionary& ) override;
225
226 bool
227 is_off_grid() const override
228 {
229 return true;
230 }
231
232private:
233 void init_state_() override;
234 void pre_run_hook() override;
235 void init_buffers_() override;
236 void update( Time const&, const long, const long ) override;
237
241 enum SynapseTypes
242 {
243 INF_SPIKE_RECEPTOR = 0,
244 AMPA,
245 GABA,
246 NMDA,
247 SUP_SPIKE_RECEPTOR
248 };
249
250 // make dynamics function quasi-member
251 friend int iaf_bw_2001_dynamics( double, const double*, double*, void* );
252
253 // The next two classes need to be friends to access the State_ class/member
254 friend class RecordablesMap< iaf_bw_2001 >;
255 friend class UniversalDataLogger< iaf_bw_2001 >;
256
257 struct Parameters_
258 {
259 double E_L;
260 double E_ex;
261 double E_in;
262 double V_th;
263 double V_reset;
264 double C_m;
265 double g_L;
266 double t_ref;
267 double tau_AMPA;
268 double tau_GABA;
269 double tau_decay_NMDA;
270 double tau_rise_NMDA;
271 double alpha;
272 double conc_Mg2;
273
274 double gsl_error_tol;
275
277 Parameters_();
278
279 void get( Dictionary& ) const;
280 void set( const Dictionary&, Node* node );
281 };
282
283public:
284 // State variables class --------------------------------------------
285
295 struct State_
296 {
298 enum StateVecElems
299 {
300 V_m = 0,
301 s_AMPA,
302 s_GABA,
303 s_NMDA,
304 STATE_VEC_SIZE
305 };
306
307 double y_[ STATE_VEC_SIZE ];
308 double s_NMDA_pre; // for determining (unweighted) alpha * (1 - s_NMDA) term on
309 // pre-synaptic side
310
311 double I_NMDA_; // For recording NMDA currents
312 double I_AMPA_; // For recording AMPA currents
313 double I_GABA_; // For recording GABA currents
314
315 int r_;
316
317 State_( const Parameters_& );
318 State_( const State_& );
319 State_& operator=( const State_& ) = default;
320
321 void get( Dictionary& ) const;
322 void set( const Dictionary&, const Parameters_&, Node* );
323 };
324
325
326private:
327 // Buffers class --------------------------------------------------------
328
335 struct Buffers_
336 {
337 Buffers_( iaf_bw_2001& );
338 Buffers_( const Buffers_&, iaf_bw_2001& );
339
341 UniversalDataLogger< iaf_bw_2001 > logger_;
342
343 // -----------------------------------------------------------------------
344 // Buffers and sums of incoming spikes and currents per timestep
345 // -----------------------------------------------------------------------
346 std::vector< RingBuffer > spikes_;
347 RingBuffer currents_;
348
349 // -----------------------------------------------------------------------
350 // GSL ODE solver data structures
351 // -----------------------------------------------------------------------
352
353 gsl_odeiv_step* s_;
354 gsl_odeiv_control* c_;
355 gsl_odeiv_evolve* e_;
356 gsl_odeiv_system sys_;
357
364 double step_;
365 double integration_step_;
366
374 double I_stim_;
375 };
376
377 // Variables class -------------------------------------------------------
378
383 struct Variables_
384 {
386 long RefractoryCounts_;
387 double k_0; // zeroth order term of jump
388 double k_1; // first order term of jump
389 };
390
391 // Access functions for UniversalDataLogger -------------------------------
392
394 template < State_::StateVecElems elem >
395 double
396 get_ode_state_elem_() const
397 {
398 return S_.y_[ elem ];
399 }
400 double
401 get_I_NMDA_() const
402 {
403 return S_.I_NMDA_;
404 }
405 double
406 get_I_AMPA_() const
407 {
408 return S_.I_AMPA_;
409 }
410 double
411 get_I_GABA_() const
412 {
413 return S_.I_GABA_;
414 }
415
416
417 // Data members -----------------------------------------------------------
418
419 // keep the order of these lines, seems to give best performance
420 Parameters_ P_;
421 State_ S_;
422 Variables_ V_;
423 Buffers_ B_;
424
426 static RecordablesMap< iaf_bw_2001 > recordablesMap_;
427
428}; /* neuron iaf_bw_2001 */
429
430inline size_t
431iaf_bw_2001::send_test_event( Node& target, size_t receptor_type, synindex, bool )
432{
433 SpikeEvent e;
434 e.set_sender( *this );
435 return target.handles_test_event( e, receptor_type );
436}
437
438inline size_t
439iaf_bw_2001::handles_test_event( SpikeEvent& e, size_t receptor_type )
440{
441 if ( not( INF_SPIKE_RECEPTOR < receptor_type and receptor_type < SUP_SPIKE_RECEPTOR ) )
442 {
443 throw UnknownReceptorType( receptor_type, get_name() );
444 }
445
446 const Node& sender = e.get_sender();
447 if ( receptor_type == NMDA and typeid( sender ) != typeid( *this ) )
448 {
449 throw IllegalConnection( "For NMDA synapses in iaf_bw_2001, pre-synaptic neuron must also be of type iaf_bw_2001" );
450 }
451 return receptor_type;
452}
453
454inline size_t
455iaf_bw_2001::handles_test_event( CurrentEvent&, size_t receptor_type )
456{
457 if ( receptor_type != 0 )
458 {
459 throw UnknownReceptorType( receptor_type, get_name() );
460 }
461 return 0;
462}
463
464inline size_t
465iaf_bw_2001::handles_test_event( DataLoggingRequest& dlr, size_t receptor_type )
466{
467 /*
468 * You should usually not change the code in this function.
469 * It confirms to the connection management system that we are able
470 * to handle @c DataLoggingRequest on port 0.
471 * The function also tells the built-in UniversalDataLogger that this node
472 * is recorded from and that it thus needs to collect data during simulation.
473 */
474 if ( receptor_type != 0 )
475 {
476 throw UnknownReceptorType( receptor_type, get_name() );
477 }
478
479 return B_.logger_.connect_logging_device( dlr, recordablesMap_ );
480}
481
482inline void
483iaf_bw_2001::get_status( Dictionary& d ) const
484{
485 P_.get( d );
486 S_.get( d );
488
490 receptor_type[ names::AMPA ] = static_cast< long >( AMPA );
491 receptor_type[ names::GABA ] = static_cast< long >( GABA );
492 receptor_type[ names::NMDA ] = static_cast< long >( NMDA );
494
495 d[ names::recordables ] = recordablesMap_.get_list();
496}
497
498inline void
499iaf_bw_2001::set_status( const Dictionary& d )
500{
501 Parameters_ ptmp = P_; // temporary copy in case of errors
502 ptmp.set( d, this ); // throws if BadProperty
503 State_ stmp = S_; // temporary copy in case of errors
504 stmp.set( d, ptmp, this ); // throws if BadProperty
505
506 /*
507 * We now know that (ptmp, stmp) are consistent. We do not
508 * write them back to (P_, S_) before we are also sure that
509 * the properties to be set in the parent class are internally
510 * consistent.
511 */
513
514 // if we get here, temporaries contain consistent set of properties
515 P_ = ptmp;
516 S_ = stmp;
517};
518} // namespace
519
520#endif // HAVE_BOOST
521#endif // HAVE_GSL
522#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 s_NMDA("s_NMDA")
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