MATLAB: Non-linear data fitting to a model

datalsqnonlinnonlinear

I am trying to fit some data using the following code:
xdata = [0.0600 0.1250 0.2540 0.4050 0.5450];
ydata = [0.0800 0.1000 0.1200 0.1400 0.1600];
objfcn = @(x)(x(1)*x(2))./((x(2)*(1-xdata)./xdata)+(1-xdata)*(x(2)-1))-ydata;
x0 = rand(2,1);
opts = optimoptions(@lsqnonlin,'Algorithm','levenberg-marquardt','Display','iter');
[x,resnorm]=lsqnonlin(objfcn,x0,[],[],opts);
M = x(1)
B = x(2)
I am getting results but sometimes M value is coming negative which is not desirable. Also, the predicted ydata deviates largely from the original ydata values. If someone could be help to analyze the small code mentioned above and what is the wrong with results.
Thanks,

Best Answer

Random guesses for the initial point x0 are a bad idea. I generate a better initial guess below, by re-arranging the model equation as linear. Also, if it is undesirable for M to be negative, then you should use the lb argument to bound it. This means you will then have to use the trust-region algorithm instead of Levenberg-Marquardt, since the latter doesn't support bound constraints.
xdata=xdata(:); ydata=ydata(:);
objfcn = @(x)(x(1)*x(2))./((x(2)*(1-xdata)./xdata)+(1-xdata)*(x(2)-1))-ydata;
expr1=(1-xdata)./xdata;
expr2=(1-xdata);
A=[ones(size(xdata)), -(expr1+expr2).*ydata, ];
b=ydata.*expr2;
s=A\b;
res=A*s-b
x0 = [s(1)/s(2),s(2)],
opts = optimoptions(@lsqnonlin,'Display','iter');
[xf,resnorm]=lsqnonlin(objfcn,x0,[0,-inf],[],opts);
This leads to
K>> yfit= objfcn(xf)+ydata
yfit =
0.0827
0.0903
0.1067
0.1342
0.1757
I tend to think this is the best fit that will be possible given such a small number of xdata, ydata samples.