跳到主要内容

改进 Euler 法

一、直观理解:先预测,再按平均斜率校正​

经典 Euler 只用区间左端点的斜率,等于假设整段时间里变化率不变。改进 Euler 法(Heun 法 / 预测—校正的一种)多做半步思考:

  1. 预测:仍用 Euler 冲到终点,得到试探值 y∗y^*;
  2. 校正:计算终点处斜率 f(tn+1,y∗)f(t_{n+1},y^*),与起点斜率平均,再重新走一步。

公式为

y∗=yn+hf(tn,yn),yn+1=yn+h2[f(tn,yn)+f(tn+1,y∗)].\begin{aligned} y^* &= y_n + h f(t_n,y_n),\\ y_{n+1} &= y_n + \frac{h}{2}\Big[f(t_n,y_n)+f(t_{n+1},y^*)\Big]. \end{aligned}

直观上,这像过河时先按当前流向预估对岸位置,到了对岸再测一次流向,用两次流向的平均修正航线。平均斜率比“只信起点”更接近区间上的真实平均变化率,因此精度从一阶提升到二阶。

改进 Euler 仍是显式方法:校正步里的 y∗y^* 已知,不必解方程。它是理解 Runge–Kutta 家族的重要台阶,也是手写二阶方法时的常用选择。

二、适用场景与优缺点​

类型说明
适用场景非刚性 ODE,希望比 Euler 更准但实现仍保持简单;教学中演示预测—校正与二阶收敛;步数不多、需要自写求解器的建模题;作为 RK4/ode45 之前的中间基线。
核心优点全局误差 O(h2)O(h^2),通常明显优于同 hh 的 Euler;每步仅两次 ff 计算;公式透明,便于推导与调试;对光滑问题效率/精度比良好。
局限与缺点仍为显式,刚性不适用;精度低于经典 RK4 与自适应 ode45;预测—校正差未自动转化为步长控制(需自行设计);对强振荡/守恒系统,长期结构仍可能漂移。

使用前应确认:

  1. 问题非刚性,或已用特征值/时间尺度粗判;
  2. 有参照(解析解、ode45 或更小步长)以检验二阶收敛;
  3. 接受每步两次右端计算的成本;
  4. 终点时刻与输出网格已规划好。

三、核心原理:梯形思路与二阶精度​

1. 积分形式​

精确地,

y(tn+1)=y(tn)+∫tntn+1f(t,y(t)) dt.y(t_{n+1})=y(t_n)+\int_{t_n}^{t_{n+1}} f(t,y(t))\,dt.

Euler 用左矩形公式近似积分;改进 Euler 用梯形公式,但右端点的 y(tn+1)y(t_{n+1}) 未知,故先 Euler 预测再代入——这就是 Heun 显式化。

2. 误差​

对足够光滑的 ff,改进 Euler 的局部截断误差为 O(h3)O(h^3),全局误差为 O(h2)O(h^2)。步长减半时,全局误差大约降为原来的 1/41/4。

3. 与中点 Euler、RK2 的关系​

  • 中点法:先走半步取斜率,再整步前进,也是二阶;
  • 改进 Euler(Heun):两端斜率平均,同为二阶显式 RK;
  • 二者均属于两级二阶 Runge–Kutta,只是 Butcher 表不同。

4. 预测—校正监控​

量

δn=∥yn+1−y∗∥\delta_n=\|y_{n+1}-y^*\|

可粗略反映该步的局部不一致程度。δn\delta_n 突然变大,常意味着 hh 过大或解进入快变区域。

四、关键决策​

  1. 步长选择
    以二阶收敛为目标:比较 hh 与 h/2h/2 的末端误差比是否接近 4。

  2. 与 Euler 同屏对比
    同一 hh 下改进 Euler 应显著更准;若几乎一样,优先怀疑实现写错(例如校正步仍用了预测斜率公式错误)。

  3. 是否升级到 RK4/ode45
    当需要 1e-6 级相对误差、事件定位、密集输出或自动变步长时,不要停留在固定步长改进 Euler。

  4. 刚性判据
    若必须 hh 小到远小于输出间隔才能稳定,改用隐式或 ode15s。

  5. 向量化与质量
    对种群等模型,检查校正后是否破坏非负性;必要时对结果做物理可行投影并在报告中说明。

五、MATLAB 示例​

%% 改进 Euler(Heun)求解 y' = -y, y(0)=1
f = @(t, y) -y;
t0 = 0; tEnd = 2; y0 = 1;
h = 0.1;

t = t0:h:tEnd;
y = zeros(size(t));
y(1) = y0;
for n = 1:numel(t)-1
k1 = f(t(n), y(n)); % 起点斜率
yPred = y(n) + h * k1; % Euler 预测
k2 = f(t(n) + h, yPred); % 终点斜率(用预测值)
y(n+1) = y(n) + h/2 * (k1 + k2); % 梯形校正
end

yTrue = exp(-t);
errHeun = max(abs(y - yTrue));

