Pith. sign in

IndisputableMonolith.Constants.GapWeight.Projection

IndisputableMonolith/Constants/GapWeight/Projection.lean · 183 lines · 17 declarations

show as:
view math explainer →

open module explainer GitHub source

Explainer status: pending

   1import Mathlib
   2import IndisputableMonolith.Constants
   3import IndisputableMonolith.Constants.GapWeight.Formula
   4import IndisputableMonolith.Spectral.DFT8
   5
   6namespace IndisputableMonolith
   7namespace Constants
   8namespace GapWeight
   9
  10open scoped BigOperators
  11
  12open Complex
  13open IndisputableMonolith.Spectral
  14
  15/-!
  16# GapWeight.Projection — closing the “weights + normalization” ambiguity
  17
  18This module defines, explicitly, the two pieces that were historically left implicit:
  19
  201) **Why the geometric weights have a `sin²(πk/8)` factor.**
  21   This is the spectral (eigenvalue) weight induced by the *discrete derivative / Laplacian*
  22   on the 8-tick cyclic shift. In DFT language, it is forced by shift-diagonalization.
  23
  242) **Why the normalization uses a factor of `64`.**
  25   `64 = 8×8` is the cardinality of the fundamental RS interface cell when we take:
  26   - 8 ticks (the octave clock), and
  27   - 8 spatial vertices (the Q₃ cell has 8 vertices).
  28   The normalization converts a scale-invariant *fraction* into a per-cell integrated weight.
  29
  30This is claim hygiene: we’re making the operator/measure choice explicit, so there is no
  31hidden degree of freedom.
  32-/
  33
  34/-! ## Canonical counts (no ambiguity) -/
  35
  36/-- Number of ticks in the fundamental octave. -/
  37@[simp] def N_ticks : ℕ := Fintype.card (Fin 8)
  38
  39@[simp] theorem N_ticks_eq : N_ticks = 8 := by
  40  decide
  41
  42/-- Number of spatial vertices in a `Q₃` cell (8 vertices). We model this as `Fin 8`. -/
  43@[simp] def N_vertices : ℕ := Fintype.card (Fin 8)
  44
  45@[simp] theorem N_vertices_eq : N_vertices = 8 := by
  46  decide
  47
  48/-- Size of the fundamental “cell index” set: ticks × vertices = 8×8 = 64. -/
  49@[simp] def N_cell : ℕ := Fintype.card (Fin 8 × Fin 8)
  50
  51@[simp] theorem N_cell_eq : N_cell = 64 := by
  52  -- card (Fin 8 × Fin 8) = 8 * 8
  53  decide
  54
  55/-- The projection scaling used to convert a dimensionless fraction into a per-cell weight. -/
  56@[simp] def projectionScale : ℝ := (N_cell : ℝ)
  57
  58@[simp] theorem projectionScale_eq : projectionScale = 64 := by
  59  simp [projectionScale, N_cell_eq]
  60
  61/-! ## A canonical normalization denominator -/
  62
  63/-- Total DFT energy of the φ-pattern (Parseval denominator). -/
  64noncomputable def phiDFTEnergyTotal : ℝ :=
  65  Finset.univ.sum fun k : Fin 8 => phiDFTAmplitude k
  66
  67lemma phiDFTEnergyTotal_nonneg : 0 ≤ phiDFTEnergyTotal := by
  68  unfold phiDFTEnergyTotal
  69  apply Finset.sum_nonneg
  70  intro k _
  71  exact phiDFTAmplitude_nonneg k
  72
  73/-! ## The explicit projection operator (minimal actionable closure) -/
  74
  75/-- **Projection weight** of the φ-pattern onto the 8-tick basis:
  76
  77`projectionScale * (rawWeightedNeutralEnergy / totalEnergy)`.
  78
  79This makes the normalization and measure choice explicit. -/
  80noncomputable def w8_projected : ℝ :=
  81  projectionScale * (w8_dft_candidate / phiDFTEnergyTotal)
  82
  83lemma w8_projected_nonneg : 0 ≤ w8_projected := by
  84  unfold w8_projected
  85  have hscale : 0 ≤ projectionScale := by simp [projectionScale]
  86  have hnum : 0 ≤ w8_dft_candidate := le_of_lt w8_dft_candidate_pos
  87  have hden : 0 ≤ phiDFTEnergyTotal := phiDFTEnergyTotal_nonneg
  88  -- If total energy is 0, then the ratio is 0 (since numerator is 0 as well). Otherwise nonneg by div_nonneg.
  89  by_cases hE : phiDFTEnergyTotal = 0
  90  · simp [hE, hnum, hscale]
  91  · have hdiv : 0 ≤ w8_dft_candidate / phiDFTEnergyTotal := div_nonneg hnum (le_of_lt (lt_of_le_of_ne' hden hE))
  92    exact mul_nonneg hscale hdiv
  93
  94/-!
  95## Important note
  96
  97At present, the pipeline constant `Constants.w8_from_eight_tick` is defined in a closed form
  98in `Constants/GapWeight.lean` and evaluates to ≈ 2.49056927545.
  99
 100The operator `w8_projected` above is the *definition-level closure* of what “projection weight”
 101means: it makes explicit the normalization and the 8×8 measure.
 102
 103Proving `w8_projected = Constants.w8_from_eight_tick` inside Lean is a tractable (but nontrivial)
 104algebraic/trigonometric reduction problem and is tracked as a follow-up theorem.
 105-/
 106
 107/-! ## Why `sin²(πk/8)` is canonical (spectral footprint of the 8-tick derivative) -/
 108
 109/-- Discrete one-step difference on the 8-tick cycle: `(S - I)v`. -/
 110def diff8 (v : Fin 8 → ℂ) : Fin 8 → ℂ :=
 111  fun t => cyclic_shift v t - v t
 112
 113/-- Total squared energy of the discrete difference (a canonical local, shift-invariant quadratic form). -/
 114noncomputable def diffEnergy8 (v : Fin 8 → ℂ) : ℝ :=
 115  ∑ t : Fin 8, Complex.normSq (diff8 v t)
 116
 117lemma diffEnergy8_nonneg (v : Fin 8 → ℂ) : 0 ≤ diffEnergy8 v := by
 118  unfold diffEnergy8
 119  exact Finset.sum_nonneg (fun _ _ => Complex.normSq_nonneg _)
 120
 121/-- DFT-8 mode `k` has unit norm (columns are orthonormal). -/
 122lemma dft8_mode_normSq_sum (k : Fin 8) :
 123    (∑ t : Fin 8, Complex.normSq (dft8_mode k t)) = 1 := by
 124  -- ⟨column k, column k⟩ = 1, and ⟨v,v⟩ = ∑ conj(v_t) * v_t = ∑ normSq(v_t).
 125  have hcol := dft8_column_orthonormal k k
 126  have h1 : (∑ t : Fin 8, star (dft8_entry t k) * dft8_entry t k) = (1 : ℂ) := by
 127    simpa using (by simpa using hcol)
 128  -- Rewrite each term `star z * z` as `(normSq z : ℂ)`.
 129  have h1' : (∑ t : Fin 8, ((Complex.normSq (dft8_entry t k) : ℝ) : ℂ)) = (1 : ℂ) := by
 130    simpa [Complex.normSq_eq_conj_mul_self] using h1
 131  -- Pull the cast out of the sum.
 132  have h1'' : ((∑ t : Fin 8, (Complex.normSq (dft8_entry t k) : ℝ)) : ℂ) = (1 : ℂ) := by
 133    simpa [Complex.ofReal_sum] using h1'
 134  -- Back to ℝ, and rewrite `dft8_mode`.
 135  have hreal : (∑ t : Fin 8, (Complex.normSq (dft8_entry t k) : ℝ)) = (1 : ℝ) :=
 136    Complex.ofReal_injective (by simpa using h1'')
 137  simpa [dft8_mode] using hreal
 138
 139/-- Discrete difference energy of a DFT mode is the squared magnitude of its shift eigenvalue minus 1.
 140
 141This is the precise mathematical reason a `sin²(πk/8)` factor appears: it is (up to a fixed factor 4)
 142the spectrum of the 8-tick discrete derivative/Laplacian. -/
 143lemma diffEnergy8_mode (k : Fin 8) :
 144    diffEnergy8 (dft8_mode k) = Complex.normSq (omega8 ^ k.val - 1) := by
 145  unfold diffEnergy8 diff8
 146  -- Use that cyclic_shift (mode k) = ω^k • mode k.
 147  have hshift := dft8_shift_eigenvector k
 148  -- rewrite the difference pointwise
 149  have hpoint : ∀ t : Fin 8, cyclic_shift (dft8_mode k) t - dft8_mode k t =
 150      (omega8 ^ k.val - 1) * dft8_mode k t := by
 151    intro t
 152    have ht := congrArg (fun f => f t) hshift
 153    -- ht : cyclic_shift (dft8_mode k) t = (omega8 ^ k.val) • dft8_mode k t
 154    simp [Pi.smul_apply, smul_eq_mul] at ht
 155    -- subtract and factor
 156    calc
 157      cyclic_shift (dft8_mode k) t - dft8_mode k t
 158          = (omega8 ^ k.val) * dft8_mode k t - dft8_mode k t := by simpa [ht]
 159      _   = (omega8 ^ k.val - 1) * dft8_mode k t := by ring
 160  -- push through normSq and sum
 161  have hns : ∀ t : Fin 8, Complex.normSq (cyclic_shift (dft8_mode k) t - dft8_mode k t) =
 162      Complex.normSq (omega8 ^ k.val - 1) * Complex.normSq (dft8_mode k t) := by
 163    intro t
 164    -- use hpoint and normSq_mul
 165    simp [hpoint t, Complex.normSq_mul]
 166  simp_rw [hns]
 167  -- factor out the constant eigenvalue term
 168  have hfac :
 169      (∑ t : Fin 8, Complex.normSq (omega8 ^ k.val - 1) * Complex.normSq (dft8_mode k t)) =
 170        Complex.normSq (omega8 ^ k.val - 1) * (∑ t : Fin 8, Complex.normSq (dft8_mode k t)) := by
 171    -- `Finset.mul_sum` gives the reverse direction, so we use `.symm`.
 172    simpa using
 173      (Finset.mul_sum
 174        (s := (Finset.univ : Finset (Fin 8)))
 175        (f := fun t : Fin 8 => Complex.normSq (dft8_mode k t))
 176        (a := Complex.normSq (omega8 ^ k.val - 1))).symm
 177  rw [hfac, dft8_mode_normSq_sum]
 178  ring
 179
 180end GapWeight
 181end Constants
 182end IndisputableMonolith
 183

source mirrored from github.com/jonwashburn/shape-of-logic