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") # -> FFTPlanx = np.random.randn(8, 4096).astype(np.float32)plan = specux.fft_plan(4096, real=True) # FFTPlan(n=4096, real=True, backend='auto')plan.bins # 2049F = plan.forward(x) # rfft; plan(x) is the same cally = plan.inverse(F) # irfft back to length 4096real=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]