How do I fit an arbitrary function to data using LSQNONLIN in Optimization Toolbox?

94 views (last 30 days)
I would like to fit the following arbitrary function to data I have using LSQNONLIN.
f = A + B*exp(C*x) + D*exp(E*x)
X and Y are data sets where Y is the expected output given X.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 12 Jun 2012
Note: LSQCURVEFIT can be used to solve nonlinear curve-fitting (data-fitting) problems in least-squares sense. The LSQCURVEFIT function uses the same algorithm as LSQNONLIN, but simply provides a convenient interface for data-fitting problems.
To do this, create the following function named fit_simp.m which uses the X and Y data, both of which are passed into lsqnonlin as optional input arguments. Use the X data to calculate values for f, and subtract the original Y data from this. The results are the differences between the experimental data and the calculated values. The lsqnonlin function will minimize the sum of the squares of these differences.
function diff = fit_simp(x,X,Y)
% This function is called by lsqnonlin.
% x is a vector which contains the coefficients of the
% equation. X and Y are the option data sets that were
% passed to lsqnonlin.
A=x(1);
B=x(2);
C=x(3);
D=x(4);
E=x(5);
diff = A + B.*exp(C.*X) + D.*exp(E.*X) - Y;
The following script is an example of how to use fit_simp.m:
% Define the data sets that you are trying to fit the
% function to.
X=0:.01:.5;
Y=2.0.*exp(5.0.*X)+3.0.*exp(2.5.*X)+1.5.*rand(size(X));
% Initialize the coefficients of the function.
X0=[1 1 1 1 1]';
% Calculate the new coefficients using LSQNONLIN.
x=lsqnonlin(@fit_simp,X0,[],[],[],X,Y);
% Plot the original and experimental data.
Y_new = x(1) + x(2).*exp(x(3).*X)+x(4).*exp(x(5).*X);
plot(X,Y,'+r',X,Y_new,'b')
  5 Comments
collinst
collinst on 4 Jan 2019
What am I doing wrong here?
I made up some data, then used lsqnonlin to see if it found the real parameters, but it fell far from it...
Thanks.
xdata = (-10:0.1:10);
b = 0; %p(1)
a = 3; %p(2)
w = 0.5; %p(3)
for i = 1:length(xdata)
ydata(i) = (xdata(i)+b) * a * w * (exp(1)^-(w*(xdata(i)+b)^2));
end
fun = @(p,xdata)(xdata+p(1)) * p(2) * p(3) .* (exp(1).^-(p(3).*(xdata+p(3)).^2));
p0 = [b a w];
p = lsqcurvefit(fun,p0,xdata,ydata);
for i = 1:length(xdata)
yt(i) = (xdata(i)+p(1)) * p(2) * p(3) * (exp(1)^-(p(3)*(xdata(i)+p(3))^2));
end
plot(xdata,ydata,'ok')
hold on
plot(xdata,yt,'-r')

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!