or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-operations.mdcuda-interface.mdcustom-kernels.mdfft-operations.mdindex.mdlinear-algebra.mdmath-functions.mdrandom-numbers.mdstatistics-sorting.md

fft-operations.mddocs/

0

# FFT Operations

1

2

GPU-accelerated Fast Fourier Transform operations using cuFFT library. Provides complete discrete Fourier transform functionality including 1D, 2D, and N-D transforms for both complex-to-complex and real-to-complex transformations.

3

4

## Capabilities

5

6

### Discrete Fourier Transform

7

8

```python { .api }

9

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

10

"""

11

Compute 1-D discrete Fourier Transform.

12

13

Parameters:

14

- a: input array

15

- n: length of transformed axis

16

- axis: axis over which to compute FFT

17

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

18

19

Returns:

20

cupy.ndarray: transformed array

21

"""

22

23

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

24

"""

25

Compute 1-D inverse discrete Fourier Transform.

26

27

Parameters:

28

- a: input array

29

- n: length of transformed axis

30

- axis: axis over which to compute IFFT

31

- norm: normalization mode

32

33

Returns:

34

cupy.ndarray: inverse transformed array

35

"""

36

37

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

38

"""

39

Compute 2-D discrete Fourier Transform.

40

41

Parameters:

42

- a: input array

43

- s: shape of transformed axes

44

- axes: axes over which to compute FFT

45

- norm: normalization mode

46

47

Returns:

48

cupy.ndarray: 2-D transformed array

49

"""

50

51

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

52

"""

53

Compute 2-D inverse discrete Fourier Transform.

54

55

Parameters:

56

- a: input array

57

- s: shape of transformed axes

58

- axes: axes over which to compute IFFT

59

- norm: normalization mode

60

61

Returns:

62

cupy.ndarray: 2-D inverse transformed array

63

"""

64

65

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

66

"""

67

Compute N-D discrete Fourier Transform.

68

69

Parameters:

70

- a: input array

71

- s: shape of transformed axes

72

- axes: axes over which to compute FFT

73

- norm: normalization mode

74

75

Returns:

76

cupy.ndarray: N-D transformed array

77

"""

78

79

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

80

"""

81

Compute N-D inverse discrete Fourier Transform.

82

83

Parameters:

84

- a: input array

85

- s: shape of transformed axes

86

- axes: axes over which to compute IFFT

87

- norm: normalization mode

88

89

Returns:

90

cupy.ndarray: N-D inverse transformed array

91

"""

92

```

93

94

### Real FFT

95

96

```python { .api }

97

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

98

"""

99

Compute 1-D discrete Fourier Transform for real input.

100

101

Parameters:

102

- a: input array (real)

103

- n: length of transformed axis

104

- axis: axis over which to compute FFT

105

- norm: normalization mode

106

107

Returns:

108

cupy.ndarray: transformed array (complex)

109

"""

110

111

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

112

"""

113

Compute 1-D inverse discrete Fourier Transform for real output.

114

115

Parameters:

116

- a: input array (complex)

117

- n: length of transformed axis

118

- axis: axis over which to compute IFFT

119

- norm: normalization mode

120

121

Returns:

122

cupy.ndarray: inverse transformed array (real)

123

"""

124

125

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

126

"""

127

Compute 2-D discrete Fourier Transform for real input.

128

129

Parameters:

130

- a: input array (real)

131

- s: shape of transformed axes

132

- axes: axes over which to compute FFT

133

- norm: normalization mode

134

135

Returns:

136

cupy.ndarray: 2-D transformed array (complex)

137

"""

138

139

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

140

"""

141

Compute 2-D inverse discrete Fourier Transform for real output.

142

143

Parameters:

144

- a: input array (complex)

145

- s: shape of transformed axes

146

- axes: axes over which to compute IFFT

147

- norm: normalization mode

148

149

Returns:

150

cupy.ndarray: 2-D inverse transformed array (real)

151

"""

152

153

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

154

"""

155

Compute N-D discrete Fourier Transform for real input.

156

157

Parameters:

158

- a: input array (real)

159

- s: shape of transformed axes

160

- axes: axes over which to compute FFT

161

- norm: normalization mode

162

163

Returns:

164

cupy.ndarray: N-D transformed array (complex)

165

"""

166

167

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

168

"""

169

Compute N-D inverse discrete Fourier Transform for real output.

170

171

Parameters:

172

- a: input array (complex)

173

- s: shape of transformed axes

174

- axes: axes over which to compute IFFT

175

- norm: normalization mode

176

177

Returns:

178

cupy.ndarray: N-D inverse transformed array (real)

179

"""

180

```

