Zulip Chat Archive
Stream: mathlib4
Topic: Theorems for binary direct sum of modules
Paul Schwahn (Jun 20 2025 at 21:39):
Hi everyone,
in the course of a linear algebra heavy project we needed some definition/theorems about direct sums of modules. Back then I noticed that these existed for arbitrarily indexed direct sums ⨁ i, M i (although I can't find them anymore), but I think it would be really useful to have them for binary direct sums/products M₁ × M₂ as well.
I am thinking of creating PRs for the following two definitions:
1) The linear map from M₁ × M₂ to L defined by specifying maps from M₁ and M₂ to L
2) A linear equivalence from the product of two complementary submodules of L to L.
import Mathlib
variable {K L : Type*} [CommRing K] [AddCommGroup L] [Module K L] (p q : Submodule K L)
/-- The linear map from `M₁ × M₂` to `L` defined by specifying maps from `M₁` and `M₂` to `L`. -/
def LinearMap.ofProd {M₁ M₂ : Type*} [AddCommGroup M₁] [AddCommGroup M₂] [Module K M₁] [Module K M₂]
(f : M₁ →ₗ[K] L) (g : M₂ →ₗ[K] L) :
M₁ × M₂ →ₗ[K] L :=
f ∘ₗLinearMap.fst K M₁ M₂ + g ∘ₗLinearMap.snd K M₁ M₂
@[simp]
theorem LinearMap.ofProd_apply {M₁ M₂ : Type*} [AddCommGroup M₁] [AddCommGroup M₂] [Module K M₁] [Module K M₂]
(f : M₁ →ₗ[K] L) (g : M₂ →ₗ[K] L) (x : M₁ × M₂) :
LinearMap.ofProd f g x = f x.1 + g x.2 := rfl
variable {p q}
/-- If two submodules are disjoint, then the canonical map from the product is injective. -/
theorem Submodule.prod_injective_of_disjoint (h : Disjoint p q) :
Function.Injective (LinearMap.ofProd p.subtype q.subtype) := by
rw [← LinearMap.ker_eq_bot, Submodule.eq_bot_iff]
intro x hx
simp only [LinearMap.mem_ker, LinearMap.ofProd_apply, subtype_apply] at hx
rw [add_eq_zero_iff_neg_eq'] at hx
have x₁p : x.1.val ∈ p := x.1.prop
have x₁q : x.1.val ∈ q := by
rw [← hx, Submodule.neg_mem_iff]
exact x.2.prop
have x₁0 := Submodule.disjoint_def.mp h _ x₁p x₁q
have x₂p : x.2.val ∈ p := by
rw [← Submodule.neg_mem_iff, hx]
exact x.1.prop
have x₂q : x.2.val ∈ q := x.2.prop
have x₂0 := Submodule.disjoint_def.mp h _ x₂p x₂q
ext
· rw [x₁0]
rfl
· rw [x₂0]
rfl
/-- If two submodules are codisjoint, then the canonical map from the product is surjectve. -/
theorem Submodule.prod_surjective_of_codisjoint (h : Codisjoint p q) :
Function.Surjective (LinearMap.ofProd p.subtype q.subtype) := by
intro x
obtain ⟨y, hy, z, hz, hx⟩ := Submodule.exists_add_eq_of_codisjoint h x
use ⟨⟨y, hy⟩, ⟨z, hz⟩⟩
simp only [LinearMap.ofProd_apply, subtype_apply]
exact hx
/-- If two submodules are complementary, then their product is isomorphic to the ambient space. -/
noncomputable def LinearEquiv.ofComplSubmodules (h : IsCompl p q) :
(p × q) ≃ₗ[K] L :=
LinearEquiv.ofBijective (LinearMap.ofProd p.subtype q.subtype)
⟨Submodule.prod_injective_of_disjoint h.disjoint, Submodule.prod_surjective_of_codisjoint h.codisjoint⟩
@[simp]
theorem LinearEquiv.ofComplSubmodules_apply (h : IsCompl p q) (x : p × q) :
(LinearEquiv.ofComplSubmodules h) x = x.1.val + x.2.val := rfl
theorem LinearEquiv.ofComplSubmodules_symm_apply (h : IsCompl p q)
(x y z : L) (hy : y ∈ p) (hz : z ∈ q) (hx : x = y + z) :
(LinearEquiv.ofComplSubmodules h).symm x = ⟨⟨y, hy⟩, ⟨z, hz⟩⟩ := by
simp only [symm_apply_eq, LinearEquiv.ofComplSubmodules_apply h, hx]
theorem LinearEquiv.ofComplSubmodules_symm_apply_left (h : IsCompl p q) (x : L) (hx : x ∈ p) :
(LinearEquiv.ofComplSubmodules h).symm x = ⟨⟨x, hx⟩, 0⟩ := by
apply LinearEquiv.ofComplSubmodules_symm_apply
rw [add_zero]
theorem LinearEquiv.ofComplSubmodules_symm_apply_right (h : IsCompl p q) (x : L) (hx : x ∈ q) :
(LinearEquiv.ofComplSubmodules h).symm x = ⟨0, ⟨x, hx⟩⟩ := by
apply LinearEquiv.ofComplSubmodules_symm_apply
rw [zero_add]
theorem LinearEquiv.ofComplSubmodules_symm_add (h : IsCompl p q) (x : L) :
x = ((LinearEquiv.ofComplSubmodules h).symm x).1.val + ((LinearEquiv.ofComplSubmodules h).symm x).2.val := by
obtain ⟨y, hy, z, hz, hx⟩ := Submodule.exists_add_eq_of_codisjoint h.codisjoint x
simp only [LinearEquiv.ofComplSubmodules_symm_apply h x y z hy hz hx.symm]
exact hx.symm
It might very well be that something like this is already in mathlib but we just couldn't find it. Any feedback is appreciated.
Kenny Lau (Jun 21 2025 at 00:48):
@Paul Schwahn
- Lean Search, "Conditions for internal direct sum" ->
DirectSum.isInternal_submodule_iff_iSupIndep_and_iSup_eq_top - Lean Search, "DirectSum.isInternal but only for two submodules" ->
DirectSum.isInternal_submodule_iff_isCompl - DirectSum.isInternal_submodule_iff_isCompl
/-- If a collection of submodules has just two indices, `i` and `j`, then
`DirectSum.IsInternal` is equivalent to `isCompl`. -/
theorem isInternal_submodule_iff_isCompl (A : ι → Submodule R M) {i j : ι} (hij : i ≠ j)
(h : (Set.univ : Set ι) = {i, j}) : IsInternal A ↔ IsCompl (A i) (A j) := by
Paul Schwahn (Jun 21 2025 at 19:58):
That's great, thanks!
Do you think it would still be worthwhile to have LinearEquiv.ofComplSubmodules? Think of it just as API for products. In my opinion, working with a direct sum indexed over a type of cardinality two is a bit awkward, both for stating theorems (because the statements are much longer and harder to read) and for proving stuff about them (because binary products already have a lot of API, and carrying the index type around is a bit annoying).
Kenny Lau (Jun 21 2025 at 21:12):
@Paul Schwahn Loogle, "IsCompl, LinearEquiv":
- Submodule.prodEquivOfIsCompl :clipboard: Mathlib.LinearAlgebra.Projection
{R : Type u_1} [Ring R] {E : Type u_2} [AddCommGroup E] [Module R E] (p q : Submodule R E) (h : IsCompl p q) : (↥p × ↥q) ≃ₗ[R] E
Paul Schwahn (Jun 22 2025 at 21:33):
Oh wow. And LinearMap.coprod is also in mathlib. I genuinely don't know how I missed them. Thanks again!
Notification Bot (Jun 22 2025 at 21:33):
Paul Schwahn has marked this topic as resolved.
Notification Bot (Jun 23 2025 at 03:32):
Paul Schwahn has marked this topic as unresolved.
Paul Schwahn (Jun 23 2025 at 03:40):
On that note:
- using these theorems, I found that it might be more useful if the submodules in
Submodule.prodEquivOfIsComplandSubmodule.linearProjOfIsCompland the theorems about it were implicit arguments - I thinkSubmodule.linearProjOfIsCompl hwould be much nicer thanSubmodule.linearProjOfIsCompl _ _ horp.linearProjOfIsCompl q h, especially if the submodulespandqare not single letters/words. - there seem to be no mathlib analogues of the theorems
LinearEquiv.ofComplSubmodules_symm_applyandLinearEquiv.ofComplSubmodules_symm_addfrom my snippet above, and I would find them useful to have.
Opinions? (I'm happy to make a PR; also please let me know if there is a better place to discuss this)
Paul Schwahn (Jun 27 2025 at 03:16):
Paul Schwahn said:
- there seem to be no mathlib analogues of the theorems
LinearEquiv.ofComplSubmodules_symm_applyandLinearEquiv.ofComplSubmodules_symm_addfrom my snippet above, and I would find them useful to have.
I've made this a PR: #26462
Last updated: Dec 20 2025 at 21:32 UTC