or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-operations.mdcuda-integration.mdcupy-extensions.mdcustom-kernels.mdfft-operations.mdindex.mdlinear-algebra.mdmath-functions.mdrandom-generation.mdstatistical-functions.md

fft-operations.mddocs/

0

# FFT Operations

1

2

Fast Fourier Transform operations through cuFFT integration, providing GPU-accelerated 1D, 2D, and N-dimensional transforms for both real and complex data. These functions enable high-performance frequency domain analysis and signal processing on GPU.

3

4

## Capabilities

5

6

### One-Dimensional FFT

7

8

Standard FFT operations for 1D signals.

9

10

```python { .api }

11

def fft(a, n=None, axis=-1, norm=None):

12

"""Compute 1-D discrete Fourier Transform.

13

14

Parameters:

15

- a: array-like, input array

16

- n: int, length of transformed axis (zero-padded or truncated)

17

- axis: int, axis over which to compute FFT

18

- norm: str, normalization mode ('backward', 'ortho', 'forward')

19

20

Returns:

21

cupy.ndarray: complex-valued FFT result

22

"""

23

24

def ifft(a, n=None, axis=-1, norm=None):

25

"""Compute 1-D inverse discrete Fourier Transform.

26

27

Parameters:

28

- a: array-like, input array

29

- n: int, length of transformed axis

30

- axis: int, axis over which to compute inverse FFT

31

- norm: str, normalization mode

32

33

Returns:

34

cupy.ndarray: complex-valued inverse FFT result

35

"""

36

```

37

38

### Multi-Dimensional FFT

39

40

FFT operations for 2D and N-dimensional arrays.

41

42

```python { .api }

43

def fft2(a, s=None, axes=(-2, -1), norm=None):

44

"""Compute 2-D discrete Fourier Transform.

45

46

Parameters:

47

- a: array-like, input array

48

- s: sequence of ints, shape of result along transformed axes

49

- axes: sequence of ints, axes over which to compute FFT

50

- norm: str, normalization mode

51

52

Returns:

53

cupy.ndarray: complex-valued 2D FFT result

54

"""

55

56

def ifft2(a, s=None, axes=(-2, -1), norm=None):

57

"""Compute 2-D inverse discrete Fourier Transform."""

58

59

def fftn(a, s=None, axes=None, norm=None):

60

"""Compute N-D discrete Fourier Transform.

61

62

Parameters:

63

- a: array-like, input array

64

- s: sequence of ints, shape of result

65

- axes: sequence of ints, axes over which to compute FFT

66

- norm: str, normalization mode

67

68

Returns:

69

cupy.ndarray: N-dimensional FFT result

70

"""

71

72

def ifftn(a, s=None, axes=None, norm=None):

73

"""Compute N-D inverse discrete Fourier Transform."""

74

```

75

76

### Real FFT

77

78

Optimized FFT functions for real-valued input data.

79

80

```python { .api }

81

def rfft(a, n=None, axis=-1, norm=None):

82

"""Compute 1-D FFT of real input.

83

84

For real input, the negative frequency terms are redundant,

85

so only positive frequencies are returned.

86

87

Parameters:

88

- a: array-like, real-valued input array

89

- n: int, length of transformed axis

90

- axis: int, axis over which to compute FFT

91

- norm: str, normalization mode

92

93

Returns:

94

cupy.ndarray: complex result with shape[axis] = n//2 + 1

95

"""

96

97

def irfft(a, n=None, axis=-1, norm=None):

98

"""Compute inverse of rfft.

99

100

Parameters:

101

- a: array-like, complex input from rfft

102

- n: int, length of real output axis

103

- axis: int, axis over which to compute inverse FFT

104

- norm: str, normalization mode

105

106

Returns:

107

cupy.ndarray: real-valued result

108

"""

109

110

def rfft2(a, s=None, axes=(-2, -1), norm=None):

111

"""Compute 2-D FFT of real input."""

112

113

def irfft2(a, s=None, axes=(-2, -1), norm=None):

114

"""Compute 2-D inverse FFT to real output."""

115

116

def rfftn(a, s=None, axes=None, norm=None):

117

"""Compute N-D FFT of real input."""

118

119

def irfftn(a, s=None, axes=None, norm=None):

120

"""Compute N-D inverse FFT to real output."""

121

```

122

123

### Hermitian FFT

124

125

FFT functions for Hermitian (conjugate symmetric) input.

126

127

