2015-06-03 13 views
6

Porównałem różne metody zawijania/korelowania dwóch sygnałów za pomocą numpy/scipy. Okazuje się, że istnieją ogromne różnice w prędkości. I w porównaniu z metodami follwing:Funkcja korelacji Scipy'ego jest powolna

  • korelację z opakowania numpy (np.correlate polarnego)
  • korelują z opakowania scipy.signal (sps.correlate polarnego)
  • fftconvolve z scipy.signal (sps.fftconvolve w działce)

Teraz oczywiście rozumiem, że istnieje znaczna różnica między fftconvolve i dwie pozostałe funkcje. Czego nie rozumiem, to dlaczego sps.correlate jest o wiele wolniejsze niż np.correlate. Czy ktokolwiek wie dlaczego scipy używa implementacji, która jest o wiele wolniejsza?

Speed comparison http://i62.tinypic.com/ofrqxc.png

Dla kompletności, tutaj jest kod, który produkuje działkę:

import time 

import numpy as np 
import scipy.signal as sps 

from matplotlib import pyplot as plt 


if __name__ == '__main__': 

    a = 10**(np.arange(10)/2) 
    print(a) 

    results = {} 
    results['np.correlate'] = np.zeros(len(a)) 
    results['sps.correlate'] = np.zeros(len(a)) 
    results['sps.fftconvolve'] = np.zeros(len(a)) 

    ii = 0 
    for length in a: 

     sig = np.random.rand(length) 

     t0 = time.clock() 
     for jj in range(3): 
      np.correlate(sig, sig, 'full') 
     t1 = time.clock() 
     elapsed = (t1-t0)/3 

     results['np.correlate'][ii] = elapsed 

     t0 = time.clock() 
     for jj in range(3): 
      sps.correlate(sig, sig, 'full') 
     t1 = time.clock() 
     elapsed = (t1-t0)/3 

     results['sps.correlate'][ii] = elapsed 

     t0 = time.clock() 
     for jj in range(3): 
      sps.fftconvolve(sig, sig, 'full') 
     t1 = time.clock() 
     elapsed = (t1-t0)/3 

     results['sps.fftconvolve'][ii] = elapsed 

     ii += 1 

    ax = plt.figure() 
    plt.loglog(a, results['np.correlate'], label='np.correlate') 
    plt.loglog(a, results['sps.correlate'], label='sps.correlate') 
    plt.loglog(a, results['sps.fftconvolve'], label='sps.fftconvolve') 
    plt.xlabel('Signal length') 
    plt.ylabel('Elapsed time in seconds') 

    plt.legend() 
    plt.grid() 

    plt.show() 
+0

będzie szybciej w przyszłości https://github.com/scipy/scipy/pull/5608 – endolith

Odpowiedz

2

Zgodnie z dokumentacją, numpy.correlate zaprojektowana dla tablic 1D, natomiast scipy.correlate może zaakceptować ND-tablic.

Implementacja scipy jest bardziej ogólna, a przez to złożona, wydaje się, że wiąże się z dodatkowym obciążeniem obliczeniowym. Możesz porównać kod C między implementacjami numpy i scipy.

Kolejna różnica, może być na przykład, że numpy realizacja lepiej wektorowy przez kompilator na nowoczesnych procesorach, itp