1
1
/-
2
2
Copyright (c) 2019 Johannes Hölzl. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
- Author: Johannes Hölzl, Casper Putz
4
+ Author: Johannes Hölzl, Patrick Massot, Casper Putz
5
5
-/
6
6
import linear_algebra.finite_dimensional
7
7
import linear_algebra.nonsingular_inverse
8
+ import linear_algebra.multilinear
8
9
9
10
/-!
10
11
# Linear maps and matrices
@@ -15,16 +16,37 @@ to matrices. This defines a linear equivalence between linear maps
15
16
between finite-dimensional vector spaces and matrices indexed by
16
17
the respective bases.
17
18
19
+ It also defines the trace of an endomorphism, and the determinant of a family of vectors with
20
+ respect to some basis.
21
+
18
22
Some results are proved about the linear map corresponding to a
19
23
diagonal matrix (`range`, `ker` and `rank`).
20
24
21
25
## Main definitions
22
26
23
- `to_lin`, `to_matrix`, `linear_equiv_matrix`
27
+ In the list below, and in all this file, `R` is a commutative ring (semiring
28
+ is sometimes enough), `M` and its variations are `R`-modules, `ι`, `κ`, `n` and `m` are finite
29
+ types used for indexing.
30
+
31
+ * `to_lin`: the `R`-linear map from `matrix m n R` to `R`-linear maps from `n → R` to `m → R`
32
+ * `to_matrix`: the map in the other direction
33
+ * `linear_equiv_matrix`: given bases `v₁ : ι → M₁` and `v₂ : κ → M₂`, the `R`-linear equivalence
34
+ from `M₁ →ₗ[R] M₂` to `matrix κ ι R`
35
+ * `linear_equiv_matrix'`: the same thing but with `M₁ = n → R` and `M₂ = m → R`, using their
36
+ standard bases
37
+ * `alg_equiv_matrix`: given a basis indexed by `n`, the `R`-algebra equivalence between
38
+ `R`-endomorphisms of `M` and `matrix n n R`
39
+ * `matrix.trace`: the trace of a square matrix
40
+ * `linear_map.trace`: the trace of an endomorphism
41
+ * `is_basis.to_matrix`: the matrix whose columns are a given family of vectors in a given basis
42
+ * `is_basis.to_matrix_equiv`: given a basis, the linear equivalence between families of vectors
43
+ and matrices arising from `is_basis.to_matrix`
44
+ * `is_basis.det`: the determinant of a family of vectors with respect to a basis, as a multilinear
45
+ map
24
46
25
47
## Tags
26
48
27
- linear_map, matrix, linear_equiv, diagonal
49
+ linear_map, matrix, linear_equiv, diagonal, det, trace
28
50
29
51
-/
30
52
@@ -202,16 +224,16 @@ variables {ι κ M₁ M₂ : Type*}
202
224
equivalence between linear maps `M₁ →ₗ M₂` and matrices over `R` indexed by the bases. -/
203
225
def linear_equiv_matrix (hv₁ : is_basis R v₁) (hv₂ : is_basis R v₂) :
204
226
(M₁ →ₗ[R] M₂) ≃ₗ[R] matrix κ ι R :=
205
- linear_equiv.trans (linear_equiv.arrow_congr (equiv_fun_basis hv₁) (equiv_fun_basis hv₂) ) linear_equiv_matrix'
227
+ linear_equiv.trans (linear_equiv.arrow_congr hv₁.equiv_fun hv₂.equiv_fun ) linear_equiv_matrix'
206
228
207
229
variables (hv₁ : is_basis R v₁) (hv₂ : is_basis R v₂)
208
230
209
231
lemma linear_equiv_matrix_apply (f : M₁ →ₗ[R] M₂) (i : κ) (j : ι) :
210
- linear_equiv_matrix hv₁ hv₂ f i j = equiv_fun_basis hv₂ (f (v₁ j)) i :=
232
+ linear_equiv_matrix hv₁ hv₂ f i j = hv₂.equiv_fun (f (v₁ j)) i :=
211
233
by simp only [linear_equiv_matrix, to_matrix, to_matrixₗ, ite_smul,
212
234
linear_equiv.trans_apply, linear_equiv.arrow_congr_apply,
213
235
linear_equiv.coe_coe, linear_equiv_matrix'_apply, finset.mem_univ, if_true,
214
- one_smul, zero_smul, finset.sum_ite_eq, equiv_fun_basis_symm_apply ]
236
+ one_smul, zero_smul, finset.sum_ite_eq, hv₁.equiv_fun_symm_apply ]
215
237
216
238
lemma linear_equiv_matrix_apply' (f : M₁ →ₗ[R] M₂) (i : κ) (j : ι) :
217
239
linear_equiv_matrix hv₁ hv₂ f i j = hv₂.repr (f (v₁ j)) i :=
@@ -221,7 +243,7 @@ linear_equiv_matrix_apply hv₁ hv₂ f i j
221
243
lemma linear_equiv_matrix_id : linear_equiv_matrix hv₁ hv₁ id = 1 :=
222
244
begin
223
245
ext i j,
224
- simp [linear_equiv_matrix_apply, equiv_fun_basis , matrix.one_apply, finsupp.single, eq_comm]
246
+ simp [linear_equiv_matrix_apply, is_basis.equiv_fun , matrix.one_apply, finsupp.single, eq_comm]
225
247
end
226
248
227
249
@[simp] lemma linear_equiv_matrix_symm_one : (linear_equiv_matrix hv₁ hv₁).symm 1 = id :=
@@ -242,7 +264,7 @@ begin
242
264
← equiv.of_injective_apply _ hv₁.injective, ← equiv.of_injective_apply _ hv₂.injective,
243
265
to_matrix_of_equiv, ← linear_equiv.trans_apply, linear_equiv.arrow_congr_trans], congr' 3 ;
244
266
refine function.left_inverse.injective linear_equiv.symm_symm _; ext x;
245
- simp_rw [linear_equiv.symm_trans_apply, equiv_fun_basis_symm_apply , fun_congr_left_symm,
267
+ simp_rw [linear_equiv.symm_trans_apply, is_basis.equiv_fun_symm_apply , fun_congr_left_symm,
246
268
fun_congr_left_apply, fun_left_apply],
247
269
convert (finset.sum_equiv (equiv.of_injective _ hv₁.injective) _).symm,
248
270
simp_rw [equiv.symm_apply_apply, equiv.of_injective_apply, subtype.coe_mk],
@@ -275,7 +297,7 @@ lemma linear_equiv_matrix_comp [decidable_eq ι] (f : M₂ →ₗ[R] M₃) (g :
275
297
linear_equiv_matrix hv₁ hv₃ (f.comp g) =
276
298
linear_equiv_matrix hv₂ hv₃ f ⬝ linear_equiv_matrix hv₁ hv₂ g :=
277
299
by simp_rw [linear_equiv_matrix, linear_equiv.trans_apply, linear_equiv_matrix'_apply,
278
- linear_equiv.arrow_congr_comp _ (equiv_fun_basis hv₂) , comp_to_matrix_mul]
300
+ linear_equiv.arrow_congr_comp _ hv₂.equiv_fun , comp_to_matrix_mul]
279
301
280
302
lemma linear_equiv_matrix_mul [decidable_eq ι] (f g : M₁ →ₗ[R] M₁) :
281
303
linear_equiv_matrix hv₁ hv₁ (f * g) = linear_equiv_matrix hv₁ hv₁ f * linear_equiv_matrix hv₁ hv₁ g :=
294
316
295
317
end comp
296
318
297
- section det
319
+ end matrix
320
+
321
+ section is_basis_to_matrix
322
+
323
+ variables {ι ι' R M : Type *} [fintype ι] [decidable_eq ι]
324
+ [comm_ring R] [add_comm_group M] [module R M]
325
+
326
+ open function matrix
327
+
328
+ /-- From a basis `e : ι → M` and a family of vectors `v : ι → M`, make the matrix whose columns
329
+ are the vectors `v i` written in the basis `e`. -/
330
+ def is_basis.to_matrix {e : ι → M} (he : is_basis R e) (v : ι → M) : matrix ι ι R :=
331
+ linear_equiv_matrix he he (he.constr v)
332
+
333
+ variables {e : ι → M} (he : is_basis R e) (v : ι → M) (i j : ι)
334
+
335
+ namespace is_basis
336
+
337
+ lemma to_matrix_apply : he.to_matrix v i j = he.equiv_fun (v j) i :=
338
+ by simp [is_basis.to_matrix, linear_equiv_matrix_apply]
339
+
340
+ @[simp] lemma to_matrix_self : he.to_matrix e = 1 :=
341
+ begin
342
+ rw is_basis.to_matrix,
343
+ ext i j,
344
+ simp [linear_equiv_matrix_apply, is_basis.equiv_fun, matrix.one_apply, finsupp.single, eq_comm]
345
+ end
346
+
347
+ lemma to_matrix_update (x : M) :
348
+ he.to_matrix (function.update v i x) = matrix.update_column (he.to_matrix v) i (he.repr x) :=
349
+ begin
350
+ ext j k,
351
+ rw [is_basis.to_matrix, linear_equiv_matrix_apply' he he (he.constr (update v i x)),
352
+ matrix.update_column_apply, constr_basis, he.to_matrix_apply],
353
+ split_ifs,
354
+ { rw [h, update_same i x v] },
355
+ { rw [update_noteq h, he.equiv_fun_apply] },
356
+ end
357
+
358
+ /-- From a basis `e : ι → M`, build a linear equivalence between families of vectors `v : ι → M`,
359
+ and matrices, making the matrix whose columns are the vectors `v i` written in the basis `e`. -/
360
+ def to_matrix_equiv {e : ι → M} (he : is_basis R e) : (ι → M) ≃ₗ[R] matrix ι ι R :=
361
+ { to_fun := he.to_matrix,
362
+ map_add' := λ v w, begin
363
+ ext i j,
364
+ change _ = _ + _,
365
+ simp [he.to_matrix_apply]
366
+ end ,
367
+ map_smul' := begin
368
+ intros c v,
369
+ ext i j,
370
+ simp [he.to_matrix_apply]
371
+ end ,
372
+ inv_fun := λ m j, ∑ i, (m i j) • e i,
373
+ left_inv := begin
374
+ intro v,
375
+ ext j,
376
+ simp [he.to_matrix_apply, he.equiv_fun_total (v j)]
377
+ end ,
378
+ right_inv := begin
379
+ intros x,
380
+ ext k l,
381
+ simp [he.to_matrix_apply, he.equiv_fun.map_sum, he.equiv_fun.map_smul,
382
+ fintype.sum_apply k (λ i, x i l • he.equiv_fun (e i)),
383
+ he.equiv_fun_self]
384
+ end }
385
+
386
+ end is_basis
298
387
388
+ end is_basis_to_matrix
389
+
390
+ open_locale matrix
391
+
392
+ section det
393
+ open matrix
299
394
variables {R ι M M' : Type *} [comm_ring R]
300
395
[add_comm_group M] [module R M]
301
396
[add_comm_group M'] [module R M']
@@ -335,8 +430,43 @@ def linear_equiv.of_is_unit_det {f : M →ₗ[R] M'} {hv : is_basis R v} {hv' :
335
430
simp [h]
336
431
end }
337
432
433
+ variables {e : ι → M} (he : is_basis R e)
434
+
435
+ /-- The determinant of a family of vectors with respect to some basis, as a multilinear map. -/
436
+ def is_basis.det : multilinear_map R (λ i : ι, M) R :=
437
+ { to_fun := λ v, det (he.to_matrix v),
438
+ map_add' := begin
439
+ intros v i x y,
440
+ simp only [he.to_matrix_update, linear_map.map_add],
441
+ apply det_update_column_add
442
+ end ,
443
+ map_smul' := begin
444
+ intros u i c x,
445
+ simp only [he.to_matrix_update, algebra.id.smul_eq_mul, map_smul_eq_smul_map],
446
+ apply det_update_column_smul
447
+ end }
448
+
449
+ lemma is_basis.det_apply (v : ι → M) : he.det v = det (he.to_matrix v) := rfl
450
+
451
+ lemma is_basis.det_self : he.det e = 1 :=
452
+ by simp [he.det_apply]
453
+
454
+ lemma is_basis.iff_det {v : ι → M} : is_basis R v ↔ is_unit (he.det v) :=
455
+ begin
456
+ split,
457
+ { intro hv,
458
+ change is_unit (linear_equiv_matrix he he (equiv_of_is_basis he hv $ equiv.refl ι)).det,
459
+ apply linear_equiv.is_unit_det },
460
+ { intro h,
461
+ convert linear_equiv.is_basis he (linear_equiv.of_is_unit_det h),
462
+ ext i,
463
+ exact (constr_basis he).symm },
464
+ end
465
+
338
466
end det
339
467
468
+ namespace matrix
469
+
340
470
section trace
341
471
342
472
variables (n) (R : Type v) (M : Type w) [semiring R] [add_comm_monoid M] [semimodule R M]
@@ -685,4 +815,4 @@ square matrices. -/
685
815
def alg_equiv_matrix {R : Type v} {M : Type w}
686
816
[comm_ring R] [add_comm_group M] [module R M] [decidable_eq n] {b : n → M} (h : is_basis R b) :
687
817
module.End R M ≃ₐ[R] matrix n n R :=
688
- (equiv_fun_basis h) .alg_conj.trans alg_equiv_matrix'
818
+ h.equiv_fun .alg_conj.trans alg_equiv_matrix'
0 commit comments