思想原理
必须要陈述一个事实,那就是欧拉方法在实际中是不采用的,因为误差较大,虽然可以增加段数,但是增加了段数,每个小误差累加起来也会很大,所以必须提出改进。
这时候,亨氏这个人就很巧妙的提出了他的方法。
有一个这样的问题,那就是欧拉方法很明显的误差,就是对于凹曲线的函数图像,以初始点做的切线延伸到下个点时的函数值总会比真实值要么大要么小。如下图。
那怎么可以更好的接近真实值呢?答案就是你不是总是要么大要么小么,那我来个折中。如下图。那怎么折中呢,那就用欧拉方法预测下个点的函数值,但是呢我用这个预测的点在求出一个斜率,这样就有两个斜率(一个欧拉求得的斜率,一个欧拉预测的点的斜率),那么取得一个平均,那么就得到了相对近似的斜率,再用这个斜率带入欧拉公示求近似的函数值。
MATLAB 代码
fun = @(x,y) (x+y);
% 欧拉近似值
re = euler_method(fun,0,2,1,0.25);
fprintf('result is %f\n',re);
% 准确值
xx = 0:0.25:1;
yy = 3*exp(xx)-xx-1;
plot(xx,yy,'b');
legend('Euler','Point','Exact');
% Euler Method
% f 表示一阶常微分方程
% (x0,y0):初始值
% xn要求的函数值的自变量的值
% h 步长
function y = euler_method(f,x0,y0,xn,h)
n = round((xn-x0)/h);
y = y0;
x = x0;
xa = [];
xa(1) =x0;
re = [];
re(1) = y;
for i=1:n
y = y + h*f(x,y);
x = x + h;
% 保存段点值,用于绘图
xa(i+1)=x;
re(i+1)=y;
end
plot(xa,re,'r');
hold on;%不清除画面
scatter(xa,re,'*');% 描点
end
Result: