Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 0009ffb

Browse files
committed
refactor(linear_algebra/charpoly): split file to reduce imports (#13778)
While working on representation theory I was annoyed to find that essentially all of field theory was being transitively imported (causing lots of unnecessary recompilation). This improves the situation slightly. Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent dd4590a commit 0009ffb

File tree

7 files changed

+127
-83
lines changed

7 files changed

+127
-83
lines changed

archive/100-theorems-list/83_friendship_graphs.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Aaron Anderson, Jalex Stark, Kyle Miller
55
-/
66
import combinatorics.simple_graph.adj_matrix
7-
import linear_algebra.matrix.charpoly.coeff
7+
import linear_algebra.matrix.charpoly.finite_field
88
import data.int.modeq
99
import data.zmod.basic
1010
import tactic.interval_cases

src/linear_algebra/charpoly/basic.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Riccardo Brasca
66

77
import linear_algebra.free_module.finite.basic
88
import linear_algebra.matrix.charpoly.coeff
9+
import field_theory.minpoly
910

1011
/-!
1112
@@ -30,6 +31,7 @@ open_locale classical matrix polynomial
3031

3132
noncomputable theory
3233

34+
3335
open module.free polynomial matrix
3436

3537
namespace linear_map

src/linear_algebra/matrix/charpoly/coeff.lean

Lines changed: 1 addition & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Aaron Anderson, Jalex Stark
55
-/
66

7-
import algebra.polynomial.big_operators
8-
import data.matrix.char_p
9-
import field_theory.finite.basic
10-
import group_theory.perm.cycles
7+
import data.polynomial.expand
118
import linear_algebra.matrix.charpoly.basic
12-
import linear_algebra.matrix.trace
13-
import linear_algebra.matrix.to_lin
14-
import ring_theory.polynomial.basic
15-
import ring_theory.power_basis
169

1710
/-!
1811
# Characteristic polynomials
@@ -182,54 +175,8 @@ begin
182175
not_false_iff] }
183176
end
184177

185-
@[simp] lemma finite_field.matrix.charpoly_pow_card {K : Type*} [field K] [fintype K]
186-
(M : matrix n n K) : (M ^ (fintype.card K)).charpoly = M.charpoly :=
187-
begin
188-
casesI (is_empty_or_nonempty n).symm,
189-
{ cases char_p.exists K with p hp, letI := hp,
190-
rcases finite_field.card K p with ⟨⟨k, kpos⟩, ⟨hp, hk⟩⟩,
191-
haveI : fact p.prime := ⟨hp⟩,
192-
dsimp at hk, rw hk at *,
193-
apply (frobenius_inj K[X] p).iterate k,
194-
repeat { rw iterate_frobenius, rw ← hk },
195-
rw ← finite_field.expand_card,
196-
unfold charpoly, rw [alg_hom.map_det, ← coe_det_monoid_hom,
197-
← (det_monoid_hom : matrix n n K[X] →* K[X]).map_pow],
198-
apply congr_arg det,
199-
refine mat_poly_equiv.injective _,
200-
rw [alg_equiv.map_pow, mat_poly_equiv_charmatrix, hk, sub_pow_char_pow_of_commute, ← C_pow],
201-
{ exact (id (mat_poly_equiv_eq_X_pow_sub_C (p ^ k) M) : _) },
202-
{ exact (C M).commute_X } },
203-
{ -- TODO[gh-6025]: remove this `haveI` once `subsingleton_of_empty_right` is a global instance
204-
haveI : subsingleton (matrix n n K) := subsingleton_of_empty_right,
205-
exact congr_arg _ (subsingleton.elim _ _), },
206-
end
207-
208-
@[simp] lemma zmod.charpoly_pow_card (M : matrix n n (zmod p)) :
209-
(M ^ p).charpoly = M.charpoly :=
210-
by { have h := finite_field.matrix.charpoly_pow_card M, rwa zmod.card at h, }
211-
212-
lemma finite_field.trace_pow_card {K : Type*} [field K] [fintype K]
213-
(M : matrix n n K) : trace (M ^ (fintype.card K)) = trace M ^ (fintype.card K) :=
214-
begin
215-
casesI is_empty_or_nonempty n,
216-
{ simp [zero_pow fintype.card_pos, matrix.trace], },
217-
rw [matrix.trace_eq_neg_charpoly_coeff, matrix.trace_eq_neg_charpoly_coeff,
218-
finite_field.matrix.charpoly_pow_card, finite_field.pow_card]
219-
end
220-
221-
lemma zmod.trace_pow_card {p : ℕ} [fact p.prime] (M : matrix n n (zmod p)) :
222-
trace (M ^ p) = (trace M)^p :=
223-
by { have h := finite_field.trace_pow_card M, rwa zmod.card at h, }
224-
225178
namespace matrix
226179

