Using the fit() function to find an exponential gives me a straight line..?

186 views (last 30 days)
I am trying to find the best fit equation using a set of data points, but when I use the fit() function and plot it, it gives me a straight line. I plotted the equation using the given a and b values on an online grapher, and it was a straight line as well. However, when I plot the original data it is not a straight line. I am not sure why the function is not working properly, so any help would be appreciated.
  7 Comments
Adam Danz
Adam Danz on 1 Feb 2021
fitnlm doesn't do any better
mdl = @(b,x)b(1).*exp(b(2).*x);
f = fitnlm(tnew, v2new, mdl, [20,.001])
coef = f.Coefficients.Estimate;
x = linspace(min(tnew), max(tnew));
y = mdl(coef, x);
plot(tnew, v2new, 'b-')
hold on
plot(x,y,'r-')
axis equal
Adam Danz
Adam Danz on 1 Feb 2021
Edited: Adam Danz on 1 Feb 2021
Well, hold on. It's not a straight line. It's an exponential decay curve defined by
f =
General model Exp1:
f(x) = a*exp(b*x)
Coefficients (with 95% confidence bounds):
a = 20.83 (20.72, 20.93)
b = -0.002372 (-0.00245, -0.002295)
In fact, you can fit a straight line to the curve and plot the residuals,
betas = polyfit(tnew, f(tnew), 1);
y = betas(1).*tnew + betas(2);
figure()
stem(tnew, f(tnew)-y)
And if you use a different set of x values where y increases more dramatically, you can see the decay curve much better,
plot(-1000:200, f(-1000:200))
axis equal

Sign in to comment.

Accepted Answer

John D'Errico
John D'Errico on 2 Feb 2021
Edited: John D'Errico on 2 Feb 2021
Your real problem is the data does NOT support the model you want to fit. You can squeeze as hard as you want. That model is simply incorrect. Thus, you are trying to fit this model:
y = a*exp(-b*t)
At least for the part of your curve above roughly t=15.5. Below that point, strange stuff happens that is clearly not even close to exponential in nature.
ind = t > 15.5;
plot(t(ind),v2(ind),'o')
Now, what should happen as that model approaches infinity? exp(-b*t) --> 0 for large t Yet if we look at your data, it seems to approch a value around roughly 17. And the last time I checked, 17 is pretty far away from zero!
So it does not matter what you try. That model is flat out incorrect.
What may work a little better, is if you try to estimate a y offset.
So instead, consider the model:
ft = fittype('a*exp(-b*t) + c','indep','t')
ft =
General model:
ft(a,b,c,t) = a*exp(-b*t) + c
c can be thought of as the asymptotic value as t approaches infinity. I would expect to see a value of roughly 17, based on that plot, maybe a little under.
mdl = fit(t(ind)',v2(ind)',ft,'start',[10,0.1,17])
mdl =
General model:
mdl(t) = a*exp(-b*t) + c
Coefficients (with 95% confidence bounds):
a = 10.84 (10.77, 10.92)
b = 0.04867 (0.04835, 0.04899)
c = 16.88 (16.88, 16.89)
plot(mdl)
hold on
plot(t(ind),v2(ind),'.')
Hmm. that looks seriously good this time. I can hardly see the red curve drawn under the dots. I even tried to make the dots small. If you look VERY carefully, it is there.
Do you see the difference?
The limit as t--> inf is now 16.88.
Using a reasonably correct model is a HUGELY important thing. Here, it was an extra term, one that you were missing. Is the result an exponential model? Well, arguably not a pure exponential model. It is similar, except for that constant translational offset in the y direction.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!