void nest::iaf_psc_exp_canon::emit_spike_(Time const &origin, long_t const lag, double_t const t0, double_t const dt) { // we know that the potential is subthreshold at t0, super at t0+dt // compute spike time relative to beginning of step double_t const spike_offset = V_.h_ms_ - (t0+thresh_find_(dt)); set_spiketime(Time::step(origin.get_steps() + lag + 1)); S_.last_spike_offset_ = spike_offset; // reset neuron and make it refractory S_.y2_ = P_.U_reset_; S_.is_refractory_ = true; // send spike SpikeEvent se; se.set_offset(S_.last_spike_offset_); network()->send(*this, se, lag); return; }
void nest::iaf_psc_alpha_canon::emit_spike_( Time const& origin, const long_t lag, const double_t t0, const double_t dt ) { // we know that the potential is subthreshold at t0, super at t0+dt // compute spike time relative to beginning of step S_.last_spike_step_ = origin.get_steps() + lag + 1; S_.last_spike_offset_ = V_.h_ms_ - ( t0 + thresh_find_( dt ) ); // reset neuron and make it refractory S_.y3_ = P_.U_reset_; S_.is_refractory_ = true; // send spike set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); kernel().event_delivery_manager.send( *this, se, lag ); return; }
void nest::iaf_psc_alpha_presc::update( Time const& origin, const long_t from, const long_t to ) { assert( to >= 0 ); assert( static_cast< delay >( from ) < kernel().connection_manager.get_min_delay() ); assert( from < to ); /* Neurons may have been initialized to superthreshold potentials. We need to check for this here and issue spikes at the beginning of the interval. */ if ( S_.y3_ >= P_.U_th_ ) { S_.last_spike_step_ = origin.get_steps() + from + 1; S_.last_spike_offset_ = V_.h_ms_ * ( 1 - std::numeric_limits< double_t >::epsilon() ); // reset neuron and make it refractory S_.y3_ = P_.U_reset_; S_.r_ = V_.refractory_steps_; // send spike set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); kernel().event_delivery_manager.send( *this, se, from ); } for ( long_t lag = from; lag < to; ++lag ) { // time at start of update step const long_t T = origin.get_steps() + lag; // save state at beginning of interval for spike-time interpolation V_.y0_before_ = S_.y0_; V_.y1_before_ = S_.y1_; V_.y2_before_ = S_.y2_; V_.y3_before_ = S_.y3_; /* obtain input to y3_ We need to collect this value even while the neuron is refractory, since we need to clear any spikes that have come in from the ring buffer. */ const double_t dy3 = B_.spike_y3_.get_value( lag ); if ( S_.r_ == 0 ) { // neuron is not refractory S_.y3_ = V_.P30_ * ( P_.I_e_ + S_.y0_ ) + V_.P31_ * S_.y1_ + V_.P32_ * S_.y2_ + V_.expm1_tau_m_ * S_.y3_ + S_.y3_; S_.y3_ += dy3; // add input // enforce lower bound S_.y3_ = ( S_.y3_ < P_.U_min_ ? P_.U_min_ : S_.y3_ ); } else if ( S_.r_ == 1 ) { // neuron returns from refractoriness during interval S_.r_ = 0; // Iterate third component (membrane pot) from end of // refractory period to end of interval. As first-order // approximation, add a proportion of the effect of synaptic // input during the interval to membrane pot. The proportion // is given by the part of the interval after the end of the // refractory period. S_.y3_ = P_.U_reset_ + // try fix 070623, md update_y3_delta_() + dy3 - dy3 * ( 1 - S_.last_spike_offset_ / V_.h_ms_ ); // enforce lower bound S_.y3_ = ( S_.y3_ < P_.U_min_ ? P_.U_min_ : S_.y3_ ); } else { // neuron is refractory // y3_ remains unchanged at 0.0 --S_.r_; } // update synaptic currents S_.y2_ = V_.expm1_tau_syn_ * V_.h_ms_ * S_.y1_ + V_.expm1_tau_syn_ * S_.y2_ + V_.h_ms_ * S_.y1_ + S_.y2_; S_.y1_ = V_.expm1_tau_syn_ * S_.y1_ + S_.y1_; // add synaptic inputs from the ring buffer // this must happen BEFORE threshold-crossing interpolation, // since synaptic inputs occured during the interval S_.y1_ += B_.spike_y1_.get_value( lag ); S_.y2_ += B_.spike_y2_.get_value( lag ); // neuron spikes if ( S_.y3_ >= P_.U_th_ ) { // compute spike time S_.last_spike_step_ = T + 1; // The time for the threshpassing S_.last_spike_offset_ = V_.h_ms_ - thresh_find_( V_.h_ms_ ); // reset AFTER spike-time interpolation S_.y3_ = P_.U_reset_; S_.r_ = V_.refractory_steps_; // sent event set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); kernel().event_delivery_manager.send( *this, se, lag ); } // Set new input current. The current change occurs at the // end of the interval and thus must come AFTER the threshold- // crossing interpolation S_.y0_ = B_.currents_.get_value( lag ); // logging B_.logger_.record_data( origin.get_steps() + lag ); } // from lag = from ... }