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

Commit e808b41

Browse files
feat(data/matrix/basic): lemmas about transpose and conj_transpose on sums and products (#9880)
This also generalizes some previous results from `star_ring` to `star_add_monoid` now that the latter exists. To help prove the non-commutative statements, this adds `monoid_hom.unop_map_list_prod` and similar. This could probably used for proving `star_list_prod` in future. Co-authored-by: Johan Commelin <johan@commelin.net>
1 parent 87fa12a commit e808b41

File tree

4 files changed

+117
-3
lines changed

4 files changed

+117
-3
lines changed

src/algebra/big_operators/basic.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ lemma ring_hom.map_list_sum [non_assoc_semiring β] [non_assoc_semiring γ]
124124
f l.sum = (l.map f).sum :=
125125
f.to_add_monoid_hom.map_list_sum l
126126

127+
/-- A morphism into the opposite ring acts on the product by acting on the reversed elements -/
128+
lemma ring_hom.unop_map_list_prod [semiring β] [semiring γ] (f : β →+* γᵒᵖ) (l : list β) :
129+
opposite.unop (f l.prod) = (l.map (opposite.unop ∘ f)).reverse.prod :=
130+
f.to_monoid_hom.unop_map_list_prod l
131+
127132
lemma ring_hom.map_multiset_prod [comm_semiring β] [comm_semiring γ] (f : β →+* γ)
128133
(s : multiset β) :
129134
f s.prod = (s.map f).prod :=

src/data/equiv/ring.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,11 @@ lemma map_list_prod [semiring R] [semiring S] (f : R ≃+* S) (l : list R) :
370370
lemma map_list_sum [non_assoc_semiring R] [non_assoc_semiring S] (f : R ≃+* S) (l : list R) :
371371
f l.sum = (l.map f).sum := f.to_ring_hom.map_list_sum l
372372

373+
/-- An isomorphism into the opposite ring acts on the product by acting on the reversed elements -/
374+
lemma unop_map_list_prod [semiring R] [semiring S] (f : R ≃+* Sᵒᵖ) (l : list R) :
375+
opposite.unop (f l.prod) = (l.map (opposite.unop ∘ f)).reverse.prod :=
376+
f.to_ring_hom.unop_map_list_prod l
377+
373378
lemma map_multiset_prod [comm_semiring R] [comm_semiring S] (f : R ≃+* S) (s : multiset R) :
374379
f s.prod = (s.map f).prod := f.to_ring_hom.map_multiset_prod s
375380

src/data/list/basic.lean

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,6 +2402,10 @@ theorem prod_append : (l₁ ++ l₂).prod = l₁.prod * l₂.prod :=
24022402
calc (l₁ ++ l₂).prod = foldl (*) (foldl (*) 1 l₁ * 1) l₂ : by simp [list.prod]
24032403
... = l₁.prod * l₂.prod : foldl_assoc
24042404

2405+
@[to_additive]
2406+
theorem prod_concat : (l.concat a).prod = l.prod * a :=
2407+
by rw [concat_eq_append, prod_append, prod_cons, prod_nil, mul_one]
2408+
24052409
@[simp, to_additive]
24062410
theorem prod_join {l : list (list α)} : l.join.prod = (l.map list.prod).prod :=
24072411
by induction l; [refl, simp only [*, list.join, map, prod_append, prod_cons]]
@@ -2485,6 +2489,18 @@ lemma prod_update_nth : ∀ (L : list α) (n : ℕ) (a : α),
24852489
| (x::xs) (i+1) a := by simp [update_nth, prod_update_nth xs i a, mul_assoc]
24862490
| [] _ _ := by simp [update_nth, (nat.zero_le _).not_lt]
24872491

2492+
open opposite
2493+
2494+
lemma _root_.opposite.op_list_prod : ∀ (l : list α), op (l.prod) = (l.map op).reverse.prod
2495+
| [] := rfl
2496+
| (x :: xs) := by rw [list.prod_cons, list.map_cons, list.reverse_cons', list.prod_concat, op_mul,
2497+
_root_.opposite.op_list_prod]
2498+
2499+
lemma _root_.opposite.unop_list_prod : ∀ (l : list αᵒᵖ), (l.prod).unop = (l.map unop).reverse.prod
2500+
| [] := rfl
2501+
| (x :: xs) := by rw [list.prod_cons, list.map_cons, list.reverse_cons', list.prod_concat, unop_mul,
2502+
_root_.opposite.unop_list_prod]
2503+
24882504
end monoid
24892505

24902506
section group
@@ -4671,6 +4687,15 @@ theorem monoid_hom.map_list_prod {α β : Type*} [monoid α] [monoid β] (f : α
46714687
f l.prod = (l.map f).prod :=
46724688
(l.prod_hom f).symm
46734689

4690+
open opposite
4691+
4692+
/-- A morphism into the opposite monoid acts on the product by acting on the reversed elements -/
4693+
lemma monoid_hom.unop_map_list_prod {α β : Type*} [monoid α] [monoid β] (f : α →* βᵒᵖ) (l : list α):
4694+
unop (f l.prod) = (l.map (unop ∘ f)).reverse.prod :=
4695+
begin
4696+
rw [f.map_list_prod l, opposite.unop_list_prod, list.map_map],
4697+
end
4698+
46744699
namespace list
46754700

46764701
@[to_additive]

src/data/matrix/basic.lean

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,42 @@ by ext i j; refl
11371137
lemma transpose_map {f : α → β} {M : matrix m n α} : Mᵀ.map f = (M.map f)ᵀ :=
11381138
by { ext, refl }
11391139

1140+
/-- `matrix.transpose` as an `add_equiv` -/
1141+
@[simps apply]
1142+
def transpose_add_equiv [has_add α] : matrix m n α ≃+ matrix n m α :=
1143+
{ to_fun := transpose,
1144+
inv_fun := transpose,
1145+
left_inv := transpose_transpose,
1146+
right_inv := transpose_transpose,
1147+
map_add' := transpose_add }
1148+
1149+
@[simp] lemma transpose_add_equiv_symm [has_add α] :
1150+
(transpose_add_equiv : matrix m n α ≃+ matrix n m α).symm = transpose_add_equiv := rfl
1151+
1152+
lemma transpose_list_sum [add_monoid α] (l : list (matrix m n α)) :
1153+
l.sumᵀ = (l.map transpose).sum :=
1154+
(transpose_add_equiv : matrix m n α ≃+ matrix n m α).to_add_monoid_hom.map_list_sum l
1155+
1156+
lemma transpose_multiset_sum [add_comm_monoid α] (s : multiset (matrix m n α)) :
1157+
s.sumᵀ = (s.map transpose).sum :=
1158+
(transpose_add_equiv : matrix m n α ≃+ matrix n m α).to_add_monoid_hom.map_multiset_sum s
1159+
1160+
lemma transpose_sum [add_comm_monoid α] {ι : Type*} (s : finset ι) (M : ι → matrix m n α) :
1161+
(∑ i in s, M i)ᵀ = ∑ i in s, (M i)ᵀ :=
1162+
(transpose_add_equiv : matrix m n α ≃+ matrix n m α).to_add_monoid_hom.map_sum _ s
1163+
1164+
/-- `matrix.transpose` as a `ring_equiv` to the opposite ring -/
1165+
@[simps]
1166+
def transpose_ring_equiv [comm_semiring α] [fintype m] : matrix m m α ≃+* (matrix m m α)ᵒᵖ :=
1167+
{ to_fun := λ M, opposite.op (Mᵀ),
1168+
inv_fun := λ M, M.unopᵀ,
1169+
map_mul' := λ M N, (congr_arg opposite.op (transpose_mul M N)).trans (opposite.op_mul _ _),
1170+
..transpose_add_equiv.trans opposite.op_add_equiv }
1171+
1172+
lemma transpose_list_prod [comm_semiring α] [fintype m] [decidable_eq m] (l : list (matrix m m α)) :
1173+
l.prodᵀ = (l.map transpose).reverse.prod :=
1174+
(transpose_ring_equiv : matrix m m α ≃+* (matrix m m α)ᵒᵖ).unop_map_list_prod l
1175+
11401176
end transpose
11411177

11421178
section conj_transpose
@@ -1162,11 +1198,10 @@ by ext i j; simp
11621198
(1 : matrix n n α)ᴴ = 1 :=
11631199
by simp [conj_transpose]
11641200

1165-
@[simp] lemma conj_transpose_add
1166-
[semiring α] [star_ring α] (M : matrix m n α) (N : matrix m n α) :
1201+
@[simp] lemma conj_transpose_add [add_monoid α] [star_add_monoid α] (M N : matrix m n α) :
11671202
(M + N)ᴴ = Mᴴ + Nᴴ := by ext i j; simp
11681203

1169-
@[simp] lemma conj_transpose_sub [ring α] [star_ring α] (M : matrix m n α) (N : matrix m n α) :
1204+
@[simp] lemma conj_transpose_sub [add_group α] [star_add_monoid α] (M N : matrix m n α) :
11701205
(M - N)ᴴ = Mᴴ - Nᴴ := by ext i j; simp
11711206

11721207
@[simp] lemma conj_transpose_smul [comm_monoid α] [star_monoid α] (c : α) (M : matrix m n α) :
@@ -1179,6 +1214,46 @@ by ext i j; simp [mul_comm]
11791214
@[simp] lemma conj_transpose_neg [ring α] [star_ring α] (M : matrix m n α) :
11801215
(- M)ᴴ = - Mᴴ := by ext i j; simp
11811216

1217+
/-- `matrix.conj_transpose` as an `add_equiv` -/
1218+
@[simps apply]
1219+
def conj_transpose_add_equiv [add_monoid α] [star_add_monoid α] : matrix m n α ≃+ matrix n m α :=
1220+
{ to_fun := conj_transpose,
1221+
inv_fun := conj_transpose,
1222+
left_inv := conj_transpose_conj_transpose,
1223+
right_inv := conj_transpose_conj_transpose,
1224+
map_add' := conj_transpose_add }
1225+
1226+
@[simp] lemma conj_transpose_add_equiv_symm [add_monoid α] [star_add_monoid α] :
1227+
(conj_transpose_add_equiv : matrix m n α ≃+ matrix n m α).symm = conj_transpose_add_equiv := rfl
1228+
1229+
lemma conj_transpose_list_sum [add_monoid α] [star_add_monoid α] (l : list (matrix m n α)) :
1230+
l.sumᴴ = (l.map conj_transpose).sum :=
1231+
(conj_transpose_add_equiv : matrix m n α ≃+ matrix n m α).to_add_monoid_hom.map_list_sum l
1232+
1233+
lemma conj_transpose_multiset_sum [add_comm_monoid α] [star_add_monoid α]
1234+
(s : multiset (matrix m n α)) :
1235+
s.sumᴴ = (s.map conj_transpose).sum :=
1236+
(conj_transpose_add_equiv : matrix m n α ≃+ matrix n m α).to_add_monoid_hom.map_multiset_sum s
1237+
1238+
lemma conj_transpose_sum [add_comm_monoid α] [star_add_monoid α] {ι : Type*} (s : finset ι)
1239+
(M : ι → matrix m n α) :
1240+
(∑ i in s, M i)ᴴ = ∑ i in s, (M i)ᴴ :=
1241+
(conj_transpose_add_equiv : matrix m n α ≃+ matrix n m α).to_add_monoid_hom.map_sum _ s
1242+
1243+
/-- `matrix.conj_transpose` as a `ring_equiv` to the opposite ring -/
1244+
@[simps]
1245+
def conj_transpose_ring_equiv [comm_semiring α] [star_ring α] [fintype m] :
1246+
matrix m m α ≃+* (matrix m m α)ᵒᵖ :=
1247+
{ to_fun := λ M, opposite.op (Mᴴ),
1248+
inv_fun := λ M, M.unopᴴ,
1249+
map_mul' := λ M N, (congr_arg opposite.op (conj_transpose_mul M N)).trans (opposite.op_mul _ _),
1250+
..conj_transpose_add_equiv.trans opposite.op_add_equiv }
1251+
1252+
lemma conj_transpose_list_prod [comm_semiring α] [star_ring α] [fintype m] [decidable_eq m]
1253+
(l : list (matrix m m α)) :
1254+
l.prodᴴ = (l.map conj_transpose).reverse.prod :=
1255+
(conj_transpose_ring_equiv : matrix m m α ≃+* (matrix m m α)ᵒᵖ).unop_map_list_prod l
1256+
11821257
end conj_transpose
11831258

11841259
section star
@@ -1195,6 +1270,10 @@ lemma star_eq_conj_transpose [has_star α] (M : matrix m m α) : star M = Mᴴ :
11951270
instance [has_involutive_star α] : has_involutive_star (matrix n n α) :=
11961271
{ star_involutive := conj_transpose_conj_transpose }
11971272

1273+
/-- When `α` is a `*`-additive monoid, `matrix.has_star` is also a `*`-additive monoid. -/
1274+
instance [add_monoid α] [star_add_monoid α] : star_add_monoid (matrix n n α) :=
1275+
{ star_add := conj_transpose_add }
1276+
11981277
/-- When `α` is a `*`-(semi)ring, `matrix.has_star` is also a `*`-(semi)ring. -/
11991278
instance [fintype n] [decidable_eq n] [semiring α] [star_ring α] : star_ring (matrix n n α) :=
12001279
{ star_add := conj_transpose_add,

0 commit comments

Comments
 (0)