Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You have a linear, coupled system of ordinary differential equations, </p> <pre><code>y' = Ay with y = [S(t); D(t); F(t)] </code></pre> <p>and you're trying to solve the <em>inverse</em> problem, </p> <pre><code>A = unknown </code></pre> <p>Interesting!</p> <h2>First line of attack</h2> <p>For given <code>A</code>, it is possible to solve such systems analytically (read <a href="http://en.wikipedia.org/wiki/Matrix_differential_equation" rel="nofollow">the wiki</a> for example). </p> <p>The general solution for 3x3 design matrices <code>A</code> take the form </p> <pre><code>[S(t) D(t) T(t)].' = c1*V1*exp(r1*t) + c2*V2*exp(r2*t) + c3*V3*exp(r3*t) </code></pre> <p>with <code>V</code> and <code>r</code> the eigenvectors and eigenvalues of <code>A</code>, respectively, and <code>c</code> scalars that are usually determined by the problem's initial values. </p> <p>Therefore, there would seem to be two steps to solve this problem: </p> <ol> <li>Find vectors <code>c*V</code> and scalars <code>r</code> that best-fit your data</li> <li>reconstruct <code>A</code> from the eigenvalues and eigenvectors.</li> </ol> <p>However, going down this road is treaturous. You'd have to solve the non-linear least-squares problem for the sum-of-exponentials equation you have (using <code>lsqcurvefit</code>, for example). That would give you vectors <code>c*V</code> and scalars <code>r</code>. You'd then have to unravel the constants <code>c</code> somehow, and reconstruct the matrix <code>A</code> with <code>V</code> and <code>r</code>. </p> <p>So, you'd have to solve for <code>c</code> (3 values), <code>V</code> (9 values), and <code>r</code> (3 values) to build the 3x3 matrix <code>A</code> (9 values) -- that seems too complicated to me.</p> <h2>Simpler method</h2> <p>There is a simpler way; use brute-force:</p> <pre><code>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 </code></pre> <p>So far so good. </p> <p>However, I tried both the complicated way and the brute-force approach above, but I found it very difficult to get the squared error anywhere near satisfyingly small. </p> <p>The best solution I could find, after numerous attempts: </p> <pre><code>A = 1.216731997197118e+000 2.298119167536851e-001 -2.050312097914556e-001 -1.357306715497143e-001 -1.395572220988427e-001 2.607184719979916e-002 5.837808840775175e+000 -2.885686207763313e+001 -6.048741083713445e-001 fval = 3.868360951628554e-004 </code></pre> <p>Which isn't bad at all :) But I would've liked a solution that was less difficult to find...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload