'Fit a function to the lists of arguments and
their respective run time in the cache.
By default, this does a linear least-square fitting
to a straight line on run time w.r.t. argument values
raised to the given power, and returns the optimal
intercept and slope.
Parameters
model : `astropy.modeling.Model`
Model for the expected trend of run time (Y-axis)
w.r.t. :math:`\text{arg}^{\text{power}}` (X-axis).
If `None`, will use `~astropy.modeling.polynomial.Polynomial1D`
with ``degree=1``.
fitter : `astropy.modeling.fitting.Fitter`
Fitter for the given model to extract optimal coefficient values.
If `None`, will use `~astropy.modeling.fitting.LinearLSQFitter`.
power : int, optional
Power of values to fit.
min_datapoints : int, optional
Minimum number of data points required for fitting.
They can be built up with `time_func`.
Returns
a : array-like
Fitted `~astropy.modeling.FittableModel` parameters.
Raises
ValueError
Insufficient data points for fitting.
ModelsError
Invalid model or fitter.'

def do_fit(self, model=None, fitter=None, power=1, min_datapoints=3):

    self._power = power
    self._cache_est = OrderedDict()
    x_arr = np.array(list(six.iterkeys(self._cache_good)))
    if (x_arr.size < min_datapoints):
        raise ValueError(u'requires    {0}    points    but    has    {1}'.format(min_datapoints, x_arr.size))
    if (model is None):
        model = modeling.models.Polynomial1D(1)
    elif (not isinstance(model, modeling.core.Model)):
        raise modeling.fitting.ModelsError(u'{0}    is    not    a    model.'.format(model))
    if (fitter is None):
        fitter = modeling.fitting.LinearLSQFitter()
    elif (not isinstance(fitter, modeling.fitting.Fitter)):
        raise modeling.fitting.ModelsError(u'{0}    is    not    a    fitter.'.format(fitter))
    self._fit_func = fitter(model, (x_arr ** power), list(six.itervalues(self._cache_good)))
    return self._fit_func.parameters
