简体   繁体   English

GSL:求解具有时间相关系数的ODE

[英]GSL: Solving ODEs with time-dependent coefficients

I have an ODE of type: 我有一个ODE类型:

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. 唯一的GSL ODE示例不是很有帮助,因为唯一的系数(\\ mu)与时间无关。

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 ?). 该问题已在GSL邮件列表中得到解答,但是答案非常不清楚g(t)被忽略,并且尚未说明如何将a(t)合并到func (应该在*params传递它吗?)。

Is there any example I can see where such an ODE is solved using GSL? 有没有我可以看到使用GSL解决此类ODE的示例?

UPDATE: As has been pointed out below, this has been answered on the GSL mailing list. 更新:正如下面所指出的,这已在GSL邮件列表中得到了回答。 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;
}

If you are not restricted to the GSL and/or C you can use http://odeint.com - a modern C++ library for ODEs. 如果您不受限于GSL和/或C,则可以使用http ://odeint.com-用于ODE的现代C ++库。 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. Odeint是boost的一部分,因此它可能已经安装在您的系统上,或者可以轻松地作为Linux发行版的大多数软件包管理器进行安装。

You can simply define your coefficients and the ODE and use for example the RK4 method: 您可以简单地定义系数和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 );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM