【C语言】实现 4阶(经典)龙格-库塔法 求解二阶微分方程

最近在网上搜了很多基于C语言实现龙格-库塔法 求解二阶微分方程的相关文章,发现基本都没解决我的问题,代码也没开源,于是自己找了很多相关资料写了一个具体实现的例子方便大家理解,大家***窥一斑而知全豹***

问题如下:

在这里插入图片描述

解题思路:

只需要将以上式子转化成以下一阶常微分方程来求即可
在这里插入图片描述

实现代码:
#include <stdio.h>

double function(double x , double y[] , int j){
    if(j == 1)
        return x * y[1] + y[0] ;    //如果j = 1 ,f = x * y[1] + y[0],然后返回回去
    return y[1] ;   //否则f = y[1],然后返回f即可
}

void rungekutta(double x ,  double *y , double h){
    double ywork[2] , k0[2] , k1[2] , k2[2] , k3[2] ;
    int j ;
    for(j = 0 ; j < 2 ; ++ j)
        k0[j] = h * function(x , y , j) ;   //计算k1
    for(j = 0 ; j < 2 ; ++ j)
        ywork[j] = y[j] + 0.5 * k0[j] ;    
         //用数组ywork存储y的变化量
    for(j = 0 ; j < 2 ; ++ j)
        k1[j] = h * function(x + 0.5 * h , ywork , j);//计算k2
    for(j = 0 ; j < 2 ; ++ j)
        ywork[j] = y[j] + 0.5 * k1[j] ;   
         //将y的变化量存储到ywork中
    for(j = 0 ; j < 2 ; ++ j)
        k2[j] = h * function(x + 0.5 * h , ywork , j);//计算k3
    for(j = 0 ; j < 2 ; ++ j)
        ywork[j] = y[j] + k2[j] ;   
        //更新ywork数组,存储y的变化量
    for(j = 0 ; j < 2 ; ++ j)
        k3[j] = h * function(x + h , ywork , j) ;   //计算k4
    for(j = 0 ; j < 2 ; ++ j)
        y[j] = y[j] + (k0[j] + 2 * k1[j] + 2 * k2[j] + k3[j]) / 6;     //计算y0和y1,用j循环先求y0,再求y1
}

int main() {
    double h , x , y[2] ; //声明变量,y0,y1使用数组y[0],y[1]表示
    h = 0.1 ;
    x = 0 ;
    y[0] = 1 , y[1] = 1 ;   //设置运算初始值
    int i; 
    for(i = 0 ; i < 10 ; ++ i){
        rungekutta(x , y , h) ; 
        //调用Runge Kutta函数进行运算,传入需要用到的数值:x , y0 , y1 , h ;
        x = x + h ;
        printf("n = %d: x = %lf, y0 = %lf, y1 = %lf\n" , i + 1 , x , y[0] , y[1]) ;
    }
    return 0;
}
效果显示:

在这里插入图片描述

大家需要详细流程图的可以评论我,因学习繁重这里笔者就写这么多。

  • 11
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
龙格库塔是一种常用的数值解微分方程的方,可以用来求解二阶微分方程。具体步骤如下: 1. 将二阶微分方程化为一组一微分方程,例如将 $y''+p(x)y'+q(x)y=f(x)$ 化为 $u_1=y, u_2=y'$,则有 $u_1'=u_2, u_2'=-p(x)u_2-q(x)u_1+f(x)$。 2. 选取步长 $h$,确定求解区间 $[a,b]$,并初始化 $u_1(a),u_2(a)$。 3. 依次计算 $u_1,u_2$ 在 $a+h,a+2h,\cdots,b$ 处的值。具体计算公式如下: $k_{11}=u_2(x_n)$ $k_{12}=-p(x_n)u_2(x_n)-q(x_n)u_1(x_n)+f(x_n)$ $k_{21}=u_2(x_n+\frac{h}{2})+\frac{h}{2}k_{12}$ $k_{22}=-p(x_n+\frac{h}{2})u_2(x_n+\frac{h}{2})-q(x_n+\frac{h}{2})u_1(x_n+\frac{h}{2})+f(x_n+\frac{h}{2})$ $k_{31}=u_2(x_n+\frac{h}{2})+\frac{h}{2}k_{22}$ $k_{32}=-p(x_n+\frac{h}{2})u_2(x_n+\frac{h}{2})-q(x_n+\frac{h}{2})u_1(x_n+\frac{h}{2})+f(x_n+\frac{h}{2})$ $k_{41}=u_2(x_n+h)+hk_{32}$ $k_{42}=-p(x_n+h)u_2(x_n+h)-q(x_n+h)u_1(x_n+h)+f(x_n+h)$ $u_1(x_{n+1})=u_1(x_n)+\frac{h}{6}(k_{11}+2k_{21}+2k_{31}+k_{41})$ $u_2(x_{n+1})=u_2(x_n)+\frac{h}{6}(k_{12}+2k_{22}+2k_{32}+k_{42})$ 4. 重复步骤 3 直到计算到 $x=b$。 下面是一个使用龙格库塔求解二阶微分方程的 Python 代码示例: ```python import numpy as np def rk4(f, a, b, h, y0): n = int((b-a)/h) t = np.linspace(a, b, n+1) y = np.zeros((n+1, len(y0))) y[0] = y0 for i in range(n): k1 = h*f(t[i], y[i]) k2 = h*f(t[i]+h/2, y[i]+k1/2) k3 = h*f(t[i]+h/2, y[i]+k2/2) k4 = h*f(t[i]+h, y[i]+k3) y[i+1] = y[i] + (k1+2*k2+2*k3+k4)/6 return t, y def f(x, u): return np.array([u[1], -x*u[1]-x**2*u[0]]) a, b = 0, 1 h = 0.1 y0 = np.array([1, 0]) t, y = rk4(f, a, b, h, y0) print(y[-1, 0]) ``` 其中,`f` 函数是一微分方程组的右端项,`rk4` 函数是龙格库塔实现函数,`a,b` 是求解区间,`h` 是步长,`y0` 是初始值。最后输出的是 $y(1)$ 的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值