FFT (1D) building blocks #
TorchLean’s layer/model definitions are scalar-polymorphic: a model runs over whatever scalar type
$\alpha$ you instantiate it with (for example Float, IEEE32Exec, or $\mathbb{R}$). A “real FFT”
would normally change the scalar type (real $\to$ 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
$\alpha$ 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\theta}=\cos\theta-I\sin\theta$.
This is intended to be instantiated with TorchLean’s own complex scalar
TorchLean.Complex β (for some base scalar $\beta$). 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 $e^{-2\pi i jk/n}$ written as $\cos\theta-i\sin\theta$.
Instances For
Twiddle factor $e^{2\pi i jk/n}$ written as $\cos\theta+i\sin\theta$.
Instances For
DFT matrix $F\in\mathbb{C}^{n\times n}$ with entries $F_{k,j}=e^{-2\pi i jk/n}$.
Instances For
Inverse DFT matrix $F^{-1}\in\mathbb{C}^{n\times n}$ with entries $(F^{-1})_{j,k}=e^{2\pi i jk/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 fftLeadingAxis, then permute back.
Instances For
Inverse FFT along the outermost axis of a tensor (uses the inverse DFT matrix).
See fftLeadingAxis 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 fftLeadingAxis, then swapping back.
If $\mathtt{depth}\ge\operatorname{rank}(s)$, this layer is the identity.
Instances For
Inverse FFT along an axis at a given depth (see fftAtDepth).