Skip to content

Commit 6286c6b

Browse files
feat: Hilbert space & unbounded operators on Space (leanprover-community#957)
* d-dim Hilbert space * d-dim schwartz submodule * init progress on unbounded ops * init progress on unbounded ops * submodule lemmas * abstract away Hilbert space * linter fixes * sorry removed: closable => adjoint dense * sorry removed: symm + dense => closable * sorry-free * comments * UnboundedOperator extends LinearPMap * remove unnecessary coe * relocate submodule lemmas * style improvements * more improvements * extract adjoint_isClosable_dense * minor cleanup * lint fixes * Remove extra blank lines * Remove extra blank lines --------- Co-authored-by: Daniel Morrison <39346894+morrison-daniel@users.noreply.github.com>
1 parent 6d5baa1 commit 6286c6b

5 files changed

Lines changed: 529 additions & 0 deletions

File tree

PhysLean.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import PhysLean.Mathematics.Geometry.Metric.Riemannian.Defs
5757
import PhysLean.Mathematics.InnerProductSpace.Adjoint
5858
import PhysLean.Mathematics.InnerProductSpace.Basic
5959
import PhysLean.Mathematics.InnerProductSpace.Calculus
60+
import PhysLean.Mathematics.InnerProductSpace.Submodule
6061
import PhysLean.Mathematics.KroneckerDelta
6162
import PhysLean.Mathematics.LinearMaps
6263
import PhysLean.Mathematics.List
@@ -233,6 +234,9 @@ import PhysLean.QuantumMechanics.DDimensions.Operators.AngularMomentum
233234
import PhysLean.QuantumMechanics.DDimensions.Operators.Commutation
234235
import PhysLean.QuantumMechanics.DDimensions.Operators.Momentum
235236
import PhysLean.QuantumMechanics.DDimensions.Operators.Position
237+
import PhysLean.QuantumMechanics.DDimensions.Operators.Unbounded
238+
import PhysLean.QuantumMechanics.DDimensions.SpaceDHilbertSpace.Basic
239+
import PhysLean.QuantumMechanics.DDimensions.SpaceDHilbertSpace.SchwartzSubmodule
236240
import PhysLean.QuantumMechanics.FiniteTarget.Basic
237241
import PhysLean.QuantumMechanics.FiniteTarget.HilbertSpace
238242
import PhysLean.QuantumMechanics.OneDimension.GeneralPotential.Basic
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/-
2+
Copyright (c) 2026 Gregory J. Loges. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Gregory J. Loges
5+
-/
6+
import Mathlib.Analysis.InnerProductSpace.LinearPMap
7+
/-!
8+
9+
# Submodules of `E × E`
10+
11+
In this module we define `submoduleToLp` which reinterprets a submodule of `E × E`,
12+
where `E` is an inner product space, as a submodule of `WithLp 2 (E × E)`.
13+
This allows us to take advantage of the inner product structure, since otherwise
14+
by default `E × E` is given the sup norm.
15+
16+
-/
17+
18+
namespace InnerProductSpaceSubmodule
19+
20+
open LinearPMap Submodule
21+
22+
variable
23+
{E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℂ E]
24+
(M : Submodule ℂ (E × E))
25+
26+
/-- The submodule of `WithLp 2 (E × E)` defined by `M`. -/
27+
def submoduleToLp : Submodule ℂ (WithLp 2 (E × E)) where
28+
carrier := {x | x.ofLp ∈ M}
29+
add_mem' := by
30+
intro a b ha hb
31+
exact Submodule.add_mem M ha hb
32+
zero_mem' := Submodule.zero_mem M
33+
smul_mem' := by
34+
intro c x hx
35+
exact Submodule.smul_mem M c hx
36+
37+
lemma mem_submodule_iff_mem_submoduleToLp (f : E × E) :
38+
f ∈ M ↔ (WithLp.toLp 2 f) ∈ submoduleToLp M := Eq.to_iff rfl
39+
40+
lemma submoduleToLp_closure :
41+
(submoduleToLp M.topologicalClosure) = (submoduleToLp M).topologicalClosure := by
42+
rw [Submodule.ext_iff]
43+
intro x
44+
rw [← mem_submodule_iff_mem_submoduleToLp]
45+
change x.ofLp ∈ _root_.closure M ↔ x ∈ _root_.closure (submoduleToLp M)
46+
repeat rw [mem_closure_iff_nhds]
47+
constructor
48+
· intro h t ht
49+
apply mem_nhds_iff.mp at ht
50+
rcases ht with ⟨t1, ht1, ht1', hx⟩
51+
have : ∃ t' ∈ nhds x.ofLp, (∀ y ∈ t', WithLp.toLp 2 y ∈ t1) := by
52+
refine Filter.eventually_iff_exists_mem.mp ?_
53+
apply ContinuousAt.eventually_mem (by fun_prop) (IsOpen.mem_nhds ht1' hx)
54+
rcases this with ⟨t2, ht2, ht2'⟩
55+
rcases h t2 ht2 with ⟨w, hw⟩
56+
use WithLp.toLp 2 w
57+
exact ⟨Set.mem_preimage.mp (ht1 (ht2' w hw.1)),
58+
(mem_submodule_iff_mem_submoduleToLp M w).mpr hw.2
59+
· intro h t ht
60+
apply mem_nhds_iff.mp at ht
61+
rcases ht with ⟨t1, ht1, ht1', hx⟩
62+
have : ∃ t' ∈ nhds x, (∀ y ∈ t', y.ofLp ∈ t1) := by
63+
refine Filter.eventually_iff_exists_mem.mp ?_
64+
exact ContinuousAt.eventually_mem (by fun_prop) (IsOpen.mem_nhds ht1' hx)
65+
rcases this with ⟨t2, ht2, ht2'⟩
66+
rcases h t2 ht2 with ⟨w, hw⟩
67+
use w.ofLp
68+
exact ⟨Set.mem_preimage.mp (ht1 (ht2' w hw.1)), (mem_toAddSubgroup (submoduleToLp M)).mp hw.2
69+
70+
lemma mem_submodule_closure_iff_mem_submoduleToLp_closure (f : E × E) :
71+
f ∈ M.topologicalClosure ↔ (WithLp.toLp 2 f) ∈ (submoduleToLp M).topologicalClosure := by
72+
rw [← submoduleToLp_closure]
73+
rfl
74+
75+
lemma mem_submodule_adjoint_iff_mem_submoduleToLp_orthogonal (f : E × E) :
76+
f ∈ M.adjoint ↔ WithLp.toLp 2 (f.2, -f.1) ∈ (submoduleToLp M)ᗮ := by
77+
constructor <;> intro h
78+
· rw [mem_orthogonal]
79+
intro u hu
80+
rw [mem_adjoint_iff] at h
81+
have h' : inner ℂ u.snd f.1 = inner ℂ u.fst f.2 := by
82+
rw [← sub_eq_zero]
83+
exact h u.fst u.snd hu
84+
simp [h']
85+
· rw [mem_adjoint_iff]
86+
intro a b hab
87+
rw [mem_orthogonal] at h
88+
have hab' := (mem_submodule_iff_mem_submoduleToLp M (a, b)).mp hab
89+
have h' : inner ℂ a f.2 = inner ℂ b f.1 := by
90+
rw [← sub_eq_zero, sub_eq_add_neg, ← inner_neg_right]
91+
exact h (WithLp.toLp 2 (a, b)) hab'
92+
simp [h']
93+
94+
lemma mem_submodule_adjoint_adjoint_iff_mem_submoduleToLp_orthogonal_orthogonal (f : E × E) :
95+
f ∈ M.adjoint.adjoint ↔ WithLp.toLp 2 f ∈ (submoduleToLp M)ᗮᗮ := by
96+
simp only [mem_adjoint_iff]
97+
trans ∀ v, (∀ w ∈ submoduleToLp M, inner ℂ w v = 0) → inner ℂ v (WithLp.toLp 2 f) = 0
98+
· constructor <;> intro h
99+
· intro v hw
100+
have h' := h (-v.snd) v.fst
101+
rw [inner_neg_left, sub_neg_eq_add] at h'
102+
apply h'
103+
intro a b hab
104+
rw [inner_neg_right, neg_sub_left, neg_eq_zero]
105+
exact hw (WithLp.toLp 2 (a, b)) ((mem_submodule_iff_mem_submoduleToLp M (a, b)).mp hab)
106+
· intro a b h'
107+
rw [sub_eq_add_neg, ← inner_neg_left]
108+
apply h (WithLp.toLp 2 (b, -a))
109+
intro w hw
110+
have hw' := h' w.fst w.snd hw
111+
rw [sub_eq_zero] at hw'
112+
simp [hw']
113+
simp only [← mem_orthogonal]
114+
115+
lemma mem_submodule_closure_adjoint_iff_mem_submoduleToLp_closure_orthogonal (f : E × E) :
116+
f ∈ M.topologicalClosure.adjoint ↔
117+
WithLp.toLp 2 (f.2, -f.1) ∈ (submoduleToLp M).topologicalClosureᗮ := by
118+
rw [mem_submodule_adjoint_iff_mem_submoduleToLp_orthogonal, submoduleToLp_closure]
119+
120+
end InnerProductSpaceSubmodule
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/-
2+
Copyright (c) 2026 Gregory J. Loges. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Gregory J. Loges
5+
-/
6+
import PhysLean.Mathematics.InnerProductSpace.Submodule
7+
import PhysLean.QuantumMechanics.DDimensions.SpaceDHilbertSpace.SchwartzSubmodule
8+
/-!
9+
10+
# Unbounded operators
11+
12+
In this file we define
13+
- `UnboundedOperator`: an unbounded operator with domain a submodule of a generic Hilbert space.
14+
All unbounded operators are assumed to be both densely defined and closable.
15+
- The closure, `UnboundedOperator.closure`, and adjoint, `UnboundedOperator.adjoint`, with notation
16+
`U† = U.adjoint`. That `U†` is densely defined is guaranteed by the closability of `U`.
17+
- The concept of a generalized eigenvector in `IsGeneralizedEigenvector`.
18+
19+
We prove some basic relations, making use of the density and closability assumptions:
20+
- `U.closure† = U†` in `closure_adjoint_eq_adjoint`
21+
- `U†† = U.closure` in `adjoint_adjoint_eq_closure`
22+
23+
## References
24+
25+
- K. Schmüdgen, (2012). "Unbounded self-adjoint operators on Hilbert space" (Vol. 265). Springer.
26+
https://doi.org/10.1007/978-94-007-4753-1
27+
28+
-/
29+
30+
namespace QuantumMechanics
31+
32+
open LinearPMap Submodule
33+
34+
/-- An `UnboundedOperator` is a linear map from a submodule of the Hilbert space
35+
to the Hilbert space, assumed to be both densely defined and closable. -/
36+
@[ext]
37+
structure UnboundedOperator
38+
(HS : Type*) [NormedAddCommGroup HS] [InnerProductSpace ℂ HS] [CompleteSpace HS]
39+
extends LinearPMap ℂ HS HS where
40+
/-- The domain of an unbounded operator is dense in the Hilbert space. -/
41+
dense_domain : Dense (domain : Set HS)
42+
/-- An unbounded operator is closable. -/
43+
is_closable : toLinearPMap.IsClosable
44+
45+
namespace UnboundedOperator
46+
47+
variable
48+
{HS : Type*} [NormedAddCommGroup HS] [InnerProductSpace ℂ HS] [CompleteSpace HS]
49+
(U : UnboundedOperator HS)
50+
51+
lemma ext' (U T : UnboundedOperator HS) (h : U.toLinearPMap = T.toLinearPMap) : U = T := by
52+
apply UnboundedOperator.ext
53+
· exact toSubMulAction_inj.mp (congrArg toSubMulAction (congrArg domain h))
54+
· exact congr_arg_heq toFun h
55+
56+
lemma ext_iff' (U T : UnboundedOperator HS) : U = T ↔ U.toLinearPMap = T.toLinearPMap := by
57+
refine ⟨?_, UnboundedOperator.ext' U T⟩
58+
intro h
59+
rw [h]
60+
61+
/-!
62+
### Construction of unbounded operators
63+
-/
64+
65+
variable {E : Submodule ℂ HS} {hE : Dense (E : Set HS)}
66+
67+
/-- An `UnboundedOperator` constructed from a symmetric linear map on a dense submodule `E`. -/
68+
def ofSymmetric (f : E →ₗ[ℂ] E) (hf : f.IsSymmetric) : UnboundedOperator HS where
69+
toLinearPMap := LinearPMap.mk E (E.subtype ∘ₗ f)
70+
dense_domain := hE
71+
is_closable := by
72+
refine isClosable_iff_exists_closed_extension.mpr ?_
73+
use (LinearPMap.mk E (E.subtype ∘ₗ f))†
74+
exact ⟨adjoint_isClosed hE, IsFormalAdjoint.le_adjoint hE hf⟩
75+
76+
@[simp]
77+
lemma ofSymmetric_apply {f : E →ₗ[ℂ] E} {hf : f.IsSymmetric} (ψ : E) :
78+
(ofSymmetric (hE := hE) f hf).toLinearPMap ψ = E.subtypeL (f ψ) := rfl
79+
80+
/-!
81+
### Closure
82+
-/
83+
84+
section Closure
85+
86+
/-- The closure of an unbounded operator. -/
87+
noncomputable def closure : UnboundedOperator HS where
88+
toLinearPMap := U.toLinearPMap.closure
89+
dense_domain := Dense.mono (HasCore.le_domain (closureHasCore U.toLinearPMap)) U.dense_domain
90+
is_closable := IsClosed.isClosable (IsClosable.closure_isClosed U.is_closable)
91+
92+
@[simp]
93+
lemma closure_toLinearPMap : U.closure.toLinearPMap = U.toLinearPMap.closure := rfl
94+
95+
/-- An unbounded operator is closed iff the graph of its defining LinearPMap is closed. -/
96+
def IsClosed : Prop := U.toLinearPMap.IsClosed
97+
98+
lemma closure_isClosed : U.closure.IsClosed := IsClosable.closure_isClosed U.is_closable
99+
100+
end Closure
101+
102+
/-!
103+
### Adjoints
104+
-/
105+
106+
section Adjoints
107+
108+
open InnerProductSpaceSubmodule
109+
110+
/-- The adjoint of a densely defined, closable `LinearPMap` is densely defined. -/
111+
lemma adjoint_isClosable_dense (f : LinearPMap ℂ HS HS) (h_dense : Dense (f.domain : Set HS))
112+
(h_closable : f.IsClosable) : Dense (f†.domain : Set HS) := by
113+
by_contra hd
114+
have : ∃ x ∈ f†.domainᗮ, x ≠ 0 := by
115+
apply not_forall.mp at hd
116+
rcases hd with ⟨y, hy⟩
117+
have hnetop : f†.domainᗮᗮ ≠ ⊤ := by
118+
rw [orthogonal_orthogonal_eq_closure]
119+
exact Ne.symm (ne_of_mem_of_not_mem' trivial hy)
120+
have hnebot : f†.domainᗮ ≠ ⊥ := by
121+
by_contra
122+
apply hnetop
123+
rwa [orthogonal_eq_top_iff]
124+
exact exists_mem_ne_zero_of_ne_bot hnebot
125+
rcases this with ⟨x, hx, hx'⟩
126+
apply hx'
127+
apply graph_fst_eq_zero_snd f.closure _ rfl
128+
rw [← IsClosable.graph_closure_eq_closure_graph h_closable,
129+
mem_submodule_closure_iff_mem_submoduleToLp_closure,
130+
← orthogonal_orthogonal_eq_closure,
131+
← mem_submodule_adjoint_adjoint_iff_mem_submoduleToLp_orthogonal_orthogonal,
132+
← LinearPMap.adjoint_graph_eq_graph_adjoint h_dense,
133+
mem_submodule_adjoint_iff_mem_submoduleToLp_orthogonal]
134+
rintro ⟨y, Uy⟩ hy
135+
simp only [neg_zero, WithLp.prod_inner_apply, inner_zero_right, add_zero]
136+
exact hx y (mem_domain_of_mem_graph hy)
137+
138+
/-- The adjoint of an unbounded operator, denoted as `U†`. -/
139+
noncomputable def adjoint : UnboundedOperator HS where
140+
toLinearPMap := U.toLinearPMap.adjoint
141+
dense_domain := adjoint_isClosable_dense U.toLinearPMap U.dense_domain U.is_closable
142+
is_closable := IsClosed.isClosable (adjoint_isClosed U.dense_domain)
143+
144+
@[inherit_doc]
145+
scoped postfix:1024 "†" => UnboundedOperator.adjoint
146+
147+
noncomputable instance instStar : Star (UnboundedOperator HS) where
148+
star := fun U ↦ U.adjoint
149+
150+
@[simp]
151+
lemma adjoint_toLinearPMap : U†.toLinearPMap = U.toLinearPMap† := rfl
152+
153+
lemma isSelfAdjoint_def : IsSelfAdjoint U ↔ U† = U := Iff.rfl
154+
155+
lemma isSelfAdjoint_iff : IsSelfAdjoint U ↔ IsSelfAdjoint U.toLinearPMap := by
156+
rw [isSelfAdjoint_def, LinearPMap.isSelfAdjoint_def, ← adjoint_toLinearPMap,
157+
UnboundedOperator.ext_iff']
158+
159+
lemma adjoint_isClosed : (U†).IsClosed := LinearPMap.adjoint_isClosed U.dense_domain
160+
161+
lemma closure_adjoint_eq_adjoint : U.closure† = U† := by
162+
-- Reduce to statement about graphs using density and closability assumptions
163+
apply UnboundedOperator.ext'
164+
apply LinearPMap.eq_of_eq_graph
165+
rw [adjoint_toLinearPMap, adjoint_graph_eq_graph_adjoint U.closure.dense_domain]
166+
rw [adjoint_toLinearPMap, adjoint_graph_eq_graph_adjoint U.dense_domain]
167+
rw [closure_toLinearPMap, ← IsClosable.graph_closure_eq_closure_graph U.is_closable]
168+
ext f
169+
rw [mem_submodule_closure_adjoint_iff_mem_submoduleToLp_closure_orthogonal,
170+
orthogonal_closure, mem_submodule_adjoint_iff_mem_submoduleToLp_orthogonal]
171+
172+
lemma adjoint_adjoint_eq_closure : U†† = U.closure := by
173+
-- Reduce to statement about graphs using density and closability assumptions
174+
apply UnboundedOperator.ext'
175+
apply LinearPMap.eq_of_eq_graph
176+
rw [adjoint_toLinearPMap, adjoint_graph_eq_graph_adjoint U†.dense_domain]
177+
rw [adjoint_toLinearPMap, adjoint_graph_eq_graph_adjoint U.dense_domain]
178+
rw [closure_toLinearPMap, ← IsClosable.graph_closure_eq_closure_graph U.is_closable]
179+
ext f
180+
rw [mem_submodule_adjoint_adjoint_iff_mem_submoduleToLp_orthogonal_orthogonal,
181+
orthogonal_orthogonal_eq_closure, mem_submodule_closure_iff_mem_submoduleToLp_closure]
182+
183+
end Adjoints
184+
185+
/-!
186+
### Generalized eigenvectors
187+
-/
188+
189+
/-- A map `F : D(U) →L[ℂ] ℂ` is a generalized eigenvector of an unbounded operator `U`
190+
if there is an eigenvalue `c` such that for all `ψ ∈ D(U)`, `F (U ψ) = c ⬝ F ψ`. -/
191+
def IsGeneralizedEigenvector (F : U.domain →L[ℂ] ℂ) (c : ℂ) : Prop :=
192+
∀ ψ : U.domain, ∃ ψ' : U.domain, ψ' = U.toFun ψ ∧ F ψ' = c • F ψ
193+
194+
lemma isGeneralizedEigenvector_ofSymmetric_iff
195+
{f : E →ₗ[ℂ] E} (hf : f.IsSymmetric) (F : E →L[ℂ] ℂ) (c : ℂ) :
196+
IsGeneralizedEigenvector (ofSymmetric (hE := hE) f hf) F c ↔ ∀ ψ : E, F (f ψ) = c • F ψ := by
197+
constructor <;> intro h ψ
198+
· obtain ⟨ψ', hψ', hψ''⟩ := h ψ
199+
apply SetLike.coe_eq_coe.mp at hψ'
200+
subst hψ'
201+
exact hψ''
202+
· use f ψ
203+
exact ⟨by simp, h ψ⟩
204+
205+
end UnboundedOperator
206+
end QuantumMechanics

0 commit comments

Comments
 (0)