% 同步长 Euler 对照
yE = zeros(size(t)); yE(1) = y0;
for n = 1:numel(t)-1
yE(n+1) = yE(n) + h * f(t(n), yE(n));
end
errEuler = max(abs(yE - yTrue));

figure;
plot(t, yTrue, "k-", "LineWidth", 1.5); hold on; grid on;
plot(t, yE, "s--");
plot(t, y, "o-");
legend("解析解", "Euler", "改进 Euler", "Location", "best");
xlabel("t"); ylabel("y");
title(sprintf("h=%.2f:Euler 最大误差=%.3e,改进 Euler=%.3e", h, errEuler, errHeun));

%% 收敛阶检验
hs = [0.2, 0.1, 0.05, 0.025];
err = zeros(size(hs));
for i = 1:numel(hs)
hi = hs(i);
ti = t0:hi:tEnd;
yi = zeros(size(ti)); yi(1) = y0;
for n = 1:numel(ti)-1
k1 = f(ti(n), yi(n));
yp = yi(n) + hi*k1;
k2 = f(ti(n)+hi, yp);
yi(n+1) = yi(n) + hi/2*(k1+k2);
end
err(i) = max(abs(yi - exp(-ti)));
end
disp(table(hs(:), err(:), [NaN, err(1:end-1)./err(2:end)]', ...
'VariableNames', {'h', 'maxErr', 'ratio'}));
% ratio 应接近 4

%% 逻辑增长方程:y' = r y (1 - y/K)
r = 1.2; K = 100;
fLog = @(t, y) r * y * (1 - y/K);
h = 0.05;
t = 0:h:10;
y = zeros(size(t)); y(1) = 5;
for n = 1:numel(t)-1
k1 = fLog(t(n), y(n));
yp = y(n) + h*k1;
k2 = fLog(t(n)+h, yp);
y(n+1) = y(n) + h/2*(k1+k2);
end

% 与 ode45 比较
[tRef, yRef] = ode45(@(t,y) fLog(t,y), [0 10], 5);

figure;
plot(t, y, "o-"); hold on; grid on;
plot(tRef, yRef, "k-", "LineWidth", 1.2);
yline(K, "--");
legend("改进 Euler", "ode45", "K", "Location", "best");
xlabel("t"); ylabel("y");
title("逻辑增长:改进 Euler 与 ode45");

通用实现:

function [t, Y] = improved_euler(f, tSpan, y0, h)
t = tSpan(1):h:tSpan(2);
if t(end) < tSpan(2) - 10*eps
t = [t, tSpan(2)];
end
m = numel(y0);
Y = zeros(numel(t), m);
Y(1,:) = y0(:).';
for n = 1:numel(t)-1
tn = t(n); hn = t(n+1) - t(n);
yn = Y(n,:).';
k1 = f(tn, yn);
yPred = yn + hn * k1;
k2 = f(tn + hn, yPred);
Y(n+1,:) = (yn + hn/2 * (k1 + k2)).';
end
end

六、如何解释结果​

解释改进 Euler 的结果时,重点不是“比 Euler 高级”,而是给出可核验的精度证据:

  1. 写出预测式与校正式,避免审稿者误以为仍是一阶 Euler;
  2. 报告 hh、函数计算次数(约 2N2N)与最大误差;
  3. 展示误差比接近 4 的表格,支撑二阶收敛;
  4. 与 ode45 在关键指标上的偏差;
  5. 若预测—校正差 δn\delta_n 在某时段升高,说明该处解变化快,应局部减小 hh;
  6. 说明方法适用边界:非刚性、中等精度。

对实际模型,把数值轨迹翻译为机制语言:例如逻辑增长是否单调趋于 KK、是否出现数值振荡越过 KK 等。

七、常见误区​

1. 校正步写成“再用一次 Euler”​

常见错误是 yn+1=y∗+hf(tn+1,y∗)y_{n+1}=y^*+h f(t_{n+1},y^*),这并不是 Heun,精度与稳定性都会变差。

2. 以为二阶方法不再需要步长检验​

阶数提高只改变收敛速度,不自动保证当前 hh 已足够。

3. 用改进 Euler 硬解刚性化学动力学​

显式二阶稳定域仍然有限,刚性下应换方法。

4. 只比较终点误差​

有的问题终点碰巧接近,中间峰值已偏。应报告区间上的最大范数误差或关键特征量误差。

5. 把 Heun 与改进欧拉的中点版本混称却公式不一致​

名称在教材中略有出入。论文中应直接给出公式,避免名词歧义。

八、小结​

改进 Euler 法的核心思想可以概括为:

先用 Euler 预测终点,再取起点与预测终点斜率的平均作为本步有效斜率,从而把积分精度提升到二阶。

它在“实现成本”和“精度”之间取得了很好的折中,是手写 ODE 求解器的重要一环。建模时可用它快速获得可信的中等精度轨迹,但在最终定量结论上,仍建议用步长收敛和 ode45 等自适应方法复核。