Корреляционная функция Scipy медленная

Я сравнил различные методы свертки / корреляции двух сигналов с помощью numpy / scipy. Оказывается, существуют огромные различия в скорости. Я сравнил следующие методы:

  • коррелировать из пакета numpy (np.коррелировать в сюжете)
  • коррелировать с scipy.пакет сигналов (СФС.коррелировать в сюжете)
  • fftconvolve от scipy.сигнал (sps.fftconvolve в сюжете)

сейчас я конечно понимаю, что есть значительная разница между fftconvolve и двумя другими функциями. Чего я не понимаю, так это почему sps.коррелят намного медленнее, чем np.соотносить. Кто-нибудь знает, почему scipy использует реализацию, которая намного медленнее?

сравнение скорости http://i62.tinypic.com/ofrqxc.png

для полноты, вот код, который производит сюжет:

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()

1 ответов


согласно документации, numpy.correlate был разработан для массивов 1D, в то время как scipy.correlate может принимать ND-массивы.

реализация scipy является более общей и, следовательно, сложной, похоже, действительно несет дополнительные вычислительные накладные расходы. Вы можете сравнить код C между включает в себя и scipy реализаций.

другое отличие, может быть, например, что реализация numpy лучше векторизована компилятором на modern процессоров и т. д.