0

I am trying to use the scipy.optimize function curve_fit to fit a set of data points using a custom exponential function. My code is as follows:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def fit(x, tau, beta):
    return np.exp(-1 * np.power(x / tau, beta))

def plot_e2e(times, e2es):
    optimalParams, covariance = curve_fit(fit, times, e2es)
    tau = optimalParams[0]
    beta = optimalParams[1]

    print 'Tau is:', tau
    print 'Beta is:', beta

if __name__ == '__main__':
    % read_e2e_data not included for proprietary reasons.
    times, e2es = read_e2e_data(fileName)
    plot_e2e(times, e2es)

Doing this raises the following exception (line numbers may be different due to taking out unrelated stuff):

Traceback (most recent call last):
  File ".\plot_e2e.py", line 54, in <module>
    plot_e2e(times, e2es)
  File ".\plot_e2e.py", line 34, in plot_e2e
    optimalParams, covariance = curve_fit(fit, times, e2es)
  File "C:\Anaconda\lib\site-packages\scipy\optimize\minpack.py", line 586,  in curve_fit 
    raise RuntimeError(msg)
RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 600.

If I increase the maxfev parameter of curve_fit I instead get bogus values for Tau (4.035e-303).

My time and e2e vectors are thus:

time = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 9.0, 11.0, 14.0, 17.0, 21.0, 25.0, 30.0, 37.0, 45.0, 54.0, 65.0, 78.0, 94.0, 113.0, 136.0, 163.0, 196.0, 236.0, 283.0, 340.0, 409.0, 491.0]
e2es = [1.0, 0.999804, 0.99964, 0.999497, 0.99937, 0.999276, 0.999139, 0.998974, 0.998566, 0.998005, 0.997225, 0.997073, 0.997793, 0.998586, 1.001542, 1.004414, 1.005311, 1.001431, 1.001016, 0.998936, 0.995649, 0.993765, 0.98663, 0.985266, 0.984635, 0.982588, 0.974413, 0.973811, 0.968772, 0.970131]

If you have any ideas as to what might be the issue, please let me know. I've been trying to debug this issue and have hit a dead end.

Joboman555
  • 83
  • 1
  • 7
  • In the search for the optimal parameters, `curve_fit` starts with them all being 1, which can be a pretty bad guess. Try using the `p0` argument, giving it a value that is more appropriate than all 1s. Even a very crude guess in which the parameters have only roughly the correct order of magnitude can make a big difference. See, for example, http://stackoverflow.com/questions/21420792/exponential-curve-fitting-in-scipy/21421137#21421137 – Warren Weckesser Jul 25 '16 at 18:39
  • I was able to converge by changing my function to `np.exp(-1 * np.power(x * tau, beta))` so that I didn't have the discontinuity. – Joboman555 Jul 25 '16 at 18:42
  • @Joboman555 these are the parameters for curve-fit http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html – Rachel Gallen Aug 01 '16 at 13:49

1 Answers1

1

The error you are getting basically means that Scipy's search for the right fit hasn't managed to converge. Scipy defines a value called maxfev, whose purpose is after how many iterations it gives up on the search. You can alter this parameter:

def plot_e2e(times, e2es):
    optimalParams, covariance = curve_fit(fit, times, e2es, maxfev=1000)
    ...

Hope this helps!

Roy Zohar
  • 19
  • 1