问题描述
我正在求解t = 0时的一组ODE(dy/dt),所有初始条件t = 0 y_0 =(0,0,0).我可以在不同的时间将一些数字添加到y值中吗(例如,在t = 10时,应将y1添加到该数字;在t = 20时,应将y2添加到该数字,等等)并求解方程式? /p>
I am solving a set of ODEs (dy/dt) at t=0, all initial conditions t=0 y_0=(0,0,0). Can I add some number to the y values at different times (e.g., at t=10, y1 should be added to that number; at t=20, y2 should be added to that number, etc.) and solve the equations?
推荐答案
按照建议的方式(以及@macduff所示的方式)在ODE中插入较大的不连续性可能会导致精度降低和计算时间延长(尤其是使用ode45
- ode15s
可能是一个更好的选择,或者至少可以使确保您的绝对和相对公差都合适).您已经有效地产生了一个非常僵硬系统.如果要在特定时间开始向ODE添加一些数字,请记住,求解器仅在自己选择的特定时间点对这些方程式求值. (不要误以为可以通过将tspan
指定为两个以上的元素来获得固定的步长输出-Matlab的所有求解器都是可变步长求解器,并根据误差标准选择它们的真实步长.)
Inserting large discontinuities in your ODE in the way you suggest (and the way illustrated by @macduff) can lead to less precision and longer computation times (especially with ode45
- ode15s
might be a better option or at least make sure that your absolute and relative tolerances are suitable). You've effectively produced a very stiff system. If you want to add some number to the ODEs starting at a specific time keep in mind that the solver only evaluates these equations at specific points in time of its own choosing. (Don't be mislead by the fact that you can obtain fixed step-size outputs by specifying tspan
as more than two elements – all of Matlab's solvers are variable step-size solvers and choose their true steps based on error criteria.)
更好的选择是分段集成系统,并将每次运行的结果输出附加在一起:
A better option is to integrate the system piecewise and append the resultant outputs from each run together:
% t = 0 to t = 10, pass parameter a = 0 to add to ODEs
a = 0;
tspan = [0 10];
[T,Y] = ode45(@(t,y)myfun(t,y,a),tspan,y_0);
% t = 10 to t = 20, pass parameter a = 10 to add to ODEs
a = 10;
[t,y] = ode45(@(t,y)myfun(t,y,a),tspan+T(end),Y(end,:));
T = [T;t(2:end)];
Y = [Y;y(2:end,:)];
% t = 20 to t = 30, pass parameter a = 20 to add to ODEs
a = 20;
[t,y] = ode45(@(t,y)myfun(t,y,a),tspan+T(end),Y(end,:));
T = [T;t(2:end)];
Y = [Y;y(2:end,:)];
Matlab编辑器可能会抱怨数组T
和Y
没有预先分配和/或增长,但是在这种情况下还可以,因为它们仅以大块增长几次.另外,如果要固定输出步长,可以执行以下操作:
The Matlab editor may complain about the array T
and Y
not being preallocated and/or growing, but it's fine in this case as they're growing in large chunks only a few times. Alternatively, if you want fixed output step-sizes, you can do this:
dt = 0.01;
T = 0:dt:30;
Y = zeros(length(T),length(y_0));
% t = 0 to t = 10, pass parameter a = 0 to add to ODEs
a = 0;
[~,Y(1:10/dt+1,:)] = ode45(@(t,y)myfun(t,y,a),T(1:10/dt+1),y_0);
% t = 10 to t = 20, pass parameter a = 10 to add to ODEs
a = 10;
[~,Y(10/dt+1:20/dt+1,:)] = ode45(@(t,y)myfun(t,y,a),T(10/dt+1:20/dt+1),Y(10/dt+1,:));
% t = 20 to t = 30, pass parameter a = 20 to add to ODEs
a = 20;
[~,Y(20/dt+1:end,:)] = ode45(@(t,y)myfun(t,y,a),T(20/dt+1:end),Y(20/dt+1,:));
如果需要,可以轻松地将上述两个代码块转换为更紧凑的for
循环.
One could easily convert both of the above blocks of code to more compact for
loops if desired.
在两种情况下,您的ODE函数myfun
都以这种方式合并参数a
:
In both cases your ODE function myfun
incorporates the parameter a
this way:
function ydot = myfun(t,y,a)
y(1) = ... % add a however you like
...
这篇关于Matlab ode求解器:更改状态和指定时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!