Zulip Chat Archive
Stream: mathlib4
Topic: Coercion for linear maps to submodules
Oliver Butterley (Jul 02 2025 at 12:51):
Informally in mathematics we often see a linear map into a Submodule as a linear map on the entire space. Would it make sense that this was an automatic coercion in mathlib?
import Mathlib
variable {š E : Type*} [RCLike š] [NormedAddCommGroup E] [InnerProductSpace š E] {K : Submodule š E}
variable (f : E āL[š] K)
-- #check (f : E āL[š] E) -- error
#check K.subtypeL.comp f -- `E āL[š] E`
Particular motivation is when working with K.orthogonalProjection, the projector onto K.
Kenny Lau (Jul 02 2025 at 12:53):
I don't think you want that
Oliver Butterley (Jul 02 2025 at 12:55):
I can't myself see the problems it could cause. Very curious to know.
Kenny Lau (Jul 02 2025 at 13:06):
you can't deduce K from the resulting type so you'll need CoeOut, and then you'll also need some simp lemmas to make sure that everything transitions smoothly, and then beyond that I admit I don't really see an immediate problem so you can try it and see if you run into any problems later on
Eric Wieser (Jul 02 2025 at 13:40):
You won't need any simp lemmas because coercions are unfolded eagerly
Eric Wieser (Jul 02 2025 at 13:42):
So this would work:
instance {R M N} [Semiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N] {S : Submodule R N} :
CoeOut (M āā[R] S) (M āā[R] N) where coe f := S.subtype.comp f
instance {R M N} [Semiring R] [TopologicalSpace M] [AddCommMonoid M] [Module R M]
[TopologicalSpace N] [AddCommMonoid N] [Module R N] {S : Submodule R N} :
CoeOut (M āL[R] S) (M āL[R] N) where coe f := S.subtypeL.comp f
and would have no harmful effect besides possibly confusing humans
Jireh Loreaux (Jul 02 2025 at 14:18):
Yeah, I would want to have a poll about this before we add it, because I think it could be rather confusing. I'm also not sure how convenient it would be in practice, but maybe I'm overlooking its utility.
Oliver Butterley (Jul 02 2025 at 16:21):
Thanks for the comments and clarifications. To be honest this functionality would only slightly improve the use case I had in mind, spelling out what I need is also fine and the situations which could be confusing weren't immediately apparent.
Yoh Tanimoto (Jul 03 2025 at 17:57):
I'm not sure if a coercion is the right choice, but I think we would like to have something like this:
import Mathlib
variable {š : Type u_1} {E : Type u_2} [RCLike š] [NormedAddCommGroup E] [InnerProductSpace š E] [CompleteSpace E] (p : E āL[š] E)
def IsOrthogonalProjection (p : E āL[š] E) : Prop := p = p ^ 2 ā§ p = p.adjoint
lemma IsOrthogonalProjection_iff (p : E āL[š] E) : IsOrthogonalProjection p ā ā (K : Submodule š E),
ā (kH : K.HasOrthogonalProjection), p = K.subtypeL.comp (@K.orthogonalProjection _ _ _ _ _ kH) := by sorry
-- the subspace corresponding to the orthogonal projection
noncomputable def toSubmodule (p : E āL[š] E) (hp : IsOrthogonalProjection p) :
Submodule š E := Classical.choose ((IsOrthogonalProjection_iff p).mp hp)
-- the projection as `orthogonalProjection`
noncomputable def toOrthogonalProjection (p : E āL[š] E) (hp : IsOrthogonalProjection p) : E āL[š] (toSubmodule p hp) :=
(@(toSubmodule p hp).orthogonalProjection _ _ _ _ _ (Classical.choose (Classical.choose_spec ((IsOrthogonalProjection_iff p).mp hp))))
Oliver Butterley (Jul 03 2025 at 18:06):
With dot notation to make the last two defs more convenient in use.
Yoh Tanimoto (Jul 03 2025 at 18:07):
more generally, when there is a coercion from Y to Z, I wonder why there is no coercion from X ā Y to X ā Z (seeing Y-valued function as Z-valued function). probably the reason is that it is confusing humans?
Jireh Loreaux (Jul 10 2025 at 14:03):
@Yoh Tanimoto see docs#IsStarProjection and #25958
Yoh Tanimoto (Jul 10 2025 at 17:10):
ok so it's under review, nice!
Oliver Butterley (Jul 10 2025 at 20:00):
Jireh Loreaux said:
Yoh Tanimoto see docs#IsStarProjection and #25958
Great! Iām happy that reading that PR conversation I now understand how these things can be properly done. Also good that it is all in the pipeline!
Last updated: Dec 20 2025 at 21:32 UTC