Skip to content

Commit

Permalink
feat: add theorem about nodal on Subgroup (#6495)
Browse files Browse the repository at this point in the history
A lemma about the vanishing polynomial.

Co-authored-by: Pratyush Mishra
  • Loading branch information
BoltonBailey committed Aug 21, 2023
1 parent 782e4d3 commit c6e395d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
24 changes: 24 additions & 0 deletions Mathlib/Data/Polynomial/Degree/Definitions.lean
Expand Up @@ -112,6 +112,7 @@ theorem coeff_natDegree : coeff p (natDegree p) = leadingCoeff p :=
rfl
#align polynomial.coeff_nat_degree Polynomial.coeff_natDegree

@[simp]
theorem degree_eq_bot : degree p = ⊥ ↔ p = 0 :=
fun h => support_eq_empty.1 (Finset.max_eq_bot.1 h), fun h => h.symm ▸ rfl⟩
#align polynomial.degree_eq_bot Polynomial.degree_eq_bot
Expand Down Expand Up @@ -892,6 +893,11 @@ theorem leadingCoeff_add_of_degree_lt (h : degree p < degree q) :
coeff_add, zero_add]
#align polynomial.leading_coeff_add_of_degree_lt Polynomial.leadingCoeff_add_of_degree_lt

theorem leadingCoeff_add_of_degree_lt' (h : degree q < degree p) :
leadingCoeff (p + q) = leadingCoeff p := by
rw [add_comm]
exact leadingCoeff_add_of_degree_lt h

