@@ -3,10 +3,7 @@ Copyright (c) 2020 Anne Baanen. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Anne Baanen, Devon Tuma
55-/
6- import Mathlib.Algebra.GroupWithZero.NonZeroDivisors
7- import Mathlib.Algebra.Polynomial.AlgebraMap
8- import Mathlib.RingTheory.Coprime.Basic
9- import Mathlib.Tactic.AdaptationNote
6+ import Mathlib.Algebra.Polynomial.Factors
107
118/-!
129# Scaling the roots of a polynomial
@@ -78,8 +75,13 @@ theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree
7875theorem natDegree_scaleRoots (p : R[X]) (s : R) : natDegree (scaleRoots p s) = natDegree p := by
7976 simp only [natDegree, degree_scaleRoots]
8077
78+ @[simp]
79+ lemma leadingCoeff_scaleRoots (p : R[X]) (r : R) :
80+ (p.scaleRoots r).leadingCoeff = p.leadingCoeff := by
81+ rw [leadingCoeff, natDegree_scaleRoots, coeff_scaleRoots_natDegree]
82+
8183theorem monic_scaleRoots_iff {p : R[X]} (s : R) : Monic (scaleRoots p s) ↔ Monic p := by
82- simp only [Monic, leadingCoeff, natDegree_scaleRoots, coeff_scaleRoots_natDegree ]
84+ simp only [Monic, leadingCoeff_scaleRoots ]
8385
8486theorem map_scaleRoots (p : R[X]) (x : R) (f : R →+* S) (h : f p.leadingCoeff ≠ 0 ) :
8587 (p.scaleRoots x).map f = (p.map f).scaleRoots (f x) := by
@@ -110,6 +112,11 @@ lemma scaleRoots_zero (p : R[X]) :
110112lemma one_scaleRoots (r : R) :
111113 (1 : R[X]).scaleRoots r = 1 := by ext; simp
112114
115+ @[simp]
116+ lemma X_add_C_scaleRoots (r s : R) : (X + C r).scaleRoots s = (X + C (r * s)) := by
117+ nontriviality R
118+ ext (_|_|i) <;> simp
119+
113120end Semiring
114121
115122section CommSemiring
@@ -143,6 +150,10 @@ theorem scaleRoots_eval₂_mul {p : S[X]} (f : S →+* R) (r : R) (s : S) :
143150theorem scaleRoots_eval₂_eq_zero {p : S[X]} (f : S →+* R) {r : R} {s : S} (hr : eval₂ f r p = 0 ) :
144151 eval₂ f (f s * r) (scaleRoots p s) = 0 := by rw [scaleRoots_eval₂_mul, hr, mul_zero]
145152
153+ lemma scaleRoots_eval_mul (p : R[X]) (r s : R) :
154+ eval (s * r) (p.scaleRoots s) = s ^ p.natDegree * eval r p :=
155+ scaleRoots_eval₂_mul _ _ _
156+
146157theorem scaleRoots_aeval_eq_zero [Algebra R A] {p : R[X]} {a : A} {r : R} (ha : aeval a p = 0 ) :
147158 aeval (algebraMap R A r * a) (scaleRoots p r) = 0 := by
148159 rw [aeval_def, scaleRoots_eval₂_mul_of_commute, ← aeval_def, ha, mul_zero]
@@ -206,6 +217,24 @@ lemma mul_scaleRoots_of_noZeroDivisors (p q : R[X]) (r : R) [NoZeroDivisors R] :
206217 apply mul_scaleRoots'
207218 simp only [ne_eq, mul_eq_zero, leadingCoeff_eq_zero, hp, hq, or_self, not_false_eq_true]
208219
220+ lemma pow_scaleRoots' (p : R[X]) (r : R) (n : ℕ)
221+ (hp : p.leadingCoeff ^ n ≠ 0 ) :
222+ (p ^ n).scaleRoots r = p.scaleRoots r ^ n := by
223+ induction n with
224+ | zero => simp
225+ | succ n IH =>
226+ rw [pow_succ, mul_scaleRoots', IH, pow_succ]
227+ · refine mt (by simp +contextual [pow_succ]) hp
228+ · rwa [leadingCoeff_pow' (mt (by simp +contextual [pow_succ]) hp), ← pow_succ]
229+
230+ lemma pow_scaleRoots_of_isReduced [IsReduced R] (p : R[X]) (r : R) (n : ℕ) :
231+ (p ^ n).scaleRoots r = p.scaleRoots r ^ n := by
232+ by_cases hp : p = 0
233+ · simp [hp, zero_pow_eq, apply_ite (scaleRoots · r)]
234+ by_cases hn : n = 0
235+ · simp [hn]
236+ exact pow_scaleRoots' _ _ _ (by simp_all)
237+
209238lemma add_scaleRoots_of_natDegree_eq (p q : R[X]) (r : R) (h : natDegree p = natDegree q) :
210239 r ^ (natDegree p - natDegree (p + q)) • (p + q).scaleRoots r =
211240 p.scaleRoots r + q.scaleRoots r := by
@@ -252,8 +281,73 @@ lemma isCoprime_scaleRoots (p q : R[X]) (r : R) (hr : IsUnit r) (h : IsCoprime p
252281 simp only [s, smul_mul_assoc, ← mul_scaleRoots, smul_smul, mul_assoc,
253282 ← mul_pow, IsUnit.val_inv_mul, one_pow, mul_one, ← smul_add, one_smul, e, natDegree_one,
254283 one_scaleRoots, ← add_scaleRoots_of_natDegree_eq _ _ _ this, tsub_zero]
284+
255285alias _root_.IsCoprime.scaleRoots := isCoprime_scaleRoots
256286
287+ lemma Factors.scaleRoots {p : R[X]} (hp : p.Factors) (r : R) :
288+ (p.scaleRoots r).Factors := by
289+ cases subsingleton_or_nontrivial R
290+ · rwa [Subsingleton.elim (p.scaleRoots r) p]
291+ obtain rfl | hp0 := eq_or_ne p 0
292+ · simp
293+ obtain ⟨m, hm⟩ := factors_iff_exists_multiset'.mp hp
294+ rw [hm, mul_scaleRoots', scaleRoots_C]
295+ · clear hm
296+ refine .mul (.C _) ?_
297+ induction m using Multiset.induction_on with
298+ | empty => simp
299+ | cons a s IH =>
300+ rw [Multiset.map_cons, Multiset.prod_cons, mul_scaleRoots', X_add_C_scaleRoots]
301+ · exact .mul (.X_add_C _) IH
302+ · simp only [leadingCoeff_X_add_C, one_mul, ne_eq, leadingCoeff_eq_zero]
303+ exact (monic_multiset_prod_of_monic _ _ fun a _ ↦ monic_X_add_C _).ne_zero
304+ · rw [(monic_multiset_prod_of_monic _ _ fun a _ ↦ monic_X_add_C _).leadingCoeff]
305+ simpa
306+
257307end CommSemiring
258308
309+ section Ring
310+
311+ @[simp]
312+ lemma X_sub_C_scaleRoots [Ring R] (r s : R) :
313+ (X - C r).scaleRoots s = (X - C (r * s)) := by
314+ nontriviality R
315+ ext (_|_|i) <;> simp
316+
317+ end Ring
318+
319+ section CommRing
320+
321+ variable [CommRing R]
322+
323+ lemma rootMultiplicity_scaleRoots (p : R[X]) {r a : R} (hr : IsLeftRegular r) :
324+ rootMultiplicity (r * a) (p.scaleRoots r) = rootMultiplicity a p := by
325+ cases subsingleton_or_nontrivial R
326+ · simp [Subsingleton.elim p 0 ]
327+ obtain rfl | hp := eq_or_ne p 0
328+ · simp
329+ obtain ⟨q, e, hq⟩ := exists_eq_pow_rootMultiplicity_mul_and_not_dvd p hp a
330+ have hq0 : q ≠ 0 := by contrapose! hp; simp_all
331+ conv_lhs => rw [e]
332+ rw [mul_scaleRoots', pow_scaleRoots', X_sub_C_scaleRoots, mul_comm, mul_comm _ (q.scaleRoots r),
333+ rootMultiplicity_mul_X_sub_C_pow (q.scaleRoots_ne_zero hq0 _)]
334+ · rw [dvd_iff_isRoot, IsRoot.def] at hq
335+ simp only [Nat.add_eq_right, rootMultiplicity_eq_zero_iff, IsRoot.def]
336+ rw [mul_comm, scaleRoots_eval_mul, (hr.pow q.natDegree).mul_left_eq_zero_iff]
337+ tauto
338+ · simp
339+ · rwa [leadingCoeff_pow' (by simp), leadingCoeff_X_sub_C,
340+ one_pow, one_mul, ne_eq, leadingCoeff_eq_zero]
341+
342+ lemma roots_scaleRoots [IsDomain R] (p : R[X]) {r : R} (hr : IsUnit r) :
343+ (p.scaleRoots r).roots = p.roots.map (r * ·) := by
344+ classical
345+ ext a
346+ have : Function.Bijective (α := R) (r * ·) := IsUnit.isUnit_iff_mulLeft_bijective.mp hr
347+ obtain ⟨a, rfl⟩ := this.2 a
348+ simp [Multiset.count_map_eq_count' _ p.roots this.1 a,
349+ rootMultiplicity_scaleRoots _ hr.isRegular.left]
350+
351+ end CommRing
352+
259353end Polynomial
0 commit comments