我有一个2个ODE的系统,我希望将这个系统适用于某些数据,以便估算一些模型参数。
有两个数据集。我想同时将模型拟合到这两个数据集,并且当适合两个数据时参数应该相同。
我得到的数据是一段时间内的总数。例如,在data1
中,第一个元素是在2-4小时的时间段内的状态A的总和。因此,对于每个tiem间隔,我在每个数据集中具有该时间段的总数。
因此,当我同时适应两个数据集时,我还必须适应4个时间间隔(2-4,5-7,8-10,11-13)。
如果数据仅在一个连续时间段内给出,例如时间= 2:13,我知道如何估计参数。但现在我不确定我实现这个的方式是否正确。这是我写的代码。
%data
t=[2 3 4;5 6 7;8 9 10; 11 12 13];
data1=[5.399537437;6.762059387;7.34552533;7.675700967];
data2=[0.153279989125067;7.395870359956480;3.519156383296502;2.553056632299227];
%initial guesses
k0=[0.001;0.001;0.001];
lb=[0,0.0002,0];
ub=Inf*ones(1,3);
x={t,data1,data2};
[fittedVal,fval]=fmincon(@(k)ssq(k,x),k0,[],[],[],[],lb,ub)
function error=ssq(k,x)
time=x{1,1};
data1=x{1,2};
data2=x{1,3};
error=0;
for it=1:4
fitted=model(k,time(it,:));
error=error+(sum((fitted-data1(it)).^2))+(sum((fitted-data2(it)).^2));
end
end
function output= model(k,time)
b0=[0;3.13];%initial conditions
[time,values] = ode45(@Equations,time,b0);
function s=Equations(t,y)
s= zeros(2,1);
rep=0.204;
ag=0.3368;
carrying=10^9;
carrying2=1*10^8;
s(1)=(rep*y(1))*(1-(y(1)/carrying))-k(2)*ag*y(1)*(1-(y(2)/carrying2))+k(3)*y(2);
s(2)=k(2)*ag*y(1)*(1-(y(2)/carrying2))+k(1)*y(2)-k(3)*y(2);
end
output=values(:,2)+values(:,1);
end
为了适应所有数据点我正在使用for循环。这是正确的方法吗?
在此我不确定是否必须在for循环中累积error
。
另外,因为这些时间点是相关的,当我从5-7开始时间段时,2-4中的数据应该有影响,我想改变颂求解算器的初始条件{{1将前一时间点的模型结果的最终值作为下一时间段的初始条件。
我怎么能这样做,因为在每次ode45
循环迭代时我都有b0 = [0; 3.13]