theorem leadingCoeff_add_of_degree_eq (h : degree p = degree q)
(hlc : leadingCoeff p + leadingCoeff q ≠ 0) :
leadingCoeff (p + q) = leadingCoeff p + leadingCoeff q := by
Expand Down Expand Up @@ -1322,6 +1328,24 @@ theorem degree_sub_le_of_le {a b : WithBot ℕ} (hp : degree p ≤ a) (hq : degr
degree (p - q) ≤ max a b :=
(p.degree_sub_le q).trans <| max_le_max ‹_› ‹_›

theorem leadingCoeff_sub_of_degree_lt (h : Polynomial.degree q < Polynomial.degree p) :
(p - q).leadingCoeff = p.leadingCoeff := by
rw [← q.degree_neg] at h
rw [sub_eq_add_neg, leadingCoeff_add_of_degree_lt' h]

theorem leadingCoeff_sub_of_degree_lt' (h : Polynomial.degree p < Polynomial.degree q) :
(p - q).leadingCoeff = -q.leadingCoeff := by
rw [← q.degree_neg] at h
rw [sub_eq_add_neg, leadingCoeff_add_of_degree_lt h, leadingCoeff_neg]

theorem leadingCoeff_sub_of_degree_eq (h : degree p = degree q)
(hlc : leadingCoeff p ≠ leadingCoeff q) :
leadingCoeff (p - q) = leadingCoeff p - leadingCoeff q := by
replace h : degree p = degree (-q) := by rwa [q.degree_neg]
replace hlc : leadingCoeff p + leadingCoeff (-q) ≠ 0 := by
rwa [← sub_ne_zero, sub_eq_add_neg, ← q.leadingCoeff_neg] at hlc
rw [sub_eq_add_neg, leadingCoeff_add_of_degree_eq h hlc, leadingCoeff_neg, sub_eq_add_neg]

theorem natDegree_sub_le (p q : R[X]) : natDegree (p - q) ≤ max (natDegree p) (natDegree q) := by
simpa only [← natDegree_neg q] using natDegree_add_le p (-q)
#align polynomial.nat_degree_sub_le Polynomial.natDegree_sub_le
Expand Down
47 changes: 47 additions & 0 deletions Mathlib/LinearAlgebra/Lagrange.lean
Expand Up @@ -67,6 +67,21 @@ theorem eq_of_degrees_lt_of_eval_finset_eq (degree_f_lt : f.degree < s.card)
rw [← mem_degreeLT]; exact Submodule.sub_mem _ degree_f_lt degree_g_lt
#align polynomial.eq_of_degrees_lt_of_eval_finset_eq Polynomial.eq_of_degrees_lt_of_eval_finset_eq

/--
Two polynomials, with the same degree and leading coefficient, which have the same evaluation
on a set of distinct values with cardinality equal to the degree, are equal.
-/
theorem eq_of_degree_le_of_eval_finset_eq
(h_deg_le : f.degree ≤ s.card)
(h_deg_eq : f.degree = g.degree)
(hlc : f.leadingCoeff = g.leadingCoeff)
(h_eval : ∀ x ∈ s, f.eval x = g.eval x) :
f = g := by
rcases eq_or_ne f 0 with rfl | hf
· rwa [degree_zero, eq_comm, degree_eq_bot, eq_comm] at h_deg_eq
· exact eq_of_degree_sub_lt_of_eval_finset_eq s
(lt_of_lt_of_le (degree_sub_lt h_deg_eq hf hlc) h_deg_le) h_eval

end Finset

section Indexed
Expand Down Expand Up @@ -101,6 +116,17 @@ theorem eq_of_degrees_lt_of_eval_index_eq (hvs : Set.InjOn v s) (degree_f_lt : f
exact Submodule.sub_mem _ degree_f_lt degree_g_lt
#align polynomial.eq_of_degrees_lt_of_eval_index_eq Polynomial.eq_of_degrees_lt_of_eval_index_eq

theorem eq_of_degree_le_of_eval_index_eq (hvs : Set.InjOn v s)
(h_deg_le : f.degree ≤ s.card)
(h_deg_eq : f.degree = g.degree)
(hlc : f.leadingCoeff = g.leadingCoeff)
(h_eval : ∀ i ∈ s, f.eval (v i) = g.eval (v i)) : f = g := by
rcases eq_or_ne f 0 with rfl | hf
· rwa [degree_zero, eq_comm, degree_eq_bot, eq_comm] at h_deg_eq
· exact eq_of_degree_sub_lt_of_eval_index_eq s hvs
(lt_of_lt_of_le (degree_sub_lt h_deg_eq hf hlc) h_deg_le)
h_eval

end Indexed

end Polynomial
Expand Down Expand Up @@ -494,10 +520,14 @@ theorem nodal_empty : nodal ∅ v = 1 := by
rfl
#align lagrange.nodal_empty Lagrange.nodal_empty

@[simp]
theorem degree_nodal : (nodal s v).degree = s.card := by
simp_rw [nodal, degree_prod, degree_X_sub_C, sum_const, Nat.smul_one_eq_coe]
#align lagrange.degree_nodal Lagrange.degree_nodal

theorem nodal_monic : (nodal s v).Monic :=
monic_prod_of_monic s (fun i ↦ X - C (v i)) fun i _ ↦ monic_X_sub_C (v i)

theorem eval_nodal {x : F} : (nodal s v).eval x = ∏ i in s, (x - v i) := by
simp_rw [nodal, eval_prod, eval_sub, eval_X, eval_C]
#align lagrange.eval_nodal Lagrange.eval_nodal
Expand Down Expand Up @@ -620,6 +650,23 @@ theorem eval_interpolate_not_at_node' (hvs : Set.InjOn v s) (hs : s.Nonempty)
simp only [mul_div_mul_left _ _ (eval_nodal_not_at_node hx), Pi.one_apply, mul_one]
#align lagrange.eval_interpolate_not_at_node' Lagrange.eval_interpolate_not_at_node'

/-- The vanishing polynomial on a multiplicative subgroup is of the form X ^ n - 1. -/
@[simp] theorem nodal_subgroup_eq_X_pow_card_sub_one (G : Subgroup Fˣ) [Fintype G] :
nodal (G : Set Fˣ).toFinset ((↑) : Fˣ → F) = X ^ (Fintype.card G) - 1 := by
have h : degree (1 : F[X]) < degree ((X : F[X]) ^ Fintype.card G) := by simp [Fintype.card_pos]
apply eq_of_degree_le_of_eval_index_eq (v := ((↑) : Fˣ → F)) (G : Set Fˣ).toFinset
· exact Set.injOn_of_injective Units.ext _
· simp
· rw [degree_sub_eq_left_of_degree_lt h, degree_nodal, Set.toFinset_card, degree_pow, degree_X,
nsmul_eq_mul, mul_one, Nat.cast_inj]
exact rfl
· rw [nodal_monic, leadingCoeff_sub_of_degree_lt h, monic_X_pow]
· intros i hi
rw [eval_nodal_at_node hi]
replace hi : i ∈ G := by simpa using hi
obtain ⟨g, rfl⟩ : ∃ g : G, g.val = i := ⟨⟨i, hi⟩, rfl⟩
simp [← Units.val_pow_eq_pow_val, ← Subgroup.coe_pow G]

end Nodal

end Lagrange

0 comments on commit c6e395d

Please sign in to comment.