```python { .api }

128

def hfft(a, n=None, axis=-1, norm=None):

129

"""Compute FFT of signal with Hermitian symmetry.

130

131

Takes complex input with Hermitian symmetry and returns real output.

132

133

Parameters:

134

- a: array-like, Hermitian input array

135

- n: int, length of transformed axis

136

- axis: int, axis over which to compute FFT

137

- norm: str, normalization mode

138

139

Returns:

140

cupy.ndarray: real-valued result

141

"""

142

143

def ihfft(a, n=None, axis=-1, norm=None):

144

"""Compute inverse of hfft.

145

146

Takes real input and returns complex output with Hermitian symmetry.

147

"""

148

```

149

150

### Frequency Arrays

151

152

Helper functions for frequency bin calculations.

153

154

```python { .api }

155

def fftfreq(n, d=1.0):

156

"""Return discrete Fourier Transform sample frequencies.

157

158

Parameters:

159

- n: int, window length

160

- d: scalar, sample spacing (time between samples)

161

162

Returns:

163

cupy.ndarray: frequency values for each bin

164

"""

165

166

def rfftfreq(n, d=1.0):

167

"""Return sample frequencies for rfft.

168

169

Parameters:

170

- n: int, window length

171

- d: scalar, sample spacing

172

173

Returns:

174

cupy.ndarray: positive frequency values

175

"""

176

```

177

178

### FFT Shifting

179

180

Functions to rearrange FFT output for centered frequency display.

181

182

```python { .api }

183

def fftshift(x, axes=None):

184

"""Shift zero-frequency component to center of spectrum.

185

186

Parameters:

187

- x: array-like, input array

188

- axes: int or shape tuple, axes over which to shift

189

190

Returns:

191

cupy.ndarray: shifted array

192

"""

193

194

def ifftshift(x, axes=None):

195

"""Inverse of fftshift.

196

197

Parameters:

198

- x: array-like, input array

199

- axes: int or shape tuple, axes over which to shift

200

201

Returns:

202

cupy.ndarray: shifted array

203

"""

204

```

205

206

### FFT Configuration

207

208

Configuration module for FFT operations.

209

210

```python { .api }

211

# From cupy.fft.config module

212

class config:

213

"""FFT configuration utilities for plan caching and optimization."""

214

215

@staticmethod

216

def get_plan_cache():

217

"""Get current FFT plan cache."""

218

219

@staticmethod

220

def set_cufft_gpus(gpus):

221

"""Set GPUs to use for multi-GPU FFT."""

222

223

@staticmethod

224

def set_cufft_callbacks(callbacks):

225

"""Set cuFFT callbacks for custom processing."""

226

```

227

228

## Usage Examples

229

230

### Basic 1D FFT

231

232

```python

233

import cupy as cp

234

import numpy as np

235

236

# Create sample signal

237

n = 1024

238

t = cp.linspace(0, 1, n)

239

signal = cp.sin(2 * cp.pi * 50 * t) + 0.5 * cp.sin(2 * cp.pi * 120 * t)

240

241

# Compute FFT

242

fft_result = cp.fft.fft(signal)

243

frequencies = cp.fft.fftfreq(n, 1/n)

244

245

# Get magnitude spectrum

246

magnitude = cp.abs(fft_result)

247

print(f"Peak frequencies at bins: {cp.argmax(magnitude[:n//2])}")

248

```

249

250

### 2D FFT for Image Processing

251

252

```python

253

import cupy as cp

254

255

# Create 2D image (or load real image data)

256

image = cp.random.random((512, 512))

257

258

# Compute 2D FFT

259

fft_image = cp.fft.fft2(image)

260

261

# Shift zero frequency to center for visualization

262

fft_shifted = cp.fft.fftshift(fft_image)

263

264

# Apply frequency domain filter (low-pass filter)

265

h, w = fft_shifted.shape

266

center_h, center_w = h // 2, w // 2

267

mask = cp.zeros((h, w))

268

mask[center_h-50:center_h+50, center_w-50:center_w+50] = 1

269

270

# Apply filter and inverse transform

271

filtered_fft = fft_shifted * mask

272

filtered_fft_shifted = cp.fft.ifftshift(filtered_fft)

273

filtered_image = cp.fft.ifft2(filtered_fft_shifted)

274

275

# Take real part (remove small imaginary components from numerical errors)

276

filtered_image = cp.real(filtered_image)

277

```

278

279

### Real FFT for Efficiency

280

281

