예제 #1
0
// finds threshpassing
inline
nest::double_t nest::iaf_psc_alpha_canon::thresh_find_(double_t const dt) const
{
  switch (P_.Interpol_) {
    case NO_INTERPOL: return dt;
    case LINEAR     : return thresh_find1_(dt);
    case QUADRATIC  : return thresh_find2_(dt);
    case CUBIC      : return thresh_find3_(dt);
    default: 
      throw BadProperty("Invalid interpolation order in iaf_psc_alpha_canon.");
  }
  return 0;
}
예제 #2
0
// finds threshpassing
inline
nest::double_t nest::iaf_psc_alpha_presc::thresh_find_(double_t const dt) const
{
  switch (P_.Interpol_) {
    case NO_INTERPOL: return dt;
    case LINEAR     : return thresh_find1_(dt);
    case QUADRATIC  : return thresh_find2_(dt);
    case CUBIC      : return thresh_find3_(dt);
    default: 
      network()->message(SLIInterpreter::M_ERROR, "iaf_psc_alpha_presc::thresh_find_()",
			 "Invalid interpolation---Internal model error.");
      throw BadProperty();
  }
  return 0;
}
nest::double_t
nest::iaf_psc_alpha_canon::thresh_find3_( double_t const dt ) const
{
  const double_t h_ms = dt;
  const double_t h_sq = h_ms * h_ms;
  const double_t h_cb = h_sq * h_ms;

  const double_t deriv_t1 = -V_.y3_before_ / P_.tau_m_
    + ( P_.I_e_ + V_.y0_before_ + V_.y2_before_ ) / P_.c_m_;
  const double_t deriv_t2 =
    -S_.y3_ / P_.tau_m_ + ( P_.I_e_ + S_.y0_ + S_.y2_ ) / P_.c_m_;

  const double_t w3_ = ( 2 * V_.y3_before_ / h_cb ) - ( 2 * S_.y3_ / h_cb )
    + ( deriv_t1 / h_sq ) + ( deriv_t2 / h_sq );
  const double_t w2_ = -( 3 * V_.y3_before_ / h_sq ) + ( 3 * S_.y3_ / h_sq )
    - ( 2 * deriv_t1 / h_ms ) - ( deriv_t2 / h_ms );
  const double_t w1_ = deriv_t1;
  const double_t w0_ = V_.y3_before_;

  // normal form :    x^3 + r*x^2 + s*x + t with coefficients : r, s, t
  const double_t r = w2_ / w3_;
  const double_t s = w1_ / w3_;
  const double_t t = ( w0_ - P_.U_th_ ) / w3_;
  const double_t r_sq = r * r;

  // substitution y = x + r/3 :  y^3 + p*y + q == 0
  const double_t p = -r_sq / 3 + s;
  const double_t q = 2 * ( r_sq * r ) / 27 - r * s / 3 + t;

  // discriminante
  const double_t D = std::pow( ( p / 3 ), 3 ) + std::pow( ( q / 2 ), 2 );

  double_t tau1;
  double_t tau2;
  double_t tau3;

  if ( D < 0 )
  {
    const double_t roh = std::sqrt( -( p * p * p ) / 27 );
    const double_t phi = std::acos( -q / ( 2 * roh ) );
    const double_t a = 2 * std::pow( roh, ( 1.0 / 3.0 ) );
    tau1 = ( a * std::cos( phi / 3 ) ) - r / 3;
    tau2 = ( a * std::cos( phi / 3 + 2 * numerics::pi / 3 ) ) - r / 3;
    tau3 = ( a * std::cos( phi / 3 + 4 * numerics::pi / 3 ) ) - r / 3;
  }
  else
  {
    const double_t sgnq = ( q >= 0 ? 1 : -1 );
    const double_t u =
      -sgnq * std::pow( std::fabs( q ) / 2.0 + std::sqrt( D ), 1.0 / 3.0 );
    const double_t v = -p / ( 3 * u );
    tau1 = ( u + v ) - r / 3;
    if ( tau1 >= 0 )
    {
      return tau1;
    }
    else
    {
      return thresh_find2_( dt );
    }
  }

  // set tau to the smallest root above 0

  double tau = ( tau1 >= 0 ) ? tau1 : 2 * h_ms;
  if ( ( tau2 >= 0 ) && ( tau2 < tau ) )
    tau = tau2;
  if ( ( tau3 >= 0 ) && ( tau3 < tau ) )
    tau = tau3;
  return ( tau <= V_.h_ms_ ) ? tau : thresh_find2_( dt );
}
예제 #4
0
// cubic interpolation
nest::double_t nest::iaf_psc_exp_canon::thresh_find3_(double_t const dt) const
{
  double_t const h_ms_ = dt;
  double_t const h_sq  = h_ms_*h_ms_;
  double_t const h_cb  = h_sq*h_ms_;

  // f' at left border used as third condition
  double_t const deriv_t1 = -V_.y2_before_/P_.tau_m_
                              + (P_.I_e_ + V_.y1_ex_before_ + V_.y1_in_before_) / P_.c_m_;

  // f' at right border used as fourth condition
  double_t const deriv_t2 = -S_.y2_/P_.tau_m_
                              + (P_.I_e_ + S_.y1_ex_ + S_.y1_in_) / P_.c_m_;

  double_t const w3_ =  (2*V_.y2_before_ / h_cb) - (2*S_.y2_ / h_cb)
                         + (deriv_t1 / h_sq) + (deriv_t2 / h_sq) ;
  double_t const w2_ = -(3*V_.y2_before_ / h_sq) + (3*S_.y2_ / h_sq)
                         - (2*deriv_t1 / h_ms_) - (deriv_t2 / h_ms_);
  double_t const w1_ = deriv_t1;
  double_t const w0_ = V_.y2_before_;

  // normal form: x^3 + r*x^2 + s*x + t with coefficients: r, s, t
  double_t const r    = w2_/w3_;
  double_t const s    = w1_/w3_;
  double_t const t    = (w0_-P_.U_th_) / w3_;
  double_t const r_sq = r*r;

  // substitution y = x + r/3:  y^3 + p*y + q == 0 
  double_t const p = -r_sq/3 + s;
  double_t const q = 2*(r_sq*r) / 27 - r*s / 3 + t;

  // discriminante
  double_t const D = std::pow((p/3), 3) + std::pow((q/2), 2);

  double_t tau1;
  double_t tau2;
  double_t tau3;

  if ( D < 0 )
  {
    double_t const roh = std::sqrt(-(p*p*p) / 27);
    double_t const phi = std::acos(-q / (2*roh));
    double_t const a   = 2*std::pow(roh, (1.0/3.0));

    tau1 = (a*std::cos(phi/3)) - r/3;
    tau2 = (a*std::cos(phi/3 + 2*numerics::pi/3)) - r/3;
    tau3 = (a*std::cos(phi/3 + 4*numerics::pi/3)) - r/3;
  }
  else
  {
    double_t const sgnq = ( q >= 0 ? 1 : -1 );
    double_t const u    = -sgnq*std::pow(std::fabs(q)/2.0 + std::sqrt(D), 1.0/3.0);
    double_t const v    = -p/(3*u);

    tau1= (u+v) - r/3;
    if ( tau1 >= 0 )
      return tau1;
    else
      return thresh_find2_(dt);
  }

  // set tau to the smallest root above 0
  double tau = ( tau1 >= 0 ? tau1 : 2*h_ms_ );

  if (( tau2 >=0 ) && ( tau2 < tau ))
    tau = tau2;
  if (( tau3 >=0 ) && ( tau3 < tau ))
    tau = tau3;
  return ( tau <= h_ms_ ? tau : thresh_find2_(dt) );
}