算法设计

用数值方法求解ODE基本上可以分为下述三种方法

  • 基于数值积分的方法
  • 基于多项式配置或Taylor展开的方法
  • 基于有限差分的方法

基于数值积分的方法

求解常微分方程(ODE)初值问题

dydt=f(t,y),y(t0)=y0\frac{dy}{dt} = f(t, y), \quad y(t_0) = y_0dtdy=f(t,y),y(t0)=y0

的一种核心途径是将其写成等价的积分方程:

y(t)=y0+∫t0tf(s,y(s)) dsy(t) = y_0 + \int_{t_0}^t f(s, y(s)) \, dsy(t)=y0+t0tf(s,y(s))ds

在离散点 tnt_ntn 上,递推关系为

y(tn+1)=y(tn)+∫tntn+1f(s,y(s)) dsy(t_{n+1}) = y(t_n) + \int_{t_n}^{t_{n+1}} f(s, y(s)) \, dsy(tn+1)=y(tn)+tntn+1f(s,y(s))ds

用不同的数值积分公式近似其中的积分,本质上是在构造不同的ODE求解器,就自然导出欧拉法、梯形法、中点法以及亚当斯(Adams)多步法等。

左矩形法 → 欧拉法(显式)

我们用两种视角来看待这种积分器

视角一:Taylor展开

证明:用 Taylor 展开推导显式欧拉法

求解初值问题:

dydx=f(x,y),y(x0)=y0 \frac{dy}{dx} = f(x, y), \quad y(x_0) = y_0 dxdy=f(x,y),y(x0)=y0

设步长为 h=xk+1−xkh = x_{k+1} - x_kh=xk+1xk,且 f(x,y)f(x, y)f(x,y) 充分光滑。

第一步:Taylor 展开

将精确解 y(xk+1)y(x_{k+1})y(xk+1)xkx_kxk 处作 Taylor 展开:

y(xk+1)=y(xk+h)=y(xk)+hy′(xk)+h22y′′(ξ) y(x_{k+1}) = y(x_k + h) = y(x_k) + h y'(x_k) + \frac{h^2}{2} y''(\xi) y(xk+1)=y(xk+h)=y(xk)+hy(xk)+2h2y′′(ξ)

其中 ξ∈(xk,xk+1)\xi \in (x_k, x_{k+1})ξ(xk,xk+1)(拉格朗日余项)。

第二步:用微分方程替换导数

由原方程 y′(x)=f(x,y(x))y'(x) = f(x, y(x))y(x)=f(x,y(x)),知 y′(xk)=f(xk,y(xk))y'(x_k) = f(x_k, y(x_k))y(xk)=f(xk,y(xk))

引入记号 yk≈y(xk)y_k \approx y(x_k)yky(xk),则上式可写为:

y(xk+1)=y(xk)+hf(xk,y(xk))+h22y′′(ξ) y(x_{k+1}) = y(x_k) + h f(x_k, y(x_k)) + \frac{h^2}{2} y''(\xi) y(xk+1)=y(xk)+hf(xk,y(xk))+2h2y′′(ξ)

第三步:截断高阶项,得到数值格式

舍去 O(h2)O(h^2)O(h2) 的余项,取近似:

yk+1=yk+hf(xk,yk) \boxed{y_{k+1} = y_k + h f(x_k, y_k)} yk+1=yk+hf(xk,yk)

这就是显式欧拉法

局部截断误差分析

从 Taylor 展开过程可以直接读出局部截断误差(单步误差):

Tk+1=y(xk+1)−[y(xk)+hf(xk,y(xk))]=h22y′′(ξ)=O(h2) T_{k+1} = y(x_{k+1}) - \big[ y(x_k) + h f(x_k, y(x_k)) \big] = \frac{h^2}{2} y''(\xi) = O(h^2) Tk+1=y(xk+1)[y(xk)+hf(xk,y(xk))]=2h2y′′(ξ)=O(h2)

所以显式欧拉法的局部截断误差O(h2)O(h^2)O(h2),而经过 N∝1/hN \propto 1/hN1/h 步累积后,全局误差O(h)O(h)O(h),即一阶精度

视角二:数值积分

