GSL:用时间相关系数求解ODE

GSL: Solving ODEs with time-dependent coefficients

本文关键字:ODE 关系 时间 GSL      更新时间:2023-10-16

我有一个类型的颂歌:

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

我要解决的问题。唯一的GSL ODE示例并不是很有帮助,因为唯一的系数( MU)与时间不相关。

这个问题已在GSL邮件列表上回答,但是答案尚不清楚-g(t)被忽略,并且没有解释如何将a(t)纳入func(是否应该在*params中传递?)。

有什么示例我可以看到使用GSL解决此类颂歌的位置?

更新:如下指出,这已在GSL邮件列表中回答。这是一个完整的示例程序:

#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("timet tapprox solution t exact solutionn");
    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=%dn", status);
            break;
        }
        printf("%.5et%.5ett%.5en", t, y[0], x0*exp(-0.5*t*t));
    }
    gsl_odeiv2_driver_free(d);
    printf("n...and done!n");
    return 0;
}

如果您不限于GSL和/或C,则可以使用http://odeint.com-现代的C 库用于ODES。Odeint是Boost的一部分,因此它可能已经在系统上安装了,或者可以轻松安装是Linux发行版的大多数软件包管理器。

您可以简单地定义您的系数和ode并使用RK4方法:

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 );