你的 RK4 函数正在采取比那些小得多的固定步骤ode45
正在服用。您真正看到的是由于以下原因造成的错误多项式插值 https://en.wikipedia.org/wiki/Polynomial_interpolation用于产生真实步骤之间的点ode45
需要。这通常被称为“密集输出”(参见海尔和奥斯特曼 1990 http://dx.doi.org/10.1007/BF01385634).
当您指定一个TSPAN
具有两个以上元素的向量,Matlab ODE 套件求解器 http://www.mathworks.com/help/matlab/ordinary-differential-equations.html产生固定步长的输出。这并不意味着他们实际上使用固定步长或他们使用您中指定的步长TSPAN
然而。您可以看到使用的实际步长,并且仍然可以通过以下方式获得所需的固定步长输出ode45
输出结构并使用deval http://www.mathworks.com/help/matlab/ref/deval.html:
sol = ode45(f,tspan,x0);
diff(sol.x) % Actual step sizes used
y_ode45 = deval(sol,tspan);
在执行初始步骤后您会看到0.02
,因为你的 ODE 很简单,所以它收敛于0.1
用于后续步骤。默认容差与默认最大步长限制(积分间隔的十分之一)相结合决定了这一点。让我们绘制真实步骤的误差:
exactsol = @(t)(4/1.3)*(exp(0.8*t)-exp(-0.5*t))+2*exp(-0.5*t);
abs_err_ode45 = abs(exactsol(tspan)-y_ode45);
abs_err_ode45_true = abs(exactsol(sol.x)-sol.y);
abs_err_rk4 = abs(exactsol(tspan)-y);
figure;
plot(tspan,abs_err_ode45,'b',sol.x,abs_err_ode45_true,'k.',tspan,abs_err_rk4,'r--')
legend('ODE45','ODE45 (True Steps)','RK4',2)
正如您所看到的,真实步骤的误差比 RK4 的误差增长得更慢(ode45
实际上是比 RK4 更高阶的方法,所以您会预料到这一点)。由于插值,误差在积分点之间增大。如果您想限制这一点,那么您应该通过调整容差或其他选项odeset http://www.mathworks.com/help/matlab/ref/odeset.html.
如果你想强行ode45
使用步骤1/50
你可以这样做(有效,因为你的 ODE 很简单):
opts = odeset('MaxStep',1/50,'InitialStep',1/50);
sol = ode45(f,tspan,x0,opts);
diff(sol.x)
y_ode45 = deval(sol,tspan);
对于另一个实验,尝试扩大积分间隔以积分到t = 10
或许。您将在错误中看到许多有趣的行为(绘制相对错误在这里很有用)。你能解释一下吗?你能用吗ode45
and odeset
产生表现良好的结果?使用自适应步骤方法对大区间内的指数函数进行积分具有挑战性,并且ode45
不一定是完成这项工作的最佳工具。有备择方案 http://en.wikipedia.org/wiki/Numerical_methods_for_ordinary_differential_equations#The_first-order_exponential_integrator_method然而,但它们可能需要一些编程。