Comparatively slow python numpy 3D Fourier Transformation

前端 未结 2 1956
执笔经年
执笔经年 2021-01-19 23:07

For my work I need to perform discrete fourier transformations (DFTs) on large images. In the current example I require a 3D FT for a 1921 x 512 x 512 image (along with 2D F

2条回答
  •  伪装坚强ぢ
    2021-01-19 23:45

    Yes, there is a chance that using FFTW through the interface pyfftw will reduce your computation time compared to numpy.fft or scipy.fftpack. The performances of these implementations of DFT algorithms can be compared in benchmarks such as this one : some interesting results are reported in Improving FFT performance in Python

    I suggest the following code for a test:

    import pyfftw
    import numpy
    import time
    import scipy
    
    f = pyfftw.n_byte_align_empty((127,512,512),16, dtype='complex128')
    #f = pyfftw.empty_aligned((33,128,128), dtype='complex128', n=16)
    f[:] = numpy.random.randn(*f.shape)
    
    # first call requires more time for plan creation
    # by default, pyfftw use FFTW_MEASURE for the plan creation, which means that many 3D dft are computed so as to choose the fastest algorithm.
    fftf=pyfftw.interfaces.numpy_fft.fftn(f)
    
    #help(pyfftw.interfaces)
    tas = time.time()
    fftf=pyfftw.interfaces.numpy_fft.fftn(f) # here the plan is applied, nothing else.
    tas = time.time()-tas
    print "3D FFT, pyfftw:", tas
    
    f = pyfftw.n_byte_align_empty((127,512,512),16, dtype='complex128')
    #f = pyfftw.empty_aligned((33,128,128), dtype='complex128', n=16)
    f[:] = numpy.random.randn(*f.shape)
    
    
    tas = time.time()
    fftf=numpy.fft.fftn(f)
    tas = time.time()-tas
    print "3D FFT, numpy:", tas
    
    tas = time.time()
    fftf=scipy.fftpack.fftn(f)
    tas = time.time()-tas
    print "3D FFT, scipy/fftpack:", tas
    
    # first call requires more time for plan creation
    # by default, pyfftw use FFTW_MEASURE for the plan creation, which means that many 3D dft are computed so as to choose the fastest algorithm.
    f = pyfftw.n_byte_align_empty((128,512,512),16, dtype='complex128')
    fftf=pyfftw.interfaces.numpy_fft.fftn(f)
    
    tas = time.time()
    fftf=pyfftw.interfaces.numpy_fft.fftn(f) # here the plan is applied, nothing else.
    tas = time.time()-tas
    print "3D padded FFT, pyfftw:", tas
    

    For a size of 127*512*512, on my modest computer, I got:

    3D FFT, pyfftw: 3.94130897522
    3D FFT, numpy: 16.0487070084
    3D FFT, scipy/fftpack: 19.001199007
    3D padded FFT, pyfftw: 2.55221295357
    

    So pyfftw is significantly faster than numpy.fft and scipy.fftpack. Using padding is even faster, but the thing that is computed is different.

    Lastly, pyfftw may seem slower at the first run due to the fact that it uses the flag FFTW_MEASURE according to the documentation. It's a good thing if and only if many DFTs of the same size are successively computed.

提交回复
热议问题