Zulip Chat Archive
Stream: Is there code for X?
Topic: tensor product distributes over `prod`
Kevin Buzzard (Jul 25 2022 at 12:32):
I need that tensor product distributes over prod
and over direct sums. I was on a plane so wrote the prod
version () from first principles because I couldn't find it:
import linear_algebra.free_module.pid
lemma prod.fst_def {α β : Type*} {a : α} {b : β} : (a, b).fst = a := rfl
lemma prod.snd_def {α β : Type*} {a : α} {b : β} : (a, b).snd = b := rfl
variables (R : Type*) [comm_ring R]
open_locale tensor_product
def tensor_product.prod_tensor {M N : Type*} [add_comm_group M] [add_comm_group N] [module R M]
[module R N] (K : Type*) [add_comm_group K] [module R K] :
(M × N) ⊗[R] K ≃ₗ[R] (M ⊗[R] K) × (N ⊗[R] K) :=
{ to_fun := tensor_product.lift $ linear_map.coprod
((tensor_product.lift.equiv R M K _).symm (linear_map.inl _ _ _))
((tensor_product.lift.equiv R N K _).symm (linear_map.inr _ _ _)),
map_add' := linear_map.map_add _,
map_smul' := linear_map.map_smul _,
inv_fun := linear_map.coprod (linear_map.rtensor K (linear_map.inl _ _ _))
(linear_map.rtensor K (linear_map.inr _ _ _)),
left_inv := λ x, begin
rw ← linear_map.comp_apply,
change _ = linear_map.id x,
refine linear_map.ext_iff.1 (tensor_product.ext' _) x,
rintros ⟨m, n⟩ k,
simp only [linear_map.comp_apply, tensor_product.lift.tmul, linear_map.coprod_apply,
linear_map.add_apply, tensor_product.lift.equiv_symm_apply, linear_map.inl_apply,
linear_map.inr_apply, prod.mk_add_mk, add_zero, zero_add, linear_map.rtensor_tmul,
linear_map.coe_inl, linear_map.coe_inr, linear_map.id_coe, id.def, ← tensor_product.add_tmul],
end,
right_inv := λ x, begin
rw ← linear_map.comp_apply,
change _ = linear_map.id x,
refine linear_map.ext_iff.1 (linear_map.prod_ext (tensor_product.ext' (λ m k, _))
(tensor_product.ext' (λ n k, _))) x,
{ rw [linear_map.comp_apply, linear_map.id_comp, linear_map.inl_apply, linear_map.comp_apply,
linear_map.coprod_apply, prod.fst_def, linear_map.rtensor_tmul, linear_map.map_zero,
add_zero, linear_map.inl_apply, tensor_product.lift.tmul, linear_map.coprod_apply,
prod.fst_def, prod.snd_def, linear_map.map_zero, add_zero,
tensor_product.lift.equiv_symm_apply, linear_map.inl_apply] },
{ rw [linear_map.comp_apply, linear_map.id_comp, linear_map.inr_apply, linear_map.comp_apply,
linear_map.coprod_apply, prod.fst_def, linear_map.rtensor_tmul, linear_map.map_zero,
zero_add, linear_map.inr_apply, tensor_product.lift.tmul, linear_map.coprod_apply,
prod.fst_def, prod.snd_def, linear_map.map_zero, zero_add,
tensor_product.lift.equiv_symm_apply, linear_map.inr_apply] },
end }
It was a lot longer than I expected (simp
would just time out so I had to work out the rewrites by hand). I suspect that will be even worse. Do we have these things already? Should I be using the category theory library and arguing that tensor products commute with these colimits or will that be even worse?
Eric Wieser (Jul 25 2022 at 12:45):
You can make that very slightly shorter by using (tensor_product.mk R N K).compr₂
instead of (tensor_product.lift.equiv R M K _).symm
Eric Wieser (Jul 25 2022 at 12:53):
I guess it's pretty annoying how awkward it is to construct M × N →ₗ[R] K →ₗ[R] M ⊗ K × N ⊗ K
when you really just want to write λ (mn : M × N) k, (mn.1 ⊗ₜ[R] k, mn.2 ⊗ₜ[R] k)
(which is also definitionally better than the coprod
/inl
/inr
spelling)
Kevin Buzzard (Jul 25 2022 at 13:08):
Right, I could have done that but of course then I have to prove that everything is R-linear manually
Adam Topaz (Jul 25 2022 at 14:11):
@Kevin Buzzard we have something like this in LTE
Adam Topaz (Jul 25 2022 at 14:13):
(But maybe only for Ab?)
Adam Topaz (Jul 25 2022 at 14:14):
We also have docs#tensor_product.direct_sum
Kevin Buzzard (Jul 25 2022 at 14:17):
Oh thanks!
Chris Hughes (Jul 25 2022 at 20:15):
Would it have been feasible to prove this using the category theory library? Just by arguing tensor preserves colimits because it has a right adjoint?
Adam Topaz (Jul 25 2022 at 20:32):
Yes, but I don't think we have the adjunction in mathlib
Adam Topaz (Jul 25 2022 at 20:33):
Note that biproducts are both colimits and limits, so if you show that tensoring is a left adjoint, you get that it commutes with colimits for free and since biproducts are in particular colimits, you get that they commute with biproducts
Antoine Labelle (Jul 25 2022 at 20:35):
We do have that adjunction, it is docs#Module.category_theory.monoidal_closed
Jack J Garzella (Jul 26 2022 at 04:03):
Should be very similar to #new members > Using the fact that a functor preserves limits, for which the solution has two lines of code. I'm not sure if the same universe issue would show up.
Eric Wieser (Sep 17 2023 at 23:00):
Ugh, I just wrote this again without searching on Zulip first!
attribute [ext] TensorProduct.ext in
def TensorProduct.prodRight : M₁ ⊗[R] (M₂ × M₃) ≃ₗ[R] ((M₁ ⊗[R] M₂) × (M₁ ⊗[R] M₃)) :=
LinearEquiv.ofLinear
(TensorProduct.lift <|
LinearMap.prodMapLinear R M₂ M₃ (M₁ ⊗[R] M₂) (M₁ ⊗[R] M₃) R
∘ₗ LinearMap.prod (TensorProduct.mk _ _ _) (TensorProduct.mk _ _ _))
(LinearMap.coprod
(LinearMap.lTensor _ <| LinearMap.inl _ _ _)
(LinearMap.lTensor _ <| LinearMap.inr _ _ _))
(by ext <;> simp)
(by ext <;> simp)
Eric Wieser (Sep 17 2023 at 23:01):
At least it's shorter than the previous version!
Eric Wieser (Sep 17 2023 at 23:26):
Antoine Chambert-Loir (Sep 18 2023 at 07:16):
Oh, that's a case where using docs#TensorProduct.comm seems to be useful to prove half of those left/right statements !
Last updated: Dec 20 2023 at 11:08 UTC