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
4
+ Author: Johannes Hölzl, Casper Putz
5
5
6
- Linear structures on function with finit support `α →₀ β` and multivariate polynomials .
6
+ The equivalence between matrices and linear maps .
7
7
-/
8
+
8
9
import data.matrix.basic
9
10
import linear_algebra.dimension linear_algebra.tensor_product
11
+
12
+ /-!
13
+
14
+ # Linear maps and matrices
15
+
16
+ This file defines the maps to send matrices to a linear map,
17
+ and to send linear maps between modules with a finite bases
18
+ to matrices. This defines a linear equivalence between linear maps
19
+ between finite-dimensional vector spaces and matrices indexed by
20
+ the respective bases.
21
+
22
+ Some results are proved about the linear map corresponding to a
23
+ diagonal matrix (range, ker and rank).
24
+
25
+ ## Main definitions
26
+
27
+ to_lin, to_matrix, lin_equiv_matrix
28
+
29
+ ## Tags
30
+
31
+ linear_map, matrix, linear_equiv, diagonal
32
+
33
+ -/
34
+
10
35
noncomputable theory
11
36
12
- open lattice set linear_map submodule
37
+ open set submodule
13
38
14
- namespace matrix
15
39
universes u v
16
- variables {l m n o : Type u} [fintype l] [fintype m] [fintype n] [fintype o ]
40
+ variables {l m n : Type u} [fintype l] [fintype m] [fintype n]
17
41
18
- instance [decidable_eq m] [decidable_eq n] (α) [fintype α] : fintype (matrix m n α) :=
19
- by unfold matrix; apply_instance
42
+ namespace matrix
20
43
21
- section ring
22
44
variables {α : Type v} [comm_ring α]
45
+ instance [decidable_eq m] [decidable_eq n] (α) [fintype α] : fintype (matrix m n α) :=
46
+ by unfold matrix; apply_instance
23
47
48
+ /-- Evaluation of matrices gives a linear map from matrix m n α to
49
+ linear maps (n → α) →ₗ[ α ] (m → α). -/
24
50
def eval : (matrix m n α) →ₗ[α] ((n → α) →ₗ[α] (m → α)) :=
25
51
begin
26
52
refine linear_map.mk₂ α mul_vec _ _ _ _,
43
69
refl }
44
70
end
45
71
72
+ /-- Evaluation of matrices gives a map from matrix m n α to
73
+ linear maps (n → α) →ₗ[ α ] (m → α). -/
46
74
def to_lin : matrix m n α → (n → α) →ₗ[α] (m → α) := eval.to_fun
47
75
48
76
lemma to_lin_add (M N : matrix m n α) : (M + N).to_lin = M.to_lin + N.to_lin :=
@@ -72,8 +100,96 @@ begin
72
100
rw [mul_assoc]
73
101
end
74
102
75
- section
76
- open linear_map
103
+ end matrix
104
+
105
+ namespace linear_map
106
+
107
+ variables {α : Type v} [comm_ring α]
108
+
109
+ /-- The linear map from linear maps (n → α) →ₗ[ α ] (m → α) to matrix m n α. -/
110
+ def to_matrixₗ [decidable_eq n] : ((n → α) →ₗ[α] (m → α)) →ₗ[α] matrix m n α :=
111
+ begin
112
+ refine linear_map.mk (λ f i j, f (λ n, ite (j = n) 1 0 ) i) _ _,
113
+ { assume f g, simp only [add_apply], refl },
114
+ { assume f g, simp only [smul_apply], refl }
115
+ end
116
+
117
+ /-- The map from linear maps (n → α) →ₗ[ α ] (m → α) to matrix m n α. -/
118
+ def to_matrix [decidable_eq n] : ((n → α) →ₗ[α] (m → α)) → matrix m n α := to_matrixₗ.to_fun
119
+
120
+ end linear_map
121
+
122
+ section lin_equiv_matrix
123
+
124
+ variables {α : Type v} [comm_ring α] [decidable_eq n]
125
+
126
+ open finsupp matrix linear_map
127
+
128
+ /-- to_lin is the left inverse of to_matrix. -/
129
+ lemma to_matrix_to_lin [decidable_eq α] {f : (n → α) →ₗ[α] (m → α)} :
130
+ to_lin (to_matrix f) = f :=
131
+ begin
132
+ ext : 1 ,
133
+ -- Show that the two sides are equal by showing that they are equal on a basis
134
+ convert linear_eq_on (set.range _) _ (is_basis.mem_span (@pi.is_basis_fun α _ n _ _ _) _),
135
+ assume e he,
136
+ rw [@std_basis_eq_single α _ _ _ _ 1 ] at he,
137
+ cases (set.mem_range.mp he) with i h,
138
+ ext j,
139
+ change finset.univ.sum (λ k, (f.to_fun (single k 1 ).to_fun) j * (e k)) = _,
140
+ rw [←h],
141
+ conv_lhs { congr, skip, funext,
142
+ rw [mul_comm, ←smul_eq_mul, ←pi.smul_apply, ←linear_map.smul, single_apply],
143
+ rw [show f.to_fun (ite (i = k) (1 :α) 0 • (single k 1 ).to_fun) = ite (i = k) (f.to_fun ((single k 1 ).to_fun)) 0 ,
144
+ { split_ifs, { rw [one_smul] }, { rw [zero_smul], exact linear_map.map_zero f } }] },
145
+ convert finset.sum_eq_single i _ _,
146
+ { rw [if_pos rfl], refl },
147
+ { assume _ _ hbi, rw [if_neg $ ne.symm hbi], refl },
148
+ { assume hi, exact false.elim (hi $ finset.mem_univ i) }
149
+ end
150
+
151
+ /-- to_lin is the right inverse of to_matrix. -/
152
+ lemma to_lin_to_matrix {M : matrix m n α} : to_matrix (to_lin M) = M :=
153
+ begin
154
+ ext,
155
+ change finset.univ.sum (λ y, M i y * ite (j = y) 1 0 ) = M i j,
156
+ have h1 : (λ y, M i y * ite (j = y) 1 0 ) = (λ y, ite (j = y) (M i y) 0 ),
157
+ { ext, split_ifs, exact mul_one _, exact ring.mul_zero _ },
158
+ have h2 : finset.univ.sum (λ y, ite (j = y) (M i y) 0 ) = (finset.singleton j).sum (λ y, ite (j = y) (M i y) 0 ),
159
+ { refine (finset.sum_subset _ _).symm,
160
+ { intros _ H, rwa finset.mem_singleton.1 H, exact finset.mem_univ _ },
161
+ { exact λ _ _ H, if_neg (mt (finset.mem_singleton.2 ∘ eq.symm) H) } },
162
+ rw [h1, h2, finset.sum_singleton],
163
+ exact if_pos rfl
164
+ end
165
+
166
+ /-- Linear maps (n → α) →ₗ[ α ] (m → α) are linearly equivalent to matrix m n α. -/
167
+ def lin_equiv_matrix' [decidable_eq α] : ((n → α) →ₗ[α] (m → α)) ≃ₗ[α] matrix m n α :=
168
+ { to_fun := to_matrix,
169
+ inv_fun := to_lin,
170
+ right_inv := λ _, to_lin_to_matrix,
171
+ left_inv := λ _, to_matrix_to_lin,
172
+ add := to_matrixₗ.add,
173
+ smul := to_matrixₗ.smul }
174
+
175
+ /-- Given a basis of two modules β and γ over a commutative ring α, we get a linear equivalence
176
+ between linear maps β →ₗ γ and matrices over α indexed by the bases. -/
177
+ def lin_equiv_matrix {ι κ β γ : Type *} [decidable_eq α]
178
+ [add_comm_group β] [decidable_eq β] [module α β]
179
+ [add_comm_group γ] [decidable_eq γ] [module α γ]
180
+ [fintype ι] [decidable_eq ι] [fintype κ] [decidable_eq κ]
181
+ {v₁ : ι → β} {v₂ : κ → γ} (hv₁ : is_basis α v₁) (hv₂ : is_basis α v₂) :
182
+ (β →ₗ[α] γ) ≃ₗ[α] matrix κ ι α :=
183
+ linear_equiv.trans (linear_equiv.arrow_congr (equiv_fun_basis hv₁) (equiv_fun_basis hv₂)) lin_equiv_matrix'
184
+
185
+ end lin_equiv_matrix
186
+
187
+ namespace matrix
188
+
189
+ section ring
190
+
191
+ variables {α : Type v} [comm_ring α]
192
+ open linear_map matrix
77
193
78
194
lemma proj_diagonal [decidable_eq m] (i : m) (w : m → α) :
79
195
(proj i).comp (to_lin (diagonal w)) = (w i) • proj i :=
@@ -89,14 +205,14 @@ begin
89
205
{ subst h },
90
206
{ rw [std_basis_ne α (λ_:n, α) _ _ (ne.symm h), _root_.mul_zero, _root_.mul_zero] }
91
207
end
92
- end
93
208
94
209
end ring
95
210
96
211
section vector_space
212
+
97
213
variables {α : Type u} [discrete_field α] -- maybe try to relax the universe constraint
98
214
99
- open linear_map
215
+ open linear_map matrix
100
216
101
217
lemma rank_vec_mul_vec [decidable_eq n] (w : m → α) (v : n → α) :
102
218
rank (vec_mul_vec w v).to_lin ≤ 1 :=
0 commit comments