Вычисления свертки в Numpy / Scipy

Профилирование некоторых вычислительных работ, которые я выполняю, показало мне, что одним узким местом в моей программе была функция, которая в основном это делала ( np is numpy , sp is scipy ):

def mix1(signal1, signal2):
    spec1 = np.fft.fft(signal1, axis=1)
    spec2 = np.fft.fft(signal2, axis=1)
    return np.fft.ifft(spec1*spec2, axis=1)

Оба сигнала имеют форму (C, N) , где C - количество наборов данных (обычно менее 20), а N - количество выборок в каждом наборе (около 5000). Вычисления для каждого набора (строки) полностью независимы от любого другого набора.

Я решил, что это была простая свертка, поэтому я попытался заменить его на:

def mix2(signal1, signal2):
    outputs = np.empty_like(signal1)

    for idx, row in enumerate(outputs):
        outputs[idx] = sp.signal.convolve(signal1[idx], signal2[idx], mode='same')

    return outputs

... просто чтобы посмотреть, получил ли я те же результаты. Но я этого не сделал, и мои вопросы:

  1. Почему бы и нет?
  2. Есть ли лучший способ вычислить эквивалент mix1 () ?

(Я понимаю, что mix2 , вероятно, не был бы быстрее как есть, но это могло бы стать хорошей отправной точкой для распараллеливания.)

Вот полный сценарий, который я использовал для быстрой проверки:

import numpy as np
import scipy as sp
import scipy.signal

N = 4680
C = 6

def mix1(signal1, signal2):
    spec1 = np.fft.fft(signal1, axis=1)
    spec2 = np.fft.fft(signal2, axis=1)
    return np.fft.ifft(spec1*spec2, axis=1)

def mix2(signal1, signal2):
    outputs = np.empty_like(signal1)

    for idx, row in enumerate(outputs):
        outputs[idx] = sp.signal.convolve(signal1[idx], signal2[idx], mode='same')

    return outputs

def test(num, chans):
    sig1 = np.random.randn(chans, num)
    sig2 = np.random.randn(chans, num)
    res1 = mix1(sig1, sig2)
    res2 = mix2(sig1, sig2)

    np.testing.assert_almost_equal(res1, res2)

if __name__ == "__main__":
    np.random.seed(0x1234ABCD)
    test(N, C)
16
задан detly 28 July 2011 в 07:00
поделиться