Nonlinear fit comparison - Matlab vs OriginLab

24 views (last 30 days)
Good afternoon, I'm posting this question because I'm not able to find a satisfactory result of a non-linear fit with Matlab. On the contrary, OriginLab returns a good fit together with errors for fit parameters. Here my x and y data: x = [177600,961200, 2504000, 4997000, 8884000]; y = [6.754, 24.416, 58.622, 107.980, 154.507]; yErr = sqrt(y);
The fitting function is the following: y = V + (A-V)*S*x*EXP(-S*x) where V, A and S are the parameters which I need to calculate from the fit. OriginLab gives me the following:
  • V = 1.978 ± 0.889
  • A = 585 ± 64
  • S = 4.392E-8 ± 6.771E-9
On Matlab I tried all the possible form of non-linear regression: fitnlm, lsqcurvefit, nlinfit etc... every time the same warning: The Jacobian is ill conditioned. Here is an example:
Nonlinear regression model:
y ~ a1 + (a2 - a1)*a3*x*exp( - a3*x)
Estimated Coefficients:
Estimate SE tStat pValue
__________ __________ ___________ __________
a1 -0.6789 2.9104e-19 -2.3327e+18 2.0265e-73
a2 530.78 8.0894e-20 6.5614e+21 3.2371e-87
a3 5.2511e-08 5.1865e-10 101.25 5.7063e-08
Of course such small standard errors are not reliable, but still I'm not able to reproduce the Origin results. Any suggestions?
  4 Comments
MZ123
MZ123 on 14 Sep 2018
@Star Strider what about the standard errors associated with the parameters?
MZ123
MZ123 on 14 Sep 2018
@Stephan almost close to Origin, but V has an enormous confidence interval.. :( thank you

Sign in to comment.

Accepted Answer

Matt J
Matt J on 14 Sep 2018
Edited: Matt J on 14 Sep 2018
Well, I guess I would credit OriginLab with knowing how to pre-scale the x,y data appropriately. If you do this manually, then lsqcurvefit works fine, and gives a slightly better fit (according to resnorm) than OriginLab,
c=10*max(x); %pre-scaling factor
a0=[1.9780 ,585, 4.3920e-08*c];
F=@(a,x) a(1)+(a(2)-a(1)).*a(3).*x/c.*exp(-a(3).*x/c);
[a,resnorm,~,~,~,~,J]=lsqcurvefit(F,[1,100,1],x,y,[],[],...
optimoptions('lsqcurvefit','Display','iter'));
solution=[a(1), a(2), a(3)/c]
resnorm %10.1985
condJ = cond(full(J)) %510.8393
plot(x,y,'x',x,F(a,x),'--'); xlabel 'x', xlabel 'y';
  3 Comments
Matt J
Matt J on 14 Sep 2018
Edited: Matt J on 14 Sep 2018
I didn't get the point.
The point is that we reached a better fit than OriginLab - the residuals are lower. Also, there are no ill-conditioned Jacobian problems once you scale the data properly. With c=1 (no scaling) you will find that cond(J)=Inf whereas with scaling, it drops nicely down to 60 or so.
Also, how do I re-map the scaled coefficient to those similar to Origin?
I already remapped them for you in the line
solution=[a(1), a(2), a(3)/c]
how to get the Standard Error with the parameters?
You have the Jacobian (a sensible one now) and the residuals, so you can use them to compute whatever gof metrics that you like.
Matt J
Matt J on 14 Sep 2018
You have the Jacobian (a sensible one now) and the residuals, so you can use them to compute whatever gof metrics that you like.
which leads me to
  • V = 0.6652 ± 1.7676
  • A = 545 ± 33
  • S = 4.9629e-08 ± 5.1273e-09

Sign in to comment.

More Answers (2)

MZ123
MZ123 on 14 Sep 2018
Another frustrating scenario.. simple polynomial fit y = a+bx+cx^2 I get another error on Matlab "Polynomial is badly conditioned". On the other hand Origin does it better.. why? To me this is really embarrassing.
  2 Comments
Stephan
Stephan on 14 Sep 2018
Edited: Stephan on 14 Sep 2018
Could you provide your code? Yesterday in the evening i tried to understand the problem you have. I did not get the exactly same result you provided from OriginLab, but it was a good fit i thinkand there was no warning. So it would be interesting to see what you are doing.
One more question to your fitting equation:
In your question it is:
y = V + (AV) * S * x * EXP (-S * x)
which should mean
A * V
In the Second Part of your question it is:
y ~ a1 + (a2 - a1) * a3 * x * exp (- a3 * x)
which is
A - V
MZ123
MZ123 on 14 Sep 2018
Thank you everybody for your answers. For Stephan: in my function I have (A - V) and also the exponential part. In my second part I just put a very simple parabola-like polynomial fit to emphasize why it is (to me) so difficult to obtain in Matlab the same results which I got with Origin.
For what concerns the code I'm running... I would say that I'm applying straightforwardly what I learned in the documentation. For example in the parabola case what I run is this:
x = [177600,961200, 2504000, 4997000, 8884000];
y = [6.754, 24.416, 58.622, 107.980, 154.507];
beta0 = [1.5,1E-5,-1E-12];
myfun = 'y~b1+b2*x+b3*x^2';
mdl1 = fitnlm(x,y,myfun,beta0)
Estimated Coefficients:
Estimate SE tStat pValue
___________ __________ __________ __________
b1 1.0237 2.3928e-13 4.2781e+12 2.8166e-38
b2 2.6025e-05 4.9385e-07 52.699 1.5049e-05
b3 -9.8098e-13 6.2704e-14 -15.645 0.00056757
Warning: The Jacobian at the solution is ill-conditioned, and some model parameters may not be estimated well (they are not identifiable). Use caution in making predictions.
Of course parameter b1 has a acceptable estimate value, but the SE is not accurate at all. Origin retrieves a SE = 0.5 more or less..

Sign in to comment.


Alex Sha
Alex Sha on 23 Sep 2019
The global solution looks like below:
Root of Mean Square Error (RMSE): 1.42818042380826
Sum of Squared Residual: 10.1984966147457
Correlation Coef. (R): 0.999655170571204
R-Square: 0.999310460049744
Adjusted R-Square: 0.998620920099487
Determination Coef. (DC): 0.999310460049744
Chi-Square: 0.212210508410738
F-Statistic: 1449.24229503583
Parameter Best Estimate
---------- -------------
v 0.665211685653936
a 544.888484613983
s 4.9628897712431E-8

Community Treasure Hunt

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

Start Hunting!