需要 Python 中的循环 FFT 卷积
Need a circular FFT convolution in Python
我需要一个更快的模拟
scipy.signal.convolve2d(data, filter, boundary="wrap", mode="same")
你能告诉我如何更换它吗?
P.S。 scipy.signal.fftconvolve
足够快,但它没有 boundary
选项,我无法使其在循环卷积模式下工作。
如果您计算以下内容:
from scipy.fftpack import fft2, ifft2
f2 = ifft2(fft2(data, shape=data.shape) * fft2(filter, shape=data.shape)).real
然后 f2
包含与 convolve2d(data, filt, boundary='wrap', mode='same')
相同的值,但值在每个轴上移动("rolled",在 numpy 术语中)。 (这是convolution theorem的一个应用。)
这是一个简短的函数,它将结果滚动到给出与 convolve2d
函数调用相同的结果:
def fftconvolve2d(x, y):
# This assumes y is "smaller" than x.
f2 = ifft2(fft2(x, shape=x.shape) * fft2(y, shape=x.shape)).real
f2 = np.roll(f2, (-((y.shape[0] - 1)//2), -((y.shape[1] - 1)//2)), axis=(0, 1))
return f2
例如,
In [91]: data = np.random.rand(256, 256)
In [92]: filt = np.random.rand(16, 16)
In [93]: c2d = convolve2d(data, filt, boundary='wrap', mode='same')
In [94]: f2 = fftconvolve2d(data, filt)
验证结果是否相同:
In [95]: np.allclose(c2d, f2)
Out[95]: True
查看性能:
In [96]: %timeit c2d = convolve2d(data, filt, boundary='wrap', mode='same')
44.9 ms ± 77.3 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [97]: %timeit f2 = fftconvolve2d(data, filt)
5.23 ms ± 11.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
FFT 版本快很多(但请注意,我选择 data
的维度是 2 的幂)。
我需要一个更快的模拟
scipy.signal.convolve2d(data, filter, boundary="wrap", mode="same")
你能告诉我如何更换它吗?
P.S。 scipy.signal.fftconvolve
足够快,但它没有 boundary
选项,我无法使其在循环卷积模式下工作。
如果您计算以下内容:
from scipy.fftpack import fft2, ifft2
f2 = ifft2(fft2(data, shape=data.shape) * fft2(filter, shape=data.shape)).real
然后 f2
包含与 convolve2d(data, filt, boundary='wrap', mode='same')
相同的值,但值在每个轴上移动("rolled",在 numpy 术语中)。 (这是convolution theorem的一个应用。)
这是一个简短的函数,它将结果滚动到给出与 convolve2d
函数调用相同的结果:
def fftconvolve2d(x, y):
# This assumes y is "smaller" than x.
f2 = ifft2(fft2(x, shape=x.shape) * fft2(y, shape=x.shape)).real
f2 = np.roll(f2, (-((y.shape[0] - 1)//2), -((y.shape[1] - 1)//2)), axis=(0, 1))
return f2
例如,
In [91]: data = np.random.rand(256, 256)
In [92]: filt = np.random.rand(16, 16)
In [93]: c2d = convolve2d(data, filt, boundary='wrap', mode='same')
In [94]: f2 = fftconvolve2d(data, filt)
验证结果是否相同:
In [95]: np.allclose(c2d, f2)
Out[95]: True
查看性能:
In [96]: %timeit c2d = convolve2d(data, filt, boundary='wrap', mode='same')
44.9 ms ± 77.3 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [97]: %timeit f2 = fftconvolve2d(data, filt)
5.23 ms ± 11.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
FFT 版本快很多(但请注意,我选择 data
的维度是 2 的幂)。