how to fit the coupled differential equations and get the coefficients?
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
Réponses (3)
Sam Chak
le 6 Nov 2023
Modifié(e) : Sam Chak
le 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 commentaires
Sam Chak
le 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
le 6 Nov 2023
See: Parameter Estimation for a System of Differential Equations (and similar posts) for an easy way to estimate the parameters.
2 commentaires
Star Strider
le 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
le 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 commentaires
Voir également
Catégories
En savoir plus sur Interpolation dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!