Skip to content

Commit e268a25

Browse files
committed
feat: continuous Riemannian vector bundles (#26197)
Given a vector bundle over a manifold whose fibers are all endowed with a scalar product, we say that this bundle is Riemannian if the scalar product depends continuously on the base point. We introduce a typeclass `[IsContinuousRiemannianBundle F E]` registering this property. Under this assumption, we show that the scalar product of two continuous maps into the same fibers of the bundle is a continuous function. If one wants to endow an existing vector bundle with a Riemannian metric, there is a subtlety: the inner product space structure on the fibers should give rise to a topology on the fibers which is defeq to the original one, to avoid diamonds. To do this, we introduce a class `[RiemannianBundle E]` containing the data of a scalar product on the fibers defining the same topology as the original one. Given this class, we can construct `NormedAddCommGroup` and `InnerProductSpace` instances on the fibers, compatible in a defeq way with the initial topology. If the data used to register the instance `RiemannianBundle E` depends continuously on the base point, we register automatically an instance of `[IsContinuousRiemannianBundle F E]` (and similarly if the data is smooth). The general theory should be built assuming `[IsContinuousRiemannianBundle F E]`, while the `[RiemannianBundle E]` mechanism is only to build data in specific situations.
1 parent 87e776f commit e268a25

File tree

4 files changed

+258
-3
lines changed

4 files changed

+258
-3
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6517,6 +6517,7 @@ import Mathlib.Topology.UrysohnsLemma
65176517
import Mathlib.Topology.VectorBundle.Basic
65186518
import Mathlib.Topology.VectorBundle.Constructions
65196519
import Mathlib.Topology.VectorBundle.Hom
6520+
import Mathlib.Topology.VectorBundle.Riemannian
65206521
import Mathlib.Util.AddRelatedDecl
65216522
import Mathlib.Util.AssertExists
65226523
import Mathlib.Util.AssertExistsExt

Mathlib/Analysis/InnerProductSpace/Defs.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ lemma topology_eq
527527

528528
/-- Normed space structure constructed from an `InnerProductSpace.Core` structure, adjusting the
529529
topology to make sure it is defeq to an already existing topology. -/
530-
def toNormedAddCommGroupOfTopology
530+
@[reducible] def toNormedAddCommGroupOfTopology
531531
[tF : TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousConstSMul 𝕜 F]
532532
(h : ContinuousAt (fun (v : F) ↦ cd.inner v v) 0)
533533
(h' : IsVonNBounded 𝕜 {v : F | re (cd.inner v v) < 1}) :
@@ -536,7 +536,7 @@ def toNormedAddCommGroupOfTopology
536536

537537
/-- Normed space structure constructed from an `InnerProductSpace.Core` structure, adjusting the
538538
topology to make sure it is defeq to an already existing topology. -/
539-
def toNormedSpaceOfTopology
539+
@[reducible] def toNormedSpaceOfTopology
540540
[tF : TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousConstSMul 𝕜 F]
541541
(h : ContinuousAt (fun (v : F) ↦ cd.inner v v) 0)
542542
(h' : IsVonNBounded 𝕜 {v : F | re (cd.inner v v) < 1}) :

Mathlib/Analysis/NormedSpace/OperatorNorm/NormedSpace.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@ theorem opNorm_comp_linearIsometryEquiv (f : F →SL[σ₂₃] G) (g : F' ≃ₛ
205205
haveI := g.symm.surjective.nontrivial
206206
simp [g.symm.toLinearIsometry.norm_toContinuousLinearMap]
207207

208-
@[simp]
208+
-- `SeminormedAddGroup (Fₗ →L[𝕜] E →L[𝕜] Fₗ)` is too slow to synthetize in the `simpNF` linter,
209+
-- which fails on this lemma with a deterministic timeout
210+
@[simp, nolint simpNF]
209211
theorem norm_smulRightL (c : E →L[𝕜] 𝕜) [Nontrivial Fₗ] : ‖smulRightL 𝕜 E Fₗ c‖ = ‖c‖ :=
210212
ContinuousLinearMap.homothety_norm _ c.norm_smulRight_apply
211213

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/-
2+
Copyright (c) 2025 Sébastien Gouëzel. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Sébastien Gouëzel
5+
-/
6+
import Mathlib.Analysis.InnerProductSpace.LinearMap
7+
import Mathlib.Topology.VectorBundle.Constructions
8+
import Mathlib.Topology.VectorBundle.Hom
9+
10+
/-! # Riemannian vector bundles
11+
12+
Given a real vector bundle over a topological space whose fibers are all endowed with an inner
13+
product, we say that this bundle is Riemannian if the inner product depends continuously on the
14+
base point.
15+
16+
We introduce a typeclass `[IsContinuousRiemannianBundle F E]` registering this property.
17+
Under this assumption, we show that the inner product of two continuous maps into the same fibers
18+
of the bundle is a continuous function.
19+
20+
If one wants to endow an existing vector bundle with a Riemannian metric, there is a subtlety:
21+
the inner product space structure on the fibers should give rise to a topology on the fibers
22+
which is defeq to the original one, to avoid diamonds. To do this, we introduce a
23+
class `[RiemannianBundle E]` containing the data of an inner
24+
product on the fibers defining the same topology as the original one. Given this class, we can
25+
construct `NormedAddCommGroup` and `InnerProductSpace` instances on the fibers, compatible in a
26+
defeq way with the initial topology. If the data used to register the instance `RiemannianBundle E`
27+
depends continuously on the base point, we register automatically an instance of
28+
`[IsContinuousRiemannianBundle F E]` (and similarly if the data is smooth).
29+
30+
The general theory should be built assuming `[IsContinuousRiemannianBundle F E]`, while the
31+
`[RiemannianBundle E]` mechanism is only to build data in specific situations.
32+
33+
## Keywords
34+
Vector bundle, Riemannian metric
35+
-/
36+
37+
open Bundle ContinuousLinearMap
38+
open scoped Topology
39+
40+
variable
41+
{B : Type*} [TopologicalSpace B]
42+
{F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F]
43+
{E : B → Type*} [TopologicalSpace (TotalSpace F E)] [∀ x, NormedAddCommGroup (E x)]
44+
[∀ x, InnerProductSpace ℝ (E x)]
45+
[FiberBundle F E] [VectorBundle ℝ F E]
46+
47+
local notation "⟪" x ", " y "⟫" => inner ℝ x y
48+
49+
variable (F E) in
50+
/-- Consider a real vector bundle in which each fiber is endowed with an inner product.
51+
We say that the bundle is *Riemannian* if the inner product depends continuously on the base point.
52+
This assumption is spelled `IsContinuousRiemannianBundle F E` where `F` is the model fiber,
53+
and `E : B → Type*` is the bundle. -/
54+
class IsContinuousRiemannianBundle : Prop where
55+
exists_continuous : ∃ g : (Π x, E x →L[ℝ] E x →L[ℝ] ℝ),
56+
Continuous (fun (x : B) ↦ TotalSpace.mk' (F →L[ℝ] F →L[ℝ] ℝ) x (g x))
57+
∧ ∀ (x : B) (v w : E x), ⟪v, w⟫ = g x v w
58+
59+
section Trivial
60+
61+
variable {F₁ : Type*} [NormedAddCommGroup F₁] [InnerProductSpace ℝ F₁]
62+
63+
/-- A trivial vector bundle, in which the model fiber has a inner product,
64+
is a Riemannian bundle. -/
65+
instance : IsContinuousRiemannianBundle F₁ (Bundle.Trivial B F₁) := by
66+
refine ⟨fun x ↦ innerSL ℝ, ?_, fun x v w ↦ rfl⟩
67+
rw [continuous_iff_continuousAt]
68+
intro x
69+
rw [FiberBundle.continuousAt_totalSpace]
70+
refine ⟨continuousAt_id, ?_⟩
71+
convert continuousAt_const (y := innerSL ℝ)
72+
ext v w
73+
simp [hom_trivializationAt_apply, inCoordinates, Trivialization.linearMapAt_apply,
74+
Trivial.trivialization_symm_apply B F₁]
75+
76+
end Trivial
77+
78+
section Continuous
79+
80+
variable
81+
{M : Type*} [TopologicalSpace M] [h : IsContinuousRiemannianBundle F E]
82+
{b : M → B} {v w : ∀ x, E (b x)} {s : Set M} {x : M}
83+
84+
/-- Given two continuous maps into the same fibers of a continuous Riemannian bundle,
85+
their inner product is continuous. Version with `ContinuousWithinAt`. -/
86+
lemma ContinuousWithinAt.inner_bundle
87+
(hv : ContinuousWithinAt (fun m ↦ (v m : TotalSpace F E)) s x)
88+
(hw : ContinuousWithinAt (fun m ↦ (w m : TotalSpace F E)) s x) :
89+
ContinuousWithinAt (fun m ↦ ⟪v m, w m⟫) s x := by
90+
rcases h.exists_continuous with ⟨g, g_cont, hg⟩
91+
have hf : ContinuousWithinAt b s x := by
92+
simp only [FiberBundle.continuousWithinAt_totalSpace] at hv
93+
exact hv.1
94+
simp only [hg]
95+
have : ContinuousWithinAt
96+
(fun m ↦ TotalSpace.mk' ℝ (E := Bundle.Trivial B ℝ) (b m) (g (b m) (v m) (w m))) s x :=
97+
(g_cont.continuousAt.comp_continuousWithinAt hf).clm_bundle_apply₂ (F₁ := F) (F₂ := F) hv hw
98+
simp only [FiberBundle.continuousWithinAt_totalSpace] at this
99+
exact this.2
100+
101+
/-- Given two continuous maps into the same fibers of a continuous Riemannian bundle,
102+
their inner product is continuous. Version with `ContinuousAt`. -/
103+
lemma ContinuousAt.inner_bundle
104+
(hv : ContinuousAt (fun m ↦ (v m : TotalSpace F E)) x)
105+
(hw : ContinuousAt (fun m ↦ (w m : TotalSpace F E)) x) :
106+
ContinuousAt (fun b ↦ ⟪v b, w b⟫) x := by
107+
simp only [← continuousWithinAt_univ] at hv hw ⊢
108+
exact ContinuousWithinAt.inner_bundle hv hw
109+
110+
/-- Given two continuous maps into the same fibers of a continuous Riemannian bundle,
111+
their inner product is continuous. Version with `ContinuousOn`. -/
112+
lemma ContinuousOn.inner_bundle
113+
(hv : ContinuousOn (fun m ↦ (v m : TotalSpace F E)) s)
114+
(hw : ContinuousOn (fun m ↦ (w m : TotalSpace F E)) s) :
115+
ContinuousOn (fun b ↦ ⟪v b, w b⟫) s :=
116+
fun x hx ↦ (hv x hx).inner_bundle (hw x hx)
117+
118+
/-- Given two continuous maps into the same fibers of a continuous Riemannian bundle,
119+
their inner product is continuous. -/
120+
lemma Continuous.inner_bundle
121+
(hv : Continuous (fun m ↦ (v m : TotalSpace F E)))
122+
(hw : Continuous (fun m ↦ (w m : TotalSpace F E))) :
123+
Continuous (fun b ↦ ⟪v b, w b⟫) := by
124+
simp only [continuous_iff_continuousAt] at hv hw ⊢
125+
exact fun x ↦ (hv x).inner_bundle (hw x)
126+
127+
end Continuous
128+
129+
namespace Bundle
130+
131+
section Construction
132+
133+
variable
134+
{B : Type*} [TopologicalSpace B]
135+
{F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F]
136+
{E : B → Type*} [TopologicalSpace (TotalSpace F E)]
137+
[∀ b, TopologicalSpace (E b)] [∀ b, AddCommGroup (E b)] [∀ b, Module ℝ (E b)]
138+
[∀ b, IsTopologicalAddGroup (E b)] [∀ b, ContinuousConstSMul ℝ (E b)]
139+
[FiberBundle F E] [VectorBundle ℝ F E]
140+
141+
open Bornology
142+
143+
variable (E) in
144+
/-- A family of inner product space structures on the fibers of a fiber bundle, defining the same
145+
topology as the already existing one. This family is not assumed to be continuous or smooth: to
146+
guarantee continuity, resp. smoothness, of the inner product as a function of the base point,
147+
use `ContinuousRiemannianMetric` or `ContMDiffRiemannianMetric`.
148+
149+
This structure is used through `RiemannianBundle` for typeclass inference, to register the inner
150+
product space structure on the fibers without creating diamonds. -/
151+
structure RiemannianMetric where
152+
/-- The inner product along the fibers of the bundle. -/
153+
inner (b : B) : E b →L[ℝ] E b →L[ℝ] ℝ
154+
symm (b : B) (v w : E b) : inner b v w = inner b w v
155+
pos (b : B) (v : E b) (hv : v ≠ 0) : 0 < inner b v v
156+
/-- The continuity at `0` is automatic when `E b` is isomorphic to a normed space, but since
157+
we are not making this assumption here we have to include it. -/
158+
continuousAt (b : B) : ContinuousAt (fun (v : E b) ↦ inner b v v) 0
159+
isVonNBounded (b : B) : IsVonNBounded ℝ {v : E b | inner b v v < 1}
160+
161+
/-- `Core structure associated to a family of inner products on the fibers of a fiber bundle. This
162+
is an auxiliary construction to endow the fibers with an inner product space structure without
163+
creating diamonds.
164+
165+
Warning: Do not use this `Core` structure if the space you are interested in already has a norm
166+
instance defined on it, otherwise this will create a second non-defeq norm instance! -/
167+
@[reducible] noncomputable def RiemannianMetric.toCore (g : RiemannianMetric E) (b : B) :
168+
InnerProductSpace.Core ℝ (E b) where
169+
inner v w := g.inner b v w
170+
conj_inner_symm v w := g.symm b w v
171+
re_inner_nonneg v := by
172+
rcases eq_or_ne v 0 with rfl | hv
173+
· simp
174+
· simpa using (g.pos b v hv).le
175+
add_left v w x := by simp
176+
smul_left c v := by simp
177+
definite v h := by contrapose! h; exact (g.pos b v h).ne'
178+
179+
variable (E) in
180+
/-- Class used to create an inner product structure space on the fibers of a fiber bundle, without
181+
creating diamonds. Use as follows:
182+
* `instance : RiemannianBundle E := ⟨g⟩` where `g : RiemannianMetric E` registers the inner product
183+
space on the fibers;
184+
* `instance : RiemannianBundle E := ⟨g.toRiemannianMetric⟩` where
185+
`g : ContinuousRiemannianMetric F E` registers the inner product space on the fibers, and the fact
186+
that it varies continuously (i.e., a `[IsContinuousRiemannianBundle]` instance).
187+
* `instance : RiemannianBundle E := ⟨g.toRiemannianMetric⟩` where
188+
`g : ContMDiffRiemannianMetric IB n F E` registers the inner product space on the fibers, and the
189+
fact that it varies smoothly (and continuously), i.e., `[IsContMDiffRiemannianBundle]` and
190+
`[IsContinuousRiemannianBundle]` instances.
191+
-/
192+
class RiemannianBundle where
193+
/-- The family of inner products on the fibers -/
194+
g : RiemannianMetric E
195+
196+
/- The normal priority for an instance which always applies like this one should be 100.
197+
We use 80 as this is rather specialized, so we want other paths to be tried first typically. -/
198+
noncomputable instance (priority := 80) [h : RiemannianBundle E] (b : B) :
199+
NormedAddCommGroup (E b) :=
200+
(h.g.toCore b).toNormedAddCommGroupOfTopology (h.g.continuousAt b) (h.g.isVonNBounded b)
201+
202+
/- The normal priority for an instance which always applies like this one should be 100.
203+
We use 80 as this is rather specialized, so we want other paths to be tried first typically. -/
204+
noncomputable instance (priority := 80) [h : RiemannianBundle E] (b : B) :
205+
InnerProductSpace ℝ (E b) :=
206+
.ofCoreOfTopology (h.g.toCore b) (h.g.continuousAt b) (h.g.isVonNBounded b)
207+
208+
variable (F E) in
209+
/-- A family of inner product space structures on the fibers of a fiber bundle, defining the same
210+
topology as the already existing one, and varying continuously with the base point. See also
211+
`ContMDiffRiemannianMetric` for a smooth version.
212+
213+
This structure is used through `RiemannianBundle` for typeclass inference, to register the inner
214+
product space structure on the fibers without creating diamonds. -/
215+
structure ContinuousRiemannianMetric where
216+
/-- The inner product along the fibers of the bundle. -/
217+
inner (b : B) : E b →L[ℝ] E b →L[ℝ] ℝ
218+
symm (b : B) (v w : E b) : inner b v w = inner b w v
219+
pos (b : B) (v : E b) (hv : v ≠ 0) : 0 < inner b v v
220+
isVonNBounded (b : B) : IsVonNBounded ℝ {v : E b | inner b v v < 1}
221+
continuous : Continuous (fun (b : B) ↦ TotalSpace.mk' (F →L[ℝ] F →L[ℝ] ℝ) b (inner b))
222+
223+
/-- A continuous Riemannian metric is in particular a Riemannian metric. -/
224+
def ContinuousRiemannianMetric.toRiemannianMetric (g : ContinuousRiemannianMetric F E) :
225+
RiemannianMetric E where
226+
inner := g.inner
227+
symm := g.symm
228+
pos := g.pos
229+
isVonNBounded := g.isVonNBounded
230+
continuousAt b := by
231+
-- Continuity of bilinear maps is only true on normed spaces. As `F` is a normed space by
232+
-- assumption, we transfer everything to `F` and argue there.
233+
let e : E b ≃L[ℝ] F := Trivialization.continuousLinearEquivAt ℝ (trivializationAt F E b) _
234+
(FiberBundle.mem_baseSet_trivializationAt' b)
235+
let m : (E b →L[ℝ] E b →L[ℝ] ℝ) ≃L[ℝ] (F →L[ℝ] F →L[ℝ] ℝ) :=
236+
e.arrowCongr (e.arrowCongr (ContinuousLinearEquiv.refl ℝ ℝ ))
237+
have A (v : E b) : g.inner b v v = ((fun w ↦ m (g.inner b) w w) ∘ e) v := by simp [m]
238+
simp only [A]
239+
fun_prop
240+
241+
/-- If a Riemannian bundle structure is defined using `g.toRiemannianMetric` where `g` is
242+
a `ContinuousRiemannianMetric`, then we make sure typeclass inference can infer automatically
243+
that the the bundle is a continuous Riemannian bundle. -/
244+
instance (g : ContinuousRiemannianMetric F E) :
245+
letI : RiemannianBundle E := ⟨g.toRiemannianMetric⟩;
246+
IsContinuousRiemannianBundle F E := by
247+
letI : RiemannianBundle E := ⟨g.toRiemannianMetric⟩
248+
exact ⟨⟨g.inner, g.continuous, fun b v w ↦ rfl⟩⟩
249+
250+
end Construction
251+
252+
end Bundle

0 commit comments

Comments
 (0)