227-
theorem is_integral : is_integral R M := ⟨M.charpoly, ⟨charpoly_monic M, aeval_self_charpoly M⟩⟩
228-
229-
theorem minpoly_dvd_charpoly {K : Type*} [field K] (M : matrix n n K) :
230-
(minpoly K M) ∣ M.charpoly :=
231-
minpoly.dvd _ _ (aeval_self_charpoly M)
232-
233180
/-- Any matrix polynomial `p` is equivalent under evaluation to `p %ₘ M.charpoly`; that is, `p`
234181
is equivalent to a polynomial with degree less than the dimension of the matrix. -/
235182
lemma aeval_eq_aeval_mod_charpoly (M : matrix n n R) (p : R[X]) :
@@ -243,29 +190,3 @@ lemma pow_eq_aeval_mod_charpoly (M : matrix n n R) (k : ℕ) : M^k = aeval M (X^
243190
by rw [←aeval_eq_aeval_mod_charpoly, map_pow, aeval_X]
244191

245192
end matrix
246-
247-
section power_basis
248-
249-
open algebra
250-
251-
/-- The characteristic polynomial of the map `λ x, a * x` is the minimal polynomial of `a`.
252-
253-
In combination with `det_eq_sign_charpoly_coeff` or `trace_eq_neg_charpoly_coeff`
254-
and a bit of rewriting, this will allow us to conclude the
255-
field norm resp. trace of `x` is the product resp. sum of `x`'s conjugates.
256-
-/
257-
lemma charpoly_left_mul_matrix {K S : Type*} [field K] [comm_ring S] [algebra K S]
258-
(h : power_basis K S) :
259-
(left_mul_matrix h.basis h.gen).charpoly = minpoly K h.gen :=
260-
begin
261-
apply minpoly.unique,
262-
{ apply matrix.charpoly_monic },
263-
{ apply (injective_iff_map_eq_zero (left_mul_matrix _)).mp (left_mul_matrix_injective h.basis),
264-
rw [← polynomial.aeval_alg_hom_apply, aeval_self_charpoly] },
265-
{ intros q q_monic root_q,
266-
rw [matrix.charpoly_degree_eq_dim, fintype.card_fin, degree_eq_nat_degree q_monic.ne_zero],
267-
apply with_bot.some_le_some.mpr,
268-
exact h.dim_le_nat_degree_of_root q_monic.ne_zero root_q }
269-
end
270-
271-
end power_basis
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/-
2+
Copyright (c) 2020 Aaron Anderson, Jalex Stark. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Aaron Anderson, Jalex Stark
5+
-/
6+
import linear_algebra.matrix.charpoly.coeff
7+
import field_theory.finite.basic
8+
import data.matrix.char_p
9+
10+
11+
/-!
12+
# Results on characteristic polynomials and traces over finite fields.
13+
-/
14+
15+
noncomputable theory
16+
17+
open polynomial matrix
18+
open_locale polynomial
19+
20+
variables {n : Type*} [decidable_eq n] [fintype n]
21+
22+
@[simp] lemma finite_field.matrix.charpoly_pow_card {K : Type*} [field K] [fintype K]
23+
(M : matrix n n K) : (M ^ (fintype.card K)).charpoly = M.charpoly :=
24+
begin
25+
casesI (is_empty_or_nonempty n).symm,
26+
{ cases char_p.exists K with p hp, letI := hp,
27+
rcases finite_field.card K p with ⟨⟨k, kpos⟩, ⟨hp, hk⟩⟩,
28+
haveI : fact p.prime := ⟨hp⟩,
29+
dsimp at hk, rw hk at *,
30+
apply (frobenius_inj K[X] p).iterate k,
31+
repeat { rw iterate_frobenius, rw ← hk },
32+
rw ← finite_field.expand_card,
33+
unfold charpoly, rw [alg_hom.map_det, ← coe_det_monoid_hom,
34+
← (det_monoid_hom : matrix n n K[X] →* K[X]).map_pow],
35+
apply congr_arg det,
36+
refine mat_poly_equiv.injective _,
37+
rw [alg_equiv.map_pow, mat_poly_equiv_charmatrix, hk, sub_pow_char_pow_of_commute, ← C_pow],
38+
{ exact (id (mat_poly_equiv_eq_X_pow_sub_C (p ^ k) M) : _) },
39+
{ exact (C M).commute_X } },
40+
{ -- TODO[gh-6025]: remove this `haveI` once `subsingleton_of_empty_right` is a global instance
41+
haveI : subsingleton (matrix n n K) := subsingleton_of_empty_right,
42+
exact congr_arg _ (subsingleton.elim _ _), },
43+
end
44+
45+
@[simp] lemma zmod.charpoly_pow_card {p : ℕ} [fact p.prime] (M : matrix n n (zmod p)) :
46+
(M ^ p).charpoly = M.charpoly :=
47+
by { have h := finite_field.matrix.charpoly_pow_card M, rwa zmod.card at h, }
48+
49+
lemma finite_field.trace_pow_card {K : Type*} [field K] [fintype K]
50+
(M : matrix n n K) : trace (M ^ (fintype.card K)) = trace M ^ (fintype.card K) :=
51+
begin
52+
casesI is_empty_or_nonempty n,
53+
{ simp [zero_pow fintype.card_pos, matrix.trace], },
54+
rw [matrix.trace_eq_neg_charpoly_coeff, matrix.trace_eq_neg_charpoly_coeff,
55+
finite_field.matrix.charpoly_pow_card, finite_field.pow_card]
56+
end
57+
58+
lemma zmod.trace_pow_card {p : ℕ} [fact p.prime] (M : matrix n n (zmod p)) :
59+
trace (M ^ p) = (trace M)^p :=
60+
by { have h := finite_field.trace_pow_card M, rwa zmod.card at h, }
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/-
2+
Copyright (c) 2020 Aaron Anderson, Jalex Stark. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Aaron Anderson, Jalex Stark
5+
-/
6+
7+
import linear_algebra.matrix.charpoly.coeff
8+
import ring_theory.power_basis
9+
10+
/-!
11+
# The minimal polynomial divides the characteristic polynomial of a matrix.
12+
-/
13+
14+
noncomputable theory
15+
16+
universes u v
17+
18+
open polynomial matrix
19+
20+
variables {R : Type u} [comm_ring R]
21+
variables {n : Type v} [decidable_eq n] [fintype n]
22+
23+
open finset
24+
25+
variable {M : matrix n n R}
26+
27+
namespace matrix
28+
29+
theorem is_integral : is_integral R M := ⟨M.charpoly, ⟨charpoly_monic M, aeval_self_charpoly M⟩⟩
30+
31+
theorem minpoly_dvd_charpoly {K : Type*} [field K] (M : matrix n n K) :
32+
(minpoly K M) ∣ M.charpoly :=
33+
minpoly.dvd _ _ (aeval_self_charpoly M)
34+
35+
end matrix
36+
37+
section power_basis
38+
39+
open algebra
40+
41+
/-- The characteristic polynomial of the map `λ x, a * x` is the minimal polynomial of `a`.
42+
43+
In combination with `det_eq_sign_charpoly_coeff` or `trace_eq_neg_charpoly_coeff`
44+
and a bit of rewriting, this will allow us to conclude the
45+
field norm resp. trace of `x` is the product resp. sum of `x`'s conjugates.
46+
-/
47+
lemma charpoly_left_mul_matrix {K S : Type*} [field K] [comm_ring S] [algebra K S]
48+
(h : power_basis K S) :
49+
(left_mul_matrix h.basis h.gen).charpoly = minpoly K h.gen :=
50+
begin
51+
apply minpoly.unique,
52+
{ apply matrix.charpoly_monic },
53+
{ apply (injective_iff_map_eq_zero (left_mul_matrix _)).mp (left_mul_matrix_injective h.basis),
54+
rw [← polynomial.aeval_alg_hom_apply, aeval_self_charpoly] },
55+
{ intros q q_monic root_q,
56+
rw [matrix.charpoly_degree_eq_dim, fintype.card_fin, degree_eq_nat_degree q_monic.ne_zero],
57+
apply with_bot.some_le_some.mpr,
58+
exact h.dim_le_nat_degree_of_root q_monic.ne_zero root_q }
59+
end
60+
61+
end power_basis

src/ring_theory/norm.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Authors: Anne Baanen
66

77
import field_theory.primitive_element
88
import linear_algebra.determinant
9-
import linear_algebra.matrix.charpoly.coeff
9+
import linear_algebra.matrix.charpoly.minpoly
1010
import linear_algebra.matrix.to_linear_equiv
1111
import field_theory.is_alg_closed.algebraic_closure
1212

src/ring_theory/trace.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Authors: Anne Baanen
55
-/
66

77
import linear_algebra.matrix.bilinear_form
8-
import linear_algebra.matrix.charpoly.coeff
8+
import linear_algebra.matrix.charpoly.minpoly
99
import linear_algebra.determinant
1010
import linear_algebra.vandermonde
1111
import linear_algebra.trace

0 commit comments

Comments
 (0)