```python

282

import cupy as cp

283

284

# Real-valued signal

285

real_signal = cp.random.random(10000)

286

287

# Use rfft for real input (more efficient)

288

rfft_result = cp.fft.rfft(real_signal)

289

print(f"Original length: {len(real_signal)}")

290

print(f"RFFT result length: {len(rfft_result)}") # n//2 + 1

291

292

# Compute power spectral density

293

psd = cp.abs(rfft_result) ** 2

294

295

# Inverse transform back to real signal

296

reconstructed = cp.fft.irfft(rfft_result, n=len(real_signal))

297

print(f"Reconstruction error: {cp.mean(cp.abs(real_signal - reconstructed))}")

298

```

299

300

### Batch FFT Processing

301

302

```python

303

import cupy as cp

304

305

# Process multiple signals simultaneously

306

batch_size = 100

307

signal_length = 1024

308

signals = cp.random.random((batch_size, signal_length))

309

310

# FFT along last axis (each row is a signal)

311

batch_fft = cp.fft.fft(signals, axis=1)

312

313

# Process along first axis (each column is a signal)

314

column_fft = cp.fft.fft(signals, axis=0)

315

316

# 2D FFT treating each signal as 2D

317

signals_2d = signals.reshape(10, 10, signal_length)

318

fft_2d = cp.fft.fft2(signals_2d, axes=(0, 1))

319

```

320

321

### Advanced FFT Applications

322

323

```python

324

import cupy as cp

325

326

# Convolution using FFT (faster for large kernels)

327

def fft_convolve(signal, kernel):

328

"""Convolution using FFT for efficiency."""

329

n = len(signal) + len(kernel) - 1

330

331

# Pad both to same length

332

signal_padded = cp.pad(signal, (0, n - len(signal)))

333

kernel_padded = cp.pad(kernel, (0, n - len(kernel)))

334

335

# FFT, multiply, inverse FFT

336

signal_fft = cp.fft.fft(signal_padded)

337

kernel_fft = cp.fft.fft(kernel_padded)

338

result_fft = signal_fft * kernel_fft

339

result = cp.fft.ifft(result_fft)

340

341

return cp.real(result)

342

343

# Example usage

344

signal = cp.random.random(10000)

345

gaussian_kernel = cp.exp(-cp.linspace(-3, 3, 101)**2)

346

convolved = fft_convolve(signal, gaussian_kernel)

347

348

# Cross-correlation using FFT

349

def fft_xcorr(x, y):

350

"""Cross-correlation using FFT."""

351

n = len(x) + len(y) - 1

352

x_padded = cp.pad(x, (0, n - len(x)))

353

y_padded = cp.pad(y, (0, n - len(y)))

354

355

X = cp.fft.fft(x_padded)

356

Y = cp.fft.fft(y_padded)

357

xcorr = cp.fft.ifft(X * cp.conj(Y))

358

359

return cp.real(xcorr)

360

361

# Find time delay between two signals

362

signal1 = cp.random.random(1000)

363

signal2 = cp.roll(signal1, 50) + 0.1 * cp.random.random(1000) # Delayed + noise

364

xcorr = fft_xcorr(signal1, signal2)

365

delay = cp.argmax(cp.abs(xcorr)) - len(signal1) + 1

366

print(f"Detected delay: {delay} samples")

367

```

368

369

### Spectral Analysis

370

371

```python

372

import cupy as cp

373

374

def power_spectral_density(signal, fs=1.0, nperseg=256):

375

"""Compute power spectral density using Welch's method."""

376

# Simple implementation - overlap segments and average

377

n_overlap = nperseg // 2

378

segments = []

379

380

for i in range(0, len(signal) - nperseg, nperseg - n_overlap):

381

segment = signal[i:i+nperseg]

382

# Apply Hanning window

383

window = 0.5 * (1 - cp.cos(2 * cp.pi * cp.arange(nperseg) / (nperseg - 1)))

384

windowed = segment * window

385

segments.append(windowed)

386

387

if segments:

388

segments = cp.stack(segments)

389

# FFT each segment

390

fft_segments = cp.fft.rfft(segments, axis=1)

391

# Compute power and average

392

power = cp.mean(cp.abs(fft_segments) ** 2, axis=0)

393

freqs = cp.fft.rfftfreq(nperseg, 1/fs)

394

return freqs, power

395

else:

396

return None, None

397

398

# Example usage

399

fs = 1000 # Sampling frequency

400

t = cp.arange(0, 10, 1/fs)

401

signal = cp.sin(2*cp.pi*50*t) + 0.5*cp.sin(2*cp.pi*120*t) + 0.2*cp.random.random(len(t))

402

403

freqs, psd = power_spectral_density(signal, fs)

404

if psd is not None:

405

peak_freq_idx = cp.argmax(psd)

406

peak_freq = freqs[peak_freq_idx]

407

print(f"Peak frequency: {peak_freq:.1f} Hz")

408

```