FFT (1D) building blocks #
TorchLean’s layer/model definitions are scalar-polymorphic: a model runs over whatever scalar type
α you instantiate it with (e.g. Float, IEEE32Exec, ℝ, etc.). A “real FFT” would normally
change the scalar type (real → complex), but TorchLean’s LayerDef does not support changing the
scalar type mid-model.
So this module provides complex-domain transforms: fft and ifft as layers that assume the
chosen scalar type α already behaves like a complex field (for example TorchLean.Complex IEEE32Exec, selected via --dtype=complex).
Implementation note: we define fft/ifft as multiplication by explicit DFT matrices (so they are
purely built from existing ops like const and matmul). This is correctness-first and keeps the
transform differentiable under the existing autograd rules. It is not optimized for large n.
Numerics note:
- Over mathlib’s
ℂ, the corresponding DFT/IDFT inversion facts are proved inNN.Proofs.Analysis.Fft(and the bridge to thesetwiddle/matrix definitions is inNN.Proofs.Analysis.FftBridge). - For executable
IEEE32Exec,sin/cosare implemented deterministically in Lean (seeNN.Floats.IEEEExec.Exec32). This makes FFT execution reproducible across platforms. Proving tight end-to-end accuracy bounds for FFT still requires a separate analysis layer (or an interval/oracle backend) to relate those executable trigonometric approximations to realsin/cos.
Shape abbreviation for a length-n vector.
Instances For
Shape abbreviation for an m×n matrix.
Instances For
We build twiddle factors using only the Context interface:
I := sqrt(-1) and e^{-iθ} = cos θ - I * sin θ.
This is intended to be instantiated with TorchLean’s own complex scalar
TorchLean.Complex β (for some base scalar β). For real-only scalar backends, the formulas are
not meaningful.
The imaginary unit, represented as sqrt(-1) in the ambient scalar type.
Instances For
Twiddle factor exp(-2π i * j*k / n) written as cos θ - i sin θ.
Instances For
Twiddle factor exp(+2π i * j*k / n) written as cos θ + i sin θ.
Instances For
DFT matrix F : n×n with entries F[k,j] = exp(-2π i j*k / n).
Instances For
Inverse DFT matrix F⁻¹ : n×n with entries F⁻¹[j,k] = exp(+2π i j*k / n) / n.
Instances For
FFT along the outermost axis of a tensor.
This applies the DFT to the leading dimension n of a shape dim n rest by:
- reshaping to a matrix
n × (numel rest), - left-multiplying by the
n×nDFT matrix, then - reshaping back.
This is the most generally useful primitive for building N-D FFTs: you can permute an axis to the
front, call fftDim0, then permute back.
Instances For
Inverse FFT along the outermost axis of a tensor (uses the inverse DFT matrix).
See fftDim0 for the implementation strategy.
Instances For
Apply a sequence of swapAdjacentAtDepth operations (shape-indexed permutation primitive).
Instances For
FFT along an axis at a given depth (0-based from the outermost).
This is implemented by swapping the target axis outward (one adjacent swap per step) until it
reaches depth 0, applying fftDim0, then swapping back.
If depth ≥ Shape.rank s, this layer is the identity.
Instances For
Inverse FFT along an axis at a given depth (see fftAtDepth).