|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Moritz Doll. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Moritz Doll |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module analysis.inner_product_space.linear_pmap |
| 7 | +! leanprover-community/mathlib commit 8b981918a93bc45a8600de608cde7944a80d92b9 |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Analysis.InnerProductSpace.Adjoint |
| 12 | +import Mathlib.Topology.Algebra.Module.LinearPMap |
| 13 | +import Mathlib.Topology.Algebra.Module.Basic |
| 14 | + |
| 15 | +/-! |
| 16 | +
|
| 17 | +# Partially defined linear operators on Hilbert spaces |
| 18 | +
|
| 19 | +We will develop the basics of the theory of unbounded operators on Hilbert spaces. |
| 20 | +
|
| 21 | +## Main definitions |
| 22 | +
|
| 23 | +* `LinearPMap.IsFormalAdjoint`: An operator `T` is a formal adjoint of `S` if for all `x` in the |
| 24 | + domain of `T` and `y` in the domain of `S`, we have that `⟪T x, y⟫ = ⟪x, S y⟫`. |
| 25 | +* `LinearPMap.adjoint`: The adjoint of a map `E →ₗ.[𝕜] F` as a map `F →ₗ.[𝕜] E`. |
| 26 | +
|
| 27 | +## Main statements |
| 28 | +
|
| 29 | +* `LinearPMap.adjoint_isFormalAdjoint`: The adjoint is a formal adjoint |
| 30 | +* `LinearPMap.IsFormalAdjoint.le_adjoint`: Every formal adjoint is contained in the adjoint |
| 31 | +* `ContinuousLinearMap.toPMap_adjoint_eq_adjoint_toPMap_of_dense`: The adjoint on |
| 32 | + `ContinuousLinearMap` and `LinearPMap` coincide. |
| 33 | +
|
| 34 | +## Notation |
| 35 | +
|
| 36 | +* For `T : E →ₗ.[𝕜] F` the adjoint can be written as `T†`. |
| 37 | + This notation is localized in `LinearPMap`. |
| 38 | +
|
| 39 | +## Implementation notes |
| 40 | +
|
| 41 | +We use the junk value pattern to define the adjoint for all `LinearPMap`s. In the case that |
| 42 | +`T : E →ₗ.[𝕜] F` is not densely defined the adjoint `T†` is the zero map from `T.adjoint.domain` to |
| 43 | +`E`. |
| 44 | +
|
| 45 | +## References |
| 46 | +
|
| 47 | +* [J. Weidmann, *Linear Operators in Hilbert Spaces*][weidmann_linear] |
| 48 | +
|
| 49 | +## Tags |
| 50 | +
|
| 51 | +Unbounded operators, closed operators |
| 52 | +-/ |
| 53 | + |
| 54 | + |
| 55 | +noncomputable section |
| 56 | + |
| 57 | +open IsROrC |
| 58 | + |
| 59 | +open scoped ComplexConjugate Classical |
| 60 | + |
| 61 | +variable {𝕜 E F G : Type _} [IsROrC 𝕜] |
| 62 | + |
| 63 | +variable [NormedAddCommGroup E] [InnerProductSpace 𝕜 E] |
| 64 | + |
| 65 | +variable [NormedAddCommGroup F] [InnerProductSpace 𝕜 F] |
| 66 | + |
| 67 | +local notation "⟪" x ", " y "⟫" => @inner 𝕜 _ _ x y |
| 68 | + |
| 69 | +namespace LinearPMap |
| 70 | + |
| 71 | +/-- An operator `T` is a formal adjoint of `S` if for all `x` in the domain of `T` and `y` in the |
| 72 | +domain of `S`, we have that `⟪T x, y⟫ = ⟪x, S y⟫`. -/ |
| 73 | +def IsFormalAdjoint (T : E →ₗ.[𝕜] F) (S : F →ₗ.[𝕜] E) : Prop := |
| 74 | + ∀ (x : T.domain) (y : S.domain), ⟪T x, y⟫ = ⟪(x : E), S y⟫ |
| 75 | +#align linear_pmap.is_formal_adjoint LinearPMap.IsFormalAdjoint |
| 76 | + |
| 77 | +variable {T : E →ₗ.[𝕜] F} {S : F →ₗ.[𝕜] E} |
| 78 | + |
| 79 | +protected theorem IsFormalAdjoint.symm (h : T.IsFormalAdjoint S) : |
| 80 | + S.IsFormalAdjoint T := fun y _ => by |
| 81 | + rw [← inner_conj_symm, ← inner_conj_symm (y : F), h] |
| 82 | +#align linear_pmap.is_formal_adjoint.symm LinearPMap.IsFormalAdjoint.symm |
| 83 | + |
| 84 | +variable (T) |
| 85 | + |
| 86 | +/-- The domain of the adjoint operator. |
| 87 | +
|
| 88 | +This definition is needed to construct the adjoint operator and the preferred version to use is |
| 89 | +`T.adjoint.domain` instead of `T.adjointDomain`. -/ |
| 90 | +def adjointDomain : Submodule 𝕜 F where |
| 91 | + carrier := {y | Continuous ((innerₛₗ 𝕜 y).comp T.toFun)} |
| 92 | + zero_mem' := by |
| 93 | + rw [Set.mem_setOf_eq, LinearMap.map_zero, LinearMap.zero_comp] |
| 94 | + exact continuous_zero |
| 95 | + add_mem' hx hy := by rw [Set.mem_setOf_eq, LinearMap.map_add] at *; exact hx.add hy |
| 96 | + smul_mem' a x hx := by |
| 97 | + rw [Set.mem_setOf_eq, LinearMap.map_smulₛₗ] at * |
| 98 | + exact hx.const_smul (conj a) |
| 99 | +#align linear_pmap.adjoint_domain LinearPMap.adjointDomain |
| 100 | + |
| 101 | +/-- The operator `λ x, ⟪y, T x⟫` considered as a continuous linear operator from `T.adjointDomain` |
| 102 | +to `𝕜`. -/ |
| 103 | +def adjointDomainMkClm (y : T.adjointDomain) : T.domain →L[𝕜] 𝕜 := |
| 104 | + ⟨(innerₛₗ 𝕜 (y : F)).comp T.toFun, y.prop⟩ |
| 105 | +#align linear_pmap.adjoint_domain_mk_clm LinearPMap.adjointDomainMkClm |
| 106 | + |
| 107 | +theorem adjointDomainMkClm_apply (y : T.adjointDomain) (x : T.domain) : |
| 108 | + adjointDomainMkClm T y x = ⟪(y : F), T x⟫ := |
| 109 | + rfl |
| 110 | +#align linear_pmap.adjoint_domain_mk_clm_apply LinearPMap.adjointDomainMkClm_apply |
| 111 | + |
| 112 | +variable {T} |
| 113 | + |
| 114 | +variable (hT : Dense (T.domain : Set E)) |
| 115 | + |
| 116 | +/-- The unique continuous extension of the operator `adjointDomainMkClm` to `E`. -/ |
| 117 | +def adjointDomainMkClmExtend (y : T.adjointDomain) : E →L[𝕜] 𝕜 := |
| 118 | + (T.adjointDomainMkClm y).extend (Submodule.subtypeL T.domain) hT.denseRange_val |
| 119 | + uniformEmbedding_subtype_val.toUniformInducing |
| 120 | +#align linear_pmap.adjoint_domain_mk_clm_extend LinearPMap.adjointDomainMkClmExtend |
| 121 | + |
| 122 | +@[simp] |
| 123 | +theorem adjointDomainMkClmExtend_apply (y : T.adjointDomain) (x : T.domain) : |
| 124 | + adjointDomainMkClmExtend hT y (x : E) = ⟪(y : F), T x⟫ := |
| 125 | + ContinuousLinearMap.extend_eq _ _ _ _ _ |
| 126 | +#align linear_pmap.adjoint_domain_mk_clm_extend_apply LinearPMap.adjointDomainMkClmExtend_apply |
| 127 | + |
| 128 | +variable [CompleteSpace E] |
| 129 | + |
| 130 | +/-- The adjoint as a linear map from its domain to `E`. |
| 131 | +
|
| 132 | +This is an auxiliary definition needed to define the adjoint operator as a `LinearPMap` without |
| 133 | +the assumption that `T.domain` is dense. -/ |
| 134 | +def adjointAux : T.adjointDomain →ₗ[𝕜] E where |
| 135 | + toFun y := (InnerProductSpace.toDual 𝕜 E).symm (adjointDomainMkClmExtend hT y) |
| 136 | + map_add' x y := |
| 137 | + hT.eq_of_inner_left fun _ => by |
| 138 | + simp only [inner_add_left, Submodule.coe_add, InnerProductSpace.toDual_symm_apply, |
| 139 | + adjointDomainMkClmExtend_apply] |
| 140 | + -- Porting note(https://github.com/leanprover-community/mathlib4/issues/5026): |
| 141 | + -- mathlib3 was finished here |
| 142 | + rw [adjointDomainMkClmExtend_apply, adjointDomainMkClmExtend_apply, |
| 143 | + adjointDomainMkClmExtend_apply] |
| 144 | + simp only [AddSubmonoid.coe_add, Submodule.coe_toAddSubmonoid, inner_add_left] |
| 145 | + map_smul' _ _ := |
| 146 | + hT.eq_of_inner_left fun _ => by |
| 147 | + simp only [inner_smul_left, Submodule.coe_smul_of_tower, RingHom.id_apply, |
| 148 | + InnerProductSpace.toDual_symm_apply, adjointDomainMkClmExtend_apply] |
| 149 | + -- Porting note(https://github.com/leanprover-community/mathlib4/issues/5026): |
| 150 | + -- mathlib3 was finished here |
| 151 | + rw [adjointDomainMkClmExtend_apply, adjointDomainMkClmExtend_apply] |
| 152 | + simp only [Submodule.coe_smul_of_tower, inner_smul_left] |
| 153 | +#align linear_pmap.adjoint_aux LinearPMap.adjointAux |
| 154 | + |
| 155 | +theorem adjointAux_inner (y : T.adjointDomain) (x : T.domain) : |
| 156 | + ⟪adjointAux hT y, x⟫ = ⟪(y : F), T x⟫ := by |
| 157 | + simp only [adjointAux, LinearMap.coe_mk, InnerProductSpace.toDual_symm_apply, |
| 158 | + adjointDomainMkClmExtend_apply] |
| 159 | + -- Porting note(https://github.com/leanprover-community/mathlib4/issues/5026): |
| 160 | + -- mathlib3 was finished here |
| 161 | + simp only [AddHom.coe_mk, InnerProductSpace.toDual_symm_apply] |
| 162 | + rw [adjointDomainMkClmExtend_apply] |
| 163 | +#align linear_pmap.adjoint_aux_inner LinearPMap.adjointAux_inner |
| 164 | + |
| 165 | +theorem adjointAux_unique (y : T.adjointDomain) {x₀ : E} |
| 166 | + (hx₀ : ∀ x : T.domain, ⟪x₀, x⟫ = ⟪(y : F), T x⟫) : adjointAux hT y = x₀ := |
| 167 | + hT.eq_of_inner_left fun v => (adjointAux_inner hT _ _).trans (hx₀ v).symm |
| 168 | +#align linear_pmap.adjoint_aux_unique LinearPMap.adjointAux_unique |
| 169 | + |
| 170 | +variable (T) |
| 171 | + |
| 172 | +/-- The adjoint operator as a partially defined linear operator. -/ |
| 173 | +def adjoint : F →ₗ.[𝕜] E where |
| 174 | + domain := T.adjointDomain |
| 175 | + toFun := if hT : Dense (T.domain : Set E) then adjointAux hT else 0 |
| 176 | +#align linear_pmap.adjoint LinearPMap.adjoint |
| 177 | + |
| 178 | +scoped postfix:1024 "†" => LinearPMap.adjoint |
| 179 | + |
| 180 | +theorem mem_adjoint_domain_iff (y : F) : y ∈ T†.domain ↔ Continuous ((innerₛₗ 𝕜 y).comp T.toFun) := |
| 181 | + Iff.rfl |
| 182 | +#align linear_pmap.mem_adjoint_domain_iff LinearPMap.mem_adjoint_domain_iff |
| 183 | + |
| 184 | +variable {T} |
| 185 | + |
| 186 | +theorem mem_adjoint_domain_of_exists (y : F) (h : ∃ w : E, ∀ x : T.domain, ⟪w, x⟫ = ⟪y, T x⟫) : |
| 187 | + y ∈ T†.domain := by |
| 188 | + cases' h with w hw |
| 189 | + rw [T.mem_adjoint_domain_iff] |
| 190 | + -- Porting note: was `by continuity` |
| 191 | + have : Continuous ((innerSL 𝕜 w).comp T.domain.subtypeL) := ContinuousLinearMap.continuous _ |
| 192 | + convert this using 1 |
| 193 | + exact funext fun x => (hw x).symm |
| 194 | +#align linear_pmap.mem_adjoint_domain_of_exists LinearPMap.mem_adjoint_domain_of_exists |
| 195 | + |
| 196 | +theorem adjoint_apply_of_not_dense (hT : ¬Dense (T.domain : Set E)) (y : T†.domain) : T† y = 0 := by |
| 197 | + change (if hT : Dense (T.domain : Set E) then adjointAux hT else 0) y = _ |
| 198 | + simp only [hT, not_false_iff, dif_neg, LinearMap.zero_apply] |
| 199 | +#align linear_pmap.adjoint_apply_of_not_dense LinearPMap.adjoint_apply_of_not_dense |
| 200 | + |
| 201 | +theorem adjoint_apply_of_dense (y : T†.domain) : T† y = adjointAux hT y := by |
| 202 | + change (if hT : Dense (T.domain : Set E) then adjointAux hT else 0) y = _ |
| 203 | + simp only [hT, dif_pos, LinearMap.coe_mk] |
| 204 | +#align linear_pmap.adjoint_apply_of_dense LinearPMap.adjoint_apply_of_dense |
| 205 | + |
| 206 | +theorem adjoint_apply_eq (y : T†.domain) {x₀ : E} (hx₀ : ∀ x : T.domain, ⟪x₀, x⟫ = ⟪(y : F), T x⟫) : |
| 207 | + T† y = x₀ := |
| 208 | + (adjoint_apply_of_dense hT y).symm ▸ adjointAux_unique hT _ hx₀ |
| 209 | +#align linear_pmap.adjoint_apply_eq LinearPMap.adjoint_apply_eq |
| 210 | + |
| 211 | +/-- The fundamental property of the adjoint. -/ |
| 212 | +theorem adjoint_isFormalAdjoint : T†.IsFormalAdjoint T := fun x => |
| 213 | + (adjoint_apply_of_dense hT x).symm ▸ adjointAux_inner hT x |
| 214 | +#align linear_pmap.adjoint_is_formal_adjoint LinearPMap.adjoint_isFormalAdjoint |
| 215 | + |
| 216 | +/-- The adjoint is maximal in the sense that it contains every formal adjoint. -/ |
| 217 | +theorem IsFormalAdjoint.le_adjoint (h : T.IsFormalAdjoint S) : S ≤ T† := |
| 218 | + ⟨-- Trivially, every `x : S.domain` is in `T.adjoint.domain` |
| 219 | + fun x hx => |
| 220 | + mem_adjoint_domain_of_exists _ |
| 221 | + ⟨S ⟨x, hx⟩, h.symm ⟨x, hx⟩⟩,-- Equality on `S.domain` follows from equality |
| 222 | + -- `⟪v, S x⟫ = ⟪v, T.adjoint y⟫` for all `v : T.domain`: |
| 223 | + fun _ _ hxy => (adjoint_apply_eq hT _ fun _ => by rw [h.symm, hxy]).symm⟩ |
| 224 | +#align linear_pmap.is_formal_adjoint.le_adjoint LinearPMap.IsFormalAdjoint.le_adjoint |
| 225 | + |
| 226 | +end LinearPMap |
| 227 | + |
| 228 | +namespace ContinuousLinearMap |
| 229 | + |
| 230 | +variable [CompleteSpace E] [CompleteSpace F] |
| 231 | + |
| 232 | +variable (A : E →L[𝕜] F) {p : Submodule 𝕜 E} |
| 233 | + |
| 234 | +/-- Restricting `A` to a dense submodule and taking the `LinearPMap.adjoint` is the same |
| 235 | +as taking the `continuous_linear_map.adjoint` interpreted as a `linear_pmap`. -/ |
| 236 | +theorem toPMap_adjoint_eq_adjoint_toPMap_of_dense (hp : Dense (p : Set E)) : |
| 237 | + (A.toPMap p).adjoint = A.adjoint.toPMap ⊤ := by |
| 238 | + ext x y hxy |
| 239 | + · simp only [LinearMap.toPMap_domain, Submodule.mem_top, iff_true_iff, |
| 240 | + LinearPMap.mem_adjoint_domain_iff, LinearMap.coe_comp, innerₛₗ_apply_coe] |
| 241 | + exact ((innerSL 𝕜 x).comp <| A.comp <| Submodule.subtypeL _).cont |
| 242 | + refine' LinearPMap.adjoint_apply_eq _ _ fun v => _ |
| 243 | + · -- Porting note: was simply `hp` as an argument above |
| 244 | + simpa using hp |
| 245 | + · simp only [adjoint_inner_left, hxy, LinearMap.toPMap_apply, coe_coe] |
| 246 | +#align continuous_linear_map.to_pmap_adjoint_eq_adjoint_to_pmap_of_dense ContinuousLinearMap.toPMap_adjoint_eq_adjoint_toPMap_of_dense |
| 247 | + |
| 248 | +end ContinuousLinearMap |
0 commit comments