我正在尝试使用ode15s
解决严格的ODE。在仿真过程中,求解器在某些点的步长很小,我想更深入地研究一下。
取决于模型参数,系统可以具有> 1000个状态,因此我使用的步长具有固定的步长(否则,状态会保存在我实际上不需要的每个微小步长上,并且占用太多RAM)。 ODE求解器仍然使用可变步长(应如此)。
但是,我想获得ODE求解器使用的“实际”时间向量,以分析为什么求解器对某些状态/跃迁采取如此小的步骤。除了固定步长时间向量t
和状态矩阵y
之外,我如何获得此时间向量?
MCVE:
tspan = [0 2000];
tstep = 10;
tspan_fix = tspan(1):tstep:tspan(2);
[t_fix,y_fix] = ode15s(@vdp1000, tspan_fix, [2 0]);
tspan_var = tspan;
[t_var,y_var] = ode15s(@vdp1000, tspan_var, [2 0]);
figure(1); clf;
subplot(211)
plot(t_fix,y_fix(:,1),'-o')
subplot(212)
plot(t_var,y_var(:,1),'-o')
因此,如您所见,ode15s
在两种情况下都将使用可变步长,但是评估解决方案的点有所不同。我想保持固定的步长,但是看看求解器在哪里执行这些小步长会很有趣。
更像是现实生活(使用outputFcn等):
% set ode plot/log settings
odeOpts = odeset();
if usejava('desktop')
% use figure progressbar if interactive session
odeOpts = odeset(odeOpts, 'OutputFcn',@odeprog,'Events',@odeabort);
% odeOpts = odeset(odeOpts, 'OutputFcn',@outputFcnWrapper); % to use multiple outputfcn / eventfcn
else
% otherwise print progress every 1 ms of simulation
odeOpts = odeset(odeOpts, 'OutputFcn', @(t,y,flag)odeprogress_mini(t,y,flag,PM.Tend));
end
% set ode integration settings
odeOpts = odeset(odeOpts, 'stats', 'on');
% numerical integration
tstep = 0.01; % ms
Tend = 40; % ms
tspan = 0:tstep:Tend;
[t, y] = ode15s(@(t, y) myode(t, y), tspan, y0);