我正在使用Matlab来解决微分方程。我想强制ode45采取恒定步长,因此在求解方程时它总是在T轴上增加0.01。我该怎么做?
ode45始终采取优化的随机步骤,我似乎无法弄清楚如何使其采取0.01的一致,小步骤。这是代码:
options= odeset('Reltol',0.001,'Stats','on');
%figure(1);
%clf;
init=[xo yo zo]';
tspan=[to tf];
%tspan = t0:0.01:tf;
[T,Y]=ode45(name,tspan,init,options);
答案 0 :(得分:12)
基于the documentation,在解决方程式时,您似乎无法控制ode45
内部采取的步骤的大小,但可以控制时间生成输出的点。您可以按照注释掉的行显示:
tspan = to:0.01:tf; % Obtain solution at specific times
[T, Y] = ode45(name, tspan, init, options);
关于使用固定步长时解决方案的准确性,请参阅以上链接中的摘录:
如果
tspan
有两个以上的元素[t0,t1,t2,...,tf]
,则求解器返回在给定点评估的解。但是,求解器不会精确地步进tspan
中指定的每个点。相反,解算器使用自己的内部步骤来计算解决方案,然后在tspan
中的请求点评估解决方案。在指定点生成的解决方案与在每个内部步骤计算的解决方案具有相同的准确度。指定几个中间点对计算效率影响不大,但对于大型系统,它可能会影响内存管理。
因此,即使您指定要在输出中的特定时间点使用解决方案,解算器仍然会在指示的时间点内部执行大量自适应步骤,即将关闭到那些固定时间点的值。
答案 1 :(得分:5)
ode45
总是使用自适应步长the documentation addresses this issue并建议使用其他求解器来固定步长 - 请参阅ode4
(四阶Runge-Kutta),这是一个相当安全的解决方案大多数颂歌 - 至少根据Numerical Recipes
答案 2 :(得分:4)
这可以做到只需要使用更多命令。
NEW:
options= odeset('Reltol',0.001,'Stats','on');
%figure(1);
%clf;
init=[xo yo zo]';
to=some number;
tf= some number;
nsteps= number of points you want function evaluated on.
tspan = linspace(t0,tf, nsteps);
[T,Y]=ode45(@function,tspan,init,options);
您可以使用命令大小(变量)验证它是否需要使用您想要的数字点。
答案 3 :(得分:2)
嗯,你不能确保它只能计算这些步骤,但是你可以确保最大的步长(如果你做得足够小,你几乎可以确定你有所有想要的时间,只需要那些样本) :
options= odeset('MaxStep',1);
[t,s] = ode45(@myode,tspan,[0;0],options);
了解更多信息,您可以访问here:
答案 4 :(得分:1)
您的脚本未指示固定步长,它仅显示将根据提供的时间步长打印解决方案。尝试检查ODE的解决方案结构,您会意识到它实际上使用了不同的时间步长。
使用固定时间步长的最佳方法是确保RelTol和AbsTol都足够大。
答案 5 :(得分:1)
ODE45(说四五不四十五)计算最佳步长,如果误差很大,甚至可以追溯到时间,如果你感兴趣,请检查Runge-Kutta。作为用户,您不会注意到这一点,因为ODE的输出将被内插,以适合tspan向量。因此,如果你将tspan设置为0:1E-5:1并且想要集成一个简单的ODE,例如dydt = -y ODE45将会做几步,但是你从ode中获得的vektor将在tspan中声明的时间步长即1E-5。如果你想要整合刚性方程dydt = 1E2 *(1-y)* y ODE45会做出很大很小的步骤但是输出会是相同的,因为后来你应该使用ode15s,因为ODE45无法处理僵硬的系统。
希望这有帮助
欢呼声 马可