# Why the nonlinear least square fitted curve is not a curve?

2 views (last 30 days)
Pooneh Shah Malekpoor on 31 May 2023
Commented: Star Strider on 7 Jun 2023
Hello
Can anyone please tell me why the resulting fit is not a curve, though I have defined an exponential curve?
Thanks
Data=[0.928571429, 0;
0.012118074, 1.5;
-0.450001188, 3;
-0.316739249, 4.5;
0.394139277, 6;
0.094786629, 7.5;
-0.139747215, 9;
-0.225960048, 10.5;
0.092637089, 12;
-0.018817212, 13.5;
0.057294651, 15;
0.034956239, 16.5;
0.099005863, 18;
-0.097958625, 19.5]
Data = 14×2
0.9286 0 0.0121 1.5000 -0.4500 3.0000 -0.3167 4.5000 0.3941 6.0000 0.0948 7.5000 -0.1397 9.0000 -0.2260 10.5000 0.0926 12.0000 -0.0188 13.5000
t = Data(:,2);
y = Data(:,1);
plot(t,y,'ro')
title('Data points')
F=@(x,t)exp(-2*abs(t)/x(1));
x0 = [1.29];
[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x = 0.5860
resnorm = 0.5758
exitflag = 3
output = struct with fields:
firstorderopt: 3.7922e-05 iterations: 13 funcCount: 28 cgiterations: 0 algorithm: 'trust-region-reflective' stepsize: 0.0070 message: 'Local minimum possible.↵↵lsqcurvefit stopped because the final change in the sum of squares relative to ↵its initial value is less than the value of the function tolerance.↵↵<stopping criteria details>↵↵Optimization stopped because the relative sum of squares (r) is changing↵by less than options.FunctionTolerance = 1.000000e-06.' bestfeasible: [] constrviolation: []
hold on
plot(t,F(x,t))
hold off

Star Strider on 31 May 2023
Just for fun, I added a periodic function and a slope to the model —
Data=[0.928571429, 0;
0.012118074, 1.5;
-0.450001188, 3;
-0.316739249, 4.5;
0.394139277, 6;
0.094786629, 7.5;
-0.139747215, 9;
-0.225960048, 10.5;
0.092637089, 12;
-0.018817212, 13.5;
0.057294651, 15;
0.034956239, 16.5;
0.099005863, 18;
-0.097958625, 19.5]
Data = 14×2
0.9286 0 0.0121 1.5000 -0.4500 3.0000 -0.3167 4.5000 0.3941 6.0000 0.0948 7.5000 -0.1397 9.0000 -0.2260 10.5000 0.0926 12.0000 -0.0188 13.5000
t = Data(:,2);
y = Data(:,1);
plot(t,y,'ro')
title('Data points')
F=@(x,t)exp(x(1).*t) .* sin(2*pi*x(2).*t + x(3)) + x(4).*t + x(5);
% x0 = [1.29];
x0 = randn(5,1);
[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x = 5×1
-0.1899 -0.8174 7.8199 0.0026 -0.0388
resnorm = 0.1143
exitflag = 3
output = struct with fields:
firstorderopt: 0.0022 iterations: 34 funcCount: 210 cgiterations: 0 algorithm: 'trust-region-reflective' stepsize: 0.0012 message: 'Local minimum possible.↵↵lsqcurvefit stopped because the final change in the sum of squares relative to ↵its initial value is less than the value of the function tolerance.↵↵<stopping criteria details>↵↵Optimization stopped because the relative sum of squares (r) is changing↵by less than options.FunctionTolerance = 1.000000e-06.' bestfeasible: [] constrviolation: []
hold on
plot(t,F(x,t))
hold off
.
Star Strider on 7 Jun 2023
The easiest way is to use the Statistics and Machine Learning Toolbox fitnlm function —
Data=[0.928571429, 0;
0.012118074, 1.5;
-0.450001188, 3;
-0.316739249, 4.5;
0.394139277, 6;
0.094786629, 7.5;
-0.139747215, 9;
-0.225960048, 10.5;
0.092637089, 12;
-0.018817212, 13.5;
0.057294651, 15;
0.034956239, 16.5;
0.099005863, 18;
-0.097958625, 19.5];
t = Data(:,2);
y = Data(:,1);
plot(t,y,'ro')
title('Data points')
F=@(b,t)exp(b(1).*t) .* sin(2*pi*b(2).*t + b(3)) + b(4).*t + b(5);
% x0 = [1.29];
x0 = randn(5,1);
[B,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y);
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
hold on
plot(t,F(B,t))
hold off
mdl = fitnlm(t, y, F, B)
mdl =
Nonlinear regression model: y ~ exp(b1*t)*sin(2*pi*b2*t + b3) + b4*t + b5 Estimated Coefficients: Estimate SE tStat pValue _________ _________ ________ __________ b1 -0.18987 0.032945 -5.7632 0.00027174 b2 1.1826 0.0083811 141.1 2.2919e-16 b3 1.5374 0.20992 7.3237 4.4504e-05 b4 0.0026496 0.0053225 0.49781 0.63055 b5 -0.03883 0.06319 -0.61449 0.5541 Number of observations: 14, Error degrees of freedom: 9 Root Mean Squared Error: 0.113 R-Squared: 0.919, Adjusted R-Squared 0.884 F-statistic vs. constant model: 25.7, p-value = 6.16e-05
The Adjusted R² Value = 0.883546
.

Torsten on 31 May 2023
Moved: Torsten on 31 May 2023
Why do you think the red line is not a curve ?
For this point cloud of experimental data, I think the red line is the best you can get as a fitting curve.

John D'Errico on 31 May 2023
Edited: John D'Errico on 31 May 2023
Data=[0.928571429, 0;
0.012118074, 1.5;
-0.450001188, 3;
-0.316739249, 4.5;
0.394139277, 6;
0.094786629, 7.5;
-0.139747215, 9;
-0.225960048, 10.5;
0.092637089, 12;
-0.018817212, 13.5;
0.057294651, 15;
0.034956239, 16.5;
0.099005863, 18;
-0.097958625, 19.5]
Data = 14×2
0.9286 0 0.0121 1.5000 -0.4500 3.0000 -0.3167 4.5000 0.3941 6.0000 0.0948 7.5000 -0.1397 9.0000 -0.2260 10.5000 0.0926 12.0000 -0.0188 13.5000
t = Data(:,2);
y = Data(:,1);
plot(t,y,'ro')
title('Data points')
F=@(x,t)exp(-2*abs(t)/x(1));
x0 = [1.29];
[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
x = 0.5860
resnorm = 0.5758
exitflag = 3
output = struct with fields:
firstorderopt: 3.7922e-05 iterations: 13 funcCount: 28 cgiterations: 0 algorithm: 'trust-region-reflective' stepsize: 0.0070 message: 'Local minimum possible.↵↵lsqcurvefit stopped because the final change in the sum of squares relative to ↵its initial value is less than the value of the function tolerance.↵↵<stopping criteria details>↵↵Optimization stopped because the relative sum of squares (r) is changing↵by less than options.FunctionTolerance = 1.000000e-06.' bestfeasible: [] constrviolation: []
hold on
plot(t,F(x,t))
hold off
It IS a curve. It is just a curve shape that does not please you. But, given the obscenity that is this data, what do you expect? (I'm not insulting you. Just your data.) Should lsqcurvefit be able to make a silk purse from a rat's ear?
Essentially, the signal is just barely present to be able to fit that data. So lsqurvefit chose a solution with a rate constant that makes the curve go to zero almost immediately, as the best fit it could find. Your data is noisy, and your model just barely fits the data.
Finally, you plotted only a connect the dots curve between your data. plot does not know what the shape of that curve is BETWEEN the data points. It plots using straight line segments.