Module docstring
{"### Linear equivalences involving submodules "}
{"### Linear equivalences involving submodules "}
LinearEquiv.ofEq
definition
(h : p = q) : p ≃ₗ[R] q
/-- Linear equivalence between two equal submodules. -/
def ofEq (h : p = q) : p ≃ₗ[R] q :=
{ Equiv.setCongr (congr_arg _ h) with
map_smul' := fun _ _ => rfl
map_add' := fun _ _ => rfl }
LinearEquiv.coe_ofEq_apply
theorem
(h : p = q) (x : p) : (ofEq p q h x : M) = x
@[simp]
theorem coe_ofEq_apply (h : p = q) (x : p) : (ofEq p q h x : M) = x :=
rfl
LinearEquiv.ofEq_symm
theorem
(h : p = q) : (ofEq p q h).symm = ofEq q p h.symm
LinearEquiv.ofEq_rfl
theorem
: ofEq p p rfl = LinearEquiv.refl R p
@[simp]
theorem ofEq_rfl : ofEq p p rfl = LinearEquiv.refl R p := by ext; rfl
LinearEquiv.ofSubmodules
definition
(p : Submodule R M) (q : Submodule R₂ M₂) (h : p.map (e : M →ₛₗ[σ₁₂] M₂) = q) : p ≃ₛₗ[σ₁₂] q
/-- A linear equivalence which maps a submodule of one module onto another, restricts to a linear
equivalence of the two submodules. -/
def ofSubmodules (p : Submodule R M) (q : Submodule R₂ M₂) (h : p.map (e : M →ₛₗ[σ₁₂] M₂) = q) :
p ≃ₛₗ[σ₁₂] q :=
(e.submoduleMap p).trans (LinearEquiv.ofEq _ _ h)
LinearEquiv.ofSubmodules_apply
theorem
{p : Submodule R M} {q : Submodule R₂ M₂} (h : p.map ↑e = q) (x : p) : ↑(e.ofSubmodules p q h x) = e x
@[simp]
theorem ofSubmodules_apply {p : Submodule R M} {q : Submodule R₂ M₂} (h : p.map ↑e = q) (x : p) :
↑(e.ofSubmodules p q h x) = e x :=
rfl
LinearEquiv.ofSubmodules_symm_apply
theorem
{p : Submodule R M} {q : Submodule R₂ M₂} (h : p.map ↑e = q) (x : q) : ↑((e.ofSubmodules p q h).symm x) = e.symm x
@[simp]
theorem ofSubmodules_symm_apply {p : Submodule R M} {q : Submodule R₂ M₂} (h : p.map ↑e = q)
(x : q) : ↑((e.ofSubmodules p q h).symm x) = e.symm x :=
rfl
LinearEquiv.ofSubmodule'
definition
[Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂) (U : Submodule R₂ M₂) : U.comap (f : M →ₛₗ[σ₁₂] M₂) ≃ₛₗ[σ₁₂] U
/-- A linear equivalence of two modules restricts to a linear equivalence from the preimage of any
submodule to that submodule.
This is `LinearEquiv.ofSubmodule` but with `comap` on the left instead of `map` on the right. -/
def ofSubmodule' [Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂) (U : Submodule R₂ M₂) :
U.comap (f : M →ₛₗ[σ₁₂] M₂) ≃ₛₗ[σ₁₂] U :=
(f.symm.ofSubmodules _ _ f.symm.map_eq_comap).symm
LinearEquiv.ofSubmodule'_toLinearMap
theorem
[Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂) (U : Submodule R₂ M₂) :
(f.ofSubmodule' U).toLinearMap = (f.toLinearMap.domRestrict _).codRestrict _ Subtype.prop
theorem ofSubmodule'_toLinearMap [Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂)
(U : Submodule R₂ M₂) :
(f.ofSubmodule' U).toLinearMap = (f.toLinearMap.domRestrict _).codRestrict _ Subtype.prop := by
ext
rfl
LinearEquiv.ofSubmodule'_apply
theorem
[Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂) (U : Submodule R₂ M₂) (x : U.comap (f : M →ₛₗ[σ₁₂] M₂)) :
(f.ofSubmodule' U x : M₂) = f (x : M)
@[simp]
theorem ofSubmodule'_apply [Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂) (U : Submodule R₂ M₂)
(x : U.comap (f : M →ₛₗ[σ₁₂] M₂)) : (f.ofSubmodule' U x : M₂) = f (x : M) :=
rfl
LinearEquiv.ofSubmodule'_symm_apply
theorem
[Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂) (U : Submodule R₂ M₂) (x : U) :
((f.ofSubmodule' U).symm x : M) = f.symm (x : M₂)
@[simp]
theorem ofSubmodule'_symm_apply [Module R M] [Module R₂ M₂] (f : M ≃ₛₗ[σ₁₂] M₂)
(U : Submodule R₂ M₂) (x : U) : ((f.ofSubmodule' U).symm x : M) = f.symm (x : M₂) :=
rfl
LinearEquiv.ofTop
definition
(h : p = ⊤) : p ≃ₗ[R] M
LinearEquiv.ofTop_apply
theorem
{h} (x : p) : ofTop p h x = x
@[simp]
theorem ofTop_apply {h} (x : p) : ofTop p h x = x :=
rfl
LinearEquiv.coe_ofTop_symm_apply
theorem
{h} (x : M) : ((ofTop p h).symm x : M) = x
@[simp]
theorem coe_ofTop_symm_apply {h} (x : M) : ((ofTop p h).symm x : M) = x :=
rfl
LinearEquiv.ofTop_symm_apply
theorem
{h} (x : M) : (ofTop p h).symm x = ⟨x, h.symm ▸ trivial⟩
theorem ofTop_symm_apply {h} (x : M) : (ofTop p h).symm x = ⟨x, h.symm ▸ trivial⟩ :=
rfl
LinearEquiv.range
theorem
: LinearMap.range (e : M →ₛₗ[σ₁₂] M₂) = ⊤
@[simp]
protected theorem range : LinearMap.range (e : M →ₛₗ[σ₁₂] M₂) = ⊤ :=
LinearMap.range_eq_top.2 e.toEquiv.surjective
LinearEquivClass.range
theorem
[Module R M] [Module R₂ M₂] {F : Type*} [EquivLike F M M₂] [SemilinearEquivClass F σ₁₂ M M₂] (e : F) :
LinearMap.range e = ⊤
@[simp]
protected theorem _root_.LinearEquivClass.range [Module R M] [Module R₂ M₂] {F : Type*}
[EquivLike F M M₂] [SemilinearEquivClass F σ₁₂ M M₂] (e : F) : LinearMap.range e = ⊤ :=
LinearMap.range_eq_top.2 (EquivLike.surjective e)
LinearEquiv.range_comp
theorem
[RingHomSurjective σ₂₃] [RingHomSurjective σ₁₃] :
LinearMap.range (h.comp (e : M →ₛₗ[σ₁₂] M₂) : M →ₛₗ[σ₁₃] M₃) = LinearMap.range h
@[simp]
theorem range_comp [RingHomSurjective σ₂₃] [RingHomSurjective σ₁₃] :
LinearMap.range (h.comp (e : M →ₛₗ[σ₁₂] M₂) : M →ₛₗ[σ₁₃] M₃) = LinearMap.range h :=
LinearMap.range_comp_of_range_eq_top _ e.range
LinearEquiv.ofLeftInverse
definition
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {g : M₂ → M} (h : Function.LeftInverse g f) :
M ≃ₛₗ[σ₁₂] (LinearMap.range f)
/-- A linear map `f : M →ₗ[R] M₂` with a left-inverse `g : M₂ →ₗ[R] M` defines a linear
equivalence between `M` and `f.range`.
This is a computable alternative to `LinearEquiv.ofInjective`, and a bidirectional version of
`LinearMap.rangeRestrict`. -/
def ofLeftInverse [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {g : M₂ → M}
(h : Function.LeftInverse g f) : M ≃ₛₗ[σ₁₂] (LinearMap.range f) :=
{ LinearMap.rangeRestrict f with
toFun := LinearMap.rangeRestrict f
invFun := g ∘ (LinearMap.range f).subtype
left_inv := h
right_inv := fun x =>
Subtype.ext <|
let ⟨x', hx'⟩ := LinearMap.mem_range.mp x.prop
show f (g x) = x by rw [← hx', h x'] }
LinearEquiv.ofLeftInverse_apply
theorem
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] (h : Function.LeftInverse g f) (x : M) : ↑(ofLeftInverse h x) = f x
@[simp]
theorem ofLeftInverse_apply [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂]
(h : Function.LeftInverse g f) (x : M) : ↑(ofLeftInverse h x) = f x :=
rfl
LinearEquiv.ofLeftInverse_symm_apply
theorem
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] (h : Function.LeftInverse g f) (x : LinearMap.range f) :
(ofLeftInverse h).symm x = g x
@[simp]
theorem ofLeftInverse_symm_apply [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂]
(h : Function.LeftInverse g f) (x : LinearMap.range f) : (ofLeftInverse h).symm x = g x :=
rfl
LinearEquiv.ofInjective
definition
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] (h : Injective f) : M ≃ₛₗ[σ₁₂] LinearMap.range f
/-- An `Injective` linear map `f : M →ₗ[R] M₂` defines a linear equivalence
between `M` and `f.range`. See also `LinearMap.ofLeftInverse`. -/
noncomputable def ofInjective [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] (h : Injective f) :
M ≃ₛₗ[σ₁₂] LinearMap.range f :=
ofLeftInverse <| Classical.choose_spec h.hasLeftInverse
LinearEquiv.ofInjective_apply
theorem
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h : Injective f} (x : M) : ↑(ofInjective f h x) = f x
@[simp]
theorem ofInjective_apply [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h : Injective f}
(x : M) : ↑(ofInjective f h x) = f x :=
rfl
LinearEquiv.ofInjective_symm_apply
theorem
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h : Injective f} (x : LinearMap.range f) :
f ((ofInjective f h).symm x) = x
@[simp]
lemma ofInjective_symm_apply [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h : Injective f}
(x : LinearMap.range f) :
f ((ofInjective f h).symm x) = x := by
obtain ⟨-, ⟨y, rfl⟩⟩ := x
have : ⟨f y, LinearMap.mem_range_self f y⟩ = LinearEquiv.ofInjective f h y := rfl
simp [this]
LinearEquiv.ofBijective
definition
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] (hf : Bijective f) : M ≃ₛₗ[σ₁₂] M₂
/-- A bijective linear map is a linear equivalence. -/
noncomputable def ofBijective [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] (hf : Bijective f) :
M ≃ₛₗ[σ₁₂] M₂ :=
(ofInjective f hf.injective).trans <| ofTop _ <|
LinearMap.range_eq_top.2 hf.surjective
LinearEquiv.ofBijective_apply
theorem
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {hf} (x : M) : ofBijective f hf x = f x
@[simp]
theorem ofBijective_apply [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {hf} (x : M) :
ofBijective f hf x = f x :=
rfl
LinearEquiv.ofBijective_symm_apply_apply
theorem
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h} (x : M) : (ofBijective f h).symm (f x) = x
@[simp]
theorem ofBijective_symm_apply_apply [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h} (x : M) :
(ofBijective f h).symm (f x) = x := by
simp [LinearEquiv.symm_apply_eq]
LinearEquiv.apply_ofBijective_symm_apply
theorem
[RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h} (x : M₂) : f ((ofBijective f h).symm x) = x
@[simp]
theorem apply_ofBijective_symm_apply [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] {h}
(x : M₂) : f ((ofBijective f h).symm x) = x := by
rw [← ofBijective_apply f ((ofBijective f h).symm x), apply_symm_apply]
Submodule.equivSubtypeMap
definition
(p : Submodule R M) (q : Submodule R p) : q ≃ₗ[R] q.map p.subtype
/-- Given `p` a submodule of the module `M` and `q` a submodule of `p`, `p.equivSubtypeMap q`
is the natural `LinearEquiv` between `q` and `q.map p.subtype`. -/
def equivSubtypeMap (p : Submodule R M) (q : Submodule R p) : q ≃ₗ[R] q.map p.subtype :=
{ (p.subtype.domRestrict q).codRestrict _ (by rintro ⟨x, hx⟩; exact ⟨x, hx, rfl⟩) with
invFun := by
rintro ⟨x, hx⟩
refine ⟨⟨x, ?_⟩, ?_⟩ <;> rcases hx with ⟨⟨_, h⟩, _, rfl⟩ <;> assumption
left_inv := fun ⟨⟨_, _⟩, _⟩ => rfl
right_inv := fun ⟨x, ⟨_, h⟩, _, rfl⟩ => by ext; rfl }
Submodule.equivSubtypeMap_apply
theorem
{p : Submodule R M} {q : Submodule R p} (x : q) : (p.equivSubtypeMap q x : M) = p.subtype.domRestrict q x
@[simp]
theorem equivSubtypeMap_apply {p : Submodule R M} {q : Submodule R p} (x : q) :
(p.equivSubtypeMap q x : M) = p.subtype.domRestrict q x :=
rfl
Submodule.equivSubtypeMap_symm_apply
theorem
{p : Submodule R M} {q : Submodule R p} (x : q.map p.subtype) : ((p.equivSubtypeMap q).symm x : M) = x
@[simp]
theorem equivSubtypeMap_symm_apply {p : Submodule R M} {q : Submodule R p} (x : q.map p.subtype) :
((p.equivSubtypeMap q).symm x : M) = x := by
cases x
rfl
Submodule.comap_equiv_self_of_inj_of_le
definition
{f : M →ₗ[R] N} {p : Submodule R N} (hf : Injective f) (h : p ≤ LinearMap.range f) : p.comap f ≃ₗ[R] p
/-- A linear injection `M ↪ N` restricts to an equivalence `f⁻¹ p ≃ p` for any submodule `p`
contained in its range. -/
@[simps! apply]
noncomputable def comap_equiv_self_of_inj_of_le {f : M →ₗ[R] N} {p : Submodule R N}
(hf : Injective f) (h : p ≤ LinearMap.range f) :
p.comap f ≃ₗ[R] p :=
LinearEquiv.ofBijective
((f ∘ₗ (p.comap f).subtype).codRestrict p <| fun ⟨_, hx⟩ ↦ mem_comap.mp hx)
(⟨fun x y hxy ↦ by simpa using hf (Subtype.ext_iff.mp hxy),
fun ⟨x, hx⟩ ↦ by obtain ⟨y, rfl⟩ := h hx; exact ⟨⟨y, hx⟩, by simp [Subtype.ext_iff]⟩⟩)
LinearMap.codRestrictOfInjective
definition
: M₁ →ₗ[R] M₃
/-- The restriction of a linear map on the target to a submodule of the target given by
an inclusion. -/
noncomputable def codRestrictOfInjective : M₁ →ₗ[R] M₃ :=
(LinearEquiv.ofInjective i hi).symm ∘ₗ f.codRestrict (LinearMap.range i) hf
LinearMap.codRestrictOfInjective_comp_apply
theorem
(x : M₁) : i (LinearMap.codRestrictOfInjective f i hi hf x) = f x
@[simp]
lemma codRestrictOfInjective_comp_apply (x : M₁) :
i (LinearMap.codRestrictOfInjective f i hi hf x) = f x := by
simp [LinearMap.codRestrictOfInjective]
LinearMap.codRestrictOfInjective_comp
theorem
: i ∘ₗ LinearMap.codRestrictOfInjective f i hi hf = f
@[simp]
lemma codRestrictOfInjective_comp :
i ∘ₗ LinearMap.codRestrictOfInjective f i hi hf = f := by
ext
simp
LinearMap.codRestrict₂
definition
: M₁ →ₗ[R] M₂ →ₗ[R] M₃
/-- The restriction of a bilinear map to a submodule in which it takes values. -/
noncomputable def codRestrict₂ :
M₁ →ₗ[R] M₂ →ₗ[R] M₃ :=
let e : LinearMap.rangeLinearMap.range i ≃ₗ[R] M₃ := (LinearEquiv.ofInjective i hi).symm
{ toFun := fun x ↦ e.comp <| (f x).codRestrict (p := LinearMap.range i) (hf x)
map_add' := by intro x₁ x₂; ext y; simp [f.map_add, ← e.map_add, codRestrict]
map_smul' := by intro t x; ext y; simp [f.map_smul, ← e.map_smul, codRestrict] }
LinearMap.codRestrict₂_apply
theorem
(x : M₁) (y : M₂) : i (codRestrict₂ f i hi hf x y) = f x y
@[simp]
lemma codRestrict₂_apply (x : M₁) (y : M₂) :
i (codRestrict₂ f i hi hf x y) = f x y := by
simp [codRestrict₂]