fitting data with a combination of exponential and linear form ( a*exp(-x/b)+c*x+d )

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')

Réponses (4)

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(:).'
ans = 1×3
-0.0007 0.0005 0.0075
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
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])
Local minimum possible. lsqnonlin stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
sol = 1×2
0.6070 0.0006
hold on
plot(x,y,'o')
plot(x,f(sol))
hold off

1 commentaire

Thanks for your time answering my question. I appreciate this.
If I use 2 expoential functions (a*exp(b*x)+c*exp(d*x)), I could achieve a better fit as well. I used curve fitting tool achieve the fitting parameters. I was looking for something better; that is why I was exploring to linear+exponential form.
"
clc; clear; close all;
%%
data= readmatrix('data');
x= data(:,1);
y = data(:,2);
a = 0.7057;
b = 1.746e-05;
c = -0.6389;
d = -0.0006763;
y_f= a*exp(b*x)+c*exp(d*x);
figure;
plot(x,y, 's')
hold on
plot(x,y_f)
ylabel('X')
xlabel('Y')
legend('data', 'fit')
set(gca, 'fontname', 'times', 'fontsize', 12)
box on
"

Connectez-vous pour commenter.

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 commentaires

Hi Alex,
Thanks so much! I am convinced with the last one.
May I know how do I get the fitting parameters for the equation "y=a*exp(b*x)+c*x+d+tanh(e*x+f)*p" ? I have to perform similar fitting for different data sets. I tried using curve fitting tool to achieve these parameters and I am getting "Inf computed by model function, fitting cannot continue. Try using or tightening upper and lower bounds on coefficients" error.
Torsten
Torsten le 4 Juil 2023
Modifié(e) : Torsten le 4 Juil 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.
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.

Connectez-vous pour commenter.

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)
yfit =
General model: yfit(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.289 (-0.5166, -0.06147) b = -0.003427 (-0.004609, -0.002245) c = -0.06304 (-0.06519, -0.06088) d = -0.0001293 (-0.0001322, -0.0001264) e = -0.975 (-1.186, -0.7636) f = -0.008562 (-0.01062, -0.006502) g = -0.1089 (-0.1211, -0.09673) h = -0.0007063 (-0.0007685, -0.0006441)
gof = struct with fields:
sse: 0.1447 rsquare: 0.9958 dfe: 1245 adjrsquare: 0.9958 rmse: 0.0108
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 commentaires

You can also use the Curve-fitting App. But you definitely need to tighten the lower and upper bounds of the coefficients. The upper bounds can be set to zero. 7 out of 8 coefficients have lower bounds in the range , except for the fifth coefficient e ().
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
Thanks @Alex Sha for the clarification on the coefficients in Fit models #2 and #3.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Linear and Nonlinear Regression dans Centre d'aide et File Exchange

Produits

Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by