前几章我们一直在寻找解析解:分离变量、积分因子、相线、模型方程。可是很多初值问题并不会给出漂亮的公式。方程可能来自混合问题、带阈值的人口模型、速度依赖的阻力,甚至只是实验数据拟合出的右端函数。
数值方法处理的是另一种问题:如果只知道变化规律
怎样从初始点出发,一步一步算出近似的解曲线?
本章只讲第一层入门:Euler 方法、改进 Euler 方法,也叫 Heun 方法,以及四阶 Runge-Kutta 方法。重点不是严格证明误差阶,而是看清每个方法怎样使用斜率、步长怎样改变结果、数值解和方向场怎样对应。
把时间轴切成等距网格:
这里的 叫步长。我们希望计算一串数
使得 近似真实解在 处的值:
数值方法的基本动作是“从已知点走到下一个点”。如果已经有 ,微分方程会告诉我们当前位置的斜率:
于是一个最自然的近似是:在短短的一步内,先把曲线看成一条直线。

图:Euler 方法把每一步的局部斜率当成短时间内的行进方向。
数值解不是“猜几个点”。每一个新点都由微分方程右端 算出来。算法的差别,主要在于它怎样估计这一小段上的平均斜率。
本章会反复使用同一个初值问题:
它的好处是右端不太简单,但真实解又可以写出来:
这样我们能把数值解和参考解直接比较。现实问题通常没有这个便利,所以“能和参考解比较”的例子适合训练直觉。
Euler 方法的想法很直接。已知 后,把 当成这一小段上的斜率,于是
这就是 Euler 公式。它只取一次斜率,所以便宜、好算,也容易画在方向场上。
用步长 近似
从 和 开始。当前斜率是 ,所以第一步给出
把这些数和参考解比较:
这里的负误差说明折线落在参考解下方。原因不是最后一步突然错了,而是每一步都只用左端斜率估计整段变化,前面的偏差又会进入后面的斜率计算。
常见错误是把 直接当成下一个 值。斜率不是高度, 才是这一小步内的高度变化量。少乘步长,单位也会错。
数值误差有两个层次。
局部误差说的是:如果某一步从真实点 出发,只走这一小步,算法会偏多少。全局误差说的是:真正算到 时, 和 差多少。
记
这就是第 个网格点上的全局误差。它会受到两件事影响:这一小步本身的近似误差,以及前面所有步骤留下来的偏差。

图:局部误差只看一步,全局误差会带着前面每一步的偏差继续传播。
步长越小,通常折线越贴近曲线。对足够光滑、不过分敏感的初值问题,Euler 方法的全局误差大致随 成比例下降。也就是说,把步长减半,误差常常会接近减半。这个说法是直觉层面的经验,本章不证明。

图:同一方法下,步长变小会让折线更密,也更贴近参考解。
但步长不是越小越随便。步长小意味着步骤数多,计算成本上升;在很长时间区间里,舍入误差也会积累。对一些刚性方程,步长还会影响稳定性,过大的步长可能让数值解出现真实模型里没有的振荡或爆炸。
不要只看“最后的数值很接近”。数值方法还要看步长、时间区间、右端函数的光滑程度,以及问题是否敏感。一个方法在短区间表现好,不代表它在长时间模拟里一定可靠。
Euler 方法只听左端点的斜率。若曲线弯得明显,左端斜率就不能代表整段的平均变化。
改进 Euler 方法的想法是:先用 Euler 预测终点,再在预测终点处算一个斜率,最后取两个斜率的平均值。
设
先预测
再计算预测终点的斜率
最后用平均斜率更新:

图:改进 Euler 先预测,再用起点和预测终点的斜率做校正。
这个方法也叫 Heun 方法。它仍然很容易手算,但每一步要算两次右端函数。换来的好处是,它对弯曲的响应比 Euler 方法更好。
还是用
步长取 。第一步中,
Euler 预测点为
预测终点处的斜率是
所以改进 Euler 给出
参考解在 处约为 。Euler 第一步得到 ,改进 Euler 得到 ,已经明显靠近参考解。
用 算到 :
改进 Euler 的核心不是“公式更长”,而是它承认一步之内斜率会变。先预测终点,再用两端斜率估计平均斜率,这是很多高阶方法的共同思想。
四阶 Runge-Kutta 方法,常简写为 RK4,是常微分方程入门中最常用的高精度显式方法之一。它仍然只从 出发走到 ,但在一步内取四次斜率。
定义
然后更新
这不是简单地平均四个斜率,而是给两个中点斜率更高权重。权重比是

