Fourier transforms along a selected axis #
TorchLean’s layer/model definitions are scalar-polymorphic: a model runs over whatever scalar type
$\alpha$ you instantiate it with (for example Float, ExecFloat.Binary 8 23, or $\mathbb{R}$). A
“real FFT”
would normally change the scalar type (real $\to$ complex), but TorchLean’s Layer 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 (FloatLib.Floats.ExecFloat.Binary 8 23), selected via --arithmetic=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
ExecFloat.Binary 8 23,sin/cosare implemented deterministically in Lean (seeFloatLib.Floats.Formats.BinaryInterchange.Configured.Transcendentals). 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.
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
Implementation of 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.
The public fftAtDepth operation moves an arbitrary axis here and restores the original axis order.
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 the outer-axis implementation, then swapping back.
If $\mathtt{depth}\ge\operatorname{rank}(s)$, this layer is the identity.