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

Commit ccd35db

Browse files
committed
feat(linear_algebra/matrix): to_matrix and to_lin as alg_equiv (#6496)
The existing `linear_map.to_matrix` and `matrix.to_lin` can be upgraded to an `alg_equiv` if working on linear endomorphisms or square matrices. The API is copied over in rote fashion. Co-authored-by: Yakov Pechersky <pechersky@users.noreply.github.com>
1 parent b1ecc98 commit ccd35db

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

src/algebra/algebra/basic.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ instance matrix_algebra (n : Type u) (R : Type v)
394394
smul_def' := by { intros, simp [matrix.scalar], },
395395
..(matrix.scalar n) }
396396

397+
@[simp] lemma matrix.algebra_map_eq_smul (n : Type u) {R : Type v} [decidable_eq n] [fintype n]
398+
[comm_semiring R] (r : R) : (algebra_map R (matrix n n R)) r = r • 1 := rfl
399+
397400
set_option old_structure_cmd true
398401
/-- Defining the homomorphism in the category R-Alg. -/
399402
@[nolint has_inhabited_instance]

src/linear_algebra/matrix.lean

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,64 @@ lemma linear_map.to_matrix'_mul [decidable_eq m]
162162
(f * g).to_matrix' = f.to_matrix' ⬝ g.to_matrix' :=
163163
linear_map.to_matrix'_comp f g
164164

