跳至主要內容

常微分方程的数值解法

大约 3 分钟

常微分方程的数值解法

主要研究以下常微分方程的数值解法

{dydx=f(x,y),微分方程y(x0)=y0,初值条件 \begin{cases}\frac{dy}{dx}=f(x,y),&\text{微分方程}\\y(x_0)=y_0,&\text{初值条件}\end{cases}

欧拉法

欧拉法

微分方程中 f(x,y)f(x,y) 表征了对于微分方程的解 y=y(x)y=y(x) 于点 P(x,y)P(x,y) 上的导数

因此当步长足够小时, 利用导数的性质可以得到

yn+1ynxn+1xnf(xn,yn) \frac{y_{n+1}-y_{n}}{x_{n+1}-x_{n}}\approx f(x_n,y_n)

因此可以设定固定的步长 hh 从初值点 P0(x0,y0)P_0(x_0,y_0) 递推到目标点 Pn(xn,yn)P_n(x_n,y_n), 有

yt=yt1+hf(x0+th,yt1) y_{t}=y_{t-1}+h\cdot f(x_0+th,y_{t-1})

后退欧拉法

于欧拉法类似, 但采用后推型的近似式以实现迭代 (注意右侧系数的区别)

yn+1ynxn+1xnf(xn+1,yn+1) \frac{y_{n+1}-y_{n}}{x_{n+1}-x_{n}}\approx f(x_{n+1},y_{n+1})

其中 yn+1y_{n+1} 无法直接得到, 可先使用 yny_{n} 近似

yt(0)=yt1+hf(xt1,yt1) y_{t}^{(0)}=y_{t-1}+h\cdot f(x_{t-1},y_{t-1})

再迭代得到更精确的值 (注意下标)

yt(k)=yt1+hf(xt,yt(k1)) y_{t}^{(k)}=y_{t-1}+h\cdot f(x_t,y_{t}^{(k-1)})

梯形欧拉法

根据数值积分的梯形公式, 结合欧拉法与后退欧拉法, 可以得到更精确的迭代式

yt(k)=yt1+h2[f(xt1,yt1)+f(xt,yt(k1))] y_{t}^{(k)}=y_{t-1}+\frac{h}{2}[f(x_{t-1},y_{t-1})+f(x_{t},y_{t}^{(k-1)})]

改进欧拉法

即仅迭代一次的梯形法, 将迭代初值称为预测值

{ytˉ=yt1+hf(xt1,yt1),预测值yt=yt1+h2[f(xt1,yt1)+f(xt,ytˉ)],校正值 \begin{cases}\bar{y_{t}}=y_{t-1}+h\cdot f(x_{t-1},y_{t-1}),&\text{预测值}\\ y_{t}=y_{t-1}+\frac{h}{2}[f(x_{t-1},y_{t-1})+f(x_{t},\bar{y_{t}})],&\text{校正值}\end{cases}

数值解法的精度

局部截断误差

假设前 ii 步的计算结果均为正确, 则在第 ii 步有局部截断误差 (注意是同级精确值 - 同级计算值)

Ri=y(xi+1)yi+1 R_{i}=y(x_{i+1})-y_{i+1}

算法精度

当截断误差满足 (o(pn)o(p^n) 表示高阶无穷小, O(pn)O(p^n) 表示等价无穷小)

Ri=khp+1+o(pp+2)=O(pp+1) R_{i}=kh^{p+1}+o(p^{p+2})=O(p^{p+1})

由于截断误差在每次递推的过程都存在, 因此阶数还需要再降低, 由此定义, 此时此算法具有 pp 阶精度

欧拉法与后退欧拉法的精度

对于这两种方法, 利用泰勒展开可以得到, 均有 p=1p=1, 属于一阶精度

梯形欧拉法精度

对于梯形欧拉法, 有 p=2p=2, 属于二阶精度

精度计算

  • 认为之前 ii 步均没误差, 因此有

y(xi)=f(xi,yi) y'(x_i)=f(x_i,y_i)

  • 由于步长确定, 因此可以展开 xi+1=xi+hx_{i+1}=x_i+h
  • 由于 xi+1xi=hx_{i+1}-x_i=h 已知, 因此可以使用泰勒展开

y(xi+h)y(xi)=y(xi)+hy(xi)+h22y(xi)++hnn!y(n)(xi)+O(hn+1) y(x_i+h)-y(x_i)=y(x_i)+hy'(x_i)+\frac{h^2}{2}y'(x_i)+\dots+\frac{h^n}{n!}y^{(n)}(x_i)+O(h^{n+1})

  • 对于 f(xi+1)f(xi)=y(xi+1)y(xi)f(x_{i+1})-f(x_i)=y'(x_{i+1})-y'(x_i) 也可对 y(x)y'(x) 使用泰勒展开
  • 变形 y(xi+1)+y(xi)=[y(xi+1)y(xi)]+2y(xi)y(x_{i+1})+y(x_i)=[y(x_{i+1})-y(x_i)]+2y(x_i)