我有三个方程的所有数据和ODE系统,它有9个未知系数(a1,a2,...,a9)。
dS/dt = a1*S+a2*D+a3*F
dD/dt = a4*S+a5*D+a6*F
dF/dt = a7*S+a8*D+a9*F
t = [1 2 3 4 5]
S = [17710 18445 20298 22369 24221]
D = [1357.33 1431.92 1448.94 1388.33 1468.95]
F = [104188 104792 112097 123492 140051]
如何使用Matlab找到ODE的这些系数(a1,...,a9)?
答案 0 :(得分:1)
你有一个常微分方程的线性耦合系统,
y' = Ay with y = [S(t); D(t); F(t)]
并且您正在尝试解决逆问题,
A = unknown
有趣!
对于给定的A
,可以通过分析方式解决此类系统(例如,阅读the wiki)。
3x3设计矩阵A
的一般解决方案采用
[S(t) D(t) T(t)].' = c1*V1*exp(r1*t) + c2*V2*exp(r2*t) + c3*V3*exp(r3*t)
V
和r
分别为A
和c
标量的特征向量和特征值,通常由问题的初始值决定。
因此,似乎有两个步骤可以解决这个问题:
c*V
和标量r
A
。然而,沿着这条路走下去是一件好事。你必须解决你所拥有的指数和方程的非线性最小二乘问题(例如,使用lsqcurvefit
)。这将为您提供向量c*V
和标量r
。然后,您必须以某种方式解开常量c
,并使用A
和V
重建矩阵r
。
因此,您必须求解c
(3个值),V
(9个值)和r
(3个值)来构建3x3矩阵{{1 (9个值) - 这对我来说似乎太复杂了。
有一种更简单的方法;使用暴力:
A
到目前为止一切顺利。
然而,我尝试了复杂的方法和上面的蛮力方法,但我发现很难在任何接近小的范围内得到平方误差。
经过多次尝试后我能找到的最佳解决方案:
function test
% find
[A, fval] = fminsearch(@objFcn, 10*randn(3))
end
function objVal = objFcn(A)
% time span to be integrated over
tspan = [1 2 3 4 5];
% your desired data
S = [17710 18445 20298 22369 24221 ];
D = [1357.33 1431.92 1448.94 1388.33 1468.95 ];
F = [104188 104792 112097 123492 140051 ];
y_desired = [S; D; F].';
% solve the ODE
y0 = y_desired(1,:);
[~,y_real] = ode45(@(~,y) A*y, tspan, y0);
% objective function value: sum of squared quotients
objVal = sum((1 - y_real(:)./y_desired(:)).^2);
end
这一点都不错:)但我会喜欢一个不太难找到的解决方案......
答案 1 :(得分:1)
我不能在此花费太多时间,但基本上你需要使用数学来将等式减少到更有意义的东西:
你的等式是
的顺序dx / dt = A * x
解决方案是
x(t-t0)= exp(A *(t-t0))* x(t0)
因此
exp(A *(t-t0))= x(t-t0)*伪(x(t0))
Pseudo是Moore-Penrose Pseudo-Inverse。
编辑:第二次看我的解决方案,我没有正确计算伪逆。基本上,伪(x(t0))= x(t0)'* inv(x(t0)* x(t0)'),如x(t0)* Pseudo(x( t0))等于单位矩阵
现在您需要做的是假设每个时间步骤(1到2,2到3,3到4)是一个实验(因此t-t0 = 1),所以解决方案是:
1-构建伪逆:
xt = [S;D;F];
xt0 = xt(:,1:4);
xInv = xt0'*inv(xt0*xt0');
2-获取指数结果
xt1 = xt(:,2:5);
expA = xt1 * xInv;
3-获取矩阵的对数:
A = logm(expA);
由于t-t0 = 1,A是我们的解决方案。
一个简单的检查证明
[t, y] = ode45(@(t,x) A*x,[1 5], xt(1:3,1));
plot (t,y,1:5, xt,'x')