【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

你可能感兴趣的:(#,水文模型基础,python,开发语言)