|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Riccardo Brasca. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Riccardo Brasca |
| 5 | +-/ |
| 6 | + |
| 7 | +import ring_theory.polynomial.cyclotomic.roots |
| 8 | + |
| 9 | +/-! |
| 10 | +# Cyclotomic polynomials and `expand`. |
| 11 | +
|
| 12 | +We gather results relating cyclotomic polynomials and `expand`. |
| 13 | +
|
| 14 | +## Main results |
| 15 | +
|
| 16 | +* `polynomial.cyclotomic_expand_eq_cyclotomic_mul` : If `p` is a prime such that `¬ p ∣ n`, then |
| 17 | + `expand R p (cyclotomic n R) = (cyclotomic (n * p) R) * (cyclotomic n R)`. |
| 18 | +* `polynomial.cyclotomic_expand_eq_cyclotomic` : If `p` is a prime such that `p ∣ n`, then |
| 19 | + `expand R p (cyclotomic n R) = cyclotomic (p * n) R`. |
| 20 | +* `polynomial.cyclotomic_mul_prime_eq_pow_of_not_dvd` : If `R` is of characteristic `p` and |
| 21 | + `¬p ∣ n`, then `cyclotomic (n * p) R = (cyclotomic n R) ^ (p - 1)`. |
| 22 | +* `polynomial.cyclotomic_mul_prime_dvd_eq_pow` : If `R` is of characteristic `p` and `p ∣ n`, then |
| 23 | + `cyclotomic (n * p) R = (cyclotomic n R) ^ p`. |
| 24 | +* `polynomial.cyclotomic_mul_prime_pow_eq` : If `R` is of characteristic `p` and `¬p ∣ m`, then |
| 25 | + `cyclotomic (p ^ k * m) R = (cyclotomic m R) ^ (p ^ k - p ^ (k - 1))`. |
| 26 | +* `polynomial.cyclotomic_mul_prime_pow_eq` : If `R` is of characteristic `p` and `¬p ∣ m`, then |
| 27 | + `cyclotomic (p ^ k * m) R = (cyclotomic m R) ^ (p ^ k - p ^ (k - 1))`. |
| 28 | +-/ |
| 29 | + |
| 30 | +namespace polynomial |
| 31 | + |
| 32 | +/-- If `p` is a prime such that `¬ p ∣ n`, then |
| 33 | +`expand R p (cyclotomic n R) = (cyclotomic (n * p) R) * (cyclotomic n R)`. -/ |
| 34 | +@[simp] lemma cyclotomic_expand_eq_cyclotomic_mul {p n : ℕ} (hp : nat.prime p) (hdiv : ¬p ∣ n) |
| 35 | + (R : Type*) [comm_ring R] : |
| 36 | + expand R p (cyclotomic n R) = (cyclotomic (n * p) R) * (cyclotomic n R) := |
| 37 | +begin |
| 38 | + rcases nat.eq_zero_or_pos n with rfl | hnpos, |
| 39 | + { simp }, |
| 40 | + haveI := ne_zero.of_pos hnpos, |
| 41 | + suffices : expand ℤ p (cyclotomic n ℤ) = (cyclotomic (n * p) ℤ) * (cyclotomic n ℤ), |
| 42 | + { rw [← map_cyclotomic_int, ← map_expand, this, polynomial.map_mul, map_cyclotomic_int] }, |
| 43 | + refine eq_of_monic_of_dvd_of_nat_degree_le ((cyclotomic.monic _ _).mul |
| 44 | + (cyclotomic.monic _ _)) ((cyclotomic.monic n ℤ).expand hp.pos) _ _, |
| 45 | + { refine (is_primitive.int.dvd_iff_map_cast_dvd_map_cast _ _ (is_primitive.mul |
| 46 | + (cyclotomic.is_primitive (n * p) ℤ) (cyclotomic.is_primitive n ℤ)) |
| 47 | + ((cyclotomic.monic n ℤ).expand hp.pos).is_primitive).2 _, |
| 48 | + rw [polynomial.map_mul, map_cyclotomic_int, map_cyclotomic_int, map_expand, map_cyclotomic_int], |
| 49 | + refine is_coprime.mul_dvd (cyclotomic.is_coprime_rat (λ h, _)) _ _, |
| 50 | + { replace h : n * p = n * 1 := by simp [h], |
| 51 | + exact nat.prime.ne_one hp (mul_left_cancel₀ hnpos.ne' h) }, |
| 52 | + { have hpos : 0 < n * p := mul_pos hnpos hp.pos, |
| 53 | + have hprim := complex.is_primitive_root_exp _ hpos.ne', |
| 54 | + rw [cyclotomic_eq_minpoly_rat hprim hpos], |
| 55 | + refine @minpoly.dvd ℚ ℂ _ _ algebra_rat _ _ _, |
| 56 | + rw [aeval_def, ← eval_map, map_expand, map_cyclotomic, expand_eval, ← is_root.def, |
| 57 | + is_root_cyclotomic_iff], |
| 58 | + convert is_primitive_root.pow_of_dvd hprim hp.ne_zero (dvd_mul_left p n), |
| 59 | + rw [nat.mul_div_cancel _ (nat.prime.pos hp)] }, |
| 60 | + { have hprim := complex.is_primitive_root_exp _ hnpos.ne.symm, |
| 61 | + rw [cyclotomic_eq_minpoly_rat hprim hnpos], |
| 62 | + refine @minpoly.dvd ℚ ℂ _ _ algebra_rat _ _ _, |
| 63 | + rw [aeval_def, ← eval_map, map_expand, expand_eval, ← is_root.def, |
| 64 | + ← cyclotomic_eq_minpoly_rat hprim hnpos, map_cyclotomic, is_root_cyclotomic_iff], |
| 65 | + exact is_primitive_root.pow_of_prime hprim hp hdiv,} }, |
| 66 | + { rw [nat_degree_expand, nat_degree_cyclotomic, nat_degree_mul (cyclotomic_ne_zero _ ℤ) |
| 67 | + (cyclotomic_ne_zero _ ℤ), nat_degree_cyclotomic, nat_degree_cyclotomic, mul_comm n, |
| 68 | + nat.totient_mul ((nat.prime.coprime_iff_not_dvd hp).2 hdiv), |
| 69 | + nat.totient_prime hp, mul_comm (p - 1), ← nat.mul_succ, nat.sub_one, |
| 70 | + nat.succ_pred_eq_of_pos hp.pos] } |
| 71 | +end |
| 72 | + |
| 73 | +/-- If `p` is a prime such that `p ∣ n`, then |
| 74 | +`expand R p (cyclotomic n R) = cyclotomic (p * n) R`. -/ |
| 75 | +@[simp] lemma cyclotomic_expand_eq_cyclotomic {p n : ℕ} (hp : nat.prime p) (hdiv : p ∣ n) |
| 76 | + (R : Type*) [comm_ring R] : expand R p (cyclotomic n R) = cyclotomic (n * p) R := |
| 77 | +begin |
| 78 | + rcases n.eq_zero_or_pos with rfl | hzero, |
| 79 | + { simp }, |
| 80 | + haveI := ne_zero.of_pos hzero, |
| 81 | + suffices : expand ℤ p (cyclotomic n ℤ) = cyclotomic (n * p) ℤ, |
| 82 | + { rw [← map_cyclotomic_int, ← map_expand, this, map_cyclotomic_int] }, |
| 83 | + refine eq_of_monic_of_dvd_of_nat_degree_le (cyclotomic.monic _ _) |
| 84 | + ((cyclotomic.monic n ℤ).expand hp.pos) _ _, |
| 85 | + { have hpos := nat.mul_pos hzero hp.pos, |
| 86 | + have hprim := complex.is_primitive_root_exp _ hpos.ne.symm, |
| 87 | + rw [cyclotomic_eq_minpoly hprim hpos], |
| 88 | + refine minpoly.is_integrally_closed_dvd (hprim.is_integral hpos) _, |
| 89 | + rw [aeval_def, ← eval_map, map_expand, map_cyclotomic, expand_eval, |
| 90 | + ← is_root.def, is_root_cyclotomic_iff], |
| 91 | + { convert is_primitive_root.pow_of_dvd hprim hp.ne_zero (dvd_mul_left p n), |
| 92 | + rw [nat.mul_div_cancel _ hp.pos] } }, |
| 93 | + { rw [nat_degree_expand, nat_degree_cyclotomic, nat_degree_cyclotomic, mul_comm n, |
| 94 | + nat.totient_mul_of_prime_of_dvd hp hdiv, mul_comm] } |
| 95 | +end |
| 96 | + |
| 97 | +/-- If the `p ^ n`th cyclotomic polynomial is irreducible, so is the `p ^ m`th, for `m ≤ n`. -/ |
| 98 | +lemma cyclotomic_irreducible_pow_of_irreducible_pow {p : ℕ} (hp : nat.prime p) |
| 99 | + {R} [comm_ring R] [is_domain R] {n m : ℕ} (hmn : m ≤ n) |
| 100 | + (h : irreducible (cyclotomic (p ^ n) R)) : irreducible (cyclotomic (p ^ m) R) := |
| 101 | +begin |
| 102 | + unfreezingI |
| 103 | + { rcases m.eq_zero_or_pos with rfl | hm, |
| 104 | + { simpa using irreducible_X_sub_C (1 : R) }, |
| 105 | + obtain ⟨k, rfl⟩ := nat.exists_eq_add_of_le hmn, |
| 106 | + induction k with k hk }, |
| 107 | + { simpa using h }, |
| 108 | + have : m + k ≠ 0 := (add_pos_of_pos_of_nonneg hm k.zero_le).ne', |
| 109 | + rw [nat.add_succ, pow_succ', ←cyclotomic_expand_eq_cyclotomic hp $ dvd_pow_self p this] at h, |
| 110 | + exact hk (by linarith) (of_irreducible_expand hp.ne_zero h) |
| 111 | +end |
| 112 | + |
| 113 | +/-- If `irreducible (cyclotomic (p ^ n) R)` then `irreducible (cyclotomic p R).` -/ |
| 114 | +lemma cyclotomic_irreducible_of_irreducible_pow {p : ℕ} (hp : nat.prime p) {R} [comm_ring R] |
| 115 | + [is_domain R] {n : ℕ} (hn : n ≠ 0) (h : irreducible (cyclotomic (p ^ n) R)) : |
| 116 | + irreducible (cyclotomic p R) := |
| 117 | +pow_one p ▸ cyclotomic_irreducible_pow_of_irreducible_pow hp hn.bot_lt h |
| 118 | + |
| 119 | +section char_p |
| 120 | + |
| 121 | +/-- If `R` is of characteristic `p` and `¬p ∣ n`, then |
| 122 | +`cyclotomic (n * p) R = (cyclotomic n R) ^ (p - 1)`. -/ |
| 123 | +lemma cyclotomic_mul_prime_eq_pow_of_not_dvd (R : Type*) {p n : ℕ} [hp : fact (nat.prime p)] |
| 124 | + [ring R] [char_p R p] (hn : ¬p ∣ n) : cyclotomic (n * p) R = (cyclotomic n R) ^ (p - 1) := |
| 125 | +begin |
| 126 | + suffices : cyclotomic (n * p) (zmod p) = (cyclotomic n (zmod p)) ^ (p - 1), |
| 127 | + { rw [← map_cyclotomic _ (algebra_map (zmod p) R), ← map_cyclotomic _ (algebra_map (zmod p) R), |
| 128 | + this, polynomial.map_pow] }, |
| 129 | + apply mul_right_injective₀ (cyclotomic_ne_zero n $ zmod p), |
| 130 | + rw [←pow_succ, tsub_add_cancel_of_le hp.out.one_lt.le, mul_comm, ← zmod.expand_card], |
| 131 | + nth_rewrite 2 [← map_cyclotomic_int], |
| 132 | + rw [← map_expand, cyclotomic_expand_eq_cyclotomic_mul hp.out hn, polynomial.map_mul, |
| 133 | + map_cyclotomic, map_cyclotomic] |
| 134 | +end |
| 135 | + |
| 136 | +/-- If `R` is of characteristic `p` and `p ∣ n`, then |
| 137 | +`cyclotomic (n * p) R = (cyclotomic n R) ^ p`. -/ |
| 138 | +lemma cyclotomic_mul_prime_dvd_eq_pow (R : Type*) {p n : ℕ} [hp : fact (nat.prime p)] [ring R] |
| 139 | + [char_p R p] (hn : p ∣ n) : cyclotomic (n * p) R = (cyclotomic n R) ^ p := |
| 140 | +begin |
| 141 | + suffices : cyclotomic (n * p) (zmod p) = (cyclotomic n (zmod p)) ^ p, |
| 142 | + { rw [← map_cyclotomic _ (algebra_map (zmod p) R), ← map_cyclotomic _ (algebra_map (zmod p) R), |
| 143 | + this, polynomial.map_pow] }, |
| 144 | + rw [← zmod.expand_card, ← map_cyclotomic_int n, ← map_expand, cyclotomic_expand_eq_cyclotomic |
| 145 | + hp.out hn, map_cyclotomic, mul_comm] |
| 146 | +end |
| 147 | + |
| 148 | +/-- If `R` is of characteristic `p` and `¬p ∣ m`, then |
| 149 | +`cyclotomic (p ^ k * m) R = (cyclotomic m R) ^ (p ^ k - p ^ (k - 1))`. -/ |
| 150 | +lemma cyclotomic_mul_prime_pow_eq (R : Type*) {p m : ℕ} [fact (nat.prime p)] |
| 151 | + [ring R] [char_p R p] (hm : ¬p ∣ m) : |
| 152 | + ∀ {k}, 0 < k → cyclotomic (p ^ k * m) R = (cyclotomic m R) ^ (p ^ k - p ^ (k - 1)) |
| 153 | +| 1 _ := by rw [pow_one, nat.sub_self, pow_zero, mul_comm, |
| 154 | + cyclotomic_mul_prime_eq_pow_of_not_dvd R hm] |
| 155 | +| (a + 2) _ := |
| 156 | +begin |
| 157 | + have hdiv : p ∣ p ^ a.succ * m := ⟨p ^ a * m, by rw [← mul_assoc, pow_succ]⟩, |
| 158 | + rw [pow_succ, mul_assoc, mul_comm, cyclotomic_mul_prime_dvd_eq_pow R hdiv, |
| 159 | + cyclotomic_mul_prime_pow_eq a.succ_pos, ← pow_mul], |
| 160 | + congr' 1, |
| 161 | + simp only [tsub_zero, nat.succ_sub_succ_eq_sub], |
| 162 | + rw [nat.mul_sub_right_distrib, mul_comm, pow_succ'] |
| 163 | +end |
| 164 | + |
| 165 | +/-- If `R` is of characteristic `p` and `¬p ∣ m`, then `ζ` is a root of `cyclotomic (p ^ k * m) R` |
| 166 | + if and only if it is a primitive `m`-th root of unity. -/ |
| 167 | +lemma is_root_cyclotomic_prime_pow_mul_iff_of_char_p {m k p : ℕ} {R : Type*} [comm_ring R] |
| 168 | + [is_domain R] [hp : fact (nat.prime p)] [hchar : char_p R p] {μ : R} [ne_zero (m : R)] : |
| 169 | + (polynomial.cyclotomic (p ^ k * m) R).is_root μ ↔ is_primitive_root μ m := |
| 170 | +begin |
| 171 | + rcases k.eq_zero_or_pos with rfl | hk, |
| 172 | + { rw [pow_zero, one_mul, is_root_cyclotomic_iff] }, |
| 173 | + refine ⟨λ h, _, λ h, _⟩, |
| 174 | + { rw [is_root.def, cyclotomic_mul_prime_pow_eq R (ne_zero.not_char_dvd R p m) hk, eval_pow] at h, |
| 175 | + replace h := pow_eq_zero h, |
| 176 | + rwa [← is_root.def, is_root_cyclotomic_iff] at h }, |
| 177 | + { rw [← is_root_cyclotomic_iff, is_root.def] at h, |
| 178 | + rw [cyclotomic_mul_prime_pow_eq R (ne_zero.not_char_dvd R p m) hk, |
| 179 | + is_root.def, eval_pow, h, zero_pow], |
| 180 | + simp only [tsub_pos_iff_lt], |
| 181 | + apply pow_strict_mono_right hp.out.one_lt (nat.pred_lt hk.ne') } |
| 182 | +end |
| 183 | + |
| 184 | +end char_p |
| 185 | + |
| 186 | +end polynomial |
0 commit comments