/*
* stdp_izh_connection.cpp
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see .
*
*/
#include "stdp_izh_connection.h"
// C++ includes:
#include
#include
namespace nest
{
STDPIzhCommonProperties::STDPIzhCommonProperties()
: CommonSynapseProperties()
, LTP_(0.1)
, LTD_(-0.12)
, tau_LTP_(20.0)
, tau_LTD_(20.0)
, Wmax_(10.0)
, tau_syn_update_interval_(10000.)
, constant_additive_value_(0.01)
, reset_weight_change_(false)
{
}
void
STDPIzhCommonProperties::get_status( DictionaryDatum& d ) const
{
CommonSynapseProperties::get_status( d );
def< double >( d, "LTP", LTP_);
def< double >( d, "LTD", LTD_);
def< double >( d, "tau_LTP", tau_LTP_);
def< double >( d, "tau_LTD", tau_LTD_);
def< double >( d, "Wmax", Wmax_);
def< double >( d, "tau_syn_update_interval", tau_syn_update_interval_ );
def< double >( d, "constant_additive_value", constant_additive_value_ );
def< bool >( d, "reset_weight_change_after_update", reset_weight_change_ );
}
void
STDPIzhCommonProperties::set_status( const DictionaryDatum& d,
ConnectorModel& cm )
{
CommonSynapseProperties::set_status( d, cm );
updateValue< double >( d, "LTP", LTP_);
updateValue< double >( d, "LTD", LTD_);
updateValue< double >( d, "tau_LTP", tau_LTP_);
updateValue< double >( d, "tau_LTD", tau_LTD_);
updateValue< double >( d, "Wmax", Wmax_);
updateValue< double >( d, "tau_syn_update_interval", tau_syn_update_interval_ );
updateValue< double >( d, "constant_additive_value", constant_additive_value_ );
updateValue< bool >( d, "reset_weight_change_after_update", reset_weight_change_ );
}
/**
* ((Default Constructor below is ACTUALLY in drop_odd_spike_connection.h sample))
* Sets default values for all parameters. Needed by GenericConnectorModel.
*/
STDPIzhConnection::STDPIzhConnection()
: ConnectionBase()
, weight_(1.0)
, wdev_(0.0)
, t_lastspike_( 0.0 ) //added to this file although recommended to be in .h file per ref: https://nest.github.io/nest-simulator/model_conversion_5g
, t_last_update_(0.0)
, t_last_post_spike_(0.0)
{
pre_spikes_.clear();
//pre_spikes_.push_back(-std::numeric_limits::max());
pre_spikes_.push_back(-10000);
}
//! Also included in the same drop_odd_spike_connection.h example is a Default Destructor.
// ~DropOddSpikeConnection()
// {
// }
STDPIzhConnection::STDPIzhConnection( const STDPIzhConnection& rhs )
: ConnectionBase( rhs )
, weight_( rhs.weight_ )
, wdev_( rhs.wdev_ )
, t_lastspike_( rhs.t_lastspike_ ) //added to this file, although recommeded for .h file per ref: https://nest.github.io/nest-simulator/model_conversion_5g
, t_last_update_( rhs.t_last_update_ )
, t_last_post_spike_( rhs.t_last_post_spike_ )
{
pre_spikes_.clear();
pre_spikes_.push_back(-10000);
}
template < typename targetidentifierT >
void
//STDPIzhConnection::get_status( DictionaryDatum& d ) const
STDPIzhConnection< targetidentifierT >::get_status( DictionaryDatum& d ) const //changed above in this file although recommended to be in .h file per sample in ref: https://github.com/nest/nest-simulator/blob/master/examples/MyModule/drop_odd_spike_connection.h
{
ConnectionBase::get_status( d );
// def< double >( d, names::weight, weight_ );
def< double >( d, nest::names::weight, weight_ ); //changed above in this file although recommended to be in .h file per sample in ref: https://github.com/nest/nest-simulator/blob/master/examples/MyModule/drop_odd_spike_connection.h
def< double >( d, "wdev", wdev_);
}
template < typename targetidentifierT > //added to this file although recommended to be in .h file per sample in ref: https://github.com/nest/nest-simulator/blob/master/examples/MyModule/drop_odd_spike_connection.h
void
//STDPIzhConnection::set_status( const DictionaryDatum& d, ConnectorModel& cm )
STDPIzhConnection< targetidentifierT >::set_status( const DictionaryDatum& d, nest::ConnectorModel& cm ) //changed above in this file although recommended to be in .h file per sample in ref: https://github.com/nest/nest-simulator/blob/master/examples/MyModule/drop_odd_spike_connection.h
{
ConnectionBase::set_status( d, cm );
// updateValue< double >( d, names::weight, weight_ );
updateValue< double >( d, nest::names::weight, weight_ ); //changed above in this file although recommended to be in .h file per sample in ref: https://github.com/nest/nest-simulator/blob/master/examples/MyModule/drop_odd_spike_connection.h
updateValue< double >( d, "wdev", wdev_);
}
template < typename targetidentifierT > //added to this file although recommended to be in .h file per sample in ref: https://github.com/nest/nest-simulator/blob/master/examples/MyModule/drop_odd_spike_connection.h
void
//STDPIzhConnection::time_driven_update( const thread tid, const double t_trig, const CommonPropertiesType& cp )
STDPIzhConnection< targetidentifierT >::time_driven_update( const thread tid, const double t_trig, const CommonPropertiesType& cp ) //changed above in this file although recommended to be in .h file per sample in ref: https://github.com/nest/nest-simulator/blob/master/examples/MyModule/drop_odd_spike_connection.h
{
Node* target = get_target( tid );
const std::vector< double >& post_spikes_tmp = target->get_post_spikes();
std::vector< double > post_spikes ( post_spikes_tmp.size() );
std::copy(post_spikes_tmp.begin(), post_spikes_tmp.end(), post_spikes.begin());
index i = 1; // index to iterate over post_spikes
index j = 1; // index to iterate over pre_spikes_
// post_spikes[0] == t_last_update_
if ( std::abs( post_spikes[0] - t_last_update_ ) < kernel().connection_manager.get_stdp_eps() )
{
post_spikes.insert( post_spikes.begin(), t_last_post_spike_ );
}
// pre_spikes_[j] <= t_trig
for ( j = 1; j < pre_spikes_.size() && ( t_trig - pre_spikes_[j] ) > ( -1.0 * kernel().connection_manager.get_stdp_eps() ); ++j )
{
// post_spikes[i] < pre_spikes_[j]
while ( i < post_spikes.size() && ( pre_spikes_[j] - post_spikes[i] ) > kernel().connection_manager.get_stdp_eps() )
{
int dt = post_spikes[i] - pre_spikes_[j-1];
wdev_ += cp.LTP_ * std::exp( -dt / cp.tau_LTP_ );
++i;
}
// facilitation (also for t_pre_spike == t_post_spike)
// depression (also for t_pre_spike == t_post_spike)
int dt = pre_spikes_[j] - post_spikes[i-1] - 1;
wdev_ += cp.LTD_ * std::exp( -dt / cp.tau_LTD_ );
}
// process remaining postsynaptic spikes in this update interval if there are any
// post_spikes[i] < t_trig
while ( i < post_spikes.size() && ( t_trig - post_spikes[i] ) > kernel().connection_manager.get_stdp_eps() )
{
// facilitation
int dt = post_spikes[i] - pre_spikes_[j-1];
wdev_ += cp.LTP_ * std::exp( -dt / cp.tau_LTP_ );
++i;
}
if ( cp.tau_syn_update_interval_ != 0. )
wdev_ *= std::exp( -kernel().simulation_manager.get_syn_update_interval() / cp.tau_syn_update_interval_ );
weight_ += cp.constant_additive_value_ * (kernel().simulation_manager.get_syn_update_interval() / 1000.) + wdev_;
if (weight_ > cp.Wmax_)
weight_ = cp.Wmax_;
if (weight_ < 0)
weight_ = 0;
if ( cp.reset_weight_change_ )
wdev_ = 0.0;
// erase all processed presynaptic spikes except the last one
// due to axonal there might be other pre_spikes left that are relevant only in the next update
pre_spikes_.erase(pre_spikes_.begin(), pre_spikes_.begin() + (j-1) );
t_last_update_ = t_trig;
t_last_post_spike_ = post_spikes[post_spikes.size()-1];
}
} // of namespace nest