lsqcurvefit: Function value and YDATA sizes are not equal.
2 views (last 30 days)
Show older comments
Hi,
I am fitting two data from the same experiment to obtain non-linear fit parameters that describe the whole system. How can I make the value returned by the "function" the same size as YDATA used by lsqcurvefit?
function [C, D] = kinetics(k,t)
x0 = [1;1;1;1];
[T,Cv] = ode45(@DiffEq,t,x0);
function dC = DiffEq(t,x)
RHOcat = 0.23552;
EPS = 0.528;
xdot = zeros(4,1);
xdot(1) = (RHOcat/EPS).*(-k(1).* x(1));
xdot(2) = k(1).* x(1) - k(2).* x(2);
xdot(3) = k(3).* x(4);
xdot(4) = k(2) .* x(2) - k(3) .* x(4);
dC=xdot;
end
C=Cv(:,1);
D=Cv(:,3);
end
Y=load('Pt330.dat');
t = Y(6:end,1);
cNO = Y(6:end,3);
cNO2 = Y(6:end,4);
c = [cNO,cNO2];
tdata = Y(:,1);
c1data = Y(:,2);
c2data = Y(:,3);
c3data = Y(:,4);
k0=[1;1;1;1];
options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt');
lb = [];
ub = [];
[k,Rsdnrm,Rsd,ExFlg,OptmInfo,Lmda,Jmat]=lsqcurvefit(@kinetics,k0,t,c,lb,ub,options)
end
PS: Pt330.txt can be renamed as Pt330.dat to run the code.
0 Comments
Accepted Answer
Star Strider
on 14 Jan 2023
The output returned by ‘kinetics’ needs to be:
C = Cv(:,[1 3]);
in this instance.
The code now works, however the fit is definitely not optimal for . I have no idea what the ‘k’ magnitudes should be, so using rand here. This gets closer ([NO] is appropriate), however there is still something wrong. (I put lower bounds on the parameters because in my experience, kinetic constants cannot be negative. If that is not true in this system, change ‘lb’ back to an empty matrix.) Also, check to be certain that ‘DifEq’ is coded correctly.
Y=readmatrix('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1263580/Pt330.txt');
t = Y(6:end,1);
cNO = Y(6:end,3);
cNO2 = Y(6:end,4);
c = [cNO,cNO2];
tdata = Y(:,1);
c1data = Y(:,2);
c2data = Y(:,3);
c3data = Y(:,4);
% k0=[1;1;1;1];
k0 = rand(4,1)*1E-2;
options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt');
lb = zeros(4,1);
ub = [];
[k,Rsdnrm,Rsd,ExFlg,OptmInfo,Lmda,Jmat]=lsqcurvefit(@kinetics,k0,t,c,lb,ub,options)
fprintf(1,'\tRate Constants:\n')
for k1 = 1:numel(k)
fprintf(1, '\t\tK(%2d) = %8.5f\n', k1, k(k1))
end
tv = linspace(min(t), max(t));
Cfit = kinetics(k, tv);
figure
hd = plot(t, c, 'p');
for k1 = 1:size(c,2)
CV(k1,:) = hd(k1).Color;
hd(k1).MarkerFaceColor = CV(k1,:);
end
hold on
hlp = plot(tv, Cfit);
for k1 = 1:size(c,2)
hlp(k1).Color = CV(k1,:);
end
hold off
grid
xlabel('Time')
ylabel('Concentration')
legend(hlp, compose('C_%d',1:size(c,2)), 'Location','best')
function C = kinetics(k,t)
x0 = [1;1;1;1];
[T,Cv] = ode45(@DiffEq,t,x0);
function dC = DiffEq(t,x)
RHOcat = 0.23552;
EPS = 0.528;
xdot = zeros(4,1);
xdot(1) = (RHOcat/EPS).*(-k(1).* x(1));
xdot(2) = k(1).* x(1) - k(2).* x(2);
xdot(3) = k(3).* x(4);
xdot(4) = k(2) .* x(2) - k(3) .* x(4);
dC=xdot;
end
C = Cv(:,[1 3]);
end
I added the plot.
.
8 Comments
Star Strider
on 15 Jan 2023
1) The lsqcurvefit function only needs to ‘see’ the data it is fitting. Everything else is irrelevant to it. ( I did not look closely at ‘DiffEq’ previoously. I see only three kinetic constants, so only three need to be defined in ‘x0’ and returned in ‘k’.) If you are fitting data to all four differential equations, then return all the columns, as in ‘kinetics4’. The benefit of that is that it might help define ‘k(3)’ that is not otherwise used in fitting the first two equations. If there are data for them, this simply involves re-definng ‘C’ in ‘DiffEq’.
I do not understand ‘I think I am wrong in treaing lsqcurvefit as any user-defined function ...’ so I cannot comment on it.
2) The lsqcurvefit function is the only function that I know of that will fit matrix dependent variables (there are others such as ga, however they do not return the Jacobian and other outputs necessary to calculate statistics on the fit), so it is the only option here. (I do not have the Curve Fitting Toolbox, so I do not know if it could be used for goodness-of-fit estimations involving matrix dependent variables.)
It is possible to get parameter confidence intervals using the Statistics and Machine Learning Toolbox function nlparci however not confidence intervals on the fitted regression lines, since the nlpredci function only works with nonlinear functions that return one dependent variable. The problem is that fitting a matrix of dependent variables significantly limits the options for calculating other statistics on the fit.
I have only calculated parameter statistics in kinetics fitting of matrix dependent variables, not statistics on the fit, since that is a much more complicated problem, and I am usually only interested in the parameter statistics (that tell me everything I usually need to know). I am not certain how to calculate statistics on the fit in matrix dependent variable regressions, since I have never needed to do it.
More Answers (0)
See Also
Categories
Find more on Get Started with Curve Fitting Toolbox 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!