Skip to content

Commit fc44d8a

Browse files
feat(LinearAlgebra/Eigenspace/Minpoly): reduce typeclass assumptions (#29898)
Co-authored-by: Aristotle Harmonic <aristotle-harmonic@harmonic.fun>
1 parent a50a869 commit fc44d8a

File tree

1 file changed

+67
-49
lines changed

1 file changed

+67
-49
lines changed

Mathlib/LinearAlgebra/Eigenspace/Minpoly.lean

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ Copyright (c) 2020 Alexander Bentkamp. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Alexander Bentkamp
55
-/
6+
import Mathlib.Algebra.Polynomial.Roots
7+
import Mathlib.FieldTheory.Minpoly.Basic
68
import Mathlib.LinearAlgebra.Eigenspace.Basic
7-
import Mathlib.FieldTheory.Minpoly.Field
9+
import Mathlib.RingTheory.IntegralClosure.Algebra.Basic
810

911
/-!
1012
# Eigenvalues are the roots of the minimal polynomial.
@@ -25,29 +27,22 @@ open Polynomial Module
2527

2628
open scoped Polynomial
2729

28-
variable {K : Type v} {V : Type w} [Field K] [AddCommGroup V] [Module K V]
30+
section CommSemiring
2931

30-
theorem eigenspace_aeval_polynomial_degree_1 (f : End K V) (q : K[X]) (hq : degree q = 1) :
31-
eigenspace f (-q.coeff 0 / q.leadingCoeff) = LinearMap.ker (aeval f q) :=
32-
calc
33-
eigenspace f (-q.coeff 0 / q.leadingCoeff)
34-
_ = LinearMap.ker (q.leadingCoeff • f - algebraMap K (End K V) (-q.coeff 0)) := by
35-
rw [eigenspace_div]
36-
intro h
37-
rw [leadingCoeff_eq_zero_iff_deg_eq_bot.1 h] at hq
38-
cases hq
39-
_ = LinearMap.ker (aeval f (C q.leadingCoeff * X + C (q.coeff 0))) := by
40-
rw [C_mul', aeval_def]; simp [algebraMap, Algebra.algebraMap]
41-
_ = LinearMap.ker (aeval f q) := by rwa [← eq_X_add_C_of_degree_eq_one]
32+
variable {R : Type v} {M : Type w} [CommSemiring R] [AddCommMonoid M] [Module R M]
33+
34+
theorem ker_aeval_ring_hom'_unit_polynomial (f : End R M) (c : R[X]ˣ) :
35+
LinearMap.ker (aeval f (c : R[X])) = ⊥ :=
36+
LinearMap.ker_eq_bot'.mpr fun m hm ↦ by
37+
simpa [← mul_apply, ← aeval_mul] using congr(c⁻¹.1.aeval f $hm)
4238

43-
theorem ker_aeval_ring_hom'_unit_polynomial (f : End K V) (c : K[X]ˣ) :
44-
LinearMap.ker (aeval f (c : K[X])) = ⊥ := by
45-
rw [Polynomial.eq_C_of_degree_eq_zero (degree_coe_units c)]
46-
simp only [aeval_def, eval₂_C]
47-
apply ker_algebraMap_end
48-
apply coeff_coe_units_zero_ne_zero c
39+
end CommSemiring
4940

50-
theorem aeval_apply_of_hasEigenvector {f : End K V} {p : K[X]} {μ : K} {x : V}
41+
section CommRing
42+
43+
variable {R : Type v} {M : Type w} [CommRing R] [AddCommGroup M] [Module R M] {f : End R M} {μ : R}
44+
45+
theorem aeval_apply_of_hasEigenvector {f : End R M} {p : R[X]} {μ : R} {x : M}
5146
(h : f.HasEigenvector μ x) : aeval f p x = p.eval μ • x := by
5247
refine p.induction_on ?_ ?_ ?_
5348
· intro a; simp [Module.algebraMap_end_apply]
@@ -57,41 +52,41 @@ theorem aeval_apply_of_hasEigenvector {f : End K V} {p : K[X]} {μ : K} {x : V}
5752
simp only [mem_eigenspace_iff.1 h.1, smul_smul, aeval_X, eval_mul, eval_C, eval_pow, eval_X,
5853
LinearMap.map_smulₛₗ, RingHom.id_apply, mul_comm]
5954

60-
theorem isRoot_of_hasEigenvalue {f : End K V} {μ : K} (h : f.HasEigenvalue μ) :
61-
(minpoly K f).IsRoot μ := by
55+
theorem isRoot_of_hasEigenvalue [NoZeroSMulDivisors R M] {f : End R M} {μ : R}
56+
(h : f.HasEigenvalue μ) : (minpoly R f).IsRoot μ := by
6257
rcases (Submodule.ne_bot_iff _).1 h with ⟨w, ⟨H, ne0⟩⟩
6358
refine Or.resolve_right (smul_eq_zero.1 ?_) ne0
64-
simp [← aeval_apply_of_hasEigenvector ⟨H, ne0⟩, minpoly.aeval K f]
65-
66-
variable [FiniteDimensional K V] (f : End K V)
67-
variable {f} {μ : K}
68-
69-
theorem hasEigenvalue_of_isRoot (h : (minpoly K f).IsRoot μ) : f.HasEigenvalue μ := by
70-
obtain ⟨p, hp⟩ := dvd_iff_isRoot.2 h
71-
rw [hasEigenvalue_iff, eigenspace_def]
72-
intro con
73-
obtain ⟨u, hu⟩ := (LinearMap.isUnit_iff_ker_eq_bot _).2 con
74-
have p_ne_0 : p ≠ 0 := by
75-
intro con
76-
apply minpoly.ne_zero (Algebra.IsIntegral.isIntegral (R := K) f)
77-
rw [hp, con, mul_zero]
78-
have : (aeval f) p = 0 := by
79-
have h_aeval := minpoly.aeval K f
80-
revert h_aeval
81-
simp [hp, ← hu, Algebra.algebraMap_eq_smul_one]
82-
have h_deg := minpoly.degree_le_of_ne_zero K f p_ne_0 this
83-
rw [hp, degree_mul, degree_X_sub_C, Polynomial.degree_eq_natDegree p_ne_0] at h_deg
84-
norm_cast at h_deg
85-
cutsat
86-
87-
theorem hasEigenvalue_iff_isRoot : f.HasEigenvalue μ ↔ (minpoly K f).IsRoot μ :=
59+
rw [← aeval_apply_of_hasEigenvector ⟨H, ne0⟩]
60+
simp
61+
62+
section IsDomain
63+
64+
variable [IsDomain R] [Module.Finite R M]
65+
66+
theorem hasEigenvalue_of_isRoot (h : (minpoly R f).IsRoot μ) : f.HasEigenvalue μ := by
67+
obtain ⟨q, hq⟩ := dvd_iff_isRoot.mpr h
68+
obtain ⟨v, hv⟩ : ∃ v : M, q.aeval f v ≠ 0 := by
69+
by_contra! h_contra
70+
have := minpoly.min R f
71+
((monic_X_sub_C μ).of_mul_monic_left (hq ▸ minpoly.monic (Algebra.IsIntegral.isIntegral f)))
72+
(LinearMap.ext h_contra)
73+
rw [hq, degree_mul, degree_X_sub_C, degree_eq_natDegree] at this
74+
· norm_cast at this; grind
75+
· rintro rfl
76+
exact minpoly.ne_zero (Algebra.IsIntegral.isIntegral f) (mul_zero (X - C μ) ▸ hq)
77+
refine Module.End.hasEigenvalue_of_hasEigenvector (hasEigenvector_iff.mpr ⟨?_, hv⟩)
78+
simpa [sub_eq_zero, hq] using congr($(minpoly.aeval R f) v)
79+
80+
variable [NoZeroSMulDivisors R M]
81+
82+
theorem hasEigenvalue_iff_isRoot : f.HasEigenvalue μ ↔ (minpoly R f).IsRoot μ :=
8883
⟨isRoot_of_hasEigenvalue, hasEigenvalue_of_isRoot⟩
8984

9085
variable (f)
9186

9287
lemma finite_hasEigenvalue : Set.Finite f.HasEigenvalue := by
93-
have h : minpoly K f ≠ 0 := minpoly.ne_zero (Algebra.IsIntegral.isIntegral (R := K) f)
94-
convert (minpoly K f).rootSet_finite K
88+
have h : minpoly R f ≠ 0 := minpoly.ne_zero (Algebra.IsIntegral.isIntegral (R := R) f)
89+
convert (minpoly R f).rootSet_finite R
9590
ext μ
9691
change f.HasEigenvalue μ ↔ _
9792
rw [hasEigenvalue_iff_isRoot, mem_rootSet_of_ne h, IsRoot, coe_aeval_eq_eval]
@@ -100,6 +95,29 @@ lemma finite_hasEigenvalue : Set.Finite f.HasEigenvalue := by
10095
noncomputable instance : Fintype f.Eigenvalues :=
10196
Set.Finite.fintype f.finite_hasEigenvalue
10297

98+
end IsDomain
99+
100+
end CommRing
101+
102+
section Field
103+
104+
variable {K : Type v} {V : Type w} [Field K] [AddCommGroup V] [Module K V]
105+
106+
theorem eigenspace_aeval_polynomial_degree_1 (f : End K V) (q : K[X]) (hq : degree q = 1) :
107+
eigenspace f (-q.coeff 0 / q.leadingCoeff) = LinearMap.ker (aeval f q) :=
108+
calc
109+
eigenspace f (-q.coeff 0 / q.leadingCoeff)
110+
_ = LinearMap.ker (q.leadingCoeff • f - algebraMap K (End K V) (-q.coeff 0)) := by
111+
rw [eigenspace_div]
112+
intro h
113+
rw [leadingCoeff_eq_zero_iff_deg_eq_bot.1 h] at hq
114+
cases hq
115+
_ = LinearMap.ker (aeval f (C q.leadingCoeff * X + C (q.coeff 0))) := by
116+
rw [C_mul', aeval_def]; simp [algebraMap, Algebra.algebraMap]
117+
_ = LinearMap.ker (aeval f q) := by rwa [← eq_X_add_C_of_degree_eq_one]
118+
119+
end Field
120+
103121
end End
104122

105123
end Module

0 commit comments

Comments
 (0)