0
# scipy.fft Interface
1
2
Compatible interface for scipy.fft functions with FFTW backend, supporting the newer scipy FFT API including workers parameter and context manager compatibility. This interface provides the same functionality as scipy.fft but with FFTW's superior performance.
3
4
## Capabilities
5
6
### Complex FFT Functions
7
8
Core complex-to-complex transform functions compatible with scipy.fft.
9
10
```python { .api }
11
def fft(
12
x,
13
n=None,
14
axis=-1,
15
norm=None,
16
overwrite_x=False,
17
workers=None
18
):
19
"""
20
1D discrete Fourier transform.
21
22
Parameters:
23
- x: Input array
24
- n: Length of transform (default: x.shape[axis])
25
- axis: Axis over which to compute FFT (default: -1)
26
- norm: Normalization mode ('backward', 'ortho', 'forward', None)
27
- overwrite_x: Whether input can be overwritten (default: False)
28
- workers: Number of workers (threads) to use (default: None)
29
- plan: Precomputed plan (not used, for compatibility)
30
31
Returns:
32
- Complex array containing the transform
33
"""
34
35
def ifft(
36
x,
37
n=None,
38
axis=-1,
39
norm=None,
40
overwrite_x=False,
41
workers=None
42
):
43
"""
44
1D inverse discrete Fourier transform.
45
46
Parameters: Same as fft()
47
48
Returns:
49
- Complex array containing the inverse transform
50
"""
51
52
def fft2(
53
x,
54
s=None,
55
axes=(-2, -1),
56
norm=None,
57
overwrite_x=False,
58
workers=None
59
):
60
"""
61
2D discrete Fourier transform.
62
63
Parameters:
64
- x: Input array
65
- s: Shape of transform (default: x.shape[axes])
66
- axes: Axes over which to compute FFT (default: (-2, -1))
67
- Other parameters: Same as fft()
68
69
Returns:
70
- Complex array containing the 2D transform
71
"""
72
73
def ifft2(
74
x,
75
s=None,
76
axes=(-2, -1),
77
norm=None,
78
overwrite_x=False,
79
workers=None
80
):
81
"""
82
2D inverse discrete Fourier transform.
83
84
Parameters: Same as fft2()
85
86
Returns:
87
- Complex array containing the 2D inverse transform
88
"""
89
90
def fftn(
91
x,
92
s=None,
93
axes=None,
94
norm=None,
95
overwrite_x=False,
96
workers=None
97
):
98
"""
99
N-dimensional discrete Fourier transform.
100
101
Parameters:
102
- x: Input array
103
- s: Shape of transform (default: x.shape[axes])
104
- axes: Axes over which to compute FFT (default: all axes)
105
- Other parameters: Same as fft()
106
107
Returns:
108
- Complex array containing the N-D transform
109
"""
110
111
def ifftn(
112
x,
113
s=None,
114
axes=None,
115
norm=None,
116
overwrite_x=False,
117
workers=None
118
):
119
"""
120
N-dimensional inverse discrete Fourier transform.
121
122
Parameters: Same as fftn()
123
124
Returns:
125
- Complex array containing the N-D inverse transform
126
"""
127
```
128
129
### Real FFT Functions
130
131
Real-to-complex and complex-to-real transform functions.
132
133
```python { .api }
134
def rfft(
135
x,
136
n=None,
137
axis=-1,
138
norm=None,
139
overwrite_x=False,
140
workers=None
141
):
142
"""
143
1D real-to-complex discrete Fourier transform.
144
145
Parameters: Same as fft()
146
147
Returns:
148
- Complex array with shape [..., n//2 + 1] along transform axis
149
"""
150
151
def irfft(
152
x,
153
n=None,
154
axis=-1,
155
norm=None,
156
overwrite_x=False,
157
workers=None
158
):
159
"""
160
1D complex-to-real inverse discrete Fourier transform.
161
162
Parameters: Same as fft()
163
164
Returns:
165
- Real array with specified length n along transform axis
166
"""
167
168
def rfft2(
169
x,
170
s=None,
171
axes=(-2, -1),
172
norm=None,
173
overwrite_x=False,
174
workers=None
175
):
176
"""
177
2D real-to-complex discrete Fourier transform.
178
179
Parameters: Same as fft2()
180
181
Returns:
182
- Complex array with last axis shape s[-1]//2 + 1
183
"""
184
185
def irfft2(
186
x,
187
s=None,
188
axes=(-2, -1),
189
norm=None,
190
overwrite_x=False,
191
workers=None
192
):
193
"""
194
2D complex-to-real inverse discrete Fourier transform.
195
196
Parameters: Same as fft2()
197
198
Returns:
199
- Real array with specified shape s
200
"""
201
202
def rfftn(
203
x,
204
s=None,
205
axes=None,
206
norm=None,
207
overwrite_x=False,
208
workers=None
209
):
210
"""
211
N-dimensional real-to-complex discrete Fourier transform.
212
213
Parameters: Same as fftn()
214
215
Returns:
216
- Complex array with last transform axis shape s[-1]//2 + 1
217
"""
218
219
def irfftn(
220
x,
221
s=None,
222
axes=None,
223
norm=None,
224
overwrite_x=False,
225
workers=None
226
):
227
"""
228
N-dimensional complex-to-real inverse discrete Fourier transform.
229
230
Parameters: Same as fftn()
231
232
Returns:
233
- Real array with specified shape s
234
"""
235
```
236
237
### Hermitian FFT Functions
238
239
Functions for transforms of Hermitian (conjugate-symmetric) data.
240
241
```python { .api }
242
def hfft(
243
x,
244
n=None,
245
axis=-1,
246
norm=None,
247
overwrite_x=False,
248
workers=None
249
):
250
"""
251
FFT of Hermitian (conjugate-symmetric) sequence.
252
253
Parameters: Same as fft()
254
255
Returns:
256
- Real array containing the transform
257
"""
258
259
def ihfft(
260
x,
261
n=None,
262
axis=-1,
263
norm=None,
264
overwrite_x=False,
265
workers=None
266
):
267
"""
268
Inverse FFT of Hermitian sequence.
269
270
Parameters: Same as fft()
271
272
Returns:
273
- Complex array containing the inverse transform
274
"""
275
```
276
277
### Discrete Cosine and Sine Transforms
278
279
Discrete Cosine Transform (DCT) and Discrete Sine Transform (DST) functions compatible with scipy.fft, supporting multiple transform types and normalization modes.
280
281
```python { .api }
282
def dct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
283
"""
284
Perform a 1D discrete cosine transform.
285
286
Parameters:
287
- x: array_like, input array
288
- type: int, optional, DCT type (1, 2, 3, or 4), default is 2
289
- n: int, optional, length of the transform
290
- axis: int, optional, axis over which to compute the DCT
291
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
292
- overwrite_x: bool, optional, whether input can be overwritten
293
- workers: int, optional, number of workers (threads) to use
294
- planner_effort: str, optional, FFTW planner effort
295
- auto_align_input: bool, optional, automatically align input
296
- auto_contiguous: bool, optional, ensure input is contiguous
297
298
Returns:
299
ndarray: DCT result
300
"""
301
302
def idct(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
303
"""
304
Perform an inverse 1D discrete cosine transform.
305
306
Parameters:
307
- x: array_like, input array
308
- type: int, optional, DCT type (1, 2, 3, or 4), default is 2
309
- n: int, optional, length of the inverse transform
310
- axis: int, optional, axis over which to compute the inverse DCT
311
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
312
- overwrite_x: bool, optional, whether input can be overwritten
313
- workers: int, optional, number of workers (threads) to use
314
- planner_effort: str, optional, FFTW planner effort
315
- auto_align_input: bool, optional, automatically align input
316
- auto_contiguous: bool, optional, ensure input is contiguous
317
318
Returns:
319
ndarray: Inverse DCT result
320
"""
321
322
def dst(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
323
"""
324
Perform a 1D discrete sine transform.
325
326
Parameters:
327
- x: array_like, input array
328
- type: int, optional, DST type (1, 2, 3, or 4), default is 2
329
- n: int, optional, length of the transform
330
- axis: int, optional, axis over which to compute the DST
331
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
332
- overwrite_x: bool, optional, whether input can be overwritten
333
- workers: int, optional, number of workers (threads) to use
334
- planner_effort: str, optional, FFTW planner effort
335
- auto_align_input: bool, optional, automatically align input
336
- auto_contiguous: bool, optional, ensure input is contiguous
337
338
Returns:
339
ndarray: DST result
340
"""
341
342
def idst(x, type=2, n=None, axis=-1, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
343
"""
344
Perform an inverse 1D discrete sine transform.
345
346
Parameters:
347
- x: array_like, input array
348
- type: int, optional, DST type (1, 2, 3, or 4), default is 2
349
- n: int, optional, length of the inverse transform
350
- axis: int, optional, axis over which to compute the inverse DST
351
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
352
- overwrite_x: bool, optional, whether input can be overwritten
353
- workers: int, optional, number of workers (threads) to use
354
- planner_effort: str, optional, FFTW planner effort
355
- auto_align_input: bool, optional, automatically align input
356
- auto_contiguous: bool, optional, ensure input is contiguous
357
358
Returns:
359
ndarray: Inverse DST result
360
"""
361
362
def dctn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
363
"""
364
Perform an N-dimensional discrete cosine transform.
365
366
Parameters:
367
- x: array_like, input array
368
- type: int, optional, DCT type (1, 2, 3, or 4), default is 2
369
- s: sequence of ints, optional, shape of the result
370
- axes: sequence of ints, optional, axes over which to compute the DCT
371
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
372
- overwrite_x: bool, optional, whether input can be overwritten
373
- workers: int, optional, number of workers (threads) to use
374
- planner_effort: str, optional, FFTW planner effort
375
- auto_align_input: bool, optional, automatically align input
376
- auto_contiguous: bool, optional, ensure input is contiguous
377
378
Returns:
379
ndarray: N-dimensional DCT result
380
"""
381
382
def idctn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
383
"""
384
Perform an N-dimensional inverse discrete cosine transform.
385
386
Parameters:
387
- x: array_like, input array
388
- type: int, optional, DCT type (1, 2, 3, or 4), default is 2
389
- s: sequence of ints, optional, shape of the result
390
- axes: sequence of ints, optional, axes over which to compute the inverse DCT
391
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
392
- overwrite_x: bool, optional, whether input can be overwritten
393
- workers: int, optional, number of workers (threads) to use
394
- planner_effort: str, optional, FFTW planner effort
395
- auto_align_input: bool, optional, automatically align input
396
- auto_contiguous: bool, optional, ensure input is contiguous
397
398
Returns:
399
ndarray: N-dimensional inverse DCT result
400
"""
401
402
def dstn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
403
"""
404
Perform an N-dimensional discrete sine transform.
405
406
Parameters:
407
- x: array_like, input array
408
- type: int, optional, DST type (1, 2, 3, or 4), default is 2
409
- s: sequence of ints, optional, shape of the result
410
- axes: sequence of ints, optional, axes over which to compute the DST
411
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
412
- overwrite_x: bool, optional, whether input can be overwritten
413
- workers: int, optional, number of workers (threads) to use
414
- planner_effort: str, optional, FFTW planner effort
415
- auto_align_input: bool, optional, automatically align input
416
- auto_contiguous: bool, optional, ensure input is contiguous
417
418
Returns:
419
ndarray: N-dimensional DST result
420
"""
421
422
def idstn(x, type=2, s=None, axes=None, norm=None, overwrite_x=False, workers=None, planner_effort=None, auto_align_input=True, auto_contiguous=True):
423
"""
424
Perform an N-dimensional inverse discrete sine transform.
425
426
Parameters:
427
- x: array_like, input array
428
- type: int, optional, DST type (1, 2, 3, or 4), default is 2
429
- s: sequence of ints, optional, shape of the result
430
- axes: sequence of ints, optional, axes over which to compute the inverse DST
431
- norm: str, optional, normalization mode ('backward', 'ortho', 'forward', None)
432
- overwrite_x: bool, optional, whether input can be overwritten
433
- workers: int, optional, number of workers (threads) to use
434
- planner_effort: str, optional, FFTW planner effort
435
- auto_align_input: bool, optional, automatically align input
436
- auto_contiguous: bool, optional, ensure input is contiguous
437
438
Returns:
439
ndarray: N-dimensional inverse DST result
440
"""
441
```
442
443
### Utility Functions
444
445
Additional utility functions compatible with scipy.fft.
446
447
```python { .api }
448
def next_fast_len(target, real=False):
449
"""
450
Find the optimal length for FFT transforms.
451
452
Parameters:
453
- target: Target transform length
454
- real: Whether this is for a real transform (default: False)
455
456
Returns:
457
- int: Optimal length >= target that gives efficient transforms
458
"""
459
```
460
461
## Usage Examples
462
463
### Drop-in scipy.fft Replacement
464
465
```python
466
# Original scipy.fft code
467
from scipy import fft
468
import numpy as np
469
470
data = np.random.randn(1024) + 1j * np.random.randn(1024)
471
result_scipy = fft.fft(data)
472
473
# Replace with pyFFTW scipy interface
474
from pyfftw.interfaces import scipy_fft
475
476
result_pyfftw = scipy_fft.fft(data)
477
print(f"Results match: {np.allclose(result_scipy, result_pyfftw)}")
478
```
479
480
### Workers Parameter
481
482
```python
483
from pyfftw.interfaces import scipy_fft
484
import numpy as np
485
486
# Use multiple workers (threads)
487
data = np.random.randn(1024, 512) + 1j * np.random.randn(1024, 512)
488
489
result = scipy_fft.fft2(data, workers=4) # Use 4 threads
490
```
491
492
### Context Manager Compatibility
493
494
```python
495
from pyfftw.interfaces import scipy_fft
496
from scipy.fft import set_workers
497
import numpy as np
498
499
# Works with scipy's context manager
500
data = np.random.randn(2048, 1024)
501
502
with set_workers(4):
503
# All transforms in this block use 4 workers
504
spectrum = scipy_fft.rfft2(data)
505
filtered = scipy_fft.irfft2(spectrum * 0.5)
506
```
507
508
### Optimal Transform Sizes
509
510
```python
511
from pyfftw.interfaces import scipy_fft
512
import numpy as np
513
514
# Find optimal sizes for efficient transforms
515
target_size = 1000
516
optimal_size = scipy_fft.next_fast_len(target_size)
517
optimal_real_size = scipy_fft.next_fast_len(target_size, real=True)
518
519
print(f"Target: {target_size}")
520
print(f"Optimal complex: {optimal_size}")
521
print(f"Optimal real: {optimal_real_size}")
522
523
# Use optimal size for better performance
524
data = np.random.randn(optimal_real_size)
525
result = scipy_fft.rfft(data, workers=2)
526
```
527
528
### Real Signal Processing
529
530
```python
531
from pyfftw.interfaces import scipy_fft
532
import numpy as np
533
534
# Generate real signal
535
t = np.linspace(0, 1, 1024, endpoint=False)
536
signal = np.sin(2 * np.pi * 50 * t) + 0.5 * np.sin(2 * np.pi * 120 * t)
537
noise = 0.2 * np.random.randn(len(t))
538
noisy_signal = signal + noise
539
540
# Analyze in frequency domain
541
spectrum = scipy_fft.rfft(noisy_signal, workers=2)
542
freqs = scipy_fft.rfftfreq(len(noisy_signal), t[1] - t[0])
543
544
# Apply frequency domain filter
545
spectrum[np.abs(freqs) > 100] = 0 # Low-pass filter at 100 Hz
546
547
# Transform back
548
filtered_signal = scipy_fft.irfft(spectrum, n=len(noisy_signal))
549
```
550
551
### 3D Volume Processing
552
553
```python
554
from pyfftw.interfaces import scipy_fft
555
import numpy as np
556
557
# 3D medical/scientific volume data
558
volume = np.random.randn(128, 128, 64)
559
560
# 3D real FFT with multiple workers
561
spectrum_3d = scipy_fft.rfftn(
562
volume,
563
workers=4,
564
norm='ortho' # Preserve energy
565
)
566
567
# Process in frequency domain
568
# (e.g., apply 3D filter, etc.)
569
570
# Transform back
571
processed_volume = scipy_fft.irfftn(
572
spectrum_3d,
573
s=volume.shape,
574
workers=4,
575
norm='ortho'
576
)
577
```
578
579
### Normalization Modes
580
581
```python
582
from pyfftw.interfaces import scipy_fft
583
import numpy as np
584
585
data = np.random.randn(256) + 1j * np.random.randn(256)
586
587
# Different normalization modes (same as scipy.fft)
588
forward_norm = scipy_fft.fft(data, norm='forward')
589
backward_norm = scipy_fft.fft(data, norm='backward') # Default
590
ortho_norm = scipy_fft.fft(data, norm='ortho')
591
592
# Verify round-trip with orthogonal normalization
593
reconstructed = scipy_fft.ifft(ortho_norm, norm='ortho')
594
print(f"Reconstruction error: {np.max(np.abs(data - reconstructed))}")
595
```
596
597
### Performance Comparison
598
599
```python
600
from pyfftw.interfaces import scipy_fft
601
from scipy import fft as scipy_fft_native
602
import numpy as np
603
import time
604
605
# Compare performance with native scipy
606
N = 1024 * 1024
607
data = np.random.randn(N) + 1j * np.random.randn(N)
608
609
# Time scipy native
610
start = time.time()
611
for _ in range(10):
612
result_scipy = scipy_fft_native.fft(data)
613
time_scipy = time.time() - start
614
615
# Time pyFFTW scipy interface
616
start = time.time()
617
for _ in range(10):
618
result_pyfftw = scipy_fft.fft(data, workers=4)
619
time_pyfftw = time.time() - start
620
621
print(f"SciPy native: {time_scipy:.3f}s")
622
print(f"pyFFTW: {time_pyfftw:.3f}s")
623
print(f"Speedup: {time_scipy/time_pyfftw:.2f}x")
624
print(f"Results match: {np.allclose(result_scipy, result_pyfftw)}")
625
```