@@ -19,11 +19,20 @@ following proof in https://math.stackexchange.com/a/978145/1277
1919
2020## Main statements
2121
22- * leadingCoeff_le_of_bounded: If `P` is a degree `n` real polynomial and `|P (x)| ≤ 1` for all
23- `|x| ≤ 1` then the leading coefficient of `P` is at most `2 ^ (n-1)`
24- * leadingCoeff_eq_iff_of_bounded: If `P` is a degree `n` polynomial and `|P (x)| ≤ 1` for all
25- `|x| ≤ 1` then the leading coefficient of `P` equals `2 ^ (n-1)` iff `P = T_n`, the `n`'th
26- Chebyshev polynomial
22+ * leadingCoeff_le_of_bounded: If `P` is a real polynomial of degree at most `n` and `|P (x)| ≤ 1`
23+ for all `|x| ≤ 1` then the leading coefficient of `P` is at most `2 ^ (n-1)`
24+ * leadingCoeff_eq_iff_of_bounded: When `n ≥ 2`, equality holds iff `P = T_n`
25+
26+ ## Implementation
27+
28+ By monotonicity of `2 ^ (n-1)`, we can assume that `P` has degree exactly `n`.
29+ Using Lagrange interpolation, we can give a formula for the leading coefficient of `P`
30+ as a linear combination of the values of `P` on the Chebyshev nodes (leadingCoeff_eq_sum_node).
31+ The Chebyshev polynomial `T_n` has value `±1` on the nodes, with the same signs as the
32+ coefficients of the linear combination (leadingCoeff_eq_sum_node_coeff_pos).
33+ Since `|P (x)| ≤ 1` on the nodes, this implies that the leading coefficient of `P` is bounded
34+ by that of `T_n`, which is known to equal `2 ^ (n-1)`.
35+ Moreover, equality holds iff `P` and `T_n` agree on the nodes, which implies that they coincide.
2736-/
2837@[expose] public section
2938namespace Polynomial.Chebyshev
@@ -94,20 +103,22 @@ private lemma negOnePow_mul_le {α : ℝ} {i : ℕ} (hα : α ∈ Set.Icc (-1) 1
94103 rw [abs_mul, abs_neg_one_pow, one_mul]
95104 exact abs_le.mpr hα
96105
97- theorem apply_le_apply_T_real {n : ℕ} {param : ℝ[X] → ℝ} {c : ℕ → ℝ}
98- (hparam : (P : ℝ[X]) → P.degree = n → param P = ∑ i ≤ n, P.eval (node n i) * (c i))
106+ /-- For a polynomial P and coefficient function c, param n c P is a linear combination of
107+ P evaluated at the n'th order Chebyshev nodes, with coefficients taken from c. -/
108+ noncomputable def param (n : ℕ) (c : ℕ → ℝ) (P : ℝ[X]) := ∑ i ≤ n, P.eval (node n i) * (c i)
109+
110+ theorem apply_le_apply_T_real {n : ℕ} {c : ℕ → ℝ}
99111 (hcnonneg : ∀ i ≤ n, 0 ≤ (-1 ) ^ i * (c i))
100- {P : ℝ[X]} (hPdeg : P.degree = n) (hPbnd : ∀ x ∈ Set.Icc (-1 ) 1 , P.eval x ∈ Set.Icc (-1 ) 1 ) :
101- param P ≤ param (T ℝ n) := by
112+ {P : ℝ[X]} (hPbnd : ∀ x ∈ Set.Icc (-1 ) 1 , P.eval x ∈ Set.Icc (-1 ) 1 ) :
113+ param n c P ≤ param n c (T ℝ n) := by
114+ rw [param, param]
102115 wlog! hn : n ≠ 0
103- · rw [hparam P hPdeg, hparam (T ℝ n) (degree_T ℝ n), hn, show Finset.Iic 0 = {0 } by rfl,
104- Nat.cast_zero, T_zero, Finset.sum_singleton, Finset.sum_singleton, node_eq_one,
105- eval_one]
116+ · rw [hn, show Finset.Iic 0 = {0 } by rfl, Nat.cast_zero, T_zero,
117+ Finset.sum_singleton, Finset.sum_singleton, node_eq_one, eval_one]
106118 exact mul_le_mul_of_nonneg_right (hPbnd 1 (by simp) |> Set.mem_Icc.mp).2
107119 (le_of_le_of_eq (hcnonneg 0 n.zero_le) (one_mul _))
108120 calc
109- param P = ∑ i ≤ n, P.eval (node n i) * (c i) := hparam P hPdeg
110- _ ≤ ∑ i ≤ n, (T ℝ n).eval (node n i) * (c i) := by
121+ ∑ i ≤ n, P.eval (node n i) * (c i) ≤ ∑ i ≤ n, (T ℝ n).eval (node n i) * (c i) := by
111122 refine Finset.sum_le_sum (fun i hi => ?_)
112123 calc
113124 P.eval (node n i) * (c i) =
@@ -118,18 +129,16 @@ theorem apply_le_apply_T_real {n : ℕ} {param : ℝ[X] → ℝ} {c : ℕ →
118129 (hcnonneg i (Finset.mem_Iic.mp hi))
119130 _ = (T ℝ n).eval (node n i) * (c i) := by
120131 rw [eval_T_real_node hn, one_mul]
121- _ = param (T ℝ n) := (hparam (T ℝ n) (degree_T ℝ n)).symm
122132
123- theorem apply_eq_apply_T_real_iff {n : ℕ} {param : ℝ[X] → ℝ} {c : ℕ → ℝ}
124- (hparam : (P : ℝ[X]) → P.degree = n → param P = ∑ i ≤ n, P.eval (node n i) * (c i))
133+ theorem apply_eq_apply_T_real_iff {n : ℕ} {c : ℕ → ℝ}
125134 (hcpos : ∀ i ≤ n, 0 < (-1 ) ^ i * (c i))
126135 {P : ℝ[X]} (hPdeg : P.degree = n) (hPbnd : ∀ x ∈ Set.Icc (-1 ) 1 , P.eval x ∈ Set.Icc (-1 ) 1 ) :
127- (param P = param (T ℝ n)) ↔ P = T ℝ n := by
136+ (param n c P = param n c (T ℝ n)) ↔ P = T ℝ n := by
128137 refine ⟨fun h => ?_, by intro h; rw [h]⟩
138+ rw [param, param] at h
129139 wlog! hn : n ≠ 0
130- · rw [hparam P hPdeg, hparam (T ℝ n) (degree_T ℝ n), hn, show Finset.Iic 0 = {0 } by rfl,
131- Nat.cast_zero, T_zero, Finset.sum_singleton, Finset.sum_singleton, node_eq_one,
132- eval_one, one_mul] at h
140+ · rw [hn, show Finset.Iic 0 = {0 } by rfl, Nat.cast_zero, T_zero, Finset.sum_singleton,
141+ Finset.sum_singleton, node_eq_one, eval_one, one_mul] at h
133142 rw [hn, Nat.cast_zero] at hPdeg
134143 rw [hn, Nat.cast_zero, T_zero]
135144 have eval_P_one : P.eval 1 = 1 :=
@@ -142,7 +151,6 @@ theorem apply_eq_apply_T_real_iff {n : ℕ} {param : ℝ[X] → ℝ} {c : ℕ
142151 · rw [degree_T, Int.natAbs_natCast, Nat.cast_lt,
143152 Finset.card_image_of_injOn (strictAntiOn_node n).injOn,
144153 Finset.card_range, Nat.lt_succ_iff]
145- rw [hparam P hPdeg, hparam (T ℝ n) (degree_T ℝ n)] at h
146154 replace h := ge_of_eq h
147155 contrapose! h
148156 obtain ⟨x, hx, hPx⟩ := h
@@ -162,31 +170,62 @@ theorem apply_eq_apply_T_real_iff {n : ℕ} {param : ℝ[X] → ℝ} {c : ℕ
162170 have := ne_of_lt (hcpos i (Finset.mem_Iic.mp hi))
163171 grind => ring
164172
165- theorem leadingCoeff_eq_sum_node (n : ℕ) (P : ℝ[X]) (hP : P.degree = n) :
166- P.leadingCoeff = ∑ i ≤ n, (P.eval (node n i)) *
167- (∏ j ∈ (Finset.range (n + 1 )).erase i, (node n i - node n j))⁻¹ := by
173+ /-- Coefficients use to reproduce the leading coefficient of a polynomial given its values on the
174+ Chebyshev nodes. -/
175+ private noncomputable def leadingCoeff_c (n i : ℕ) :=
176+ (∏ j ∈ (Finset.range (n + 1 )).erase i, (node n i - node n j))⁻¹
177+
178+ private theorem leadingCoeff_eq_sum_node {n : ℕ} {P : ℝ[X]} (hP : P.degree = n) :
179+ param n (leadingCoeff_c n) P = P.leadingCoeff := by
180+ simp_rw [param, leadingCoeff_c]
168181 rw [Lagrange.leadingCoeff_eq_sum (strictAntiOn_node n).injOn (by simp [hP]),
169182 show Finset.range (n + 1 ) = Finset.Iic n by grind]
170183 rfl
171184
172- theorem leadingCoeff_eq_sum_node_coeff_pos {n i : ℕ} (hi : i ≤ n) :
173- 0 < (-1 ) ^ i *
174- (∏ j ∈ (Finset.range (n + 1 )).erase i, (node n i - node n j))⁻¹ := by
185+ private theorem leadingCoeff_eq_sum_node_coeff_pos {n i : ℕ} (hi : i ≤ n) :
186+ 0 < (-1 ) ^ i * leadingCoeff_c n i := by
175187 have := inv_pos_of_pos <| zero_lt_prod_node_sub_node hi
176188 rwa [mul_inv, ← inv_pow, inv_neg_one] at this
177189
178- theorem leadingCoeff_le_of_bounded {n : ℕ} {P : ℝ[X]}
190+ theorem leadingCoeff_le_of_bounded' {n : ℕ} {P : ℝ[X]}
179191 (hPdeg : P.degree = n) (hPbnd : ∀ x ∈ Set.Icc (-1 ) 1 , P.eval x ∈ Set.Icc (-1 ) 1 ) :
180192 P.leadingCoeff ≤ 2 ^ (n - 1 ) := by
181- convert apply_le_apply_T_real (leadingCoeff_eq_sum_node n)
182- (fun i hi => le_of_lt <| leadingCoeff_eq_sum_node_coeff_pos hi) hPdeg hPbnd
183- simp
193+ rw [← leadingCoeff_eq_sum_node hPdeg]
194+ convert apply_le_apply_T_real
195+ (fun i hi => le_of_lt <| leadingCoeff_eq_sum_node_coeff_pos hi) hPbnd
196+ simp [leadingCoeff_eq_sum_node]
184197
185- theorem leadingCoeff_eq_iff_of_bounded {n : ℕ} {P : ℝ[X]}
198+ theorem leadingCoeff_le_of_bounded {n : ℕ} {P : ℝ[X]}
199+ (hPdeg : P.degree ≤ n) (hPbnd : ∀ x ∈ Set.Icc (-1 ) 1 , P.eval x ∈ Set.Icc (-1 ) 1 ) :
200+ P.leadingCoeff ≤ 2 ^ (n - 1 ) := by
201+ by_cases P = 0
202+ case pos hP => simp [hP]
203+ case neg hP =>
204+ lift P.degree to ℕ using degree_ne_bot.mpr hP with d hd
205+ replace hPdeg : d ≤ n := (WithBot.coe_le rfl).mp hPdeg
206+ calc P.leadingCoeff ≤ 2 ^ (d - 1 ) := leadingCoeff_le_of_bounded' hd.symm hPbnd
207+ _ ≤ 2 ^ (n - 1 ) := by gcongr; norm_num
208+
209+ theorem leadingCoeff_eq_iff_of_bounded' {n : ℕ} {P : ℝ[X]}
186210 (hPdeg : P.degree = n) (hPbnd : ∀ x ∈ Set.Icc (-1 ) 1 , P.eval x ∈ Set.Icc (-1 ) 1 ) :
187211 P.leadingCoeff = 2 ^ (n - 1 ) ↔ P = T ℝ n := by
188- convert apply_eq_apply_T_real_iff (leadingCoeff_eq_sum_node n)
189- (fun i hi => leadingCoeff_eq_sum_node_coeff_pos hi) hPdeg hPbnd
190- simp
212+ rw [← leadingCoeff_eq_sum_node hPdeg]
213+ convert apply_eq_apply_T_real_iff (fun i hi => leadingCoeff_eq_sum_node_coeff_pos hi) hPdeg hPbnd
214+ simp [leadingCoeff_eq_sum_node]
215+
216+ theorem leadingCoeff_eq_iff_of_bounded {n : ℕ} {P : ℝ[X]} (hn : 2 ≤ n)
217+ (hPdeg : P.degree ≤ n) (hPbnd : ∀ x ∈ Set.Icc (-1 ) 1 , P.eval x ∈ Set.Icc (-1 ) 1 ) :
218+ P.leadingCoeff = 2 ^ (n - 1 ) ↔ P = T ℝ n := by
219+ refine ⟨fun hP => ?_, fun hP => by simp [hP]⟩
220+ lift P.degree to ℕ with d hd
221+ · contrapose! hP
222+ rw [degree_eq_bot.mp hP, leadingCoeff_zero]
223+ positivity
224+ suffices n ≤ P.degree from (leadingCoeff_eq_iff_of_bounded' (by grind) hPbnd).mp hP
225+ replace hP := ge_of_eq hP
226+ contrapose! hP
227+ have : d - 1 < n - 1 := by grind [Nat.cast_withBot, WithBot.coe_le_coe, WithBot.coe_lt_coe]
228+ calc P.leadingCoeff ≤ 2 ^ (d - 1 ) := leadingCoeff_le_of_bounded' hd.symm hPbnd
229+ _ < 2 ^ (n - 1 ) := by gcongr; norm_num
191230
192231end Polynomial.Chebyshev
0 commit comments