165+
/-- Linear maps `(n → R) →ₗ[R] (n → R)` are algebra equivalent to `matrix n n R`. -/
166+
def linear_map.to_matrix_alg_equiv' : ((n → R) →ₗ[R] (n → R)) ≃ₐ[R] matrix n n R :=
167+
alg_equiv.of_linear_equiv linear_map.to_matrix' linear_map.to_matrix'_mul
168+
(by simp [module.algebra_map_End_eq_smul_id])
169+
170+
/-- A `matrix n n R` is algebra equivalent to a linear map `(n → R) →ₗ[R] (n → R)`. -/
171+
def matrix.to_lin_alg_equiv' : matrix n n R ≃ₐ[R] ((n → R) →ₗ[R] (n → R)) :=
172+
linear_map.to_matrix_alg_equiv'.symm
173+
174+
@[simp] lemma linear_map.to_matrix_alg_equiv'_symm :
175+
(linear_map.to_matrix_alg_equiv'.symm : matrix n n R ≃ₐ[R] _) = matrix.to_lin_alg_equiv' :=
176+
rfl
177+
178+
@[simp] lemma matrix.to_lin_alg_equiv'_symm :
179+
(matrix.to_lin_alg_equiv'.symm : ((n → R) →ₗ[R] (n → R)) ≃ₐ[R] _) =
180+
linear_map.to_matrix_alg_equiv' :=
181+
rfl
182+
183+
@[simp] lemma linear_map.to_matrix_alg_equiv'_to_lin_alg_equiv' (M : matrix n n R) :
184+
linear_map.to_matrix_alg_equiv' (matrix.to_lin_alg_equiv' M) = M :=
185+
linear_map.to_matrix_alg_equiv'.apply_symm_apply M
186+
187+
@[simp] lemma matrix.to_lin_alg_equiv'_to_matrix_alg_equiv' (f : (n → R) →ₗ[R] (n → R)) :
188+
matrix.to_lin_alg_equiv' (linear_map.to_matrix_alg_equiv' f) = f :=
189+
matrix.to_lin_alg_equiv'.apply_symm_apply f
190+
191+
@[simp] lemma linear_map.to_matrix_alg_equiv'_apply (f : (n → R) →ₗ[R] (n → R)) (i j) :
192+
linear_map.to_matrix_alg_equiv' f i j = f (λ j', if j' = j then 1 else 0) i :=
193+
by simp [linear_map.to_matrix_alg_equiv']
194+
195+
@[simp] lemma matrix.to_lin_alg_equiv'_apply (M : matrix n n R) (v : n → R) :
196+
matrix.to_lin_alg_equiv' M v = M.mul_vec v := rfl
197+
198+
@[simp] lemma matrix.to_lin_alg_equiv'_one :
199+
matrix.to_lin_alg_equiv' (1 : matrix n n R) = id :=
200+
by { ext, simp [matrix.one_apply, std_basis_apply] }
201+
202+
@[simp] lemma linear_map.to_matrix_alg_equiv'_id :
203+
(linear_map.to_matrix_alg_equiv' (linear_map.id : (n → R) →ₗ[R] (n → R))) = 1 :=
204+
by { ext, rw [matrix.one_apply, linear_map.to_matrix_alg_equiv'_apply, id_apply] }
205+
206+
@[simp] lemma matrix.to_lin_alg_equiv'_mul (M N : matrix n n R) :
207+
matrix.to_lin_alg_equiv' (M ⬝ N) =
208+
(matrix.to_lin_alg_equiv' M).comp (matrix.to_lin_alg_equiv' N) :=
209+
by { ext, simp }
210+
211+
lemma linear_map.to_matrix_alg_equiv'_comp (f g : (n → R) →ₗ[R] (n → R)) :
212+
(f.comp g).to_matrix_alg_equiv' = f.to_matrix_alg_equiv' ⬝ g.to_matrix_alg_equiv' :=
213+
suffices (f.comp g) = (f.to_matrix_alg_equiv' ⬝ g.to_matrix_alg_equiv').to_lin_alg_equiv',
214+
by rw [this, linear_map.to_matrix_alg_equiv'_to_lin_alg_equiv'],
215+
by rw [matrix.to_lin_alg_equiv'_mul, matrix.to_lin_alg_equiv'_to_matrix_alg_equiv',
216+
matrix.to_lin_alg_equiv'_to_matrix_alg_equiv']
217+
218+
lemma linear_map.to_matrix_alg_equiv'_mul
219+
(f g : (n → R) →ₗ[R] (n → R)) :
220+
(f * g).to_matrix_alg_equiv' = f.to_matrix_alg_equiv' ⬝ g.to_matrix_alg_equiv' :=
221+
linear_map.to_matrix_alg_equiv'_comp f g
222+
165223
end to_matrix'
166224

167225
section to_matrix
@@ -273,6 +331,91 @@ begin
273331
repeat { rw linear_map.to_matrix_to_lin },
274332
end
275333

334+
/-- Given a basis of a module `M₁` over a commutative ring `R`, we get an algebra
335+
equivalence between linear maps `M₁ →ₗ M₁` and square matrices over `R` indexed by the basis. -/
336+
def linear_map.to_matrix_alg_equiv :
337+
(M₁ →ₗ[R] M₁) ≃ₐ[R] matrix n n R :=
338+
alg_equiv.of_linear_equiv (linear_map.to_matrix hv₁ hv₁) (linear_map.to_matrix_mul hv₁)
339+
(by simp [module.algebra_map_End_eq_smul_id, linear_map.to_matrix_id])
340+
341+
/-- Given a basis of a module `M₁` over a commutative ring `R`, we get an algebra
342+
equivalence between square matrices over `R` indexed by the basis and linear maps `M₁ →ₗ M₁`. -/
343+
def matrix.to_lin_alg_equiv : matrix n n R ≃ₐ[R] (M₁ →ₗ[R] M₁) :=
344+
(linear_map.to_matrix_alg_equiv hv₁).symm
345+
346+
@[simp] lemma linear_map.to_matrix_alg_equiv_symm :
347+
(linear_map.to_matrix_alg_equiv hv₁).symm = matrix.to_lin_alg_equiv hv₁ :=
348+
rfl
349+
350+
@[simp] lemma matrix.to_lin_alg_equiv_symm :
351+
(matrix.to_lin_alg_equiv hv₁).symm = linear_map.to_matrix_alg_equiv hv₁ :=
352+
rfl
353+
354+
@[simp] lemma matrix.to_lin_alg_equiv_to_matrix_alg_equiv (f : M₁ →ₗ[R] M₁) :
355+
matrix.to_lin_alg_equiv hv₁ (linear_map.to_matrix_alg_equiv hv₁ f) = f :=
356+
by rw [← matrix.to_lin_alg_equiv_symm, alg_equiv.apply_symm_apply]
357+
358+
@[simp] lemma linear_map.to_matrix_alg_equiv_to_lin_alg_equiv (M : matrix n n R) :
359+
linear_map.to_matrix_alg_equiv hv₁ (matrix.to_lin_alg_equiv hv₁ M) = M :=
360+
by rw [← matrix.to_lin_alg_equiv_symm, alg_equiv.symm_apply_apply]
361+
362+
lemma linear_map.to_matrix_alg_equiv_apply (f : M₁ →ₗ[R] M₁) (i j : n) :
363+
linear_map.to_matrix_alg_equiv hv₁ f i j = hv₁.equiv_fun (f (v₁ j)) i :=
364+
by simp [linear_map.to_matrix_alg_equiv, linear_map.to_matrix_apply]
365+
366+
lemma linear_map.to_matrix_alg_equiv_transpose_apply (f : M₁ →ₗ[R] M₁) (j : n) :
367+
(linear_map.to_matrix_alg_equiv hv₁ f)ᵀ j = hv₁.equiv_fun (f (v₁ j)) :=
368+
funext $ λ i, f.to_matrix_apply _ _ i j
369+
370+
lemma linear_map.to_matrix_alg_equiv_apply' (f : M₁ →ₗ[R] M₁) (i j : n) :
371+
linear_map.to_matrix_alg_equiv hv₁ f i j = hv₁.repr (f (v₁ j)) i :=
372+
linear_map.to_matrix_alg_equiv_apply hv₁ f i j
373+
374+
lemma linear_map.to_matrix_alg_equiv_transpose_apply' (f : M₁ →ₗ[R] M₁) (j : n) :
375+
(linear_map.to_matrix_alg_equiv hv₁ f)ᵀ j = hv₁.repr (f (v₁ j)) :=
376+
linear_map.to_matrix_alg_equiv_transpose_apply hv₁ f j
377+
378+
lemma matrix.to_lin_alg_equiv_apply (M : matrix n n R) (v : M₁) :
379+
matrix.to_lin_alg_equiv hv₁ M v = ∑ j, M.mul_vec (hv₁.equiv_fun v) j • v₁ j :=
380+
show hv₁.equiv_fun.symm (matrix.to_lin_alg_equiv' M (hv₁.equiv_fun v)) = _,
381+
by rw [matrix.to_lin_alg_equiv'_apply, hv₁.equiv_fun_symm_apply]
382+
383+
@[simp] lemma matrix.to_lin_alg_equiv_self (M : matrix n n R) (i : n) :
384+
matrix.to_lin_alg_equiv hv₁ M (v₁ i) = ∑ j, M j i • v₁ j :=
385+
by simp only [matrix.to_lin_alg_equiv_apply, matrix.mul_vec, dot_product, hv₁.equiv_fun_self,
386+
mul_boole, finset.sum_ite_eq, finset.mem_univ, if_true]
387+
388+
lemma linear_map.to_matrix_alg_equiv_id : linear_map.to_matrix_alg_equiv hv₁ id = 1 :=
389+
by simp_rw [linear_map.to_matrix_alg_equiv, alg_equiv.of_linear_equiv_apply,
390+
linear_map.to_matrix_id]
391+
392+
@[simp]
393+
lemma matrix.to_lin_alg_equiv_one : matrix.to_lin_alg_equiv hv₁ 1 = id :=
394+
by rw [← linear_map.to_matrix_alg_equiv_id hv₁, matrix.to_lin_alg_equiv_to_matrix_alg_equiv]
395+
396+
theorem linear_map.to_matrix_alg_equiv_range [decidable_eq M₁]
397+
(f : M₁ →ₗ[R] M₁) (k i : n) :
398+
linear_map.to_matrix_alg_equiv hv₁.range f ⟨v₁ k, mem_range_self k⟩ ⟨v₁ i, mem_range_self i⟩ =
399+
linear_map.to_matrix_alg_equiv hv₁ f k i :=
400+
by simp_rw [linear_map.to_matrix_alg_equiv_apply, subtype.coe_mk, is_basis.equiv_fun_apply,
401+
hv₁.range_repr]
402+
403+
lemma linear_map.to_matrix_alg_equiv_comp (f g : M₁ →ₗ[R] M₁) :
404+
linear_map.to_matrix_alg_equiv hv₁ (f.comp g) =
405+
linear_map.to_matrix_alg_equiv hv₁ f ⬝ linear_map.to_matrix_alg_equiv hv₁ g :=
406+
by simp [linear_map.to_matrix_alg_equiv, linear_map.to_matrix_comp hv₁ hv₁ hv₁ f g]
407+
408+
lemma linear_map.to_matrix_alg_equiv_mul (f g : M₁ →ₗ[R] M₁) :
409+
linear_map.to_matrix_alg_equiv hv₁ (f * g) =
410+
linear_map.to_matrix_alg_equiv hv₁ f ⬝ linear_map.to_matrix_alg_equiv hv₁ g :=
411+
by { rw [show (@has_mul.mul (M₁ →ₗ[R] M₁) _) = linear_map.comp, from rfl,
412+
linear_map.to_matrix_alg_equiv_comp hv₁ f g] }
413+
414+
lemma matrix.to_lin_alg_equiv_mul (A B : matrix n n R) :
415+
matrix.to_lin_alg_equiv hv₁ (A ⬝ B) =
416+
(matrix.to_lin_alg_equiv hv₁ A).comp (matrix.to_lin_alg_equiv hv₁ B) :=
417+
by convert matrix.to_lin_mul hv₁ hv₁ hv₁ A B
418+
276419
end to_matrix
277420

278421
section is_basis_to_matrix

0 commit comments

Comments
 (0)