Skip to content

FFTPlan

fft_plan binds a length once and hands back a reusable handle, mirroring stft_plan for the STFT. The FFT kernels are fully determined by the length, so a plan is a convenience (one object to pass around, bins precomputed), not an autotune.

specux.fft_plan(n, *, real=False, backend="auto") # -> FFTPlan
x = np.random.randn(8, 4096).astype(np.float32)
plan = specux.fft_plan(4096, real=True) # FFTPlan(n=4096, real=True, backend='auto')
plan.bins # 2049
F = plan.forward(x) # rfft; plan(x) is the same call
y = plan.inverse(F) # irfft back to length 4096

real=True selects the onesided pair rfft / irfft; real=False (the default) the complex pair fft / ifft. backend= is bound at construction and passed through to every call. Plans work on every backend and array library the functions accept, and the handle is cheap enough to create per configuration and keep for the process lifetime.

plans = {n: specux.fft_plan(n, real=True) for n in (1024, 4096, 16384)}
jobs = [(n, np.random.randn(4, n).astype(np.float32)) for n in (1024, 4096, 16384)]
spectra = [plans[n].forward(sig) for n, sig in jobs]