Fitting kinetic model to estimate kinetic parameter
Show older comments
Hello, I want to ask a question. I want to curve fit the data with the kinetic model. I am able to run the code (written and attached below), but the result is still far from my expectation.
function trycurvefitlunaflores
function C=kinetics(theta,t)
c0=[0.6178; 28.90; 0.4589];
[T,Cv]=ode45(@DifEq,t,c0);
function dC=DifEq(t,c)
dcdt=zeros(3,1);
mu = ((theta(1).*c(2))./(theta(2)+c(2)+(c(2)^2./(theta(3))))).*((1-c(3)./theta(4)).^theta(5));
dcdt(1) = mu.*c(1);
dcdt(2) = -c(1).*((mu./(theta(6))+theta(7)));
dcdt(3) = c(1).*((theta(8).*mu)+theta(9));
dC=dcdt;
end
C=Cv;
end
t = [0
12
24
36
48
60
72];
c = [0.6178489703 28.90160183 0.7586206897
0.823798627 28.83295195 4.045977011
2.402745995 21.62471396 6.827586207
5.972540046 13.04347826 18.5862069
8.306636156 6.178489703 34.01149425
9.885583524 2.402745995 44.88505747
9.542334096 2.059496568 50.44827586];
theta0 = [1;1;1;1;1;1;1;1;1];
[theta,Rsdnrm,Rsd,ExFlg,OptmInfo,Lmda,Jmat]=lsqcurvefit(@kinetics,theta0,t,c);
fprintf(1,'\tRate Constants:\n')
for k1 = 1:length(theta)
fprintf(1, '\t\tTheta(%d) = %8.5f\n', k1, theta(k1))
end
tv = linspace(min(t), max(t));
Cfit = kinetics(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)', 'Location','N')
end

In the normal circumstance, the plot line (from kinetic model) should follow the data's tren, like this figure below.

Could you help me to fix the plot to make it more similar to the data? Any little advice or help will be much appreciated. Thank you.
7 Comments
Alex Sha
on 5 Nov 2021
Hi, Salman, the results below are obtained by using a package other than Matlab, you may have a check:
Root of Mean Square Error (RMSE): 0.732135213542845
Sum of Squared Residual: 9.64839547636969
Correlation Coef. (R): 0.997606342175452
R-Square: 0.995218413948685
Parameter Best Estimate
-------------------- -------------
theta1 -0.0242147478503888
theta2 -12.5872182600746
theta3 -28.8723626819411
theta4 50.506381835912
theta5 0.152709651271307
theta6 0.348919829234199
theta7 0.00280925362885251
theta8 1.98890080928454
theta9 0.0951796615605864



Nadya Shalsabila salman
on 5 Nov 2021
Alex Sha
on 5 Nov 2021
1stOpt, an package with great advance features on global optimization, the code is simple as fellow:
ConstStr mu = ((theta1*c2)/(theta2+c2+(c2^2/(theta3))))*((1-c3/theta4)^theta5);
Parameter theta(9);
Variable t,c(3);
ODEFunction
c1' = mu*c1;
c2' = -c1*((mu/(theta6)+theta7));
c3' = c1*((theta8*mu)+theta9);
Data;
0 0.6178489703 28.90160183 0.7586206897
12 0.823798627 28.83295195 4.045977011
24 2.402745995 21.62471396 6.827586207
36 5.972540046 13.04347826 18.5862069
48 8.306636156 6.178489703 34.01149425
60 9.885583524 2.402745995 44.88505747
72 9.542334096 2.059496568 50.44827586
Star Strider
on 7 Nov 2021
@Nadya Shalsabila salman — For what it’s worth, I gave this my best shot with a number of Global Optimization Toolbox functions over a couple days, and could never get a good fit to
with any of them, although I had no problems with
and
. (I have no idea how ‘1stOpt’ solves these problems. Perhaps that information can be shared.)
Nadya Shalsabila salman
on 8 Nov 2021
Nadya Shalsabila salman
on 8 Nov 2021
Accepted Answer
More Answers (2)
Your basic structure seems to be ok. Here are some hints you could consider:
- Try playing around with the solver options, like using different algorithms, different initial points and tolerances:
theta0 = [1;1;1;1;1;1;1;1;1];
options = optimoptions('lsqcurvefit', 'Algorithm','trust-region-reflective');
options.MaxFunctionEvaluations = 10e5;
options.StepTolerance = 10e-7;
options.FunctionTolerance = 10e-7;
options.MaxIterations = 10e5;
[theta,Rsdnrm,Rsd,ExFlg,OptmInfo,Lmda,Jmat]=lsqcurvefit(@kinetics,theta0,t,c, [],[], options);
- Use the accurate intitial condition for your differential equation:
c0=[0.6178489703 28.90160183 0.7586206897];
- Watch out for local minimum warnings. Matlab provides further thoughts on how to avoid local minimum convergence when clicking on the link in the matlab console (or directly via this link):
>> trycurvefitlunaflores
Local minimum possible.
After playing around a bit I was able to produce the following result:

