数学

常微分方程数值解:Runge-Kutta 方法族

引言

初值问题 $y’ = f(t, y)$、$y(t_0) = y_0$ 是科学计算中出现频率最高的数学模型之一:轨道动力学、化学反应、电路瞬态、流行病传播都由它描述。除少数可积情形外只能数值求解,而 Runge-Kutta(RK)方法族凭借「单步自启动、精度可调、实现简单」的特点成为最通用的选择。本文从 Taylor 展开出发导出 RK 方法的一般形式与阶数条件,介绍经典四阶格式、绝对稳定性概念与嵌入对自适应步长控制,最后用数值实验验证收敛阶并演示自适应算法的效率优势。

理论基础

从 Euler 方法到 Runge-Kutta

对精确解作 Taylor 展开 $y(t+h) = y + h f + \frac{h^2}{2}(f_t + f_y f) + \cdots$。Euler 方法 $y_{n+1} = y_n + h f(t_n, y_n)$ 只保留一阶项,局部截断误差 $\mathcal{O}(h^2)$、全局误差 $\mathcal{O}(h)$。RK 方法的思想是:用 $f$ 在步内若干点的值的加权组合匹配 Taylor 展开的高阶项,而避免直接计算偏导数。$s$ 级 RK 方法的一般形式为

$$y_{n+1} = y_n + h \sum_{i=1}^{s} b_i k_i, \qquad k_i = f!\left(t_n + c_i h, y_n + h \sum_{j=1}^{s} a_{ij} k_j\right)$$

系数习惯排成 Butcher 表:左侧为 $c$ 与 $A = (a_{ij})$,底行为 $b$。$a_{ij}$ 构成严格下三角矩阵时为显式格式(ERK),每步 $s$ 次函数求值;否则为隐式格式(IRK),每步需解方程组但稳定性极佳。

阶数条件与经典 RK4

使方法达到 $p$ 阶需满足由有根树(rooted tree)理论导出的代数方程组:1 阶需 $\sum b_i = 1$,2 阶加 $\sum b_i c_i = 1/2$,3 阶再加两条,4 阶共 8 条,且随阶数急剧增多——这就是 RK 方法「级数多于阶数」的原因(5 阶至少 6 级,8 阶至少 11 级)。最著名的是 4 级 4 阶经典格式:

$$y_{n+1} = y_n + \frac{h}{6}(k_1 + 2k_2 + 2k_3 + k_4)$$

其中 $k_1 = f(t_n, y_n)$、$k_2 = f(t_n + h/2, y_n + h k_1/2)$、$k_3 = f(t_n + h/2, y_n + h k_2/2)$、$k_4 = f(t_n + h, y_n + h k_3)$,可看作 Simpson 积分公式的单步实现,精度与代价的平衡极佳。

绝对稳定性与刚性

把方法作用于试验方程 $y' = \lambda y$ 得 $y_{n+1} = R(h\lambda), y_n$,稳定域为复平面上 $|R(z)| \le 1$ 的区域。RK 方法 $p$ 阶时 $R(z)$ 是指数函数 $e^z$ 的 $[s/s]$ 阶 Padé 截断,故所有显式 RK 的稳定域都有界:对衰减很快的分量($\mathrm{\Re},\lambda \ll 0$),步长必须满足 $|h\lambda|$ 落入稳定域——这不是精度要求而是稳定性要求。当方程组含有时间尺度悬殊的分量(刚性问题,如燃烧化学、电力电子),显式方法被迫采用极小步长,此时应换用稳定域覆盖整个左半平面(A-稳定)的隐式格式,如隐式 Euler、Radau IIA 或 BDF 族。

自适应步长

固定步长无法兼顾解的平缓区与剧变区。嵌入对在同一组 $k_i$ 上给出 $p$ 阶与 $p+1$ 阶两个公式(如 Dormand-Prince 的 RK45、MATLAB ode45 所用),两者之差即局部误差估计,据此按 $h_{\text{new}} = h(\mathrm{tol}/\mathrm{err})^{1/(p+1)}$ 调节步长。无现成嵌入对时也可用步长加倍法(Richardson 外推思想):整步与两个半步之差除以 $2^p – 1$ 给出误差估计。

方法实现

