|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Alexander Bentkamp. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Author: Alexander Bentkamp. |
| 5 | +-/ |
| 6 | + |
| 7 | +import field_theory.algebraic_closure |
| 8 | +import linear_algebra.finsupp |
| 9 | + |
| 10 | +/-! |
| 11 | +# Eigenvectors and eigenvalues |
| 12 | +
|
| 13 | +This file defines eigenspaces and eigenvalues. |
| 14 | +
|
| 15 | +An eigenspace of a linear map `f` for a scalar `μ` is the kernel of the map `(f - μ • id)`. The |
| 16 | +nonzero elements of an eigenspace are eigenvectors `x`. They have the property `f x = μ • x`. If |
| 17 | +there are eigenvectors for a scalar `μ`, the scalar `μ` is called an eigenvalue. |
| 18 | +
|
| 19 | +There is no consensus in the literature whether `0` is an eigenvector. Our definition of |
| 20 | +`eigenvector` permits only nonzero vectors. For an eigenvector `x` that may also be `0`, we write |
| 21 | +`x ∈ eigenspace f μ`. |
| 22 | +
|
| 23 | +## Notations |
| 24 | +
|
| 25 | +The expression `algebra_map K (End K V)` appears very often, which is why we use `am` as a local |
| 26 | +notation for it. |
| 27 | +
|
| 28 | +## References |
| 29 | +
|
| 30 | +* [Sheldon Axler, *Down with determinants!*, |
| 31 | + https://www.maa.org/sites/default/files/pdf/awards/Axler-Ford-1996.pdf][axler1996] |
| 32 | +* https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors |
| 33 | +
|
| 34 | +## Tags |
| 35 | +
|
| 36 | +eigenspace, eigenvector, eigenvalue, eigen |
| 37 | +-/ |
| 38 | + |
| 39 | +universes u v w |
| 40 | + |
| 41 | +namespace module |
| 42 | +namespace End |
| 43 | + |
| 44 | +open vector_space principal_ideal_ring polynomial finite_dimensional |
| 45 | + |
| 46 | +variables {K : Type v} {V : Type w} [add_comm_group V] |
| 47 | + |
| 48 | +local notation `am` := algebra_map K (End K V) |
| 49 | + |
| 50 | +/-- The submodule `eigenspace f μ` for a linear map `f` and a scalar `μ` consists of all vectors `x` |
| 51 | + such that `f x = μ • x`. -/ |
| 52 | +def eigenspace [comm_ring K] [module K V] (f : End K V) (μ : K) : submodule K V := |
| 53 | +(f - am μ).ker |
| 54 | + |
| 55 | +/-- A nonzero element of an eigenspace is an eigenvector. -/ |
| 56 | +def has_eigenvector [comm_ring K] [module K V] (f : End K V) (μ : K) (x : V) : Prop := |
| 57 | +x ≠ 0 ∧ x ∈ eigenspace f μ |
| 58 | + |
| 59 | +/-- A scalar `μ` is an eigenvalue for a linear map `f` if there are nonzero vectors `x` |
| 60 | + such that `f x = μ • x`. -/ |
| 61 | +def has_eigenvalue [comm_ring K] [module K V] (f : End K V) (a : K) : Prop := |
| 62 | +eigenspace f a ≠ ⊥ |
| 63 | + |
| 64 | +lemma mem_eigenspace_iff [comm_ring K] [module K V] |
| 65 | + {f : End K V} {μ : K} {x : V} : x ∈ eigenspace f μ ↔ f x = μ • x := |
| 66 | +by rw [eigenspace, linear_map.mem_ker, linear_map.sub_apply, algebra_map_End_apply, |
| 67 | + sub_eq_zero] |
| 68 | + |
| 69 | +lemma eigenspace_div [field K] [vector_space K V] (f : End K V) (a b : K) (hb : b ≠ 0) : |
| 70 | + eigenspace f (a / b) = (b • f - am a).ker := |
| 71 | +calc |
| 72 | + eigenspace f (a / b) = eigenspace f (b⁻¹ * a) : by { dsimp [(/)], rw mul_comm } |
| 73 | + ... = (f - (b⁻¹ * a) • linear_map.id).ker : rfl |
| 74 | + ... = (f - b⁻¹ • a • linear_map.id).ker : by rw smul_smul |
| 75 | + ... = (f - b⁻¹ • am a).ker : rfl |
| 76 | + ... = (b • (f - b⁻¹ • am a)).ker : by rw linear_map.ker_smul _ b hb |
| 77 | + ... = (b • f - am a).ker : by rw [smul_sub, smul_inv_smul' hb] |
| 78 | + |
| 79 | +lemma eigenspace_eval₂_polynomial_degree_1 [field K] [vector_space K V] |
| 80 | + (f : End K V) (q : polynomial K) (hq : degree q = 1) : |
| 81 | + eigenspace f (- q.coeff 0 / q.leading_coeff) = (eval₂ am f q).ker := |
| 82 | +calc |
| 83 | + eigenspace f (- q.coeff 0 / q.leading_coeff) = (q.leading_coeff • f - am (- q.coeff 0)).ker |
| 84 | + : by { rw eigenspace_div, intro h, rw leading_coeff_eq_zero_iff_deg_eq_bot.1 h at hq, cases hq } |
| 85 | + ... = (eval₂ am f (C q.leading_coeff * X + C (q.coeff 0))).ker |
| 86 | + : by { rw C_mul', simpa [algebra_map, algebra.to_ring_hom] } |
| 87 | + ... = (eval₂ am f q).ker |
| 88 | + : by { congr, apply (eq_X_add_C_of_degree_eq_one hq).symm } |
| 89 | + |
| 90 | +lemma ker_eval₂_ring_hom_noncomm_unit_polynomial [field K] [vector_space K V] |
| 91 | + (f : End K V) (c : units (polynomial K)) : |
| 92 | + ((eval₂_ring_hom_noncomm am (λ x y, (algebra.commutes x y).symm) f) ↑c).ker = ⊥ := |
| 93 | +begin |
| 94 | + rw polynomial.eq_C_of_degree_eq_zero (degree_coe_units c), |
| 95 | + simp only [eval₂_ring_hom_noncomm, ring_hom.of, ring_hom.coe_mk, eval₂_C], |
| 96 | + apply ker_algebra_map_End, |
| 97 | + apply coeff_coe_units_zero_ne_zero c |
| 98 | +end |
| 99 | + |
| 100 | +/-- Every linear operator on a vector space over an algebraically closed field has |
| 101 | + an eigenvalue. (Axler's Theorem 2.1.) -/ |
| 102 | +lemma exists_eigenvalue |
| 103 | + [field K] [is_alg_closed K] [vector_space K V] [finite_dimensional K V] [nontrivial V] |
| 104 | + (f : End K V) : |
| 105 | + ∃ (c : K), f.has_eigenvalue c := |
| 106 | +begin |
| 107 | + classical, |
| 108 | + -- Choose a nonzero vector `v`. |
| 109 | + obtain ⟨v, hv⟩ : ∃ v : V, v ≠ 0 := exists_ne (0 : V), |
| 110 | + -- The infinitely many vectors v, f v, f (f v), ... cannot be linearly independent |
| 111 | + -- because the vector space is finite dimensional. |
| 112 | + have h_lin_dep : ¬ linear_independent K (λ n : ℕ, (f ^ n) v), |
| 113 | + { apply not_linear_independent_of_infinite, }, |
| 114 | + -- Therefore, there must be a nonzero polynomial `p` such that `p(f) v = 0`. |
| 115 | + obtain ⟨p, h_eval_p, h_p_ne_0⟩ : ∃ p, eval₂ am f p v = 0 ∧ p ≠ 0, |
| 116 | + { simp only [not_imp.symm], |
| 117 | + exact not_forall.1 (λ h, h_lin_dep ((linear_independent_powers_iff_eval₂ f v).2 h)) }, |
| 118 | + -- Then `p(f)` is not invertible. |
| 119 | + have h_eval_p_not_unit : eval₂_ring_hom_noncomm am _ f p ∉ is_unit.submonoid (End K V), |
| 120 | + { rw [is_unit.mem_submonoid_iff, linear_map.is_unit_iff, linear_map.ker_eq_bot'], |
| 121 | + intro h, |
| 122 | + exact hv (h v h_eval_p) }, |
| 123 | + -- Hence, there must be a factor `q` of `p` such that `q(f)` is not invertible. |
| 124 | + obtain ⟨q, hq_factor, hq_nonunit⟩ : ∃ q, q ∈ factors p ∧ ¬ is_unit (eval₂ am f q), |
| 125 | + { simp only [←not_imp, (is_unit.mem_submonoid_iff _).symm], |
| 126 | + apply not_forall.1 (λ h, h_eval_p_not_unit (ring_hom_mem_submonoid_of_factors_subset_of_units_subset |
| 127 | + (eval₂_ring_hom_noncomm am (λ x y, (algebra.commutes x y).symm) f) |
| 128 | + (is_unit.submonoid (End K V)) p h_p_ne_0 h _)), |
| 129 | + simp only [is_unit.mem_submonoid_iff, linear_map.is_unit_iff], |
| 130 | + apply ker_eval₂_ring_hom_noncomm_unit_polynomial }, |
| 131 | + -- Since the field is algebraically closed, `q` has degree 1. |
| 132 | + have h_deg_q : q.degree = 1 := is_alg_closed.degree_eq_one_of_irreducible _ |
| 133 | + (ne_zero_of_mem_factors h_p_ne_0 hq_factor) |
| 134 | + ((factors_spec p h_p_ne_0).1 q hq_factor), |
| 135 | + -- Then the kernel of `q(f)` is an eigenspace. |
| 136 | + have h_eigenspace: eigenspace f (-q.coeff 0 / q.leading_coeff) = (eval₂ am f q).ker, |
| 137 | + from eigenspace_eval₂_polynomial_degree_1 f q h_deg_q, |
| 138 | + -- Since `q(f)` is not invertible, the kernel is not `⊥`, and thus there exists an eigenvalue. |
| 139 | + show ∃ (c : K), f.has_eigenvalue c, |
| 140 | + { use -q.coeff 0 / q.leading_coeff, |
| 141 | + rw [has_eigenvalue, h_eigenspace], |
| 142 | + intro h_eval_ker, |
| 143 | + exact hq_nonunit ((linear_map.is_unit_iff (eval₂ am f q)).2 h_eval_ker) } |
| 144 | +end |
| 145 | + |
| 146 | +/-- Eigenvectors corresponding to distinct eigenvalues of a linear operator are linearly |
| 147 | + independent. (Axler's Proposition 2.2) |
| 148 | +
|
| 149 | + We use the eigenvalues as indexing set to ensure that there is only one eigenvector for each |
| 150 | + eigenvalue in the image of `xs`. -/ |
| 151 | +lemma eigenvectors_linear_independent [field K] [vector_space K V] |
| 152 | + (f : End K V) (μs : set K) (xs : μs → V) |
| 153 | + (h_eigenvec : ∀ μ : μs, f.has_eigenvector μ (xs μ)) : |
| 154 | + linear_independent K xs := |
| 155 | +begin |
| 156 | + classical, |
| 157 | + -- We need to show that if a linear combination `l` of the eigenvectors `xs` is `0`, then all |
| 158 | + -- its coefficients are zero. |
| 159 | + suffices : ∀ l, finsupp.total μs V K xs l = 0 → l = 0, |
| 160 | + { rw linear_independent_iff, |
| 161 | + apply this }, |
| 162 | + intros l hl, |
| 163 | + -- We apply induction on the finite set of eigenvalues whose eigenvectors have nonzero |
| 164 | + -- coefficients, i.e. on the support of `l`. |
| 165 | + induction h_l_support : l.support using finset.induction with μ₀ l_support' hμ₀ ih generalizing l, |
| 166 | + -- If the support is empty, all coefficients are zero and we are done. |
| 167 | + { exact finsupp.support_eq_empty.1 h_l_support }, |
| 168 | + -- Now assume that the support of `l` contains at least one eigenvalue `μ₀`. We define a new |
| 169 | + -- linear combination `l'` to apply the induction hypothesis on later. The linear combination `l'` |
| 170 | + -- is derived from `l` by multiplying the coefficient of the eigenvector with eigenvalue `μ` |
| 171 | + -- by `μ - μ₀`. |
| 172 | + -- To get started, we define `l'` as a function `l'_f : μs → K` with potentially infinite support. |
| 173 | + { let l'_f : μs → K := (λ μ : μs, (↑μ - ↑μ₀) * l μ), |
| 174 | + -- The support of `l'_f` is the support of `l` without `μ₀`. |
| 175 | + have h_l_support' : ∀ (μ : μs), μ ∈ l_support' ↔ l'_f μ ≠ 0 , |
| 176 | + { intro μ, |
| 177 | + suffices : μ ∈ l_support' → μ ≠ μ₀, |
| 178 | + { simp [l'_f, ← finsupp.not_mem_support_iff, h_l_support, sub_eq_zero, ←subtype.ext_iff], |
| 179 | + tauto }, |
| 180 | + rintro hμ rfl, |
| 181 | + contradiction }, |
| 182 | + -- Now we can define `l'_f` as an actual linear combination `l'` because we know that the |
| 183 | + -- support is finite. |
| 184 | + let l' : μs →₀ K := |
| 185 | + { to_fun := l'_f, support := l_support', mem_support_to_fun := h_l_support' }, |
| 186 | + -- The linear combination `l'` over `xs` adds up to `0`. |
| 187 | + have total_l' : finsupp.total μs V K xs l' = 0, |
| 188 | + { let g := f - am μ₀, |
| 189 | + have h_gμ₀: g (l μ₀ • xs μ₀) = 0, |
| 190 | + by rw [linear_map.map_smul, linear_map.sub_apply, mem_eigenspace_iff.1 (h_eigenvec _).2, |
| 191 | + algebra_map_End_apply, sub_self, smul_zero], |
| 192 | + have h_useless_filter : finset.filter (λ (a : μs), l'_f a ≠ 0) l_support' = l_support', |
| 193 | + { rw finset.filter_congr _, |
| 194 | + { apply finset.filter_true }, |
| 195 | + { apply_instance }, |
| 196 | + exact λ μ hμ, (iff_true _).mpr ((h_l_support' μ).1 hμ) }, |
| 197 | + have bodies_eq : ∀ (μ : μs), l'_f μ • xs μ = g (l μ • xs μ), |
| 198 | + { intro μ, |
| 199 | + dsimp only [g, l'_f], |
| 200 | + rw [linear_map.map_smul, linear_map.sub_apply, mem_eigenspace_iff.1 (h_eigenvec _).2, |
| 201 | + algebra_map_End_apply, ←sub_smul, smul_smul, mul_comm] }, |
| 202 | + rw [←linear_map.map_zero g, ←hl, finsupp.total_apply, finsupp.total_apply, |
| 203 | + finsupp.sum, finsupp.sum, linear_map.map_sum, h_l_support, |
| 204 | + finset.sum_insert hμ₀, h_gμ₀, zero_add], |
| 205 | + refine finset.sum_congr rfl (λ μ _, _), |
| 206 | + apply bodies_eq }, |
| 207 | + -- Therefore, by the induction hypothesis, all coefficients in `l'` are zero. |
| 208 | + have l'_eq_0 : l' = 0 := ih l' total_l' rfl, |
| 209 | + -- By the defintion of `l'`, this means that `(μ - μ₀) * l μ = 0` for all `μ`. |
| 210 | + have h_mul_eq_0 : ∀ μ : μs, (↑μ - ↑μ₀) * l μ = 0, |
| 211 | + { intro μ, |
| 212 | + calc (↑μ - ↑μ₀) * l μ = l' μ : rfl |
| 213 | + ... = 0 : by { rw [l'_eq_0], refl } }, |
| 214 | + -- Thus, the coefficients in `l` for all `μ ≠ μ₀` are `0`. |
| 215 | + have h_lμ_eq_0 : ∀ μ : μs, μ ≠ μ₀ → l μ = 0, |
| 216 | + { intros μ hμ, |
| 217 | + apply or_iff_not_imp_left.1 (mul_eq_zero.1 (h_mul_eq_0 μ)), |
| 218 | + rwa [sub_eq_zero, ←subtype.ext_iff] }, |
| 219 | + -- So if we sum over all these coefficients, we obtain `0`. |
| 220 | + have h_sum_l_support'_eq_0 : finset.sum l_support' (λ (μ : ↥μs), l μ • xs μ) = 0, |
| 221 | + { rw ←finset.sum_const_zero, |
| 222 | + apply finset.sum_congr rfl, |
| 223 | + intros μ hμ, |
| 224 | + rw h_lμ_eq_0, |
| 225 | + apply zero_smul, |
| 226 | + intro h, |
| 227 | + rw h at hμ, |
| 228 | + contradiction }, |
| 229 | + -- The only potentially nonzero coefficient in `l` is the one corresponding to `μ₀`. But since |
| 230 | + -- the overall sum is `0` by assumption, this coefficient must also be `0`. |
| 231 | + have : l μ₀ = 0, |
| 232 | + { rw [finsupp.total_apply, finsupp.sum, h_l_support, |
| 233 | + finset.sum_insert hμ₀, h_sum_l_support'_eq_0, add_zero] at hl, |
| 234 | + by_contra h, |
| 235 | + exact (h_eigenvec μ₀).1 ((smul_eq_zero.1 hl).resolve_left h) }, |
| 236 | + -- Thus, all coefficients in `l` are `0`. |
| 237 | + show l = 0, |
| 238 | + { ext μ, |
| 239 | + by_cases h_cases : μ = μ₀, |
| 240 | + { rw h_cases, |
| 241 | + assumption }, |
| 242 | + exact h_lμ_eq_0 μ h_cases } } |
| 243 | +end |
| 244 | + |
| 245 | +end End |
| 246 | +end module |
0 commit comments