我正在使用简单的if循环来更改我的ode脚本中的参数值。这是我写的一个示例脚本,它表现出同样的问题。首先是有效的版本:
function aah = al(t,x)
if (t>10000 && t<10300)
ab = [0; 150];
else
ab = [150; 0];
end
aah = [ab];
这可以使用
运行t = [0:1:10400];
x0 = [0,0];
[t,x] = ode23tb(@al, t,x0);
并用
显示plot(t,x(:,1))
plot(t,x(:,2))
好的,那是好的版本。现在,如果您所做的只是改为
t = [0:1:12000];
整个事情爆发了。您可能认为这只是matlab对图表进行平均化,但并不是因为如果您查看
x(10300,2)
答案在两种情况下都应该相同,因为代码没有改变。但是这第二个版本输出0,这是错误的!
到底是怎么回事?有人有想法吗?
非常感谢您的帮助
答案 0 :(得分:3)
您的函数是常量(10000&lt; t&lt; 10300除外),因此内部求解器开始以非常大的时间步长求解系统,默认情况下占总时间的10%。 (在自适应ODE求解器中,如果系统是常数,则高阶和低阶解决方案将给出相同的解,并且(估计的)误差将为零。因此求解器假定当前时间步长足够好。)您可以看看你是否只给tspan
两个元素,即开始和结束时间。
t = [0 12000];
通常tspan
不会影响求解器的内部时间步长。求解器用其内部时间步长求解系统,然后在用户给出的tspan
处进行插值。因此,如果内部时间步骤不幸地“跳过”间隔[10000,10300],则解算器将不知道间隔。
所以你最好设置最大步长,相对小于300。
options = odeset('MaxStep', 10);
[t, x] = ode23tb(@al, t, x0, options);
如果你不想一直用小步长解决(如果你“知道”函数不是常数时),你应该单独解决。
t1 = [0 9990];
t2 = [9990 10310];
t3 = [10310 12000];
[T1, x1] = ode23tb(@al, t1, x0);
[T2, x2] = ode23tb(@al, t2, x1(end,:));
[T3, x3] = ode23tb(@al, t3, x2(end,:));
T = [T1; T2(2:end); T3(2:end)];
x = [x1; x2(2:end,:); x3(2:end,:)];