CuPy: NumPy & SciPy for GPU - A NumPy/SciPy-compatible array library for GPU-accelerated computing with Python, specifically built for CUDA 11.1
—
GPU-accelerated Fast Fourier Transform operations using cuFFT for high-performance frequency domain analysis. CuPy provides comprehensive FFT functionality for real and complex transforms in 1D, 2D, and N-dimensional cases with significant performance improvements over CPU implementations.
Standard complex FFT operations for frequency domain analysis of 1D signals.
def fft(a, n=None, axis=-1, norm=None):
"""
Compute 1D discrete Fourier Transform.
Parameters:
- a: array_like, input array
- n: int, optional, length of transformed axis
- axis: int, optional, axis over which to compute FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued transformed array
"""
def ifft(a, n=None, axis=-1, norm=None):
"""
Compute 1D inverse discrete Fourier Transform.
Parameters:
- a: array_like, input array
- n: int, optional, length of transformed axis
- axis: int, optional, axis over which to compute inverse FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued inverse transformed array
"""Optimized FFT operations for real-valued input data with reduced memory usage and improved performance.
def rfft(a, n=None, axis=-1, norm=None):
"""
Compute 1D FFT of real input.
Parameters:
- a: array_like, real-valued input array
- n: int, optional, length of transformed axis
- axis: int, optional, axis over which to compute FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued FFT, only positive frequency components
Notes:
- Output length is n//2 + 1 for real transforms
- Exploits Hermitian symmetry for efficiency
"""
def irfft(a, n=None, axis=-1, norm=None):
"""
Compute inverse of rfft.
Parameters:
- a: array_like, complex-valued input from rfft
- n: int, optional, length of output axis
- axis: int, optional, axis over which to compute inverse FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Real-valued inverse transformed array
"""Specialized transforms for Hermitian symmetric data.
def hfft(a, n=None, axis=-1, norm=None):
"""
Compute FFT of signal with Hermitian symmetry.
Parameters:
- a: array_like, complex input with Hermitian symmetry
- n: int, optional, length of transformed axis
- axis: int, optional, axis over which to compute FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Real-valued transformed array
"""
def ihfft(a, n=None, axis=-1, norm=None):
"""
Compute inverse of hfft.
Parameters:
- a: array_like, real-valued input
- n: int, optional, length of transformed axis
- axis: int, optional, axis over which to compute inverse FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued array with Hermitian symmetry
"""Multi-dimensional FFT operations for image processing and 2D signal analysis.
def fft2(a, s=None, axes=(-2, -1), norm=None):
"""
Compute 2D discrete Fourier Transform.
Parameters:
- a: array_like, input array
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued 2D transformed array
"""
def ifft2(a, s=None, axes=(-2, -1), norm=None):
"""
Compute 2D inverse discrete Fourier Transform.
Parameters:
- a: array_like, input array
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute inverse FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued 2D inverse transformed array
"""
def rfft2(a, s=None, axes=(-2, -1), norm=None):
"""
Compute 2D FFT of real input.
Parameters:
- a: array_like, real-valued input array
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued 2D FFT with reduced last dimension
"""
def irfft2(a, s=None, axes=(-2, -1), norm=None):
"""
Compute inverse of rfft2.
Parameters:
- a: array_like, complex-valued input from rfft2
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute inverse FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Real-valued 2D inverse transformed array
"""General N-dimensional FFT operations for multi-dimensional data analysis.
def fftn(a, s=None, axes=None, norm=None):
"""
Compute N-dimensional discrete Fourier Transform.
Parameters:
- a: array_like, input array
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued N-D transformed array
"""
def ifftn(a, s=None, axes=None, norm=None):
"""
Compute N-dimensional inverse discrete Fourier Transform.
Parameters:
- a: array_like, input array
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute inverse FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued N-D inverse transformed array
"""
def rfftn(a, s=None, axes=None, norm=None):
"""
Compute N-dimensional FFT of real input.
Parameters:
- a: array_like, real-valued input array
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Complex-valued N-D FFT with reduced last transformed dimension
"""
def irfftn(a, s=None, axes=None, norm=None):
"""
Compute inverse of rfftn.
Parameters:
- a: array_like, complex-valued input from rfftn
- s: sequence of ints, optional, shape of result
- axes: sequence of ints, optional, axes over which to compute inverse FFT
- norm: {None, 'ortho'}, normalization mode
Returns:
- ndarray: Real-valued N-D inverse transformed array
"""Utility functions for frequency analysis and FFT result manipulation.
def fftfreq(n, d=1.0):
"""
Return discrete Fourier Transform sample frequencies.
Parameters:
- n: int, window length
- d: scalar, optional, sample spacing (default: 1.0)
Returns:
- ndarray: Array of length n containing sample frequencies
Notes:
- Frequencies are in cycles per unit of sample spacing
- For even n: [..., -2, -1, 0, 1, 2, ...]
- For odd n: [..., -1, 0, 1, ...]
"""
def rfftfreq(n, d=1.0):
"""
Return sample frequencies for real FFT.
Parameters:
- n: int, window length
- d: scalar, optional, sample spacing (default: 1.0)
Returns:
- ndarray: Array of length n//2 + 1 containing positive sample frequencies
Notes:
- Only returns positive frequency components
- Length is n//2 + 1 to match rfft output
"""
def fftshift(x, axes=None):
"""
Shift zero-frequency component to center of spectrum.
Parameters:
- x: array_like, input array
- axes: int or shape tuple, optional, axes over which to shift
Returns:
- ndarray: Shifted array with zero-frequency at center
Notes:
- Swaps left and right halves of array
- Useful for visualization of FFT results
"""
def ifftshift(x, axes=None):
"""
Inverse of fftshift.
Parameters:
- x: array_like, input array
- axes: int or shape tuple, optional, axes over which to shift
Returns:
- ndarray: Array shifted back to original ordering
Notes:
- Undoes the effect of fftshift
- Prepares centered spectrum for FFT processing
"""Advanced configuration options for optimal performance tuning.
# Configuration module for FFT planning and optimization
import cupy.fft.config
# Example configuration usage:
with cupy.fft.config.set_plan_cache_size(1024):
# FFT operations use larger plan cache
result = cupy.fft.fft2(large_array)
# Plan caching for repeated operations
plan = cupy.fft.config.get_current_plan()
# Reuse plan for multiple similar operationsimport cupy as cp
import cupy.fft
import numpy as np
# Generate sample signal
t = cp.linspace(0, 1, 1000, endpoint=False)
signal = cp.sin(2 * cp.pi * 50 * t) + 0.5 * cp.sin(2 * cp.pi * 120 * t)
signal += 0.1 * cp.random.randn(1000) # Add noise
# Compute FFT
fft_result = cupy.fft.fft(signal)
frequencies = cupy.fft.fftfreq(len(signal), d=1/1000)
# Filter low frequencies
fft_result[cp.abs(frequencies) > 100] = 0
# Inverse transform
filtered_signal = cupy.fft.ifft(fft_result).realimport cupy as cp
import cupy.fft
# Load or create 2D image data
image = cp.random.random((512, 512))
# Compute 2D FFT
fft_image = cupy.fft.fft2(image)
# Shift for visualization
fft_shifted = cupy.fft.fftshift(fft_image)
# Apply frequency domain filter (low-pass)
rows, cols = image.shape
crow, ccol = rows // 2, cols // 2
mask = cp.zeros((rows, cols), dtype=bool)
r = 50 # Radius for low-pass filter
y, x = cp.ogrid[:rows, :cols]
mask_area = (x - ccol) ** 2 + (y - crow) ** 2 <= r ** 2
mask[mask_area] = True
# Apply mask and inverse transform
fft_shifted[~mask] = 0
fft_filtered = cupy.fft.ifftshift(fft_shifted)
filtered_image = cupy.fft.ifft2(fft_filtered).realimport cupy as cp
import cupy.fft
# For real-valued data, use rfft for better performance
real_signal = cp.random.randn(10000)
# Real FFT (more efficient for real input)
rfft_result = cupy.fft.rfft(real_signal)
print(f"Real FFT shape: {rfft_result.shape}") # Length is n//2 + 1
# Corresponding frequencies
rfreqs = cupy.fft.rfftfreq(len(real_signal))
# Process in frequency domain
# ... frequency domain operations ...
# Inverse transform back to real signal
reconstructed = cupy.fft.irfft(rfft_result)import cupy as cp
import cupy.fft
# Process multiple signals simultaneously
batch_signals = cp.random.randn(100, 1024) # 100 signals, 1024 samples each
# FFT along last axis (axis=-1 is default)
batch_fft = cupy.fft.fft(batch_signals, axis=-1)
# Or process along first axis
batch_fft_axis0 = cupy.fft.fft(batch_signals, axis=0)
# 3D batch processing
volume_data = cp.random.randn(32, 64, 64)
volume_fft = cupy.fft.fftn(volume_data) # N-D FFTimport cupy as cp
import cupy.fft
# For repeated operations on same size data,
# CuPy automatically caches FFT plans for better performance
# Warm up with first operation
data_size = (1024, 1024)
test_data = cp.random.randn(*data_size)
_ = cupy.fft.fft2(test_data) # Plan gets cached
# Subsequent operations reuse the cached plan
for i in range(100):
new_data = cp.random.randn(*data_size)
result = cupy.fft.fft2(new_data) # Uses cached plan - faster!
# Configure plan cache size for memory management
with cupy.fft.config.set_plan_cache_size(512):
# Operations within this block use larger plan cache
large_fft = cupy.fft.fft2(cp.random.randn(2048, 2048))Install with Tessl CLI
npx tessl i tessl/pypi-cupy-cuda111