从积分方程视角推导显式欧拉法

1. 积分方程是出发点

将微分方程 dydt=f(t,y)\dfrac{dy}{dt} = f(t, y)dtdy=f(t,y) 在区间 [tn,tn+1][t_n, t_{n+1}][tn,tn+1] 上积分,得到等价的积分方程:

y(tn+1)=y(tn)+∫tntn+1f(s,y(s)) ds y(t_{n+1}) = y(t_n) + \int_{t_n}^{t_{n+1}} f(s, y(s)) \, ds y(tn+1)=y(tn)+tntn+1f(s,y(s))ds

这里,y(tn)y(t_n)y(tn)已知的当前值,而 y(tn+1)y(t_{n+1})y(tn+1)未知的未来值。要计算未来值,关键就在于怎么处理那个积分项

2. 左矩形公式:用"旧信息"代替"新积分"

积分项 ∫tntn+1f(s,y(s)) ds\displaystyle\int_{t_n}^{t_{n+1}} f(s, y(s)) \, dstntn+1f(s,y(s))ds 的几何意义是曲线 f(t,y(t))f(t, y(t))f(t,y(t)) 在区间 [tn,tn+1][t_n, t_{n+1}][tn,tn+1] 下的面积。

显式欧拉法做了一个极其暴力的近似:它假设在整个区间 [tn,tn+1][t_n, t_{n+1}][tn,tn+1] 上,fff 的值是不变的,始终等于它在左端点 tnt_ntn 处的值 f(tn,yn)f(t_n, y_n)f(tn,yn)

这在几何上,就是用一个以左端点函数值为高的矩形面积,去替代曲线下的真实面积。

在这里插入图片描述

所以积分近似为:

∫tntn+1f(s,y(s)) ds≈(tn+1−tn)⋅f(tn,yn)=h⋅f(tn,yn) \int_{t_n}^{t_{n+1}} f(s, y(s)) \, ds \approx (t_{n+1} - t_n) \cdot f(t_n, y_n) = h \cdot f(t_n, y_n) tntn+1f(s,y(s))ds(tn+1tn)f(tn,yn)=hf(tn,yn)

这本质上就是左矩形积分公式(Left Rectangle Rule)。

3. 代回原式,欧拉法诞生

把这个近似代回积分方程:

yn+1=yn+h⋅f(tn,yn) \boxed{y_{n+1} = y_n + h \cdot f(t_n, y_n)} yn+1=yn+hf(tn,yn)

它之所以是 “显式” 的,正是因为这个积分近似只用到了时刻 tnt_ntn 的旧信息 f(tn,yn)f(t_n, y_n)f(tn,yn),完全没有涉及到我们还不知道的 yn+1y_{n+1}yn+1

用数值积分的视角更适合建立几何直觉,而用Taylor展开更适合做误差分析

代码实现

我们假定迭代是均匀的

显式欧拉法

#python

import numpy as np
def explicit_euler(f, t0, y0, h, n):
    t = [t0]
    y = [y0]
    for i in range(n):
        y_new = y[-1] + h * f(t[-1], y[-1])
        t_new = t[-1] + h
        t.append(t_new)
        y.append(y_new)
    return t, y
    
#输出:t = [t0, t1, t2, ..., t_n];y = [y0, y1, y2, ..., y_n]

t_arr = np.array(t)
y_arr = np.array(y)

梯形法

几何视角:梯形数值积分

梯形法的几何直觉非常直接:用梯形面积代替曲线下的真实面积

在这里插入图片描述

在区间 [tn,tn+1][t_n, t_{n+1}][tn,tn+1] 上,被积函数 f(t,y(t))f(t, y(t))f(t,y(t)) 在两个端点的值分别为
f(tn,yn)f(t_n, y_n)f(tn,yn)f(tn+1,yn+1)f(t_{n+1}, y_{n+1})f(tn+1,yn+1)
梯形的面积公式为

面积≈h⋅f(tn,yn)+f(tn+1,yn+1)2. \text{面积} \approx h \cdot \frac{f(t_n, y_n) + f(t_{n+1}, y_{n+1})}{2} . 面积h2f(tn,yn)+f(tn+1,yn+1).

