我正在尝试使用ODE系统对某些数据拟合曲线。 ODE系统根据预定义的时间点改变到不同的ODE系统。
我在下面构建了一个简单的例子来说明。
function examplefitting
init = [1];
expdata = [10;40;70;76;80;90;101;110;150;180;200;202;215;240;245]';
time = [5;10;15;20;25;30;35;40;50;55;60;65;70;75;80]';
[x,resnorm] = lsqcurvefit(@data,init,time,expdata);
function z = data(init,time)
alpha = init(1);
y0 = 100;
tout = [];
yout = [];
for i = 2:5
tvec = [0 15 30 50 65];
u = [1 0 1 0 1];
[t y] = ode23s(@Model,[tvec(i-1) tvec(i)],y0,[],alpha,u(i-1));
nt = length(t);
tout = [tout;t];
yout = [yout;y];
y0 = [y(nt,1)];
end
z = yout;
function Y = Model(t,y,alpha,u)
if u == 0
Y(1) = y(1).^alpha;
elseif u == 1
Y(1) = alpha*y(1);
end
Y = Y.';
你可以看到,因为我必须停止积分器并重置它,输出的长度和原始数据输入的长度不同。这会导致“功能值和YDATA大小不相称”的错误。有没有一种方法可以提取最合适的alpha,因为它出现在两个不同的ODES系统中,根据时间切换。
答案 0 :(得分:0)
可能还没回答,但有些建议。
首先,将参数传递给集成函数的现代(和更快)方法是使用匿名函数:
[t,y] = ode23s(@(t,y)Model(t,y,alpha,u(i-1)),[tvec(i-1) tvec(i)],y0);
其次,你要两次追加一些值。将tvec
和u
移到for
循环之外,因为它们是常量,并将tout
和yout
初始化为初始时间和状态
tout = tvec(1);
yout = y0;
然后,在你的循环中添加如下新数据:
tout = [tout;t(2:end)];
yout = [yout;y(2:end,:)];
最后,我想知道您是否可以通过指定固定的步长输出来解决您的问题。您可以通过将tspan
设置为两个以上元素的向量来完成此操作。然后积分器只会在那些特定时间返回点。