Filter löschen
Filter löschen

Make lsqcurvefit go through a defined point?

1 Ansicht (letzte 30 Tage)
Christopher Hunt
Christopher Hunt am 19 Aug. 2022
Bearbeitet: Torsten am 24 Aug. 2022
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 Kommentare
Christopher Hunt
Christopher Hunt am 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? My essential question is whether I can force the routine to make the solution go through one of the given points such that fun0(xdata(1,:))=0. It seems like the answer is yes in a sense is I use fun1(), but then all other fun1() points have an offset. So I am in search of a way to do both: force the solution through fun0(xdata(1,:)) and model the other data points without the offset.
I will also throw out there that the equation underpinning fun0() comes from a couple publications which have used it in the same way to model titration data identical to those I am working with. One of these papers notes a potential need to adjust out(3) to make it result in fun0(out,xdata(1,:))==0 but doesn't say how they adjust it. I think fun1() is trying to do that, but something is not quite right.
Torsten
Torsten am 24 Aug. 2022
Bearbeitet: Torsten am 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.

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Torsten
Torsten am 19 Aug. 2022
Bearbeitet: Torsten am 19 Aug. 2022
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 Kommentare
Torsten
Torsten am 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
Christopher Hunt am 23 Aug. 2022
Thanks, I gave MultiStart a try, but it gavethe same result coefficients as lsqnonlin, so it seems like a local minimum doesn't seem to be the issue

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Get Started with Curve Fitting Toolbox finden Sie in Help Center und File Exchange

Produkte


Version

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by