Exemplo n.º 1
0
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 ...
}