GNFN = IA closed-form Chinese-remainder merge reverses every sibling split. Reduction and reconstruction are mutual inverses, locally and globally.
In 1978, G. Bruun described a real-coefficient route through the discrete Fourier transform. It was remembered as clever, awkward, and numerically suspect. BFFT asks a different question: what if the factor tree was sound and the local coordinates were standing wrong?
01 / THE OBJECT
BFFT computes the ordinary discrete Fourier transform of a real signal. Its standard output has the familiar bins from DC through Nyquist, and its inverse returns the original samples. The unusual part lies beneath that interface: a normalized form of Bruun’s real factorization, several lawful orders for walking it, and direct access to the native residue coordinates.
That distinction matters. Most users need only a reliable transform. A researcher may also want to pause inside it, retain its two-dimensional intermediate lattice, filter in residue space, follow the difference between decimation-in-frequency and decimation-in-time, or build a transform whose product includes support and timing information. BFFT makes those possibilities branches of one object instead of unrelated post-processing tricks.
BFFT takes Bruun’s recursive real-polynomial factorization, expresses every quadratic leaf in a normalized complex frame, and turns that repaired geometry into a usable forward, inverse, and intermediate-state library.
The implementation showed that the repaired transform worked. On Bruun, Revisited now proves why: every reduction edge has an explicit inverse, every normalized cell has a uniform metric, and terminal evaluation is exactly the ordinary real DFT after one declared permutation.
GNFN = IA closed-form Chinese-remainder merge reverses every sibling split. Reduction and reconstruction are mutual inverses, locally and globally.
eθ = (z − cosθ) / sinθ
eθ2 = −1Each real conjugate-pair quotient becomes an ordinary Euclidean complex line, without requiring complex polynomial arithmetic.
TθTTθ = 2IEvery nontrivial cell is a rotation followed by a Hadamard merge. The angle changes; the energy law does not.
PNBN = DNRReduction commutes with evaluation at the roots. Therefore BFFT is a factorization of the DFT itself, not a numerically similar transform.
BNTBN = NIAfter the standard packing weights, every singular value is √N and the transform condition number is exactly one.
02 / HISTORICAL LINE
Their machine algorithm made the factor-and-reuse strategy standard. It was not the only way to factor a DFT, but it became the dominant vocabulary against which later algorithms were described.
Original paperBruun showed that a DFT could be implemented as a filter bank with fewer coefficients. The real-signal form kept real coefficients through the factor tree and, in Bruun’s accounting, used half as many real multiplications as the classical FFT.
Bruun, “z-transform DFT filters and FFT’s”Sorensen, Jones, Heideman, and Burrus described construction methods across the major FFT families and presented a real split-radix implementation with a lower operation count. Bruun’s branch remained mathematically interesting but did not become the practical default.
Real-Valued Fast Fourier Transform AlgorithmsDuhamel and Vetterli’s tutorial review placed Cooley–Tukey, split-radix, prime-factor, Winograd, and polynomial-factor approaches in one state-of-the-art account. By then the question was no longer whether many FFTs existed, but which arithmetic and implementation structure deserved to survive.
Tutorial reviewFFTW demonstrated that operation count alone does not determine speed on modern processors. Codelets, runtime planning, SIMD, and memory movement became first-class design objects.
The Design and Implementation of FFTW3Steven G. Johnson’s MIT FFT notes presented the Bruun construction directly as a recursive factorization of zN−1 into real quadratic factors whose constants remain real until the final step.
MIT FFT notesThe public BFFT repository began on June 10. The implementation replaced the raw quadratic residue basis with normalized unit-circle frames, completed a matched inverse, added DIT and diagonal walks, and built C, C++, Python, Numba, STFT, BODFT, magnitude, phase, native-layout, and residue-filter interfaces around the same core.
BFFT repository and history03 / BRUUN’S FACTOR TREE
x(z) = Σ x[n]zⁿ
↓ reduce through real factors of zᴺ − 1
z²ᴹ + a zᴹ + 1 with |a| ≤ 2
↓ finish at conjugate roots of unity
X[k] = x(e−2πik/N)
For a real input, conjugate frequency bins contain redundant information. Bruun’s factor tree works with real coefficients until the leaves, aligning the arithmetic with that symmetry rather than running a full complex transform and throwing half of it away.
The familiar raw recurrence uses coefficients such as 2 cos θ inside quadratic residue coordinates. Near particular angles, the basis can become badly conditioned and inverse formulas inherit subtractive cancellation. A numerical defect in those coordinates was easily read as a defect in the factorization itself.
Do not tune the unstable coordinates harder. Replace each local quadratic pair with the same normalized complex plane, so every twiddle is a point on the unit circle and every merge has the same energy law.
04 / THE COORDINATE REPAIR
The normalized butterfly rotates the odd child by (cos θ, sin θ), then combines it with the even child. Rotation preserves the odd pair’s energy; the plus/minus merge doubles total energy uniformly. No direction receives a special scale.
The raw monomial chart (1, z) has κ₂ = cot(θ/2) for 0° < θ ≤ 90°. The normalized chart remains at κ₂ = 1.
(eₐ,eᵦ,oₐ,oᵦ) → (eₐ+r, eᵦ+i, eₐ−r, i−eᵦ)with r = cosθ·oₐ − sinθ·oᵦ and i = sinθ·oₐ + cosθ·oᵦ. The inverse applies the adjoint cell with a factor ½ at each level; across log₂N levels those factors become the ordinary 1/N inverse normalization.
The paper does not claim that silicon has become unnecessary. It proves a narrower and more useful statement: any signed BFFT stage can be lifted to nonnegative rails, gauged into a mass-preserving transport or a convex equilibrium map, and projected back to the exact Fourier observable.
x ↦ (x⁺, x⁻)A signed coordinate becomes two nonnegative rails whose difference is x.
C(M) ≥ 0Positive and negative matrix parts route mass without changing the signed projection.
ΠC(M) = MΠSubtract the rails at the boundary and recover the original stage exactly.
A backward diagonal gauge makes each lifted stage column-stochastic. Total two-rail mass is conserved; equal positive and negative common mode can be removed without altering any Fourier coordinate.
A forward gauge makes the stage row-stochastic. Each output becomes a convex combination, with a unique clamped quadratic-energy equilibrium at the desired transformed state.
Before real folding, every normalized DIP butterfly is a unit phase delay followed by a lossless balanced coupler. The folded form adds only the declared real reflection.
05 / THREE WALKS THROUGH ONE GEOMETRY
Natural-order samples enter. One node angle applies across a whole block, making the interior an isoclinic rotation that widens cleanly across SIMD lanes. Working sets shrink as the walk descends; the native spectrum emerges in Bruun’s residue order and can be packed into standard FFT order.
Best understood as: finish one region, then descend.Small seed blocks enter in bit-reversed block order and merge upward. Angles vary by position rather than node. Standard spectrum order falls out of the walk without a final permutation, exchanging some full-array stage sweeps for a simpler exit.
Best understood as: build local spectra, then merge.The walk resolves one time bit and one frequency bit together. At every level its N scalars form a two-dimensional lattice with a fine-frequency row axis and a fine-time column axis. It can be paused, inspected, aligned, or resumed to the same final Fourier product.
Best understood as: keep time and frequency alive together.06 / SPECIAL BREAKOUT
DIP is not another display made after an FFT. It is an ordering of the transform itself. After stage t, let e = 2t and q = N/e. The state is an e × q finite Zak lattice:
Bt[δ,j] = Σr x[j + rq] e−2πiδr/eRows δ carry the low frequency bits. Columns j carry the low time bits. Coarse frequency survives as phase along a row; coarse time survives as phase down a column.
Stage 0 is the time signal. Stage 8 is the final spectrum. The interior stages are exact transform states, not approximations between the two.
A two-axis lattice translation can align diagonal motion—such as a chirp or a shifted observation—that no frequency-only shift of the final spectrum can express.
A recovered or modified intermediate state can continue through the remaining feed-forward cells. No inverse-to-time and second FFT are required merely to re-enter the transform.
Every stage is a scaled unitary map and stores exactly N complex cells. Adjoints, momentum, and cross-stage comparison therefore operate on known conditioning.
The Zak boundary law turns a leading edge into complete comb rows plus one partial row. That creates an intrinsic route for timing, support, and certified phase-disk selection rather than an endpoint heuristic added afterward.
Half-bin BODFT is the α = ½ case of the same twisted cell family. Finer dyadic offsets can share transport, opening a path toward support-aware and correlated transforms.
07 / THE PUBLIC LIBRARY
import numpy as np
import bfft
x = np.random.randn(1024)
X = bfft.rfft(x) # ordinary bins: 0 … N/2
y = bfft.irfft(X) # returns the real samples
assert np.allclose(y, x)
08 / RECEIPTS AND BOUNDARIES