CuPy: NumPy & SciPy for GPU - CUDA 11.x optimized distribution providing GPU-accelerated computing with Python
—
CuPy provides comprehensive Fast Fourier Transform operations for GPU-accelerated computation, offering NumPy-compatible FFT functionality supporting 1D, 2D, and N-D transforms with both forward and inverse operations optimized for CUDA and ROCm platforms.
Standard discrete Fourier transform functions for complex-to-complex transforms in 1D, 2D, and N-D.
def fft(a, n=None, axis=-1, norm=None):
"""
Compute the one-dimensional discrete Fourier Transform.
Parameters:
a: array_like - Input array, can be complex
n: int, optional - Length of the transformed axis of the output
axis: int, optional - Axis over which to compute the FFT (default is -1)
norm: {None, 'ortho'}, optional - Normalization mode
"""
def ifft(a, n=None, axis=-1, norm=None):
"""
Compute the one-dimensional inverse discrete Fourier Transform.
Parameters:
a: array_like - Input array, can be complex
n: int, optional - Length of the transformed axis of the output
axis: int, optional - Axis over which to compute the FFT (default is -1)
norm: {None, 'ortho'}, optional - Normalization mode
"""
def fft2(a, s=None, axes=(-2, -1), norm=None):
"""
Compute the 2-dimensional discrete Fourier Transform.
Parameters:
a: array_like - Input array, can be complex
s: sequence of ints, optional - Shape (length of each transformed axis) of the output
axes: sequence of ints, optional - Axes over which to compute the FFT (default is (-2, -1))
norm: {None, 'ortho'}, optional - Normalization mode
"""
def ifft2(a, s=None, axes=(-2, -1), norm=None):
"""
Compute the 2-dimensional inverse discrete Fourier Transform.
Parameters:
a: array_like - Input array, can be complex
s: sequence of ints, optional - Shape (length of each transformed axis) of the output
axes: sequence of ints, optional - Axes over which to compute the FFT (default is (-2, -1))
norm: {None, 'ortho'}, optional - Normalization mode
"""
def fftn(a, s=None, axes=None, norm=None):
"""
Compute the N-dimensional discrete Fourier Transform.
Parameters:
a: array_like - Input array, can be complex
s: sequence of ints, optional - Shape (length of each transformed axis) of the output
axes: sequence of ints, optional - Axes over which to compute the FFT
norm: {None, 'ortho'}, optional - Normalization mode
"""
def ifftn(a, s=None, axes=None, norm=None):
"""
Compute the N-dimensional inverse discrete Fourier Transform.
Parameters:
a: array_like - Input array, can be complex
s: sequence of ints, optional - Shape (length of each transformed axis) of the output
axes: sequence of ints, optional - Axes over which to compute the FFT
norm: {None, 'ortho'}, optional - Normalization mode
"""Optimized FFT functions for real-valued input data, taking advantage of conjugate symmetry to improve performance and memory usage.
def rfft(a, n=None, axis=-1, norm=None):
"""
Compute the one-dimensional discrete Fourier Transform for real input.
Parameters:
a: array_like - Input array
n: int, optional - Number of points along transformation axis in the input to use
axis: int, optional - Axis over which to compute the FFT (default is -1)
norm: {None, 'ortho'}, optional - Normalization mode
"""
def irfft(a, n=None, axis=-1, norm=None):
"""
Computes the inverse of rfft.
Parameters:
a: array_like - Input array
n: int, optional - Length of the transformed axis of the output
axis: int, optional - Axis over which to compute the FFT (default is -1)
norm: {None, 'ortho'}, optional - Normalization mode
"""
def rfft2(a, s=None, axes=(-2, -1), norm=None):
"""
Compute the 2-dimensional FFT of a real array.
Parameters:
a: array - Input array, taken to be real
s: sequence of ints, optional - Shape of the FFT
axes: sequence of ints, optional - Axes over which to compute the FFT (default is (-2, -1))
norm: {None, 'ortho'}, optional - Normalization mode
"""
def irfft2(a, s=None, axes=(-2, -1), norm=None):
"""
Computes the inverse of rfft2.
Parameters:
a: array_like - Input array
s: sequence of ints, optional - Shape of the real output
axes: sequence of ints, optional - Axes over which to compute the FFT (default is (-2, -1))
norm: {None, 'ortho'}, optional - Normalization mode
"""
def rfftn(a, s=None, axes=None, norm=None):
"""
Compute the N-dimensional discrete Fourier Transform for real input.
Parameters:
a: array_like - Input array, taken to be real
s: sequence of ints, optional - Shape (length of each transformed axis) of the output
axes: sequence of ints, optional - Axes over which to compute the FFT
norm: {None, 'ortho'}, optional - Normalization mode
"""
def irfftn(a, s=None, axes=None, norm=None):
"""
Computes the inverse of rfftn.
Parameters:
a: array_like - Input array
s: sequence of ints, optional - Shape (length of each axis) of the output
axes: sequence of ints, optional - Axes over which to compute the inverse FFT
norm: {None, 'ortho'}, optional - Normalization mode
"""FFT functions for Hermitian-symmetric data, which is real-valued in the frequency domain.
def hfft(a, n=None, axis=-1, norm=None):
"""
Compute the FFT of a signal that has Hermitian symmetry, i.e., a real spectrum.
Parameters:
a: array_like - Input array
n: int, optional - Number of points along transformation axis in the input to use
axis: int, optional - Axis over which to compute the FFT (default is -1)
norm: {None, 'ortho'}, optional - Normalization mode
"""
def ihfft(a, n=None, axis=-1, norm=None):
"""
Compute the inverse FFT of a signal that has Hermitian symmetry.
Parameters:
a: array_like - Input array
n: int, optional - Length of the inverse transform
axis: int, optional - Axis over which to compute the FFT (default is -1)
norm: {None, 'ortho'}, optional - Normalization mode
"""Utility functions for working with FFT operations including frequency calculations and shifting.
def fftfreq(n, d=1.0):
"""
Return the Discrete Fourier Transform sample frequencies.
Parameters:
n: int - Window length
d: scalar, optional - Sample spacing (inverse of the sampling rate, default is 1.0)
"""
def rfftfreq(n, d=1.0):
"""
Return the Discrete Fourier Transform sample frequencies for rfft.
Parameters:
n: int - Window length
d: scalar, optional - Sample spacing (inverse of the sampling rate, default is 1.0)
"""
def fftshift(x, axes=None):
"""
Shift the zero-frequency component to the center of the spectrum.
Parameters:
x: array_like - Input array
axes: int or shape tuple, optional - Axes over which to shift
"""
def ifftshift(x, axes=None):
"""
The inverse of fftshift. Although identical for even-length x, the functions differ by one sample for odd-length x.
Parameters:
x: array_like - Input array
axes: int or shape tuple, optional - Axes over which to shift
"""FFT configuration module for performance tuning and backend selection.
# Configuration module for FFT performance tuning
config = cupy.fft.configimport cupy as cp
import cupy.fft as fft
import matplotlib.pyplot as plt
# 1D FFT example
# Generate a signal with two frequency components
fs = 1000 # Sample rate
t = cp.linspace(0, 1, fs, endpoint=False)
signal = cp.sin(2 * cp.pi * 50 * t) + 0.5 * cp.sin(2 * cp.pi * 120 * t)
# Compute FFT
signal_fft = fft.fft(signal)
freqs = fft.fftfreq(len(signal), 1/fs)
# Get magnitude spectrum
magnitude = cp.abs(signal_fft)
# 2D FFT example - Image processing
# Create a 2D signal (e.g., an image with periodic patterns)
x = cp.linspace(-5, 5, 256)
y = cp.linspace(-5, 5, 256)
X, Y = cp.meshgrid(x, y)
image = cp.sin(X) * cp.cos(Y) + 0.5 * cp.sin(2*X + Y)
# Compute 2D FFT
image_fft = fft.fft2(image)
image_fft_shifted = fft.fftshift(image_fft)
# Get magnitude spectrum
magnitude_2d = cp.abs(image_fft_shifted)
# Real FFT for real-valued signals (more efficient)
real_signal = cp.cos(2 * cp.pi * 10 * t) + cp.sin(2 * cp.pi * 25 * t)
real_fft = fft.rfft(real_signal)
real_freqs = fft.rfftfreq(len(real_signal), 1/fs)
# Inverse FFT
reconstructed_signal = fft.ifft(signal_fft)
reconstructed_real = fft.irfft(real_fft)
# N-dimensional FFT for 3D data
volume = cp.random.rand(64, 64, 64)
volume_fft = fft.fftn(volume)
volume_reconstructed = fft.ifftn(volume_fft)
# FFT-based convolution
def fft_convolve(signal1, signal2):
# Zero-pad to avoid circular convolution
n = len(signal1) + len(signal2) - 1
signal1_padded = cp.zeros(n)
signal2_padded = cp.zeros(n)
signal1_padded[:len(signal1)] = signal1
signal2_padded[:len(signal2)] = signal2
# Convolution via FFT
result = fft.ifft(fft.fft(signal1_padded) * fft.fft(signal2_padded))
return result[:n].real
# Apply FFT-based filter
def lowpass_filter(signal, cutoff_freq, sample_rate):
signal_fft = fft.fft(signal)
freqs = fft.fftfreq(len(signal), 1/sample_rate)
# Create filter mask
mask = cp.abs(freqs) <= cutoff_freq
# Apply filter
filtered_fft = signal_fft * mask
filtered_signal = fft.ifft(filtered_fft)
return filtered_signal.real
# Example usage of filter
filtered = lowpass_filter(signal, 80, fs)
# Spectral analysis
def compute_power_spectrum(signal, sample_rate):
signal_fft = fft.fft(signal)
freqs = fft.fftfreq(len(signal), 1/sample_rate)
power_spectrum = cp.abs(signal_fft)**2
return freqs[:len(freqs)//2], power_spectrum[:len(power_spectrum)//2]
freqs_pos, power = compute_power_spectrum(signal, fs)
# Windowing before FFT to reduce spectral leakage
def apply_window(signal, window_type='hann'):
if window_type == 'hann':
window = cp.hanning(len(signal))
elif window_type == 'hamming':
window = cp.hamming(len(signal))
elif window_type == 'blackman':
window = cp.blackman(len(signal))
else:
window = cp.ones(len(signal))
return signal * window
windowed_signal = apply_window(signal, 'hann')
windowed_fft = fft.fft(windowed_signal)# Use real FFT when input is real-valued
real_data = cp.random.rand(10000)
real_fft = fft.rfft(real_data) # More memory efficient than fft(real_data)
# In-place operations when possible
data = cp.random.rand(1000) + 1j * cp.random.rand(1000)
fft.fft(data, overwrite_x=True) # Note: overwrite_x not always available, check cuFFT backend# FFT is most efficient for sizes that are powers of 2
optimal_size = 2**int(cp.log2(len(signal)) + 1) # Next power of 2
padded_signal = cp.pad(signal, (0, optimal_size - len(signal)), 'constant')
efficient_fft = fft.fft(padded_signal)# Process multiple signals simultaneously
batch_signals = cp.random.rand(100, 1024) # 100 signals of length 1024
batch_fft = fft.fft(batch_signals, axis=1) # FFT along each signalFast Fourier Transform operations in CuPy provide high-performance frequency domain analysis capabilities optimized for GPU acceleration, enabling efficient signal processing, image analysis, and scientific computing with familiar NumPy interfaces while leveraging the parallel processing power of modern GPUs.
Install with Tessl CLI
npx tessl i tessl/pypi-cupy-cuda11x