2015-07-08 13 views
5

Próbuję wykreślić kilka wizualizacji za pomocą matplotlib, aw jednej z moich funkcji sprawdzam, czy fale są logarytmiczne. To jest moja aktualna wersja robocza:Alternatywa dla scipy.optimize.curve_fit

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 

Próbuję znaleźć alternatywę do scipy na curve_fit(), ponieważ nie chcę, aby zainstalować taką dużą bibliotekę prostu w obsłudze, że jednej funkcji. Czy jest coś innego, czego mogę użyć, lub kombinację innych funkcji, używając idealnie tylko numpy i matplotlib, aby uzyskać podobny rezultat?

+1

Cóż, 'curve_fit' używa algorytmu [Levenberg-Marquardt] (https://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm) do minimalizacji błędów. Zawsze możesz to zaimplementować samodzielnie. – hitzg

+1

Jeśli nie pracujesz z systemami wbudowanymi, "46 MB" (zainstalowane na Linuksie) dla scipy to niewiele. Matplotlib ma w porównaniu '72 MB'. – rth

Odpowiedz

3

Numpy może zrobić liniowy (numpy.linalg.lstsq) i wielomianowy pasuje (numpy.polyfit). Ogólnie rzecz biorąc, potrzebujesz scipy, aby dopasować się do zdefiniowanych przez ciebie funkcji (scipy używa minboxa fortranowego, podczas gdy numpy jest budowana tylko z C).

Jednakże, dla przykładu, można zastosować podobne podejście do pytania this, aby dopasować eksp. Zasadniczo, weź logatyt z obu stron równania i użyj numpy.polyfit.

+0

Mam na myśli C, dziękuję –

+1

Biorąc "log" z obu stron nie będzie działać w tym przypadku ze względu na stały termin 'c' w' a * np.exp (b * x) + c'. – tom10