0

I have an ODE of type:

x'(t) = a(t)x+g(t)

Which I am trying to solve. The only GSL ODE example isn't very helpful because the only coefficient (\mu) is not time dependent.

This question has been answered on the GSL mailing list however the answer is very unclear - g(t) is ignored and it has not been explained how to incorporate a(t) into func ( should it be passed in *params?).

Is there any example I can see where such an ODE is solved using GSL?

UPDATE: As has been pointed out below, this has been answered on the GSL mailing list. Here is a full example program of how this is done:

#include <stdio.h>
#include <math.h>
#include "gsl/gsl_errno.h"
#include "gsl/gsl_matrix.h"
#include "gsl/gsl_odeiv2.h"
int func(double t, const double y[], double f[], void *params) {
    f[0] = -t* y[0];
    return GSL_SUCCESS;
}
int jac(double t, const double y[], double *dfdy, double dfdt[], void
*params) {
    gsl_matrix_view dfdy_mat = gsl_matrix_view_array(dfdy, 1, 1);
    gsl_matrix * m = &dfdy_mat.matrix;
    gsl_matrix_set(m, 0, 0, -t);
    dfdt[0] = -1;
    return GSL_SUCCESS;
}
int main(void) {
    double mu = 0;
    gsl_odeiv2_system sys = { func, jac, 1, &mu };
    gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new(&sys,
            gsl_odeiv2_step_rk1imp, 1e-7, 1e-7, 0.0);
    int i;
    double t = 0.0, t1 = 2.0;
    const double x0 = 1.0;
    double y[1] = {x0};
    const int N = 100;
    printf("time\t \tapprox solution \t exact solution\n");
    for (i = 0; i <= N; i++) {
        double ti = i * (t1 / N);
        int status = gsl_odeiv2_driver_apply(d, &t, ti, y);
        if (status != GSL_SUCCESS) {
            printf("error, return value=%d\n", status);
            break;
        }
        printf("%.5e\t%.5e\t\t%.5e\n", t, y[0], x0*exp(-0.5*t*t));
    }
    gsl_odeiv2_driver_free(d);
    printf("\n...and done!\n");
    return 0;
}
Mike Vella
  • 10,187
  • 14
  • 59
  • 86

1 Answers1

2

If you are not restricted to the GSL and/or C you can use http://odeint.com - a modern C++ library for ODEs. Odeint is part of boost, so it might be already installed on your system or can easily be installed be most of the package managers for Linux distributions.

You can simply define your coefficients and the ODE and use for example the RK4 method:

double coef_a( double t ) { /* return a(t) */ };
double coef_g( double t ) { /* return b(t) */ };

typedef std::array< double , 1 > state_type;
double ode( state_type const &x , state_type &dxdt , double )
{
    dxdt[0] = coef_a( t ) * x[0] + coef_g( t );
}

state_type x;
double t_state , t_end , dt;
// initialize x
integrate_const( runge_kutta< state_type >() , ode , x , t_start , dt , t_end );
headmyshoulder
  • 6,240
  • 2
  • 20
  • 27
  • Thanks! What are the pros/cons to GSL vs ODEint for evolving ODEs? – Mike Vella Jan 21 '14 at 01:45
  • 1
    odeint pros: modern C++, highly performant, works on GPUs, very flexibel, odeint cons: difficult to read internals (if you are not used to C++), gsl pros: more implicit methods, gsl cons: old-school C-style API. Of course, my opinion is biased towards odeint :) – headmyshoulder Jan 21 '14 at 07:22