Make lsqcurvefit go through a defined point?
Show older comments
I am trying to run lsqcurvefit to model some chemical titration data. It uses a custom function I define. However, the fitted result returns a negative x-value at y(0), when I need it to pass through (0,y(0)). I'm attaching an example of my input data. Here is my code:
fun=@(out,xdata) (xdata(:,2).*(out(1)./(1+(xdata(:,1)./out(2))))) + (xdata(:,2).*(xdata(:,5)./(1+(xdata(:,1)./xdata(:,6))))) - (xdata(:,2) + xdata(:,3)).*(xdata(:,1)-xdata(:,4)) + xdata(:,2).*out(3);
out0=[10^-5 10^-4 xdata(1,1)];
options = optimoptions(@lsqcurvefit,'StepTolerance',10^-50,'OptimalityTolerance',10^-15,'FunctionTolerance',10^-15,'MaxFunctionEvaluations',10000);
out_OneGroup = lsqcurvefit(fun,out0,xdata,ydata,[1e-6 1e-5 0],[1e-3 1e-3 0.1],options);
OneGroup_results=feval(fun,out_OneGroup,xdata);
I can take the first value of OneGroup_results (-3.3866e-6), subtract it from the 3rd out_OneGroup value (increasing that value by the offset 3.3866e-6), and re-run the program and all values will be above zero, but the resulting fit it also offset and doesn't work.
Any suggestions greatly appreciated!
8 Comments
Christopher Hunt
on 19 Aug 2022
Christopher Hunt
on 20 Aug 2022
Matt J
on 20 Aug 2022
It uses a custom function I define. However, the fitted result returns a negative x-value at y(0), when I need it to pass through (0,y(0)).
But in your code above, you are plotting ydata on the x-axis, so it is still not clear in your statement what you consider the "x-values" and whether "y(0)" means ydata(1) or something else.
Christopher Hunt
on 23 Aug 2022
Edited: Christopher Hunt
on 23 Aug 2022
Christopher Hunt
on 24 Aug 2022
But isn't that the point of multivariate least squares fitting: that a solution can be found using a combination of input data and adjusted model coefficients which satisfies the given function but may not pass through some or most of the points, including the first one?
Of course - including the first one. But you want to exclude the first one because you want the function to pass through this point.
Say you have a model function f0(t) = exp(k*t) for the concentration of a substance over time and you know you start with a concentration of 0 - would you take this model function which starts with a concentration of 1 ? Of course, f1(t) = exp(k*t) - exp(k*0) = exp(k*t) - 1 could be used to satisfy f1(0) = 0. But it is only one possibility to force f0 to pass through (0,0), so you don't know if it is also suited for t>0.
Answers (1)
fun = @(out)((xdata(:,2).*(out(1)./(1+(xdata(:,1)./out(2))))) + (xdata(:,2).*(xdata(:,5)./(1+(xdata(:,1)./xdata(:,6))))) - (xdata(:,2) + xdata(:,3)).*(xdata(:,1)-xdata(:,4)) + xdata(:,2).*out(3))-...
((xdata(1,2).*(out(1)./(1+(xdata(1,1)./out(2))))) + (xdata(1,2).*(xdata(1,5)./(1+(xdata(1,1)./xdata(1,6))))) - (xdata(1,2) + xdata(1,3)).*(xdata(1,1)-xdata(1,4)) + xdata(1,2).*out(3));
fun1 = @(out) fun(out) - ydata;
out0 = [10^-5 10^-4 xdata(1,1)];
out_OneGroup = lsqnonlin(fun1,out0);
plot(1:numel(xdata(:,1)),fun(out_OneGroup))
hold on
plot(1:numel(xdata(:,1)),ydata)
hold off
3 Comments
Christopher Hunt
on 19 Aug 2022
Torsten
on 19 Aug 2022
I might be thinking about this wrong, but it seems like it should be possible to drive the fit through (x,y(0)) and have the fit follow the observations closer than this?
Then you are more clever than "lsqnonlin" ...
But seriously: It's kind of strange that your function does not automatically fulfill the constraint that it goes through (x,y(0)). Usually, fitting objects are chosen such that they follow the physics they reflect.
You may try different starting values and see whether the approximation gets better. Look up "MultiStart".
Christopher Hunt
on 23 Aug 2022
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!

