我在理解如何在微分方程的分辨率中实现octave / matlab中的事件时遇到了一些麻烦。
考虑这个简单的代码来解决微分方程y'= -y:
function dy = odefun(t,y)
dy = -y;
endfunction
options = odeset('RelTol',1e-4,'AbsTol',[1e-4]);
[T,Y] = ode45(@odefun,[0 12],[1],options);
现在我想介绍一个随机事件。例如,在某个固定时间步骤,我想随机改变y
的值,然后根据微分方程继续进化。我怎么能这样做?
答案 0 :(得分:2)
这样做的方法是分段整合系统并将每次运行的结果输出附加在一起:
% t = 0 to t = 6
tspan = [0 6];
y0 = 1;
options = odeset('RelTol',1e-4,'AbsTol',1e-4);
[T,Y] = ode45(@odefun,tspan,y0,options);
% t = 6 to t = 12
tspan = [6 12];
y0 = Y(end,:)+randn; % Pertubation
[t,y] = ode45(@odefun,tspan,y0,options);
T = [T;t(2:end)]; % Remove first value as it will be same as last of previous run
Y = [Y;y(2:end,:)];
Matlab编辑器可能会抱怨数组T
和Y
未被预先分配和/或增长,但在这种情况下它很好,因为它们只在大块中生长了几次。 / p>
你不想尝试做什么(但许多尝试)是在集成功能中添加你的扰动。首先,如果您希望它恰好在特定时间或特定条件满足时发生,则无法在ODE函数内完成。其次,在ODE中插入大的不连续性会导致精度降低和计算时间延长(特别是使用ode45
- ode15s
可能是更好的选择,或者至少确保您的绝对和相对容差是合适的) 。你本可以有效地制作一个非常stiff system。
如果您确实希望在满足特定条件时(而不是在特定时间)发生扰动,那么您将需要使用事件函数(例如,请参阅this question)。您需要使用事件函数在满足条件时终止集成,然后应用您在上面显示的扰动。