@@ -7,6 +7,8 @@ import linear_algebra.finite_dimensional
7
7
import linear_algebra.nonsingular_inverse
8
8
import linear_algebra.multilinear
9
9
import linear_algebra.dual
10
+ import ring_theory.algebra_tower
11
+ import ring_theory.matrix_algebra
10
12
11
13
/-!
12
14
# Linear maps and matrices
@@ -299,6 +301,9 @@ begin
299
301
simp [linear_map.to_matrix_apply, is_basis.equiv_fun, matrix.one_apply, finsupp.single, eq_comm]
300
302
end
301
303
304
+ lemma linear_map.to_matrix_one : linear_map.to_matrix hv₁ hv₁ 1 = 1 :=
305
+ linear_map.to_matrix_id hv₁
306
+
302
307
@[simp]
303
308
lemma matrix.to_lin_one : matrix.to_lin hv₁ hv₁ 1 = id :=
304
309
by rw [← linear_map.to_matrix_id hv₁, matrix.to_lin_to_matrix]
@@ -323,6 +328,14 @@ lemma linear_map.to_matrix_mul (f g : M₁ →ₗ[R] M₁) :
323
328
by { rw [show (@has_mul.mul (M₁ →ₗ[R] M₁) _) = linear_map.comp, from rfl,
324
329
linear_map.to_matrix_comp hv₁ hv₁ hv₁ f g] }
325
330
331
+ lemma linear_map.to_matrix_mul_vec_repr (f : M₁ →ₗ[R] M₂) (x : M₁) :
332
+ (linear_map.to_matrix hv₁ hv₂ f).mul_vec (hv₁.repr x) = hv₂.repr (f x) :=
333
+ by { ext i,
334
+ rw [← matrix.to_lin'_apply, linear_map.to_matrix, linear_equiv.trans_apply,
335
+ matrix.to_lin'_to_matrix', linear_equiv.arrow_congr_apply, hv₂.equiv_fun_apply],
336
+ congr,
337
+ exact hv₁.equiv_fun.symm_apply_apply x }
338
+
326
339
lemma matrix.to_lin_mul [decidable_eq m] (A : matrix l m R) (B : matrix m n R) :
327
340
matrix.to_lin hv₁ hv₃ (A ⬝ B) =
328
341
(matrix.to_lin hv₂ hv₃ A).comp (matrix.to_lin hv₁ hv₂ B) :=
@@ -704,6 +717,8 @@ variables {n} {R} {M}
704
717
705
718
@[simp] lemma trace_diag (A : matrix n n M) : trace n R M A = ∑ i, diag n R M A i := rfl
706
719
720
+ lemma trace_apply (A : matrix n n M) : trace n R M A = ∑ i, A i i := rfl
721
+
707
722
@[simp] lemma trace_one [decidable_eq n] :
708
723
trace n R R 1 = fintype.card n :=
709
724
have h : trace n R R 1 = ∑ i, diag n R R 1 i := rfl,
@@ -744,8 +759,11 @@ lemma diagonal_to_lin' (w : n → R) :
744
759
(diagonal w).to_lin' = linear_map.pi (λi, w i • linear_map.proj i) :=
745
760
by ext v j; simp [mul_vec_diagonal]
746
761
747
- /-- An invertible matrix yields a linear equivalence from the free module to itself. -/
748
- def to_linear_equiv (P : matrix n n R) (h : is_unit P) : (n → R) ≃ₗ[R] (n → R) :=
762
+ /-- An invertible matrix yields a linear equivalence from the free module to itself.
763
+
764
+ See `matrix.to_linear_equiv` for the same map on arbitrary modules.
765
+ -/
766
+ def to_linear_equiv' (P : matrix n n R) (h : is_unit P) : (n → R) ≃ₗ[R] (n → R) :=
749
767
have h' : is_unit P.det := P.is_unit_iff_is_unit_det.mp h,
750
768
{ inv_fun := P⁻¹.to_lin',
751
769
left_inv := λ v,
@@ -756,11 +774,11 @@ have h' : is_unit P.det := P.is_unit_iff_is_unit_det.mp h,
756
774
by rw [← matrix.to_lin'_mul, P.mul_nonsing_inv h', matrix.to_lin'_one, linear_map.id_apply],
757
775
..P.to_lin' }
758
776
759
- @[simp] lemma to_linear_equiv_apply (P : matrix n n R) (h : is_unit P) :
760
- (↑(P.to_linear_equiv h) : module.End R (n → R)) = P.to_lin' := rfl
777
+ @[simp] lemma to_linear_equiv'_apply (P : matrix n n R) (h : is_unit P) :
778
+ (↑(P.to_linear_equiv' h) : module.End R (n → R)) = P.to_lin' := rfl
761
779
762
- @[simp] lemma to_linear_equiv_symm_apply (P : matrix n n R) (h : is_unit P) :
763
- (↑(P.to_linear_equiv h).symm : module.End R (n → R)) = P⁻¹.to_lin' := rfl
780
+ @[simp] lemma to_linear_equiv'_symm_apply (P : matrix n n R) (h : is_unit P) :
781
+ (↑(P.to_linear_equiv' h).symm : module.End R (n → R)) = P⁻¹.to_lin' := rfl
764
782
765
783
end ring
766
784
@@ -813,6 +831,34 @@ begin
813
831
apply h₂,
814
832
end
815
833
834
+ variables {R M : Type *} [comm_ring R] [add_comm_group M] [module R M]
835
+ variables {b : n → M} (hb : is_basis R b)
836
+
837
+ include hb
838
+
839
+ /-- Given `hA : is_unit A.det` and `hb : is_basis R b`, `A.to_linear_equiv hb hA` is
840
+ the `linear_equiv` arising from `to_lin hb hb A`.
841
+
842
+ See `matrix.to_linear_equiv'` for this result on `n → R`.
843
+ -/
844
+ @[simps apply]
845
+ def to_linear_equiv [decidable_eq n] (A : matrix n n R) (hA : is_unit A.det) :
846
+ M ≃ₗ[R] M :=
847
+ begin
848
+ refine ⟨to_lin hb hb A, linear_map.map_add _, linear_map.map_smul _, to_lin hb hb A⁻¹,
849
+ λ x, _, λ x, _⟩;
850
+ simp only [← linear_map.comp_apply, ← to_lin_mul,
851
+ matrix.nonsing_inv_mul _ hA, matrix.mul_nonsing_inv _ hA,
852
+ to_lin_one, linear_map.id_apply]
853
+ end
854
+ lemma ker_to_lin_eq_bot [decidable_eq n] (A : matrix n n R) (hA : is_unit A.det) :
855
+ (to_lin hb hb A).ker = ⊥ :=
856
+ ker_eq_bot.mpr (to_linear_equiv hb A hA).injective
857
+
858
+ lemma range_to_lin_eq_top [decidable_eq n] (A : matrix n n R) (hA : is_unit A.det) :
859
+ (to_lin hb hb A).range = ⊤ :=
860
+ range_eq_top.mpr (to_linear_equiv hb A hA).surjective
861
+
816
862
end vector_space
817
863
818
864
section finite_dimensional
@@ -998,6 +1044,92 @@ end reindexing
998
1044
999
1045
end matrix
1000
1046
1047
+ namespace algebra
1048
+
1049
+ section lmul
1050
+
1051
+ variables {R S T : Type *} [comm_ring R] [comm_ring S] [comm_ring T]
1052
+ variables [algebra R S] [algebra S T] [algebra R T] [is_scalar_tower R S T]
1053
+ variables {m n : Type *} [fintype m] [decidable_eq m] [fintype n] [decidable_eq n]
1054
+ variables {b : m → S} (hb : is_basis R b) {c : n → T} (hc : is_basis S c)
1055
+
1056
+ open algebra
1057
+
1058
+ lemma to_matrix_lmul' (x : S) (i j) :
1059
+ linear_map.to_matrix hb hb (lmul R S x) i j = hb.repr (x * b j) i :=
1060
+ by rw [linear_map.to_matrix_apply', lmul_apply]
1061
+
1062
+ @[simp] lemma to_matrix_lsmul (x : R) (i j) :
1063
+ linear_map.to_matrix hb hb (algebra.lsmul R S x) i j = if i = j then x else 0 :=
1064
+ by { rw [linear_map.to_matrix_apply', algebra.lsmul_coe, linear_map.map_smul, finsupp.smul_apply,
1065
+ hb.repr_self_apply, smul_eq_mul, mul_boole],
1066
+ congr' 1 ; simp only [eq_comm] }
1067
+
1068
+ /-- `left_mul_matrix hb x` is the matrix corresponding to the linear map `λ y, x * y`.
1069
+
1070
+ `left_mul_matrix_eq_repr_mul` gives a formula for the entries of `left_mul_matrix`.
1071
+
1072
+ This definition is useful for doing (more) explicit computations with `algebra.lmul`,
1073
+ such as the trace form or norm map for algebras.
1074
+ -/
1075
+ noncomputable def left_mul_matrix : S →ₐ[R] matrix m m R :=
1076
+ { to_fun := λ x, linear_map.to_matrix hb hb (algebra.lmul R S x),
1077
+ map_zero' := by rw [alg_hom.map_zero, linear_equiv.map_zero],
1078
+ map_one' := by rw [alg_hom.map_one, linear_map.to_matrix_one],
1079
+ map_add' := λ x y, by rw [alg_hom.map_add, linear_equiv.map_add],
1080
+ map_mul' := λ x y, by rw [alg_hom.map_mul, linear_map.to_matrix_mul, matrix.mul_eq_mul],
1081
+ commutes' := λ r, by { ext, rw [lmul_algebra_map, to_matrix_lsmul,
1082
+ algebra_map_matrix_apply, id.map_eq_self] } }
1083
+
1084
+ lemma left_mul_matrix_apply (x : S) :
1085
+ left_mul_matrix hb x = linear_map.to_matrix hb hb (lmul R S x) := rfl
1086
+
1087
+ lemma left_mul_matrix_eq_repr_mul (x : S) (i j) :
1088
+ left_mul_matrix hb x i j = hb.repr (x * b j) i :=
1089
+ -- This is defeq to just `to_matrix_lmul' hb x i j`,
1090
+ -- but the unfolding goes a lot faster with this explicit `rw`.
1091
+ by rw [left_mul_matrix_apply, to_matrix_lmul' hb x i j]
1092
+
1093
+ lemma left_mul_matrix_mul_vec_repr (x y : S) :
1094
+ (left_mul_matrix hb x).mul_vec (hb.repr y) = hb.repr (x * y) :=
1095
+ linear_map.to_matrix_mul_vec_repr hb hb (algebra.lmul R S x) y
1096
+
1097
+ @[simp] lemma to_matrix_lmul_eq (x : S) :
1098
+ linear_map.to_matrix hb hb (lmul R S x) = left_mul_matrix hb x :=
1099
+ rfl
1100
+
1101
+ lemma left_mul_matrix_injective : function.injective (left_mul_matrix hb) :=
1102
+ λ x x' h, calc x = algebra.lmul R S x 1 : (mul_one x).symm
1103
+ ... = algebra.lmul R S x' 1 : by rw (linear_map.to_matrix hb hb).injective h
1104
+ ... = x' : mul_one x'
1105
+
1106
+ lemma smul_left_mul_matrix (x) (i j) (k k') :
1107
+ left_mul_matrix (hb.smul hc) x (i, k) (j, k') =
1108
+ left_mul_matrix hb (left_mul_matrix hc x k k') i j :=
1109
+ by simp only [left_mul_matrix_apply, linear_map.to_matrix_apply, is_basis.equiv_fun_apply, mul_comm,
1110
+ is_basis.smul_repr, finsupp.smul_apply, algebra.lmul_apply, id.smul_eq_mul,
1111
+ linear_map.map_smul, mul_smul_comm]
1112
+
1113
+ lemma smul_left_mul_matrix_algebra_map (x : S) :
1114
+ left_mul_matrix (hb.smul hc) (algebra_map _ _ x) = block_diagonal (λ k, left_mul_matrix hb x) :=
1115
+ begin
1116
+ ext ⟨i, k⟩ ⟨j, k'⟩,
1117
+ rw [smul_left_mul_matrix, alg_hom.commutes, block_diagonal_apply, algebra_map_matrix_apply],
1118
+ split_ifs with h; simp [h],
1119
+ end
1120
+
1121
+ lemma smul_left_mul_matrix_algebra_map_eq (x : S) (i j k) :
1122
+ left_mul_matrix (hb.smul hc) (algebra_map _ _ x) (i, k) (j, k) = left_mul_matrix hb x i j :=
1123
+ by rw [smul_left_mul_matrix_algebra_map, block_diagonal_apply_eq]
1124
+
1125
+ lemma smul_left_mul_matrix_algebra_map_ne (x : S) (i j) {k k'}
1126
+ (h : k ≠ k') : left_mul_matrix (hb.smul hc) (algebra_map _ _ x) (i, k) (j, k') = 0 :=
1127
+ by rw [smul_left_mul_matrix_algebra_map, block_diagonal_apply_ne _ _ _ h]
1128
+
1129
+ end lmul
1130
+
1131
+ end algebra
1132
+
1001
1133
namespace linear_map
1002
1134
1003
1135
open_locale matrix
@@ -1008,7 +1140,8 @@ def trace_aux (R : Type u) [comm_ring R] {M : Type v} [add_comm_group M] [module
1008
1140
(M →ₗ[R] M) →ₗ[R] R :=
1009
1141
(matrix.trace ι R R).comp $ linear_map.to_matrix hb hb
1010
1142
1011
- @[simp] lemma trace_aux_def (R : Type u) [comm_ring R] {M : Type v} [add_comm_group M] [module R M]
1143
+ -- Can't be `simp` because it would cause a loop.
1144
+ lemma trace_aux_def (R : Type u) [comm_ring R] {M : Type v} [add_comm_group M] [module R M]
1012
1145
{ι : Type w} [decidable_eq ι] [fintype ι] {b : ι → M} (hb : is_basis R b) (f : M →ₗ[R] M) :
1013
1146
trace_aux R hb f = matrix.trace ι R R (linear_map.to_matrix hb hb f) :=
1014
1147
rfl
@@ -1066,7 +1199,8 @@ else 0
1066
1199
1067
1200
theorem trace_eq_matrix_trace (R : Type u) [comm_ring R] {M : Type v} [add_comm_group M]
1068
1201
[module R M] {ι : Type w} [fintype ι] [decidable_eq ι] {b : ι → M} (hb : is_basis R b)
1069
- (f : M →ₗ[R] M) : trace R M f = matrix.trace ι R R (linear_map.to_matrix hb hb f) :=
1202
+ (f : M →ₗ[R] M) :
1203
+ trace R M f = matrix.trace ι R R (linear_map.to_matrix hb hb f) :=
1070
1204
have ∃ s : finset M, is_basis R (λ x, x : (↑s : set M) → M),
1071
1205
from ⟨finset.univ.image b,
1072
1206
by { rw [finset.coe_image, finset.coe_univ, set.image_univ], exact hb.range }⟩,
0 commit comments