Make lsqcurvefit go through a defined point?
Afficher commentaires plus anciens
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 commentaires
Christopher Hunt
le 19 Août 2022
Christopher Hunt
le 20 Août 2022
Matt J
le 20 Août 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
le 23 Août 2022
Modifié(e) : Christopher Hunt
le 23 Août 2022
Christopher Hunt
le 24 Août 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.
Réponses (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 commentaires
Christopher Hunt
le 19 Août 2022
Torsten
le 19 Août 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
le 23 Août 2022
Catégories
En savoir plus sur Get Started with Curve Fitting Toolbox dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


