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

Commit 89f3bbc

Browse files
committed
feat(data/matrix): std_basis_matrix (#3244)
The definition of ``` def std_basis_matrix (i : m) (j : n) (a : α) : matrix m n α := (λ i' j', if i' = i ∧ j' = j then a else 0) ``` and associated lemmas, and some refactoring of `src/ring_theory/matrix_algebra.lean` to use it. This is work of @jalex-stark which I'm PR'ing as part of getting Cayley-Hamilton ready. Co-authored-by: Jalex Stark <alexmaplegm@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent a40be98 commit 89f3bbc

File tree

4 files changed

+128
-15
lines changed

4 files changed

+128
-15
lines changed

src/algebra/big_operators.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Johannes Hölzl
66

77
import data.finset
88
import data.nat.enat
9+
import data.equiv.mul_add
910
import tactic.omega
1011
import tactic.abel
1112

@@ -101,6 +102,11 @@ lemma monoid_hom.map_prod [comm_monoid β] [comm_monoid γ] (g : β →* γ) (f
101102
g (∏ x in s, f x) = ∏ x in s, g (f x) :=
102103
by simp only [finset.prod_eq_multiset_prod, g.map_multiset_prod, multiset.map_map]
103104

105+
@[to_additive]
106+
lemma mul_equiv.map_prod [comm_monoid β] [comm_monoid γ] (g : β ≃* γ) (f : α → β) (s : finset α) :
107+
g (∏ x in s, f x) = ∏ x in s, g (f x) :=
108+
g.to_monoid_hom.map_prod f s
109+
104110
lemma ring_hom.map_list_prod [semiring β] [semiring γ] (f : β →+* γ) (l : list β) :
105111
f l.prod = (l.map f).prod :=
106112
f.to_monoid_hom.map_list_prod l
@@ -242,6 +248,12 @@ begin
242248
apply h, cc
243249
end
244250

251+
/-- An uncurried version of `prod_product`. -/
252+
@[to_additive]
253+
lemma prod_product' {s : finset γ} {t : finset α} {f : γ → α → β} :
254+
(∏ x in s.product t, f x.1 x.2) = ∏ x in s, ∏ y in t, f x y :=
255+
by rw prod_product
256+
245257
@[to_additive]
246258
lemma prod_sigma {σ : α → Type*}
247259
{s : finset α} {t : Πa, finset (σ a)} {f : sigma σ → β} :

src/data/matrix/basic.lean

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,22 @@ def scalar (n : Type u) [fintype n] [decidable_eq n] : α →+* matrix n n α :=
362362
map_one' := by simp,
363363
map_mul' := by { intros, ext, simp [mul_assoc], }, }
364364

365+
section scalar
366+
367+
variable [decidable_eq n]
368+
369+
@[simp] lemma coe_scalar : (scalar n : α → matrix n n α) = λ a, a • 1 := rfl
370+
371+
lemma scalar_apply_eq (a : α) (i : n) :
372+
scalar n a i i = a :=
373+
by simp only [coe_scalar, mul_one, one_val_eq, smul_val]
374+
375+
lemma scalar_apply_ne (a : α) (i j : n) (h : i ≠ j) :
376+
scalar n a i j = 0 :=
377+
by simp only [h, coe_scalar, one_val_ne, ne.def, not_false_iff, smul_val, mul_zero]
378+
379+
end scalar
380+
365381
end semiring
366382

367383
section comm_semiring
@@ -437,6 +453,79 @@ lemma vec_mul_vec_eq (w : m → α) (v : n → α) :
437453
vec_mul_vec w v = (col w) ⬝ (row v) :=
438454
by { ext i j, simp [vec_mul_vec, mul_val], refl }
439455

456+
variables [decidable_eq m] [decidable_eq n]
457+
458+
/--
459+
`std_basis_matrix i j a` is the matrix with `a` in the `i`-th row, `j`-th column,
460+
and zeroes elsewhere.
461+
-/
462+
def std_basis_matrix (i : m) (j : n) (a : α) : matrix m n α :=
463+
(λ i' j', if i' = i ∧ j' = j then a else 0)
464+
465+
@[simp] lemma smul_std_basis_matrix (i : m) (j : n) (a b : α) :
466+
b • std_basis_matrix i j a = std_basis_matrix i j (b • a) :=
467+
by { unfold std_basis_matrix, ext, dsimp, simp }
468+
469+
@[simp] lemma std_basis_matrix_zero (i : m) (j : n) :
470+
std_basis_matrix i j (0 : α) = 0 :=
471+
by { unfold std_basis_matrix, ext, simp }
472+
473+
lemma std_basis_matrix_add (i : m) (j : n) (a b : α) :
474+
std_basis_matrix i j (a + b) = std_basis_matrix i j a + std_basis_matrix i j b :=
475+
begin
476+
unfold std_basis_matrix, ext,
477+
split_ifs with h; simp [h],
478+
end
479+
480+
481+
lemma matrix_eq_sum_elementary (x : matrix n m α) :
482+
x = ∑ (i : n) (j : m), std_basis_matrix i j (x i j) :=
483+
begin
484+
ext, iterate 2 {rw finset.sum_apply},
485+
rw ← finset.sum_subset, swap 4, exact {i},
486+
{ norm_num [std_basis_matrix] },
487+
{ simp },
488+
intros, norm_num at a, norm_num,
489+
convert finset.sum_const_zero,
490+
ext, norm_num [std_basis_matrix],
491+
rw if_neg, tauto!,
492+
end
493+
494+
-- TODO: tie this up with the `basis` machinery of linear algebra
495+
-- this is not completely trivial because we are indexing by two types, instead of one
496+
497+
-- TODO: add `std_basis_vec`
498+
lemma elementary_eq_basis_mul_basis (i : m) (j : n) :
499+
std_basis_matrix i j 1 = vec_mul_vec (λ i', ite (i = i') 1 0) (λ j', ite (j = j') 1 0) :=
500+
begin
501+
ext, norm_num [std_basis_matrix, vec_mul_vec],
502+
split_ifs; tauto,
503+
end
504+
505+
@[elab_as_eliminator] protected lemma induction_on'
506+
{X : Type*} [semiring X] {M : matrix n n X → Prop} (m : matrix n n X)
507+
(h_zero : M 0)
508+
(h_add : ∀p q, M p → M q → M (p + q))
509+
(h_elementary : ∀ i j x, M (std_basis_matrix i j x)) :
510+
M m :=
511+
begin
512+
rw [matrix_eq_sum_elementary m, ← finset.sum_product'],
513+
apply finset.sum_induction _ _ h_add h_zero,
514+
{ intros, apply h_elementary, }
515+
end
516+
517+
@[elab_as_eliminator] protected lemma induction_on
518+
[nonempty n] {X : Type*} [semiring X] {M : matrix n n X → Prop} (m : matrix n n X)
519+
(h_add : ∀p q, M p → M q → M (p + q))
520+
(h_elementary : ∀ i j x, M (std_basis_matrix i j x)) :
521+
M m :=
522+
matrix.induction_on' m
523+
begin
524+
have i : n := classical.choice (by assumption),
525+
simpa using h_elementary i i 0,
526+
end
527+
h_add h_elementary
528+
440529
end semiring
441530

442531
section ring

src/ring_theory/algebra.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ end
415415
[ring A₁] [ring A₂] [algebra R A₁] [algebra R A₂] (e : A₁ ≃ₐ[R] A₂) :
416416
∀ x y, e (x - y) = e x - e y := e.to_add_equiv.map_sub
417417

418+
lemma map_sum (e : A₁ ≃ₐ[R] A₂) {ι : Type*} (f : ι → A₁) (s : finset ι) :
419+
e (∑ x in s, f x) = ∑ x in s, e (f x) :=
420+
e.to_add_equiv.map_sum f s
421+
418422
instance has_coe_to_alg_hom : has_coe (A₁ ≃ₐ[R] A₂) (A₁ →ₐ[R] A₂) :=
419423
⟨λ e, { map_one' := e.map_one, map_zero' := e.map_zero, ..e }⟩
420424

@@ -462,6 +466,9 @@ def trans (e₁ : A₁ ≃ₐ[R] A₂) (e₂ : A₂ ≃ₐ[R] A₃) : A₁ ≃
462466
@[simp] lemma symm_apply_apply (e : A₁ ≃ₐ[R] A₂) : ∀ x, e.symm (e x) = x :=
463467
e.to_equiv.symm_apply_apply
464468

469+
@[simp] lemma trans_apply (e₁ : A₁ ≃ₐ[R] A₂) (e₂ : A₂ ≃ₐ[R] A₃) (x : A₁) :
470+
(e₁.trans e₂) x = e₂ (e₁ x) := rfl
471+
465472
@[simp] lemma comp_symm (e : A₁ ≃ₐ[R] A₂) :
466473
alg_hom.comp (e : A₁ →ₐ[R] A₂) ↑e.symm = alg_hom.id R A₂ :=
467474
by { ext, simp }

src/ring_theory/matrix_algebra.lean

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ open_locale big_operators
1818

1919
open tensor_product
2020
open algebra.tensor_product
21+
open matrix
2122

2223
variables {R : Type u} [comm_ring R]
2324
variables {A : Type v} [comm_ring A] [algebra R A]
@@ -90,7 +91,8 @@ variables [decidable_eq n]
9091
The function `(A ⊗[R] matrix n n R) →ₐ[R] matrix n n A`, as an algebra homomorphism.
9192
-/
9293
def to_fun_alg_hom : (A ⊗[R] matrix n n R) →ₐ[R] matrix n n A :=
93-
alg_hom_of_linear_map_tensor_product (to_fun_linear R A n)
94+
alg_hom_of_linear_map_tensor_product
95+
(to_fun_linear R A n)
9496
begin
9597
intros, ext,
9698
simp only [to_fun_linear, to_fun_bilinear, to_fun_right_linear, to_fun, lift.tmul,
@@ -119,7 +121,7 @@ The bare function `matrix n n A → A ⊗[R] matrix n n R`.
119121
(We don't need to show that it's an algebra map, thankfully --- just that it's an inverse.)
120122
-/
121123
def inv_fun (M : matrix n n A) : A ⊗[R] matrix n n R :=
122-
∑ (p : n × n), M p.1 p.2 ⊗ₜ (λ i' j', if (i', j') = p then 1 else 0)
124+
∑ (p : n × n), M p.1 p.2 ⊗ₜ (std_basis_matrix p.1 p.2 1)
123125

124126
@[simp] lemma inv_fun_zero : inv_fun R A n 0 = 0 :=
125127
by simp [inv_fun]
@@ -136,22 +138,17 @@ by simp [inv_fun,finset.mul_sum]
136138
inv_fun R A n (λ i j, algebra_map R A (M i j)) = 1 ⊗ₜ M :=
137139
begin
138140
dsimp [inv_fun],
139-
simp only [algebra.algebra_map_eq_smul_one, smul_tmul, ←tmul_sum, (•), mul_boole],
140-
congr, ext,
141-
calc
142-
(∑ (x : n × n), λ (i i_1 : n), ite ((i, i_1) = x) (M x.fst x.snd) 0) i j
143-
= (∑ (x : n × n), λ (i_1 : n), ite ((i, i_1) = x) (M x.fst x.snd) 0) j : _
144-
... = (∑ (x : n × n), ite ((i, j) = x) (M x.fst x.snd) 0) : _
145-
... = M i j : _,
146-
{ apply congr_fun, dsimp, simp, },
147-
{ simp, },
148-
{ simp, },
141+
simp only [algebra.algebra_map_eq_smul_one, smul_tmul, ←tmul_sum, mul_boole],
142+
congr,
143+
conv_rhs {rw matrix_eq_sum_elementary M},
144+
convert finset.sum_product, simp,
149145
end
150146

151147
lemma right_inv (M : matrix n n A) : (to_fun_alg_hom R A n) (inv_fun R A n M) = M :=
152148
begin
153-
ext,
154-
simp [inv_fun, alg_hom.map_sum, apply_ite (algebra_map R A)],
149+
simp only [inv_fun, alg_hom.map_sum, std_basis_matrix, apply_ite ⇑(algebra_map R A),
150+
mul_boole, to_fun_alg_hom_apply, ring_hom.map_zero, ring_hom.map_one],
151+
convert finset.sum_product, apply matrix_eq_sum_elementary,
155152
end
156153

157154
lemma left_inv (M : A ⊗[R] matrix n n R) : inv_fun R A n (to_fun_alg_hom R A n M) = M :=
@@ -187,9 +184,17 @@ open matrix_equiv_tensor
187184

188185
@[simp] lemma matrix_equiv_tensor_apply (M : matrix n n A) :
189186
matrix_equiv_tensor R A n M =
190-
∑ (p : n × n), M p.1 p.2 ⊗ₜ (λ i' j', if (i', j') = p then 1 else 0) :=
187+
∑ (p : n × n), M p.1 p.2 ⊗ₜ (std_basis_matrix p.1 p.2 1) :=
191188
rfl
192189

190+
@[simp] lemma matrix_equiv_tensor_apply_elementary (i j : n) (x : A):
191+
matrix_equiv_tensor R A n (std_basis_matrix i j x) =
192+
x ⊗ₜ (std_basis_matrix i j 1) :=
193+
begin
194+
have t : ∀ (p : n × n), (p.1 = i ∧ p.2 = j) ↔ (p = (i, j)) := by tidy,
195+
simp [ite_tmul, t, std_basis_matrix],
196+
end
197+
193198
@[simp] lemma matrix_equiv_tensor_apply_symm (a : A) (M : matrix n n R) :
194199
(matrix_equiv_tensor R A n).symm (a ⊗ₜ M) =
195200
λ i j, a * algebra_map R A (M i j) :=

0 commit comments

Comments
 (0)