forked from leanprover-community/mathlib4
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMatrix.lean
More file actions
141 lines (110 loc) · 5.45 KB
/
Copy pathMatrix.lean
File metadata and controls
141 lines (110 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/-
Copyright (c) 2024 Jon Bannon. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jon Bannon, Jireh Loreaux
-/
module
public import Mathlib.LinearAlgebra.Eigenspace.Basic
/-!
# Eigenvalues, Eigenvectors and Spectrum for Matrices
This file collects results about eigenvectors, eigenvalues and spectrum specific to matrices
over a nontrivial commutative ring, nontrivial commutative ring without zero divisors, or field.
## Tags
eigenspace, eigenvector, eigenvalue, spectrum, matrix
-/
public section
section SpectrumDiagonal
variable {R n M : Type*} [DecidableEq n] [Fintype n]
open Matrix Module End
section NontrivialCommRing
variable [CommRing R] [Nontrivial R] [AddCommGroup M] [Module R M]
/-- Basis vectors are eigenvectors of associated diagonal linear operator. -/
lemma hasEigenvector_toLin_diagonal (d : n → R) (i : n) (b : Basis n R M) :
HasEigenvector (toLin b b (diagonal d)) (d i) (b i) :=
⟨mem_eigenspace_iff.mpr <| by simp [diagonal], Basis.ne_zero b i⟩
/-- Standard basis vectors are eigenvectors of any associated diagonal linear operator. -/
lemma hasEigenvector_toLin'_diagonal (d : n → R) (i : n) :
HasEigenvector (toLin' (diagonal d)) (d i) (Pi.basisFun R n i) :=
hasEigenvector_toLin_diagonal _ _ (Pi.basisFun R n)
set_option linter.overlappingInstances false
/-- Eigenvalues of a diagonal linear operator are the diagonal entries. -/
lemma hasEigenvalue_toLin_diagonal_iff (d : n → R) {μ : R} [IsDomain R] [IsTorsionFree R M]
(b : Basis n R M) : HasEigenvalue (toLin b b (diagonal d)) μ ↔ ∃ i, d i = μ := by
have (i : n) : HasEigenvalue (toLin b b (diagonal d)) (d i) :=
hasEigenvalue_of_hasEigenvector <| hasEigenvector_toLin_diagonal d i b
constructor
· contrapose!
intro hμ h_eig
have h_iSup : ⨆ μ ∈ Set.range d, eigenspace (toLin b b (diagonal d)) μ = ⊤ := by
rw [eq_top_iff, ← b.span_eq, Submodule.span_le]
rintro - ⟨i, rfl⟩
simp only [SetLike.mem_coe]
apply Submodule.mem_iSup_of_mem (d i)
apply Submodule.mem_iSup_of_mem ⟨i, rfl⟩
rw [mem_eigenspace_iff]
exact (hasEigenvector_toLin_diagonal d i b).apply_eq_smul
have hμ_notMem : μ ∉ Set.range d := by simpa using fun i ↦ (hμ i)
have := eigenspaces_iSupIndep (toLin b b (diagonal d)) |>.disjoint_biSup hμ_notMem
rw [h_iSup, disjoint_top] at this
exact h_eig this
· rintro ⟨i, rfl⟩
exact this i
/-- Eigenvalues of a diagonal linear operator with respect to standard basis
are the diagonal entries. -/
lemma hasEigenvalue_toLin'_diagonal_iff [IsDomain R] (d : n → R) {μ : R} :
HasEigenvalue (toLin' (diagonal d)) μ ↔ (∃ i, d i = μ) :=
hasEigenvalue_toLin_diagonal_iff _ <| Pi.basisFun R n
end NontrivialCommRing
namespace Matrix
variable [CommRing R] [AddCommGroup M] [Module R M] (d : n → R) {μ : R} (b : Basis n R M)
@[simp]
lemma iSup_eigenspace_toLin_diagonal_eq_top :
⨆ μ, eigenspace ((diagonal d).toLin b b) μ = ⊤ := by
refine (Submodule.eq_top_iff_forall_basis_mem b).mpr fun j ↦ ?_
exact Submodule.mem_iSup_of_mem (d j) <| by simp [diagonal_apply]
@[simp]
lemma iSup_eigenspace_toLin'_diagonal_eq_top :
⨆ μ, eigenspace (diagonal d).toLin' μ = ⊤ :=
iSup_eigenspace_toLin_diagonal_eq_top d <| Pi.basisFun R n
@[simp]
lemma maxGenEigenspace_toLin_diagonal_eq_eigenspace [IsDomain R] :
maxGenEigenspace ((diagonal d).toLin b b) μ = eigenspace ((diagonal d).toLin b b) μ := by
refine le_antisymm (fun x hx ↦ ?_) eigenspace_le_maxGenEigenspace
obtain ⟨k, hk⟩ := (mem_maxGenEigenspace _ _ _).mp hx
replace hk (j : n) : b.repr x j = 0 ∨ d j = μ ∧ k ≠ 0 := by
have aux : (diagonal d).toLin b b - μ • 1 = (diagonal (d - μ • 1)).toLin b b := by
rw [Pi.sub_def, ← diagonal_sub]; simp [one_eq_id]
rw [aux, ← toLin_pow, diagonal_pow, toLin_apply_eq_zero_iff] at hk
simpa [mulVec_eq_sum, diagonal_apply, sub_eq_zero] using hk j
have aux (j : n) : (b.repr x j * d j) • b j = μ • (b.repr x j • b j) := by
rcases hk j with hj | hj
· simp [hj]
· rw [← hj.1, mul_comm, mul_smul]
simp [toLin_apply, mulVec_eq_sum, diagonal_apply, aux, ← Finset.smul_sum]
@[simp]
lemma maxGenEigenspace_toLin'_diagonal_eq_eigenspace [IsDomain R] :
maxGenEigenspace (diagonal d).toLin' μ = eigenspace (diagonal d).toLin' μ :=
maxGenEigenspace_toLin_diagonal_eq_eigenspace d <| Pi.basisFun R n
@[simp]
theorem _root_.LinearMap.spectrum_toMatrix (f : M →ₗ[R] M) (b : Basis n R M) :
spectrum R (f.toMatrix b b) = spectrum R f :=
AlgEquiv.spectrum_eq (LinearMap.toMatrixAlgEquiv b) f
@[simp]
theorem _root_.LinearMap.spectrum_toMatrix' (f : (n → R) →ₗ[R] (n → R)) :
spectrum R f.toMatrix' = spectrum R f :=
AlgEquiv.spectrum_eq LinearMap.toMatrixAlgEquiv' f
@[simp]
theorem spectrum_toLin (A : Matrix n n R) (b : Basis n R M) :
spectrum R (A.toLin b b) = spectrum R A :=
AlgEquiv.spectrum_eq (Matrix.toLinAlgEquiv b) A
@[simp]
theorem spectrum_toLin' (A : Matrix n n R) : spectrum R A.toLin' = spectrum R A :=
AlgEquiv.spectrum_eq Matrix.toLinAlgEquiv' A
end Matrix
/-- The spectrum of the diagonal operator is the range of the diagonal viewed as a function. -/
@[simp] lemma spectrum_diagonal [Field R] (d : n → R) :
spectrum R (diagonal d) = Set.range d := by
ext μ
rw [← AlgEquiv.spectrum_eq (toLinAlgEquiv <| Pi.basisFun R n), ← hasEigenvalue_iff_mem_spectrum]
exact hasEigenvalue_toLin'_diagonal_iff d
end SpectrumDiagonal