int integrate_ode_using_driver (double t, double t1, double y[], int n_steps, double h_init, double h_max, double eps_abs, double eps_rel, void *params, int print_values) { int i; // Counter in macro-step loop int j; // Counter in print loop int status; size_t dim = NY; double ti; double dt = (t1-t)/(double)n_steps; const gsl_odeiv2_step_type * T = gsl_odeiv2_step_msbdf; gsl_odeiv2_step * s = gsl_odeiv2_step_alloc (T, dim); gsl_odeiv2_system sys = {func, jac, dim, params}; gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new(&sys, gsl_odeiv2_step_msbdf, h_init, eps_abs, eps_rel); gsl_odeiv2_step_set_driver(s, d); if (h_max > 0.0) { gsl_odeiv2_driver_set_hmax(d, h_max); } for (i = 0; i < n_steps; ++i) { // Macro-step loop ti = t + dt*(i+1); status = gsl_odeiv2_driver_apply (d, &t, ti, y); if (status != GSL_SUCCESS) { printf ("error, return value=%d\n", status); break; } if (print_values) { printf(STRINGIFY(PRECISION), t); for (j = 0; j < NY; ++j) { printf(" " STRINGIFY(PRECISION), y[j]); } printf("\n"); } } gsl_odeiv2_driver_free (d); gsl_odeiv2_step_free (s); return status; }
int main () { double alpha = 2; double beta = 4; double gamma = 7; //3 and 7 double gmax = 5; // 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,gmax,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; }
gsl_odeiv2_driver * gsl_odeiv2_driver_alloc_scaled_new (const gsl_odeiv2_system * sys, const gsl_odeiv2_step_type * T, const double hstart, const double epsabs, const double epsrel, const double a_y, const double a_dydt, const double scale_abs[]) { /* Initializes an ODE driver system with control object of type scaled_new. */ gsl_odeiv2_driver *state = driver_alloc (sys, hstart, T); if (state == NULL) { GSL_ERROR_NULL ("failed to allocate driver object", GSL_ENOMEM); } if (epsabs >= 0.0 && epsrel >= 0.0) { state->c = gsl_odeiv2_control_scaled_new (epsabs, epsrel, a_y, a_dydt, scale_abs, sys->dimension); if (state->c == NULL) { gsl_odeiv2_driver_free (state); GSL_ERROR_NULL ("failed to allocate control object", GSL_ENOMEM); } } else { gsl_odeiv2_driver_free (state); GSL_ERROR_NULL ("epsabs and epsrel must be positive", GSL_EINVAL); } /* Distribute pointer to driver object */ gsl_odeiv2_step_set_driver (state->s, state); gsl_odeiv2_evolve_set_driver (state->e, state); gsl_odeiv2_control_set_driver (state->c, state); return state; }