From 76f7f82bb8fa13a7b63321739e40bd75e3007e9e Mon Sep 17 00:00:00 2001 From: Susanne Kunkel Date: Thu, 22 Feb 2018 10:31:48 +0100 Subject: [PATCH 1/5] Expose numerical imprescision in synaptic plasticity --- models/stdp_pl_connection_hom.h | 9 +++++++++ nestkernel/archiving_node.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/models/stdp_pl_connection_hom.h b/models/stdp_pl_connection_hom.h index 3cba435038..32b71e9c7f 100644 --- a/models/stdp_pl_connection_hom.h +++ b/models/stdp_pl_connection_hom.h @@ -58,6 +58,8 @@ // C++ includes: #include +#include +#include // Includes from nestkernel: #include "connection.h" @@ -261,6 +263,13 @@ STDPPLConnectionHom< targetidentifierT >::send( Event& e, { continue; } + // check if entry was accepted by mistake + if ( minus_dt > -0.5 * Time::get_resolution().get_ms() ) + { + std::cout << "STDPPLConnectionHom::send minus_dt = " + << std::setprecision( std::numeric_limits::digits10 + 1 ) + << minus_dt << std::endl; + } weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt * cp.tau_plus_inv_ ), cp ); } diff --git a/nestkernel/archiving_node.cpp b/nestkernel/archiving_node.cpp index e992ed39c9..db1c4b65b9 100644 --- a/nestkernel/archiving_node.cpp +++ b/nestkernel/archiving_node.cpp @@ -29,6 +29,10 @@ #include "archiving_node.h" +// C++ includes: +#include +#include + // Includes from sli: #include "dictutils.h" @@ -102,6 +106,13 @@ nest::Archiving_Node::get_K_value( double t ) { if ( t > history_[ i ].t_ ) { + // check if entry was accepted by mistake + if ( ( t - history_[ i ].t_ ) < ( 0.5 * Time::get_resolution().get_ms() ) ) + { + std::cout << "Archiving_Node::get_K_value at " + << std::setprecision( std::numeric_limits::digits10 + 1 ) + << t << ", history entry at " << history_[ i ].t_ << std::endl; + } return ( history_[ i ].Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_inv_ ) ); } @@ -170,6 +181,24 @@ nest::Archiving_Node::get_history( double t1, ++runner; } *finish = runner; + + // check if start entry was included by mistake + if ( (*start)->t_ - t1 > -0.5 * Time::get_resolution().get_ms() && + (*start)->t_ - t1 < 0.5 * Time::get_resolution().get_ms() ) + { + std::cout << "Archiving_Node::get_history t1 = " + << std::setprecision(std::numeric_limits::digits10 + 1) + << t1 << ", start history entry t = " << (*start)->t_ << std::endl; + } + // check if finish entry was excluded by mistake + if ( (*finish) != history_.end() + && (*finish)->t_ - t2 > -0.5 * Time::get_resolution().get_ms() + && (*finish)->t_ - t2 < 0.5 * Time::get_resolution().get_ms() ) + { + std::cout << "Archiving_Node::get_history t2 = " + << std::setprecision(std::numeric_limits::digits10 + 1) + << t2 << ", finish history entry t = " << (*finish)->t_ << std::endl; + } } } From c0d88698b440f6492644aa37434f101fb2b3ccea Mon Sep 17 00:00:00 2001 From: Susanne Kunkel Date: Fri, 23 Feb 2018 11:24:43 +0100 Subject: [PATCH 2/5] Temporary fix for imprecision in synaptic plasticity --- models/stdp_connection.h | 7 +++-- models/stdp_connection_hom.h | 7 +++-- models/stdp_dopa_connection.h | 10 +++++--- models/stdp_pl_connection_hom.h | 14 +++------- models/stdp_triplet_connection.h | 8 +++--- models/vogels_sprekeler_connection.h | 7 +++-- nestkernel/archiving_node.cpp | 38 ++++++---------------------- 7 files changed, 29 insertions(+), 62 deletions(-) diff --git a/models/stdp_connection.h b/models/stdp_connection.h index 487252795b..58e04f318d 100644 --- a/models/stdp_connection.h +++ b/models/stdp_connection.h @@ -250,10 +250,9 @@ STDPConnection< targetidentifierT >::send( Event& e, { minus_dt = t_lastspike - ( start->t_ + dendritic_delay ); ++start; - if ( minus_dt == 0 ) - { - continue; - } + // get_history() should make sure that + // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 + assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ) ); } diff --git a/models/stdp_connection_hom.h b/models/stdp_connection_hom.h index 4980bfafd7..5d3c92b16e 100644 --- a/models/stdp_connection_hom.h +++ b/models/stdp_connection_hom.h @@ -302,10 +302,9 @@ STDPConnectionHom< targetidentifierT >::send( Event& e, { minus_dt = t_lastspike - ( start->t_ + dendritic_delay ); ++start; - if ( minus_dt == 0 ) - { - continue; - } + // get_history() should make sure that + // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 + assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/models/stdp_dopa_connection.h b/models/stdp_dopa_connection.h index 7c0a7858c1..b0e7aefe37 100644 --- a/models/stdp_dopa_connection.h +++ b/models/stdp_dopa_connection.h @@ -452,7 +452,8 @@ STDPDopaConnection< targetidentifierT >::process_dopa_spikes_( // process dopa spikes in (t0, t1] // propagate weight from t0 to t1 if ( ( dopa_spikes.size() > dopa_spikes_idx_ + 1 ) - && ( dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ <= t1 ) ) + && ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -0.5 + * Time::get_resolution().get_ms() ) ) { // there is at least 1 dopa spike in (t0, t1] // propagate weight up to first dopa spike and update dopamine trace @@ -468,7 +469,8 @@ STDPDopaConnection< targetidentifierT >::process_dopa_spikes_( // process remaining dopa spikes in (t0, t1] double cd; while ( ( dopa_spikes.size() > dopa_spikes_idx_ + 1 ) - && ( dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ <= t1 ) ) + && ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -0.5 + * Time::get_resolution().get_ms() ) ) { // propagate weight up to next dopa spike and update dopamine trace // weight and dopamine trace n are at time of last dopa spike td but @@ -565,8 +567,8 @@ STDPDopaConnection< targetidentifierT >::send( Event& e, process_dopa_spikes_( dopa_spikes, t0, start->t_ + dendritic_delay, cp ); t0 = start->t_ + dendritic_delay; minus_dt = t_last_update_ - t0; - if ( start->t_ < t_spike ) // only depression if pre- and postsyn. spike - // occur at the same time + // only depression if pre- and postsyn. spike occur at the same time + if ( t_spike - start->t_ > 0.5 * Time::get_resolution().get_ms() ) { facilitate_( Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/models/stdp_pl_connection_hom.h b/models/stdp_pl_connection_hom.h index 32b71e9c7f..9e1a03d2a5 100644 --- a/models/stdp_pl_connection_hom.h +++ b/models/stdp_pl_connection_hom.h @@ -259,17 +259,9 @@ STDPPLConnectionHom< targetidentifierT >::send( Event& e, { minus_dt = t_lastspike - ( start->t_ + dendritic_delay ); start++; - if ( minus_dt == 0 ) - { - continue; - } - // check if entry was accepted by mistake - if ( minus_dt > -0.5 * Time::get_resolution().get_ms() ) - { - std::cout << "STDPPLConnectionHom::send minus_dt = " - << std::setprecision( std::numeric_limits::digits10 + 1 ) - << minus_dt << std::endl; - } + // get_history() should make sure that + // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 + assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt * cp.tau_plus_inv_ ), cp ); } diff --git a/models/stdp_triplet_connection.h b/models/stdp_triplet_connection.h index 288f3d844e..5adf165746 100644 --- a/models/stdp_triplet_connection.h +++ b/models/stdp_triplet_connection.h @@ -259,11 +259,9 @@ STDPTripletConnection< targetidentifierT >::send( Event& e, // Pfister et al, 2006 double ky = start->triplet_Kminus_ - 1.0; ++start; - if ( minus_dt == 0 ) - { - continue; - } - + // get_history() should make sure that + // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 + assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ), ky ); } diff --git a/models/vogels_sprekeler_connection.h b/models/vogels_sprekeler_connection.h index 363214a29e..b40ed06699 100644 --- a/models/vogels_sprekeler_connection.h +++ b/models/vogels_sprekeler_connection.h @@ -215,10 +215,9 @@ VogelsSprekelerConnection< targetidentifierT >::send( Event& e, { minus_dt = t_lastspike - ( start->t_ + dendritic_delay ); ++start; - if ( minus_dt == 0 ) - { - continue; - } + // get_history() should make sure that + // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 + assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_ ) ); } diff --git a/nestkernel/archiving_node.cpp b/nestkernel/archiving_node.cpp index db1c4b65b9..39acd25123 100644 --- a/nestkernel/archiving_node.cpp +++ b/nestkernel/archiving_node.cpp @@ -85,7 +85,8 @@ Archiving_Node::register_stdp_connection( double t_first_read ) // For details see bug #218. MH 08-04-22 for ( std::deque< histentry >::iterator runner = history_.begin(); - runner != history_.end() && runner->t_ <= t_first_read; + runner != history_.end() && ( t_first_read - runner->t_ > -0.5 + * Time::get_resolution().get_ms() ); ++runner ) { ( runner->access_counter_ )++; @@ -104,15 +105,8 @@ nest::Archiving_Node::get_K_value( double t ) int i = history_.size() - 1; while ( i >= 0 ) { - if ( t > history_[ i ].t_ ) + if ( t - history_[ i ].t_ > 0.5 * Time::get_resolution().get_ms() ) { - // check if entry was accepted by mistake - if ( ( t - history_[ i ].t_ ) < ( 0.5 * Time::get_resolution().get_ms() ) ) - { - std::cout << "Archiving_Node::get_K_value at " - << std::setprecision( std::numeric_limits::digits10 + 1 ) - << t << ", history entry at " << history_[ i ].t_ << std::endl; - } return ( history_[ i ].Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_inv_ ) ); } @@ -137,7 +131,7 @@ nest::Archiving_Node::get_K_values( double t, int i = history_.size() - 1; while ( i >= 0 ) { - if ( t > history_[ i ].t_ ) + if ( t - history_[ i ].t_ > 0.5 * Time::get_resolution().get_ms() ) { triplet_K_value = ( history_[ i ].triplet_Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_triplet_inv_ ) ); @@ -170,35 +164,19 @@ nest::Archiving_Node::get_history( double t1, else { std::deque< histentry >::iterator runner = history_.begin(); - while ( ( runner != history_.end() ) && ( runner->t_ <= t1 ) ) + while ( ( runner != history_.end() ) + && ( t1 - runner->t_ > -0.5 * Time::get_resolution().get_ms() ) ) { ++runner; } *start = runner; - while ( ( runner != history_.end() ) && ( runner->t_ <= t2 ) ) + while ( ( runner != history_.end() ) + && ( t2 - runner->t_ > -0.5 * Time::get_resolution().get_ms() ) ) { ( runner->access_counter_ )++; ++runner; } *finish = runner; - - // check if start entry was included by mistake - if ( (*start)->t_ - t1 > -0.5 * Time::get_resolution().get_ms() && - (*start)->t_ - t1 < 0.5 * Time::get_resolution().get_ms() ) - { - std::cout << "Archiving_Node::get_history t1 = " - << std::setprecision(std::numeric_limits::digits10 + 1) - << t1 << ", start history entry t = " << (*start)->t_ << std::endl; - } - // check if finish entry was excluded by mistake - if ( (*finish) != history_.end() - && (*finish)->t_ - t2 > -0.5 * Time::get_resolution().get_ms() - && (*finish)->t_ - t2 < 0.5 * Time::get_resolution().get_ms() ) - { - std::cout << "Archiving_Node::get_history t2 = " - << std::setprecision(std::numeric_limits::digits10 + 1) - << t2 << ", finish history entry t = " << (*finish)->t_ << std::endl; - } } } From 005e957d9756f8655f01a9c641b8c590dbb156b0 Mon Sep 17 00:00:00 2001 From: Susanne Kunkel Date: Mon, 9 Apr 2018 15:16:28 +0200 Subject: [PATCH 3/5] Use kernel variable for epsilon needed in STDP --- models/stdp_connection.h | 2 +- models/stdp_connection_hom.h | 2 +- models/stdp_dopa_connection.h | 11 ++++++----- models/stdp_pl_connection_hom.h | 2 +- models/stdp_triplet_connection.h | 2 +- models/vogels_sprekeler_connection.h | 2 +- nestkernel/archiving_node.cpp | 20 ++++++++++++++------ nestkernel/connection_manager.cpp | 1 + nestkernel/connection_manager.h | 20 ++++++++++++++++++++ nestkernel/nestmodule.cpp | 21 +++++++++++++++++++++ nestkernel/nestmodule.h | 6 ++++++ 11 files changed, 73 insertions(+), 16 deletions(-) diff --git a/models/stdp_connection.h b/models/stdp_connection.h index 58e04f318d..f46ccb6c89 100644 --- a/models/stdp_connection.h +++ b/models/stdp_connection.h @@ -252,7 +252,7 @@ STDPConnection< targetidentifierT >::send( Event& e, ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); + assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ) ); } diff --git a/models/stdp_connection_hom.h b/models/stdp_connection_hom.h index 5d3c92b16e..2aa72ea514 100644 --- a/models/stdp_connection_hom.h +++ b/models/stdp_connection_hom.h @@ -304,7 +304,7 @@ STDPConnectionHom< targetidentifierT >::send( Event& e, ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); + assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/models/stdp_dopa_connection.h b/models/stdp_dopa_connection.h index b0e7aefe37..63b53be7aa 100644 --- a/models/stdp_dopa_connection.h +++ b/models/stdp_dopa_connection.h @@ -452,8 +452,8 @@ STDPDopaConnection< targetidentifierT >::process_dopa_spikes_( // process dopa spikes in (t0, t1] // propagate weight from t0 to t1 if ( ( dopa_spikes.size() > dopa_spikes_idx_ + 1 ) - && ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -0.5 - * Time::get_resolution().get_ms() ) ) + && ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -1.0 + * kernel().connection_manager.get_stdp_eps() ) ) { // there is at least 1 dopa spike in (t0, t1] // propagate weight up to first dopa spike and update dopamine trace @@ -469,8 +469,8 @@ STDPDopaConnection< targetidentifierT >::process_dopa_spikes_( // process remaining dopa spikes in (t0, t1] double cd; while ( ( dopa_spikes.size() > dopa_spikes_idx_ + 1 ) - && ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -0.5 - * Time::get_resolution().get_ms() ) ) + && ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -1.0 + * kernel().connection_manager.get_stdp_eps() ) ) { // propagate weight up to next dopa spike and update dopamine trace // weight and dopamine trace n are at time of last dopa spike td but @@ -568,7 +568,8 @@ STDPDopaConnection< targetidentifierT >::send( Event& e, t0 = start->t_ + dendritic_delay; minus_dt = t_last_update_ - t0; // only depression if pre- and postsyn. spike occur at the same time - if ( t_spike - start->t_ > 0.5 * Time::get_resolution().get_ms() ) + if ( t_spike - start->t_ > 1.0 + * kernel().connection_manager.get_stdp_eps() ) { facilitate_( Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/models/stdp_pl_connection_hom.h b/models/stdp_pl_connection_hom.h index 9e1a03d2a5..1072466544 100644 --- a/models/stdp_pl_connection_hom.h +++ b/models/stdp_pl_connection_hom.h @@ -261,7 +261,7 @@ STDPPLConnectionHom< targetidentifierT >::send( Event& e, start++; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); + assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt * cp.tau_plus_inv_ ), cp ); } diff --git a/models/stdp_triplet_connection.h b/models/stdp_triplet_connection.h index 5adf165746..e9845c407c 100644 --- a/models/stdp_triplet_connection.h +++ b/models/stdp_triplet_connection.h @@ -261,7 +261,7 @@ STDPTripletConnection< targetidentifierT >::send( Event& e, ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); + assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ), ky ); } diff --git a/models/vogels_sprekeler_connection.h b/models/vogels_sprekeler_connection.h index b40ed06699..80a5f55ce8 100644 --- a/models/vogels_sprekeler_connection.h +++ b/models/vogels_sprekeler_connection.h @@ -217,7 +217,7 @@ VogelsSprekelerConnection< targetidentifierT >::send( Event& e, ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -0.5 * Time::get_resolution().get_ms() ); + assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_ ) ); } diff --git a/nestkernel/archiving_node.cpp b/nestkernel/archiving_node.cpp index 39acd25123..951bfc1605 100644 --- a/nestkernel/archiving_node.cpp +++ b/nestkernel/archiving_node.cpp @@ -33,6 +33,9 @@ #include #include +// Includes from nestkernel: +#include "kernel_manager.h" + // Includes from sli: #include "dictutils.h" @@ -85,8 +88,9 @@ Archiving_Node::register_stdp_connection( double t_first_read ) // For details see bug #218. MH 08-04-22 for ( std::deque< histentry >::iterator runner = history_.begin(); - runner != history_.end() && ( t_first_read - runner->t_ > -0.5 - * Time::get_resolution().get_ms() ); + runner != history_.end() + && ( t_first_read - runner->t_ > -1.0 + * kernel().connection_manager.get_stdp_eps() ); ++runner ) { ( runner->access_counter_ )++; @@ -105,7 +109,8 @@ nest::Archiving_Node::get_K_value( double t ) int i = history_.size() - 1; while ( i >= 0 ) { - if ( t - history_[ i ].t_ > 0.5 * Time::get_resolution().get_ms() ) + if ( t - history_[ i ].t_ > 1.0 + * kernel().connection_manager.get_stdp_eps() ) { return ( history_[ i ].Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_inv_ ) ); @@ -131,7 +136,8 @@ nest::Archiving_Node::get_K_values( double t, int i = history_.size() - 1; while ( i >= 0 ) { - if ( t - history_[ i ].t_ > 0.5 * Time::get_resolution().get_ms() ) + if ( t - history_[ i ].t_ > 1.0 + * kernel().connection_manager.get_stdp_eps() ) { triplet_K_value = ( history_[ i ].triplet_Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_triplet_inv_ ) ); @@ -165,13 +171,15 @@ nest::Archiving_Node::get_history( double t1, { std::deque< histentry >::iterator runner = history_.begin(); while ( ( runner != history_.end() ) - && ( t1 - runner->t_ > -0.5 * Time::get_resolution().get_ms() ) ) + && ( t1 - runner->t_ > -1.0 + * kernel().connection_manager.get_stdp_eps() ) ) { ++runner; } *start = runner; while ( ( runner != history_.end() ) - && ( t2 - runner->t_ > -0.5 * Time::get_resolution().get_ms() ) ) + && ( t2 - runner->t_ > -1.0 + * kernel().connection_manager.get_stdp_eps() ) ) { ( runner->access_counter_ )++; ++runner; diff --git a/nestkernel/connection_manager.cpp b/nestkernel/connection_manager.cpp index 3c26cadd27..7d942a84ef 100644 --- a/nestkernel/connection_manager.cpp +++ b/nestkernel/connection_manager.cpp @@ -77,6 +77,7 @@ nest::ConnectionManager::ConnectionManager() , initial_connector_capacity_( CONFIG_CONNECTOR_CUTOFF ) , large_connector_limit_( CONFIG_CONNECTOR_CUTOFF * 2 ) , large_connector_growth_factor_( 1.5 ) + , stdp_eps_( 1.0e-6 ) { } diff --git a/nestkernel/connection_manager.h b/nestkernel/connection_manager.h index 28c4bc7b40..256c6f7e1c 100644 --- a/nestkernel/connection_manager.h +++ b/nestkernel/connection_manager.h @@ -313,6 +313,10 @@ class ConnectionManager : public ManagerInterface */ double get_large_connector_growth_factor() const; + double get_stdp_eps() const; + + void set_stdp_eps( const double stdp_eps ); + private: /** * Update delay extrema to current values. @@ -419,6 +423,10 @@ class ConnectionManager : public ManagerInterface //! Capacity growth factor to use beyond the limit double large_connector_growth_factor_; + + //! Maximum distance between (double) spike times in STDP that is + //! still considered 0 + double stdp_eps_; }; inline DictionaryDatum& @@ -457,6 +465,18 @@ ConnectionManager::get_large_connector_growth_factor() const return large_connector_growth_factor_; } +inline double +ConnectionManager::get_stdp_eps() const +{ + return stdp_eps_; +} + +inline void +ConnectionManager::set_stdp_eps( const double stdp_eps ) +{ + stdp_eps_ = stdp_eps; +} + } // namespace nest #endif /* CONNECTION_MANAGER_H */ diff --git a/nestkernel/nestmodule.cpp b/nestkernel/nestmodule.cpp index 69999316a8..b1a2f99d69 100644 --- a/nestkernel/nestmodule.cpp +++ b/nestkernel/nestmodule.cpp @@ -1699,6 +1699,24 @@ NestModule::DisableStructuralPlasticity_Function::execute( i->EStack.pop(); } +/** + * Set epsilon that is used for comparing spike times in STDP. + * Spike times in STDP synapses are currently represented as double + * values. The epsilon defines the maximum distance between spike + * times that is still considered 0. + */ +void +NestModule::SetStdpEps_dFunction::execute( SLIInterpreter* i ) const +{ + i->assert_stack_load( 1 ); + const double stdp_eps = getValue< double >( i->OStack.top() ); + + kernel().connection_manager.set_stdp_eps( stdp_eps ); + + i->OStack.pop(); + i->EStack.pop(); +} + void NestModule::init( SLIInterpreter* i ) { @@ -1794,6 +1812,9 @@ NestModule::init( SLIInterpreter* i ) "GetStructuralPlasticityStatus", &getstructuralplasticitystatus_function ); i->createcommand( "Disconnect", &disconnect_i_i_lfunction ); i->createcommand( "Disconnect_g_g_D_D", &disconnect_g_g_D_Dfunction ); + + i->createcommand( "SetStdpEps", &setstdpeps_dfunction ); + // Add connection rules kernel().connection_manager.register_conn_builder< OneToOneBuilder >( "one_to_one" ); diff --git a/nestkernel/nestmodule.h b/nestkernel/nestmodule.h index f790d4d1c1..c1ffbc35fb 100644 --- a/nestkernel/nestmodule.h +++ b/nestkernel/nestmodule.h @@ -441,6 +441,12 @@ class NestModule : public SLIModule void execute( SLIInterpreter* ) const; } disablestructuralplasticity_function; + class SetStdpEps_dFunction : public SLIFunction + { + public: + void execute( SLIInterpreter* ) const; + } setstdpeps_dfunction; + //@} }; From 8604e228c961a736ed0c575a109e47030cc16e4f Mon Sep 17 00:00:00 2001 From: Susanne Kunkel Date: Wed, 11 Apr 2018 09:53:34 +0200 Subject: [PATCH 4/5] Clean up for SetStdpEps - Remove unnecessary multiplications with 1.0 - Add checks and info output for SetStdpEps - Refer to issue #894 in comments --- models/stdp_dopa_connection.h | 6 +++--- nestkernel/archiving_node.cpp | 6 ++---- nestkernel/connection_manager.cpp | 30 ++++++++++++++++++++++++++++++ nestkernel/connection_manager.h | 8 +------- nestkernel/nestmodule.cpp | 2 ++ 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/models/stdp_dopa_connection.h b/models/stdp_dopa_connection.h index 63b53be7aa..9c07a88200 100644 --- a/models/stdp_dopa_connection.h +++ b/models/stdp_dopa_connection.h @@ -567,9 +567,9 @@ STDPDopaConnection< targetidentifierT >::send( Event& e, process_dopa_spikes_( dopa_spikes, t0, start->t_ + dendritic_delay, cp ); t0 = start->t_ + dendritic_delay; minus_dt = t_last_update_ - t0; - // only depression if pre- and postsyn. spike occur at the same time - if ( t_spike - start->t_ > 1.0 - * kernel().connection_manager.get_stdp_eps() ) + // faciltate only in case of post- after presyn. spike + // skip facilitation if pre- and postsyn. spike occur at the same time + if ( t_spike - start->t_ > kernel().connection_manager.get_stdp_eps() ) { facilitate_( Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/nestkernel/archiving_node.cpp b/nestkernel/archiving_node.cpp index 951bfc1605..107ea73698 100644 --- a/nestkernel/archiving_node.cpp +++ b/nestkernel/archiving_node.cpp @@ -109,8 +109,7 @@ nest::Archiving_Node::get_K_value( double t ) int i = history_.size() - 1; while ( i >= 0 ) { - if ( t - history_[ i ].t_ > 1.0 - * kernel().connection_manager.get_stdp_eps() ) + if ( t - history_[ i ].t_ > kernel().connection_manager.get_stdp_eps() ) { return ( history_[ i ].Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_inv_ ) ); @@ -136,8 +135,7 @@ nest::Archiving_Node::get_K_values( double t, int i = history_.size() - 1; while ( i >= 0 ) { - if ( t - history_[ i ].t_ > 1.0 - * kernel().connection_manager.get_stdp_eps() ) + if ( t - history_[ i ].t_ > kernel().connection_manager.get_stdp_eps() ) { triplet_K_value = ( history_[ i ].triplet_Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_triplet_inv_ ) ); diff --git a/nestkernel/connection_manager.cpp b/nestkernel/connection_manager.cpp index 7d942a84ef..796dc78df1 100644 --- a/nestkernel/connection_manager.cpp +++ b/nestkernel/connection_manager.cpp @@ -28,6 +28,8 @@ // C++ includes: #include #include +#include +#include #include #include @@ -1451,3 +1453,31 @@ nest::ConnectionManager::get_targets( const std::vector< index >& sources, } } } + +void +nest::ConnectionManager::set_stdp_eps( const double stdp_eps ) +{ + if ( not( stdp_eps < Time::get_resolution().get_ms() ) ) + { + throw KernelException( + "The epsilon used for spike-time comparison in STDP must be less " + "than the simulation resolution." ); + } + else if ( stdp_eps < 0 ) + { + throw KernelException( + "The epsilon used for spike-time comparison in STDP must not be " + "negative." ); + } + else + { + stdp_eps_ = stdp_eps; + + std::ostringstream os; + os << "Epsilon for spike-time comparison in STDP was set to " + << std::setprecision( std::numeric_limits< long double >::digits10 ) + << stdp_eps_ << "."; + + LOG( M_INFO, "ConnectionManager::set_stdp_eps", os.str() ); + } +} diff --git a/nestkernel/connection_manager.h b/nestkernel/connection_manager.h index 256c6f7e1c..ed48d035aa 100644 --- a/nestkernel/connection_manager.h +++ b/nestkernel/connection_manager.h @@ -425,7 +425,7 @@ class ConnectionManager : public ManagerInterface double large_connector_growth_factor_; //! Maximum distance between (double) spike times in STDP that is - //! still considered 0 + //! still considered 0. See issue #894 double stdp_eps_; }; @@ -471,12 +471,6 @@ ConnectionManager::get_stdp_eps() const return stdp_eps_; } -inline void -ConnectionManager::set_stdp_eps( const double stdp_eps ) -{ - stdp_eps_ = stdp_eps; -} - } // namespace nest #endif /* CONNECTION_MANAGER_H */ diff --git a/nestkernel/nestmodule.cpp b/nestkernel/nestmodule.cpp index b1a2f99d69..deb8b6b6ba 100644 --- a/nestkernel/nestmodule.cpp +++ b/nestkernel/nestmodule.cpp @@ -1704,6 +1704,8 @@ NestModule::DisableStructuralPlasticity_Function::execute( * Spike times in STDP synapses are currently represented as double * values. The epsilon defines the maximum distance between spike * times that is still considered 0. + * + * Note: See issue #894 */ void NestModule::SetStdpEps_dFunction::execute( SLIInterpreter* i ) const From 85fdbea9809c074cbe27567b351903968c2a77c8 Mon Sep 17 00:00:00 2001 From: Susanne Kunkel Date: Wed, 11 Apr 2018 11:33:15 +0200 Subject: [PATCH 5/5] Remove unnecessary includes and fix typo --- models/stdp_dopa_connection.h | 2 +- models/stdp_pl_connection_hom.h | 2 -- nestkernel/archiving_node.cpp | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/models/stdp_dopa_connection.h b/models/stdp_dopa_connection.h index 9c07a88200..763c4a9f9c 100644 --- a/models/stdp_dopa_connection.h +++ b/models/stdp_dopa_connection.h @@ -567,7 +567,7 @@ STDPDopaConnection< targetidentifierT >::send( Event& e, process_dopa_spikes_( dopa_spikes, t0, start->t_ + dendritic_delay, cp ); t0 = start->t_ + dendritic_delay; minus_dt = t_last_update_ - t0; - // faciltate only in case of post- after presyn. spike + // facilitate only in case of post- after presyn. spike // skip facilitation if pre- and postsyn. spike occur at the same time if ( t_spike - start->t_ > kernel().connection_manager.get_stdp_eps() ) { diff --git a/models/stdp_pl_connection_hom.h b/models/stdp_pl_connection_hom.h index 1072466544..aabc2026ce 100644 --- a/models/stdp_pl_connection_hom.h +++ b/models/stdp_pl_connection_hom.h @@ -58,8 +58,6 @@ // C++ includes: #include -#include -#include // Includes from nestkernel: #include "connection.h" diff --git a/nestkernel/archiving_node.cpp b/nestkernel/archiving_node.cpp index 107ea73698..b1c3a0fbd4 100644 --- a/nestkernel/archiving_node.cpp +++ b/nestkernel/archiving_node.cpp @@ -29,10 +29,6 @@ #include "archiving_node.h" -// C++ includes: -#include -#include - // Includes from nestkernel: #include "kernel_manager.h"