fourier - Mejora del rendimiento de FFT en Python
np.fft python (6)
¿Cuál es la implementación FFT más rápida en Python?
Parece que numpy.fft y scipy.fftpack están basados en fftpack, y no en FFTW. ¿Es fftpack tan rápido como FFTW? ¿Qué pasa con el uso de FFT multiproceso, o el uso de FFT distribuido (MPI)?
Donde trabajo, algunos investigadores han compilado esta biblioteca de Fortran que configura y llama a la FFTW para un problema particular. Esta biblioteca de Fortran (módulo con algunas subrutinas) espera algunos datos de entrada (listas 2D) de mi programa Python.
Lo que hice fue crear una pequeña extensión C para Python envolviendo la biblioteca Fortran, donde básicamente llamo "init" para configurar un planificador FFTW, y otra función para alimentar mis listas 2D (arrays), y una función "compute".
Crear una C-extensiones es una tarea pequeña, y hay muchos buenos tutoriales para esa tarea en particular.
Lo bueno de este enfoque es que obtenemos velocidad ... mucha velocidad. El único inconveniente está en la extensión C, donde debemos iterar sobre la lista de Python y extraer todos los datos de Python en un búfer de memoria.
El sitio de FFTW muestra fftpack ejecutándose aproximadamente 1/3 tan rápido como FFTW, pero eso es un paso de Fortran-to-C traducido mecánicamente seguido de compilación de C, y no sé si numpy / scipy usa una compilación de Fortran más directa. Si el rendimiento es crítico para usted, podría considerar compilar FFTW en una biblioteca compartida / DLL y usar ctypes para acceder a él, o crear una extensión C personalizada.
El paquete pyFFTW3 es inferior en comparación con la biblioteca pyFFTW, al menos en cuanto a implementación. Dado que ambos envuelven la biblioteca FFTW3, creo que la velocidad debería ser la misma.
FFTW3 parece ser la implementación más rápida disponible que está bien envuelta. Los enlaces de PyFFTW en la primera respuesta funcionan. Aquí hay un código que compara los tiempos de ejecución: test_ffts.py
Sin duda, podría incluir la implementación de FFT que desea probar con Cython u otras herramientas afines que le permitan acceder a bibliotecas externas.
Basado en GPU
Si va a probar las implementaciones de FFT, también puede echar un vistazo a los códigos basados en GPU (si tiene acceso al hardware adecuado). Hay varias: reikna.fft , scikits.cuda .
Basado en la CPU
También hay un envoltorio de python FFTW pyFFTW basado en CPU.
(También hay pyFFTW3 , pero no se mantiene tan activamente como pyFFTW, y no funciona con Python3. ( source ))
No tengo experiencia con ninguno de estos. Probablemente le corresponderá investigar y comparar diferentes códigos para su aplicación en particular si la velocidad es importante para usted.
Para una prueba detallada en https://gist.github.com/fnielsen/99b981b9da34ae3d5035 encuentro que scipy.fftpack funciona bien en comparación con mi aplicación simple de pyfftw a través de pyfftw.interfaces.scipy_fftpack
, excepto por datos con una longitud correspondiente a un primo número.
Parece que hay un costo de instalación asociado con evocar pyfftw.interfaces.scipy_fftpack.fft la primera vez. La segunda vez es más rápido. El paquete de Fft de Numpy y Scipy con un número primo se desempeña terriblemente para el tamaño de los datos que probé. CZT es más rápido en ese caso. Hace algunos meses se presentó un problema en Github de Scipy sobre el problema, consulte https://github.com/scipy/scipy/issues/4288
20000 prime=False
padded_fft : 0.003116
numpy_fft : 0.003502
scipy_fft : 0.001538
czt : 0.035041
fftw_fft : 0.004007
------------------------------------------------------------
20011 prime=True
padded_fft : 0.001070
numpy_fft : 1.263672
scipy_fft : 0.875641
czt : 0.033139
fftw_fft : 0.009980
------------------------------------------------------------
21803 prime=True
padded_fft : 0.001076
numpy_fft : 1.510341
scipy_fft : 1.043572
czt : 0.035129
fftw_fft : 0.011463
------------------------------------------------------------
21804 prime=False
padded_fft : 0.001108
numpy_fft : 0.004672
scipy_fft : 0.001620
czt : 0.033854
fftw_fft : 0.005075
------------------------------------------------------------
21997 prime=True
padded_fft : 0.000940
numpy_fft : 1.534876
scipy_fft : 1.058001
czt : 0.034321
fftw_fft : 0.012839
------------------------------------------------------------
32768 prime=False
padded_fft : 0.001222
numpy_fft : 0.002410
scipy_fft : 0.000925
czt : 0.039275
fftw_fft : 0.005714
------------------------------------------------------------