当前位置: 首页 > article >正文

【Hydro】龙格-库塔方法的公式推导

龙格-库塔方法的公式推导

考虑一阶常微分方程 y ′ = f ( x , y ) y' = f(x, y) y=f(x,y),初始条件为 y ( x 0 ) = y 0 y(x_0) = y_0 y(x0)=y0,我们希望求解其在区间 [ x 0 , x n ] [x_0, x_n] [x0,xn] 上的数值解。为了简化问题,我们假设步长为 h = x n − x 0 n h = \frac{x_n - x_0}{n} h=nxnx0,其中 n n n 表示迭代次数,即时间步数。

首先,我们可以使用泰勒级数展开 y ( x i + 1 ) y(x_{i+1}) y(xi+1),得到:

y ( x i + 1 ) = y ( x i ) + h y ′ ( x i ) + h 2 2 y ′ ′ ( x i ) + O ( h 3 ) y(x_{i+1}) = y(x_i) + h y'(x_i) + \frac{h^2}{2}y''(x_i) + O(h^3) y(xi+1)=y(xi)+hy(xi)+2h2y′′(xi)+O(h3)

其中 O ( h 3 ) O(h^3) O(h3) 表示高阶项,其大小与 h 3 h^3 h3 同阶或更高。由于我们无法直接求得 y ′ ′ ( x i ) y''(x_i) y′′(xi),因此我们需要通过一阶导数 y ′ ( x i ) y'(x_i) y(xi) 来近似计算二阶导数。

接下来,我们使用龙格-库塔方法的经典四阶公式,得到:

y i + 1 = y i + 1 6 ( k 1 + 2 k 2 + 2 k 3 + k 4 ) y_{i+1} = y_i + \frac{1}{6}(k_1 + 2k_2 + 2k_3 + k_4) yi+1=yi+61(k1+2k2+2k3+k4)

其中,

k 1 = h f ( x i , y i ) k 2 = h f ( x i + h 2 , y i + k 1 2 ) k 3 = h f ( x i + h 2 , y i + k 2 2 ) k 4 = h f ( x i + h , y i + k 3 ) \begin{aligned} k_1 &= hf(x_i, y_i) \\ k_2 &= hf(x_i + \frac{h}{2}, y_i + \frac{k_1}{2}) \\ k_3 &= hf(x_i + \frac{h}{2}, y_i + \frac{k_2}{2}) \\ k_4 &= hf(x_i + h, y_i + k_3) \end{aligned} k1k2k3k4=hf(xi,yi)=hf(xi+2h,yi+2k1)=hf(xi+2h,yi+2k2)=hf(xi+h,yi+k3)

这里的 k 1 , k 2 , k 3 , k 4 k_1, k_2, k_3, k_4 k1,k2,k3,k4 分别表示在 y i y_i yi 处的四个斜率。直观上来说,这些斜率是在 y i y_i yi 处、 y i y_i yi y i + 1 y_{i+1} yi+1 之间的四个点处计算得到的。

将上式代入泰勒级数展开式,我们可以得到:

y i + 1 = y i + 1 6 ( k 1 + 2 k 2 + 2 k 3 + k 4 ) + O ( h 5 ) y_{i+1} = y_i + \frac{1}{6}(k_1 + 2k_2 + 2k_3 + k_4) + O(h^5) yi+1=yi+61(k1+2k2+2k3+k4)+O(h5)

这里的 O ( h 5 ) O(h^5) O(h5) 表示高阶项,其大小与 h 5 h^5 h5 同阶或更高。因此,龙格-库塔方法是一种五阶收敛的数值积分方法,其误差随步长的减小而快速收敛。

python代码

    def runge_kutta(self, f, x0, y0, h, n):
        """
        使用龙格-库塔方法求解一阶常微分方程的数值解
        :param f: 函数 f(x, y) 的句柄,表示 y' = f(x, y)
        :param x0: 自变量的初始值
        :param y0: 因变量的初始值
        :param h: 步长
        :param n: 迭代次数
        :return: 返回一个二元组,包含自变量和因变量的数组
        """
        x = np.zeros(n + 1)
        y = np.zeros(n + 1)
        x[0] = x0
        y[0] = y0
        for i in range(n):
            k1 = f(x[i], y[i])
            k2 = f(x[i] + h / 2, y[i] + h / 2 * k1)
            k3 = f(x[i] + h / 2, y[i] + h / 2 * k2)
            k4 = f(x[i] + h, y[i] + h * k3)
            y[i + 1] = y[i] + h / 6 * (k1 + 2 * k2 + 2 * k3 + k4)
            x[i + 1] = x[i] + h
        return x, y

http://www.kler.cn/a/4875.html

相关文章:

  • python类和对象
  • cmake - build MS STL project
  • ChatGPT背后有哪些关键技术?CSIG企业行带你一探究竟
  • PyTorch 深度学习实战 | 基于生成式对抗网络生成动漫人物
  • JavaScript中bind的用法
  • STM32基于STM32CubeMX DMA + EXTI读取DS1307数据
  • 人大金仓数据库CentOS7安装简述
  • Windows7操作系统
  • 电脑图片压缩到200k以内怎么办?怎么让图片小于200kb?
  • 蓝桥杯--最少刷题数--java
  • 【Flutter 问题系列第 76 篇】在 Flutter 中 Builder 组件的作用以及如何解决 Scaffold.of 找不到上下文问题的解决文案
  • 【16】核心易中期刊推荐——机器学习模式识别
  • 班里的一个ACM大佬,居然放弃了某大厂ssp的offer,准备回老家小县城烟草局工作,他是不是傻?...
  • Spring Boot+vue智慧公寓管理系统
  • JDBC教程下篇
  • Blender教程利用Cell Fracture插件制作破碎效果
  • 容器的老祖宗LXC和Docker的关系
  • 第二十五章 绘制简单物体总结
  • Redis Cluster集群搭建、Cluster集群扩缩容、底层原理
  • 参考文献整理 MDPI格式
  • linux查看硬件信息
  • 代码随想录二刷——动规篇章