The dihedral action on the Fourier basis of ℂ[ℤ/N] #
With the characters dftChar k j = stdAddChar (j * k), translation acts diagonally
(transl a (dftChar k) = stdAddChar (-(a * k)) • dftChar k) and inversion swaps k and -k
(inv (dftChar k) = dftChar (-k)). Hence each block k = span {dftChar k, dftChar (-k)} is
invariant under the dihedral group generated by translations and inversion, and it is irreducible
when k ≠ -k. Mathlib has the transform-level statement ZMod.dft_comp_neg; here the statements
are about the characters themselves. The decomposition into the abstract irreducible
representations of the dihedral group is not formalized (Mathlib has no classification of them).
Main results #
inv_dftChar,transl_dftChar: the two operators on the characters.block_dihedral_invariant,block_irreducible: the blocks are invariant, and irreducible fork ≠ -k.selfPaired_eq,selfPaired_iff,selfPaired_odd,selfPaired_even,tritone_selfPaired: the self-paired frequencies ({0, 6}forN = 12;{0, m}forN = 2m).
References #
- C. Marín, The Tonnetz spectrum is the generating triad's Fourier balance profile, Zenodo (2026), doi:10.5281/zenodo.20862821.
The k-th DFT character as a vector on ZMod N: dftChar k j = stdAddChar (j * k).
(The same characters as CycleGraphSpectrum.dftChar.)
Equations
- MusicTheory.InversionDFT.dftChar k j = ZMod.stdAddChar (j * k)
Instances For
T1 — the two operator actions on the DFT basis. #
T2 — the D₁₂-invariant 2-dimensional block. #
Inversion preserves the block (T2). inv maps block k into block k: it swaps the two
spanning characters (dftChar k ↦ dftChar (-k) and dftChar (-k) ↦ dftChar k, using
-(-k) = k), so the whole span is preserved.
The block is D₁₂-invariant (T2 corollary). block k is closed under inversion AND under
every transposition transl a — i.e. under the whole group ⟨T, I⟩ = D₁₂. This is the
block-diagonalization of the dihedral action in the DFT basis.
T3 — the pairing counts over ℤ/12. #
The self-paired classes {k | k = -k} are exactly {0, 6}: the two 1-dim blocks. The remaining
ten classes split into the five pairs {1,11},{2,10},{3,9},{4,8},{5,7}, each a 2-dim block. The
dimension bookkeeping 2·1 + 5·2 = 12 = dim ℂ[ℤ₁₂] is recorded as an example.
The self-paired frequencies for every N. #
selfPaired_eq and the 2·1 + 5·2 = 12 bookkeeping above are the EVEN instance of a statement true
over every ZMod N. The self-paired frequencies {k | k = -k} — the negation fixed points = the
1-dimensional dihedral blocks — and the rest pair into 2-dimensional blocks:
• N ODD : self-paired = {0} (1 one-dim block ; (N−1)/2 two-dim blocks),
• N EVEN : self-paired = {0, N/2} (2 one-dim blocks; (N−2)/2 two-dim blocks — the extra
self-paired frequency is the TRITONE N/2).
The count of 1-dim blocks is gcd(2, N). The structural theorems above (block_dihedral_invariant,
block_irreducible) hold for arbitrary N. The key lemma is Mathlib's ZMod.neg_eq_self_iff.
Even N — two 1-dim blocks, DC and the TRITONE. {k : ZMod N | k = -k} = {0, (m : ZMod N)}
where N = 2m: the only nonzero self-paired frequency is the tritone m = N/2. The n=12 case
{0, 6} (selfPaired_eq) is m = 6.
**The tritone is self-paired in every even universe ** (m : ZMod N) = -(m : ZMod N) when N = 2m: the tritone N/2 is fixed by inversion in every even ℤ_N. This is
the structural reason the tritone keeps recurring.
The conjugate pair {k, −k} #
The orbit conjPair k = {k, −k} of k under negation indexes the dihedral blocks: block k is the
span of dftChar '' conjPair k (block_eq_span_conjPair), of dimension (conjPair k).ncard ∈ {1, 2};
it is a singleton exactly at the self-paired frequencies (conjPair_ncard_*), which for even N are
0 and the tritone N/2 (tritone_selfPaired).
The block is the span of the conjugate pair. block k = span ℂ (dftChar '' conjPair k): the dihedral block is literally the span of the two characters indexed by
the conjugate pair. So conjPair k IS the block index.
Self-paired ⟹ the block is 1-dimensional. When k = -k the conjugate pair collapses to
a singleton, (conjPair k).ncard = 1: the two fixed frequencies {0, N/2} are the 1-dim blocks.
Irreducibility of the 2-dim blocks (eigenvalue separation). #
For k ≠ -k the block block k is an IRREDUCIBLE ⟨T, I⟩ = D₁₂ representation: it has no proper
nonzero subspace invariant under both inv and all transl a. The mechanism is eigenvalue
separation — at a = 1 the two transl 1 eigenvalues stdAddChar(-k) and stdAddChar k are
DISTINCT iff k ≠ -k, so the only transl-invariant lines are the two coordinate axes, which inv
swaps. Standard 2-dim-dihedral-irrep representation theory; here for this concrete
DFT block.
T-next-1 — eigenvalue apartness. #
Eigenvalue apartness (T-next-1). For k ≠ -k the two transl 1 eigenvalues are distinct:
stdAddChar k ≠ stdAddChar (-k). Immediate from injectivity of the standard additive character
(ZMod.injective_stdAddChar).
The non-self-paired ℤ/12 frequencies (T-next-1, ZMod face). Over ℤ/12, k ∉ {0,6} is
exactly the apartness hypothesis k ≠ -k (contrapositive of selfPaired_eq).
T-next-2 — pair independence + operator linearity. #
dftChar k 1 = stdAddChar k.
Pair independence (T-next-2). For k ≠ -k the two DFT characters dftChar k, dftChar (-k)
are ℂ-linearly independent: a vanishing combination c • dftChar k + d • dftChar (-k) = 0 forces
c = d = 0. Proof: evaluate at x = 0 (gives c + d = 0) and at x = 1 (gives
c·stdAddChar k + d·stdAddChar(-k) = 0); the 2×2 system has determinant
stdAddChar(-k) − stdAddChar k ≠ 0 by dftChar_apart.
T-next-3 — concrete irreducibility (eigenvalue separation). #
Helper: the eigenvalue-separation vector. For w₀ = c • dftChar k + d • dftChar (-k),
transl 1 w₀ - stdAddChar k • w₀ = (c * (stdAddChar (-k) - stdAddChar k)) • dftChar k.
The dftChar (-k) component cancels because transl 1 acts on it by stdAddChar k — the same
scalar we subtract. This is the algebra that isolates the k-eigenvector.
Concrete irreducibility of the 2-dim block (T-next-3, THE PRIZE). For k ≠ -k, any subspace
W ≤ block k invariant under inversion inv and all transpositions transl a is either ⊥ or
all of block k. So block k is an IRREDUCIBLE ⟨T, I⟩ = D₁₂ representation. The proof is
eigenvalue separation: a nonzero w₀ ∈ W, written c • dftChar k + d • dftChar (-k), yields via
eigen_sep the vector u = c·(stdAddChar(-k) − stdAddChar k) • dftChar k ∈ W; when c ≠ 0 the
scalar is nonzero (apartness) so dftChar k ∈ W, when c = 0 then dftChar (-k) ∈ W directly;
inv supplies the partner, hence block k ≤ W, and le_antisymm finishes.
Not formalized #
The packaging of block k as a simple module over MonoidAlgebra ℂ (DihedralGroup 6), its
isomorphism with an abstract irreducible representation, and the isotypic decomposition
ℂ[ℤ₁₂] = ⊕ block need a classification of the irreducible representations of the dihedral group,
which Mathlib does not have.
Other equal temperaments — the block census for arbitrary N-TET, for free. #
Every theorem above is generic over `{N : ℕ} [NeZero N]`, so the dihedral block decomposition holds
in ANY equal temperament, instantiated with no extra proof. For the famous microtonal systems 19-, 31-,
53-TET (all odd) the ONLY self-paired frequency is the DC term — there is NO tritone, and `gcd(2,N)=1`
gives a single 1-dimensional block, the remaining `(N-1)/2` frequencies pairing into 2-dimensional
irreducible blocks (`block_irreducible`, generic in N). For an even temperament such as 24-TET (quarter
tones) the tritone reappears at `N/2 = 12`, giving two 1-dim blocks. The proof assistant supplies each
instance by feeding `N` to the same generic theorem — no per-system work.