Partially defined linear maps #
A LinearPMap R E F
or E →ₗ.[R] F
is a linear map from a submodule of E
to F
.
We define a SemilatticeInf
with OrderBot
instance on this, and define three operations:
mkSpanSingleton
defines a partial linear map defined on the span of a singleton.sup
takes two partial linear mapsf
,g
that agree on the intersection of their domains, and returns the unique partial linear map onf.domain ⊔ g.domain
that extends bothf
andg
.sSup
takes aDirectedOn (· ≤ ·)
set of partial linear maps, and returns the unique partial linear map on thesSup
of their domains that extends all these maps.
Moreover, we define
LinearPMap.graph
is the graph of the partial linear map viewed as a submodule ofE × F
.
Partially defined maps are currently used in Mathlib
to prove Hahn-Banach theorem
and its variations. Namely, LinearPMap.sSup
implies that every chain of LinearPMap
s
is bounded above.
They are also the basis for the theory of unbounded operators.
A LinearPMap R E F
or E →ₗ.[R] F
is a linear map from a submodule of E
to F
.
- domain : Submodule R E
A LinearPMap R E F
or E →ₗ.[R] F
is a linear map from a submodule of E
to F
.
Equations
- One or more equations did not get rendered due to their size.
Equations
- ↑f = ⇑f.toFun
Equations
The unique LinearPMap
on R ∙ x
that sends x
to y
. This version works for modules
over rings, and requires a proof of ∀ c, c • x = 0 → c • y = 0
.
Equations
- One or more equations did not get rendered due to their size.
The unique LinearPMap
on span R {x}
that sends a non-zero vector x
to y
.
This version works for modules over division rings.
Equations
- LinearPMap.mkSpanSingleton x y hx = LinearPMap.mkSpanSingleton' x y ⋯
Projection to the first coordinate as a LinearPMap
Equations
- LinearPMap.fst p p' = { domain := p.prod p', toFun := LinearMap.fst R E F ∘ₗ (p.prod p').subtype }
Projection to the second coordinate as a LinearPMap
Equations
- LinearPMap.snd p p' = { domain := p.prod p', toFun := LinearMap.snd R E F ∘ₗ (p.prod p').subtype }
Given two partial linear maps f
, g
, the set of points x
such that
both f
and g
are defined at x
and f x = g x
form a submodule.
Equations
- LinearPMap.bot = { bot := { domain := ⊥, toFun := 0 } }
Equations
- LinearPMap.inhabited = { default := ⊥ }
Equations
- LinearPMap.semilatticeInf = SemilatticeInf.mk (fun (f g : E →ₗ.[R] F) => { domain := f.eqLocus g, toFun := f.toFun ∘ₗ Submodule.inclusion ⋯ }) ⋯ ⋯ ⋯
Equations
Given two partial linear maps that agree on the intersection of their domains,
f.sup g h
is the unique partial linear map on f.domain ⊔ g.domain
that agrees
with f
and g
.
Equations
- f.sup g h = { domain := f.domain ⊔ g.domain, toFun := Classical.choose ⋯ }
Hypothesis for LinearPMap.sup
holds, if f.domain
is disjoint with g.domain
.
Algebraic operations #
Equations
- LinearPMap.instZero = { zero := { domain := ⊤, toFun := 0 } }
Equations
- LinearPMap.instSMul = { smul := fun (a : M) (f : E →ₗ.[R] F) => { domain := f.domain, toFun := a • f.toFun } }
Equations
Equations
- LinearPMap.instNeg = { neg := fun (f : E →ₗ.[R] F) => { domain := f.domain, toFun := -f.toFun } }
Equations
Equations
- LinearPMap.instAdd = { add := fun (f g : E →ₗ.[R] F) => { domain := f.domain ⊓ g.domain, toFun := f.toFun ∘ₗ Submodule.inclusion ⋯ + g.toFun ∘ₗ Submodule.inclusion ⋯ } }
Equations
Equations
Equations
Equations
Equations
Equations
- LinearPMap.instSub = { sub := fun (f g : E →ₗ.[R] F) => { domain := f.domain ⊓ g.domain, toFun := f.toFun ∘ₗ Submodule.inclusion ⋯ - g.toFun ∘ₗ Submodule.inclusion ⋯ } }
Extend a LinearPMap
to f.domain ⊔ K ∙ x
.
Equations
- f.supSpanSingleton x y hx = f.sup (LinearPMap.mkSpanSingleton x y ⋯) ⋯
Equations
- LinearPMap.sSup c hc = { domain := sSup (LinearPMap.domain '' c), toFun := Classical.choose ⋯ }
Restrict a linear map to a submodule, reinterpreting the result as a LinearPMap
.
Equations
- f.toPMap p = { domain := p, toFun := f ∘ₗ p.subtype }
Compose a linear map with a LinearPMap
Equations
- g.compPMap f = { domain := f.domain, toFun := g ∘ₗ f.toFun }
Restrict codomain of a LinearPMap
Equations
- f.codRestrict p H = { domain := f.domain, toFun := LinearMap.codRestrict p f.toFun H }
Compose two LinearPMap
s
Equations
- g.comp f H = g.toFun.compPMap (f.codRestrict g.domain H)
f.coprod g
is the partially defined linear map defined on f.domain × g.domain
,
and sending p
to f p.1 + g p.2
.
Equations
- f.coprod g = { domain := f.domain.prod g.domain, toFun := (f.comp (LinearPMap.fst f.domain g.domain) ⋯).toFun + (g.comp (LinearPMap.snd f.domain g.domain) ⋯).toFun }
Restrict a partially defined linear map to a submodule of E
contained in f.domain
.
Equations
- f.domRestrict S = { domain := S ⊓ f.domain, toFun := f.toFun ∘ₗ Submodule.inclusion ⋯ }
Graph #
The graph of a LinearPMap
viewed as a submodule on E × F
.
Equations
- f.graph = Submodule.map (f.domain.subtype.prodMap LinearMap.id) f.toFun.graph
The tuple (x, f x)
is contained in the graph of f
.
The graph of z • f
as a pushforward.
The graph of -f
as a pushforward.
The property that f 0 = 0
in terms of the graph.
Auxiliary definition to unfold the existential quantifier.
Equations
- Submodule.valFromGraph hg ha = ⋯.choose
Define a LinearMap
from its graph.
Helper definition for LinearPMap
.
Equations
- g.toLinearPMapAux hg = { toFun := fun (x : ↥(Submodule.map (LinearMap.fst R E F) g)) => Submodule.valFromGraph hg ⋯, map_add' := ⋯, map_smul' := ⋯ }
Define a LinearPMap
from its graph.
In the case that the submodule is not a graph of a LinearPMap
then the underlying linear map
is just the zero map.
Equations
- g.toLinearPMap = { domain := Submodule.map (LinearMap.fst R E F) g, toFun := if hg : ∀ x ∈ g, x.1 = 0 → x.2 = 0 then g.toLinearPMapAux hg else 0 }
The inverse of a LinearPMap
.
Equations
- f.inverse = (Submodule.map (LinearEquiv.prodComm R E F) f.graph).toLinearPMap
The graph of the inverse generates a LinearPMap
.