Fitting to exp plus a constant
이전 댓글 표시
Hello, I am trying to fit some data to an exponential + constant function and have this approach that I came across:
% code is giving good results with template equation : % y = a.*(1-exp(b.*(x-c))) + d;
f = @(a,b,c,d,x) a.*(1-exp(b.*(x-c))) + d;
obj_fun = @(params) norm(f(params(1), params(2), params(3), params(4),x)-y);
sol = fminsearch(obj_fun, [y(end)-y(1),0,0,y(1)]);
a_sol = sol(1);
b_sol = sol(2);
c_sol = sol(3);
d_sol = sol(4);
y_fit = f(a_sol, b_sol,c_sol ,d_sol, x);
figure
plot(x,y,'-+b',x,y_fit,'-r'); grid on;
legend('signal','aexp(b(x-c))+d');
title(['a=',num2str(a_sol,'%0.2f'), ' b=',num2str(b_sol),' c=',num2str(c_sol),' d=',num2str(d_sol)],'FontSize',14,'Color','b')
Whilst the fit is good, the value of "a" seems wrong (at the expense of "d")

I've tried another approach that I came across from Steven Lord (as i don't really understand the code above)
D=[x y]
% It would be better to parametrize the function as
xmin=min(x);
fitfun = fittype( @(a,b,c,x) a*exp(b*(x-xmin))+c );
[fitted_curve,gof] = fit(D(:,1),D(:,2),fitfun,'StartPoint',[max(y) -2 min(y)])
plot(fitted_curve,'r-')
But I get this error:
Error using fit>iFit (line 362)
Inf computed by model function, fitting cannot continue.
Try using or tightening upper and lower bounds on coefficients.
Error in fit (line 117)
[fitobj, goodness, output, convmsg] = iFit( xdatain, ydatain, fittypeobj, ...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in PlotAnalysis/FitExp1ContstantButtonPushed (line 1361)
[fitted_curve,gof] = fit(D(:,1),D(:,2),fitfun,'StartPoint',[max(y) -2 min(y)])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
답변 (1개)
It looks like the fit was successful, but the model function is overparametrized, so there is no specific value for a (or c) that you can count on,

where
. Whatever the decay rate b needed for the fit, there are infinite choices for a and c that will produce the same A (and thus the same curve).
댓글 수: 12
Jason
2025년 12월 17일
This is the model you show in your original code,
f = @(a,b,c,d,x) a.*(1-exp(b.*(x-c))) + d;
This model spans the same space of curves as a*exp(-b*c)+d, but with this parametrization, it is appropriate that "a" would be negative.
Hi @Jason
To understand what occurred, you need to plot both models for the negative and positive signs of the function's amplitude (a).

One model exhibits exponential growth, while the other demonstrates exponential decay. The constant parameter "d" simply shifts the exponential curve upward or downward.
% domain
x = 0:.01:100;
% parameters
a = -2.58;
b = -0.020469;
c = 0.020776;
d = 750.5648; % bias
% models
z = exp(b*(x - c)); % pure exponential model
y1 = a*(1 - z) + 0; % exponentially decaying
y2 = -a*(1 - z) + 0; % exponentially growing
% plot result
figure
plot(x, [y1; y2]), grid on
xlabel('x')
ylabel('Amplitude')
legend('exponentially decaying', 'exponentially growing', 'location', 'east')
figure
plot(x, z), grid on
xlabel('x')
ylabel('Amplitude')
title('decaying exponential model: exp(- 0.020469*(x - c))')
@Jason Just to put a finer point on it, there is no reason to think the value of "d" you're seeing is inappropriate in any way, or linked to the negative sign you're seeing on the "a" parameter. We know the sign of the "a" parameter is correct because otherwise, your convex data would end up being fitted by a concave curve. That's true independently of the specific form of the model equation that you're using.
Jason
2025년 12월 17일
Jason
2025년 12월 17일
You should not use a custom fittype model for the fit. This requires you to provide a very accurate initial guess of the parameters. Instead, use the built-in 'exp2' fittype, with bounds to constrain the second decay rate to zero.
Alternatively, fminspleas from the File Exchange would also be very robust,
a = 2.5846; b = 0.020469; c = 747.9813; %hypothetical data
x=1:100;
y=a*exp(-b*x)+c; y=y+randn(size(y))*0.1;
[b,ac]=fminspleas( {@(b,x) exp(-b*x),1} ,0.005, x,y,0); %Do fit
a=ac(1); c=ac(2);
plot(x,y,'--bx',x, a*exp(-b*x)+c,'-r'); %Plot
title(sprintf('a=%.02f, b=%.04f,c=%.02f,',a,b,c))
legend Signal 'a*exp(-b*x)+c'
Torsten
2025년 12월 17일
Supply initial values for the fitting parameters. Then you should get back the same results.
Maybe "fit" uses randomized initial guesses.
Jason
2025년 12월 17일
I think you would get a better handle on that if you familiarized yourself with the fminspleas documentation. Briefly, though,
(1) 0.005 is the initial guess for b
(2) a and c are the coefficients applied to the exp(-b*x) and the 1 respectively in the input {@(b,x) exp(-b*x),1}. Their fitted values are returned in "ac". They do not require initial guess values.
카테고리
도움말 센터 및 File Exchange에서 Linear and Nonlinear Regression에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


