gsl gnu求解一阶常微分方程

gsl gnu solving first order ordinary differential equation

我访问了 gnu gsl 网站,但我发现那里求解微分方程的示例根本不直观(尤其是因为它使用的是二阶微分方程)。 https://www.gnu.org/software/gsl/manual/html_node/ODE-Example-programs.html#ODE-Example-programs 有人可以指导一下在哪里可以找到有关如何求解非常简单的 一阶 微分方程的描述性指南。

例如,假设我的函数是 y'=x+2y(或任何此类函数),那么我如何在 gsl 中编写代码以在给定的固定步长和初始条件下求解它。

对于 y'=f(x,y)=x+2y,数组的维度都是 1,这通常是要避免的,但在这里是指导性的。对于显式求解器,即名称中不包含 imp 的求解器,您不需要 Jacobian:

#include <stdio.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>

int odefunc (double x, const double y[], double f[], void *params)
{
    f[0] = x+2*y[0];   
    return GSL_SUCCESS;
}


int * jac;

int main ()
{
    int dim = 1;
    gsl_odeiv2_system sys = {odefunc, NULL, dim, NULL};

    gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
    int i;
    double x0 = 0.0,  xf = 100.0; /* start and end of integration interval */
    double x = x0;
    double y[1] = { 1.0  };  /* initial value */

    for (i = 1; i <= 100; i++)
    {
        double xi = x0 + i * (xf-x0) / 100.0;
        int status = gsl_odeiv2_driver_apply (d, &x, xi, y);

        if (status != GSL_SUCCESS)
        {
            printf ("error, return value=%d\n", status);
            break;
        }

        printf ("%.8e %.8e\n", x, y[0]);
    }

    gsl_odeiv2_driver_free (d);
    return 0;
}

你可能想看看 Jose M. Garrido 的书 "Introduction to Computational Modeling Using C and Open-Source Tools"

Lutzl,请评论:

 '#include <stdio.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>

int odefunc (double x, const double y[], double f[], void *params)
{
    f[0] = x+2*y[0];
    return GSL_SUCCESS;
}


int  jac(double x , const double y[] ,double *dfdy , double dfdx[], 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,x);
    dfdx[0]=2;
    return GSL_SUCCESS;
}
int main ()
{
    int dim =1;
    gsl_odeiv2_system sys = {odefunc, jac, dim, NULL};
    gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys,     gsl_odeiv2_step_rk1imp,1e-7,1e-7, 0.0);
    int i;
    double x0 = 0.0,  xf =1.0; /*al value */

   while(x<xf)
    {
        double xi = x0 + 0.25;
        int status = gsl_odeiv2_driver_apply (d, &x, xi, y);

        if (status != GSL_SUCCESS)
        {
            printf ("error, return value=%d\n", status);
            break;
        }

        printf ("%.8e %.8e\n", x, y[0]);
    }
    gsl_odeiv2_driver_free (d);
    return 0;
}
'