将此近似代入积分递推式,就得到梯形法的格式:

yn+1=yn+h2[f(tn,yn)+f(tn+1,yn+1)]. \boxed{y_{n+1} = y_n + \frac{h}{2} \big[ f(t_n, y_n) + f(t_{n+1}, y_{n+1}) \big]} . yn+1=yn+2h[f(tn,yn)+f(tn+1,yn+1)].

几何直觉

  • 梯形比只用一个端点值的矩形(显式欧拉法)更贴近真实曲线,因此精度更高
  • 梯形的右端点高依赖于未知的 yn+1y_{n+1}yn+1,这意味着公式两端都含有 yn+1y_{n+1}yn+1,因此梯形法是隐式
代数视角:Taylor 展开与误差分析

代数推导能严格求出局部截断误差,并揭示低阶项完全抵消的数学结构

假设 f(t,y)f(t,y)f(t,y) 充分光滑,记精确解为 y(t)y(t)y(t),且 yn=y(tn)y_n = y(t_n)yn=y(tn)

第一步:展开精确解

y(tn+1)y(t_{n+1})y(tn+1)tnt_ntn 处 Taylor 展开:

y(tn+1)=y(tn+h)=y(tn)+hy′(tn)+h22y′′(tn)+h36y′′′(ξ1),ξ1∈(tn,tn+1). \begin{aligned} y(t_{n+1}) &= y(t_n + h) \\ &= y(t_n) + h y'(t_n) + \frac{h^2}{2} y''(t_n) + \frac{h^3}{6} y'''(\xi_1), \quad \xi_1 \in (t_n, t_{n+1}) . \end{aligned} y(tn+1)=y(tn+h)=y(tn)+hy(tn)+2h2y′′(tn)+6h3y′′′(ξ1),ξ1(tn,tn+1).

第二步:展开导数项 f(tn+1,yn+1)f(t_{n+1}, y_{n+1})f(tn+1,yn+1)

注意到 y′(t)=f(t,y(t))y'(t) = f(t, y(t))y(t)=f(t,y(t)),将 y′(tn+1)y'(t_{n+1})y(tn+1)tnt_ntn 处展开:

y′(tn+1)=f(tn+1,y(tn+1))=y′(tn)+hy′′(tn)+h22y′′′(ξ2),ξ2∈(tn,tn+1). \begin{aligned} y'(t_{n+1}) &= f(t_{n+1}, y(t_{n+1})) \\ &= y'(t_n) + h y''(t_n) + \frac{h^2}{2} y'''(\xi_2), \quad \xi_2 \in (t_n, t_{n+1}) . \end{aligned} y(tn+1)=f(tn+1,y(tn+1))=y(tn)+hy′′(tn)+2h2y′′′(ξ2),ξ2(tn,tn+1).

第三步:构造梯形和

计算数值格式等号右侧的表达式:

y(tn)+h2[y′(tn)+y′(tn+1)]=y(tn)+h2[y′(tn)+(y′(tn)+hy′′(tn)+h22y′′′(ξ2))]=y(tn)+hy′(tn)+h22y′′(tn)+h34y′′′(ξ2). \begin{aligned} & y(t_n) + \frac{h}{2} \big[ y'(t_n) + y'(t_{n+1}) \big] \\ = & y(t_n) + \frac{h}{2} \Big[ y'(t_n) + \big( y'(t_n) + h y''(t_n) + \frac{h^2}{2} y'''(\xi_2) \big) \Big] \\ = & y(t_n) + h y'(t_n) + \frac{h^2}{2} y''(t_n) + \frac{h^3}{4} y'''(\xi_2) . \end{aligned} ==y(tn)+2h[y(tn)+y(tn+1)]y(tn)+2h[y(tn)+(y(tn)+hy′′(tn)+2h2y′′′(ξ2))]y(tn)+hy(tn)+2h2y′′(tn)+4h3y′′′(ξ2).

第四步:计算局部截断误差

