# how to fit the coupled differential equations and get the coefficients?

5 views (last 30 days)

Show older comments

Hi! I'm trying to fit the coupled differential equations to my data and get the coefficients. Below is the equations that I use

d(N) = -(2/3)*L1*N^2*K - (1/3)*L2*N*K^2;

d(K) = -(1/3)*L1*N^2*K - (2/3)*L2*N*K^2;

Here, N and K are the data from the experiments, and L1 and L2 are what I want to get from the fit.

I'm not sure what method I should use to get L1 and L2.. Any tips are very appreciated!

##### 0 Comments

### Answers (3)

Sam Chak
on 6 Nov 2023

Edited: Sam Chak
on 6 Nov 2023

Hi @영훈 임

Update: The solution is updated at your request to plot the comparisons. The Batch Least Squares algorithm does not change.

%% For generating data purposes (real data can skip)

tspan = linspace(0, 10, 101);

[t, y1] = ode45(@odefcn1, tspan, [1 0.5]);

N = y1(:,1); % data N

K = y1(:,2); % data K

%% Batch Least Squares method to estimate L1 & L2

dN = gradient(N)./gradient(t);

dK = gradient(K)./gradient(t);

phi1 = [-(2/3)*(N.^2).*K -(1/3)*N.*(K.^2)];

phi2 = [-(1/3)*(N.^2).*K -(2/3)*(N.*K.^2)];

phi = [phi1; phi2];

Y = [dN; dK];

L = ((phi'*phi)\eye(length(phi'*phi)))*phi'*Y

%% Testing the fitness

tspan = linspace(0, 10, 101);

[t, y2] = ode45(@(t, y) odefcn2(t, y, L), tspan, [N(1) K(1)]);

subplot(211)

plot(t, N, 'o'), hold on

plot(t, y2(:,1), 'linewidth', 1.5), title('Comparison between data N and numerical N')

grid on, xlabel('t'), ylabel('N'), legend('data N', 'numerical N')

subplot(212)

plot(t, K, 'o'), hold on

plot(t, y2(:,2), 'linewidth', 1.5), title('Comparison between data K and numerical K')

grid on, xlabel('t'), ylabel('K'), legend('data K', 'numerical K')

%% differential equations (for generating data purposes)

function dydt = odefcn1(t, y)

dydt = zeros(2, 1);

L1 = 2; % true value of L1

L2 = 3; % true value of L2

N = y(1);

K = y(2);

dydt(1) = - (2/3)*L1*N^2*K - (1/3)*L2*N*K^2;

dydt(2) = - (1/3)*L1*N^2*K - (2/3)*L2*N*K^2;

end

%% differential equations (for testing purposes)

function dydt = odefcn2(t, y, L)

dydt = zeros(2, 1);

L1 = L(1); % estimated value of L1

L2 = L(2); % estimated value of L2

N = y(1);

K = y(2);

dydt(1) = - (2/3)*L1*N^2*K - (1/3)*L2*N*K^2;

dydt(2) = - (1/3)*L1*N^2*K - (2/3)*L2*N*K^2;

end

##### 2 Comments

Sam Chak
on 6 Nov 2023

Hi @영훈 임

I have updated my answer to show the comparison. I hope this helps. Also study @Star Strider's approach.

Star Strider
on 6 Nov 2023

##### 2 Comments

Star Strider
on 6 Nov 2023

The original problem was that ode45 was crashing (saturating) and stopped. The result was that the returned matrix had fewer rows than the data matrix, throwing the error.

This works (in the sense that it runs completely), however it does not come close to fitting the data —

Tbody2

function Tbody2

t = [0.4

0.6

0.8

1

1.2

1.5

1.8

2

2.5

3

3.5

4

4.5

5

7

10

15

20

30

50];

% c(:,1) = [770211; 715721.400000000;779650.800000000;807933.200000000;718145.600000000;746019.400000000;680262.600000000;643406.400000000;654130.600000000;597111.400000000;662146;578453;531229.400000000;574800.200000000;513836.800000000;400240.200000000;287214.400000000;308158.400000000;216808;191333.200000000];

% c(:,2) = [556098.903900000;597496.722600000;564025.111900000;506661.652400000;517884.943100000;500070.435600000;500966.444800000;517265.509000000;448318.326500000;509527.419300000;432720.902200000;434608.807900000;468438.727900000;401627.602100000;339789.050100000;351852.917000000;337195.730400000;241086.271400000;236918.419200000;161586.537200000];

c = [770211 556098.9039

715721.4 597496.7

779650.8 564025.1

807933.2 506661.6

718145.6 517884.9

746019.4 500070.4

680262.6 500966.4

643406.4 517265.5

654130.6 448318.3

597111.4 509527.4

662146 432720.9

578453 434608.8

531229.4 468438.7

574800.2 401627.6

513836.8 339789.0

400240.2 351852.9

287214.4 337195.7

308158.4 241086.2

216808 236918.40

191333.2 161586.5];

% theta0 = [1e-12; 1e-12];

theta0 = [rand(2,1)*1E-14; c(1,:).'];

[theta,Rsdnrm,Rsd,ExFlg,OptmInfo,Lmda,Jmat]=lsqcurvefit(@Loss,theta0,t,c);

fprintf(1,'\tRate Constants:\n')

for k1 = 1:length(theta)

fprintf(1, '\t\tTheta(%d) = %13.5E\n', k1, theta(k1))

end

tv = linspace(min(t), max(t));

Cfit = Loss(theta, tv)

figure(1)

plot(t, c, 'p')

hold on

hlp = plot(tv, Cfit);

hold off

grid

xlabel('Time')

ylabel('Concentration')

legend(hlp, 'C_1(t)', 'C_2(t)', 'C_3(t)', 'C_4(t)', 'Location','N')

function C=Loss(theta,t)

% c0=[1e6; 5e5];

c0 = theta(3:4)*0.9;

[T,Cv]=ode45(@DifEq,t,c0);

%

function dC=DifEq(t,c)

dcdt=zeros(2,1);

dcdt(1) = -theta(1).*(-2/3)*c(1).^2.*c(2) - theta(2).*(-1/3)*c(1).*c(2).^2;

dcdt(2) = -theta(1).*(-1/3)*c(1).^2.*c(2) - theta(2).*(-2/3)*c(1).*c(2).^2;

dC=dcdt;

end

C=Cv;

end

end

The changes I made specifically adding ther initial conditions for the differential equation as the last two elements of‘theta’ since that usually results in a successful fit, however that is only marginally successful here.

I am not certain what the problem is, since I do not understand the system you are modeling and estimating. One option may be to re-scale the data so that it is possible to estimate the parameters (that are currently approaching the eps value and so are likely not actually doing anything) to fit the data and then scale the parameters appropriately after estimating them. The model and the data are currently stretching the limits of floating-point computations.

You might also consider using ode15s even though your system is not specifically ‘stiff’. (I got good results with it in MATLAB Online, and better than I got here, however I was still not pleased with the results.)

.

Alex Sha
on 20 Nov 2023

Refer to the results below:

Sum Squared Error (SSE): 46715596564.0427

Root of Mean Square Error (RMSE): 35062.1990798768

Correlation Coef. (R): 0.977599960330532

R-Square: 0.955701682438257

Parameter Best Estimate

--------- -------------

L1 3.57062147972612E-13

L2 7.93804069320317E-14

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!