@@ -1419,7 +1419,7 @@ def toCoeffsVec (ℓ : Nat) : L⦃<2^ℓ⦄[X] →ₗ[L] CoeffVecSpace L ℓ whe
14191419non-zero diagonal entries are linearly independent. -/
14201420lemma linearIndependent_rows_of_lower_triangular_ne_zero_diag
14211421 {n : ℕ} {R : Type *} [Field R] (A : Matrix (Fin n) (Fin n) R)
1422- (h_lower_triangular: A.BlockTriangular ⇑OrderDual.toDual) (h_diag: ∀ i, A i i ≠ 0 ) :
1422+ (h_lower_triangular : A.BlockTriangular ⇑OrderDual.toDual) (h_diag : ∀ i, A i i ≠ 0 ) :
14231423 LinearIndependent R A := by -- This follows from the fact that such a matrix is invertible
14241424 -- because its determinant is non-zero.
14251425 have h_det : A.det ≠ 0 := by
@@ -1428,12 +1428,65 @@ lemma linearIndependent_rows_of_lower_triangular_ne_zero_diag
14281428 intro i _; exact h_diag i
14291429 exact Matrix.linearIndependent_rows_of_det_ne_zero (A := A) h_det
14301430
1431+ /-- The change-of-basis matrix from the novel basis to the monomial basis.
1432+ Aⱼᵢ = coeff of Xⁱ in novel basis vector 𝕏ⱼ. novel_coeffs * A = monomial_coeffs -/
14311433noncomputable def changeOfBasisMatrix (hF₂ : Fintype.card 𝔽q = 2 )
14321434 (hβ_lin_indep : LinearIndependent 𝔽q β)
14331435 (ℓ : Nat) (h_ℓ : ℓ ≤ r) : Matrix (Fin (2 ^ℓ)) (Fin (2 ^ℓ)) L :=
14341436 fun j i => (toCoeffsVec (L := L) (ℓ := ℓ) (
14351437 basisVectors 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ j)) i
14361438
1439+ theorem changeOfBasisMatrix_lower_triangular (hF₂ : Fintype.card 𝔽q = 2 )
1440+ (hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1441+ (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ).BlockTriangular ⇑OrderDual.toDual := by
1442+ intro i j hij
1443+ dsimp only [toCoeffsVec, basisVectors, LinearMap.coe_mk, AddHom.coe_mk, changeOfBasisMatrix]
1444+ -- ⊢ (Xⱼ β ℓ ↑i).coeff ↑j = 0
1445+ have deg_X : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i :=
1446+ degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1447+ have h_i_lt_j : i < j := by
1448+ simp only [OrderDual.toDual_lt_toDual] at hij
1449+ exact hij
1450+ have h_res: (Xⱼ 𝔽q β ℓ h_ℓ i).coeff j = 0 := by
1451+ apply coeff_eq_zero_of_natDegree_lt -- we don't use coeff_eq_zero_of_degree_lt
1452+ -- because p.natDegree returns a value of type ℕ instead of WithBot ℕ as in p.degree
1453+ rw [natDegree_eq_of_degree_eq_some (degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i)]
1454+ norm_cast -- auto resolve via h_i_lt_j
1455+ exact h_res
1456+
1457+ theorem changeOfBasisMatrix_diag_ne_zero (hF₂ : Fintype.card 𝔽q = 2 )
1458+ (hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1459+ (∀ i, (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ) i i ≠ 0 ) := by
1460+ intro i
1461+ dsimp [changeOfBasisMatrix, toCoeffsVec, basisVectors]
1462+ have h_deg : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i := degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1463+ apply coeff_ne_zero_of_eq_degree
1464+ norm_cast
1465+
1466+ /-- The determinant of the change-of-basis matrix is non-zero. -/
1467+ theorem changeOfBasisMatrix_det_ne_zero (hF₂ : Fintype.card 𝔽q = 2 )
1468+ (hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1469+ (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ).det ≠ 0 := by
1470+ let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1471+ -- Use the fact that A is lower-triangular with non-zero diagonal
1472+ rw [Matrix.det_of_lowerTriangular A]
1473+ · -- The determinant of a lower-triangular matrix is
1474+ -- the product of diagonal entries: ⊢ ∏ i, A i i ≠ 0
1475+ let res := changeOfBasisMatrix_diag_ne_zero 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1476+ exact prod_ne_zero_iff.mpr fun a a_1 ↦ res a
1477+ · -- A is lower-triangular
1478+ exact changeOfBasisMatrix_lower_triangular 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1479+
1480+ /-- The change-of-basis matrix is invertible, this is required by the proofs
1481+ of inversion between monomial and novel polynomial basis coefficients. -/
1482+ noncomputable instance changeOfBasisMatrix_invertible (hF₂ : Fintype.card 𝔽q = 2 )
1483+ (hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
1484+ Invertible (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ) := by
1485+ let h_A_invertible: Invertible (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ) := by
1486+ refine (changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ).invertibleOfIsUnitDet ?_
1487+ (expose_names; exact Ne.isUnit (changeOfBasisMatrix_det_ne_zero 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ))
1488+ exact h_A_invertible
1489+
14371490/--
14381491The coefficient vectors of the novel basis polynomials are linearly independent.
14391492This is proven by showing that the change-of-basis matrix to the monomial basis
@@ -1448,29 +1501,9 @@ lemma coeff_vectors_linear_independent (hF₂ : Fintype.card 𝔽q = 2)
14481501 -- Apply the lemma about triangular matrices.
14491502 apply linearIndependent_rows_of_lower_triangular_ne_zero_diag A
14501503 · -- ⊢ A.BlockTriangular ⇑OrderDual.toDual => Prove the matrix A is lower-triangular.
1451- intro i j hij
1452- dsimp only [toCoeffsVec, basisVectors, LinearMap.coe_mk, AddHom.coe_mk, A]
1453- -- ⊢ (Xⱼ β ℓ ↑i).coeff ↑j = 0
1454- have deg_X : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i :=
1455- degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1456- have h_i_lt_j : i < j := by
1457- simp only [OrderDual.toDual_lt_toDual] at hij
1458- exact hij
1459- have h_res: (Xⱼ 𝔽q β ℓ h_ℓ i).coeff j = 0 := by
1460- apply coeff_eq_zero_of_natDegree_lt -- we don't use coeff_eq_zero_of_degree_lt
1461- -- because p.natDegree returns a value of type ℕ instead of WithBot ℕ as in p.degree
1462- rw [natDegree_eq_of_degree_eq_some (degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i)]
1463- norm_cast -- auto resolve via h_i_lt_j
1464- exact h_res
1504+ exact changeOfBasisMatrix_lower_triangular 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
14651505 · -- ⊢ ∀ (i : Fin (2 ^ ℓ)), A i i ≠ 0 => All diagonal entries are non-zero.
1466- intro i
1467- dsimp [A, toCoeffsVec, basisVectors]
1468- -- `A i i` is the `i`-th (also the leading) coefficient of `Xⱼ`, which is non-zero.
1469- have h_deg : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i := degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1470- have h_natDegree : (Xⱼ 𝔽q β ℓ h_ℓ i).natDegree = i := natDegree_eq_of_degree_eq_some h_deg
1471- have deg_X : (Xⱼ 𝔽q β ℓ h_ℓ i).degree = i := degree_Xⱼ 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ i
1472- apply coeff_ne_zero_of_eq_degree -- (hn : degree p = n) : coeff p n ≠ 0
1473- norm_cast
1506+ exact fun i ↦ changeOfBasisMatrix_diag_ne_zero 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ i
14741507
14751508/-- The basis vectors are linearly independent over `L`. -/
14761509theorem basisVectors_linear_independent (hF₂ : Fintype.card 𝔽q = 2 ) (ℓ : Nat) (h_ℓ : ℓ ≤ r) :
@@ -1524,4 +1557,63 @@ theorem novelPolynomialBasis_is_basisVectors (hF₂ : Fintype.card 𝔽q = 2) (
15241557 = basisVectors 𝔽q β hβ_lin_indep hF₂ ℓ h_ℓ := by
15251558 simp only [novelPolynomialBasis, Basis.coe_mk]
15261559
1560+ /-- Convert monomial coefficients to novel polynomial basis coefficients.
1561+ Using row vectors: n = m * A⁻¹.
1562+ -/
1563+ noncomputable def monomialToNovelCoeffs (hF₂ : Fintype.card 𝔽q = 2 )
1564+ (hβ_lin_indep : LinearIndependent 𝔽q β)
1565+ (ℓ : ℕ) (h_ℓ : ℓ ≤ r) (monomial_coeffs : Fin (2 ^ ℓ) → L) : Fin (2 ^ℓ) → L :=
1566+ let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1567+ -- We need A to be invertible to use A⁻¹. This is implicitly handled by Lean
1568+ -- when A⁻¹ is used, but we will rely on the determinant proof later.
1569+ Matrix.vecMul monomial_coeffs A⁻¹
1570+
1571+ /-- Convert novel polynomial basis coefficients to monomial coefficients.
1572+ Using row vectors: m = n * A.
1573+ -/
1574+ noncomputable def novelToMonomialCoeffs (hF₂ : Fintype.card 𝔽q = 2 )
1575+ (hβ_lin_indep : LinearIndependent 𝔽q β)
1576+ (ℓ : ℕ) (h_ℓ : ℓ ≤ r) (novel_coeffs : Fin (2 ^ ℓ) → L) : Fin (2 ^ℓ) → L :=
1577+ let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1578+ Matrix.vecMul novel_coeffs A
1579+
1580+ /-- The conversion functions are inverses of each other. (Monomial -> Novel -> Monomial) -/
1581+ theorem monomialToNovel_novelToMonomial_inverse (hF₂ : Fintype.card 𝔽q = 2 )
1582+ (hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : ℕ) (h_ℓ : ℓ ≤ r) :
1583+ ∀ coeffs : Fin (2 ^ℓ) → L,
1584+ novelToMonomialCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1585+ (monomialToNovelCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ coeffs) = coeffs := by
1586+ intro coeffs
1587+ -- Unfold the definitions and the let bindings.
1588+ unfold monomialToNovelCoeffs novelToMonomialCoeffs
1589+ dsimp only
1590+ -- Let A be the change of basis matrix.
1591+ let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1592+ -- Goal: (coeffs * A⁻¹) * A = coeffs
1593+ -- Use associativity of vecMul: (v * M) * N = v * (M * N).
1594+ rw [Matrix.vecMul_vecMul]
1595+ -- Goal: coeffs * (A⁻¹ * A) = coeffs, We need A⁻¹ * A = I. This requires det(A) ≠ 0.
1596+ -- Use Matrix.nonsing_inv_mul (A⁻¹ * A = I).
1597+ rw [Matrix.nonsing_inv_mul A (Matrix.isUnit_det_of_invertible A)]
1598+ -- Goal: coeffs * 1 = coeffs
1599+ rw [Matrix.vecMul_one]
1600+
1601+ /-- The conversion functions are inverses of each other. (Novel -> Monomial -> Novel) -/
1602+ theorem novelToMonomial_monomialToNovel_inverse (hF₂ : Fintype.card 𝔽q = 2 )
1603+ (hβ_lin_indep : LinearIndependent 𝔽q β) (ℓ : ℕ) (h_ℓ : ℓ ≤ r) :
1604+ ∀ coeffs : Fin (2 ^ℓ) → L,
1605+ monomialToNovelCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1606+ (novelToMonomialCoeffs 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ coeffs) = coeffs := by
1607+ intro coeffs
1608+ -- Unfold the definitions and the let bindings.
1609+ unfold novelToMonomialCoeffs monomialToNovelCoeffs
1610+ dsimp only
1611+ let A := changeOfBasisMatrix 𝔽q β hF₂ hβ_lin_indep ℓ h_ℓ
1612+ -- Goal: (coeffs * A) * A⁻¹ = coeffs
1613+ rw [Matrix.vecMul_vecMul]
1614+ -- Goal: coeffs * (A * A⁻¹) = coeffs, we need A * A⁻¹ = I.
1615+ rw [Matrix.mul_nonsing_inv A (Matrix.isUnit_det_of_invertible A)]
1616+ -- Goal: coeffs * 1 = coeffs
1617+ rw [Matrix.vecMul_one]
1618+
15271619end AdditiveNTT
0 commit comments