How to dot I use lsqcurvefit and now get the Optimization terminated error?

3 views (last 30 days)
Hi I haven't used lsqcurvefit before and I can't get it to work.
As a test I thought I would generate a curve from the equation I would like to fit and then try to fit that curve and see if I can get back to the parameter values I initially put in.
But I get the following error
Optimization terminated: first-order optimality less than OPTIONS.TolFun, and no negative/zero curvature detected in trust region model.
Here's my code
% generate dummy data from same equation with values a = [1 1 0.7]
T = linspace(0.2,2,100);
a = [1 1 0.7];
for n = 1 : length(T)
% This is the equation I will apply the fit to
r(n) = (2* sqrt(a(3)))/ sqrt(a(1) + 3* a(3)* (2*pi/T(n)));
end
xdata = T';
ydata =r';
%Now I attempt to fit using lsqcurvefit - I would hope to get a = 1 1 0.7
%as above
predicted = @(a,xdata) (2.* sqrt(a(3))*ones(length(T),1)) ./ sqrt(a(1)*ones(length(T),1)+ 3* a(2)* (2*pi*ones(length(T),1)./xdata));
a0 = [1;1;0.6];
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =...
lsqcurvefit(predicted,a0,xdata,ydat)
Any help much appreciated

Answers (3)

Star Strider
Star Strider on 11 Sep 2014
First, you have a typo:
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =...
lsqcurvefit(predicted,a0,xdata,ydat)
ydat should be ydata.
Second, the function you are fitting is not the function that generated your data.
Correcting that and using an anonymous function in place of your loop (and using it also as your objective function):
T = linspace(0.2,2,100);
a = [1 1 0.7];
% for n = 1 : length(T)
% % This is the equation I will apply the fit to
% r(n) = (2* sqrt(a(3)))/ sqrt(a(1) + 3* a(3)* (2*pi/T(n)));
% end
rfun = @(a,T) (2* sqrt(a(3)))./ sqrt(a(1) + 3* a(3).* (2*pi./T));
r = rfun(a,T);
xdata = T';
ydata =r';
%Now I attempt to fit using lsqcurvefit - I would hope to get a = 1 1 0.7
%as above
% predicted = @(a,xdata) (2.* sqrt(a(3))*ones(length(T),1)) ./ sqrt(a(1)*ones(length(T),1)+ 3* a(2)* (2*pi*ones(length(T),1)./xdata));
a0 = [1;1;0.6];
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =...
lsqcurvefit(rfun,a0,xdata,ydata);
produces appropriate estimates for your parameters.
  3 Comments
Star Strider
Star Strider on 11 Sep 2014
Edited: Star Strider on 11 Sep 2014
My pleasure!
No worries about the typo. I pointed it out in case you had another variable by that name elsewhere in your code but not visible here, and that could have caused the problem.
My code as I posted it ran perfectly for me. (I wouldn’t have posted it otherwise.)
When I ran it just now (requesting only ‘ahat’ for my purposes here), I get:
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the function tolerance.
<stopping criteria details>
ahat =
957.3467e-003
1.0000e+000
670.1427e-003
Increasing the precision (decreasing the tolerances) would get more precise estimates, but these are acceptably close for the default tolerances.
I suggest you run this line:
options = optimoptions('lsqcurvefit')
(with no trailing semicolon so it will output to the Command Window) to see what 'TolFun' and the other options are. You can use a similar call to optimoptions to reset 'TolFun' and the other parameters to values more in keeping with your requirements. For some reason, the options for lsqcurvefit on your machine are set so that it satisfies the function tolerance before it encounters a minimum.
Star Strider
Star Strider on 15 Sep 2014
My pleasure!
I don’t have access to R2008, so I don’t know how the versions of lsqcurvefit differ. I suggest you run:
options = optimoptions('lsqcurvefit')
on your R2013 machine and the analogous command on your R2008 machine to see how they differ. Set the options to approximate R2013. You will probably need to tweak the options for R2008, increasing the iteration and evaluation limits and decreasing the tolerances.

Sign in to comment.


Matt J
Matt J on 11 Sep 2014
It's not an error. A stopping criterion was reached.

Eddy
Eddy on 15 Sep 2014
Thanks again.
You're right. I'm running matlab 2008. I just tried your code on matlab 2013 (I have remote access to this) and I got the result below which matches yours. I checked the 'options' in matlab 2008 I have
Display: 'final'
MaxFunEvals: '100*numberofvariables'
MaxIter: 400
TolFun: 1.0000e-006
TolX: 1.0000e-006
FunValCheck: 'off'
OutputFcn: []
PlotFcns: []
ActiveConstrTol: []
Algorithm: []
AlwaysHonorConstraints: []
BranchStrategy: []
DerivativeCheck: 'off'
Diagnostics: 'off'
DiffMaxChange: 0.1000
DiffMinChange: 1.0000e-008
but these are totally different to options in 2013 so I guess lsqcurvefit has probably been developed a fair bit. If you have an idea how I might get the 2008 fitting working that would be great, if not I will just have to do my fitting on a different machine with the newer version of matlab.
Anyway thanks for the help
Ed
Local minimum found.
Optimization completed because the size of the gradient is less than the default value of the function tolerance.
Optimization completed: The first-order optimality measure, 5.639938e-10, is less than options.TolFun = 1.000000e-06.
Optimization Metric Options relative first-order optimality = 5.64e-10 TolFun = 1e-06 (default)
>> ahat
ahat =
0.9573
1.0000
0.6701

Categories

Find more on Systems of Nonlinear Equations 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!