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

 Réponse acceptée

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
.

6 commentaires

Thanks for your response. What does exitflag 3 here means?Does it show the problem has an answer?
My pleasure!
From the documentation on exitflag: ‘Change in the residual is less than the specified tolerance.’ So that essentially means it converged on a solution, however not the best solution (that would have returned 1).
.
Is there any other way to fit theoretical models to experimental data?
There is, but in your case, it's not a question of the numerical method of fitting, but of the bad experimental data.
I see. Is there any way to get the coefficient of determination for the fit? for example, what is the coefficient of determination for the exponential model used to fit the experimental data here?
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
fprintf('\nThe Adjusted R² Value = %.6f\n', mdl.Rsquared.Adjusted)
The Adjusted R² Value = 0.883546
.

Connectez-vous pour commenter.

Plus de réponses (2)

Torsten
Torsten le 31 Mai 2023
Déplacé(e) : Torsten le 31 Mai 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.
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.

Catégories

En savoir plus sur Curve Fitting Toolbox dans Centre d'aide et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by