181

182

### Hermitian FFT

183

184

```python { .api }

185

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

186

"""

187

Compute 1-D discrete Fourier Transform of Hermitian input.

188

189

Parameters:

190

- a: input array (Hermitian symmetric)

191

- n: length of transformed axis

192

- axis: axis over which to compute FFT

193

- norm: normalization mode

194

195

Returns:

196

cupy.ndarray: transformed array (real)

197

"""

198

199

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

200

"""

201

Compute 1-D inverse discrete Fourier Transform to produce Hermitian output.

202

203

Parameters:

204

- a: input array (real)

205

- n: length of transformed axis

206

- axis: axis over which to compute IFFT

207

- norm: normalization mode

208

209

Returns:

210

cupy.ndarray: inverse transformed array (Hermitian)

211

"""

212

```

213

214

### Helper Functions

215

216

```python { .api }

217

def fftfreq(n, d=1.0):

218

"""

219

Return discrete Fourier Transform sample frequencies.

220

221

Parameters:

222

- n: window length

223

- d: sample spacing

224

225

Returns:

226

cupy.ndarray: sample frequencies

227

"""

228

229

def rfftfreq(n, d=1.0):

230

"""

231

Return sample frequencies for real FFT.

232

233

Parameters:

234

- n: window length

235

- d: sample spacing

236

237

Returns:

238

cupy.ndarray: sample frequencies for real FFT

239

"""

240

241

def fftshift(x, axes=None):

242

"""

243

Shift zero-frequency component to center of spectrum.

244

245

Parameters:

246

- x: input array

247

- axes: axes over which to shift

248

249

Returns:

250

cupy.ndarray: shifted array

251

"""

252

253

def ifftshift(x, axes=None):

254

"""

255

Inverse of fftshift.

256

257

Parameters:

258

- x: input array

259

- axes: axes over which to shift

260

261

Returns:

262

cupy.ndarray: shifted array

263

"""

264

```

265

266

### Configuration

267

268

```python { .api }

269

# FFT configuration module

270

import cupy.fft.config

271

272

# Planning and caching controls available through config module

273

```

274

275

## Usage Examples

276

277

### Basic 1-D FFT

278

279

```python

280

import cupy as cp

281

import numpy as np

282

283

# Create sample signal

284

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

285

freq1, freq2 = 5, 20 # Hz

286

signal = cp.sin(2*cp.pi*freq1*t) + 0.5*cp.sin(2*cp.pi*freq2*t)

287

288

# Add noise

289

noise = 0.1 * cp.random.randn(len(t))

290

noisy_signal = signal + noise

291

292

# Compute FFT

293

fft_result = cp.fft.fft(noisy_signal)

294

frequencies = cp.fft.fftfreq(len(t), t[1] - t[0])

295

296

# Magnitude spectrum

297

magnitude = cp.abs(fft_result)

298

299

# Find peaks (transfer to CPU for analysis)

300

magnitude_cpu = cp.asnumpy(magnitude)

301

freq_cpu = cp.asnumpy(frequencies)

302

```

303

304

### 2-D FFT for Image Processing

305

306

```python

307

import cupy as cp

308

309

# Create or load 2D image data

310

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

311

312

# Compute 2-D FFT

313

fft2d = cp.fft.fft2(image)

314

315

# Shift zero frequency to center

316

fft2d_shifted = cp.fft.fftshift(fft2d)

317

318

# Magnitude and phase

319

magnitude = cp.abs(fft2d_shifted)

320

phase = cp.angle(fft2d_shifted)

321

322

# Apply frequency domain filter (low-pass)

323

rows, cols = image.shape

324

crow, ccol = rows//2, cols//2

325

mask = cp.zeros((rows, cols))

326

mask[crow-30:crow+30, ccol-30:ccol+30] = 1

327

328

# Apply mask

329

filtered_fft = fft2d_shifted * mask

330

331

# Inverse transform

332

filtered_fft_ishifted = cp.fft.ifftshift(filtered_fft)

333

filtered_image = cp.fft.ifft2(filtered_fft_ishifted)

334

filtered_image = cp.real(filtered_image) # Take real part

335

```

336

337

### Real FFT for Efficiency

338

339