图:RK4 在一步中多次估计斜率,用加权平均决定最终更新方向。
为什么中点斜率更重要?因为一步的变化更像由区间内部的趋势决定,而不是只由端点决定。RK4 的公式来自 Taylor 展开和斜率采样的精细配合;本课不展开推导,只保留它的使用方式和直觉。
对同一个初值问题,用 算到 :
这个例子中,RK4 用同样步长给出了很接近的结果。它不是每个问题都“万无一失”,但在光滑、非刚性的普通初值问题上,RK4 往往是很稳的第一选择。
比较方法时要分清“同步长”和“同计算量”。RK4 每步要算四次 。如果函数计算很贵,同样的计算预算下未必总能直接使用最小步长的 RK4。
把步长也纳入比较,结果会更清楚:
同一个表里能读出三件事。
第一,步长变小会让三种方法都变好。第二,高阶方法通常能用较大的步长达到更小误差。第三,误差不是唯一指标,方法需要的函数计算次数也要算进去。

图:三种方法都在估计平均斜率,只是花费的斜率信息不同。
在实际建模里,可以把这张表转化为一个工作流程:
先用较粗步长试算,观察解的数量级和图像趋势是否合理。不要一开始就追求很多小数位。
把步长减半,再算一次。如果两次结果差异很大,说明当前步长还不可靠,或者模型本身对初值和参数很敏感。
换一种更高阶的方法交叉检查。若 Euler、改进 Euler 和 RK4 在较小步长下给出相近趋势,可信度会高很多。
回到模型语境解释结果。数值解只是近似轨迹,最后还要看单位、参数、初值和现实假设是否合理。
方向场告诉我们每个点附近的“应该往哪里走”。数值方法把这种局部方向变成一串点。两者不是分开的工具,而是同一件事的几何面和计算面。

图:方向场给出局部方向,数值算法给出下一点,表格记录近似轨迹。
有了方向场,很多数值错误会更容易被发现。比如方程的方向场显示解应该单调上升,但数值折线突然剧烈下降,这通常说明步长太大、公式用错,或者右端函数输入点写错。相反,如果方向场本身已经显示不同初值附近的解会快速分离,那么数值结果对步长和初值敏感就不是意外。
在模型问题中,建议同时保留三样东西:方程、图像和表格。
数值方法给出的不是解析公式,而是一条可检查的近似轨迹。它的可靠性来自多重核对:换步长、换方法、看方向场、回到模型单位。
对初值问题
用 Euler 方法和步长 计算到 。
先算 ,所以
同样的初值问题
用改进 Euler 方法和步长 做一步,近似 。
起点斜率为
Euler 预测点是
解释下面这句话为什么不完整:“RK4 一定比 Euler 好,所以总是直接用 RK4。”
RK4 在许多光滑、非刚性的初值问题中精度很好,但它每步要计算四次 。如果右端函数计算很贵,计算预算需要一起考虑。某些刚性问题中,显式 RK4 也可能受步长稳定性限制。更稳妥的说法是:RK4 是常用的高精度显式方法,但仍要配合步长检查、模型判断和必要的稳定性分析。
某模型的方向场显示,在 时解应该缓慢上升并趋近 。你用 Euler 方法算出的轨迹却在 附近上下大幅震荡。最可能先检查什么?
先检查步长是否太大。Euler 方法只用当前斜率外推,靠近平衡值时如果步长过大,可能越过平衡点太多,再被反向斜率拉回来,形成真实解没有的数值振荡。还要检查右端函数和初值是否输入正确,但从现象看,步长过大是最直接的嫌疑。
Euler 方法把当前斜率当成整步斜率,所以简单,但误差容易积累。改进 Euler 先预测再校正,用两端斜率的平均值改善一步内的斜率估计。RK4 在一步内取四次斜率,用 的权重形成更准确的更新方向。
学到这里,数值方法不应只是三条公式。你应该能看着方向场解释数值折线怎样走,能用步长减半检查结果是否稳定,也能在模型语境里判断一个近似值是否可信。下一次遇到没有解析解的初值问题,我们至少已经知道怎样把“变化规律”变成一条可计算、可检查的轨迹。
到了 ,用新的点重新计算斜率:
因此
继续到 ,斜率为 ,于是
最后到 ,斜率为 ,所以
这就是 Euler 方法在 处的近似值。
| 0 | 0.500000 | 0.500000 | 0.000000 |
| 0.5 | 1.250000 | 1.425639 | -0.175639 |
| 1.0 | 2.250000 | 2.640859 | -0.390859 |
| 1.5 | 3.375000 | 4.009155 | -0.634155 |
| 2.0 | 4.437500 | 5.305472 | -0.867972 |
此时 。再算
所以
Euler 方法给出 。
预测终点处的斜率为
改进 Euler 给出