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()
będzie szybciej w przyszłości https://github.com/scipy/scipy/pull/5608 – endolith