Pregunta

¿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 distribuida (MPI)?

¿Fue útil?

Solución

Ciertamente, podría empaquetar cualquier implementación de FFT que quisiera probar usando Cython u otras herramientas similares que le permitan acceder a bibliotecas externas.

Basado en GPU

Si va a probar implementaciones de FFT, también puede echar un vistazo a los códigos basados ​​en GPU (si tiene acceso al hardware adecuado).Hay varios: reikna.fft, scikits.cuda.

basado en CPU

También hay un contenedor FFTW de Python basado en CPU pyFFTW.

(Hay pyFFTW3 también, pero no se mantiene tan activamente como pyFFTW y no funciona con Python3.(fuente))

No tengo experiencia con ninguno de estos.Probablemente le corresponderá a usted investigar un poco y comparar diferentes códigos para su aplicación particular si la velocidad es importante para usted.

Otros consejos

Para una prueba detallada en https://gist.github.com/fnielsen/99b981b9da34ae3d5035 Encuentro que scipy.fftpack funciona bien en comparación con mi simple aplicación de pyfftw a través de pyfftw.interfaces.scipy_fftpack, excepto los datos con una longitud correspondiente a un número primo.

Parece haber algún costo de configuración asociado con evocar pyfftw.interfaces.scipy_fftpack.fft la primera vez. La segunda vez es más rápida. El fftpack de Numpy y Scipy con un número primo funciona terriblemente para el tamaño de los datos que probé. CZT es más rápido en ese caso. Hace unos meses se presentó un problema en Github de Scipy sobre el problema, ver 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
------------------------------------------------------------

El paquete PYFFTW3 es inferior en comparación con la biblioteca PYFFTW, al menos en cuanto a la implementación. Dado que ambos envuelven la biblioteca FFTW3, supongo que la velocidad debería ser la misma.

https://pypi.python.org/pypi/pyfftw

Donde trabajo, algunos investigadores han compilado esta biblioteca Fortran que configura y llama al FFTW para un problema particular. Esta biblioteca Fortran (módulo con algunas subrutinas) espera algunos datos de entrada (listas 2D) de mi programa Python.

Lo que hice fue crear un poco de 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 (matrices) y una función de "cómputo".

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.

los Sitio FFTW Muestra FFTPack que se ejecuta aproximadamente 1/3 tan rápido como FFTW, pero eso es con un paso 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 fundamental para usted, puede considerar compilar FFTW en una biblioteca DLL/compartida y usar CTYPES para acceder a él, o construir una extensión C personalizada.

FFTW3 parece ser la implementación más rápida disponible que está bien envuelta. Los enlaces PyffTW en el primer trabajo de respuesta. Aquí hay algún código que compara los tiempos de ejecución: test_ffts.py

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top