I am sure that with a little tweaking you will be able to also fit C_1 correctly. Let me know if you found a solution.
9 Comments
Nadya Shalsabila salman
on 5 Nov 2021
Nadya Shalsabila salman
on 7 Nov 2021
Alex Sha
on 7 Nov 2021
Hi, you may take the results I provided above as initial start values in your Matlab code, and see what's happen
Nadya Shalsabila salman
on 8 Nov 2021
Alex Sha
on 8 Nov 2021
Hi, taking:
theta0 = [1;1;1;1;1;1;1;1;1];
as:
theta0 = [-0.024;-12.55;-28.80;50.63;0.168;0.3501;0.003146;1.9802;0.0954];
run and see the result
Nadya Shalsabila salman
on 8 Nov 2021
Alex Sha
on 8 Nov 2021
if paameters of [Miumax,Ks,Ki,Kp,gamma,Yxs,alfa,betha,ms] correspond to [theta1,theta2,...,theta9], then you could take:
Miumax=0.145;
Ks=1.6607;
Ki=50.3151;
Kp=8798.15;
gamma=3.6658;
Yxs=0.3941;
alfa=371.45;
betha=1.5502;
ms=0.005;
into your ODE function to test and verify the performance, as my test, the results are much bad.
Nadya Shalsabila salman
on 13 Nov 2021
Manish
on 24 Nov 2024
0 votes
function C=kinetics(theta,t)
c0=[0.6178; 28.90; 0.4589];
[T,Cv]=ode45(@DifEq,t,c0);
function dC=DifEq(t,c)
dcdt=zeros(3,1);
mu = ((theta(1).*c(2))./(theta(2)+c(2)+(c(2)^2./(theta(3))))).*((1-c(3)./theta(4)).^theta(5));
dcdt(1) = mu.*c(1);
dcdt(2) = -c(1).*((mu./(theta(6))+theta(7)));
dcdt(3) = c(1).*((theta(8).*mu)+theta(9));
dC=dcdt;
end
C=Cv;
end
t = [0
12
24
36
48
60
72];
c = [0.6178489703 28.90160183 0.7586206897
0.823798627 28.83295195 4.045977011
2.402745995 21.62471396 6.827586207
5.972540046 13.04347826 18.5862069
8.306636156 6.178489703 34.01149425
9.885583524 2.402745995 44.88505747
9.542334096 2.059496568 50.44827586];
theta0 = [1;1;1;1;1;1;1;1;1];
[theta,Rsdnrm,Rsd,ExFlg,OptmInfo,Lmda,Jmat]=lsqcurvefit(@kinetics,theta0,t,c);
fprintf(1,'\tRate Constants:\n')
for k1 = 1:length(theta)
fprintf(1, '\t\tTheta(%d) = %8.5f\n', k1, theta(k1))
end
tv = linspace(min(t), max(t));
Cfit = kinetics(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)', 'Location','N')
end
Categories
Find more on Linear and Nonlinear Regression in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






