void nest::pif_psc_delta_canon_cvv::emit_spike_(Time const &origin, const long_t lag,
					    const double_t offset_U) 
{
  assert(S_.U_ >= P_.U_th_);  // ensure we are superthreshold
 
  // compute time since threhold crossing
  double_t dt = P_.c_m_ * (S_.U_ - P_.U_th_) / P_.I_e_;

  // set stamp and offset for spike
  set_spiketime(Time::step(origin.get_steps() + lag + 1));
  S_.last_spike_offset_ = offset_U + dt;

  // reset neuron and make it refractory
  // if we are in emit_spike, the crossing was due to DC input, so threshold was exactly reached
  S_.U_t_spike_plus_ = P_.U_th_;
  S_.U_ = 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_delta_canon::emit_spike_( Time const& origin,
  const long lag,
  const double offset_U )
{
  assert( S_.U_ >= P_.U_th_ ); // ensure we are superthreshold

  // 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_ ) );

  // set stamp and offset for spike
  S_.last_spike_step_ = origin.get_steps() + lag + 1;
  S_.last_spike_offset_ = offset_U + dt;

  // reset neuron and make it refractory
  S_.U_ = 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;
}
Exemple #3
0
void
ht_neuron::update( Time const& origin, const long_t from, const long_t to )
{
  assert( to >= 0 && ( delay ) from < Scheduler::get_min_delay() );
  assert( from < to );

  for ( long_t lag = from; lag < to; ++lag )
  {
    double tt = 0.0; // it's all relative!

    // adaptive step integration
    while ( tt < B_.step_ )
    {
      const int status = gsl_odeiv_evolve_apply( B_.e_,
        B_.c_,
        B_.s_,
        &B_.sys_,             // system of ODE
        &tt,                  // from t...
        B_.step_,             // ...to t=t+h
        &B_.IntegrationStep_, // integration window (written on!)
        S_.y_ );              // neuron state

      if ( status != GSL_SUCCESS )
        throw GSLSolverFailure( get_name(), status );
    }

    // Deactivate potassium current after spike time have expired
    if ( S_.r_potassium_ && --S_.r_potassium_ == 0 )
      S_.g_spike_ = false; // Deactivate potassium current.

    // Add new spikes to node state array
    for ( size_t i = 0; i < B_.spike_inputs_.size(); ++i )
      S_.y_[ 2 + 2 * i ] += V_.cond_steps_[ i ] * B_.spike_inputs_[ i ].get_value( lag );

    // A spike is generated when the membrane potential (V) exceeds
    // the threshold (Theta).
    if ( !S_.g_spike_ && S_.y_[ State_::VM ] >= S_.y_[ State_::THETA ] )
    {
      // Set V and Theta to the sodium reversal potential.
      S_.y_[ State_::VM ] = P_.E_Na;
      S_.y_[ State_::THETA ] = P_.E_Na;

      // Activate fast potassium current. Drives the
      // membrane potential towards the potassium reversal
      // potential (activate only if duration is non-zero).
      S_.g_spike_ = V_.PotassiumRefractoryCounts_ > 0;
      S_.r_potassium_ = V_.PotassiumRefractoryCounts_;

      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

      SpikeEvent se;
      network()->send( *this, se, lag );
    }

    // set new input current
    B_.I_stim_ = B_.currents_.get_value( lag );

    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
nest::amat2_psc_exp::update( Time const& origin, const long_t from, const long_t to )
{
  assert( to >= 0 && ( delay ) from < kernel().connection_builder_manager.get_min_delay() );
  assert( from < to );

  // evolve from timestep 'from' to timestep 'to' with steps of h each
  for ( long_t lag = from; lag < to; ++lag )
  {

    // evolve voltage dependency (6,7)
    S_.V_th_v_ = ( P_.I_e_ + S_.i_0_ ) * V_.P70_ + S_.i_syn_ex_ * V_.P71_ + S_.i_syn_in_ * V_.P72_
      + S_.V_m_ * V_.P73_ + S_.V_th_dv_ * V_.P76_ + S_.V_th_v_ * V_.P77_;

    S_.V_th_dv_ = ( P_.I_e_ + S_.i_0_ ) * V_.P60_ + S_.i_syn_ex_ * V_.P61_ + S_.i_syn_in_ * V_.P62_
      + S_.V_m_ * V_.P63_ + S_.V_th_dv_ * V_.P66_;


    // evolve membrane potential (3)
    S_.V_m_ = ( P_.I_e_ + S_.i_0_ ) * V_.P30_ + S_.i_syn_ex_ * V_.P31_ + S_.i_syn_in_ * V_.P32_
      + S_.V_m_ * V_.P33_;


    // evolve adaptive threshold (4,5)
    S_.V_th_1_ *= V_.P44_;
    S_.V_th_2_ *= V_.P55_;

    // exponential decaying PSCs (1,2)
    S_.i_syn_ex_ *= V_.P11_;
    S_.i_syn_in_ *= V_.P22_;
    S_.i_syn_ex_ += B_.spikes_ex_.get_value( lag ); // the spikes arriving at T+1 have an
    S_.i_syn_in_ += B_.spikes_in_.get_value( lag ); // the spikes arriving at T+1 have an


    if ( S_.r_ == 0 ) // neuron is allowed to fire
    {
      if ( S_.V_m_ >= P_.omega_ + S_.V_th_2_ + S_.V_th_1_ + S_.V_th_v_ ) // threshold crossing
      {
        S_.r_ = V_.RefractoryCountsTot_;

        // procedure for adaptive potential
        S_.V_th_1_ += P_.alpha_1_; // short time
        S_.V_th_2_ += P_.alpha_2_; // long time

        set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

        SpikeEvent se;
        kernel().event_delivery_manager.send( *this, se, lag );
      }
    }
    else
      --S_.r_; // neuron is totally refractory (cannot generate spikes)

    // set new input current
    S_.i_0_ = B_.currents_.get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
/* ----------------------------------------------------------------
 * Update and spike handling functions
 * ---------------------------------------------------------------- */
void
nest::hh_cond_exp_traub::update( Time const& origin, const long_t from, const long_t to )
{
  assert( to >= 0 && ( delay ) from < kernel().connection_builder_manager.get_min_delay() );
  assert( from < to );

  for ( long_t lag = from; lag < to; ++lag )
  {

    double tt = 0.0; // it's all relative!
    V_.U_old_ = S_.y_[ State_::V_M ];


    // adaptive step integration
    while ( tt < B_.step_ )
    {
      const int status = gsl_odeiv_evolve_apply( B_.e_,
        B_.c_,
        B_.s_,
        &B_.sys_,             // system of ODE
        &tt,                  // from t...
        B_.step_,             // ...to t=t+h
        &B_.IntegrationStep_, // integration window (written on!)
        S_.y_ );              // neuron state

      if ( status != GSL_SUCCESS )
        throw GSLSolverFailure( get_name(), status );
    }

    S_.y_[ State_::G_EXC ] += B_.spike_exc_.get_value( lag );
    S_.y_[ State_::G_INH ] += B_.spike_inh_.get_value( lag );

    // sending spikes: crossing 0 mV, pseudo-refractoriness and local maximum...
    // refractory?
    if ( S_.r_ )
    {
      --S_.r_;
    }
    else
    {
      // (threshold   &&    maximum    )
      if ( S_.y_[ State_::V_M ] >= P_.V_T + 30. && V_.U_old_ > S_.y_[ State_::V_M ] )
      {
        S_.r_ = V_.RefractoryCounts_;

        set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

        SpikeEvent se;
        kernel().event_delivery_manager.send( *this, se, lag );
      }
    }

    // set new input current
    B_.I_stim_ = B_.currents_.get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
nest::izhikevich::update( Time const& origin, const long from, const long to )
{
  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  const double h = Time::get_resolution().get_ms();
  double v_old, u_old;

  for ( long lag = from; lag < to; ++lag )
  {
    // neuron is never refractory
    // use standard forward Euler numerics in this case
    if ( P_.consistent_integration_ )
    {
      v_old = S_.v_;
      u_old = S_.u_;
      S_.v_ += h * ( 0.04 * v_old * v_old + 5.0 * v_old + 140.0 - u_old + S_.I_
                     + P_.I_e_ )
        + B_.spikes_.get_value( lag );
      S_.u_ += h * P_.a_ * ( P_.b_ * v_old - u_old );
    }
    // use numerics published in Izhikevich (2003) in this case (not
    // recommended)
    else
    {
      double I_syn = B_.spikes_.get_value( lag );
      S_.v_ += h * 0.5 * ( 0.04 * S_.v_ * S_.v_ + 5.0 * S_.v_ + 140.0 - S_.u_
                           + S_.I_ + P_.I_e_ + I_syn );
      S_.v_ += h * 0.5 * ( 0.04 * S_.v_ * S_.v_ + 5.0 * S_.v_ + 140.0 - S_.u_
                           + S_.I_ + P_.I_e_ + I_syn );
      S_.u_ += h * P_.a_ * ( P_.b_ * S_.v_ - S_.u_ );
    }

    // lower bound of membrane potential
    S_.v_ = ( S_.v_ < P_.V_min_ ? P_.V_min_ : S_.v_ );

    // threshold crossing
    if ( S_.v_ >= P_.V_th_ )
    {
      S_.v_ = P_.c_;
      S_.u_ = S_.u_ + P_.d_;

      // compute spike time
      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    // set new input current
    S_.I_ = B_.currents_.get_value( lag );

    // voltage logging
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
nest::iaf_psc_delta::update( Time const& origin, const long_t from, const long_t to )
{
  assert( to >= 0 && ( delay ) from < Scheduler::get_min_delay() );
  assert( from < to );

  const double_t h = Time::get_resolution().get_ms();
  for ( long_t lag = from; lag < to; ++lag )
  {
    if ( S_.r_ == 0 )
    {
      // neuron not refractory
      S_.y3_ = V_.P30_ * ( S_.y0_ + P_.I_e_ ) + V_.P33_ * S_.y3_ + B_.spikes_.get_value( lag );

      // if we have accumulated spikes from refractory period,
      // add and reset accumulator
      if ( P_.with_refr_input_ && S_.refr_spikes_buffer_ != 0.0 )
      {
        S_.y3_ += S_.refr_spikes_buffer_;
        S_.refr_spikes_buffer_ = 0.0;
      }

      // lower bound of membrane potential
      S_.y3_ = ( S_.y3_ < P_.V_min_ ? P_.V_min_ : S_.y3_ );
    }
    else // neuron is absolute refractory
    {
      // read spikes from buffer and accumulate them, discounting
      // for decay until end of refractory period
      if ( P_.with_refr_input_ )
        S_.refr_spikes_buffer_ += B_.spikes_.get_value( lag ) * std::exp( -S_.r_ * h / P_.tau_m_ );
      else
        B_.spikes_.get_value( lag ); // clear buffer entry, ignore spike

      --S_.r_;
    }

    // threshold crossing
    if ( S_.y3_ >= P_.V_th_ )
    {
      S_.r_ = V_.RefractoryCounts_;
      S_.y3_ = P_.V_reset_;

      // EX: must compute spike time
      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

      SpikeEvent se;
      network()->send( *this, se, lag );
    }

    // set new input current
    S_.y0_ = B_.currents_.get_value( lag );

    // voltage logging
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
iaf_psc_alpha_multisynapse::update( Time const& origin, const long_t from, const long_t to )
{
  assert( to >= 0 && ( delay ) from < kernel().connection_builder_manager.get_min_delay() );
  assert( from < to );

  for ( long_t lag = from; lag < to; ++lag )
  {
    if ( S_.r_ == 0 )
    {
      // neuron not refractory
      S_.y3_ = V_.P30_ * ( S_.y0_ + P_.I_e_ ) + V_.P33_ * S_.y3_;

      S_.current_ = 0.0;
      for ( size_t i = 0; i < P_.num_of_receptors_; i++ )
      {
        S_.y3_ += V_.P31_syn_[ i ] * S_.y1_syn_[ i ] + V_.P32_syn_[ i ] * S_.y2_syn_[ i ];
        S_.current_ += S_.y2_syn_[ i ];
      }

      // lower bound of membrane potential
      S_.y3_ = ( S_.y3_ < P_.LowerBound_ ? P_.LowerBound_ : S_.y3_ );
    }
    else // neuron is absolute refractory
      --S_.r_;

    for ( size_t i = 0; i < P_.num_of_receptors_; i++ )
    {
      // alpha shape PSCs
      S_.y2_syn_[ i ] = V_.P21_syn_[ i ] * S_.y1_syn_[ i ] + V_.P22_syn_[ i ] * S_.y2_syn_[ i ];
      S_.y1_syn_[ i ] *= V_.P11_syn_[ i ];

      // collect spikes
      S_.y1_syn_[ i ] += V_.PSCInitialValues_[ i ] * B_.spikes_[ i ].get_value( lag );
    }

    if ( S_.y3_ >= P_.Theta_ ) // threshold crossing
    {
      S_.r_ = V_.RefractoryCounts_;
      S_.y3_ = P_.V_reset_;
      // A supra-threshold membrane potential should never be observable.
      // The reset at the time of threshold crossing enables accurate integration
      // independent of the computation step size, see [2,3] for details.

      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );
      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    // set new input current
    S_.y0_ = B_.currents_.get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
Exemple #9
0
void
nest::iaf_tum_2000::update( Time const& origin, const long from, const long to )
{
  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  // evolve from timestep 'from' to timestep 'to' with steps of h each
  for ( long lag = from; lag < to; ++lag )
  {

    if ( S_.r_abs_ == 0 ) // neuron not refractory, so evolve V
    {
      S_.V_m_ = S_.V_m_ * V_.P22_ + S_.i_syn_ex_ * V_.P21ex_
        + S_.i_syn_in_ * V_.P21in_ + ( P_.I_e_ + S_.i_0_ ) * V_.P20_;
    }
    else
    {
      --S_.r_abs_;
    } // neuron is absolute refractory

    // exponential decaying PSCs
    S_.i_syn_ex_ *= V_.P11ex_;
    S_.i_syn_in_ *= V_.P11in_;
    // the spikes arriving at T+1 have an immediate effect on the
    // state of the neuron
    S_.i_syn_ex_ += B_.spikes_ex_.get_value( lag );
    S_.i_syn_in_ += B_.spikes_in_.get_value( lag );

    if ( S_.r_tot_ == 0 )
    {
      if ( S_.V_m_ >= P_.Theta_ ) // threshold crossing
      {
        S_.r_abs_ = V_.RefractoryCountsAbs_;
        S_.r_tot_ = V_.RefractoryCountsTot_;
        S_.V_m_ = P_.V_reset_;

        set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

        SpikeEvent se;
        kernel().event_delivery_manager.send( *this, se, lag );
      }
    }
    else
    {
      --S_.r_tot_;
    } // neuron is totally refractory (cannot generate spikes)


    // set new input current
    S_.i_0_ = B_.currents_.get_value( lag );

    // logging
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
iaf_psc_exp_multisynapse::update( const Time& origin,
  const long from,
  const long to )
{
  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  // evolve from timestep 'from' to timestep 'to' with steps of h each
  for ( long lag = from; lag < to; ++lag )
  {
    if ( S_.refractory_steps_ == 0 ) // neuron not refractory, so evolve V
    {
      S_.V_m_ = S_.V_m_ * V_.P22_
        + ( P_.I_e_ + S_.I_const_ ) * V_.P20_; // not sure about this

      S_.current_ = 0.0;
      for ( size_t i = 0; i < P_.n_receptors_(); i++ )
      {
        S_.V_m_ += V_.P21_syn_[ i ] * S_.i_syn_[ i ];
        S_.current_ += S_.i_syn_[ i ]; // not sure about this
      }
    }
    else
    {
      --S_.refractory_steps_; // neuron is absolute refractory
    }
    for ( size_t i = 0; i < P_.n_receptors_(); i++ )
    {
      // exponential decaying PSCs
      S_.i_syn_[ i ] *= V_.P11_syn_[ i ];

      // collect spikes
      S_.i_syn_[ i ] += B_.spikes_[ i ].get_value( lag ); // not sure about this
    }

    if ( S_.V_m_ >= P_.Theta_ ) // threshold crossing
    {
      S_.refractory_steps_ = V_.RefractoryCounts_;
      S_.V_m_ = P_.V_reset_;

      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );
      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    // set new input current
    S_.I_const_ = B_.currents_.get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void nest::iaf_neuron_dif_alpha_stdp::update(Time const & origin, const long_t from, const long_t to)
{
  //bool ok=true;
  assert(to >= 0 && (delay) from < Scheduler::get_min_delay());
  assert(from < to);
  const double_t h = Time::get_resolution().get_ms();
  double_t v_old;
  double_t t=origin.get_ms();
  //std::cout<<S_.v_<<"\t";
  for ( long_t lag = from ; lag < to ; ++lag )
   {
      if ( S_.r_ == 0 ) // neuron not refractory
      {
	  v_old = S_.v_;
	  //S_.v_ +=h*( ((P_.E_L_-v_old)/P_.Tau_) + (P_.I_e_/P_.C_) + (S_.I_/P_.C_) )+B_.spikes_.get_value(lag);
	  S_.v_ +=h*( ((P_.E_L_-v_old)/P_.Tau_) + (P_.I_e_/P_.C_) + (S_.I_/P_.C_)) ;
	  //std::cout<<"fun S_.I_="<<S_.I_<<"\t"<<"delta_V="<<h*(S_.I_/P_.C_)<<"\n";
       }
       else // neuron is absolute refractory
	 --S_.r_;
  
    
	// threshold crossing
	//std::cout<<"index "<<this->get_gid()<<" to "<<to<<"\t"<<"lag "<<lag<<"\t"<<"h "<<h<<"\n";
	//if (emission_procedure(S_.v_))
	if (S_.v_ >= P_.V_th_)
	{
		stdp_procedure(t+h*lag);
		//std::cout<<"spike_time"<<"\n";
		//clean spike history
		S_.r_ = V_.RefractoryCounts_;
		S_.v_= P_.V_reset_;   
		set_spiketime(Time::step(origin.get_steps()+lag)); // change -1
		//std::cout<<"fun time spike from neuron "<<Time::step(origin.get_steps()+lag)<<"\n";// change -1
		SpikeEvent se;
		//se.set_weight(-1.0);
		network()->send(*this, se, lag);
 		clear_spike_history(t+h*lag);
		//ok=false;
	}
     
	//B_.spikes_.get_value(lag);// Need for clean buffer. It's necessary for working log-device wrapper.
	S_.I_=B_.currents_.get_value(lag);
	
	S_.I_ =S_.I_+get_sum_I(t+h*lag); // надо делать инач
	//std::cout<<"fun S_.I_="<<S_.I_<<"\n\n";
	// voltage logging
	B_.logger_.record_data(origin.get_steps()+lag);
	
      }
      //std::cout<<"\n"; // delete after use
}                           
void IzhikevichBranch::update(nest::Time const & origin, const nest::long_t from, const nest::long_t to) {

    assert(to >= 0 && (nest::delay) from < nest::Scheduler::get_min_delay());
    assert(from < to);

    nest::long_t current_steps = origin.get_steps();

    for (nest::long_t lag = from; lag < to; ++lag) {

        /***** Solve ODE over timestep *****/
        B_.current_regime->step_ode();

        /***** Transition handling *****/
        // Get multiplicity incoming events for the current lag and reset multiplicity of outgoing events
        refresh_events(lag);
        
        Transition_* transition;
        int simultaneous_transition_count = 0;
        double prev_t = origin.get_ms();
        while ((transition = B_.current_regime->transition(origin, lag))) {  // Check for a transition (i.e. the output of current_regime->transition is not NULL) and record it in the 'transition' variable.
            double t = transition->time_occurred(origin, lag);  // Get the exact time the transition occurred.
            if (t == prev_t)
                ++simultaneous_transition_count;
            else
                simultaneous_transition_count = 0;
            if (simultaneous_transition_count > MAX_SIMULTANEOUS_TRANSITIONS)
                throw ExceededMaximumSimultaneousTransitions("IzhikevichBranch", simultaneous_transition_count, t);
            bool discontinuous = transition->body(t) || (transition->get_target_regime() != B_.current_regime);
            B_.current_regime = transition->get_target_regime();
            B_.current_regime->set_triggers(t);
            if (discontinuous)
                B_.current_regime->init_solver();  // Reset the solver if the transition contains state assignments or switches to a new regime.
        }
        
        
        /***** Send output events for each event send port *****/
        // FIXME: Need to specify different output ports in a way that can be read by the receiving nodes
        // Output events        
        if (B_.num_spike_events) {
		    set_spiketime(nest::Time::step(origin.get_steps()+lag+1));
		    nest::SpikeEvent se;
		    se.set_multiplicity(B_.num_spike_events);
		    network()->send(*this, se, lag); 
        }

        /***** Get analog port values *****/
        B_.Isyn_value = B_.Isyn_analog_port.get_value(lag);

        /***** Record data *****/
        B_.logger_.record_data(current_steps + lag);
    }
}
void
nest::sli_neuron::update( Time const& origin,
  const long_t from,
  const long_t to )
{
  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );
  ( *state_ )[ names::t_origin ] = origin.get_steps();

  if ( state_->known( names::error ) )
  {
    std::string msg =
      String::compose( "Node %1 still has its error state set.", get_gid() );
    LOG( M_ERROR, "sli_neuron::update", msg.c_str() );
    LOG( M_ERROR,
      "sli_neuron::update",
      "Please check /calibrate and /update for errors" );
    kernel().simulation_manager.terminate();
    return;
  }

  for ( long_t lag = from; lag < to; ++lag )
  {
    ( *state_ )[ names::in_spikes ] =
      B_.in_spikes_.get_value( lag ); // in spikes arriving at right border
    ( *state_ )[ names::ex_spikes ] =
      B_.ex_spikes_.get_value( lag ); // ex spikes arriving at right border
    ( *state_ )[ names::currents ] = B_.currents_.get_value( lag );
    ( *state_ )[ names::t_lag ] = lag;

#pragma omp critical( sli_neuron )
    {
      execute_sli_protected( state_, names::update_node ); // call interpreter
    }

    bool spike_emission = false;
    if ( state_->known( names::spike ) )
      spike_emission = ( *state_ )[ names::spike ];

    // threshold crossing
    if ( spike_emission )
    {
      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );
      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
Exemple #14
0
void
nest::iaf_neuron::update( Time const& origin, const long_t from, const long_t to )
{
  assert( to >= 0 && ( delay ) from < Scheduler::get_min_delay() );
  assert( from < to );

  for ( long_t lag = from; lag < to; ++lag )
  {
    if ( S_.r_ == 0 )
    {
      // neuron not refractory
      S_.y3_ =
        V_.P30_ * ( S_.y0_ + P_.I_e_ ) + V_.P31_ * S_.y1_ + V_.P32_ * S_.y2_ + V_.P33_ * S_.y3_;
    }
    else // neuron is absolute refractory
      --S_.r_;

    // alpha shape PSCs
    S_.y2_ = V_.P21_ * S_.y1_ + V_.P22_ * S_.y2_;
    S_.y1_ *= V_.P11_;

    // Apply spikes delivered in this step: The spikes arriving at T+1 have an
    // immediate effect on the state of the neuron
    S_.y1_ += V_.PSCInitialValue_ * B_.spikes_.get_value( lag );

    // threshold crossing
    if ( S_.y3_ >= P_.Theta_ )
    {
      S_.r_ = V_.RefractoryCounts_;
      S_.y3_ = P_.V_reset_;

      // A supra-threshold membrane potential should never be observable.
      // The reset at the time of threshold crossing enables accurate integration
      // independent of the computation step size, see [2,3] for details.
      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );
      SpikeEvent se;
      network()->send( *this, se, lag );
    }

    // set new input current
    S_.y0_ = B_.currents_.get_value( lag );

    // voltage logging
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
Exemple #15
0
void nest::iaf_psc_exp_ps::emit_instant_spike_(const Time & origin, const long_t lag,
					       const double_t spike_offs) 
{
  assert( S_.y2_ >= P_.U_th_ );  // ensure we are superthreshold
  
  // set stamp and offset for spike
  set_spiketime(Time::step(origin.get_steps() + lag + 1));
  S_.last_spike_offset_ = spike_offs;
  
  // 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);
}
Exemple #16
0
void nest::iaf_chs_2007::update(const Time &origin, const long_t from, const long_t to)
{
  assert(to >= 0 && (delay) from < Scheduler::get_min_delay());
  assert(from < to);

  // evolve from timestep 'from' to timestep 'to' with steps of h each
  for ( long_t lag = from; lag < to; ++lag )
  {	
    S_.V_syn_ = S_.V_syn_*V_.P22_ + S_.i_syn_ex_*V_.P21ex_;

    // exponential decaying PSCs
    S_.i_syn_ex_ *= V_.P11ex_;

    // the spikes arriving at T+1 have an immediate effect on the state of the neuron
    S_.i_syn_ex_ += B_.spikes_ex_.get_value(lag);

    // exponentially decaying ahp
    S_.V_spike_ *= V_.P30_;

    double noise_term = P_.U_noise_ > 0.0 && !P_.noise_.empty() ? P_.U_noise_ * P_.noise_[S_.position_++] : 0.0;

    S_.V_m_ = S_.V_syn_ + S_.V_spike_ + noise_term;

                                                       
    if ( S_.V_m_ >= P_.U_th_ )  // threshold crossing
    {
    	S_.V_spike_ -= P_.U_reset_;
    	S_.V_m_ -= P_.U_reset_;


        
      set_spiketime(Time::step(origin.get_steps()+lag+1));
	    
      SpikeEvent se;
      network()->send(*this, se, lag);
    }

    // log state data
    B_.logger_.record_data(origin.get_steps() + lag);

  }  
}                           
void
parrot_neuron_ps::update( Time const& origin,
  long_t const from,
  long_t const to )
{
  assert( to >= 0 );
  assert( static_cast< delay >( from )
    < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  // at start of slice, tell input queue to prepare for delivery
  if ( from == 0 )
    B_.events_.prepare_delivery();

  for ( long_t lag = from; lag < to; ++lag )
  {
    // time at start of update step
    long_t const T = origin.get_steps() + lag;

    double_t ev_offset;
    double_t ev_multiplicity; // parrot stores multiplicity in weight
    bool end_of_refract;

    while ( B_.events_.get_next_spike(
      T, ev_offset, ev_multiplicity, end_of_refract ) )
    {
      const ulong_t multiplicity = static_cast< ulong_t >( ev_multiplicity );

      // send spike
      SpikeEvent se;
      se.set_multiplicity( multiplicity );
      se.set_offset( ev_offset );
      kernel().event_delivery_manager.send( *this, se, lag );

      for ( ulong_t i = 0; i < multiplicity; ++i )
      {
        set_spiketime( Time::step( T + 1 ), ev_offset );
      }
    }
  }
}
Exemple #18
0
void nest::iaf_psc_exp_ps::emit_spike_(const Time & 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
  const double_t spike_offset = V_.h_ms_ - (t0 + bisectioning_(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(spike_offset);
  network()->send(*this, se, lag);
}
Exemple #19
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;
}
Exemple #20
0
void nest::iaf_cond_delta::update(Time const & origin, const long_t from, const long_t to)
{
   
  assert(to >= 0 && (delay) from < Scheduler::get_min_delay());
  assert(from < to);

  for ( long_t lag = from ; lag < to ; ++lag )
  {
    
    if ( S_.r_ == 0 )
    {
      // neuron not refractory
      S_.V_m_ = V_.P_L_*S_.V_m_;
      S_.V_m_ += (P_.E_ex_ - S_.V_m_)*B_.spikes_ex_.get_value(lag) + (P_.E_in_ - S_.V_m_)*B_.spikes_in_.get_value(lag);

    }
    else // neuron is absolute refractory
    {
      B_.spikes_ex_.get_value(lag);  // clear buffer entry, ignore spike
      B_.spikes_in_.get_value(lag);  // clear buffer entry, ignore spike
      --S_.r_;
    }
   
    // threshold crossing
    if (S_.V_m_ >= P_.V_th_)
    {
      S_.r_ = V_.RefractoryCounts_;
      S_.V_m_ = P_.V_reset_;
        
      // EX: must compute spike time
      set_spiketime(Time::step(origin.get_steps()+lag+1));
        
      SpikeEvent se;
      network()->send(*this, se, lag);
    }

    // voltage logging
    B_.potentials_.record_data(origin.get_steps()+lag, S_.V_m_ + P_.E_L_);
  }
}
void
nest::iaf_psc_alpha_canon::emit_instant_spike_( Time const& origin,
  const long_t lag,
  const double_t spike_offs )
{
  assert( S_.y3_ >= P_.U_th_ ); // ensure we are superthreshold

  // set stamp and offset for spike
  S_.last_spike_step_ = origin.get_steps() + lag + 1;
  S_.last_spike_offset_ = spike_offs;

  // 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_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_cond_alpha_mc::update( Time const& origin,
  const long from,
  const long to )
{

  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  for ( long lag = from; lag < to; ++lag )
  {

    double t = 0.0;

    // numerical integration with adaptive step size control:
    // ------------------------------------------------------
    // gsl_odeiv_evolve_apply performs only a single numerical
    // integration step, starting from t and bounded by step;
    // the while-loop ensures integration over the whole simulation
    // step (0, step] if more than one integration step is needed due
    // to a small integration step size;
    // note that (t+IntegrationStep > step) leads to integration over
    // (t, step] and afterwards setting t to step, but it does not
    // enforce setting IntegrationStep to step-t; this is of advantage
    // for a consistent and efficient integration across subsequent
    // simulation intervals
    while ( t < B_.step_ )
    {
      const int status = gsl_odeiv_evolve_apply( B_.e_,
        B_.c_,
        B_.s_,
        &B_.sys_,             // system of ODE
        &t,                   // from t
        B_.step_,             // to t <= step
        &B_.IntegrationStep_, // integration step size
        S_.y_ );              // neuronal state
      if ( status != GSL_SUCCESS )
      {
        throw GSLSolverFailure( get_name(), status );
      }
    }

    // add incoming spikes at end of interval
    // exploit here that spike buffers are compartment for compartment,
    // alternating between excitatory and inhibitory
    for ( size_t n = 0; n < NCOMP; ++n )
    {
      S_.y_[ n * State_::STATE_VEC_COMPS + State_::DG_EXC ] +=
        B_.spikes_[ 2 * n ].get_value( lag ) * V_.PSConInit_E_[ n ];
      S_.y_[ n * State_::STATE_VEC_COMPS + State_::DG_INH ] +=
        B_.spikes_[ 2 * n + 1 ].get_value( lag ) * V_.PSConInit_I_[ n ];
    }

    // refractoriness and spiking
    // exploit here that plain offset enum value V_M indexes soma V_M
    if ( S_.r_ )
    { // neuron is absolute refractory
      --S_.r_;
      S_.y_[ State_::V_M ] = P_.V_reset;
    }
    else if ( S_.y_[ State_::V_M ] >= P_.V_th )
    { // neuron fires spike
      S_.r_ = V_.RefractoryCounts_;
      S_.y_[ State_::V_M ] = P_.V_reset;

      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    // set new input currents
    for ( size_t n = 0; n < NCOMP; ++n )
    {
      B_.I_stim_[ n ] = B_.currents_[ n ].get_value( lag );
    }

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
nest::iaf_cond_alpha::update( Time const& origin,
  const long from,
  const long to )
{

  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  for ( long lag = from; lag < to; ++lag )
  {

    double t = 0.0;

    // numerical integration with adaptive step size control:
    // ------------------------------------------------------
    // gsl_odeiv_evolve_apply performs only a single numerical
    // integration step, starting from t and bounded by step;
    // the while-loop ensures integration over the whole simulation
    // step (0, step] if more than one integration step is needed due
    // to a small integration step size;
    // note that (t+IntegrationStep > step) leads to integration over
    // (t, step] and afterwards setting t to step, but it does not
    // enforce setting IntegrationStep to step-t; this is of advantage
    // for a consistent and efficient integration across subsequent
    // simulation intervals
    while ( t < B_.step_ )
    {
      const int status = gsl_odeiv_evolve_apply( B_.e_,
        B_.c_,
        B_.s_,
        &B_.sys_,             // system of ODE
        &t,                   // from t
        B_.step_,             // to t <= step
        &B_.IntegrationStep_, // integration step size
        S_.y );               // neuronal state
      if ( status != GSL_SUCCESS )
      {
        throw GSLSolverFailure( get_name(), status );
      }
    }

    // refractoriness and spike generation
    if ( S_.r )
    { // neuron is absolute refractory
      --S_.r;
      S_.y[ State_::V_M ] = P_.V_reset; // clamp potential
    }
    else
      // neuron is not absolute refractory
      if ( S_.y[ State_::V_M ] >= P_.V_th )
    {
      S_.r = V_.RefractoryCounts;
      S_.y[ State_::V_M ] = P_.V_reset;

      // log spike with Archiving_Node
      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    // add incoming spikes
    S_.y[ State_::DG_EXC ] += B_.spike_exc_.get_value( lag ) * V_.PSConInit_E;
    S_.y[ State_::DG_INH ] += B_.spike_inh_.get_value( lag ) * V_.PSConInit_I;

    // set new input current
    B_.I_stim_ = B_.currents_.get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
nest::pp_psc_delta::update( Time const& origin, const long_t from, const long_t to )
{

    assert( to >= 0 && ( delay ) from < kernel().connection_builder_manager.get_min_delay() );
    assert( from < to );

    for ( long_t lag = from; lag < to; ++lag )
    {

        S_.y3_ = V_.P30_ * ( S_.y0_ + P_.I_e_ ) + V_.P33_ * S_.y3_ + B_.spikes_.get_value( lag );

        double_t q_temp_ = 0;
        for ( uint_t i = 0; i < S_.q_elems_.size(); i++ )
        {

            S_.q_elems_[ i ] = V_.Q33_[ i ] * S_.q_elems_[ i ];

            q_temp_ += S_.q_elems_[ i ];
        }

        S_.q_ = q_temp_;

        if ( S_.r_ == 0 )
        {
            // Neuron not refractory

            // Calculate instantaneous rate from transfer function:
            //     rate = c1 * y3' + c2 * exp(c3 * y3')
            // Adaptive threshold leads to effective potential V_eff instead of y3

            double_t V_eff;

            V_eff = S_.y3_ - S_.q_;

            double_t rate = ( P_.c_1_ * V_eff + P_.c_2_ * std::exp( P_.c_3_ * V_eff ) );

            if ( rate > 0.0 )
            {
                ulong_t n_spikes = 0;

                if ( P_.dead_time_ > 0.0 )
                {
                    // Draw random number and compare to prob to have a spike
                    if ( V_.rng_->drand() <= -numerics::expm1( -rate * V_.h_ * 1e-3 ) )
                    {
                        n_spikes = 1;
                    }
                }
                else
                {
                    // Draw Poisson random number of spikes
                    V_.poisson_dev_.set_lambda( rate * V_.h_ * 1e-3 );
                    n_spikes = V_.poisson_dev_.ldev( V_.rng_ );
                }

                if ( n_spikes > 0 ) // Is there a spike? Then set the new dead time.
                {
                    // Set dead time interval according to paramters
                    if ( P_.dead_time_random_ )
                    {
                        S_.r_ = Time( Time::ms( V_.gamma_dev_( V_.rng_ ) / V_.dt_rate_ ) ).get_steps();
                    }
                    else
                        S_.r_ = V_.DeadTimeCounts_;


                    for ( uint_t i = 0; i < S_.q_elems_.size(); i++ )
                    {
                        S_.q_elems_[ i ] += P_.q_sfa_[ i ] * n_spikes;
                    }


                    // And send the spike event
                    SpikeEvent se;
                    se.set_multiplicity( n_spikes );
                    kernel().event_delivery_manager.send( *this, se, lag );

                    // set spike time for STDP to work,
                    // see https://github.com/nest/nest-simulator/issues/77
                    for ( uint_t i = 0; i < n_spikes; i++ )
                    {
                        set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );
                    }

                    // Reset the potential if applicable
                    if ( P_.with_reset_ )
                    {
                        S_.y3_ = 0.0;
                    }
                } // S_.y3_ = P_.V_reset_;
            }   // if (rate > 0.0)
        }
        else // Neuron is within dead time
        {
            --S_.r_;
        }

        // Set new input current
        S_.y0_ = B_.currents_.get_value( lag );

        // Voltage logging
        B_.logger_.record_data( origin.get_steps() + lag );
    }
}
void nest::iaf_neuron_dif_alpha::update(Time const & origin, const long_t from, const long_t to)
{
  //bool ok=true;
  assert(to >= 0 && (delay) from < Scheduler::get_min_delay());
  assert(from < to);
  const double_t h = Time::get_resolution().get_ms();
  
  DictionaryDatum *d = new DictionaryDatum(new Dictionary);
  //behav_learning_loc->get((*d));
  double_t v_old;
  get_status_user((*d));
  //get_status((*d));
  double_t t=origin.get_ms();
  bool trig_seal_;
  bool trig_learn_oper_;
  updateValue<bool>((*d), names::trig_seal,trig_seal_);// d->trig_seal_
  updateValue<bool>((*d), names::trig_learn_oper,trig_learn_oper_);
  if (trig_seal_)
  {
    //*std::cout<<"trig_seal\n";
    //std::cout<<"grad "<<"\n";
    trig_seal_=0;
    def<bool>((*d), names::trig_seal, trig_seal_);
    behav_learning_loc->reset_iterator_desired();
    behav_learning_loc->set((*d));
    clear_spike_history();
    S_.I_=0;
  }
  if (trig_learn_oper_)
  {
    //std::cout<<"learn"<<"\n";
    //std::vector<double > v_learn_exam=v_learn_set_desired[P_.number_prim_];
    //std::cout<<v_learn_exam.size()<<"\n";
    //std::cout<<"l I current="<<(P_.I_e_/P_.C_) + (S_.I_/P_.C_)<<"\n";
    for ( long_t lag = from ; lag < to ; ++lag )
    {
	if ( S_.r_ == 0 ) // neuron not refractory
	{
	  v_old = S_.v_;
	  //S_.v_ +=h*( ((P_.E_L_-v_old)/P_.Tau_) + (P_.I_e_/P_.C_) + (S_.I_/P_.C_) )+B_.spikes_.get_value(lag);
	  S_.v_ +=h*( ((P_.E_L_-v_old)/P_.Tau_) + (P_.I_e_/P_.C_) + (S_.I_/P_.C_) );
	  //std::cout<<"learn S_.I_="<<S_.I_<<"\t"<<"S_.v_="<<S_.v_<<"\n";
	}
	else // neuron is absolute refractory
	  --S_.r_;
  
    
	
	//*std::cout<<"index "<<this->get_gid()<<" to "<<to<<"\t"<<"lag "<<lag<<"\t"<<"h "<<h<<"\t time"<<t+h*lag<<"\t"<<" S_.I_="<<S_.I_<<"\n";
	//behav_learning_loc->get_learning_vector(P_.number_prim_)
	//calculate currents
	//add value to t_parametrs
	def<double>((*d), names::time,t+h*lag);// t+h*lag->d
	//std::cout<<"S_.v_="<<S_.v_<<"\t";
	//std::cout<<"norm="<<normalization(S_.v_)<<"\t";
	def<double>((*d), names::potential,S_.v_);
	//std::cout<<"op"<<"\n";
	std::vector<double > currents;	
	set_learning_variables((*d),t+h*lag,currents);
	//std::cout<<"opop"<<"\n";
	
	if (behav_learning_loc->learn(behav_loc,(*d),currents))
	{
		//*std::cout<<"spike_time"<<"\n";
		//clean spike history
		S_.r_ = V_.RefractoryCounts_;
		S_.v_= P_.E_L_;   
		set_spiketime(Time::step(origin.get_steps()+lag));
		//std::cout<<"learn time spike from neuron "<<Time::step(origin.get_steps()+lag)<<"\n";
		SpikeEvent se;
		//se.set_weight(-1.0);
		network()->send(*this, se, lag);
		//clear_spike_history();
		//ok=false;
	}
	else if (S_.v_ >= P_.V_th_)
	{
		//std::cout<<"spike_time"<<"\n";
		//clean spike history
		S_.r_ = V_.RefractoryCounts_;
		S_.v_= P_.E_L_;   
		set_spiketime(Time::step(origin.get_steps()+lag)); // change -1
		SpikeEvent se;
		//se.set_weight(-1.0);
		network()->send(*this, se, lag);
 		//clear_spike_history();
		//ok=false;
	}
	//B_.spikes_.get_value(lag);// Need for clean buffer. It's necessary for working log-device wrapper.
	S_.I_=B_.currents_.get_value(lag);
	S_.I_ =S_.I_+get_sum_I(t+h*lag); //two time calclulate
	//std::cout<<"S_.I_="<<S_.I_<<"\n";;
	// voltage logging
	B_.logger_.record_data(origin.get_steps()+lag);
      }
      //std::cout<<"opop3"<<"\n";
  }
  else /*function mode */
  {
    //std::cout<<"function"<<"\n";
    //std::cout<<"I current="<<(P_.I_e_/P_.C_) + (S_.I_/P_.C_)<<"\t";
    for ( long_t lag = from ; lag < to ; ++lag )
    {
	if ( S_.r_ == 0 ) // neuron not refractory
	{
	  v_old = S_.v_;
	  //S_.v_ +=h*( ((P_.E_L_-v_old)/P_.Tau_) + (P_.I_e_/P_.C_) + (S_.I_/P_.C_) )+B_.spikes_.get_value(lag);
	  S_.v_ +=h*( ((P_.E_L_-v_old)/P_.Tau_) + (P_.I_e_/P_.C_) + (S_.I_/P_.C_) );
	  //std::cout<<"fun S_.I_="<<S_.I_<<"\t"<<"S_.v_="<<S_.v_<<"\n";
	  std::cout<<"fun S_.I_="<<S_.I_<<"\n";
	}
	else // neuron is absolute refractory
	  --S_.r_;
  
    
	// threshold crossing
	std::cout<<"index "<<this->get_gid()<<" to "<<to<<"\t"<<"lag "<<lag<<"\t"<<"h "<<h<<"\t";
	std::cout<<S_.v_<<"\t"<<"\n";
	//if (emission_procedure(S_.v_))
	if (S_.v_ >= P_.V_th_)
	{
		//std::cout<<"spike_time"<<"\n";
		//clean spike history
		S_.r_ = V_.RefractoryCounts_;
		S_.v_= P_.E_L_;   
		set_spiketime(Time::step(origin.get_steps()+lag)); // change -1
		//std::cout<<"fun time spike from neuron "<<Time::step(origin.get_steps()+lag)<<"\n";// change -1
		SpikeEvent se;
		//se.set_weight(-1.0);
		network()->send(*this, se, lag);
 		//clear_spike_history();
		//ok=false;
	}
     
	//B_.spikes_.get_value(lag);// Need for clean buffer. It's necessary for working log-device wrapper.
	S_.I_=B_.currents_.get_value(lag);
	
	S_.I_ =S_.I_+get_sum_I(t+h*lag); // надо делать инач
	//std::cout<<"fun S_.I_="<<S_.I_<<"\n";
	// voltage logging
	B_.logger_.record_data(origin.get_steps()+lag);
      }
      //std::cout<<"\n";
      /*function mode */
  }
  delete d;
}                           
void
nest::iaf_cond_exp::update( Time const& origin, const long_t from, const long_t to )
{

  assert( to >= 0 && ( delay ) from < Scheduler::get_min_delay() );
  assert( from < to );

  for ( long_t lag = from; lag < to; ++lag )
  {

    double t = 0.0;

    // numerical integration with adaptive step size control:
    // ------------------------------------------------------
    // gsl_odeiv_evolve_apply performs only a single numerical
    // integration step, starting from t and bounded by step;
    // the while-loop ensures integration over the whole simulation
    // step (0, step] if more than one integration step is needed due
    // to a small integration step size;
    // note that (t+IntegrationStep > step) leads to integration over
    // (t, step] and afterwards setting t to step, but it does not
    // enforce setting IntegrationStep to step-t; this is of advantage
    // for a consistent and efficient integration across subsequent
    // simulation intervals
    while ( t < B_.step_ )
    {
      const int status = gsl_odeiv_evolve_apply( B_.e_,
        B_.c_,
        B_.s_,
        &B_.sys_,             // system of ODE
        &t,                   // from t
        B_.step_,             // to t <= step
        &B_.IntegrationStep_, // integration step size
        S_.y_ );              // neuronal state

      if ( status != GSL_SUCCESS )
        throw GSLSolverFailure( get_name(), status );
    }

    S_.y_[ State_::G_EXC ] += B_.spike_exc_.get_value( lag );
    S_.y_[ State_::G_INH ] += B_.spike_inh_.get_value( lag );

    // absolute refractory period
    if ( S_.r_ )
    { // neuron is absolute refractory
      --S_.r_;
      S_.y_[ State_::V_M ] = P_.V_reset_;
    }
    else
      // neuron is not absolute refractory
      if ( S_.y_[ State_::V_M ] >= P_.V_th_ )
    {
      S_.r_ = V_.RefractoryCounts_;
      S_.y_[ State_::V_M ] = P_.V_reset_;

      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );

      SpikeEvent se;
      network()->send( *this, se, lag );
    }

    // set new input current
    B_.I_stim_ = B_.currents_.get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
void
iaf_psc_alpha::update( Time const& origin, const long from, const long to )
{
  assert(
    to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() );
  assert( from < to );

  for ( long lag = from; lag < to; ++lag )
  {
    if ( S_.r_ == 0 )
    {
      // neuron not refractory
      S_.y3_ = V_.P30_ * ( S_.y0_ + P_.I_e_ ) + V_.P31_ex_ * S_.y1_ex_
        + V_.P32_ex_ * S_.y2_ex_ + V_.P31_in_ * S_.y1_in_
        + V_.P32_in_ * S_.y2_in_ + V_.expm1_tau_m_ * S_.y3_ + S_.y3_;

      // lower bound of membrane potential
      S_.y3_ = ( S_.y3_ < P_.LowerBound_ ? P_.LowerBound_ : S_.y3_ );
    }
    else // neuron is absolute refractory
      --S_.r_;

    // alpha shape EPSCs
    S_.y2_ex_ = V_.P21_ex_ * S_.y1_ex_ + V_.P22_ex_ * S_.y2_ex_;
    S_.y1_ex_ *= V_.P11_ex_;

    // Apply spikes delivered in this step; spikes arriving at T+1 have
    // an immediate effect on the state of the neuron
    V_.weighted_spikes_ex_ = B_.ex_spikes_.get_value( lag );
    S_.y1_ex_ += V_.EPSCInitialValue_ * V_.weighted_spikes_ex_;

    // alpha shape EPSCs
    S_.y2_in_ = V_.P21_in_ * S_.y1_in_ + V_.P22_in_ * S_.y2_in_;
    S_.y1_in_ *= V_.P11_in_;

    // Apply spikes delivered in this step; spikes arriving at T+1 have
    // an immediate effect on the state of the neuron
    V_.weighted_spikes_in_ = B_.in_spikes_.get_value( lag );
    S_.y1_in_ += V_.IPSCInitialValue_ * V_.weighted_spikes_in_;

    // threshold crossing
    if ( S_.y3_ >= P_.Theta_ )
    {
      S_.r_ = V_.RefractoryCounts_;
      S_.y3_ = P_.V_reset_;
      // A supra-threshold membrane potential should never be observable.
      // The reset at the time of threshold crossing enables accurate
      // integration independent of the computation step size, see [2,3] for
      // details.

      set_spiketime( Time::step( origin.get_steps() + lag + 1 ) );
      SpikeEvent se;
      kernel().event_delivery_manager.send( *this, se, lag );
    }

    // set new input current
    S_.y0_ = B_.currents_.get_value( lag );

    // log state data
    B_.logger_.record_data( origin.get_steps() + lag );
  }
}
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 ...
}
Exemple #30
0
void nest::aeif_cond_exp::update(const Time &origin, const long_t from, const long_t to)
{
  assert ( to >= 0 && (delay) from < Scheduler::get_min_delay() );
  assert ( from < to );
  assert ( State_::V_M == 0 );

  for ( long_t lag = from; lag < to; ++lag )
  {
    double t = 0.0;

    if ( S_.r_ > 0 )
      --S_.r_;

    // numerical integration with adaptive step size control:
    // ------------------------------------------------------
    // gsl_odeiv_evolve_apply performs only a single numerical
    // integration step, starting from t and bounded by step;
    // the while-loop ensures integration over the whole simulation
    // step (0, step] if more than one integration step is needed due
    // to a small integration step size;
    // note that (t+IntegrationStep > step) leads to integration over
    // (t, step] and afterwards setting t to step, but it does not
    // enforce setting IntegrationStep to step-t
    while ( t < B_.step_ )
    {
      const int status = gsl_odeiv_evolve_apply(B_.e_, B_.c_, B_.s_, 
						&B_.sys_,             // system of ODE
						&t,                   // from t
						B_.step_,             // to t <= step
						&B_.IntegrationStep_, // integration step size
						S_.y_);               // neuronal state
      
      if ( status != GSL_SUCCESS )
        throw GSLSolverFailure(get_name(), status);

      // check for unreasonable values; we allow V_M to explode
      if ( S_.y_[State_::V_M] < -1e3 ||
	   S_.y_[State_::W  ] <    -1e6 || S_.y_[State_::W] > 1e6    )
	throw NumericalInstability(get_name());
      
      // spikes are handled inside the while-loop
      // due to spike-driven adaptation
      if ( S_.r_ > 0 )
	S_.y_[State_::V_M] = P_.V_reset_;
      else if ( S_.y_[State_::V_M] >= P_.V_peak_ )
	{
	  S_.y_[State_::V_M]  = P_.V_reset_;
	  S_.y_[State_::W]   += P_.b; // spike-driven adaptation
	  S_.r_               = V_.RefractoryCounts_;
	  
	  set_spiketime(Time::step(origin.get_steps() + lag + 1));
	  SpikeEvent se;
	  network()->send(*this, se, lag);
	}
    }  
    S_.y_[State_::G_EXC] += B_.spike_exc_.get_value(lag);
    S_.y_[State_::G_INH] += B_.spike_inh_.get_value(lag);
    
    // set new input current
    B_.I_stim_ = B_.currents_.get_value(lag);
    
    // log state data
    B_.logger_.record_data(origin.get_steps() + lag);
  }
}