Numpy/Sply中如何实现卷积计算?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (232)

通过分析我正在做的一些计算工作,我发现程序中的一个瓶颈是一个函数,它基本上就是这样做的(npnumpyspscipy)):

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)

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

下面是我用来快速检查的完整脚本:

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)
提问于
用户回答回答于

1)numpy.convolve不是循环的,这就是FFT代码给您的结果:

2)FFT的内部功率为2。比较以下操作的不同速度:

x1 = np.random.uniform(size=2**17-1)
x2 = np.random.uniform(size=2**17)

np.fft.fft(x1)
np.fft.fft(x2)

3)归一化不是区别--如果你用a(K)来做一个朴素的圆形卷积。*B(i-k),你将得到FFT代码的结果。

用户回答回答于

fftconvolve通过FFT进行卷积,它是python代码。需要是使用Mix 1函数。

扫码关注云+社区