Fitting a double exponential function to three points
The previous post needed to fit a double exponential function to data, a function of the form
By taking logs, we have a function of the form
where thea in the latter equation is the log of thea in the former.
In the previous post I used a curve fitting function from SciPy to find the parameters a,b, andc. The solution in the post works, but I didn't show all the false starts along the way. I ran into problems with overflow and with the solution method not converging before I came up with the right formulation of the problem and a good enough initial guess at the solution.
This post will look at fitting the function more analytically. I'll still need to solve an equation numerically, but an equation in only one variable, not three.
If you need to do a regression, fitting a function with noisy data to more than three points, you could use the code below with three chosen data points to find a good starting point for a curve-fitting method.
SolutionSuppose we have x1 < x2 < x3 and we want to find a, b, and c such that
where y1 < y2 < y3.
Subtract the equations pairwise to eliminate a:
Divide these to eliminate b:
Factor out exp(cx1) from the right side:
Now the task is to solve
where
Note that L, d2, and d3 are all positive.
Once we find c numerically,
and
Here's a Python implementation to illustrate and test the derivation above.
from scipy import expfrom scipy.optimize import newtondef fit(x1, x2, x3, y1, y2, y3): assert(x1 < x2 < x3) assert(y1 < y2 < y3) d2 = x2 - x1 d3 = x3 - x1 L = (y2 - y1)/(y3 - y1) g = lambda x: L - (1 - exp(x*d2))/(1 - exp(x*d3)) c = newton(g, 0.315) b = (y2 - y1)/(exp(c*x2) - exp(c*x1)) a = y1 - b*exp(c*x1) return a, b, ca, b, c = fit(9, 25, 28, 42, 55, 92)print([a + b*exp(c*x) for x in [9, 25, 28]])The post Fitting a double exponential function to three points first appeared on John D. Cook.