Custom exponential fit doesn't seem to work
19 views (last 30 days)
Show older comments
Hey everyone,
I was stumbling in a bit of a problem and I hope one of you might be able to help me out. I have some data points (it's about 250ish) and am trying to fit an exponentially decreasing function with non-zero constant term to it, i.e. . However, no matter what I tried so far (different fitting functions, methods, starting points), I always end up with something that looks a lot like a constant function and basically resembles the data points not at all. This is the code I've been using so far:
% Here comes a previous part of the code, which extracts the data in
% question from a larger array and ends up giving you some x- and y-values.
% Those will be attached to the question.
x0 = [1 -2 12500];
fitfun = fittype( @(a,b,c,x) a*exp(b*x)+c );
[fitted_curve,gof] = fit(Data(:,1),Data(:,2),fitfun,'StartPoint',x0)
Unfortunately, when I plot the results, I end up with the following:
That obviously can't be the best fit possible.I've already looked at the fit-Function itself, but didn't get any useful information regarding my problem from the doc. Even though I'm almost certain it's just some trivial error, I fail to spot it. So thanks in advance for anyone trying to help me out here.
Cheers!
2 Comments
Alex Sha
on 14 Nov 2022
Edited: Alex Sha
on 14 Nov 2022
The start values your given/guessed are not appropriate。Refer to the result below:
Sum Squared Error (SSE): 31299597.4141903
Root of Mean Square Error (RMSE): 353.128292963896
Correlation Coef. (R): 0.992075938598263
R-Square: 0.984214667945624
Parameter Best Estimate Std. Deviation Confidence Bounds[95%]
--------- ------------- -------------- --------------------------------
a 4.76448778913171E18 1.06042570762486E-5 [4.76448778913171E18, 4.76448778913171E18]
b -0.0445919965391538 24.8230867373737 [-48.935539282319, 48.8463552892407]
c 12317.7442468735 4.75238610300809E-14 [12317.7442468735, 12317.7442468735]
Accepted Answer
Matt J
on 14 Nov 2022
Edited: Matt J
on 14 Nov 2022
Is there a way to automatically find more appropriate initial guesses?
Use fminspleas from the File Exchange. Then you only need an initial guess for 'b'.
load Data
x=Data(:,1); y=Data(:,2);
funlist={@(b,x)exp(b.*x),1};
warning off
[b,ac]=fminspleas(funlist,0,x,y,-2,0)
warning on
f=@(x) ac(1)*exp(b*x)+ac(2);
plot(x,y,'x',x,f(x))
More Answers (2)
Steven Lord
on 14 Nov 2022
Consider specifying the Normalize name-value pair argument in your fit call to normalize the X data. In my example below I'll use the normalize function instead of that argument, but it's the same general idea.
format longg
x = (750:10:800)';
Your x data is so large in magnitude that the exponential overflows to Inf.
plainExp = exp(x)
Even if we cut the magnitude by a factor of 10, the values of the exponential are still really large in magnitude.
expOfOneTenthX = exp(x/10)
But if we normalize the x data, the values are much smaller:
centeredAndScaledX = normalize(x)
and so are the values of the exponential. These can be "nicer" to work with.
centedAndScaledExp = exp(centeredAndScaledX)
0 Comments
Matt J
on 14 Nov 2022
Edited: Matt J
on 14 Nov 2022
It would be better to parametrize the function as
xmin=min(x)
f=@(x)a*exp(-b.*(x-xmin))+c;
The fit is better conditioned that way, and you don't get such insanely large values for a and c. Your original approach works much better with this change, as you can see below.
load Data; x=Data(:,1); y=Data(:,2);
xmin=min(x);
fitfun = fittype( @(a,b,c,x) a*exp(b*(x-xmin))+c );
[fitted_curve,gof] = fit(Data(:,1),Data(:,2),fitfun,'StartPoint',[max(y) -2 min(y)])
plot(fitted_curve,x,y)
1 Comment
Matt J
on 14 Nov 2022
You don't really even need a StartPoint guess (although you do need positivity bounds):
[fitted_curve,gof] = fit(Data(:,1),Data(:,2),fitfun,'Lower',[0,0,0])
plot(fitted_curve,x,y)
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!