gpt4 book ai didi

python - PyFFTW 比 SciPy FFT 慢?

转载 作者:太空宇宙 更新时间:2023-11-03 17:40:43 25 4
gpt4 key购买 nike

我尝试了用户 henry-gomersall 在 Stackoverflow 上提出的解决方案来重复加速基于 FFT 的卷积,但获得了不同的结果。

import numpy as np
import pyfftw
import scipy.signal
import timeit

class CustomFFTConvolution(object):

def __init__(self, A, B, threads=1):

shape = (np.array(A.shape) + np.array(B.shape))-1

if np.iscomplexobj(A) and np.iscomplexobj(B):
self.fft_A_obj = pyfftw.builders.fftn(
A, s=shape, threads=threads)
self.fft_B_obj = pyfftw.builders.fftn(
B, s=shape, threads=threads)
self.ifft_obj = pyfftw.builders.ifftn(
self.fft_A_obj.get_output_array(), s=shape,
threads=threads)

else:
self.fft_A_obj = pyfftw.builders.rfftn(
A, s=shape, threads=threads)
self.fft_B_obj = pyfftw.builders.rfftn(
B, s=shape, threads=threads)
self.ifft_obj = pyfftw.builders.irfftn(
self.fft_A_obj.get_output_array(), s=shape,
threads=threads)

def __call__(self, A, B):

fft_padded_A = self.fft_A_obj(A)
fft_padded_B = self.fft_B_obj(B)

return self.ifft_obj(fft_padded_A * fft_padded_B)

N = 200

A = np.random.rand(N, N, N)
B = np.random.rand(N, N, N)

start_time = timeit.default_timer()

C = scipy.signal.fftconvolve(A,B,"same")
print timeit.default_timer() - start_time

custom_fft_conv_nthreads = CustomFFTConvolution(A, B, threads=1)
C = custom_fft_conv_nthreads(A, B)
print timeit.default_timer() - start_time

PyFFTW 约为。比 SciPy FFT 慢 7 倍,这与其他用户体验不同。这段代码有什么问题? Python 2.7.9、PyFFTW 0.9.2。

最佳答案

你没有做你认为你正在做的事情,你认为你正在做的事情你也不应该做。

您没有做您认为正在做的事情,因为上面的代码只定义了 start_time 一次(因此您对 pyfftw 的测试不仅包括耗时的创建 CustomFFTConvolution 对象,还有 scipy 卷积!)。

您不应该做您认为正在做的事情,因为您应该使用 timeit 来测试此类事情。

所以,对于一些文件 foo.py:

import numpy as np
import pyfftw
import scipy.signal

class CustomFFTConvolution(object):

def __init__(self, A, B, threads=1):

shape = (np.array(A.shape) + np.array(B.shape))-1

if np.iscomplexobj(A) and np.iscomplexobj(B):
self.fft_A_obj = pyfftw.builders.fftn(
A, s=shape, threads=threads)
self.fft_B_obj = pyfftw.builders.fftn(
B, s=shape, threads=threads)
self.ifft_obj = pyfftw.builders.ifftn(
self.fft_A_obj.get_output_array(), s=shape,
threads=threads)

else:
self.fft_A_obj = pyfftw.builders.rfftn(
A, s=shape, threads=threads)
self.fft_B_obj = pyfftw.builders.rfftn(
B, s=shape, threads=threads)
self.ifft_obj = pyfftw.builders.irfftn(
self.fft_A_obj.get_output_array(), s=shape,
threads=threads)

def __call__(self, A, B):

fft_padded_A = self.fft_A_obj(A)
fft_padded_B = self.fft_B_obj(B)

return self.ifft_obj(fft_padded_A * fft_padded_B)

N = 200

A = np.random.rand(N, N, N)
B = np.random.rand(N, N, N)

在ipython中,可以得到以下内容:

In [1]: %run foo.py

In [2]: timeit scipy.signal.fftconvolve(A,B,"same")
1 loops, best of 3: 8.38 s per loop

In [3]: custom_fft_conv_nthreads = CustomFFTConvolution(A, B, threads=1)

In [4]: timeit custom_fft_conv_nthreads(A, B)
1 loops, best of 3: 6.9 s per loop

并且具有多个线程:

In [5]: custom_fft_conv_nthreads = CustomFFTConvolution(A, B, threads=4)

In [6]: timeit custom_fft_conv_nthreads(A, B)
1 loops, best of 3: 3.81 s per loop

如果您通过在 C = custom_fft_conv_nthreads(A, B) 之前插入 start_time = timeit.default_timer() 来更正代码以执行您认为正在执行的操作,您将得到更接近预期的东西:

10.8795630932
8.31241607666

关于python - PyFFTW 比 SciPy FFT 慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30595949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com