From 47da6d4f45c33f61afa0eddc59e5e268e8564922 Mon Sep 17 00:00:00 2001 From: Hans Ekkehard Plesser Date: Thu, 7 Sep 2017 23:16:06 +0200 Subject: [PATCH 1/3] Replaced test for exact numerical equality for test with relative error 1e-14. Improved formatting of SLI code. --- testsuite/unittests/test_dcgen_versus_I_e.sli | 131 +++++++++++------- 1 file changed, 81 insertions(+), 50 deletions(-) diff --git a/testsuite/unittests/test_dcgen_versus_I_e.sli b/testsuite/unittests/test_dcgen_versus_I_e.sli index 80d5f7a957..31e17957ef 100644 --- a/testsuite/unittests/test_dcgen_versus_I_e.sli +++ b/testsuite/unittests/test_dcgen_versus_I_e.sli @@ -47,64 +47,95 @@ M_ERROR setverbosity /amp 123.456 def /res [] def % array to collect bool results -modeldict keys{ - - /model Set - - % check if both membrane potential can be measured.... - /record_VM model GetDefaults /recordables known def - record_VM { model GetDefaults /recordables get { /V_m eq {true} if } forall count 1 eq {; /record_VM true def} {/record_VM false def} ifelse } if - - % .... and I_e can be set - model GetDefaults /I_e known record_VM and +modeldict keys +{ + /model Set + + % check if both membrane potential can be measured.... + /record_VM model GetDefaults /recordables known def + record_VM + { + model GetDefaults /recordables get + { + /V_m eq { true } if + } + forall + count 1 eq { - - ResetKernel - - % special case for Poisson Neuron - - model /gif_psc_exp eq { model << /lambda_0 0.0 >> SetDefaults} if - model /gif_cond_exp eq { model << /lambda_0 0.0 >> SetDefaults} if - model /gif_psc_exp_multisynapse eq { model << /lambda_0 0.0 >> SetDefaults} if - model /gif_cond_exp_multisynapse eq { model << /lambda_0 0.0 >> SetDefaults} if - model /pp_psc_delta eq { model << /c_2 0.0 >> SetDefaults} if - - model =only (\t: ) =only - - %executive - - model Create /n1 Set - model Create /n2 Set - - %take into account synaptic delay - /dc_generator <> Create /dc Set - - % todo: make sure that this procedure is 'stopped' if and only if current events are not supported! - {dc n1 Connect - - dc << /amplitude amp >> SetStatus - - 100 Simulate - n2 << /I_e amp >> SetStatus - - 300 Simulate - - % compare final membrane potentials - n1 GetStatus /V_m get n2 GetStatus /V_m get eq dup - {(pass) =} - { (failed: unequal voltages) = executive } - ifelse - res exch append /res Set - } stopped { clear (DC not allowed) = errordict /newerror false put } if % skip models that don't support current event + ; /record_VM true def } - if % model GetDefaults /I_e known record_VM and + { + /record_VM false def + } + ifelse + } + if + + % .... and I_e can be set + model GetDefaults /I_e known record_VM and + { + ResetKernel + + % models requiring special parameters + model /gif_psc_exp eq { model << /lambda_0 0.0 >> SetDefaults} if + model /gif_cond_exp eq { model << /lambda_0 0.0 >> SetDefaults} if + model /gif_psc_exp_multisynapse eq { model << /lambda_0 0.0 >> SetDefaults} if + model /gif_cond_exp_multisynapse eq { model << /lambda_0 0.0 >> SetDefaults} if + model /pp_psc_delta eq { model << /c_2 0.0 >> SetDefaults} if + + model =only (\t: ) =only + + model Create /n1 Set + model Create /n2 Set + + %take into account synaptic delay + /dc_generator <> Create /dc Set + + % todo: make sure that this procedure is 'stopped' if + % and only if current events are not supported! + { + dc n1 Connect + dc << /amplitude amp >> SetStatus + + 100 Simulate + + n2 << /I_e amp >> SetStatus + + 300 Simulate + + % compare final membrane potentials + n1 GetStatus /V_m get /v1 Set + n2 GetStatus /V_m get /v2 Set + + % relative error 1e-14 allowed + v1 v2 sub abs v1 v2 add abs 1e-14 mul lt dup + { + (pass) = + } + { + (failed with V1: ) =only v1 =only + (, V2: ) =only v2 =only + (, dV: ) =only v1 v2 sub = + } + ifelse + res exch append /res Set + } + stopped + { + clear (DC not allowed) = + errordict /newerror false put + } if % skip models that don't support current event + } + if % model GetDefaults /I_e known record_VM and + } forall % modeldict keys % combine results, one bool left on stack res First res Rest { and } Fold +} +assert_or_die -} assert_or_die endusing From 2829b739db0c3964767c66d89c91a39af61b974e Mon Sep 17 00:00:00 2001 From: Hans Ekkehard Plesser Date: Thu, 7 Sep 2017 23:49:31 +0200 Subject: [PATCH 2/3] Revised iaf_psc_delta_canon to handle I_e and current input in exactly the same way. --- precise/iaf_psc_delta_canon.cpp | 15 +++++++-------- precise/iaf_psc_delta_canon.h | 7 +++---- testsuite/unittests/test_dcgen_versus_I_e.sli | 3 +-- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/precise/iaf_psc_delta_canon.cpp b/precise/iaf_psc_delta_canon.cpp index 39f3576b28..f8c5d0e97b 100644 --- a/precise/iaf_psc_delta_canon.cpp +++ b/precise/iaf_psc_delta_canon.cpp @@ -258,8 +258,7 @@ iaf_psc_delta_canon::calibrate() V_.exp_t_ = std::exp( -V_.h_ms_ / P_.tau_m_ ); V_.expm1_t_ = numerics::expm1( -V_.h_ms_ / P_.tau_m_ ); - V_.v_inf_ = P_.I_e_ * P_.tau_m_ / P_.c_m_; - V_.I_contrib_ = -V_.v_inf_ * V_.expm1_t_; + V_.R_ = P_.tau_m_ / P_.c_m_; // t_ref_ is the refractory period in ms // refractory_steps_ is the duration of the refractory period in whole @@ -352,9 +351,8 @@ iaf_psc_delta_canon::update( Time const& origin, // contribution of the stepwise constant current - double I_contrib_t = -S_.I_ * P_.tau_m_ / P_.c_m_ * V_.expm1_t_; - - S_.U_ = V_.I_contrib_ + I_contrib_t + V_.expm1_t_ * S_.U_ + S_.U_; + const double I_ext = -V_.expm1_t_ * V_.R_ * ( S_.I_ + P_.I_e_ ); + S_.U_ = I_ext + V_.expm1_t_ * S_.U_ + S_.U_; S_.U_ = S_.U_ < P_.U_min_ ? P_.U_min_ : S_.U_; // lower bound on potential @@ -478,7 +476,7 @@ nest::iaf_psc_delta_canon::propagate_( const double dt ) // see comment on regular update above const double expm1_dt = numerics::expm1( -dt / P_.tau_m_ ); - const double v_inf = V_.v_inf_ + S_.I_ * P_.tau_m_ / P_.c_m_; + const double v_inf = V_.R_ * ( S_.I_ + P_.I_e_ ); S_.U_ = -v_inf * expm1_dt + S_.U_ * expm1_dt + S_.U_; return; @@ -492,8 +490,9 @@ nest::iaf_psc_delta_canon::emit_spike_( Time const& origin, assert( S_.U_ >= P_.U_th_ ); // ensure we are superthreshold // compute time since threhold crossing - double v_inf = V_.v_inf_ + S_.I_ * P_.tau_m_ / P_.c_m_; - double dt = -P_.tau_m_ * std::log( ( v_inf - S_.U_ ) / ( v_inf - P_.U_th_ ) ); + const double v_inf = V_.R_ * ( S_.I_ + P_.I_e_ ); + const double dt = + -P_.tau_m_ * std::log( ( v_inf - S_.U_ ) / ( v_inf - P_.U_th_ ) ); // set stamp and offset for spike S_.last_spike_step_ = origin.get_steps() + lag + 1; diff --git a/precise/iaf_psc_delta_canon.h b/precise/iaf_psc_delta_canon.h index bc938a3798..6b2549f95d 100644 --- a/precise/iaf_psc_delta_canon.h +++ b/precise/iaf_psc_delta_canon.h @@ -358,10 +358,9 @@ class iaf_psc_delta_canon : public Archiving_Node */ struct Variables_ { - double exp_t_; //!< @$ e^{-t/\tau_m} @$ - double expm1_t_; //!< @$ e^{-t/\tau_m} - 1 @$ - double v_inf_; //!< @$ \frac{I_e\tau_m}{c_m} @$ - double I_contrib_; //!< @$ \frac{I_e\tau_m}{c_m} (1-e^{-t/\tau_m})@$ + double exp_t_; //!< @$ e^{-t/\tau_m} @$ + double expm1_t_; //!< @$ e^{-t/\tau_m} - 1 @$ + double R_; //!< @$ \frac{\tau_m}{c_m} @$ double h_ms_; //!< duration of time step [ms] diff --git a/testsuite/unittests/test_dcgen_versus_I_e.sli b/testsuite/unittests/test_dcgen_versus_I_e.sli index 31e17957ef..957db1e5ec 100644 --- a/testsuite/unittests/test_dcgen_versus_I_e.sli +++ b/testsuite/unittests/test_dcgen_versus_I_e.sli @@ -107,8 +107,7 @@ modeldict keys n1 GetStatus /V_m get /v1 Set n2 GetStatus /V_m get /v2 Set - % relative error 1e-14 allowed - v1 v2 sub abs v1 v2 add abs 1e-14 mul lt dup + v1 v2 eq dup { (pass) = } From 190855b8a82d86b26f6288dd22e219f42f14e3a1 Mon Sep 17 00:00:00 2001 From: Hans Ekkehard Plesser Date: Wed, 27 Sep 2017 20:45:42 +0200 Subject: [PATCH 3/3] Fixed typos in comments. --- precise/iaf_psc_delta_canon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/precise/iaf_psc_delta_canon.cpp b/precise/iaf_psc_delta_canon.cpp index f8c5d0e97b..02d8182d6c 100644 --- a/precise/iaf_psc_delta_canon.cpp +++ b/precise/iaf_psc_delta_canon.cpp @@ -58,7 +58,7 @@ template <> void RecordablesMap< iaf_psc_delta_canon >::create() { - // use standard names whereever you can for consistency! + // use standard names wherever you can for consistency! insert_( names::V_m, &iaf_psc_delta_canon::get_V_m_ ); } @@ -489,7 +489,7 @@ nest::iaf_psc_delta_canon::emit_spike_( Time const& origin, { assert( S_.U_ >= P_.U_th_ ); // ensure we are superthreshold - // compute time since threhold crossing + // compute time since threshold crossing const double v_inf = V_.R_ * ( S_.I_ + P_.I_e_ ); const double dt = -P_.tau_m_ * std::log( ( v_inf - S_.U_ ) / ( v_inf - P_.U_th_ ) );