Clear Filters
Clear Filters

Curve Fitting using lsqcurvefit

1 view (last 30 days)
SAZZAD HOSSAIN
SAZZAD HOSSAIN on 15 Feb 2016
Edited: Matt J on 15 Feb 2016
Hello All
I have some experimental data that i am trying to fit using lsqcurvefit. However, the fitting is all wrong and just gives a straight line. I may have poor initial guess although have got the three initial guesses for the three parameters i am looking for from the literature. The code is -
%--------------------------------------
clear all
xdata = linspace(0.1,1,201)';
ydata= ((xdata.^2) + exp(-xdata))';
h = .000040;
A = 0.0002;
epsilon_0 = 8.854e-12;
x_ini = [0.1;0.5;0.17];
fun = @(x,xdata)(epsilon_0*A/h)*x(1) / ...
( 1-x(2)^2 * tan(xdata/(4*x(3))) ./ (xdata/(4*x(3))) ) ;
options = optimset('MaxIter',50000,'MaxFunEvals',50000,'FunValCheck','off',...
'Algorithm',{'levenberg-marquardt',.00001});
p = lsqcurvefit(fun,x_ini,xdata,ydata,[],[],options);
lse = fun(p,xdata);
plot(xdata,ydata,'o','color','red','linewidth',1)
line(xdata,lse,'linewidth',2)
%--------------------------------------
If someone please help me with what i am doing wrong, i would be grateful.
Thanks Sazzad

Answers (1)

Star Strider
Star Strider on 15 Feb 2016
I can’t run your code, but as a general rule, when in doubt, vectorise everything:
fun = @(x,xdata) (epsilon_0*A./h).*x(1) ./ ( 1-x(2).^2 .* tan(xdata./(4*x(3))) ./ (xdata./(4*x(3))) ) ;
  3 Comments
Star Strider
Star Strider on 15 Feb 2016
I didn’t see that you have created your own data.
I ran it and compared the value of your function with your fixed parameters, and your function doesn’t appear to have any relation to the data you want to fit to them. It’s constrained by ‘epsilon_0’ to be close to the minimum floating-point precision of most computers. That is likely the problem.
Vectorising your function is necessary, but it is likely not sufficient to fit your synthesised data. You need a better model, or actual data.
Matt J
Matt J on 15 Feb 2016
Edited: Matt J on 15 Feb 2016
Or, you need to be initializing x(1) differently, so that
(epsilon_0*A/h)*x(1)
has a more reasonable starting magnitude. It seems like a bad idea, though, to express x(1) in such small units that its typical magnitude will be 1e12. I would just lump (epsilon_0*A/h) and x(1) together to form one new variable.
z = (epsilon_0*A/h)*x(1)

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!