局部截断误差定义为真实解与数值解(从精确数据出发)的差:
Tn+1=y(tn+1)−[y(tn)+h2(f(tn,y(tn))+f(tn+1,y(tn+1)))]. T_{n+1} = y(t_{n+1}) - \left[ y(t_n) + \frac{h}{2} \big( f(t_n, y(t_n)) + f(t_{n+1}, y(t_{n+1})) \big) \right] . Tn+1=y(tn+1)[y(tn)+2h(f(tn,y(tn))+f(tn+1,y(tn+1)))].
将两个展开式代入,相减:
Tn+1=[y(tn)+hy′(tn)+h22y′′(tn)+h36y′′′(ξ1)]−[y(tn)+hy′(tn)+h22y′′(tn)+h34y′′′(ξ2)]=h36y′′′(ξ1)−h34y′′′(ξ2)=O(h3). \begin{aligned} T_{n+1} &= \left[ y(t_n) + h y'(t_n) + \frac{h^2}{2} y''(t_n) + \frac{h^3}{6} y'''(\xi_1) \right] \\ &\quad - \left[ y(t_n) + h y'(t_n) + \frac{h^2}{2} y''(t_n) + \frac{h^3}{4} y'''(\xi_2) \right] \\ &= \frac{h^3}{6} y'''(\xi_1) - \frac{h^3}{4} y'''(\xi_2) \\ &= O(h^3) . \end{aligned} Tn+1=[y(tn)+hy(tn)+2h2y′′(tn)+6h3y′′′(ξ1)][y(tn)+hy(tn)+2h2y′′(tn)+4h3y′′′(ξ2)]=6h3y′′′(ξ1)4h3y′′′(ξ2)=O(h3).
解释

  • 常数项、hhh 项和 h2h^2h2 项全部抵消,只剩下 h3h^3h3
  • 因此梯形法的局部截断误差为 O(h3)O(h^3)O(h3),比显式欧拉(O(h2)O(h^2)O(h2))高一阶
  • 经过 N∝1/hN \propto 1/hN1/h 步累积后,全局误差O(h2)O(h^2)O(h2),即方法具有二阶精度

代数视角的优势
精确量化误差,揭示对称性(梯形法取两端点平均)带来的低阶抵消效应。

总结

设步长 h=tn+1−tnh = t_{n+1} - t_nh=tn+1tn,近似解记为 yny_nyn

数值积分规则 公式 方法 局部截断误差
左矩形 ∫tntn+1f(s,y(s)) ds≈hf(tn,yn)\int_{t_n}^{t_{n+1}} f(s, y(s)) \, ds \approx h f(t_n, y_n)tntn+1f(s,y(s))dshf(tn,yn) 显式欧拉 O(h2)O(h^2)O(h2)
右矩形 ∫tntn+1f(s,y(s)) ds≈hf(tn+1,yn+1)\int_{t_n}^{t_{n+1}} f(s, y(s)) \, ds\approx h f(t_{n+1}, y_{n+1})tntn+1f(s,y(s))dshf(tn+1,yn+1) 隐式欧拉 O(h2)O(h^2)O(h2)
梯形 ∫tntn+1f(s,y(s)) ds≈h2[f(tn,yn)+f(tn+1,yn+1)]\int_{t_n}^{t_{n+1}} f(s, y(s)) \, ds\approx \frac{h}{2} \left[ f(t_n, y_n) + f(t_{n+1}, y_{n+1}) \right]tntn+1f(s,y(s))ds2h[f(tn,yn)+f(tn+1,yn+1)] 梯形法(隐式) O(h3)O(h^3)O(h3)
中点 ∫tntn+1f(s,y(s)) ds≈hf(tn+h2,yn+1/2)需预测\int_{t_n}^{t_{n+1}} f(s, y(s)) \, ds\approx h f\left(t_n + \frac{h}{2}, y_{n+1/2}\right) \quad \text{需预测}tntn+1f(s,y(s))dshf(tn+2h,yn+1/2)需预测 显式中点法 O(h3)O(h^3)O(h3)

补充:数值求解的形式

数值求解常微分方程(ODE)的最终目的,就是得到两组一一对应的离散数据:

  • 一组时间点 t0,t1,t2,…t_0, t_1, t_2, \dotst0,t1,t2,
  • 一组对应的数值解 y0,y1,y2,…y_0, y_1, y_2, \dotsy0,y1,y2,
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