inline Polynomial<T, Structure>& Polynomial<T, Structure>::operator*=(const Polynomial<T, Structure>& other) { coefficient_list new_coefficients (deg() + other.deg() + 1, 0); for (size_type i = 0; i <= deg(); ++i) { for (size_type j = 0; j <= other.deg(); ++j) { new_coefficients[i + j] += m_coefficients[i] * other.m_coefficients[j]; } } m_coefficients = new_coefficients; remove_zeros(); return *this; }
bool nest::hh_psc_alpha_gap::update_( Time const& origin, const long from, const long to, const bool wfr_update ) { assert( to >= 0 && ( delay ) from < kernel().connection_manager.get_min_delay() ); assert( from < to ); bool done = true; const size_t interpolation_order = kernel().simulation_manager.get_wfr_interpolation_order(); const double wfr_tol = kernel().simulation_manager.get_wfr_tol(); // allocate memory to store the new interpolation coefficients // to be sent by gap event const size_t quantity = kernel().connection_manager.get_min_delay() * ( interpolation_order + 1 ); std::vector< double > new_coefficients( quantity, 0.0 ); // parameters needed for piecewise interpolation double y_i = 0.0, y_ip1 = 0.0, hf_i = 0.0, hf_ip1 = 0.0; double f_temp[ State_::STATE_VEC_SIZE ]; for ( long lag = from; lag < to; ++lag ) { // B_.lag is needed by hh_psc_alpha_gap_dynamics to // determine the current section B_.lag_ = lag; if ( wfr_update ) { y_i = S_.y_[ State_::V_M ]; if ( interpolation_order == 3 ) { hh_psc_alpha_gap_dynamics( 0, S_.y_, f_temp, reinterpret_cast< void* >( this ) ); hf_i = B_.step_ * f_temp[ State_::V_M ]; } } double t = 0.0; const double U_old = S_.y_[ State_::V_M ]; // 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 ); } if ( not wfr_update ) { S_.y_[ State_::DI_EXC ] += B_.spike_exc_.get_value( lag ) * V_.PSCurrInit_E_; S_.y_[ State_::DI_INH ] += B_.spike_inh_.get_value( lag ) * V_.PSCurrInit_I_; // sending spikes: crossing 0 mV, pseudo-refractoriness and local // maximum... // refractory? if ( S_.r_ > 0 ) --S_.r_; else // ( threshold && maximum ) if ( S_.y_[ State_::V_M ] >= 0 && 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 ); } // log state data B_.logger_.record_data( origin.get_steps() + lag ); // set new input current B_.I_stim_ = B_.currents_.get_value( lag ); } else // if(wfr_update) { S_.y_[ State_::DI_EXC ] += B_.spike_exc_.get_value_wfr_update( lag ) * V_.PSCurrInit_E_; S_.y_[ State_::DI_INH ] += B_.spike_inh_.get_value_wfr_update( lag ) * V_.PSCurrInit_I_; // check deviation from last iteration done = ( fabs( S_.y_[ State_::V_M ] - B_.last_y_values[ lag ] ) <= wfr_tol ) && done; B_.last_y_values[ lag ] = S_.y_[ State_::V_M ]; // update different interpolations // constant term is the same for each interpolation order new_coefficients[ lag * ( interpolation_order + 1 ) + 0 ] = y_i; switch ( interpolation_order ) { case 0: break; case 1: y_ip1 = S_.y_[ State_::V_M ]; new_coefficients[ lag * ( interpolation_order + 1 ) + 1 ] = y_ip1 - y_i; break; case 3: y_ip1 = S_.y_[ State_::V_M ]; hh_psc_alpha_gap_dynamics( B_.step_, S_.y_, f_temp, reinterpret_cast< void* >( this ) ); hf_ip1 = B_.step_ * f_temp[ State_::V_M ]; new_coefficients[ lag * ( interpolation_order + 1 ) + 1 ] = hf_i; new_coefficients[ lag * ( interpolation_order + 1 ) + 2 ] = -3 * y_i + 3 * y_ip1 - 2 * hf_i - hf_ip1; new_coefficients[ lag * ( interpolation_order + 1 ) + 3 ] = 2 * y_i - 2 * y_ip1 + hf_i + hf_ip1; break; default: throw BadProperty( "Interpolation order must be 0, 1, or 3." ); } } } // end for-loop // if !wfr_update perform constant extrapolation and reset last_y_values if ( not wfr_update ) { for ( long temp = from; temp < to; ++temp ) new_coefficients[ temp * ( interpolation_order + 1 ) + 0 ] = S_.y_[ State_::V_M ]; B_.last_y_values.clear(); B_.last_y_values.resize( kernel().connection_manager.get_min_delay(), 0.0 ); } // Send gap-event GapJunctionEvent ge; ge.set_coeffarray( new_coefficients ); kernel().event_delivery_manager.send_secondary( *this, ge ); // Reset variables B_.sumj_g_ij_ = 0.0; B_.interpolation_coefficients.clear(); B_.interpolation_coefficients.resize( quantity, 0.0 ); return done; }