Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to scipy.optimize.curve_fit

I'm trying to plot some visualisations with matplotlib, and in one of my functions, I check if waves are logarithmic. This is my current working version:

import numpy as np
def is_logarithmic(waves):

    def expfunc(x, a, b, c):
        return a*np.exp(b*x) + c

    wcopy = list(waves)
    wcopy.sort()

    # If the ratio of x-max : x-min < 10, don't use a logarithmic scale
    # (at least in matplotlib)
    if (wcopy[-1] / wcopy[0]) < 10:
        return False

    # Take a guess at whether it is logarithmic by seeing how well the x-scale
    # fits an exponential curve
    diffs = []
    for ii in range(len(wcopy) - 1):
        diffs.append(wcopy[ii + 1] - wcopy[ii])

    # Fit the diffs to an exponential curve
    x = np.arange(len(wcopy)-1)
    try:
        popt, pcov = curve_fit(expfunc, x, diffs)
    except Exception as e:
        print e
        popt = [0.0, 0.0, 0.0]
        pcov = np.inf

    # If a > 0.5 and covsum < 1000.0
    # use a logarithmic scale.
    if type(pcov) == float:
        # It's probably np.inf
        covsum = pcov
    else:
        covsum = pcov.diagonal().sum()
    res = (covsum < 1000.0) & (popt[0] > 0.5)
    return res

I'm trying to find an alternative to scipy's curve_fit(), because I don't want to install such a big library just to use that one function. Is there something else I can use, or a combination of other functions from using ideally just numpy and matplotlib, to get a similar result?

like image 933
Andrew Avatar asked Jul 08 '15 04:07

Andrew


2 Answers

Numpy can do linear (numpy.linalg.lstsq) and polynomial fits (numpy.polyfit). In general you need scipy for fitting to functions you define yourself (scipy uses the fortran minpack while numpy is built only with C).

However, for your example, you could use a similar approach to this question to fit an exp. Basically, take the logatithm of both sides of the equation and use numpy.polyfit.

like image 78
Ed Smith Avatar answered Oct 21 '22 01:10

Ed Smith


You can also use the lmfit.models library which has a lot of predefined models.

https://lmfit.github.io/lmfit-py/

https://lmfit.github.io/lmfit-py/builtin_models.html#exponential-and-power-law-models

It also supports custom functions.

like image 40
Joni Avatar answered Oct 21 '22 00:10

Joni