@@ -3,45 +3,59 @@ Copyright (c) 2021 Alex J. Best. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
4
Authors: Alex J. Best
5
5
6
- ! This file was ported from Lean 3 source module number_theory.cyclotomic.factoring
7
6
-/
8
7
import Mathlib.RingTheory.Polynomial.Cyclotomic.Basic
9
- import FltRegular.ReadyForMathlib.Homogenization
10
8
11
- open Polynomial Finset MvPolynomial
9
+ open Polynomial Finset
10
+
11
+ variable {R : Type *} [CommRing R] [IsDomain R] {ζ : R} {n : ℕ} (x y : R)
12
12
13
- -- TODO might be nice to have an explicit two variable version of this factorization
14
- -- in an mv_polynomial ring with two chosen variables
15
13
/-- If there is a primitive `n`th root of unity in `K`, then `X ^ n - Y ^ n = ∏ (X - μ Y)`,
16
14
where `μ` varies over the `n`-th roots of unity. -/
17
- theorem pow_sub_pow_eq_prod_sub_zeta_runity_mul {K : Type _} [CommRing K] [IsDomain K] {ζ : K}
18
- {n : ℕ} (hpos : 0 < n) (h : IsPrimitiveRoot ζ n) (x y : K) :
19
- x ^ (n : ℕ) - y ^ (n : ℕ) = ∏ ζ : K in nthRootsFinset n K, (x - ζ * y) := by
20
- -- suffices to show the identity in a multivariate polynomial ring with two generators over K
21
- suffices
22
- (X 0 : MvPolynomial (Fin 2 ) K) ^ (n : ℕ) - X 1 ^ (n : ℕ) =
23
- ∏ ζ in nthRootsFinset n K, (X 0 - MvPolynomial.C ζ * X 1 )
24
- by
25
- apply_fun MvPolynomial.eval fun i : Fin 2 => if i = 0 then x else y at this
26
- simpa [MvPolynomial.eval_prod] using this
27
- -- we know the univariate / one argument version of the identity
28
- have := X_pow_sub_one_eq_prod hpos h
29
- -- transfer this to a polynomial ring with two variables
30
- have := congr_arg (Polynomial.aeval (X 0 : MvPolynomial (Fin 2 ) K)) this
31
- simp only [map_prod, aeval_X_pow, Polynomial.aeval_X, aeval_one, Polynomial.aeval_C,
32
- map_sub] at this
33
- -- the homogenization of the identity is also true
34
- have := congr_arg (homogenization 1 ) this
35
- -- simplify to get the result we want
36
- simpa [homogenization_prod, Polynomial.algebraMap_eq, hpos]
15
+ theorem pow_sub_pow_eq_prod_sub_zeta_runity_mul_field {K : Type *} [Field K] {ζ : K} (x y : K)
16
+ (hpos : 0 < n) (h : IsPrimitiveRoot ζ n) :
17
+ x ^ n - y ^ n = ∏ ζ ∈ nthRootsFinset n K, (x - ζ * y) := by
18
+ by_cases hy : y = 0
19
+ · simp only [hy, zero_pow (Nat.not_eq_zero_of_lt hpos), sub_zero, mul_zero, prod_const]
20
+ congr
21
+ rw [h.card_nthRootsFinset]
22
+ have := congr_arg (eval (x/y)) <| X_pow_sub_one_eq_prod hpos h
23
+ rw [eval_sub, eval_pow, eval_one, eval_X, eval_prod] at this
24
+ simp_rw [eval_sub, eval_X, eval_C] at this
25
+ apply_fun (· * y ^ n) at this
26
+ rw [sub_mul, one_mul, div_pow, div_mul_cancel₀ _ (pow_ne_zero n hy)] at this
27
+ nth_rw 4 [← h.card_nthRootsFinset] at this
28
+ rw [mul_comm, pow_card_mul_prod] at this
29
+ convert this using 2
30
+ field_simp [hy]
31
+ rw [mul_comm]
32
+
33
+ /-- If there is a primitive `n`th root of unity in `R`, then `X ^ n - Y ^ n = ∏ (X - μ Y)`,
34
+ where `μ` varies over the `n`-th roots of unity. -/
35
+ theorem pow_sub_pow_eq_prod_sub_zeta_runity_mul (hpos : 0 < n) (h : IsPrimitiveRoot ζ n) :
36
+ x ^ n - y ^ n = ∏ ζ ∈ nthRootsFinset n R, (x - ζ * y) := by
37
+ let K := FractionRing R
38
+ apply NoZeroSMulDivisors.algebraMap_injective R K
39
+ rw [map_sub, map_pow, map_pow, map_prod]
40
+ simp_rw [map_sub, map_mul]
41
+ have h' : IsPrimitiveRoot (algebraMap R K ζ) n :=
42
+ h.map_of_injective <| NoZeroSMulDivisors.algebraMap_injective R K
43
+ rw [pow_sub_pow_eq_prod_sub_zeta_runity_mul_field _ _ hpos h']
44
+ symm
45
+ refine prod_nbij (algebraMap R K) (fun a ha ↦ ?_) (fun a _ b _ H ↦
46
+ NoZeroSMulDivisors.algebraMap_injective R K H) (fun a ha ↦ ?_) (fun _ _ ↦ rfl)
47
+ · rw [mem_nthRootsFinset hpos, ← map_pow, (mem_nthRootsFinset hpos).1 ha, map_one]
48
+ · rw [mem_coe, mem_nthRootsFinset hpos] at ha
49
+ simp only [Set.mem_image, mem_coe]
50
+ obtain ⟨i, -, hζ⟩ := h'.eq_pow_of_pow_eq_one ha hpos
51
+ refine ⟨ζ ^ i, ?_, by rwa [map_pow]⟩
52
+ rw [mem_nthRootsFinset hpos, ← pow_mul, mul_comm, pow_mul, h.pow_eq_one, one_pow]
37
53
38
54
/-- If there is a primitive `n`th root of unity in `K` and `n` is odd, then
39
55
`X ^ n + Y ^ n = ∏ (X + μ Y)`, where `μ` varies over the `n`-th roots of unity. -/
40
- theorem pow_add_pow_eq_prod_add_zeta_runity_mul {K : Type _} [CommRing K] [IsDomain K] {ζ : K}
41
- {n : ℕ} (hodd : n % 2 = 1 ) (h : IsPrimitiveRoot ζ n) (x y : K) :
42
- x ^ (n : ℕ) + y ^ (n : ℕ) = ∏ ζ : K in nthRootsFinset n K, (x + ζ * y) :=
43
- by
44
- have := pow_sub_pow_eq_prod_sub_zeta_runity_mul (Nat.odd_iff.mpr hodd).pos h x (-y)
56
+ theorem pow_add_pow_eq_prod_add_zeta_runity_mul (hodd : n % 2 = 1 ) (h : IsPrimitiveRoot ζ n) :
57
+ x ^ n + y ^ n = ∏ ζ ∈ nthRootsFinset n R, (x + ζ * y) := by
58
+ have := pow_sub_pow_eq_prod_sub_zeta_runity_mul x (-y) (Nat.odd_iff.mpr hodd).pos h
45
59
simp only [mul_neg, sub_neg_eq_add] at this
46
60
rw [neg_pow, neg_one_pow_eq_pow_mod_two] at this
47
61
simpa [hodd] using this
0 commit comments