int main () { double alpha = 2; double beta = 4; double gamma = 7; //3 and 7 // you can use any stepper here const gsl_odeiv2_step_type * T = gsl_odeiv2_step_rk4imp; gsl_odeiv2_step * s = gsl_odeiv2_step_alloc(T, 3); gsl_odeiv2_control * c = gsl_odeiv2_control_y_new(1e-6, 0.0); gsl_odeiv2_evolve * e = gsl_odeiv2_evolve_alloc(3); predprey_params pars = {alpha,beta,gamma,0,0}; /* the parameters */ gsl_odeiv2_system sys = {predprey, jac_predprey, 3, &pars}; gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new(&sys, T, 1e-6, 1e-6, 1e-6 ); gsl_odeiv2_step_set_driver(s, d); double t = 0.0, t1 = 20.0; double h = 1e-6; double x[3] = { 1.0, 0.1, 3.0 }; double t2 = t; double interval = 0.01; while (t < t1) { int status = gsl_odeiv2_evolve_apply (e, c, s, &sys, &t, t1, &h, x); if (status != GSL_SUCCESS) break; if(t > t2+interval) { printf ("%.5e %.5e %.5e %.5e\n", t, x[0], x[1], x[2]); t2 = t; } } gsl_odeiv2_evolve_free (e); gsl_odeiv2_control_free (c); gsl_odeiv2_step_free (s); fprintf(stderr,"Number of Jacobian evaluations = %d\n" "Number of Function evaluations = %d\n", pars.jac_count, pars.count); return 0; }
int Integrator::dointstep(int (*func)(double, const double*, double*, void*), IntParams ¶ms, double data[], double &time, const double endtime) { // Integrates a single step // Sets up the system to integrate, including the function that specifies the derivatives, NULL for the Jacobian, the number of elements // being integrated, and the parameters to pass through to the function gsl_odeiv2_system sys = { func, NULL, numelements, ¶ms }; // Make a copy of the stepsize - the evolution function wants to update this quantity, but a reference to the class' private information // makes things unhappy double stepsizecopy = stepsize; // Actually take the integration step int status = gsl_odeiv2_evolve_apply(evolve, control, step, &sys, &time, endtime, &stepsizecopy, data); // Update the stepsize according to what GSL thinks will work well, but make sure it doesn't get too big. We want some resolution on our functions! setstepsize(stepsizecopy); // Return the status: should be GSL_SUCCESS if everything worked return status; }
void IzhikevichBranch::subthreshold_regimeRegime_::step_ode() { IzhikevichBranch::State_& S_ = cell->S_; //FIXME: Clamping of vars should be replaced by the resizing of the state // vector that is solved to only the states that have time-derivatives // in the regime. /***** Set clamp vars for state variables that don't have a time derivative in this regime *****/ // Step ODE solver double dt = nest::Time::get_resolution().get_ms(); double tt = 0.0; while (tt < dt) { const int status = gsl_odeiv2_evolve_apply( e_, c_, s_, &sys_, // system of ODE &tt, // from t... dt, // ...to t= t + dt &IntegrationStep_, // integration window (written on!) this->cell->S_.y_); // neuron state if (status != GSL_SUCCESS) throw nest::GSLSolverFailure(this->cell->get_name(), status); } /***** Reset state variables from clamp vars for state variables that don't have a time derivative in this regime *****/ }
int main (void) { size_t neqs = 4; /* number of equations */ double eps_abs = 1.e-10, eps_rel = 0.; /* desired precision */ double stepsize = 1e-6; /* initial integration step */ double R = 10.; /* the aerodynamic efficiency */ double t, t1; /* time interval */ int status; int i, np = 50; /* number of points */ double alt1 = 0.1, alt2 = 5., altitude; double step; step = (alt2 - alt1)/(np - 1); for (i = 0; i < np; i++) { t = 0.; t1 = 520.; /* Code stops before hitting maximum time step */ altitude = alt1 + i*step; /* * Initial conditions */ double y[4] = { 2., 0., 0., altitude }; /* for res3 */ /* * Explicit embedded Runge-Kutta-Fehlberg (4,5) method. * This method is a good general-purpose integrator. */ gsl_odeiv2_step *s = gsl_odeiv2_step_alloc (gsl_odeiv2_step_rkf45, neqs); gsl_odeiv2_control *c = gsl_odeiv2_control_y_new (eps_abs, eps_rel); gsl_odeiv2_evolve *e = gsl_odeiv2_evolve_alloc (neqs); gsl_odeiv2_system sys = {func, NULL, neqs, &R}; /* * Evolution loop */ while ( (t < t1) && (y[3] > 0) ) /* ends loop before max time step */ { status = gsl_odeiv2_evolve_apply (e, c, s, &sys, &t, t1, &stepsize, y); if (status != GSL_SUCCESS) { printf ("Troubles: % .5e % .5e % .5e % .5e % .5e\n", t, y[0], y[1], y[2], y[3]); break; } } printf ("% .5e % .5e % .5e % .5e % .5e % .5e \n", t, y[0], y[1], y[2], y[3], altitude); gsl_odeiv2_evolve_free (e); gsl_odeiv2_control_free (c); gsl_odeiv2_step_free (s); } return 0; }
void contractor_gsl::prune(box & b, SMTConfig & config) { // TODO(soonhok): add timeout fesetround(FE_TONEAREST); // Without this, GSL might cause a segmentation fault due to problems in floating point lib gsl_odeiv2_step_reset(m_step); gsl_odeiv2_evolve_reset(m_evolve); double const T_lb = b[m_time_t].lb(); double const T_ub = b[m_time_t].ub(); double t = 0.0, old_t = 0.0; /* initialize t */ double T_next = 0.0; double h = 1e-10; /* starting step size for ode solver */ DREAL_LOG_INFO << "GSL: prune begin " << m_time_t << " = [" << T_lb << ", " << T_ub << "]" << "\t" << b.max_diam(); DREAL_LOG_INFO << m_ctr->get_ic(); if (b.max_diam() < config.nra_precision) { return; } bool need_to_run = false; for (Enode * e : m_vars_0) { if (b[e].diam() > config.nra_precision) { need_to_run = true; break; } } if (b[m_time_t].diam() > config.nra_precision) { need_to_run = true; } if (!need_to_run) { return; } extract_sample_point(b, m_vars_0, m_values); extract_sample_point(b, m_pars_0, m_params); for (unsigned i = 0; i < m_vars_0.size(); i++) { b[m_vars_0[i]] = m_values[i]; } for (unsigned i = 0; i < m_pars_0.size(); i++) { b[m_pars_0[i]] = m_params[i]; } // First move to T_lb without checking m_values while (t < T_lb) { interruption_point(); T_next = T_lb; // T_next = min(t + config.nra_precision, T_lb); int status = gsl_odeiv2_evolve_apply(m_evolve, m_control, m_step, &m_system, &t, T_next, &h, m_values); if (status != GSL_SUCCESS) { DREAL_LOG_INFO << "GSL: error, return value " << status; throw contractor_exception("GSL FAILED"); } } // Now we're in the range in [T_lb, T_ub], need to check m_values. while (t < T_ub) { interruption_point(); T_next = min(t + config.nra_precision, T_ub); // T_next = T_ub; // Copy m_values to m_old_values, and t to old_t for (unsigned i = 0; i < m_dim; i++) { m_old_values[i] = m_values[i]; } old_t = t; int status = gsl_odeiv2_evolve_apply(m_evolve, m_control, m_step, &m_system, &t, T_next, &h, m_values); if (status != GSL_SUCCESS) { DREAL_LOG_INFO << "GSL: error, return value " << status; throw contractor_exception("GSL FAILED"); } // print_values(t, m_values, m_dim); /* print at t */ bool values_good = true; unsigned i = 0; for (Enode * e : m_vars_t) { double const old_v_i = m_old_values[i]; double const v_i = m_values[i]; auto iv = (old_v_i < v_i) ? ibex::Interval(old_v_i, v_i) : ibex::Interval(v_i, old_v_i); auto const & iv_X_t = b[e]; iv &= iv_X_t; if (iv.is_empty()) { values_good = false; DREAL_LOG_INFO << "GSL Not in Range: " << e << " : " << m_values[i] << " not in " << b[e] << " at t = " << t; break; } i++; } if (values_good) { thread_local static box old_box(b); old_box = b; // Update X_t with m_values i = 0; for (Enode * e : m_vars_t) { double const old_v_i = m_old_values[i]; double const v_i = m_values[i]; auto iv = (old_v_i < v_i) ? ibex::Interval(old_v_i, v_i) : ibex::Interval(v_i, old_v_i); auto const & iv_X_t = b[e]; iv &= iv_X_t; DREAL_LOG_INFO << "GSL Update: " << e << " : " << b[e] << " ==> " << iv; b[e] = iv; i++; } // Update Time with T double const new_t = t/2.0 + old_t/2.0; DREAL_LOG_INFO << "GSL Update: time: " << b[m_time_t] << " ==> " << new_t; b[m_time_t] = new_t; m_eval_ctc.prune(b, config); if (!b.is_empty()) { DREAL_LOG_INFO << "This box satisfies other non-linear constraints"; return; } else { DREAL_LOG_INFO << "This box failed to satisfy other non-linear constraints"; b = old_box; } } } DREAL_LOG_INFO << "GSL failed in the end"; throw contractor_exception("GSL failed"); }
int gsl_odeiv2_driver_apply (gsl_odeiv2_driver * d, double *t, const double t1, double y[]) { /* Main driver function that evolves the system from t to t1. In beginning vector y contains the values of dependent variables at t. This function returns values at t=t1 in y. In case of unrecoverable error, y and t contains the values after the last successful step. */ int sign = 0; d->n = 0; /* Determine integration direction sign */ if (d->h > 0.0) { sign = 1; } else { sign = -1; } /* Check that t, t1 and step direction are sensible */ if (sign * (t1 - *t) < 0.0) { GSL_ERROR_NULL ("integration limits and/or step direction not consistent", GSL_EINVAL); } /* Evolution loop */ while (sign * (t1 - *t) > 0.0) { int s = gsl_odeiv2_evolve_apply (d->e, d->c, d->s, d->sys, t, t1, &(d->h), y); if (s != GSL_SUCCESS) { return s; } /* Check for maximum allowed steps */ if ((d->nmax > 0) && (d->n > d->nmax)) { return GSL_EMAXITER; } /* Set step size if maximum size is exceeded */ if (fabs (d->h) > d->hmax) { d->h = sign * d->hmax; } /* Check for too small step size */ if (fabs (d->h) < d->hmin) { return GSL_ENOPROG; } d->n++; } return GSL_SUCCESS; }