fitting data with a combination of exponential and linear form ( a*exp(-x/b)+c*x+d )
15 views (last 30 days)
Show older comments
Hello Altruists,
I have been trying to fit my data to a combination of exponential and linear form, i.e., a*exp(-x/b)+c*x+d . I am not getting a good fit (image attached). I am getting an warning as well (Warning: Start point not provided, choosing random start point). Could anyone offer some help?
I have tried with this code:
data= readmatrix('data');
x= data(:,1);
y = data(:,2);
% getting fitting parameters
explinearfit = fittype('a*exp(-x/b)+c*x+d')
fo = fitoptions(explinearfit);
fo.normalize = 'on';
myFit = fit(x,y,explinearfit);
%plot
plot(myFit,x,y)
ylabel('Y')
xlabel('X')
legend('Data','Fit', 'location', 'best')
0 Comments
Answers (4)
Matt J
on 4 Jul 2023
Edited: Matt J
on 4 Jul 2023
If you download fminspleas, you can get a pretty good fit with a fairly naive initial guess [b,e,f]=[-1,0,0]:
[x,y]=readvars('data.csv');
flist={ @(p,x)exp(p(1)*x) ,@(p,x) x, 1, @(p,x)tanh(p(2)*x+p(3))};
warning off
[p,coeff]=fminspleas(flist,[-1,0,0],x,y,-inf(1,3),[0,inf,inf]); warning on
p(:).'
xs=linspace(min(x),max(x));
plot(x,y,'--g',xs, ffit(xs,p,coeff,flist));
function y=ffit(x,p,coeff,flist)
y=0;
for i=1:numel(flist)
f=flist{i};
if isnumeric(f)
y=y+coeff(i)*f;
else
y=y+coeff(i)*f(p,x);
end
end
end
0 Comments
Torsten
on 3 Jul 2023
Moved: Torsten
on 3 Jul 2023
Try
f(x) = a*atan(b*x)
It's too steep at the beginning and too flat at the end, but better than your model function.
data= readmatrix('data');
x = data(:,1);
y = data(:,2);
f = @(p) p(1)*atan(p(2)*x);
fun = @(p) f(p) - y;
sol = lsqnonlin(fun,[2/pi 1])
hold on
plot(x,y,'o')
plot(x,f(sol))
hold off
Alex Sha
on 4 Jul 2023
If taking fitting function as "y=a*exp(-x/b)+c*x+d", the result will be:
Sum Squared Error (SSE): 0.473516174967249
Root of Mean Square Error (RMSE): 0.0194398036424297
Correlation Coef. (R): 0.993172772220197
R-Square: 0.986392155479551
Parameter Best Estimate
--------- -------------
a -0.626947642051749
b 1365.46862978889
c 1.57136165222552E-5
d 0.682801486192597
If taking fitting function as "y=a*exp(b*x)+c*exp(d*x)", the result will be:
Sum Squared Error (SSE): 0.517841961771885
Root of Mean Square Error (RMSE): 0.0203293308633968
Correlation Coef. (R): 0.992531430423344
R-Square: 0.985118640378209
Parameter Best Estimate
--------- -------------
a -0.637793104918275
b -0.00067464442828496
c 0.705787394940032
d 1.74592589676531E-5
A much better result will be obtained if taking fitting function as "y=a*exp(b*x)+c*x+d+tanh(e*x+f)*p"
Sum Squared Error (SSE): 0.154723411889559
Root of Mean Square Error (RMSE): 0.0111122622277951
Correlation Coef. (R): 0.997774312797138
R-Square: 0.995553579277802
Parameter Best Estimate
--------- -------------
a -0.44380788683452
b -0.000338851451599573
c 1.0070723631259E-5
d 0.571547658395962
e 0.0025117355962601
f -0.850904593274322
p 0.195041944730927
3 Comments
Torsten
on 4 Jul 2023
Edited: Torsten
on 4 Jul 2023
Try if you can reproduce the results if you use the fitting parameters as initial guesses in MATLAB.
@Alex Sha has his "special tool" to do the fitting (not part of MATLAB), and I think he invests quite a long time to adequate initial guesses for the parameters.
Alex Sha
on 5 Jul 2023
I'm ashamed that it's not my product, although hopefully it's a commercial optimization solver package, I just like to use it because it's simple to use but works well.
Sam Chak
on 5 Jul 2023
The data seems to exhibit the pattern of an nth-root function (a form of the power function), given by
where is a negative exponent function that varies with x. Because the data is bounded by 1, we can assume that . Since the exponential function-based models yield some good results in @Alex Sha's fitting, I attempted with the following model:
Fit model #1
% Data Sets
[x, y] = readvars('data.csv');
% Curve-fitting
fo = fitoptions('Method', 'NonlinearLeastSquares', ...
'Lower', [-0.9, -0.006, -0.07, -0.0002, -1.2, -0.04, -0.2, -0.0008], ...
'Upper', [0, 0, 0, 0, 0, 0, 0, 0], ...
'StartPoint', [1 1 1 1 1 1 1 1]);
ft = fittype('x^(a*exp(b*x) + c*exp(d*x) + e*exp(f*x) + g*exp(h*x))', 'options', fo);
[yfit, gof] = fit(x, y, ft)
figure
plot(x, y, '.', 'color', '#A7B7F7'), hold on
plot(yfit, 'r'), hold off, grid on
legend('Data', 'Fitted curve', 'location', 'best')
Note that the coefficients are not unique. In my machine, I got different results"
Fit model #2
General model:
f(x) = x^(a*exp(b*x) + c*exp(d*x) + e*exp(f*x) + g*exp(h*x))
Coefficients (with 95% confidence bounds):
a = -0.1227 (-0.1285, -0.1169)
b = -0.0007697 (-0.0008078, -0.0007315)
c = -0.06455 (-0.06617, -0.06292)
d = -0.0001311 (-0.0001335, -0.0001288)
e = -1.12 (-1.968, -0.2716)
f = -0.03423 (-0.0573, -0.01116)
g = -0.8431 (-0.929, -0.7572)
h = -0.005286 (-0.005609, -0.004962)
Goodness of fit:
SSE: 0.1438
R-square: 0.9959
Adjusted R-square: 0.9958
RMSE: 0.01075
Fit model #3
General model:
f(x) = x^(a*exp(b*x) + c*exp(d*x) + e*exp(f*x) + g*exp(h*x))
Coefficients (with 95% confidence bounds):
a = -0.8429 (-0.9291, -0.7566)
b = -0.005285 (-0.00561, -0.00496)
c = -0.06455 (-0.06617, -0.06292)
d = -0.0001311 (-0.0001335, -0.0001288)
e = -1.107 (-1.94, -0.2753)
f = -0.03402 (-0.05694, -0.01109)
g = -0.1227 (-0.1285, -0.1169)
h = -0.0007697 (-0.0008078, -0.0007315)
Goodness of fit:
SSE: 0.1438
R-square: 0.9959
Adjusted R-square: 0.9958
RMSE: 0.01075
3 Comments
Alex Sha
on 5 Jul 2023
For fitting function provided by @Sam Chak, the results are actually unique, only the order is different
Sum Squared Error (SSE): 0.143801140894944
Root of Mean Square Error (RMSE): 0.0107128649564239
Correlation Coef. (R): 0.997931669471303
R-Square: 0.995867616933781
Parameter Best Estimate
--------- -------------
a -0.842982011054431
b -0.00528502909652476
c -0.122676258206711
d -0.000769613241785951
e -0.0645440331501187
f -0.000131143071549622
g -1.11996380236003
h -0.0342317204260728
See Also
Categories
Find more on Linear and Nonlinear Regression in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!