% Nonlinear Curve-Fitting
% Rather than restricting ourselves to polynomial fits, we can use Matlab to fit to an arbitrary function, but it will often be nonlinear and thus force us to do some iteration. Fortunately, there are some built-in routines that can help us. For example, we can generate a random set of data and then fit that data to a power law function:
% y=A*x^n
% Here our goal is to determine A and n such that the error between this model and our data is minimized. We will use the fminsearch function to minimize the sum of the square of the errors between the model and the points. The code is as follows:

clear all
global x y
global numpts
numpts=30;
x=(0:numpts)/numpts;
y=3*x.^2+2*(0.5-rand(1,numpts+1));
z(1)=1;
z(2)=2;
zResult=fminsearch(@sumoferrs,z);
A=zResult(1)
n=zResult(2)
xplot=0:0.01:1;
yplot=zResult(1)*xplot.^zResult(2);
plot(x,y,'+',xplot,yplot)
xlabel('x')
ylabel('y')
lgd=legend('data', 'power law fit');
lgd.FontSize = 14; lgd.Location='northwest';
set(gca,'FontSize',20)

datamean=mean(y);
errorsum=sum((curve(x,zResult)-y).^2);
othersum=sum((datamean-y).^2);
rsquared=1-errorsum/othersum

% Here z is a vector containing guesses for our two fitting parameters. I've chosen to represent A as z(1) and n as z(2). In this case, the guesses are not all that critical and the fit will converge with a wide variety of guesses. Other fits will require a better guess. It pays to estimate what your parameters ought to be prior to fitting.
% The variable zResult is a vector containing the optimal values of A and n (after running the fminsearch routine).
%

function f=sumoferrs(z)
global x y
global numpts
a=z(1);
n=z(2);
f=sum((curve(x,z)-y).^2);
end

function f=curve(x,z)
a=z(1);
n=z(2);
f=a*x.^n; 
end

% These two functions above are used in the fitting. The curve function determines what function you are fitting to and it returns a value of the fitting model at a particular value of x for a given set of parameters, contained in z. The sumoferrs function takes a set of data and a fitting function and returns the sum of the squares of the errors between the data and the function.
% © James Blanchard, University of Wisconsin-Madison, blanchard@engr.wisc.edu