```python

340

import cupy as cp

341

342

# For real-valued signals, use rfft for efficiency

343

real_signal = cp.random.randn(1024)

344

345

# Real FFT (more efficient than complex FFT)

346

rfft_result = cp.fft.rfft(real_signal)

347

348

# Only positive frequencies are computed

349

n_pos_freq = len(rfft_result)

350

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

351

352

# Recover original signal

353

recovered_signal = cp.fft.irfft(rfft_result)

354

355

# Check reconstruction accuracy

356

reconstruction_error = cp.linalg.norm(real_signal - recovered_signal)

357

print(f"Reconstruction error: {reconstruction_error}")

358

```

359

360

### N-D FFT

361

362

```python

363

import cupy as cp

364

365

# 3-D data (e.g., volumetric data)

366

volume_data = cp.random.random((64, 64, 64))

367

368

# 3-D FFT

369

fft3d = cp.fft.fftn(volume_data)

370

371

# Compute magnitude spectrum

372

magnitude_spectrum = cp.abs(fft3d)

373

374

# FFT along specific axes only

375

fft_xy = cp.fft.fft2(volume_data, axes=(0, 1)) # FFT in X-Y plane for each Z

376

377

# Real 3-D FFT for real input

378

real_volume = cp.random.randn(32, 32, 32)

379

rfft3d = cp.fft.rfftn(real_volume)

380

```

381

382

### Convolution using FFT

383

384

```python

385

import cupy as cp

386

387

# Create signals

388

signal = cp.random.randn(1000)

389

kernel = cp.array([1, -1, 1, -1, 1]) / 5 # Simple kernel

390

391

# Pad for full convolution

392

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

393

signal_padded = cp.zeros(n)

394

signal_padded[:len(signal)] = signal

395

kernel_padded = cp.zeros(n)

396

kernel_padded[:len(kernel)] = kernel

397

398

# FFT-based convolution

399

signal_fft = cp.fft.fft(signal_padded)

400

kernel_fft = cp.fft.fft(kernel_padded)

401

convolved_fft = signal_fft * kernel_fft

402

convolved = cp.fft.ifft(convolved_fft)

403

convolved = cp.real(convolved) # Take real part

404

405

# Compare with direct convolution (on CPU)

406

signal_cpu = cp.asnumpy(signal)

407

kernel_cpu = cp.asnumpy(kernel)

408

direct_conv = np.convolve(signal_cpu, kernel_cpu, mode='full')

409

```

410

411

### Spectral Analysis

412

413

```python

414

import cupy as cp

415

416

# Generate test signal with multiple frequencies

417

fs = 1000 # Sampling frequency

418

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

419

f1, f2, f3 = 10, 50, 120 # Frequencies in Hz

420

421

signal = (cp.sin(2*cp.pi*f1*t) +

422

0.5*cp.sin(2*cp.pi*f2*t) +

423

0.2*cp.sin(2*cp.pi*f3*t))

424

425

# Add noise

426

signal += 0.1 * cp.random.randn(len(t))

427

428

# Windowing (Hann window)

429

window = cp.hanning(len(signal))

430

windowed_signal = signal * window

431

432

# Compute FFT

433

fft_result = cp.fft.fft(windowed_signal)

434

freqs = cp.fft.fftfreq(len(signal), 1/fs)

435

436

# Power spectral density

437

psd = cp.abs(fft_result)**2

438

439

# Find positive frequencies only

440

positive_freq_mask = freqs >= 0

441

positive_freqs = freqs[positive_freq_mask]

442

positive_psd = psd[positive_freq_mask]

443

```

444

445

### Frequency Domain Filtering

446

447

```python

448

import cupy as cp

449

450

# Create noisy signal

451

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

452

clean_signal = cp.sin(2*cp.pi*10*t) # 10 Hz signal

453

noise = 0.5 * cp.sin(2*cp.pi*60*t) # 60 Hz noise

454

noisy_signal = clean_signal + noise

455

456

# FFT

457

signal_fft = cp.fft.fft(noisy_signal)

458

freqs = cp.fft.fftfreq(len(t), t[1] - t[0])

459

460

# Design low-pass filter (cutoff at 20 Hz)

461

cutoff_freq = 20

462

filter_mask = cp.abs(freqs) <= cutoff_freq

463

464

# Apply filter in frequency domain

465

filtered_fft = signal_fft * filter_mask

466

467

# Inverse FFT to get filtered signal

468

filtered_signal = cp.fft.ifft(filtered_fft)

469

filtered_signal = cp.real(filtered_signal)

470

471

# Compare signals

472

print(f"Original SNR: {cp.var(clean_signal) / cp.var(noise)}")

473

residual_noise = filtered_signal - clean_signal

474

print(f"Filtered SNR: {cp.var(clean_signal) / cp.var(residual_noise)}")

475

```