[计算机数值分析]四阶龙格-库塔经典格式解常微分方程的初值问题

Spring-_-Bear 的 CSDN 博客导航

式(1)是四阶龙格 - 库塔格式的一种常用经典格式:

{ y n + 1 = y n + h 6 ( K 1 + 2 K 2 + 2 K 3 + K 4 ) K 1 = f ( x n , y n ) K 2 = f ( x n + 1 2 , y n + h 2 K 1 ) K 3 = f ( x n + 1 2 , y n + h 2 K 2 ) K 4 = f ( x n + 1 , y n + h K 3 ) (1) \begin{cases} y_{n+1}=y_{n}+\frac{h}{6}(K_{1}+2K_{2}+2K_{3}+K_{4})\\ K_{1}=f(x_{n},y_{n})\\ K_{2}=f(x_{n+\frac{1}{2}},y_{n}+\frac{h}{2}K_{1})\\ K_{3}=f(x_{n+\frac{1}{2}},y_{n}+\frac{h}{2}K_{2})\\ K_{4}=f(x_{n+1},y_{n}+hK_{3}) \end{cases} \tag1 yn+1=yn+6h(K1+2K2+2K3+K4)K1=f(xn,yn)K2=f(xn+21,yn+2hK1)K3=f(xn+21,yn+2hK2)K4=f(xn+1,yn+hK3)(1)

经典的龙格 - 库塔格式(1)每一步需要 4 次计算函数值 f f f,可以直接验证它具有四阶精度,不过其论证极其繁琐,此处从略。下图描述了四阶经典的龙格 - 库塔方法。

在这里插入图片描述

例:设取步长 h = 0.2,从 x = 0 到 x = 1 用四阶经典格式(1)解决以下常微分方程的初值问题。

{ y ′ = y − 2 x y ( 0 < x < 1 ) y ( 0 ) = 1 \begin{cases} y'=y-\frac{2x}{y} (0 < x < 1)\\ y(0)=1 \end{cases} {y=yy2x(0<x<1)y(0)=1

解:这里四阶经典格式(1)中 K1,K2,K3,K4 的具体形式是

K 1 = y n − 2 x n y n K_{1}=y_{n}-\frac{2x_{n}}{y_{n}} K1=ynyn2xn

K 2 = y n + h 2 K 1 − 2 x n + h y n + h 2 K 1 K_{2}=y_{n}+\frac{h}{2}K_{1}-\frac{2x_{n}+h}{y_{n}+\frac{h}{2}K_{1}} K2=yn+2hK1yn+2hK12xn+h

K 3 = y n + h 2 K 2 − 2 x n + h y n + h 2 K 2 K_{3}=y_{n}+\frac{h}{2}K_{2}-\frac{2x_{n}+h}{y_{n}+\frac{h}{2}K_{2}} K3=yn+2hK2yn+2hK22xn+h

K 4 = y n + h K 3 − 2 ( x n + h ) y n + h K 3 K_{4}=y_{n}+hK_{3}-\frac{2(x_{n}+h)}{y_{n}+hK_{3}} K4=yn+hK3yn+hK32(xn+h)

下表中记录了计算结果,其中 y ( x n ) y(x_{n}) y(xn) 仍表示准确解。

xnyny(xn)
0.21.18321.1832
0.41.34171.3416
0.61.48331.4832
0.81.61251.6125
1.01.73211.7321

运行示例:

在这里插入图片描述

程序源码:

#include <iostream>
#include <iomanip>
#include <math.h>

using namespace std;

/**
 * 欧拉格式中的 x,y 的函数关系式,即 f(xn,yn)
 */
double f(double x, double y)
{
    return y - 2 * x / y;
}

/**
 * 实际函数解析式
 */
double f1(double x)
{
    return sqrt(1 + 2 * x);
}

int main(void)
{
    double x0, y0;
    cout << "请输入初值:";
    cin >> x0 >> y0;

    double h;
    cout << "请输入步长:";
    cin >> h;

    int N;
    cout << "请输入步数:";
    cin >> N;

    // 输出提示信息
    cout << "\t" << setw(10) << "xn"
        << "\t" << setw(10) << "yn"
        << "\t" << setw(10) << "y(xn)" << endl;

    for (int i = 1; i <= N; i++)
    {
        // 离散点
        double x1 = x0 + h;
        // 求斜率
        double K1 = f(x0, y0);
        double K2 = f(x0 + h / 2, y0 + h / 2 * K1);
        double K3 = f(x0 + h / 2, y0 + h / 2 * K2);
        double K4 = f(x1, y0 + h * K3);
        // 求新值
        double y1 = y0 + h / 6 * (K1 + 2 * K2 + 2 * K3 + K4);
        // 输出本次步进后的离散点数据
        cout << i << "\t" << setw(10) << x1 << "\t" << setw(10) << y1 << "\t" << setw(10) << f1(x1) << endl;

        x0 = x1;
        y0 = y1;
    }

    return 0;
}

  • 7
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春天熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值