pyFFTW
pyFFTW is a high-performance Pythonic wrapper around FFTW 3, the highly optimized Fast Fourier Transform C library. It provides a unified interface for various FFT operations, including interfaces compatible with NumPy's `fft` module, SciPy's `fft` module, and Dask's `fft` module. The current version is 0.15.1, with releases typically occurring a few times a year, including significant updates for Python and dependency compatibility.
Common errors
-
ModuleNotFoundError: No module named 'pyfftw'
cause The `pyfftw` Python package has not been installed in the current environment.fixRun `pip install pyfftw` to install the package. -
PyFFTWError: The self-test of the installed FFTW library failed
cause The underlying FFTW C library is either not installed, not correctly linked, or a compatible version could not be found by `pyfftw`.fixEnsure FFTW3 (e.g., `libfftw3-dev` on Debian/Ubuntu, `fftw-devel` on Fedora, `fftw` on Homebrew) is correctly installed on your system and accessible in the system's library path. For Windows, refer to pyFFTW's installation documentation for pre-compiled binaries or build instructions. -
AttributeError: module 'pyfftw' has no attribute 'fft'
cause Attempting to use a top-level `fft` function directly from `pyfftw` without importing one of the specific interface modules (e.g., `numpy_fft`).fixImport the desired interface explicitly, for example: `import pyfftw.interfaces.numpy_fft as fft`. -
ValueError: Input array is not C-contiguous or Fortran-contiguous.
cause FFTW and `pyfftw` perform optimally with contiguous arrays. If you pass a sliced or non-contiguous NumPy array, it might raise this error or force a copy, reducing performance.fixEnsure your input array is contiguous. Use `np.ascontiguousarray(my_array)` if necessary, or create the array directly using `pyfftw.empty_aligned`, `pyfftw.zeros`, or `pyfftw.ones` for maximum efficiency.
Warnings
- gotcha The `pyfftw` Python package is a wrapper around the FFTW 3 C library. You MUST have the FFTW 3 C library installed on your system for `pyfftw` to function. `pip install pyfftw` only installs the Python bindings, not the underlying C library.
- breaking Python 3.7 and 2.7 support has been dropped in recent versions. Specifically, Python 2.7 support ended with v0.11.x (last version to support it was v0.11.1), and Python 3.7 support ended with v0.13.0. Version 0.15.0 and later require Python >= 3.11.
- gotcha For optimal performance, especially with repeated transforms of the same size and type, configure `pyfftw.config.PLANNER_EFFORT` and use wisdom files. Setting `PLANNER_EFFORT = 'FFTW_MEASURE'` or `'FFTW_PATIENT'` allows FFTW to find a highly optimized plan (takes longer for the first run). Wisdom files (`pyfftw.export_wisdom()`/`pyfftw.import_wisdom()`) save these plans to disk, avoiding re-planning on subsequent executions.
- deprecated The `pyfftw.interfaces.scipy_fftpack` interface, which mirrored the older `scipy.fftpack` module, is deprecated. Users should migrate to `pyfftw.interfaces.scipy_fft` which aligns with the modern `scipy.fft` module (introduced in SciPy 1.4).
Install
-
pip install pyfftw
Imports
- FFTW
from pyfftw import FFTW
- interfaces.numpy_fft
import pyfftw; pyfftw.fft.fft(...)
import pyfftw.interfaces.numpy_fft as fft
- config
import pyfftw.config
- zeros
from pyfftw import zeros
Quickstart
import pyfftw
import numpy as np
import pyfftw.interfaces.numpy_fft as fft
import os
# Configure pyFFTW for optimal performance
pyfftw.config.NUM_THREADS = os.cpu_count() or 1 # Use all available CPU cores
pyfftw.config.PLANNER_EFFORT = 'FFTW_ESTIMATE' # 'FFTW_MEASURE' for better, but slower, planning
pyfftw.config.overwrite_input = True # Allow FFTW to overwrite input array for efficiency
# Create a sample NumPy array
input_data = np.random.randn(128) + 1j*np.random.randn(128)
# Perform FFT using the numpy_fft interface (drop-in replacement)
output_fft = fft.fft(input_data)
# Perform inverse FFT
output_ifft = fft.ifft(output_fft)
print(f"Original data (first 5): {input_data[:5]})")
print(f"FFT output (first 5): {output_fft[:5]})")
print(f"IFFT output (first 5): {output_ifft[:5]})")
print(f"Difference (should be close to zero): {np.max(np.abs(input_data - output_ifft))}")
# Example using the direct FFTW class for more control
# Pre-allocate arrays for in-place transform if desired
a = pyfftw.empty_aligned(128, dtype='complex128')
b = pyfftw.empty_aligned(128, dtype='complex128')
a[:] = input_data # Copy data to aligned array
fft_object = pyfftw.FFTW(a, b, direction='FFTW_FORWARD',
flags=('FFTW_MEASURE',), threads=pyfftw.config.NUM_THREADS,
planning_effort=pyfftw.config.PLANNER_EFFORT)
fft_object()
print(f"\nDirect FFTW class output (first 5): {b[:5]})")