Matlab:寻找ODE系统的系数

时间:2013-05-15 09:44:23

标签: matlab differential-equations ode

我有三个方程的所有数据和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)?

2 个答案:

答案 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)

Vr分别为Ac标量的特征向量和特征值,通常由问题的初始值决定。

因此,似乎有两个步骤可以解决这个问题:

  1. 查找最适合您数据的向量c*V和标量r
  2. 从特征值和特征向量重建A
  3. 然而,沿着这条路走下去是一件好事。你必须解决你所拥有的指数和方程的非线性最小二乘问题(例如,使用lsqcurvefit)。这将为您提供向量c*V和标量r。然后,您必须以某种方式解开常量c,并使用AV重建矩阵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')

enter image description here