先验证经典 RK4 的 4 阶收敛性,再实现基于步长加倍的自适应 RK4 并求解 van der Pol 振子($\mu = 8$,极限环上变化剧烈,适合展示自适应价值):

import numpy as np

def rk4_step(f, t, y, h):
    k1 = f(t, y)
    k2 = f(t + 0.5 * h, y + 0.5 * h * k1)
    k3 = f(t + 0.5 * h, y + 0.5 * h * k2)
    k4 = f(t + h, y + h * k3)
    return y + h * (k1 + 2 * k2 + 2 * k3 + k4) / 6.0

# 收敛阶验证: y' = y, y(0)=1, 精确解 e^t
f = lambda t, y: y
prev = None
for h in (0.4, 0.2, 0.1, 0.05):
    y = np.array([1.0]); t = 0.0
    for _ in range(int(round(1.0 / h))):
        y = rk4_step(f, t, y, h); t += h
    err = abs(y[0] - np.e)
    rate = "" if prev is None else f"  阶数 {np.log2(prev / err):.2f}"
    print(f"h={h:.2f}  误差={err:.3e}{rate}")
    prev = err

# 自适应 RK4 (步长加倍估计误差)
def solve_adaptive(f, y0, t0, t1, h=0.1, tol=1e-6):
    t, y = t0, np.asarray(y0, dtype=float)
    while t < t1 - 1e-12:
        h = min(h, t1 - t)
        y1 = rk4_step(f, t, y, h)
        y2 = rk4_step(f, t + 0.5 * h, rk4_step(f, t, y, 0.5 * h), 0.5 * h)
        err = np.max(np.abs(y2 - y1)) / 15.0      # 2^4 - 1 = 15
        if err <= tol:
            t += h; y = y2
            h *= min(2.0, 0.9 * (tol / max(err, 1e-16))**0.2)
        else:
            h *= 0.9 * (tol / err)**0.2
    return y

mu = 8.0
vdp = lambda t, y: np.array([y[1], mu * (1.0 - y[0]**2) * y[1] - y[0]])
print("van der Pol (mu=8), t=20:", np.round(solve_adaptive(vdp, [2.0, 0.0], 0.0, 20.0), 6))

收敛阶实验打印出的实测阶数应接近 4:步长减半,误差缩小约 16 倍。自适应求解器在 van der Pol 极限环的平缓段自动放大步长、在「拐角」处加密,同等精度下函数求值次数远少于固定步长。

工程案例分析

航天轨道积分是 RK 方法的传统主场:两体问题中卫星轨道需积分数月至数年,固定低阶方法的相位误差会线性累积,工程上常用 8 阶 Dormand-Prince(DOP853)配合严格误差容限,并以 Jacobi 积分或能量守恒量做在线监测。分子动力学则偏好辛积分(Verlet/蛙跳格式)——它牺牲高阶精度换取哈密顿量长期无漂移,说明「选格式」要先问「保什么结构」。混沌系统(如 Lorenz 方程)对步长极度敏感:Lyapunov 指数使任何局部误差指数放大,自适应步长控制不能保证轨道逐点正确,只能保证统计性质可信,这类问题需要影子定理(shadowing)支撑结论的合理性。

方法 级数 $s$ 阶数 $p$ 每步 $f$ 求值 特点
显式 Euler 1 1 1 教学用,精度太低
中点法 RK2 2 2 2 最简实用格式
经典 RK4 4 4 4 精度/代价平衡极佳
DOPRI (RK45) 6(嵌入对 7 级复用) 5(4) 6 ode45 标准,自适应
Radau IIA 3 5 3 次隐式求解 A/L-稳定,刚性问题

结论与展望

Runge-Kutta 方法用多点函数值匹配 Taylor 展开,其阶数条件由有根树理论完整刻画;经典 RK4 是固定步长的首选,嵌入对自适应(RK45/DOP853)是通用求解器的标准,刚性问题则必须转向 A-稳定的隐式格式。现代发展包括:保结构几何积分(辛 RK、流形上的 RKMK 方法)、指数积分器(exponential integrators,高效处理半线性刚性项),以及神经网络 ODE 中的伴随敏感性分析——它与 RK 格式的对偶问题共享同一套数学结构。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注