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

Commit cd36773

Browse files
committed
feat(linear_algebra/eigenspace): add generalized eigenspaces (#4015)
Add the definition of generalized eigenspaces, eigenvectors and eigenvalues. Add some basic lemmas about them. Another step towards #3864.
1 parent 7310eab commit cd36773

File tree

2 files changed

+119
-3
lines changed

2 files changed

+119
-3
lines changed

src/algebra/group_power.lean

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,16 @@ namespace commute
6969
variables [monoid M] {a b : M}
7070

7171
@[simp] theorem pow_right (h : commute a b) (n : ℕ) : commute a (b ^ n) := h.pow_right n
72+
7273
@[simp] theorem pow_left (h : commute a b) (n : ℕ) : commute (a ^ n) b := (h.symm.pow_right n).symm
74+
7375
@[simp] theorem pow_pow (h : commute a b) (m n : ℕ) : commute (a ^ m) (b ^ n) :=
7476
(h.pow_left m).pow_right n
7577

7678
@[simp] theorem self_pow (a : M) (n : ℕ) : commute a (a ^ n) := (commute.refl a).pow_right n
79+
7780
@[simp] theorem pow_self (a : M) (n : ℕ) : commute (a ^ n) a := (commute.refl a).pow_left n
81+
7882
@[simp] theorem pow_pow_self (a : M) (m n : ℕ) : commute (a ^ m) (a ^ n) :=
7983
(commute.refl a).pow_pow m n
8084

@@ -87,12 +91,15 @@ section monoid
8791
variables [monoid M] [monoid N] [add_monoid A] [add_monoid B]
8892

8993
@[simp] theorem pow_zero (a : M) : a^0 = 1 := rfl
94+
9095
@[simp] theorem zero_nsmul (a : A) : 0 •ℕ a = 0 := rfl
9196

9297
theorem pow_succ (a : M) (n : ℕ) : a^(n+1) = a * a^n := rfl
98+
9399
theorem succ_nsmul (a : A) (n : ℕ) : (n+1) •ℕ a = a + n •ℕ a := rfl
94100

95101
@[simp] theorem pow_one (a : M) : a^1 = a := mul_one _
102+
96103
@[simp] theorem one_nsmul (a : A) : 1 •ℕ a = a := add_zero _
97104

98105
@[simp] lemma pow_ite (P : Prop) [decidable P] (a : M) (b c : ℕ) :
@@ -108,55 +115,77 @@ by split_ifs; refl
108115
by simp
109116

110117
theorem pow_mul_comm' (a : M) (n : ℕ) : a^n * a = a * a^n := commute.pow_self a n
118+
111119
theorem nsmul_add_comm' : ∀ (a : A) (n : ℕ), n •ℕ a + a = a + n •ℕ a :=
112120
@pow_mul_comm' (multiplicative A) _
113121

114122
theorem pow_succ' (a : M) (n : ℕ) : a^(n+1) = a^n * a :=
115123
by rw [pow_succ, pow_mul_comm']
124+
116125
theorem succ_nsmul' (a : A) (n : ℕ) : (n+1) •ℕ a = n •ℕ a + a :=
117126
@pow_succ' (multiplicative A) _ _ _
118127

119128
theorem pow_two (a : M) : a^2 = a * a :=
120129
show a*(a*1)=a*a, by rw mul_one
130+
121131
theorem two_nsmul (a : A) : 2 •ℕ a = a + a :=
122132
@pow_two (multiplicative A) _ a
123133

124134
theorem pow_add (a : M) (m n : ℕ) : a^(m + n) = a^m * a^n :=
125135
by induction n with n ih; [rw [add_zero, pow_zero, mul_one],
126136
rw [pow_succ', ← mul_assoc, ← ih, ← pow_succ', add_assoc]]
137+
127138
theorem add_nsmul : ∀ (a : A) (m n : ℕ), (m + n) •ℕ a = m •ℕ a + n •ℕ a :=
128139
@pow_add (multiplicative A) _
129140

130141
@[simp] theorem one_pow (n : ℕ) : (1 : M)^n = 1 :=
131142
by induction n with n ih; [refl, rw [pow_succ, ih, one_mul]]
143+
132144
@[simp] theorem nsmul_zero (n : ℕ) : n •ℕ (0 : A) = 0 :=
133145
by induction n with n ih; [refl, rw [succ_nsmul, ih, zero_add]]
134146

135147
theorem pow_mul (a : M) (m n : ℕ) : a^(m * n) = (a^m)^n :=
136148
by induction n with n ih; [rw mul_zero, rw [nat.mul_succ, pow_add, pow_succ', ih]]; refl
149+
137150
theorem mul_nsmul' : ∀ (a : A) (m n : ℕ), m * n •ℕ a = n •ℕ (m •ℕ a) :=
138151
@pow_mul (multiplicative A) _
139152

140153
theorem pow_mul' (a : M) (m n : ℕ) : a^(m * n) = (a^n)^m :=
141154
by rw [mul_comm, pow_mul]
155+
142156
theorem mul_nsmul (a : A) (m n : ℕ) : m * n •ℕ a = m •ℕ (n •ℕ a) :=
143157
@pow_mul' (multiplicative A) _ a m n
144158

159+
theorem pow_mul_pow_sub (a : M) {m n : ℕ} (h : m ≤ n) : a ^ m * a ^ (n - m) = a ^ n :=
160+
by rw [←pow_add, nat.add_sub_cancel' h]
161+
162+
theorem nsmul_add_sub_nsmul (a : A) {m n : ℕ} (h : m ≤ n) : (m •ℕ a) + ((n - m) •ℕ a) = n •ℕ a :=
163+
@pow_mul_pow_sub (multiplicative A) _ _ _ _ h
164+
165+
theorem pow_sub_mul_pow (a : M) {m n : ℕ} (h : m ≤ n) : a ^ (n - m) * a ^ m = a ^ n :=
166+
by rw [←pow_add, nat.sub_add_cancel h]
167+
168+
theorem sub_nsmul_nsmul_add (a : A) {m n : ℕ} (h : m ≤ n) : ((n - m) •ℕ a) + (m •ℕ a) = n •ℕ a :=
169+
@pow_sub_mul_pow (multiplicative A) _ _ _ _ h
170+
145171
@[simp] theorem nsmul_one [has_one A] : ∀ n : ℕ, n •ℕ (1 : A) = n :=
146172
add_monoid_hom.eq_nat_cast
147173
⟨λ n, n •ℕ (1 : A), zero_nsmul _, λ _ _, add_nsmul _ _ _⟩
148174
(one_nsmul _)
149175

150176
theorem pow_bit0 (a : M) (n : ℕ) : a ^ bit0 n = a^n * a^n := pow_add _ _ _
177+
151178
theorem bit0_nsmul (a : A) (n : ℕ) : bit0 n •ℕ a = n •ℕ a + n •ℕ a := add_nsmul _ _ _
152179

153180
theorem pow_bit1 (a : M) (n : ℕ) : a ^ bit1 n = a^n * a^n * a :=
154181
by rw [bit1, pow_succ', pow_bit0]
182+
155183
theorem bit1_nsmul : ∀ (a : A) (n : ℕ), bit1 n •ℕ a = n •ℕ a + n •ℕ a + a :=
156184
@pow_bit1 (multiplicative A) _
157185

158186
theorem pow_mul_comm (a : M) (m n : ℕ) : a^m * a^n = a^n * a^m :=
159187
commute.pow_pow_self a m n
188+
160189
theorem nsmul_add_comm : ∀ (a : A) (m n : ℕ), m •ℕ a + n •ℕ a = n •ℕ a + m •ℕ a :=
161190
@pow_mul_comm (multiplicative A) _
162191

@@ -167,6 +196,7 @@ begin
167196
{ refl },
168197
{ rw [list.repeat_succ, list.prod_cons, ih], refl, }
169198
end
199+
170200
@[simp, priority 500]
171201
theorem list.sum_repeat : ∀ (a : A) (n : ℕ), (list.repeat a n).sum = n •ℕ a :=
172202
@list.prod_repeat (multiplicative A) _
@@ -215,6 +245,7 @@ variables [comm_monoid M] [add_comm_monoid A]
215245

216246
theorem mul_pow (a b : M) (n : ℕ) : (a * b)^n = a^n * b^n :=
217247
(commute.all a b).mul_pow n
248+
218249
theorem nsmul_add : ∀ (a b : A) (n : ℕ), n •ℕ (a + b) = n •ℕ a + n •ℕ b :=
219250
@mul_pow (multiplicative A) _
220251

@@ -239,18 +270,21 @@ section nat
239270
@[simp] theorem inv_pow (a : G) (n : ℕ) : (a⁻¹)^n = (a^n)⁻¹ :=
240271
by induction n with n ih; [exact one_inv.symm,
241272
rw [pow_succ', pow_succ, ih, mul_inv_rev]]
273+
242274
@[simp] theorem neg_nsmul : ∀ (a : A) (n : ℕ), n •ℕ (-a) = -(n •ℕ a) :=
243275
@inv_pow (multiplicative A) _
244276

245277
theorem pow_sub (a : G) {m n : ℕ} (h : n ≤ m) : a^(m - n) = a^m * (a^n)⁻¹ :=
246278
have h1 : m - n + n = m, from nat.sub_add_cancel h,
247279
have h2 : a^(m - n) * a^n = a^m, by rw [←pow_add, h1],
248280
eq_mul_inv_of_mul_eq h2
281+
249282
theorem nsmul_sub : ∀ (a : A) {m n : ℕ}, n ≤ m → (m - n) •ℕ a = m •ℕ a - n •ℕ a :=
250283
@pow_sub (multiplicative A) _
251284

252285
theorem pow_inv_comm (a : G) (m n : ℕ) : (a⁻¹)^m * a^n = a^n * (a⁻¹)^m :=
253286
(commute.refl a).inv_left.pow_pow m n
287+
254288
theorem nsmul_neg_comm : ∀ (a : A) (m n : ℕ), m •ℕ (-a) + n •ℕ a = n •ℕ a + m •ℕ (-a) :=
255289
@pow_inv_comm (multiplicative A) _
256290
end nat
@@ -278,26 +312,32 @@ def gsmul (n : ℤ) (a : A) : A :=
278312
infix ` •ℤ `:70 := gsmul
279313

280314
@[simp] theorem gpow_coe_nat (a : G) (n : ℕ) : a ^ (n:ℤ) = a ^ n := rfl
315+
281316
@[simp] theorem gsmul_coe_nat (a : A) (n : ℕ) : n •ℤ a = n •ℕ a := rfl
282317

283318
theorem gpow_of_nat (a : G) (n : ℕ) : a ^ of_nat n = a ^ n := rfl
319+
284320
theorem gsmul_of_nat (a : A) (n : ℕ) : of_nat n •ℤ a = n •ℕ a := rfl
285321

286322
@[simp] theorem gpow_neg_succ_of_nat (a : G) (n : ℕ) : a ^ -[1+n] = (a ^ n.succ)⁻¹ := rfl
323+
287324
@[simp] theorem gsmul_neg_succ_of_nat (a : A) (n : ℕ) : -[1+n] •ℤ a = - (n.succ •ℕ a) := rfl
288325

289326
local attribute [ematch] le_of_lt
290327
open nat
291328

292329
@[simp] theorem gpow_zero (a : G) : a ^ (0:ℤ) = 1 := rfl
330+
293331
@[simp] theorem zero_gsmul (a : A) : (0:ℤ) •ℤ a = 0 := rfl
294332

295333
@[simp] theorem gpow_one (a : G) : a ^ (1:ℤ) = a := pow_one a
334+
296335
@[simp] theorem one_gsmul (a : A) : (1:ℤ) •ℤ a = a := add_zero _
297336

298337
@[simp] theorem one_gpow : ∀ (n : ℤ), (1 : G) ^ n = 1
299338
| (n : ℕ) := one_pow _
300339
| -[1+ n] := show _⁻¹=(1:G), by rw [_root_.one_pow, one_inv]
340+
301341
@[simp] theorem gsmul_zero : ∀ (n : ℤ), n •ℤ (0 : A) = 0 :=
302342
@one_gpow (multiplicative A) _
303343

@@ -313,6 +353,7 @@ by simp only [mul_inv_rev, gpow_one, gpow_neg]
313353
@gpow_neg (multiplicative A) _
314354

315355
theorem gpow_neg_one (x : G) : x ^ (-1:ℤ) = x⁻¹ := congr_arg has_inv.inv $ pow_one x
356+
316357
theorem neg_one_gsmul (x : A) : (-1:ℤ) •ℤ x = -x := congr_arg has_neg.neg $ one_nsmul x
317358

318359
theorem gsmul_one [has_one A] (n : ℤ) : n •ℤ (1 : A) = n :=
@@ -321,6 +362,7 @@ by cases n; simp
321362
theorem inv_gpow (a : G) : ∀n:ℤ, a⁻¹ ^ n = (a ^ n)⁻¹
322363
| (n : ℕ) := inv_pow a n
323364
| -[1+ n] := congr_arg has_inv.inv $ inv_pow a (n+1)
365+
324366
theorem gsmul_neg (a : A) (n : ℤ) : gsmul n (- a) = - gsmul n a :=
325367
@inv_gpow (multiplicative A) _ a n
326368

@@ -363,11 +405,13 @@ lemma sub_gsmul (m n : ℤ) (a : A) : (m - n) •ℤ a = m •ℤ a - n •ℤ a
363405

364406
theorem gpow_one_add (a : G) (i : ℤ) : a ^ (1 + i) = a * a ^ i :=
365407
by rw [gpow_add, gpow_one]
408+
366409
theorem one_add_gsmul : ∀ (a : A) (i : ℤ), (1 + i) •ℤ a = a + i •ℤ a :=
367410
@gpow_one_add (multiplicative A) _
368411

369412
theorem gpow_mul_comm (a : G) (i j : ℤ) : a ^ i * a ^ j = a ^ j * a ^ i :=
370413
by rw [← gpow_add, ← gpow_add, add_comm]
414+
371415
theorem gsmul_add_comm : ∀ (a : A) (i j), i •ℤ a + j •ℤ a = j •ℤ a + i •ℤ a :=
372416
@gpow_mul_comm (multiplicative A) _
373417

@@ -380,14 +424,17 @@ theorem gsmul_mul' : ∀ (a : A) (m n : ℤ), m * n •ℤ a = n •ℤ (m •
380424

381425
theorem gpow_mul' (a : G) (m n : ℤ) : a ^ (m * n) = (a ^ n) ^ m :=
382426
by rw [mul_comm, gpow_mul]
427+
383428
theorem gsmul_mul (a : A) (m n : ℤ) : m * n •ℤ a = m •ℤ (n •ℤ a) :=
384429
by rw [mul_comm, gsmul_mul']
385430

386431
theorem gpow_bit0 (a : G) (n : ℤ) : a ^ bit0 n = a ^ n * a ^ n := gpow_add _ _ _
432+
387433
theorem bit0_gsmul (a : A) (n : ℤ) : bit0 n •ℤ a = n •ℤ a + n •ℤ a := gpow_add _ _ _
388434

389435
theorem gpow_bit1 (a : G) (n : ℤ) : a ^ bit1 n = a ^ n * a ^ n * a :=
390436
by rw [bit1, gpow_add]; simp [gpow_bit0]
437+
391438
theorem bit1_gsmul : ∀ (a : A) (n : ℤ), bit1 n •ℤ a = n •ℤ a + n •ℤ a + a :=
392439
@gpow_bit1 (multiplicative A) _
393440

src/linear_algebra/eigenspace.lean

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,21 @@ import linear_algebra.finsupp
1010
/-!
1111
# Eigenvectors and eigenvalues
1212
13-
This file defines eigenspaces and eigenvalues.
13+
This file defines eigenspaces, eigenvalues, and eigenvalues, as well as their generalized
14+
counterparts.
1415
1516
An eigenspace of a linear map `f` for a scalar `μ` is the kernel of the map `(f - μ • id)`. The
1617
nonzero elements of an eigenspace are eigenvectors `x`. They have the property `f x = μ • x`. If
1718
there are eigenvectors for a scalar `μ`, the scalar `μ` is called an eigenvalue.
1819
1920
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 μ`.
21+
`has_eigenvector` permits only nonzero vectors. For an eigenvector `x` that may also be `0`, we
22+
write `x ∈ f.eigenspace μ`.
23+
24+
A generalized eigenspace of a linear map `f` for a natural number `k` and a scalar `μ` is the kernel
25+
of the map `(f - μ • id) ^ k`. The nonzero elements of a generalized eigenspace are generalized
26+
eigenvectors `x`. If there are generalized eigenvectors for a natural number `k` and a scalar `μ`,
27+
the scalar `μ` is called a generalized eigenvalue.
2228
2329
## Notations
2430
@@ -242,5 +248,68 @@ begin
242248
exact h_lμ_eq_0 μ h_cases } }
243249
end
244250

251+
/-- The generalized eigenspace for a linear map `f`, a scalar `μ`, and an exponent `k ∈ ℕ` is the
252+
kernel of `(f - μ • id) ^ k`. -/
253+
def generalized_eigenspace [comm_ring K] [module K V]
254+
(f : End K V) (μ : K) (k : ℕ) : submodule K V :=
255+
((f - am μ) ^ k).ker
256+
257+
/-- A nonzero element of a generalized eigenspace is a generalized eigenvector. -/
258+
def has_generalized_eigenvector [comm_ring K] [module K V]
259+
(f : End K V) (μ : K) (k : ℕ) (x : V) : Prop :=
260+
x ≠ 0 ∧ x ∈ generalized_eigenspace f μ k
261+
262+
/-- A scalar `μ` is a generalized eigenvalue for a linear map `f` and an exponent `k ∈ ℕ` if there
263+
are generalized eigenvectors for `f`, `k`, and `μ`. -/
264+
def has_generalized_eigenvalue [comm_ring K] [module K V]
265+
(f : End K V) (μ : K) (k : ℕ) : Prop :=
266+
generalized_eigenspace f μ k ≠ ⊥
267+
268+
/-- The exponent of a generalized eigenvalue is never 0. -/
269+
lemma exp_ne_zero_of_has_generalized_eigenvalue [comm_ring K] [module K V]
270+
{f : End K V} {μ : K} {k : ℕ} (h : f.has_generalized_eigenvalue μ k) :
271+
k ≠ 0 :=
272+
begin
273+
rintro rfl,
274+
exact h linear_map.ker_id
275+
end
276+
277+
/-- A generalized eigenspace for some exponent `k` is contained in
278+
the generalized eigenspace for exponents larger than `k`. -/
279+
lemma generalized_eigenspace_mono [field K] [vector_space K V]
280+
{f : End K V} {μ : K} {k : ℕ} {m : ℕ} (hm : k ≤ m) :
281+
f.generalized_eigenspace μ k ≤ f.generalized_eigenspace μ m :=
282+
begin
283+
simp only [generalized_eigenspace, ←pow_sub_mul_pow _ hm],
284+
exact linear_map.ker_le_ker_comp ((f - am μ) ^ k) ((f - am μ) ^ (m - k))
285+
end
286+
287+
/-- A generalized eigenvalue for some exponent `k` is also
288+
a generalized eigenvalue for exponents larger than `k`. -/
289+
lemma has_generalized_eigenvalue_of_has_generalized_eigenvalue_of_le [field K] [vector_space K V]
290+
{f : End K V} {μ : K} {k : ℕ} {m : ℕ} (hm : k ≤ m) (hk : f.has_generalized_eigenvalue μ k) :
291+
f.has_generalized_eigenvalue μ m :=
292+
begin
293+
unfold has_generalized_eigenvalue at *,
294+
contrapose! hk,
295+
rw [←le_bot_iff, ←hk],
296+
exact generalized_eigenspace_mono hm
297+
end
298+
299+
/-- The eigenspace is a subspace of the generalized eigenspace. -/
300+
lemma eigenspace_le_generalized_eigenspace [field K] [vector_space K V]
301+
{f : End K V} {μ : K} {k : ℕ} (hk : 0 < k) :
302+
f.eigenspace μ ≤ f.generalized_eigenspace μ k :=
303+
generalized_eigenspace_mono (nat.succ_le_of_lt hk)
304+
305+
/-- All eigenvalues are generalized eigenvalues. -/
306+
lemma has_generalized_eigenvalue_of_has_eigenvalue [field K] [vector_space K V]
307+
{f : End K V} {μ : K} {k : ℕ} (hk : 0 < k) (hμ : f.has_eigenvalue μ) :
308+
f.has_generalized_eigenvalue μ k :=
309+
begin
310+
apply has_generalized_eigenvalue_of_has_generalized_eigenvalue_of_le hk,
311+
rwa [has_generalized_eigenvalue, generalized_eigenspace, pow_one]
312+
end
313+
245314
end End
246315
end module

0 commit comments

Comments
 (0)