diff --git a/Mathlib.lean b/Mathlib.lean index 2ed01bc313bb77..8f655d3724c8ed 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4463,6 +4463,7 @@ public import Mathlib.Geometry.Manifold.Notation public import Mathlib.Geometry.Manifold.PartitionOfUnity public import Mathlib.Geometry.Manifold.PoincareConjecture public import Mathlib.Geometry.Manifold.Riemannian.Basic +public import Mathlib.Geometry.Manifold.Riemannian.ExistsRiemannianMetric public import Mathlib.Geometry.Manifold.Riemannian.PathELength public import Mathlib.Geometry.Manifold.Sheaf.Basic public import Mathlib.Geometry.Manifold.Sheaf.LocallyRingedSpace @@ -4472,16 +4473,31 @@ public import Mathlib.Geometry.Manifold.SmoothEmbedding public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.ChristoffelSymbols +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Curvature +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Geodesics +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.IntegralCurvePrelim +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion2 +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial public import Mathlib.Geometry.Manifold.VectorBundle.FiberwiseLinear +public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho public import Mathlib.Geometry.Manifold.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame public import Mathlib.Geometry.Manifold.VectorBundle.Pullback public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection public import Mathlib.Geometry.Manifold.VectorBundle.Tangent public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorBundle.Unused public import Mathlib.Geometry.Manifold.VectorField.LieBracket public import Mathlib.Geometry.Manifold.VectorField.Pullback public import Mathlib.Geometry.Manifold.WhitneyEmbedding diff --git a/Mathlib/Geometry/Manifold/CheatSheet.md b/Mathlib/Geometry/Manifold/CheatSheet.md new file mode 100644 index 00000000000000..ede331a4011da6 --- /dev/null +++ b/Mathlib/Geometry/Manifold/CheatSheet.md @@ -0,0 +1,127 @@ +## Differential geometry cheat sheet + +How do I say certain basic things in Lean? +For each of them, include a variable block. Can verso do this already? + + +Let M be a C^k manifold. +``` +variable {๐•œ E M H : Type*} [NontriviallyNormedField ๐•œ] [NormedAddCommGroup E] + [NormedSpace ๐•œ E] [TopologicalSpace H] [TopologicalSpace M] {k : โ„•} -- more general: take k : WithTop โ„•โˆž, allows smooth and analytic; remove WithTop to exclude analyticity + {I : ModelWithCorners ๐•œ E H} [ChartedSpace H M] [IsManifold I k M] +``` + +Let M be a smooth manifold +``` +variable {๐•œ E M H : Type*} [NontriviallyNormedField ๐•œ] [NormedAddCommGroup E] + [NormedSpace ๐•œ E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners ๐•œ E H} [ChartedSpace H M] [IsManifold I โˆž M] +``` + +Let M be a smooth real manifold. +``` +variable {E M H : Type*} [NormedAddCommGroup E] + [NormedSpace โ„ E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners โ„ E H} [ChartedSpace H M] [IsManifold I โˆž M] -- test, needs open scoped Manifold?? +``` + +Let M be an analytic manifold +``` +open scoped Manifold -- test, necessary? + +variable {๐•œ E M H : Type*} [NontriviallyNormedField ๐•œ] [NormedAddCommGroup E] + [NormedSpace ๐•œ E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners ๐•œ E H} [ChartedSpace H M] [IsManifold I ฯ‰ M] +``` + +Differentiability of functions between manifolds +``` +import Mathlib.Geometry.Manifold.MFDeriv.Defs +import Mathlib.Geometry.Manifold.ContMDiff.Defs + +variable + -- Given a non-trivially normed field ๐•œ + {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + -- A manifold M over ๐•œ + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ๐•œ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + -- A manifold M' over ๐•œ + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners ๐•œ E' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + -- A function from M to M' and x in M + (f : M โ†’ M') (x : M) + +variable (x : M) in +-- f is differentiable at x +#check MDifferentiableAt I I' f x + +variable (n : WithTop โ„•โˆž) in -- A natural number or โˆž or ฯ‰ +#check ContMDiff I I' n f + + +variable + {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + (g : M โ†’ F) in +open scoped Manifold in +#check ContMDiff I ๐“˜(๐•œ, F) n g -- g is n times continuously differentiable +``` + +Consider the product manifold M \times N. + + +Let \phi be the preferred chart at x\in M. + +Let \phi be any (compatible) chart on M. + +-------- + +Let E\to M be a topological vector bundle. + +Let E\to M be a smooth vector bundle. + +Let s be a section of E. +``` +variable (s : ฮ  x : M, V x) +``` +Let X be a vector field on `M` +``` +(X : ฮ  x : M, TangentSpace I x) +``` + +Let s be a C^k section of E. / The section s of E is C^k. +``` +ContMDiff I (I.prod ๐“˜(๐•œ, F)) (k + 1) (fun x โ†ฆ TotalSpace.mk' F x (ฯƒ x)) +``` + +Let `X` be a C^k vector field on M. +``` +variable {X : ฮ  x : M, TangentSpace I x} +-- TODO: this doesn't work! +-- variable (___hX: ContMDiff I I.tangent 2 (fun x โ†ฆ (X x : TangentBundle I M))) +``` + +Let \phi be the preferred local trivialisation at x\in E. +Let \phi be any compatible trivialisation on M. + +Consider the tangent bundle TM of M. + +Let X be a C^k vector field on M. + +explain TotalSpace.mk' somewhere in here... + + + +**Basic API lemmas** +- testing smoothness of a map in charts: the standard charts; any charts + +- testing smoothness of a section in trivialisations: the standard charts; any charts + + +**constructions** +- product manifold (tricky!) +- disjoint union + +- product bundle (how difficult?) +- Lie bracket of vector fields diff --git a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean index aefaa0e157067d..0e2769b98e8589 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -83,7 +83,7 @@ theorem Differentiable.comp_mdifferentiable {g : F โ†’ F'} {f : M โ†’ F} end Module -section ExtChartAt +section extChartAt variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] {f : M โ†’ F} @@ -101,7 +101,7 @@ theorem DifferentiableWithinAt.mdifferentiableWithinAt_of_comp_extChartAt_symm [ refine (mdifferentiableWithinAt_iff_source_of_mem_source (mem_chart_source H x)).2 ?_ simpa [extChartAt_self_eq] using hf.mdifferentiableWithinAt -end ExtChartAt +end extChartAt /-! ### Linear maps between normed spaces are differentiable -/ @@ -398,20 +398,20 @@ end smul /-! ### Exterior derivative of a scalar function -/ /-- The exterior derivative of a scalar function on `M`, as a section of the cotangent bundle. -/ -noncomputable abbrev extDerivFun (g : M โ†’ ๐•œ) : - ฮ  x : M, TangentSpace I x โ†’L[๐•œ] ๐•œ := +noncomputable abbrev extDerivFun (g : M โ†’ F) : + ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F := fun x โ†ฆ (NormedSpace.fromTangentSpace <| g x).toContinuousLinearMap โˆ˜L (mfderiv% g x) @[simp] -lemma extDerivFun_add {g g' : M โ†’ ๐•œ} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) : +lemma extDerivFun_add {g g' : M โ†’ F} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) : extDerivFun (g + g') x = extDerivFun (I := I) g x + extDerivFun g' x := by simp [extDerivFun, mfderiv_add hg hg'] congr @[simp] -lemma extDerivFun_zero {x : M} : extDerivFun (I := I) (0 : M โ†’ ๐•œ) x = 0 := by - have : extDerivFun (0 : M โ†’ ๐•œ) x + extDerivFun (0 : M โ†’ ๐•œ) x = - extDerivFun (I := I) (0 : M โ†’ ๐•œ) x := by +lemma extDerivFun_zero {x : M} : extDerivFun (I := I) (0 : M โ†’ F) x = 0 := by + have : extDerivFun (0 : M โ†’ F) x + extDerivFun (0 : M โ†’ F) x = + extDerivFun (I := I) (0 : M โ†’ F) x := by rw [โ† extDerivFun_add (by exact mdifferentiable_const ..) (by exact mdifferentiable_const ..)] simp simpa using this diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 19a57d0c91d8d5..0f77ccf83303c0 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -790,6 +790,20 @@ theorem mfderiv_add (hf : MDiffAt f z) (hg : MDiffAt g z) : (by exact mfderiv% f z) + (by exact mfderiv% g z) := (hf.hasMFDerivAt.add hg.hasMFDerivAt).mfderiv +open NormedSpace in +theorem fromTangentSpace_mfderiv_add (hf : MDiffAt f z) (hg : MDiffAt g z) : + (fromTangentSpace _).toContinuousLinearMap โˆ˜L (mfderiv% (f + g) z) + = (fromTangentSpace _).toContinuousLinearMap โˆ˜L (mfderiv% f z) + + (fromTangentSpace _).toContinuousLinearMap โˆ˜L (mfderiv% g z) := + (hf.hasMFDerivAt.add hg.hasMFDerivAt).mfderiv + +open NormedSpace in +theorem fromTangentSpace_mfderiv_add_apply (hf : MDiffAt f z) (hg : MDiffAt g z) + (v : TangentSpace I x) : + fromTangentSpace _ (mfderiv% (f + g) z v) + = fromTangentSpace _ (mfderiv% f z v) + fromTangentSpace _ (mfderiv% g z v) := + congr($(fromTangentSpace_mfderiv_add hf hg) v) + section sum variable {ฮน : Type} {t : Finset ฮน} {f : ฮน โ†’ M โ†’ E'} {f' : ฮน โ†’ TangentSpace I z โ†’L[๐•œ] E'} diff --git a/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean new file mode 100644 index 00000000000000..5dac18d1b9c710 --- /dev/null +++ b/Mathlib/Geometry/Manifold/Riemannian/ExistsRiemannianMetric.lean @@ -0,0 +1,301 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michael Rothgang +-/ +module + +import Mathlib.Geometry.Manifold.PartitionOfUnity +import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame +import Mathlib.Geometry.Manifold.VectorBundle.Riemannian + +/-! ## Existence of a Riemannian bundle metric +Using a partition of unity, we prove that every finite-dimensional smooth vector bundle +admits a smooth Riemannian metric. + +## TODO +- this should work for C^n; prove the same for topological bundles and add it there +- also deduce that every manifold can be made Riemannian... +-/ + +open Bundle ContDiff Manifold + +-- Let E be a smooth vector bundle over a manifold E + +variable + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace โ„ EB] + {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners โ„ EB HB} {n : WithTop โ„•โˆž} + {B : Type*} [TopologicalSpace B] [ChartedSpace HB B] + {F : Type*} [NormedAddCommGroup F] [NormedSpace โ„ F] + {E : B โ†’ Type*} [TopologicalSpace (TotalSpace F E)] + [โˆ€ x, TopologicalSpace (E x)] [โˆ€ x, AddCommGroup (E x)] [โˆ€ x, Module โ„ (E x)] + [FiberBundle F E] [VectorBundle โ„ F E] + [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + +-- This file is really slow, for reasons to be investigated, and not crucially required for +-- studying Ehresman or the Levi-Civita connections. Thus, let us not compile it for now. +#exit + +section + +variable (E) in +/-- This is the bundle `Hom_โ„(E, T)`, where `T` is the rank one trivial bundle over `B`. -/ +private def V : (b : B) โ†’ Type _ := (fun b โ†ฆ E b โ†’L[โ„] Trivial B โ„ b) + +-- TODO: all of these instances are really slow, investigate and fix this! +noncomputable instance : (x : B) โ†’ TopologicalSpace (V E x) := by + unfold V + infer_instance + +noncomputable instance : (x : B) โ†’ AddCommGroup (V E x) := by + unfold V + infer_instance + +noncomputable instance (x : B) : Module โ„ (V E x) := by + unfold V + infer_instance + +noncomputable instance : TopologicalSpace (TotalSpace (F โ†’L[โ„] โ„) (V E)) := by + unfold V + infer_instance + +noncomputable instance : FiberBundle (F โ†’L[โ„] โ„) (V E) := by + unfold V + infer_instance + +noncomputable instance : VectorBundle โ„ (F โ†’L[โ„] โ„) (V E) := by + unfold V + infer_instance + +noncomputable instance : ContMDiffVectorBundle n (F โ†’L[โ„] โ„) (V E) IB := by + unfold V + infer_instance + +instance (x : B) : ContinuousAdd (V E x) := by + unfold V + infer_instance + +instance (x : B) : ContinuousSMul โ„ (V E x) := by + unfold V + infer_instance + +instance (x : B) : IsTopologicalAddGroup (V E x) := by + unfold V + infer_instance + +example : ContMDiffVectorBundle n (F โ†’L[โ„] F โ†’L[โ„] โ„) (fun b โ†ฆ E b โ†’L[โ„] V E b) IB := + ContMDiffVectorBundle.continuousLinearMap (IB := IB) (n := n) + (Fโ‚ := F) (Eโ‚ := E) (Fโ‚‚ := F โ†’L[โ„] โ„) (Eโ‚‚ := V E) + +variable (E) in +/-- The real vector bundle `Hom(E, Hom(E, T)) = Hom(E, V)`, whose fiber at `x` is +(equivalent to) the space of continuous real bilinear maps `E x โ†’ E x โ†’ โ„`. -/ +private def W : (b : B) โ†’ Type _ := fun b โ†ฆ E b โ†’L[โ„] V E b + +noncomputable instance (x : B) : AddCommGroup (W E x) := by + unfold W + infer_instance + +noncomputable instance (x : B) : Module โ„ (W E x) := by + unfold W + infer_instance + +noncomputable instance : TopologicalSpace (TotalSpace (F โ†’L[โ„] F โ†’L[โ„] โ„) (W E)) := by + unfold W + infer_instance + +noncomputable instance (x : B) : TopologicalSpace (W E x) := by + unfold W + infer_instance + +noncomputable instance : FiberBundle (F โ†’L[โ„] F โ†’L[โ„] โ„) (W E) := by + unfold W + infer_instance + +noncomputable instance : VectorBundle โ„ (F โ†’L[โ„] F โ†’L[โ„] โ„) (W E) := by + unfold W + infer_instance + +noncomputable instance : ContMDiffVectorBundle n (F โ†’L[โ„] F โ†’L[โ„] โ„) (W E) IB := by + unfold W + infer_instance + +end + +variable (E) in +/-- The first condition imposed on sections of `W`: they should give rise to a symmetric +pairing on each fibre `E x`. -/ +private def condition1 (x : B) : Set (E x โ†’L[โ„] E x โ†’L[โ„] โ„) := + {ฯ† | โˆ€ v w : E x, ฯ† v w = ฯ† w v} + +variable (E) in +/-- The second condition imposed on sections of `W`: they should give rise to a positive definite +pairing on each fibre `E x`. -/ +private def condition2 (x : B) : Set (E x โ†’L[โ„] E x โ†’L[โ„] โ„) := + {ฯ† | โˆ€ v : E x, v โ‰  0 โ†’ 0 < ฯ† v v} + +omit [TopologicalSpace B] in +lemma convex_condition1 (x : B) : Convex โ„ (condition1 E x) := by + intro ฯ† hฯ† ฯˆ hฯˆ s t hs ht hst v w + simp [hฯ† v w, hฯˆ v w] + +omit [TopologicalSpace B] in +lemma convex_condition2 (x : B) : Convex โ„ (condition2 E x) := by + unfold condition2 + intro ฯ† hฯ† ฯˆ hฯˆ s t hs ht hst v hv + rw [Set.mem_setOf] at hฯ† hฯˆ + have aux := Convex.min_le_combo ((ฯ† v) v) ((ฯˆ v) v) hs ht hst + have : 0 < min ((ฯ† v) v) ((ฯˆ v) v) := lt_min (hฯ† v hv) (hฯˆ v hv) + simpa using gt_of_ge_of_gt aux this + +variable (E) in +/-- Conditions imposed on sections of `W`: they should give rise to a positive definite symmetric +pairing on each fibre `E x`. -/ +def condition (x : B) : Set (W E x) := by + unfold W V Bundle.Trivial + exact condition1 E x โˆฉ condition2 E x + +omit [TopologicalSpace B] in +lemma convex_condition (x : B) : Convex โ„ (condition E x) := + Convex.inter (convex_condition1 x) (convex_condition2 x) + +variable [FiniteDimensional โ„ EB] [IsManifold IB โˆž B] [SigmaCompactSpace B] [T2Space B] + +-- TODO: construct a local section which is smooth in my coords, +-- and has all the definiteness properties I'll want later! +variable (E) in +def local_section_at (xโ‚€ : B) : (x : B) โ†’ W E x := sorry + +variable (E F) in +lemma contMDiff_localSection (xโ‚€ : B) : + letI t := trivializationAt F E xโ‚€ + ContMDiffOn IB (IB.prod ๐“˜(โ„, F โ†’L[โ„] F โ†’L[โ„] โ„)) โˆž + (fun x โ†ฆ TotalSpace.mk' (F โ†’L[โ„] F โ†’L[โ„] โ„) x (local_section_at E xโ‚€ x)) t.baseSet := + sorry + +-- MAYBE: also make a definition nhd, which is the nhd on which local_section_at stays pos. def. +lemma is_good_localSection (xโ‚€ : B) : + โˆ€ y โˆˆ (trivializationAt F E xโ‚€).baseSet, local_section_at E xโ‚€ y โˆˆ condition E y := by + intro y hy + unfold condition + simp only [id_eq] + erw [Set.mem_setOf] + refine โŸจ?_, ?_โŸฉ + ยท sorry -- symmetry + ยท sorry -- pos. definite + +lemma hloc_TODO (xโ‚€ : B) : + โˆƒ U_xโ‚€ โˆˆ nhds xโ‚€, โˆƒ s_loc : (x : B) โ†’ W E x, + ContMDiffOn IB (IB.prod ๐“˜(โ„, F โ†’L[โ„] F โ†’L[โ„] โ„)) โˆž + (fun x โ†ฆ TotalSpace.mk' (F โ†’L[โ„] F โ†’L[โ„] โ„) x (s_loc x)) U_xโ‚€ โˆง + โˆ€ y โˆˆ U_xโ‚€, s_loc y โˆˆ condition E y := by + letI t := trivializationAt F E xโ‚€ + have := t.open_baseSet.mem_nhds <| FiberBundle.mem_baseSet_trivializationAt' xโ‚€ + use t.baseSet, this, local_section_at E xโ‚€ + exact โŸจcontMDiff_localSection F E xโ‚€, is_good_localSection xโ‚€โŸฉ + +variable (E F IB) in +/-- Key step in the construction of a Riemannian metric on `E`: we construct a smooth section +of the bundle `W = Hom(E, Hom(E, T))` with the right properties (translating into symmetric +and positive definiteness of the resulting metric. -/ +noncomputable def foo_aux : Cโ‚›^โˆžโŸฎIB; F โ†’L[โ„] F โ†’L[โ„] โ„, W EโŸฏ := + Classical.choose <| + exists_contMDiffOn_section_forall_mem_convex_of_local IB (V := W E) (n := (โŠค : โ„•โˆž)) + (condition E) convex_condition hloc_TODO + +variable (E F IB) in +lemma foo_aux_prop (xโ‚€ : B) : foo_aux IB F E xโ‚€ โˆˆ condition E xโ‚€ := by + apply Classical.choose_spec <| + exists_contMDiffOn_section_forall_mem_convex_of_local IB (V := W E) (n := (โŠค : โ„•โˆž)) + (condition E) convex_condition hloc_TODO + +-- In what generality does this hold? +lemma aux_special (G : Type*) [NormedAddCommGroup G] [NormedSpace โ„ G] [FiniteDimensional โ„ G] + (ฯ† : G โ†’L[โ„] G โ†’L[โ„] โ„) (hpos : โˆ€ v : G, v โ‰  0 โ†’ 0 < ฯ† v v) : + Bornology.IsVonNBounded โ„ {v | (ฯ† v) v < 1} := by + -- Proof sketch: choose a basis {b_i} of G. + -- Each `ฯ† b_i b_i` is non-zero by hypothesis, hence has positive norm. + -- By finite-dimensionality of `G`, we have `0 < r := min โ€–ฯ† b_i b_iโ€–`, + -- thus B(r, 0) is contained in the image of the unit ball under v โ†ฆ ฯ† v v. + sorry + +section aux + +variable {G : Type*} [AddCommGroup G] [TopologicalSpace G] [Module โ„ G] + [ContinuousAdd G] [ContinuousSMul โ„ G] [FiniteDimensional โ„ G] + +-- XXX: this is also a norm, not just a seminorm! +noncomputable def mynorm (ฯ† : G โ†’L[โ„] G โ†’L[โ„] โ„) : Seminorm โ„ G where + toFun v := Real.sqrt (ฯ† v v) + map_zero' := by simp + add_le' r s := by sorry -- shouldn't be difficult + neg' r := by simp + smul' a v := by simp [โ† mul_assoc, โ† Real.sqrt_mul_self_eq_abs, Real.sqrt_mul (mul_self_nonneg a)] + +-- noncomputable def mynorm_space (ฯ† : G โ†’L[โ„] G โ†’L[โ„] โ„) : SeminormedAddCommGroup G where +-- norm := mynorm ฯ† +-- dist_self x := by simp +-- dist_comm x y := by +-- simp only [mynorm] +-- change Real.sqrt (ฯ† (x - y) (x - y)) = Real.sqrt (ฯ† (y - x) (y - x)) +-- sorry -- is just neg, so provable +-- dist_triangle := sorry -- follows from add_le' above (probably not difficult) + +-- attribute [local instance] mynorm_space +-- noncomputable def mynorm_space2 (ฯ† : G โ†’L[โ„] G โ†’L[โ„] โ„) : NormedSpace โ„ G where + +noncomputable def aux (ฯ† : G โ†’L[โ„] G โ†’L[โ„] โ„) : SeminormFamily โ„ G (Fin 1) := fun _ โ†ฆ mynorm ฯ† + +lemma hoge (ฯ† : G โ†’L[โ„] G โ†’L[โ„] โ„) (hpos : โˆ€ v : G, v โ‰  0 โ†’ 0 < ฯ† v v) : WithSeminorms (aux ฯ†) := + -- In finite dimension there is a single topological vector space structure... + -- and mynorm defines a norm, hence a TVS structure. + sorry + +end aux + +-- golfing suggestions welcome +lemma qux {ฮฑ : Type*} [Unique ฮฑ] (s : Finset ฮฑ) : s = โˆ… โˆจ s = {default} := by + by_cases h : s = โˆ… + ยท simp [h] + ยท rw [Finset.eq_singleton_iff_nonempty_unique_mem] + refine Or.inr โŸจFinset.nonempty_iff_ne_empty.mpr h, fun x hx โ†ฆ Unique.uniq _ _โŸฉ + +lemma aux_tvs (G : Type*) [AddCommGroup G] [TopologicalSpace G] [Module โ„ G] + [ContinuousAdd G] [ContinuousSMul โ„ G] [FiniteDimensional โ„ G] + (ฯ† : G โ†’L[โ„] G โ†’L[โ„] โ„) (hpos : โˆ€ v : G, v โ‰  0 โ†’ 0 < ฯ† v v) : + Bornology.IsVonNBounded โ„ {v | (ฯ† v) v < 1} := by + -- Proof sketch (courtesy of Sรฉbastien Gouezel): + -- Phi gives you a norm, which defines the same topology as the initial one + -- (as in finite dimension there is a single topological vector space structure). + -- The unit ball for the norm is von Neumann bounded wrt the topology defined by the norm + -- (we have this in mathlib), so also for the initial topology. + rw [WithSeminorms.isVonNBounded_iff_finset_seminorm_bounded (p := aux ฯ†) (hoge ฯ† hpos)] + intro I + letI J : Finset (Fin 1) := {1} + suffices โˆƒ r > 0, โˆ€ x โˆˆ {v | (ฯ† v) v < 1}, (J.sup (aux ฯ†)) x < r by + obtain (rfl | h) := qux I + ยท use 1; simp + ยท convert this + simp only [Set.mem_setOf_eq, Finset.sup_singleton, J] + refine โŸจ1, by norm_num, fun x h โ†ฆ ?_โŸฉ + simp only [aux, mynorm] + change Real.sqrt (ฯ† x x) < 1 + rw [Real.sqrt_lt' (by norm_num)] + simp [h] + +-- TODO: is the finite-dimensionality actually required? +-- Are the TVS hypotheses actually a restriction? +noncomputable def foo + [โˆ€ x, FiniteDimensional โ„ (E x)] [โˆ€ x, ContinuousAdd (E x)] [โˆ€ x, ContinuousSMul โ„ (E x)] : + ContMDiffRiemannianMetric IB โˆž F E where + inner := foo_aux IB F E + symm b := (foo_aux_prop IB F E b).1 + pos b := (foo_aux_prop IB F E b).2 + isVonNBounded b := aux_tvs (E b) (foo_aux IB F E b) (foo_aux_prop IB F E b).2 + contMDiff := (foo_aux IB F E).contMDiff + +-- /-- Every `C^n` vector bundle whose fibre admits a `C^n` partition of unity +-- is a `C^n` Riemannian vector bundle. (The Lean statement assumes an inner product on each fibre +-- already, which is why there are no other assumptions yet??) -/ +-- lemma ContDiffVectorBundle.isContMDiffRiemannianBundle : IsContMDiffRiemannianBundle IB n F E := +-- โŸจRMetric IB E, rMetric_contMDiff, fun x v w โ†ฆ rMetric_eq x v wโŸฉ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean index 4b5bb3c3a8d11b..cb07d559d2b07b 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -63,13 +63,9 @@ fields, etc. assert_not_exists mfderiv -open Bundle Set OpenPartialHomeomorph - +open Bundle Filter Set OpenPartialHomeomorph open Function (id_def) - -open Filter - -open scoped Manifold Bundle Topology ContDiff +open scoped Manifold Topology ContDiff variable {n : WithTop โ„•โˆž} {๐•œ B B' F M : Type*} {E : B โ†’ Type*} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index f91202ea2fd00f..78ddcd4334d0d0 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -142,13 +142,10 @@ lemma iUnion {ฮน : Type*} {cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x end changing_set --- TODO: prove that `cov ฯƒ x` depends on `ฯƒ` only via the 1-jet of `ฯƒ` at `x`. --- This will be easy using the projection formula about Ehresmann connections, --- which will be added in the planned file `CovariantDerivative/Ehresmann.lean`. --- In the mean-time we use the following weaker results (which are convenient to apply anyway). - /-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `ฯƒ` and -`ฯƒ'` agree on `s` and are differentiable at `x`, then `cov ฯƒ x = cov ฯƒ x'`. -/ +`ฯƒ'` agree on `s` and are differentiable at `x`, then `cov ฯƒ x = cov ฯƒ x'`. + +This is a convenient special case of `congr_of_eq_one_jet`. -/ lemma congr_of_eqOn {cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -183,7 +180,9 @@ lemma congr_of_eqOn open Filter Set in /-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `ฯƒ` and -`ฯƒ'` agree near `x` and are differentiable at `x`, then `cov ฯƒ x = cov ฯƒ x'`. -/ +`ฯƒ'` agree near `x` and are differentiable at `x`, then `cov ฯƒ x = cov ฯƒ x'`. + +This is a convenient special case of `congr_of_eq_one_jet`. -/ lemma congr_of_eventuallyEq {cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)} {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) @@ -195,6 +194,18 @@ lemma congr_of_eventuallyEq choose s' hs' b using hฯƒฯƒ' exact (hcov.mono inter_subset_left).congr_of_eqOn hฯƒ hฯƒ' (inter_mem hxs hs') fun x hx โ†ฆ b x hx.2 +/-- Given a covariant derivative `cov` on a neighborhood `s` of a point `x`, if sections `ฯƒ` and +`ฯƒ'` are differentiable at `x` with the same one-jet (i.e., agree at `x` and have the same +`mfderiv`), then `cov ฯƒ x = cov ฯƒ x'`. -/ +lemma congr_of_eq_one_jet + {cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) {x : M} (hxs : s โˆˆ ๐“ x) + {ฯƒ ฯƒ' : ฮ  x : M, V x} (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯƒ' : MDiffAt (T% ฯƒ') x) + (hฯƒฯƒ' : ฯƒ x = ฯƒ' x) (hฯƒฯƒ' : mfderiv% (T% ฯƒ) x = mfderiv% (T% ฯƒ') x) : + cov ฯƒ x = cov ฯƒ' x := by + -- This should be easy using the projection formula in `CovariantDerivative.Ehresmann`. + sorry + /-! ### Computational properties -/ section computational_properties @@ -207,6 +218,20 @@ lemma zero [VectorBundle ๐•œ F V] (hcov : IsCovariantDerivativeOn F cov s) simpa using (hcov.add (mdifferentiableAt_zeroSection ..) (mdifferentiableAt_zeroSection ..) : cov (0 + 0) x = _) +lemma neg [VectorBundle ๐•œ F V] (hcov : IsCovariantDerivativeOn F cov s) + {ฯƒ : ฮ  x : M, V x} {x} + (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ s := by trivial) : + cov (-ฯƒ) x = - cov ฯƒ x := by + rw [eq_neg_iff_add_eq_zero, โ† hcov.add (mdifferentiableAt_neg_section hฯƒ) hฯƒ] + simp (disch := assumption) [hcov.zero] + +lemma sub [VectorBundle ๐•œ F V] (hcov : IsCovariantDerivativeOn F cov s) + {ฯƒ ฯƒ' : ฮ  x : M, V x} {x} + (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯƒ' : MDiffAt (T% ฯƒ') x) (hx : x โˆˆ s := by trivial) : + cov (ฯƒ - ฯƒ') x = cov ฯƒ x - cov ฯƒ' x := by + rw [sub_eq_neg_add, hcov.add (mdifferentiableAt_neg_section hฯƒ') hฯƒ, hcov.neg hฯƒ'] + abel + theorem smul_const (hcov : IsCovariantDerivativeOn F cov s) {ฯƒ : ฮ  x : M, V x} {x} (a : ๐•œ) (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ s := by trivial) : @@ -386,6 +411,22 @@ lemma zero [VectorBundle ๐•œ F V] (cov : CovariantDerivative I F V) : cov 0 = 0 ext1 x simp [cov.isCovariantDerivativeOnUniv.zero] +-- XXX: do we prefer this statement, or point-wise versions instead? +-- if both, which one should be simp? +@[simp] +lemma neg [VectorBundle ๐•œ F V] (cov : CovariantDerivative I F V) + {ฯƒ : ฮ  x : M, V x} (hฯƒ : MDiff (T% ฯƒ)) : + cov (-ฯƒ) = - cov ฯƒ := by + ext1 x + exact cov.isCovariantDerivativeOnUniv.neg (hฯƒ x) + +@[simp] +lemma sub [VectorBundle ๐•œ F V] (cov : CovariantDerivative I F V) + {ฯƒ ฯƒ' : ฮ  x : M, V x} (hฯƒ : MDiff (T% ฯƒ)) (hฯƒ' : MDiff (T% ฯƒ')) : + cov (ฯƒ - ฯƒ') = cov ฯƒ - cov ฯƒ' := by + ext1 x + exact cov.isCovariantDerivativeOnUniv.sub (hฯƒ x) (hฯƒ' x) + /-- If `cov` is a covariant derivative on each set in an open cover, it is a covariant derivative. -/ def of_isCovariantDerivativeOn_of_open_cover {ฮน : Type*} {s : ฮน โ†’ Set M} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/ChristoffelSymbols.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/ChristoffelSymbols.lean new file mode 100644 index 00000000000000..ac3171e202f810 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/ChristoffelSymbols.lean @@ -0,0 +1,319 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michael Rothgang +-/ +module + +public import Mathlib.Analysis.InnerProductSpace.Dual +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame + +/-! # Christoffel symbols for a covariant derivative + +Old code for defining the Christoffel symbols of a connection: +it's not clear how much this will be used, +and it would need to be thoroughly updated to compile, given the other modifications made + +-/ +set_option backward.isDefEq.respectTransparency false + +namespace CovariantDerivative + +open Bundle Filter Function Module NormedSpace Topology +open scoped ContDiff Manifold + +variable {n : WithTop โ„•โˆž} + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners โ„ E H) + {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] + [RiemannianBundle (fun (x : M) โ†ฆ TangentSpace I x)] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace โ„ E'] + {X X' X'' Y Y' Y'' Z Z' : ฮ  x : M, TangentSpace I x} + (cov : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)) + [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] {x : M} + +-- TODO: move this section to `Torsion.lean` +section + +--omit [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] +--omit [RiemannianBundle (fun (x : M) โ†ฆ TangentSpace I x)] + +/-- The **Christoffel symbol** of a covariant derivative on a set `U โІ M` +with respect to a local frame `(s_i)` on `U`: for each triple `(i, j, k)` of indices, +this is a function `ฮ“แตขโฑผแต : M โ†’ โ„`, whose value outside of `U` is meaningless. -/ +noncomputable def ChristoffelSymbol + (f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)) + {U : Set M} {ฮน : Type*} {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ฮน) : M โ†’ โ„ := + (LinearMap.piApply (hs.coeff k)) (fun x โ†ฆ f (s i) x (s j x)) + +-- special case of `foobar` below; needed? +lemma ChristoffelSymbol.sum_eq + (f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)) + {U : Set M} {ฮน : Type*} [Fintype ฮน] {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j : ฮน) (hx : x โˆˆ U) : + f (s i) x (s j x) = โˆ‘ k, (ChristoffelSymbol I f hs i j k x) โ€ข (s k) x := by + simp only [ChristoffelSymbol, LinearMap.piApply_apply] + apply hs.coeff_sum_eq _ hx + +variable {U : Set M} + {f g : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)} + {ฮน : Type*} {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} + +-- Note that this result is false if `{s i}` is merely a local frame. +lemma eq_product_apply [Fintype ฮน] + (hf : IsCovariantDerivativeOn E f U) + (hs : IsOrthonormalFrameOn I E n s U) + (i j k : ฮน) (hx : x โˆˆ U) : + ChristoffelSymbol I f hs.toIsLocalFrameOn i j k x = inner โ„ (f (s i) x (s j x)) (s k x) := by + -- Choose a linear order on ฮน: which one really does not matter for our result. + have : LinearOrder ฮน := by + choose r wo using exists_wellOrder _ + exact r + have : LocallyFiniteOrderBot ฮน := by sorry + sorry + -- was: rw [ChristoffelSymbol, hs.coeff_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] + +#exit +-- TODO: the next lines have a number of errors, and would need to be updated + +-- Lemma 4.3 in Lee, Chapter 5: first term still missing +lemma foobar [Fintype ฮน] [FiniteDimensional โ„ E] (hf : IsCovariantDerivativeOn E f U) + (hs : IsLocalFrameOn I E 1 s U) {x : M} (hx : x โˆˆ U) : + f X x (Y x) = โˆ‘ k, + letI Sโ‚ := โˆ‘ i, โˆ‘ j, + ((LinearMap.piApply (hs.coeff i)) X) * (LinearMap.piApply (hs.coeff j) Y) + * (ChristoffelSymbol I f hs i j k) + letI Sโ‚‚ : M โ†’ โ„ := sorry -- first summand in Leibniz' rule! + Sโ‚ x โ€ข s k x := by + have hY := hs.coeff_sum_eq Y hx + -- should this be a separate lemma also? + have : โˆ€ x โˆˆ U, Y x = โˆ‘ i, hs.coeff i x (Y x) โ€ข s i x := by + intro x hx + apply hs.coeff_sum_eq Y hx + have : f X x (Y x) = f X (fun x โ†ฆ โˆ‘ i, (hs.coeff i) Y x โ€ข s i x) x := by + -- apply `congr_ฯƒ_of_eventuallyEq` from Basic.lean (after restoring it) + -- want U to be a neighbourhood of x to make this work + sorry + rw [this] + -- straightforward computation: use linearity and Leibniz rule + sorry + +/- TODO: prove some basic properties, such as +- the Christoffel symbols are linear in cov +- if (s_i) is a smooth local frame on U, then cov is smooth on U iff each Christoffel symbol is (?) +- prove a `spec` equality +- deduce: two covariant derivatives are equal iff their Christoffel symbols are equal +-/ + +lemma _root_.IsCovariantDerivativeOn.congr_of_christoffelSymbol_eq [Fintype ฮน] + [FiniteDimensional โ„ E] -- TODO: this is implied by Finite ฮน, right? + (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) + (hs : IsLocalFrameOn I E n s U) + (hfg : โˆ€ i j k, โˆ€ x โˆˆ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x) : + โˆ€ X Y : ฮ  x : M, TangentSpace I x, โˆ€ x โˆˆ U, f X x (Y x) = g X x (Y x) := by + have (i j : ฮน) : โˆ€ x โˆˆ U, f (s i) (s j) x = g (s i) (s j) x := by + intro x hx + rw [hs.eq_iff_coeff hx] + exact fun k โ†ฆ hfg i j k x hx + intro X Y x hx + -- use linearity (=formula for f in terms of Christoffel symbols) now, another separate lemma! + sorry + +/-- Two covariant derivatives on `U` are equal on `U` if and only if all of their +covariant derivatives w.r.t. some local frame on `U` are equal on `U`. -/ +lemma _root_.IsCovariantDerivativeOn.congr_iff_christoffelSymbol_eq [Fintype ฮน] + [FiniteDimensional โ„ E] -- TODO: this is implied by Finite ฮน, right? + (hf : IsCovariantDerivativeOn E f U) (hg : IsCovariantDerivativeOn E g U) + (hs : IsLocalFrameOn I E n s U) : + (โˆ€ X Y : ฮ  x : M, TangentSpace I x, โˆ€ x โˆˆ U, f X x (Y x) = g X x (Y x)) โ†” + โˆ€ i j k, โˆ€ x โˆˆ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I g hs i j k x := + โŸจfun hfg _i _j _k _x hx โ†ฆ hs.coeff_congr (hfg _ _ _ hx ) .., + fun h X Y x hx โ†ฆ hf.congr_of_christoffelSymbol_eq I hg hs h X Y x hxโŸฉ + +-- TODO: global version for convenience, with an alias for the interesting direction! + +variable (hs : IsLocalFrameOn I E n s U) + +lemma christoffelSymbol_zero (U : Set M) {ฮน : Type*} {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ฮน) : ChristoffelSymbol I 0 hs i j k = 0 := by + simp [ChristoffelSymbol] + +@[simp] +lemma christoffelSymbol_zero_apply (U : Set M) {ฮน : Type*} {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} + (hs : IsLocalFrameOn I E n s U) (i j k : ฮน) (x) : ChristoffelSymbol I 0 hs i j k x = 0 := by + simp [christoffelSymbol_zero] + +end + +-- Lemma 4.3 in Lee, Chapter 5: first term still missing +variable {U : Set M} {ฮน : Type*} [Fintype ฮน] {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)} + +-- XXX: generalise this to any field +variable {I} in +/-- `โˆ‡` is torsion-free on `U` if its torsion vanishes at each `x โˆˆ U` -/ +noncomputable def IsTorsionFreeOn + (cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)) + (U : Set M) : Prop := + โˆ€ x โˆˆ U, โˆ€ X Y : ฮ  x : M, TangentSpace I x, IsCovariantDerivativeOn.torsionAux cov X Y x = 0 +namespace IsTorsionFreeOn +section changing_set +/-! Changing set +In this changing we change `s` in `IsTorsionFreeOn F f s`. +-/ +lemma mono {s t : Set M} (hf : IsTorsionFreeOn f t) (hst : s โІ t) : + IsTorsionFreeOn f s := + fun _ hx _ _ โ†ฆ hf _ (hst hx) .. + +lemma iUnion {ฮน : Type*} {s : ฮน โ†’ Set M} (hf : โˆ€ i, IsTorsionFreeOn f (s i)) : + IsTorsionFreeOn cov (โ‹ƒ i, s i) := by + rintro x โŸจsi, โŸจi, hiโŸฉ, hxsiโŸฉ X Y + sorry -- was: exact hf i x (by simp [hi, hxsi]) X Y +end changing_set +end IsTorsionFreeOn + +-- errors: omit [IsContMDiffRiemannianBundle I 1 E fun x โ†ฆ TangentSpace I x] in +/-- Let `{s i}` be a local frame on `U` such that `[s i, s j] = 0` on `U` for all `i, j`. +A covariant derivative on `U` is torsion-free on `U` iff for each `x โˆˆ U`, +the Christoffel symbols `ฮ“แตขโฑผแต` w.r.t. `{s i}` are symmetric. -/ +lemma isTorsionFreeOn_iff_christoffelSymbols [CompleteSpace E] {ฮน : Type*} [Fintype ฮน] + [FiniteDimensional โ„ E] -- TODO: this is implied by Finite ฮน, right? + (hf : IsCovariantDerivativeOn E f U) + {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} (hs : IsLocalFrameOn I E n s U) + (hs'' : โˆ€ i j, โˆ€ x : U, VectorField.mlieBracket I (s i) (s j) x = 0) : + IsTorsionFreeOn f U โ†” + โˆ€ i j k, โˆ€ x โˆˆ U, ChristoffelSymbol I f hs i j k x = ChristoffelSymbol I f hs j i k x := by + rw [hf.isTorsionFreeOn_iff_localFrame (n := n) hs] + have (i j : ฮน) {x} (hx : x โˆˆ U) : + torsion f (s i) (s j) x = f (s i) x (s j x) - f (s j) x (s i x) := by + simp [torsion, hs'' i j โŸจx, hxโŸฉ] + peel with i j + refine โŸจ?_, ?_โŸฉ + ยท intro h k x hx + simp only [ChristoffelSymbol] + apply hs.coeff_congr + specialize h x hx + rw [this i j hx, sub_eq_zero] at h + exact h + ยท intro h x hx + rw [this i j hx, sub_eq_zero, hs.eq_iff_coeff hx] + exact fun k โ†ฆ h k x hx + +-- Exercise 4.2(b) in Lee, Chapter 4 +/-- A covariant derivative on `U` is torsion-free on `U` iff for each `x โˆˆ U` and +any local coordinate frame, the Christoffel symbols `ฮ“แตขโฑผแต` are symmetric. + +TODO: figure out the right quantifiers here! +right now, I just have one fixed coordinate frame... will this do?? +-/ +lemma isTorsionFree_iff_christoffelSymbols' [FiniteDimensional โ„ E] [IsManifold I โˆž M] + (hf : IsCovariantDerivativeOn E f U) : + IsTorsionFreeOn f U โ†” + โˆ€ x โˆˆ U, + -- Let `{s_i}` be the coordinate frame at `x`: this statement is false for arbitrary frames. + -- TODO: does the following do what I want?? + letI cs := ChristoffelSymbol I f + (trivializationAt E _ x).isLocalFrameOn_localFrame_baseSet I 1 ((Basis.ofVectorSpace โ„ E)) + โˆ€ i j k, cs i j k x = cs j i k x := by + letI t := (trivializationAt E (fun (x : M) โ†ฆ TangentSpace I x)) + have hs (x) := + ((Basis.ofVectorSpace โ„ E).localFrame_isLocalFrameOn_baseSet I 1 (t x)) + + -- TODO: check that the Lie bracket of any two coordinate vector fields is zero! + rw [isTorsionFreeOn_iff_christoffelSymbols (ฮน := (โ†‘(Basis.ofVectorSpaceIndex โ„ E))) I hf] + -- issues with quantifier order in the statement... prove both directions separately, at each x? + repeat sorry + +theorem LeviCivitaConnection.christoffelSymbol_symm [FiniteDimensional โ„ E] (x : M) : + letI t := trivializationAt E (TangentSpace I) x; + letI hs := t.isLocalFrameOn_localFrame_baseSet I 1 (Basis.ofVectorSpace โ„ E) + โˆ€ x', x' โˆˆ t.baseSet โ†’ โˆ€ (i j k : โ†‘(Basis.ofVectorSpaceIndex โ„ E)), + ChristoffelSymbol I (LeviCivitaConnection I M) hs i j k x' = + ChristoffelSymbol I (LeviCivitaConnection I M) hs j i k x' := by + by_cases hE : Subsingleton E + ยท have (y : M) (X : TangentSpace I y) : X = 0 := by + have : Subsingleton (TangentSpace I y) := inferInstanceAs (Subsingleton E) + apply Subsingleton.eq_zero X + have (X : ฮ  y : M, TangentSpace I y) : X = 0 := sorry + intro x'' hx'' i j k + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] + unfold lcCandidate + simp only [lcAux, hE, โ†“reduceDIte] + + letI t := trivializationAt E (TangentSpace I) x; + letI hs := (Basis.ofVectorSpace โ„ E).localFrame_isLocalFrameOn_baseSet I 1 t + have : ChristoffelSymbol I 0 hs i j k = 0 := christoffelSymbol_zero I t.baseSet hs i j k + -- now, use a congruence result and the first `have` + sorry + -- Note that hs is not necessarily an orthonormal frame, so we cannot simply rewrite + -- the Christoffel symbols as ฮ“แตขโฑผแต = โŸชโˆ‡แต X Y, ZโŸซ`: however, the result we wants to prove boils + -- down to proving the same. + intro x' hx' i j + set t := trivializationAt E (TangentSpace I) x + set b := (Basis.ofVectorSpace โ„ E) + set s := t.localFrame b + set ฮน := โ†‘(Basis.ofVectorSpaceIndex โ„ E) + -- Same computation as above; extract as lemma! + let O : (x : M) โ†’ TangentSpace I x := fun x โ†ฆ 0 + have need : โˆ€ i j, VectorField.mlieBracket I (s i) (s j) x' = O x' := sorry + have aux : โˆ€ k, โŸชLeviCivitaConnection I M (s i) (s j), (s k)โŸซ x' + = โŸชLeviCivitaConnection I M (s j) (s i), (s k)โŸซ x' := by + intro k + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] + unfold lcCandidate + rw [product_apply, product_apply] + simp only [lcAux, hE, โ†“reduceDIte] + -- Choose a linear order on ฮน: which one really does not matter for our result. + have : LinearOrder ฮน := by + choose r wo using exists_wellOrder _ + exact r + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + have : Nonempty ฮน := b.index_nonempty + -- The linear ordering on the indexing set of `b` is only used in this proof, + -- so our choice does not matter. + have : LinearOrder ฮน := by + choose r wo using exists_wellOrder _ + exact r + have : Fintype ฮน := sorry + -- why does this fail? are there two different orders in play? + have : LocallyFiniteOrderBot ฮน := sorry + have : โˆ‘ k', inner โ„ + (leviCivitaRhs I (s i) (s j) + (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' โ€ข + b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') + (s k x') = + โˆ‘ k', inner โ„ + (leviCivitaRhs I (s j) (s i) + (b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k') x' โ€ข + b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x') + (s k x') := by + congr with k' + simp only [leviCivitaRhs] + set sij := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' x' + rw [inner_smul_left, inner_smul_left] + congr + simp [leviCivitaRhs'] + set S := b.orthonormalFrame (trivializationAt E (TangentSpace I) x') k' + have need' : โˆ€ i, VectorField.mlieBracket I (s i) S x' = O x' := by + -- expand the definition of Gram-Schmidt and use need and linearity + sorry + have need'' : โˆ€ i, VectorField.mlieBracket I S (s i) x' = O x' := by + sorry -- swap and use need', or so + rw [product_congr_right I (need i j), product_congr_right I (need j i), + product_congr_right I (need' i), product_congr_right I (need'' i), + product_congr_right I (need' j), product_congr_right I (need'' j), + rhs_aux_swap I (s i) (s j), rhs_aux_swap I (s j) S, rhs_aux_swap I S (s i)] + simp [O] + abel + -- now, just rewrite `inner` to take out a sum: same lemma twice + convert this + ยท sorry + ยท sorry + + -- deduce the goal from `aux` + sorry + +end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean new file mode 100644 index 00000000000000..ed040d3b593566 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean @@ -0,0 +1,279 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.LinearAlgebra.Trace + +/-! # Curvature of an affine connection + +We define the curvature tensor of an affine connection, i.e. a covariant derivative on the tangent +bundle `TM` of some manifold `M`. + +## Main definitions and results + +TODO! + +-/ + +@[expose] public section + +open Bundle Set NormedSpace +open scoped Manifold ContDiff + +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +/-! A preliminary lemma about -/ +section prelim + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace ๐•œ F] + {V : M โ†’ Type*} [TopologicalSpace (TotalSpace F V)] + [โˆ€ x, AddCommGroup (V x)] [โˆ€ x, Module ๐•œ (V x)] + [โˆ€ x : M, TopologicalSpace (V x)] + [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul ๐•œ (V x)] + [FiberBundle F V] + +-- FIXME: does this require real bundles? +lemma exists_contMDiff_of_one_form {k : WithTop โ„•โˆž} + {ฯƒ : ฮ  x : M, V x} (hฯƒ : CMDiffAt k (T% ฯƒ) x) : + โˆƒ ฯƒ' : (ฮ  x : M, V x), + CMDiff k (T% ฯƒ') โˆง ฯƒ' x = ฯƒ x โˆง mfderiv% (T% ฯƒ') x = mfderiv% (T% ฯƒ) x := by + /- proof idea: assuming smooth bump functions, this becomes a local question + locally, convolve ฯƒ with a bump function of small support; should preserve ฯƒ x and mfderiv + does mathlib have this already? (Moritz Doll proved something similar, I think!) + -/ + sorry + +-- We need one level more of agreement! + +-- TODO: might be a better definition of smoothness; proving the equivalence requires more work! +variable {F} in +lemma ContMDiffCovariantDerivativeOn.contMDiff' [IsManifold I 1 M] [VectorBundle ๐•œ F V] + {k : WithTop โ„•โˆž} {cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)} + (hcov : IsCovariantDerivativeOn F cov) [hcov' : ContMDiffCovariantDerivativeOn F k cov univ] + {ฯƒ : ฮ  x : M, V x} (hฯƒ :CMDiffAt (k + 1) (T% ฯƒ) x) : + letI cov (x : M) : TotalSpace (E โ†’L[๐•œ] F) fun x โ†ฆ TangentSpace I x โ†’L[๐•œ] V x := โŸจx, cov ฯƒ xโŸฉ + ContMDiffAt I (I.prod ๐“˜(๐•œ, E โ†’L[๐•œ] F)) k cov x := by + obtain โŸจฯƒ', hฯƒ', heqs, hdiffxโŸฉ := exists_contMDiff_of_one_form F hฯƒ + have aux := contMDiffOn_univ.mp (hcov'.contMDiff hฯƒ'.contMDiffOn) + -- know: โˆ‡ ฯƒ and โˆ‡ ฯƒ' agree at x + have aux' := hcov.congr_of_eq_one_jet (Filter.univ_mem) + (hฯƒ.mdifferentiableAt (by simp)) (hฯƒ'.mdifferentiableAt (by simp)) + heqs.symm hdiffx.symm -- TODO: choose direction for both equalities! + -- we need one more level, though! + sorry + +end prelim + +/-! ## The Riemannian curvature tensor of an unbundled covariant derivative on `TM` on a set `s` + +TODO: generalise this discussion to any vector bundle E +-/ +namespace IsCovariantDerivativeOn + +variable (cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] TangentSpace I x)) + +variable {X X' Y : (ฮ  x : M, TangentSpace I x)} + +/-- Local notation for a covariant derivative on a vector bundle acting on a vector field and a +section. -/ +local syntax "โˆ‡" term:arg term : term +local macro_rules | `(โˆ‡ $X $ฯƒ) => `(fun (x : M) โ†ฆ cov $ฯƒ x ($X x)) + +example {x} : (โˆ‡ X Y) x = cov Y x (X x) := by rfl + +/-- The Riemannian curvature endomorphism of a covariant derivative on the tangent bundle `TM`, +as a bare function. Prefer to use `IsCovariantDerivativeOn.curvatureTensor` +(which is a (3,1)-tensor) instead. -/ +noncomputable def curvatureTensorAux : + (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ + (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) := + fun X Y Z โ†ฆ (โˆ‡ X (โˆ‡ Y Z)) - โˆ‡ Y (โˆ‡ X Z) - โˆ‡ (VectorField.mlieBracket I X Y) Z + +variable [IsManifold I 2 M] [CompleteSpace E] + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] TangentSpace I x)} + {X X' Y Z : ฮ  x : M, TangentSpace I x} + +-- TODO: generalise further and try to find in the library! +lemma temp + {cov : ((x : M) โ†’ TangentSpace I x) โ†’ (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] TangentSpace I x} + (hcov : IsCovariantDerivativeOn E cov) + {x : M} {X ฯƒ : (x : M) โ†’ TangentSpace I x} + (hฯƒ : CMDiff 2 T% ฯƒ) (hZ : CMDiff 2 T% X) + (aux : ContMDiffAt I (I.prod ๐“˜(๐•œ, E โ†’L[๐•œ] E)) 1 + (fun x โ†ฆ TotalSpace.mk' (E โ†’L[๐•œ] E) x (cov X x)) x) : + ContMDiffAt I (I.prod ๐“˜(๐•œ, E)) 1 (fun x โ†ฆ TotalSpace.mk' E x ((cov X x) (ฯƒ x))) x := by + sorry + +lemma temp' -- I suspect this one will also work! + {cov : ((x : M) โ†’ TangentSpace I x) โ†’ (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] TangentSpace I x} + (hcov : IsCovariantDerivativeOn E cov) + {x : M} {X ฯƒ : (x : M) โ†’ TangentSpace I x} + -- XXX: I suspect ฯƒ being Cยน will suffice, and no extra hypotheses on X are necessary + (hฯƒ : CMDiffAt 1 (T% ฯƒ) x) + (aux : ContMDiffAt I (I.prod ๐“˜(๐•œ, E โ†’L[๐•œ] E)) 1 + (fun x โ†ฆ TotalSpace.mk' (E โ†’L[๐•œ] E) x (cov X x)) x) : + ContMDiffAt I (I.prod ๐“˜(๐•œ, E)) 1 (fun x โ†ฆ TotalSpace.mk' E x ((cov X x) (ฯƒ x))) x := by + sorry + +/- Lessons learned from the experiment below: +- we need the lemma temp (or perhaps just temp'); is this in mathlib already? +- the curvature tensor needs a Cยน connection, and a manifold of order 3 and minSmoothness k 2 or so +- we can only prove tensoriality for Cยฒ sections (at a point, I hope! to be confirmed), + so need new tensoriality lemmas +- `mdifferentiableAt` lemmas for C^k covariant derivatives would be nice API addition +-/ + +variable [IsManifold I (2 + 1) M] [IsManifold I (minSmoothness ๐•œ 2) M] + +lemma aux + (hcov : IsCovariantDerivativeOn E cov) [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + {x : M} {Y Z ฯƒ : (x : M) โ†’ TangentSpace I x} + (hฯƒ : CMDiffAt 2 (T% ฯƒ) x) (hY : CMDiffAt 2 (T% Y) x) (hZ : CMDiffAt 2 (T% Z) x) : + (MDiffAt fun x โ†ฆ TotalSpace.mk' E x ((cov Z x) (VectorField.mlieBracket I ฯƒ Y x))) x := by + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply temp' hcov ?_ (hcov'.contMDiff' hcov hZ) + apply ContMDiffAt.mlieBracket_vectorField hฯƒ hY _ + simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general ๐•œ + +theorem curvatureTensorAux_tensorialโ‚ (hcov : IsCovariantDerivativeOn E cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + (Y Z : (ฮ  x : M, TangentSpace I x)) : + TensorialAt I E (curvatureTensorAux cov ยท Y Z x) x where + smul {f X} hf hX := by + unfold curvatureTensorAux + dsimp + sorry + add {ฯƒ ฯƒ'} hฯƒ hฯƒ' := by + unfold curvatureTensorAux + simp only [Pi.add_apply, map_add, Pi.sub_apply] + --rw [VectorField.mlieBracket_add_left hฯƒ hฯƒ'] + have : VectorField.mlieBracket I (ฯƒ + ฯƒ') Y x = + VectorField.mlieBracket I ฯƒ Y x + VectorField.mlieBracket I ฯƒ' Y x := by + rw [VectorField.mlieBracket_add_left hฯƒ hฯƒ'] + set A := cov (fun x โ†ฆ (cov Z x) (Y x)) x (ฯƒ x) + set B := cov (fun x โ†ฆ (cov Z x) (Y x)) x (ฯƒ' x) + --erw [ContinuousLinearMap.add_apply] + -- TODO: need stronger assumptions on ฯƒ, ฯƒ' and Z! + have hฯƒ : CMDiff 2 (T% ฯƒ) := sorry + have hฯƒ' : CMDiff 2 (T% ฯƒ') := sorry + have hY : CMDiffAt 2 (T% Y) x := sorry + have hZ : CMDiff 2 (T% Z) := sorry + have hZ' : CMDiffAt 2 (T% Z) x := sorry + -- corollaries, which occur as side goals several times + have hZฯƒ : MDiffAt (fun x โ†ฆ TotalSpace.mk' E x (cov Z x (ฯƒ x))) x := by + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact temp hcov hฯƒ hZ (hcov'.contMDiff' hcov hZ') + have hZฯƒ' : MDiffAt (fun x โ†ฆ TotalSpace.mk' E x (cov Z x (ฯƒ' x))) x := by + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact temp hcov hฯƒ' hZ (hcov'.contMDiff' hcov hZ') + have missing : + (cov (fun x โ†ฆ (cov Z x) (VectorField.mlieBracket I (ฯƒ + ฯƒ') Y x)) x) (Y x) = + (cov (fun x โ†ฆ (cov Z x) (VectorField.mlieBracket I ฯƒ Y x)) x) (Y x) + + (cov (fun x โ†ฆ (cov Z x) (VectorField.mlieBracket I ฯƒ' Y x)) x) (Y x) := by + trans (cov (fun x โ†ฆ ( + cov Z x (VectorField.mlieBracket I ฯƒ Y x)) + cov Z x (VectorField.mlieBracket I ฯƒ' Y x) + ) x) (Y x) + ยท congr 1 + sorry -- missing tensoriality lemma; first arguments are equal at x + ยท erw [hcov.add (aux hcov (hฯƒ x) hY hZ') (aux hcov (hฯƒ' x) hY hZ')] + simp + rw [hcov.sub] + rotate_left + ยท exact mdifferentiableAt_add_section hZฯƒ hZฯƒ' + ยท apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + apply temp' hcov ?_ (hcov'.contMDiff' hcov hZ') + apply ContMDiffAt.mlieBracket_vectorField (ContMDiff.add_section hฯƒ hฯƒ' ..) hY + simp; sorry -- want sth with minSmoothness instead; otherwise too weak for general k + rw [hcov.sub hZฯƒ (aux hcov (hฯƒ x) hY hZ')] + dsimp + erw [hcov.add hZฯƒ hZฯƒ'] + simp only [ContinuousLinearMap.add_apply] + --set C := cov (fun x โ†ฆ (cov Z x) (ฯƒ x)) x + --set D := cov (fun x โ†ฆ (cov Z x) (ฯƒ' x)) x + rw [hcov.sub hZฯƒ' ((aux hcov (hฯƒ' x) hY hZ'))] + rw [missing] + --set E := (cov (fun x โ†ฆ (cov Z x) (VectorField.mlieBracket I ฯƒ Y x)) x) (Y x) + dsimp + --set F := (cov (fun x โ†ฆ (cov Z x) (VectorField.mlieBracket I ฯƒ' Y x)) x) (Y x) + abel + +-- update hypotheses to match lemma above, once proven! +theorem curvatureTensorAux_tensorialโ‚‚ (hcov : IsCovariantDerivativeOn E cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + (X Z : (ฮ  x : M, TangentSpace I x)) : + TensorialAt I E (curvatureTensorAux cov X ยท Z x) x := + -- proof is analogous to the version in X + sorry + +-- update hypotheses to match lemma above, once proven! +theorem curvatureTensorAux_tensorialโ‚ƒ (hcov : IsCovariantDerivativeOn E cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn E 1 cov univ] + (X Y : (ฮ  x : M, TangentSpace I x)) : + TensorialAt I E (curvatureTensorAux cov X Y ยท x) x := + -- linearity should be "easy" also, scalar multiplication is a different proof + sorry + +noncomputable section + +/-- The Riemannian curvature endomorphism `R`, as a (3,1)-tensor field: for vector fields `X`, `Y` +and `Z`, it is defined as `R(X, Y)Z = โˆ‡_X (โˆ‡_Y Z) - โˆ‡_Y (โˆ‡_X Z) - โˆ‡_[X,Y] Z`. -/ +-- This definition follows Lee's sign conventions. +-- TODO: decide if we want this one, and add a comment accordingly! +def curvatureEndomorphismTensor (hcov : IsCovariantDerivativeOn E cov) (x : M) + [ContMDiffCovariantDerivativeOn E 1 cov univ] : + TangentSpace I x โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] TangentSpace I x := + TensorialAt.mkHomโ‚ƒ (curvatureTensorAux cov ยท ยท ยท x) x + (fun ฯƒ ฯ„ _ โ†ฆ hcov.curvatureTensorAux_tensorialโ‚ x ฯƒ ฯ„) + (fun ฯƒ ฯ„ _ โ†ฆ hcov.curvatureTensorAux_tensorialโ‚‚ x ฯƒ ฯ„) + (fun ฯƒ ฯ„ _ โ†ฆ hcov.curvatureTensorAux_tensorialโ‚ƒ x ฯƒ ฯ„) + +variable [ContMDiffCovariantDerivativeOn E 1 cov univ] + +-- lemmas: curvatureEndomorphismTensor_apply and curvatureEndomorphismTensor_apply_extend + +variable (X) in +@[simp] +lemma curvatureEndomorphismTensor_self (hcov : IsCovariantDerivativeOn E cov) + (Xโ‚€ : TangentSpace I x) : + hcov.curvatureEndomorphismTensor x Xโ‚€ Xโ‚€ = 0 := by + sorry + +variable (X Y) in +lemma curvatureEndomorphismTensor_swap (hcov : IsCovariantDerivativeOn E cov) + (Xโ‚€ Yโ‚€ : TangentSpace I x) : + hcov.curvatureEndomorphismTensor x Xโ‚€ Yโ‚€ = - hcov.curvatureEndomorphismTensor x Yโ‚€ Xโ‚€ := by + sorry + +-- lemma: if cov is the Levi-Civita connection, we have + = 0 +-- for all vector fields V, X, Y and Z. + +-- The Ricci curvature is the trace of this linear map +def ricciCurvatureAux (hcov : IsCovariantDerivativeOn E cov) (x : M) (Y Z : TangentSpace I x) : + TangentSpace I x โ†’L[๐•œ] TangentSpace I x where + toFun := fun Xโ‚€ โ†ฆ curvatureEndomorphismTensor hcov x Xโ‚€ Y Z + map_add' Xโ‚€ Xโ‚ := by simp + map_smul' a Xโ‚€ := by simp + +def RicciCurvatureFun (hcov : IsCovariantDerivativeOn E cov) (x : M) : + TangentSpace I x โ†’ TangentSpace I x โ†’ ๐•œ := + fun Y Z โ†ฆ LinearMap.trace ๐•œ _ (ricciCurvatureAux hcov x Y Z).toLinearMap + +def RicciCurvature (hcov : IsCovariantDerivativeOn E cov) (x : M) : + TangentSpace I x โ†’L[๐•œ] TangentSpace I x โ†’ ๐•œ := + sorry -- apply tensoriality criterion, again + +-- most conceptual proof: define the contraction of a tensor and show it is still a tensor + +-- scalar curvature left to the reader + +end + +end IsCovariantDerivativeOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean new file mode 100644 index 00000000000000..2a29fff87c7ffe --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -0,0 +1,403 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Trivial + +/-! +# Covariant derivatives + +TODO: add a more complete doc-string + +-/ + +open Bundle Filter Module Topology Set +open scoped Bundle Manifold ContDiff + +lemma Bundle.Trivialization.continuousLinearMapAt_apply_of_mem (R : Type*) {B : Type*} {F : Type*} + {E : B โ†’ Type*} [NontriviallyNormedField R] [(x : B) โ†’ AddCommMonoid (E x)] + [(x : B) โ†’ Module R (E x)] + [NormedAddCommGroup F] [NormedSpace R F] + [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + [(x : B) โ†’ TopologicalSpace (E x)] [FiberBundle F E] (e : Trivialization F TotalSpace.proj) + [Trivialization.IsLinear R e] {b : B} (hb : b โˆˆ e.baseSet) (y : E b) : + (continuousLinearMapAt R e b) y = (e โŸจb, yโŸฉ).2 := by + simp [coe_linearMapAt_of_mem e hb] + +attribute [simp] Bundle.Trivialization.coe_linearMapAt_of_mem + +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + +@[expose] public section -- TODO: think if we want to expose all definitions! + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + -- `F` model fiber + (n : WithTop โ„•โˆž) + {V : M โ†’ Type*} [TopologicalSpace (TotalSpace F V)] + [โˆ€ x, AddCommGroup (V x)] [โˆ€ x, Module ๐•œ (V x)] + [โˆ€ x : M, TopologicalSpace (V x)] [FiberBundle F V] + -- `V` vector bundle + +--- TODO FROM HERE! + +namespace IsCovariantDerivativeOn + +section projection_trivial_bundle + +variable [CompleteSpace ๐•œ] [FiniteDimensional ๐•œ F] + [IsManifold I 1 M] + +local notation "TM" => TangentSpace I + +variable {cov : (M โ†’ F) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F)} {s : Set M} + +noncomputable +def projection (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : (TM x) ร— F โ†’L[๐•œ] F := + .snd ๐•œ (TM x) F + (hcov.one_form x f โˆ˜L .fst ๐•œ (TM x) F) + +@[simp] +lemma projection_apply (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) (v : TM x) (w : F) : + hcov.projection x f (v, w) = w + hcov.one_form x f v := rfl + +lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (ฯƒ : M โ†’ F) + {x : M} (Xโ‚€ : TM x) (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ s := by trivial) : + cov ฯƒ x Xโ‚€ = hcov.projection x (ฯƒ x) (Xโ‚€, mfderiv I ๐“˜(๐•œ, F) ฯƒ x Xโ‚€) := by + simpa using congr($(hcov.eq_one_form hฯƒ) Xโ‚€) + +noncomputable def horiz (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : + Submodule ๐•œ (TM x ร— F) := + (hcov.projection x f).ker + +lemma horiz_vert_direct_sum (hcov : IsCovariantDerivativeOn F cov s) (x : M) (f : F) : + IsCompl (hcov.horiz x f) (.prod โŠฅ โŠค) := by + refine IsCompl.of_eq ?_ ?_ + ยท refine (Submodule.eq_bot_iff _).mpr ?_ + rintro โŸจu, wโŸฉ โŸจhuw, hu, hwโŸฉ + simp_all [horiz] + ยท apply Submodule.sup_eq_top_iff _ _ |>.2 + intro u + use u - (0, hcov.projection x f u), ?_, (0, hcov.projection x f u), ?_, ?_ + all_goals simp [horiz] + +set_option backward.isDefEq.respectTransparency false in +lemma mem_horiz_iff_exists [FiniteDimensional ๐•œ E] (hcov : IsCovariantDerivativeOn F cov s) {x : M} + {f : F} {u : TM x} {v : F} (hx : x โˆˆ s := by trivial) : (u, v) โˆˆ hcov.horiz x f โ†” + โˆƒ s : M โ†’ F, MDiffAt s x โˆง + s x = f โˆง + mfderiv I ๐“˜(๐•œ, F) s x u = v โˆง + cov s x u = 0 := by + constructor + ยท intro huv + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply] at huv + let w : TangentSpace ๐“˜(๐•œ, F) f := v + by_cases hu : u = 0 + ยท subst hu + replace huv : v = 0 := by simpa using huv + subst huv + use fun x โ†ฆ f + simp [mdifferentiableAt_const] + rcases map_of_one_jet_spec u w (by tauto) with โŸจh, h', h''โŸฉ + use map_of_one_jet u w, h', h, h'' + ยท rw [hcov.eq_one_form] + ยท simp only [w, h] + convert huv + convert ContinuousLinearMap.add_apply (Mโ‚ := TangentSpace I x) (Mโ‚‚ := F) _ + (hcov.one_form x f) u + exact h''.symm + ยท rwa [mdifferentiableAt_section] + ยท rintro โŸจs, s_diff, rfl, rfl, covsโŸฉ + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, โ† covs] + rw [hcov.eq_one_form (mdifferentiableAt_section_trivial_iff.mpr s_diff)] + rfl + +end projection_trivial_bundle + +end IsCovariantDerivativeOn + +namespace Bundle.Trivialization + +section to_trivialization + +variable (e : Trivialization F (ฯ€ F V)) [VectorBundle ๐•œ F V] [MemTrivializationAtlas e] + [IsManifold I 1 M] + +noncomputable +def pushCovDer + (cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)) : + (M โ†’ F) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F) := + fun ฯƒ x โ†ฆ e.continuousLinearMapAt ๐•œ x โˆ˜L (cov (e.funToSec ฯƒ) x) + + +-- FIXME Decide whether we want to add enough assumption to use the commented out statement +omit [IsManifold I 1 M] in +lemma pushCovDer_secToFun -- [CompleteSpace ๐•œ] + [FiniteDimensional ๐•œ F] [IsManifold I 1 M] + [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul ๐•œ (V x)] + [ContMDiffVectorBundle 1 F V I] + {cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)} + (hcov : IsCovariantDerivativeOn F cov e.baseSet) + {u : TangentSpace I x} {ฯƒ : ฮ  x : M, V x} {x : M} + (hฯƒ : MDiffAt T%ฯƒ x) + (hx : x โˆˆ e.baseSet := by assumption) : +-- e.pushCovDer cov (e.secToFun ฯƒ) x = (e.linearEquivAt ๐•œ x hx).toContinuousLinearMap โˆ˜L (cov ฯƒ x) + e.pushCovDer cov (e.secToFun ฯƒ) x u = (e (cov ฯƒ x u)).2 := by + have : cov (e.funToSec (e.secToFun ฯƒ)) x = cov ฯƒ x := by + apply hcov.congr_of_eqOn _ hฯƒ (e.baseSet_mem_nhds hx) + ยท simp +contextual + ยท rw [(e.total_funToSec_secToFun_eventuallyEq hx ฯƒ).mdifferentiableAt_iff] + exact hฯƒ + unfold pushCovDer + simp [this, hx] + +omit [IsManifold I 1 M] in +lemma pushCovDer_funToSec [FiniteDimensional ๐•œ F] + [IsManifold I 1 M] + [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul ๐•œ (V x)] + [ContMDiffVectorBundle 1 F V I] + (cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)) + {x : M} {s : M โ†’ F} + (hx : x โˆˆ e.baseSet := by assumption) : + cov (e.funToSec s) x = e.symmL ๐•œ x โˆ˜L (e.pushCovDer cov s x) := by + ext u + simp [pushCovDer, hx] + +variable {cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)} + -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + +omit [IsManifold I 1 M] in +lemma pushCovDer_isCovariantDerivativeOn + [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul ๐•œ (V x)] + [ContMDiffVectorBundle 1 F V I] + {u : Set M} (hu : u โІ e.baseSet) + (hcov : IsCovariantDerivativeOn F cov u) : + IsCovariantDerivativeOn F (e.pushCovDer cov) u where + add {ฯƒ ฯƒ' x} hฯƒ hฯƒ' hx := by + have hs := mdifferentiableAt_funToSec' e (hu hx) hฯƒ + have hs' := mdifferentiableAt_funToSec' e (hu hx) hฯƒ' + unfold Trivialization.pushCovDer + rw [โ† ContinuousLinearMap.comp_add, โ† hcov.add hs hs' hx, e.funToSec_map_add ๐•œ] + leibniz {ฯƒ g x} hฯƒ hg hx := by + have hs := mdifferentiableAt_funToSec' e (hu hx) hฯƒ + ext u + unfold Trivialization.pushCovDer + rw [e.funToSec_map_smul g] + rw [hcov.leibniz hs hg hx] + simp [e.linearMapAt_funToSec (hu hx)] + +-- This is PAIIIIINNNN and currently unused +variable {e} in +lemma coordChangeL_coordChangeL + {e' : Trivialization F (ฯ€ F V)} [MemTrivializationAtlas e'] + {x : M} (hx : x โˆˆ e.baseSet โˆฉ e'.baseSet) (v : F) : + e'.coordChangeL ๐•œ e x (e.coordChangeL ๐•œ e' x v) = v := by + have hx' := inter_comm _ _ โ–ธ hx + change ((coordChangeL ๐•œ e' e x) โˆ˜ (coordChangeL ๐•œ e e' x)) v = v + rw [coe_coordChangeL _ _ hx] + rw [coe_coordChangeL _ _ hx'] + change + ((linearEquivAt ๐•œ e x hx'.2 โˆ˜ (linearEquivAt ๐•œ e' x hx'.1).symm) โˆ˜ + (linearEquivAt ๐•œ e' x hx'.1 โˆ˜ (linearEquivAt ๐•œ e x hx'.2).symm)) + v = v + rw [Function.comp_assoc] + conv => + congr + congr + rfl + rw [โ† Function.comp_assoc] + change + ((linearEquivAt ๐•œ e x _) โˆ˜ + (โ†‘(linearEquivAt ๐•œ e' x hx'.1).symm โˆ˜โ‚— (linearEquivAt ๐•œ e' x hx'.1).toLinearMap) โˆ˜ _) + v = v + rw [(linearEquivAt ๐•œ e' x hx'.1).symm_comp] + simp only [LinearMap.id_coe, CompTriple.comp_eq] + change (โ†‘(linearEquivAt ๐•œ e x hx'.2) โˆ˜โ‚— (linearEquivAt ๐•œ e x _).symm.toLinearMap) v = v + rw [(linearEquivAt ๐•œ e x hx'.2).comp_symm] + simp + + +end to_trivialization + +end Bundle.Trivialization + +section horiz +namespace CovariantDerivative + +variable [CompleteSpace ๐•œ] [FiniteDimensional ๐•œ F] + [IsManifold I 1 M] + [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul ๐•œ (V x)] + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + +local notation "TM" => TangentSpace I + +noncomputable +def proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + TangentSpace (I.prod ๐“˜(๐•œ, F)) v โ†’L[๐•œ] V v.proj := + letI t := trivializationAt F V v.proj + haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn (u := t.baseSet) subset_rfl + cov.isCovariantDerivativeOn + letI tproj := d_covDerOn.projection v.proj (t v).2 + letI Tvt := t.deriv I v + t.symmL ๐•œ v.proj โˆ˜L tproj โˆ˜L Tvt + +omit [FiniteDimensional ๐•œ F] [CompleteSpace ๐•œ] [IsManifold I 1 M] in +lemma isCovariantDerivativeOn_pushCovDer + (cov : CovariantDerivative I F V) (e : Trivialization F (ฯ€ F V)) [MemTrivializationAtlas e] : + IsCovariantDerivativeOn F (e.pushCovDer cov) e.baseSet := + e.pushCovDer_isCovariantDerivativeOn subset_rfl + (cov.isCovariantDerivativeOn.mono fun _ _ โ†ฆ mem_univ _) + +lemma snd_triv_proj (cov : CovariantDerivative I F V) (v : TotalSpace F V) (u : TangentSpace (I.prod + ๐“˜(๐•œ, F)) v) : + letI t := trivializationAt F V v.proj + haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t + letI tproj := d_covDerOn.projection v.proj (t v).2 + letI Tvt := t.deriv I v + (t <| cov.proj v u).2 = tproj (Tvt u) := by + simp [CovariantDerivative.proj, (mem_baseSet_trivializationAt F V v.proj)] + +noncomputable def horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + Submodule ๐•œ (TangentSpace (I.prod ๐“˜(๐•œ, F)) v) := + (cov.proj v).ker + +lemma mem_horiz_iff_proj {cov : CovariantDerivative I F V} {v : TotalSpace F V} + (u : TangentSpace (I.prod ๐“˜(๐•œ, F)) v) : + u โˆˆ cov.horiz v โ†” cov.proj v u = 0 := by + simp [horiz] + +lemma comap_trivializationAt_horiz (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + letI t := trivializationAt F V v.proj + haveI d_covDerOn := cov.isCovariantDerivativeOn_pushCovDer t + horiz cov v = Submodule.comap (t.deriv I v).toLinearMap + (d_covDerOn.horiz v.proj (t v).2) := by + -- FIXME: needing all those lets and the change is awful + let t := trivializationAt F V v.proj + let Tvt := t.deriv I v + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer t + let tproj := hcov.projection v.proj (t v).2 + let t' := t.continuousLinearEquivAt ๐•œ v.proj (mem_baseSet_trivializationAt F V v.proj) + ext u + change t'.symm (tproj (Tvt u)) = 0 โ†” tproj (Tvt u) = 0 + simp + +omit [ContMDiffVectorBundle 1 F V I] in +lemma horiz_vert_direct_sum [ContMDiffVectorBundle 1 F V I] + (cov : CovariantDerivative I F V) (v : TotalSpace F V) : + IsCompl (cov.horiz v) (vert v) := by + let t := trivializationAt F V v.proj + let Tvt := t.deriv I v + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + rw [t.comap_vert (mem_baseSet_trivializationAt F V v.proj), comap_trivializationAt_horiz] + apply LinearMap.comap_isCompl + ยท apply t.bijective_deriv + exact FiberBundle.mem_baseSet_trivializationAt' v.proj + ยท apply hcov.horiz_vert_direct_sum + +variable {cov : CovariantDerivative I F V} + +lemma proj_mderiv {ฯƒ : ฮ  x : M, V x} (x : M) + (hฯƒ : MDiffAt (T% ฯƒ) x) : + cov ฯƒ x = cov.proj (ฯƒ x) โˆ˜L + (mfderiv I (I.prod ๐“˜(๐•œ, F)) (T% ฯƒ) x) := by + let t := trivializationAt F V x + let s := t.secToFun ฯƒ + let Tฯƒx := mfderiv% (T% ฯƒ) x + -- FIXME `mfderiv%` fails in next line + let Ttฯƒx := mfderiv (I.prod ๐“˜(๐•œ, F)) (I.prod ๐“˜(๐•œ, F)) t (ฯƒ x) + ext1 Xโ‚€ + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + have hx := mem_baseSet_trivializationAt F V x + have hs : MDiffAt (T% s) x := t.mdifferentiableAt_total_secToFun hx hฯƒ + change cov ฯƒ x Xโ‚€ = cov.proj (T% ฯƒ x) (mfderiv% (T% ฯƒ) x Xโ‚€) + apply t.eq_of hx + rw [cov.snd_triv_proj (T% ฯƒ x), + โ† t.pushCovDer_secToFun cov.isCovariantDerivativeOn hฯƒ, + hcov.cov_eq_proj s Xโ‚€ hs, t.mfderiv_comp_section hฯƒ _ hx] + rfl + +lemma mem_horiz_iff_exists [FiniteDimensional ๐•œ E] + {cov : CovariantDerivative I F V} {v : TotalSpace F V} + (w : TangentSpace (I.prod ๐“˜(๐•œ, F)) v) : + letI u := mfderiv (I.prod ๐“˜(๐•œ, F)) I TotalSpace.proj v w + w โˆˆ cov.horiz v โ†” โˆƒ ฯƒ : ฮ  x, V x, + MDiffAt (T% ฯƒ) v.proj โˆง + ฯƒ v.proj = v โˆง + mfderiv% (T% ฯƒ) v.proj u = w โˆง + cov ฯƒ v.proj u = 0 + := by + set u := mfderiv (I.prod ๐“˜(๐•œ, F)) I TotalSpace.proj v w with u_def + set t := trivializationAt F V v.proj with t_def + set Tvt := t.deriv I v with Tvt_def + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + have hvproj : v.proj โˆˆ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' v.proj + have hTvtw : (Tvt w).1 = u := + t.mfderiv_proj_fst_deriv hvproj w |>.symm + simp_rw [cov.comap_trivializationAt_horiz v, โ† t_def, โ† Tvt_def, Submodule.mem_comap, + hcov.mem_horiz_iff_exists] + constructor + ยท rintro โŸจs, sdiff, sval, mfderivs, covsโŸฉ + use t.funToSec s, ?_, ?_, ?_, ?_ + ยท exact t.mdifferentiableAt_funToSec hvproj sdiff + ยท simp [sval, hvproj] + ยท -- TODO needs a lot of cleanup here + -- TODO cleanup those erw by understanding why we sometimes have Tvt and + -- sometimes Tvt.toLinerMap + erw [hTvtw] at mfderivs + rw [u_def, t.mfderiv_total_funToSec sdiff hvproj] + simp only [ContinuousLinearMap.coe_comp', Function.comp_apply, ContinuousLinearMap.prod_apply, + ContinuousLinearMap.coe_id', id_eq] + erw [mfderivs] + rw [t.mfderiv_proj_fst_deriv hvproj] + have : (((Trivialization.deriv I t v) w).1, (Tvt w).2) = Tvt w := rfl + erw [this, Tvt_def, t.funToSec_proj_eq hvproj sval] + exact t.derivInv_deriv_apply hvproj w + ยท rw [ContinuousLinearMap.coe_coe] at covs + simp [t.pushCovDer_funToSec cov, โ† hTvtw, covs, t.symm_map_zero ๐•œ] + ยท rintro โŸจฯƒ, ฯƒdiff, ฯƒval, mfderivฯƒ, covฯƒโŸฉ + use t.secToFun ฯƒ, ?_, ?_, ?_ + ยท rw [t.pushCovDer_secToFun cov.isCovariantDerivativeOn ฯƒdiff] + -- TODO cleanup those erw by understanding why we sometimes have Tvt and + -- sometimes Tvt.toLinerMap + erw [hTvtw, covฯƒ] + exact t.map_zero ๐•œ hvproj + ยท exact Trivialization.mdifferentiableAt_secToFun t hvproj ฯƒdiff + ยท exact t.secToFun_apply_of_eq ฯƒval + ยท erw [hTvtw] + rw [t.mfderiv_secToFun_apply ฯƒdiff hvproj, mfderivฯƒ, ฯƒval] + rfl + +end CovariantDerivative +end horiz + +-- variable (E E') in +-- /-- The trivial connection on a trivial bundle, given by the directional derivative -/ +-- @[simps] +-- noncomputable def trivial : CovariantDerivative ๐“˜(๐•œ, E) E' +-- (Bundle.Trivial E E') where +-- toFun X s := fun x โ†ฆ fderiv ๐•œ s x (X x) +-- isCovariantDerivativeOn := +-- { addX X X' ฯƒ x _ := by simp +-- smulX X ฯƒ c' x _ := by simp +-- add X ฯƒ ฯƒ' x hฯƒ hฯƒ' hx := by +-- rw [Bundle.Trivial.mdifferentiableAt_iff] at hฯƒ hฯƒ' +-- rw [fderiv_add hฯƒ hฯƒ'] +-- rfl +-- smul_constX ฯƒ a x hx := by simp [fderiv_const_smul_of_field a] +-- leibniz X ฯƒ f x hฯƒ hf hx := by +-- have : fderiv ๐•œ (f โ€ข ฯƒ) x = f x โ€ข fderiv ๐•œ ฯƒ x + (fderiv ๐•œ f x).smulRight (ฯƒ x) := +-- fderiv_smul (by simp_all) (by simp_all) +-- simp [this, bar] +-- rfl } + +end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean new file mode 100644 index 00000000000000..0aeb17de89fd81 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Geodesics.lean @@ -0,0 +1,97 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Heather Macbeth, Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.IntegralCurvePrelim + +/-! +# Geodesics for covariant derivatives on tangent bundles + +TODO: add a more complete doc-string + +-/ + +@[expose] public section + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] [FiniteDimensional โ„ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners โ„ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] + [IsManifold I 2 M] + (cov : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)) + +lemma IsMIntegralCurveAt.proj_acceleration {X : ฮ  x : M, TangentSpace I x} + {ฮณ : โ„ โ†’ M} {tโ‚€ : โ„} (hX : MDiffAt (T% X) (ฮณ tโ‚€)) + (hฮณX : IsMIntegralCurveAt ฮณ X tโ‚€) : + cov.proj _ (velocity I.tangent (velocity I ฮณ) tโ‚€).2 = cov X (ฮณ tโ‚€) (X (ฮณ tโ‚€)) := by + rw [hฮณX.acceleration hX, cov.proj_mderiv _ hX] + simp + +/-- The geodesic vector field of a covariant derivative on a tangent bundle, defined +by send any vector `v` to its lift at itself. -/ +noncomputable +def CovariantDerivative.geodVF (v : TotalSpace E (TangentSpace I : M โ†’ Type _)) : + TangentSpace (I.prod ๐“˜(โ„, E)) v := cov.lift_vec v v.2 + +@[simp] +lemma CovariantDerivative.geodVF_horiz (v : TotalSpace E (TangentSpace I : M โ†’ Type _)) : + cov.geodVF v โˆˆ cov.horiz v := by + simp [CovariantDerivative.geodVF] + +@[simp] +lemma CovariantDerivative.proj_geodVF (v : TotalSpace E (TangentSpace I : M โ†’ Type _)) : + cov.proj v (cov.geodVF v) = 0 := by + simp [CovariantDerivative.geodVF] + +/-- A curve `ฮณ : โ„ โ†’ M` is a geodesic for `cov` at `t` if it is an integral +curve of the geodesic vector field of `cov` near `t`. +Remember: `IsMIntegralCurveAt` is local, not pointwise. -/ +def CovariantDerivative.isGeodAt (ฮณ : โ„ โ†’ M) (t : โ„) := + IsMIntegralCurveAt (velocity I ฮณ) cov.geodVF t + +set_option backward.isDefEq.respectTransparency false in +lemma CovariantDerivative.isGeodAt_iff_horiz {ฮณ : โ„ โ†’ M} {tโ‚€ : โ„} + (hฮณ : โˆ€แถ  (t : โ„) in ๐“ tโ‚€, MDiffAt (velocity I ฮณ) t) : + cov.isGeodAt ฮณ tโ‚€ โ†” + โˆ€แถ  (t : โ„) in ๐“ tโ‚€, (velocity I.tangent (velocity I ฮณ) t).2 โˆˆ cov.horiz _ := by + unfold CovariantDerivative.isGeodAt CovariantDerivative.geodVF + rw [IsMIntegralCurveAt_iff_mfderiv _ _ _ hฮณ] + refine eventually_congr ?_ + filter_upwards [hฮณ] with t ht + conv_lhs => rw [Eq.comm, cov.lift_vec_eq_iff (velocity I ฮณ t).2] + rw [โ† cov.mem_horiz_iff_proj, proj_velocity, + show mfderiv% (velocity I ฮณ) t (1 : โ„) = (velocity I.tangent (velocity I ฮณ) t).2 from + rfl, -- TODOโ€ฏneed a simp lemma here? + ] + -- TODO: understand why + -- simp [proj_velocity, proj_acceleration I ht] + -- doesnโ€™t close the goal + simp only [proj_velocity, and_iff_left_iff_imp] + exact fun _ โ†ฆ proj_acceleration I ht + +lemma CovariantDerivative.isGeodAt_iff_proj {ฮณ : โ„ โ†’ M} {tโ‚€ : โ„} + (hฮณ : โˆ€แถ  (t : โ„) in ๐“ tโ‚€, MDiffAt (velocity I ฮณ) t) : + cov.isGeodAt ฮณ tโ‚€ โ†” + โˆ€แถ  (t : โ„) in ๐“ tโ‚€, cov.proj _ (velocity I.tangent (velocity I ฮณ) t).2 = 0 := + cov.isGeodAt_iff_horiz hฮณ + +def CovariantDerivative.isGeod (ฮณ : โ„ โ†’ M) := โˆ€ t, cov.isGeodAt ฮณ t + +set_option backward.isDefEq.respectTransparency false in +lemma CovariantDerivative.orbit_geodVF {X : ฮ  x : M, TangentSpace I x} + {ฮณ : โ„ โ†’ M} {tโ‚€ : โ„} (hX : โˆ€แถ  t in ๐“ tโ‚€, MDiffAt (T% X) (ฮณ t)) + (hฮณ : โˆ€แถ  (t : โ„) in ๐“ tโ‚€, MDiffAt (velocity I ฮณ) t) + (hฮณX : IsMIntegralCurveAt ฮณ X tโ‚€) : + cov.isGeodAt ฮณ tโ‚€ โ†” โˆ€แถ  t in ๐“ tโ‚€, cov X (ฮณ t) (X (ฮณ t)) = 0 := by + rw [cov.isGeodAt_iff_proj hฮณ] + refine eventually_congr ?_ + filter_upwards [hX, hฮณX.eventually_isMIntegralCurveAt] with t ht ht' + rw [ht'.proj_acceleration cov ht] diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean new file mode 100644 index 00000000000000..c762b2b4f68fc0 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/IntegralCurvePrelim.lean @@ -0,0 +1,108 @@ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +public import Mathlib.Geometry.Manifold.IntegralCurve.Basic + + +/-! +# Preliminaries about integral curves of vector fiels + +TODO: PR that material to Mathlib.Geometry.Manifold.IntegralCurve.Basic +except for `proj_acceleration` which uses +`Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable`. +-/ + +@[expose] public section + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] {H : Type*} + [TopologicalSpace H] {I : ModelWithCorners โ„ E H} {M : Type*} + [TopologicalSpace M] [ChartedSpace H M] (ฮณ : โ„ โ†’ M) + (v : (x : M) โ†’ TangentSpace I x) (tโ‚€ : โ„) + +variable (I) in +noncomputable +def velocity (ฮณ : โ„ โ†’ M) (t : โ„) : TangentBundle I M := โŸจฮณ t, mfderiv% ฮณ t (1 : โ„)โŸฉ + +@[simp] +lemma proj_velocity (ฮณ : โ„ โ†’ M) (t : โ„) : (velocity I ฮณ t).proj = ฮณ t := rfl + +lemma IsMIntegralCurveAt.mdifferentiableAt (h : IsMIntegralCurveAt ฮณ v tโ‚€) : + โˆ€แถ  t in ๐“ tโ‚€, MDiffAt ฮณ t := by + filter_upwards [h] with t ht + exact ht.mdifferentiableAt + +set_option backward.isDefEq.respectTransparency false in +protected lemma IsMIntegralCurveAt.mfderiv (hฮณ : IsMIntegralCurveAt ฮณ v tโ‚€) : + โˆ€แถ  t in ๐“ tโ‚€, mfderiv% ฮณ t (1 : โ„) = v (ฮณ t) := by + filter_upwards [hฮณ] with t ht + rw [ht.mfderiv] + rw [ContinuousLinearMap.smulRight_apply] + change 1 โ€ข v (ฮณ t) = v (ฮณ t) + simp + +protected lemma IsMIntegralCurveAt.velocity_eventuallyEq + (hฮณ : IsMIntegralCurveAt ฮณ v tโ‚€) : velocity I ฮณ =แถ [๐“ tโ‚€] T%v โˆ˜ ฮณ := by + filter_upwards [hฮณ.mfderiv] with t ht + simp [ht, velocity] + +-- Is this really missing?? +lemma IsMIntegralCurveAt_iff_mfderiv (hฮณ : โˆ€แถ  t in ๐“ tโ‚€, MDiffAt ฮณ t) : + IsMIntegralCurveAt ฮณ v tโ‚€ โ†” โˆ€แถ  t in ๐“ tโ‚€, mfderiv% ฮณ t (1 : โ„) = v (ฮณ t) := by + refine โŸจfun h โ†ฆ h.mfderiv, fun h โ†ฆ ?_โŸฉ + filter_upwards [hฮณ.and h] with t โŸจht, ht'โŸฉ + rw [โ† ht'] + convert ht.hasMFDerivAt + ext + simp + rfl + +lemma IsMIntegralCurveAt.eventually_isMIntegralCurveAt + {X : ฮ  x : M, TangentSpace I x} {ฮณ : โ„ โ†’ M} {tโ‚€ : โ„} + (hฮณX : IsMIntegralCurveAt ฮณ X tโ‚€) : + โˆ€แถ  t in ๐“ tโ‚€, IsMIntegralCurveAt ฮณ X t := + eventually_eventually_nhds.2 hฮณX + +variable [IsManifold I 1 M] + +set_option linter.flexible false in --FIXME +lemma IsMIntegralCurveAt.acceleration {X : ฮ  x : M, TangentSpace I x} + {ฮณ : โ„ โ†’ M} {tโ‚€ : โ„} (hX : MDiffAt (T% X) (ฮณ tโ‚€)) + (hฮณX : IsMIntegralCurveAt ฮณ X tโ‚€) : + velocity I.tangent (velocity I ฮณ) tโ‚€ = mfderiv% (T% X) (ฮณ tโ‚€) (X (ฮณ tโ‚€)) := by + have : velocity I ฮณ =แถ [๐“ tโ‚€] T%X โˆ˜ ฮณ := hฮณX.velocity_eventuallyEq + have := this.mfderiv_eq (I := ๐“˜(โ„, โ„)) (I' := I.tangent) + have foo := EventuallyEq.eq_of_nhds hฮณX.mfderiv + simp [velocity, this, foo] + have := hฮณX.mdifferentiableAt.self_of_nhds + rw [mfderiv_comp tโ‚€ hX this, โ† foo] + rfl + +lemma IsMIntegralCurveAt.eventually_acceleration {X : ฮ  x : M, TangentSpace I x} + {ฮณ : โ„ โ†’ M} {tโ‚€ : โ„} (hX : โˆ€แถ  t in ๐“ tโ‚€, MDiffAt (T% X) (ฮณ t)) + (hฮณX : IsMIntegralCurveAt ฮณ X tโ‚€) : + โˆ€แถ  t in ๐“ tโ‚€, velocity I.tangent (velocity I ฮณ) t = mfderiv% (T% X) (ฮณ t) (X (ฮณ t)) := by + filter_upwards [hX, hฮณX.eventually_isMIntegralCurveAt] with t hXt hฮณXt + exact acceleration hXt hฮณXt + +-- FIXME: bug in `mfderiv%`? +-- FIXME: missing elaborator support to find I.tangent +variable (I) in +@[simp] +lemma proj_acceleration {ฮณ : โ„ โ†’ M} {t : โ„} (h : MDiffAt (velocity I ฮณ) t) : + mfderiv I.tangent I (TotalSpace.proj : TangentBundle I M โ†’ M) + (velocity I ฮณ t) (velocity I.tangent (velocity I ฮณ) t).2 = (velocity +I ฮณ t).2 := by + have comp_eq: (TotalSpace.proj : TangentBundle I M โ†’ M) โˆ˜ (velocity I ฮณ) = ฮณ := by + ext t + simp + have diff : MDifferentiableAt I.tangent I (TotalSpace.proj : TangentBundle I M โ†’ M) + (velocity I ฮณ t) := by + exact mdifferentiableAt_proj (TangentSpace I) + have := mfderiv_comp t diff h + rw [comp_eq] at this + exact congr($this (1 : โ„)).symm diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean new file mode 100644 index 00000000000000..38b8450d10b69e --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -0,0 +1,860 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth +-/ +module + +public import Mathlib.Analysis.InnerProductSpace.Dual +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Metric +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion + +/-! +# The Levi-Civita connection on a Riemannian manifold + +To be continued and polished! + +This file defines the Levi-Civita connection on a (finite-dimensional) Riemannian manifold `(M, g)`. +connection `โˆ‡` on the tangent bundle of a Riemannian manifold `(M, g)` is called a +*Levi-Civita connection* if and only if it is both compatible with the metric `g` and torsion-free. +Any two such connections are equal (on differentiable vector fields), which is why one speaks of +*the* Levi-Civita connection on `TM`. +We construct a Levi-Civita connection and prove that is defines a compatible torsion-free +connection. + + +## Main definitions and results + +* `CovariantDerivative.IsLeviCivitaConnection`: a covariant derivative `โˆ‡` on `(M, g)` is a + Levi-Civita connection if and only if it is both torsion-free and compatible with `g` + +* `CovariantDerivative.IsLeviCivitaConnection.uniqueness`: a Levi-Civita connection on `(M, g)` is + uniquely determined on differentiable vector fields. + +* `CovariantDerivative.LeviCivitaConnection`: a choice of Levi-Civita connection on the tangent + bundle `TM` of a Riemannian manifold `(M, g)`: this is unique up to the value on + non-differentiable vector fields. + If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. +* `CovariantDerivative.leviCivitaConnection_isLeviCivitaConnection`: + `LeviCivitaConnection` is a Levi-Civita connection (i.e., compatible and torsion-free) + +## Implementation notes +* construction of LC using a tensoriality argument, and the musical isomorphism + (avoids the use of local frames and trivialisations) + +-/ + +open Bundle FiberBundle Function NormedSpace +open scoped Manifold ContDiff + +@[expose] public section -- TODO: think if we want to expose all definitions! + +-- TODO: revisit and fix this once the dust has settled +set_option backward.isDefEq.respectTransparency false + +-- Let `(M, g)` be a `C^k` real manifold modeled on `(E, H)`, endowed with a Riemannian metric `g`. +variable {n : WithTop โ„•โˆž} + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners โ„ E H) + {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] + [RiemannianBundle (fun (x : M) โ†ฆ TangentSpace I x)] + {X X' X'' Y Y' Y'' Z Z' : ฮ  x : M, TangentSpace I x} + +namespace CovariantDerivative + +-- Let `cov` be a covariant derivative on `TM`. +-- TODO: include in cheat sheet! +variable (cov : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)) + +/-- Local notation for a connection. Caution: `โˆ‡ Y, X` corresponds to `โˆ‡โ‚“ Y` in textbooks -/ +local notation "โˆ‡" Y "," X => fun (x:M) โ†ฆ cov Y x (X x) + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] + +/-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** +iff it is torsion-free and compatible with `g`. +Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a +version depending on a choice of Riemannian metric on `M`. +-/ +def IsLeviCivitaConnection [FiniteDimensional โ„ E] : Prop := cov.IsCompatible โˆง cov.torsion = 0 + +local notation "โŸช" X ", " Y "โŸซ" => product X Y + +/- TODO: writing `hฯƒ.inner_bundle hฯ„` or writing `by apply MDifferentiable.inner_bundle hฯƒ hฯ„` +yields an error +synthesized type class instance is not definitionally equal to expression inferred by typing rules, +synthesized + fun x โ†ฆ instNormedAddCommGroupOfRiemannianBundle x +inferred + fun b โ†ฆ instโœโท +Diagnose and fix this, and then replace the below by `MDifferentiable(At).inner_bundle! -/ + +variable {I} in +lemma _root_.MDifferentiable.inner_bundle' {X Y : ฮ  x : M, TangentSpace I x} + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) : MDiff โŸชX, YโŸซ := + MDifferentiable.inner_bundle hX hY + +variable {I} in +lemma _root_.MDifferentiableAt.inner_bundle' {x : M} {X Y : ฮ  x : M, TangentSpace I x} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : + MDiffAt โŸชX, YโŸซ x := + MDifferentiableAt.inner_bundle hX hY + +variable (X Y Z) in +/-- The first term in the definition of the candidate Levi-Civita connection: +`rhs_aux I X Y Z = X โŸจY, ZโŸฉ = x โ†ฆ d(โŸจY, ZโŸฉ)_x (X x)`. + +This definition contains mild defeq abuse, which is invisible on paper: +The function `โŸจY, ZโŸฉ` maps `M` into `โ„`, hence its differential at a point `x` maps `T_p M` +to an element of the tangent space of `โ„`. A summand `โŸจY, [X, Z]โŸฉ`, however, yields an honest +real number: Lean complains that these have different types. +Fortunately, `โ„` is defeq to its own tangent space; casting `rhs_aux` to the real numbers +allows the addition to type-check. -/ +noncomputable abbrev rhs_aux : M โ†’ โ„ := fun x โ†ฆ (mfderiv% โŸชY, ZโŸซ x (X x)) + +section rhs_aux + +variable (Y Z) in +omit [IsManifold I 2 M] in +lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by + ext x + simp only [rhs_aux] + congr 2 + exact product_swap Z Y + +omit [IsManifold I 2 M] in +variable (X X' Y Z) in +lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by + ext x + simp [rhs_aux] + +variable {x : M} + +variable (X) in +@[simp] +lemma rhs_aux_addY_apply (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X (Y + Y') Z x = rhs_aux I X Y Z x + rhs_aux I X Y' Z x := by + simp only [rhs_aux] + rw [product_add_left, mfderiv_add (hY.inner_bundle' hZ) (hY'.inner_bundle' hZ)] + simp; congr + +variable (X) in +lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : + rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by + ext x + exact rhs_aux_addY_apply I X (hY x) (hY' x) (hZ x) + +variable (X) in +@[simp] +lemma rhs_aux_addZ_apply (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + rhs_aux I X Y (Z + Z') x = rhs_aux I X Y Z x + rhs_aux I X Y Z' x := by + unfold rhs_aux + rw [product_add_right, mfderiv_add (hY.inner_bundle' hZ) (hY.inner_bundle' hZ')]; simp; congr + +variable (X) in +lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by + ext x + exact rhs_aux_addZ_apply I X (hY x) (hZ x) (hZ' x) + +omit [IsManifold I 2 M] in +variable (X Y Z) in +lemma rhs_aux_smulX_apply (f : M โ†’ โ„) (x) : rhs_aux I (f โ€ข X) Y Z x = f x * rhs_aux I X Y Z x := by + simp [rhs_aux] + +omit [IsManifold I 2 M] in +variable (X Y Z) in +lemma rhs_aux_smulX (f : M โ†’ โ„) : rhs_aux I (f โ€ข X) Y Z = f * rhs_aux I X Y Z := by + ext x + exact rhs_aux_smulX_apply .. + +variable (X) in +lemma rhs_aux_smulY_apply {f : M โ†’ โ„} + (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) + rhs_aux I X (f โ€ข Y) Z x = f x * rhs_aux I X Y Z x + A x * โŸชY, ZโŸซ x := by + rw [rhs_aux, product_smul_left, mfderiv_smul hf (hY.inner_bundle' hZ)] + rfl + +variable (X) in +lemma rhs_aux_smulY {f : M โ†’ โ„} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) + rhs_aux I X (f โ€ข Y) Z = f * rhs_aux I X Y Z + A * โŸชY, ZโŸซ := by + ext x + simp [rhs_aux_smulY_apply I X (hf x) (hY x) (hZ x)] + +variable (X) in +lemma rhs_aux_smulY_const_apply {a : โ„} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X (a โ€ข Y) Z x = a * rhs_aux I X Y Z x := by + let f : M โ†’ โ„ := fun _ โ†ฆ a + have h1 : rhs_aux I X (a โ€ข Y) Z x = rhs_aux I X (f โ€ข Y) Z x := by simp only [f]; congr + rw [h1, rhs_aux_smulY_apply I X mdifferentiableAt_const hY hZ] + simp [mfderiv_const] + +variable (X) in +lemma rhs_aux_smulY_const {a : โ„} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + rhs_aux I X (a โ€ข Y) Z = a โ€ข rhs_aux I X Y Z := by + ext x + apply rhs_aux_smulY_const_apply I X (hY x) (hZ x) + +variable (X) in +lemma rhs_aux_smulZ_apply {f : M โ†’ โ„} + (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) + rhs_aux I X Y (f โ€ข Z) x = f x * rhs_aux I X Y Z x + A x * โŸชY, ZโŸซ x := by + rw [rhs_aux_swap, rhs_aux_smulY_apply, rhs_aux_swap, product_swap] + exacts [hf, hZ, hY] + +variable (X) in +lemma rhs_aux_smulZ {f : M โ†’ โ„} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + letI A (x) := fromTangentSpace _ ((mfderiv% f x) (X x)) + rhs_aux I X Y (f โ€ข Z) = f * rhs_aux I X Y Z + A * โŸชY, ZโŸซ := by + rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] + exacts [hf, hZ, hY] + +variable (X) in +lemma rhs_aux_smulZ_const_apply {a : โ„} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X Y (a โ€ข Z) x = a * rhs_aux I X Y Z x := by + let f : M โ†’ โ„ := fun _ โ†ฆ a + have h1 : rhs_aux I X Y (a โ€ข Z) x = rhs_aux I X Y (f โ€ข Z) x := by simp only [f]; congr + rw [h1, rhs_aux_smulZ_apply I X mdifferentiableAt_const hY hZ] + simp [mfderiv_const] + +variable (X) in +lemma rhs_aux_smulZ_const {a : โ„} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + rhs_aux I X Y (a โ€ข Z) = a โ€ข rhs_aux I X Y Z := by + ext x + exact rhs_aux_smulZ_const_apply I X (hY x) (hZ x) + +end rhs_aux + +variable {x : M} + +variable (X Y Z) in +/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: +If โˆ‡ is a Levi-Civita connection on `TM`, then +`2 โŸจโˆ‡ X Y, ZโŸฉ = leviCivitaRhs' I X Y Z` for all vector fields `Z`. -/ +noncomputable def leviCivitaRhs' : M โ†’ โ„ := + rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y + - โŸชY ,(VectorField.mlieBracket I X Z)โŸซ + - โŸชZ, (VectorField.mlieBracket I Y X)โŸซ + + โŸชX, (VectorField.mlieBracket I Z Y)โŸซ + +variable (X Y Z) in +/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: +If `โˆ‡` is a Levi-Civita connection on `TM`, then +`โŸจโˆ‡ X Y, ZโŸฉ = leviCivitaRhs I X Y Z` for all smooth vector fields `X`, `Y` and `Z`. -/ +noncomputable def leviCivitaRhs : M โ†’ โ„ := (1 / 2 : โ„) โ€ข leviCivitaRhs' I X Y Z + +omit [IsManifold I 2 M] in +lemma leviCivitaRhs_apply : leviCivitaRhs I X Y Z x = (1 / 2 : โ„) โ€ข leviCivitaRhs' I X Y Z x := + rfl + +section leviCivitaRhs + +@[simp] +lemma leviCivitaRhs'_addX_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I (X + X') Y Z x = + leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X' Y Z x := by + simp only [leviCivitaRhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply] + -- We have to rewrite back and forth: the Lie bracket is only additive at x, + -- as we are only asking for differentiability at x. + -- Fortunately, the `product_congr_rightโ‚‚` lemma abstracts this very well. + rw [product_congr_rightโ‚‚ (VectorField.mlieBracket_add_right (V := Y) hX hX'), + product_congr_rightโ‚‚ (VectorField.mlieBracket_add_left (W := Z) hX hX'), + product_add_left_apply, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + abel + +lemma leviCivitaRhs'_addX [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs' I (X + X') Y Z = + leviCivitaRhs' I X Y Z + leviCivitaRhs' I X' Y Z := by + ext x + simp [leviCivitaRhs'_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] + +lemma leviCivitaRhs_addX_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I (X + X') Y Z x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X' Y Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_addX_apply I hX hX' hY hZ, left_distrib] + +lemma leviCivitaRhs_addX [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I (X + X') Y Z = leviCivitaRhs I X Y Z + leviCivitaRhs I X' Y Z := by + ext x + simp [leviCivitaRhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] + +open VectorField NormedSpace + +variable {I} in +lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I (f โ€ข X) Y Z x = f x โ€ข leviCivitaRhs' I X Y Z x := by + unfold leviCivitaRhs' + simp only [Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_smulX, rhs_aux_smulY_apply, rhs_aux_smulZ_apply] <;> try assumption + -- TODO: add the right congr_right lemma to avoid the product_apply, โ† product_apply dance! + simp only [product_apply, mlieBracket_smul_left (W := Z) hf hX, + mlieBracket_smul_right (V := Y) hf hX, inner_add_right] + -- Combining this line with the previous one fails. + simp only [โ† product_apply, neg_smul, inner_neg_right] + have h1 : + inner โ„ (Y x) ((fromTangentSpace _ (mfderiv% f x (Z x))) โ€ข X x) = + fromTangentSpace (f x) (mfderiv% f x (Z x)) * โŸชX, YโŸซ x := by + simp only [product] + rw [โ† real_inner_smul_left, real_inner_smul_right, real_inner_smul_left, real_inner_comm] + have h2 : + inner โ„ (Z x) (fromTangentSpace (f x) ((mfderiv% f x (Y x))) โ€ข X x) = + (fromTangentSpace (f x) (mfderiv% f x (Y x))) * โŸชZ, XโŸซ x := by + simp only [product] + rw [โ† real_inner_smul_left, real_inner_smul_right, real_inner_smul_left] + rw [h1, h2] + --set dfY := fromTangentSpace (f x) ((mfderiv% f x (Y x)))--(mfderiv% f x) (Y x) + --set dfZ : โ„ := (mfderiv% f x) (Z x) + have h3 : โŸชf โ€ข X, mlieBracket I Z YโŸซ x = f x * โŸชX, mlieBracket I Z YโŸซ x := by + rw [product_apply, Pi.smul_apply', real_inner_smul_left] + have h4 : inner โ„ (Z x) (f x โ€ข mlieBracket I Y X x) = f x * โŸชZ, mlieBracket I Y XโŸซ x := by + rw [product_apply, real_inner_smul_right] + rw [real_inner_smul_right (Y x), h3, h4] + -- Push all applications of `x` inwards, then it's indeed obvious. + simp + -- set A := โŸชY, mlieBracket I X ZโŸซ with hA + -- set B := โŸชZ, mlieBracket I X YโŸซ + -- set C := โŸชX, mlieBracket I Z YโŸซ + -- set R := dfZ * โŸชX, YโŸซ x with hR + -- set R' := dfY * โŸชZ, XโŸซ x with hR' + -- set E := rhs_aux I X Y Z x + -- set F := rhs_aux I Y Z X x + -- set G := rhs_aux I Z X Y x + ring_nf + +variable {I} in +lemma leviCivitaRhs_smulX_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I (f โ€ข X) Y Z x = f x โ€ข leviCivitaRhs I X Y Z x := by + simp only [leviCivitaRhs, one_div, Pi.smul_apply, smul_eq_mul] + simp_rw [leviCivitaRhs'_smulX_apply (I := I) hf hX hY hZ] + rw [โ† mul_assoc, mul_comm (f x), smul_eq_mul] + ring + +variable {I} in +lemma leviCivitaRhs_smulX [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I (f โ€ข X) Y Z = f โ€ข leviCivitaRhs I X Y Z := by + ext x + exact leviCivitaRhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) + +lemma leviCivitaRhs'_addY_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (Y + Y') Z x = leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X Y' Z x := by + simp only [leviCivitaRhs', Pi.add_apply, Pi.sub_apply, product_add_left_apply] + rw [rhs_aux_addX, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + -- We have to rewrite back and forth: the Lie bracket is only additive at x, + -- as we are only asking for differentiability at x. + rw [product_congr_rightโ‚‚ (mlieBracket_add_left (W := X) hY hY')] + rw [product_congr_rightโ‚‚ (VectorField.mlieBracket_add_right (V := Z) hY hY')] + simp only [Pi.add_apply] + abel + +lemma leviCivitaRhs_addY_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (Y + Y') Z x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X Y' Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_addY_apply I hX hY hY' hZ, left_distrib] + +lemma leviCivitaRhs_addY [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : + leviCivitaRhs I X (Y + Y') Z = leviCivitaRhs I X Y Z + leviCivitaRhs I X Y' Z := by + ext x + simp [leviCivitaRhs_addY_apply I (hX x) (hY x) (hY' x) (hZ x)] + +variable {I} in +lemma leviCivitaRhs'_smulY_const_apply [CompleteSpace E] {a : โ„} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (a โ€ข Y) Z x = a โ€ข leviCivitaRhs' I X Y Z x := by + simp only [leviCivitaRhs'] + simp only [product_smul_const_left, Pi.add_apply, Pi.sub_apply, Pi.smul_apply] + rw [rhs_aux_smulY_const_apply I X hY hZ] + -- TODO: clean up this proof! + let f : M โ†’ โ„ := fun _ โ†ฆ a + have : rhs_aux I (a โ€ข Y) Z X x = a โ€ข rhs_aux I Y Z X x := by + trans rhs_aux I (f โ€ข Y) Z X x + ยท rfl + rw [rhs_aux_smulX I Y (f := f) (Y := Z) (Z := X)] + rfl + rw [this, rhs_aux_smulZ_const_apply I _ hX hY] + -- is there a better abstraction for "Lie bracket conv mode"? + have : โŸชZ, mlieBracket I (a โ€ข Y) XโŸซ x = a โ€ข โŸชZ, mlieBracket I Y XโŸซ x := by + simp_rw [product_apply, mlieBracket_const_smul_left (W := X) hY, inner_smul_right_eq_smul] + rw [this] + have aux2 : โŸชX, mlieBracket I Z (a โ€ข Y)โŸซ x = a โ€ข โŸชX, mlieBracket I Z YโŸซ x := by + simp_rw [product_apply, mlieBracket_const_smul_right (V := Z) hY, inner_smul_right_eq_smul] + rw [aux2] + simp + ring + +variable {I} in +lemma leviCivitaRhs_smulY_const_apply [CompleteSpace E] {a : โ„} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (a โ€ข Y) Z x = a โ€ข leviCivitaRhs I X Y Z x := by + simp_rw [leviCivitaRhs, Pi.smul_apply]; rw [smul_comm] + congr + exact leviCivitaRhs'_smulY_const_apply hX hY hZ + +variable {I} in +lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : โ„} + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I X (a โ€ข Y) Z = a โ€ข leviCivitaRhs I X Y Z := by + ext x + exact leviCivitaRhs_smulY_const_apply (hX x) (hY x) (hZ x) + +lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (f โ€ข Y) Z x = + f x โ€ข leviCivitaRhs' I X Y Z x + + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) โ€ข 2 * โŸชY, ZโŸซ x := by + simp only [leviCivitaRhs'] + simp_rw [rhs_aux_smulX I Y Z X f] + simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] + rw [rhs_aux_smulY_apply I X hf hY hZ, rhs_aux_smulZ_apply I Z hf hX hY] + -- TODO: is there a better abstraction for this kind of "Lie bracket conv mode"? + have h1 : โŸชZ, mlieBracket I (f โ€ข Y) XโŸซ x = + - (fromTangentSpace _).toFun (((mfderiv% f x) (X x))) โ€ข โŸชZ, YโŸซ x + + f x โ€ข โŸชZ, mlieBracket I Y XโŸซ x := by + simp_rw [product_apply, mlieBracket_smul_left (W := X) hf hY, inner_add_right] + congr + ยท simp only [neg_smul, inner_neg_right, fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, + smul_eq_mul, neg_mul, neg_inj] + rw [real_inner_smul_right] + rfl + ยท rw [inner_smul_right_eq_smul] + have h2 : โŸชX, mlieBracket I Z (f โ€ข Y)โŸซ x = + (fromTangentSpace _).toFun (((mfderiv% f x) (Z x))) โ€ข โŸชX, YโŸซ x + + f x โ€ข โŸชX, mlieBracket I Z YโŸซ x := by + simp_rw [product_apply, mlieBracket_smul_right (V := Z) hf hY, inner_add_right] + congr + ยท simp only [fromTangentSpace, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul] + rw [real_inner_smul_right] + rfl + ยท rw [inner_smul_right_eq_smul] + rw [h1, h2, product_swap Y Z] + set A := rhs_aux I X Y Z x + set B := rhs_aux I Y Z X x + set C := rhs_aux I Z X Y x + set D := โŸชY, mlieBracket I X ZโŸซ x + set E := โŸชZ, mlieBracket I Y XโŸซ x + set F := โŸชX, mlieBracket I Z YโŸซ x + set G1 := โŸชY, ZโŸซ x + set G2 := โŸชX, YโŸซ x + set dfx := (mfderiv I ๐“˜(โ„, โ„) f x) + set H := (fromTangentSpace (f x)) (dfx (X x)) with H_eq + set K := (fromTangentSpace (f x)) (dfx (Z x)) with K_eq + change f x * A + (fromTangentSpace _).toFun (dfx (X x)) * G1 + f x * B + - (f x * C + (fromTangentSpace _).toFun (dfx (Z x)) * G2) + - f x * D - (-H * G1 + f x * E) + (K * G2 + f x * F) = _ + dsimp + rw [โ† H_eq, โ† K_eq] + ring + +lemma leviCivitaRhs_smulY_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (f โ€ข Y) Z x = + f x โ€ข leviCivitaRhs I X Y Z x + + ((fromTangentSpace _).toFun <| mfderiv% f x (X x)) โ€ข โŸชY, ZโŸซ x := by + simp only [leviCivitaRhs, Pi.smul_apply, leviCivitaRhs'_smulY_apply I hf hX hY hZ] + rw [smul_add, smul_comm] + congr 1 + rw [โ† smul_eq_mul] + dsimp + field_simp + +lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + leviCivitaRhs' I X Y (Z + Z') x = + leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X Y Z' x := by + simp only [leviCivitaRhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply, product_add_left_apply] + rw [product_congr_rightโ‚‚ (VectorField.mlieBracket_add_right (V := X) hZ hZ'), + product_congr_rightโ‚‚ (VectorField.mlieBracket_add_left (W := Y) hZ hZ'), + rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + abel + +lemma leviCivitaRhs'_addZ [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + leviCivitaRhs' I X Y (Z + Z') = + leviCivitaRhs' I X Y Z + leviCivitaRhs' I X Y Z' := by + ext x + exact leviCivitaRhs'_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) + +lemma leviCivitaRhs_addZ_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + leviCivitaRhs I X Y (Z + Z') x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X Y Z' x := by + simp [leviCivitaRhs, leviCivitaRhs'_addZ_apply I hX hY hZ hZ', left_distrib] + +lemma leviCivitaRhs_addZ [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + leviCivitaRhs I X Y (Z + Z') = leviCivitaRhs I X Y Z + leviCivitaRhs I X Y Z' := by + ext x + exact leviCivitaRhs_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) + +lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X Y (f โ€ข Z) x = f x โ€ข leviCivitaRhs' I X Y Z x := by + simp only [leviCivitaRhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] + -- Apply the product rule for the lie bracket. + -- Let's encapsulate the going into the product and back out again. + have h1 : โŸชY, mlieBracket I X (f โ€ข Z)โŸซ x = + f x โ€ข โŸชY, mlieBracket I X ZโŸซ x + โŸชY, fromTangentSpace _ (mfderiv% f x (X x)) โ€ข ZโŸซ x := by + rw [product_apply, VectorField.mlieBracket_smul_right hf hZ, inner_add_right, add_comm, + inner_smul_right] + congr + have h2 : letI dfY := fromTangentSpace _ ((mfderiv% f x) (Y x)); + โŸชX, mlieBracket I (f โ€ข Z) YโŸซ x = - dfY โ€ข โŸชX, ZโŸซ x + f x โ€ข โŸชX, mlieBracket I Z YโŸซ x := by + rw [product_apply, VectorField.mlieBracket_smul_left hf hZ, inner_add_right, inner_smul_right, + inner_smul_right] + congr + rw [h1, h2, product_smul_left, product_swap X Z] + erw [product_smul_right] + simp + -- set A := rhs_aux I X Y Z x + -- set B := rhs_aux I Y Z X x + -- set C := rhs_aux I Z X Y x + -- set D := โŸชY, mlieBracket I X ZโŸซ x + -- set E := โŸชZ, mlieBracket I Y XโŸซ x with E_eq + -- set F := โŸชX, mlieBracket I Z YโŸซ x + -- letI dfX : โ„ := (mfderiv I ๐“˜(โ„, โ„) f x) (X x) + -- set G := dfX * โŸชY, ZโŸซ x + -- letI dfY : โ„ := (mfderiv I ๐“˜(โ„, โ„) f x) (Y x) + -- set H := dfY * โŸชX, ZโŸซ x + ring + +lemma leviCivitaRhs'_smulZ [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs' I X Y (f โ€ข Z) = f โ€ข leviCivitaRhs' I X Y Z := by + ext x + exact leviCivitaRhs'_smulZ_apply I (hf x) (hX x) (hY x) (hZ x) + +lemma leviCivitaRhs_smulZ [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I X Y (f โ€ข Z) = f โ€ข leviCivitaRhs I X Y Z := by + simp only [leviCivitaRhs] + rw [smul_comm, leviCivitaRhs'_smulZ I hf hX hY hZ] + +lemma leviCivitaRhs_smulZ_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X Y (f โ€ข Z) x = f x * leviCivitaRhs I X Y Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_smulZ_apply I hf hX hY hZ] + ring + +end leviCivitaRhs + +variable [FiniteDimensional โ„ E] in +lemma aux (h : cov.IsLeviCivitaConnection) {x : M} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : rhs_aux I X Y Z x = + โŸชโˆ‡ Y, X, ZโŸซ x + โŸชY, โˆ‡ X, ZโŸซ x + โŸชY, VectorField.mlieBracket I X ZโŸซ x := by + trans โŸชโˆ‡ Y, X, ZโŸซ x + โŸชY, โˆ‡ Z, XโŸซ x + ยท exact cov.isCompatible_iff.mp h.1 hX hY hZ + ยท simp [โ† cov.torsion_eq_zero_iff.mp h.2 hX hZ, product, inner_sub_right] + +variable {cov} in +/-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term +โŸจโˆ‡ X Y, ZโŸฉ for all differentiable vector fields X, Y and Z, without reference to โˆ‡. -/ +lemma IsLeviCivitaConnection.eq_leviCivitaRhs [FiniteDimensional โ„ E] + (h : cov.IsLeviCivitaConnection) + {x : M} (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + โŸชโˆ‡ Y, X, ZโŸซ x = leviCivitaRhs I X Y Z x := by + unfold leviCivitaRhs leviCivitaRhs' + have eq1 := aux I cov h hX hY hZ + have eq2 := aux I cov h hY hZ hX + have eq3 := aux I cov h hZ hX hY + simp [real_inner_comm, smul_eq_mul] at * + linear_combination - (eq1 + eq2 - eq3) / 2 + +section + +omit [IsManifold I 2 M] [IsContMDiffRiemannianBundle I 1 E (TangentSpace I (M := M))] in +variable {I} in +lemma congr_of_forall_product_apply [FiniteDimensional โ„ E] {Y Y' : TangentSpace I x} + (h : โˆ€ Z : TangentSpace I x, inner โ„ Y Z = inner โ„ Y' Z) : Y = Y' := by + have : FiniteDimensional โ„ (TangentSpace I x) := inferInstanceAs (FiniteDimensional โ„ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete โ„ _ + set ฮฆ := InnerProductSpace.toDual โ„ (TangentSpace I x) + apply ฮฆ.injective + ext Zโ‚€ + simpa [ฮฆ, product] using h Zโ‚€ + +omit [IsContMDiffRiemannianBundle I 1 E (TangentSpace I (M := M))] in +variable {I} in +/-- If two vector fields `X` and `X'` on `M` satisfy the relation `โŸจX, ZโŸฉ = โŸจX', ZโŸฉ` for all +vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ +-- TODO: is this true if E is infinite-dimensional? trace the origin of the `Fintype` assumptions! +lemma congr_of_forall_product [FiniteDimensional โ„ E] + (h : โˆ€ Z : ฮ  x : M, TangentSpace I x, โŸชX, ZโŸซ = โŸชX', ZโŸซ) : X = X' := by + ext1 x + apply congr_of_forall_product_apply + intro Zโ‚€ + simpa [product] using congr($(h (extend E Zโ‚€)) x) + +/-- The Levi-Civita connection on `(M, g)` is uniquely determined, +at least on differentiable vector fields. -/ +-- (probably not everywhere, as addition rules apply only for differentiable vector fields?) +theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional โ„ E] + {cov cov' : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)} + (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) + {X Y : ฮ  x : M, TangentSpace I x} {x : M} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : + cov Y x (X x) = cov' Y x (X x) := by + have : FiniteDimensional โ„ (TangentSpace I x) := inferInstanceAs (FiniteDimensional โ„ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete โ„ _ + set ฮฆ := InnerProductSpace.toDual โ„ (TangentSpace I x) + apply ฮฆ.injective + ext Zโ‚€ + let Z := extend E Zโ‚€ + have hZ := mdifferentiableAt_extend I E Zโ‚€ + suffices inner โ„ (cov Y x (X x)) (Z x) = inner โ„ (cov' Y x (X x)) (Z x) by simpa [ฮฆ, Z] + trans leviCivitaRhs I X Y Z x + ยท rw [โ† hcov.eq_leviCivitaRhs I hX hY hZ] + ยท rw [โ† hcov'.eq_leviCivitaRhs I hX hY hZ] + +open Classical in +noncomputable def lcAuxโ‚€' (Y : ฮ  x : M, TangentSpace I x) (x : M) + (X Z : ฮ  x : M, TangentSpace I x) := + if MDiffAt (T% X) x then if MDiffAt (T% Z) x then + leviCivitaRhs I X Y Z + else 0 else 0 + +theorem leviCivitaRhs_tensorialโ‚ [FiniteDimensional โ„ E] + {Y : ฮ  x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) (Z : ฮ  x, TangentSpace I x) : + TensorialAt I E (lcAuxโ‚€' I Y x ยท Z x) x where + smul hf hX := by + dsimp [lcAuxโ‚€'] + rw [if_pos hX, if_pos] + ยท split_ifs with hZ + ยท exact leviCivitaRhs_smulX_apply hf hX hY hZ + ยท simp + ยท exact hf.smul_section hX + add hXโ‚ hXโ‚‚ := by + dsimp [lcAuxโ‚€'] + rw [if_pos hXโ‚, if_pos hXโ‚‚, if_pos] + ยท split_ifs with hZ + ยท exact leviCivitaRhs_addX_apply I hXโ‚ hXโ‚‚ hY hZ + ยท simp + ยท exact mdifferentiableAt_add_section hXโ‚ hXโ‚‚ + +theorem leviCivitaRhs_tensorialโ‚‚ [FiniteDimensional โ„ E] + {Y : ฮ  x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) (X : ฮ  x, TangentSpace I x) + (hX : MDiffAt (T% X) x) : + TensorialAt I E (lcAuxโ‚€' I Y x X ยท x) x where + smul hf hZ := by + dsimp [lcAuxโ‚€'] + rw [if_pos hX, if_pos hZ, if_pos, if_pos hX] + ยท exact leviCivitaRhs_smulZ_apply I hf hX hY hZ + ยท exact hf.smul_section hZ + add hZโ‚ hZโ‚‚ := by + dsimp [lcAuxโ‚€'] + rw [if_pos hZโ‚, if_pos hZโ‚‚, if_pos hX, if_pos, if_pos hX, if_pos hX] + ยท exact leviCivitaRhs_addZ_apply I hX hY hZโ‚ hZโ‚‚ + ยท exact mdifferentiableAt_add_section hZโ‚ hZโ‚‚ + +open Classical in +noncomputable def lcAuxโ‚€ [FiniteDimensional โ„ E] + {Y : ฮ  x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : + TangentSpace I x โ†’L[โ„] TangentSpace I x โ†’L[โ„] โ„ := + TensorialAt.mkHomโ‚‚ _ (x := x) + (fun Z _ โ†ฆ leviCivitaRhs_tensorialโ‚ _ _ hY Z) + (fun X hX โ†ฆ leviCivitaRhs_tensorialโ‚‚ _ _ hY X hX) + +theorem lcAuxโ‚€_apply [FiniteDimensional โ„ E] {x : M} + {X : ฮ  x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : ฮ  x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : ฮ  x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + lcAuxโ‚€ I x hY (X x) (Z x) = leviCivitaRhs I X Y Z x := by + unfold lcAuxโ‚€ + rw [TensorialAt.mkHomโ‚‚_apply _ _ hX hZ, lcAuxโ‚€', if_pos hX, if_pos hZ] + +noncomputable def lcAuxโ‚ [FiniteDimensional โ„ E] + {Y : ฮ  x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) : + TangentSpace I x โ†’L[โ„] TangentSpace I x := + -- use the musical isomorphism to produce a candidate โˆ‡ Y as a (1,1)-tensor + -- (rather than a 2-tensor) + have : FiniteDimensional โ„ (TangentSpace I x) := inferInstanceAs (FiniteDimensional โ„ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete โ„ _ + (InnerProductSpace.toDual โ„ _).symm.toContinuousLinearEquiv.toContinuousLinearMap โˆ˜L + (lcAuxโ‚€ I x hY) + +theorem lcAuxโ‚_apply [FiniteDimensional โ„ E] {x : M} + {X : ฮ  x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : ฮ  x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : ฮ  x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + inner โ„ (lcAuxโ‚ I x hY (X x)) (Z x) = leviCivitaRhs I X Y Z x := by + simpa [lcAuxโ‚] using lcAuxโ‚€_apply I hX hY hZ + +open Classical in +noncomputable def lcAux [FiniteDimensional โ„ E] + (Y : ฮ  x : M, TangentSpace I x) (x : M) : + TangentSpace I x โ†’L[โ„] TangentSpace I x := + if hY : MDiffAt (T% Y) x then lcAuxโ‚ I x hY else 0 + +theorem lcAux_apply [FiniteDimensional โ„ E] {x : M} + {X : ฮ  x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : ฮ  x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : ฮ  x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + inner โ„ (lcAux I Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := by + unfold lcAux + rw [dif_pos hY] + simpa [lcAux] using lcAuxโ‚_apply I hX hY hZ + +lemma isCovariantDerivativeOn_lcAux [FiniteDimensional โ„ E] : + IsCovariantDerivativeOn E (lcAux I (M := M)) where + add {Y Y'} x hY hY' _ := by + unfold lcAux + rw [dif_pos hY, dif_pos hY', dif_pos (mdifferentiableAt_add_section hY hY')] + unfold lcAuxโ‚ + dsimp + rw [โ† ContinuousLinearMap.comp_add] + congr! 1 + simp only [lcAuxโ‚€] + ext Xโ‚€ Yโ‚€ + simp only [TensorialAt.mkHomโ‚‚_apply_eq_extend, ContinuousLinearMap.add_apply, lcAuxโ‚€'] + rw [if_pos, if_pos, if_pos, if_pos, if_pos, if_pos] + ยท exact leviCivitaRhs_addY_apply _ (FiberBundle.mdifferentiableAt_extend ..) + hY hY' (FiberBundle.mdifferentiableAt_extend ..) + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + leibniz {Y f x} hY hf _ := by + dsimp [lcAux] + rw [dif_pos hY, dif_pos] + ยท unfold lcAuxโ‚ + dsimp + rw [โ† ContinuousLinearMap.comp_smul] + have : FiniteDimensional โ„ (TangentSpace I x) := inferInstanceAs (FiniteDimensional โ„ E) + have : CompleteSpace (TangentSpace I x) := FiniteDimensional.complete โ„ _ + set ฮฆ := InnerProductSpace.toDual โ„ (TangentSpace I x) + ext Xโ‚€ + apply ฮฆ.injective + simp only [ContinuousLinearMap.coe_comp', ContinuousLinearEquiv.coe_coe, + LinearIsometryEquiv.coe_symm_toContinuousLinearEquiv, comp_apply, + LinearIsometryEquiv.apply_symm_apply, ContinuousLinearMap.comp_smulโ‚›โ‚—, RingHom.id_apply, + ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, + map_add, map_smul] + ext Zโ‚€ + simp only [lcAuxโ‚€, lcAuxโ‚€', TensorialAt.mkHomโ‚‚_apply_eq_extend, + ContinuousLinearMap.add_apply, ContinuousLinearMap.coe_smul', Pi.smul_apply, smul_eq_mul] + rw [if_pos, if_pos, if_pos, if_pos] + ยท convert leviCivitaRhs_smulY_apply I hf (FiberBundle.mdifferentiableAt_extend I E Xโ‚€) hY + (FiberBundle.mdifferentiableAt_extend I E Zโ‚€) + simp [ฮฆ, product] + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + ยท exact FiberBundle.mdifferentiableAt_extend .. + exact MDifferentiableAt.smul_section hf hY + +end + +-- TODO: make g part of the notation! +variable (M) in +/-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: +this is unique up to the value on non-differentiable vector fields. +If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ +noncomputable def LeviCivitaConnection [FiniteDimensional โ„ E] : + CovariantDerivative I E (TangentSpace I : M โ†’ Type _) where + toFun := lcAux I + isCovariantDerivativeOnUniv := isCovariantDerivativeOn_lcAux I + +theorem leviCivitaConnection_apply [FiniteDimensional โ„ E] {x : M} + {X : ฮ  x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {Y : ฮ  x : M, TangentSpace I x} (hY : MDiffAt (T% Y) x) + {Z : ฮ  x : M, TangentSpace I x} (hZ : MDiffAt (T% Z) x) : + inner โ„ (LeviCivitaConnection I M Y x (X x)) (Z x) = leviCivitaRhs I X Y Z x := + lcAux_apply _ hX hY hZ + +-- Side computation for `leviCivitaConnection_isCompatible`. +omit [IsManifold I 2 M] in +lemma leviCivitaConnection_isCompatible_aux + {x : M} {X Y Z : (x : M) โ†’ TangentSpace I x} : + leviCivitaRhs I X Y Z x + leviCivitaRhs I X Z Y x = + fromTangentSpace _ ((mfderiv% fun x โ†ฆ inner โ„ (Y x) (Z x)) x (X x)) := by + simp only [leviCivitaRhs, Pi.smul_apply, โ† smul_add, leviCivitaRhs'] + -- Normalise the expressions by swapping arguments for rhs_aux and mlieBracket, + -- until the swappable arguments are in order X < Y < Z. + rw [rhs_aux_swap I Z Y, rhs_aux_swap I Z X, rhs_aux_swap I Y X, + VectorField.mlieBracket_swap (V := Z) (W := Y), + VectorField.mlieBracket_swap (V := Y) (W := X), + VectorField.mlieBracket_swap (V := Z) (W := X)] + -- Observe that the right hand side is rhx_aux X Y Z; then we just need to simplify and rearrange. + trans 1 / 2 * (rhs_aux I X Y Z x + rhs_aux I X Y Z x) + ยท simp + abel + ยท rw [โ† two_mul, โ† mul_assoc, one_div, inv_mul_cancelโ‚€ (by simp), one_mul] + rfl + +-- Why is everything so slow? +lemma leviCivitaConnection_isCompatible [FiniteDimensional โ„ E] : + (LeviCivitaConnection I M).IsCompatible := by + rw [isCompatible_iff] + intro x X Y Z hX hY hZ + symm + unfold product + dsimp + rw [leviCivitaConnection_apply I hX hY hZ] + have : inner โ„ (Y x) (((LeviCivitaConnection I M) Z x) (X x)) = + inner โ„ (((LeviCivitaConnection I M) Z x) (X x)) (Y x) := by + rw [real_inner_comm] + -- TODO: why does the following line not work, but `rw [this]` does? + --rw [real_inner_comm] + rw [this] + have : inner โ„ (((LeviCivitaConnection I M) Z x) (X x)) (Y x) = leviCivitaRhs I X Z Y x := by + rw [leviCivitaConnection_apply I hX hZ hY] + rw [leviCivitaConnection_apply I hX hZ hY, leviCivitaConnection_isCompatible_aux] + +lemma leviCivitaConnection_torsion_eq_zero [FiniteDimensional โ„ E] : + (LeviCivitaConnection I M).torsion = 0 := by + have a := (LeviCivitaConnection I M).isCovariantDerivativeOnUniv + rw [CovariantDerivative.torsion_eq_zero_iff] + intro X Y x hX hY + apply congr_of_forall_product_apply + intro Z + trans (inner โ„ (((LeviCivitaConnection I M) Y x) (X x)) Z) - + (inner โ„ (((LeviCivitaConnection I M) X x) (Y x)) Z) + ยท apply inner_sub_left + have hZ' : extend E Z x = Z := extend_apply_self E Z + rw [โ† hZ'] + rw [leviCivitaConnection_apply I hY hX (mdifferentiableAt_extend ..)] + rw [leviCivitaConnection_apply I hX hY (mdifferentiableAt_extend ..)] + simp only [leviCivitaRhs_apply] + -- XXX: should there be leviCivitaRhs'_apply? + simp only [leviCivitaRhs', Pi.add_apply, Pi.sub_apply, product_apply] + simp only [VectorField.mlieBracket_swap (V := Y) (W := X)] + simp only [Pi.neg_apply, inner_neg_right, sub_neg_eq_add] + set C := inner โ„ Z (VectorField.mlieBracket I X Y x) + set Z' := extend E Z + simp only [VectorField.mlieBracket_swap (V := Z') (W := X)] + simp only [VectorField.mlieBracket_swap (V := Z') (W := Y)] + simp only [Pi.neg_apply, inner_neg_right] + rw [rhs_aux_swap (Y := Z'), rhs_aux_swap (Y := Z'), rhs_aux_swap (X := Z')] + rw [real_inner_comm (Z' x) (VectorField.mlieBracket I X Y x)] + -- set A := inner โ„ (Z' x) (VectorField.mlieBracket I X Y x) + -- set B := inner โ„ (Y x) (VectorField.mlieBracket I X Z' x) + -- set C := inner โ„ (X x) (VectorField.mlieBracket I Y Z' x) + -- set D := rhs_aux I X Y Z' x + -- set E := rhs_aux I Y X Z' x + -- set F := rhs_aux I Z' X Y x + match_scalars <;> simp + norm_num + +/-- `LeviCivitaConnection` is a Levi-Civita connection (i.e., compatible and torsion-free) -/ +lemma leviCivitaConnection_isLeviCivitaConnection [FiniteDimensional โ„ E] : + (LeviCivitaConnection I M).IsLeviCivitaConnection := + โŸจleviCivitaConnection_isCompatible I, leviCivitaConnection_torsion_eq_zero IโŸฉ + +end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean new file mode 100644 index 00000000000000..3fd2e5a3696bab --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -0,0 +1,196 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Heather Macbeth, Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Ehresmann + +/-! +# Lifting vectors using covariant derivatives + +TODO: add a more complete doc-string + +-/ + +@[expose] public section + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +section +variable + {๐•œ : Type*} [NontriviallyNormedField ๐•œ] [CompleteSpace ๐•œ] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + [FiniteDimensional ๐•œ F] [IsManifold I 1 M] + {cov : (M โ†’ F) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + + +noncomputable +def IsCovariantDerivativeOn.lift_vec (x : M) (f : F) : + TangentSpace I x โ†’L[๐•œ] TangentSpace I x ร— F := + .prod (.id ๐•œ _) (-hcov.one_form x f) + +@[simp] +lemma IsCovariantDerivativeOn.lift_vec_apply (x : M) (f : F) (u : TangentSpace I x) : + hcov.lift_vec x f u = (u , -hcov.one_form x f u) := + rfl + +@[simp] +lemma IsCovariantDerivativeOn.fst_comp_lift_vec (x : M) (f : F) : + .fst ๐•œ _ _ โˆ˜L hcov.lift_vec x f = .id ๐•œ _ := by + ext u + simp + +@[simp] +lemma IsCovariantDerivativeOn.projection_lift_vec (x : M) (f : F) : + (hcov.projection x f) โˆ˜L (hcov.lift_vec x f) = 0 := by + ext u + simp + +lemma IsCovariantDerivativeOn.lift_vec_mem_horiz (x : M) (f : F) (u : TangentSpace I x) : + hcov.lift_vec x f u โˆˆ hcov.horiz x f := by + rw [horiz] + simp + +lemma IsCovariantDerivativeOn.lift_vec_eq_iff + {x : M} {f : F} {u : TangentSpace I x} {w : TangentSpace I x ร— F} : + hcov.lift_vec x f u = w โ†” hcov.projection x f w = 0 โˆง w.1 = u := by + constructor + ยท intro rfl + simp + ยท rcases w with โŸจa, bโŸฉ + rintro โŸจh, rflโŸฉ + simp_all + grind + +end + +section +variable + {๐•œ : Type*} [NontriviallyNormedField ๐•œ] [CompleteSpace ๐•œ] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] {V : M โ†’ Type*} + [TopologicalSpace (TotalSpace F V)] [(x : M) โ†’ AddCommGroup (V x)] [(x : M) โ†’ Module ๐•œ (V x)] + [(x : M) โ†’ TopologicalSpace (V x)] [FiberBundle F V] + [โˆ€ (x : M), IsTopologicalAddGroup (V x)] [โˆ€ (x : M), ContinuousSMul ๐•œ (V x)] + [FiniteDimensional ๐•œ F] + [IsManifold I 1 M] [VectorBundle ๐•œ F V] {cov : CovariantDerivative I F V} + [ContMDiffVectorBundle 1 F V I] + +/-- Horizontal lift of a vector tangent to the base at a point in the corresponding fiber. -/ +noncomputable +def CovariantDerivative.lift_vec (v : TotalSpace F V) : + TangentSpace I v.proj โ†’L[๐•œ] TangentSpace (I.prod ๐“˜(๐•œ, F)) v := + letI t := trivializationAt F V v.proj + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + letI tlift := hcov.lift_vec v.proj (t v).2 + t.derivInv I v โˆ˜L tlift + +lemma CovariantDerivative.lift_vec_apply {v : TotalSpace F V} (u : TangentSpace I v.proj) : + letI t := trivializationAt F V v.proj + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer t + letI tlift := hcov.lift_vec v.proj (t v).2 + cov.lift_vec v u = t.derivInv I v (tlift u) := rfl + +@[simp] +lemma CovariantDerivative.lift_vec_mem_horiz {v : TotalSpace F V} (u : TangentSpace I v.proj) : + cov.lift_vec v u โˆˆ cov.horiz v := by + let t := trivializationAt F V v.proj + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + let tlift := hcov.lift_vec v.proj (t v).2 + rw [lift_vec_apply, CovariantDerivative.mem_horiz_iff_proj] + -- TODO: cleanup + simp only [proj, IsCovariantDerivativeOn.lift_vec_apply, ContinuousLinearMap.coe_comp', + Trivialization.symmL_apply, Function.comp_apply] + rw [t.deriv_derivInv_apply (FiberBundle.mem_baseSet_trivializationAt' v.proj)] + suffices t.symm v.proj 0 = 0 by simpa + exact (t.symmL ๐•œ v.proj).map_zero + +@[simp] +lemma CovariantDerivative.proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : + cov.proj v (cov.lift_vec v u) = 0 := by + rw [โ† cov.mem_horiz_iff_proj] + exact lift_vec_mem_horiz u + +@[simp] +lemma CovariantDerivative.mfderiv_proj_lift_vec {v : TotalSpace F V} (u : TangentSpace I v.proj) : + mfderiv (I.prod ๐“˜(๐•œ, F)) I TotalSpace.proj v (cov.lift_vec v u) = u := by + unfold CovariantDerivative.lift_vec + simp [FiberBundle.mem_baseSet_trivializationAt' v.proj] + +lemma CovariantDerivative.lift_vec_eq_iff {v : TotalSpace F V} (u : TangentSpace I v.proj) + (w : TangentSpace (I.prod ๐“˜(๐•œ, F)) v) : + cov.lift_vec v u = w โ†” + cov.proj v w = 0 โˆง + mfderiv (I.prod ๐“˜(๐•œ, F)) I (TotalSpace.proj : TotalSpace F V โ†’ M) v w = u := by + constructor + ยท rintro rfl + simp + ยท rintro โŸจh, h'โŸฉ + let t := trivializationAt F V v.proj + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + have mem := FiberBundle.mem_baseSet_trivializationAt F V v.proj + apply (t.bijective_deriv mem).1 + unfold CovariantDerivative.lift_vec + simp only [ContinuousLinearMap.coe_comp', Function.comp_apply] + rw [t.deriv_derivInv_apply mem] + rw [hcov.lift_vec_eq_iff] + constructor + ยท change t.symm v.proj ((hcov.projection v.proj (t v).2) ((t.deriv I v) w)) = 0 at h + apply t.injective_symm mem + refold_let t + simp [h, t.symm_map_zero ๐•œ] + ยท rw [โ† h', t.mfderiv_proj_fst_deriv mem] + +lemma CovariantDerivative.lift_vec_eq_iff' {v : TotalSpace F V} (u : TangentSpace I v.proj) + (w : TangentSpace (I.prod ๐“˜(๐•œ, F)) v) : + cov.lift_vec v u = w โ†” + w โˆˆ cov.horiz v โˆง + mfderiv (I.prod ๐“˜(๐•œ, F)) I (TotalSpace.proj : TotalSpace F V โ†’ M) v w = u := by + simp [CovariantDerivative.lift_vec_eq_iff, horiz] + +/-- We can compute `lift_vec v` using any trivialization whose +base set contains `v.proj`. This is crucial to prove smoothness +of `lift_vec`. -/ +lemma CovariantDerivative.lift_vec_eq [FiniteDimensional ๐•œ E] {v : TotalSpace F V} + {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] + (hv : v.proj โˆˆ e.baseSet) + (u : TangentSpace I v.proj) : + haveI hcov := cov.isCovariantDerivativeOn_pushCovDer e + cov.lift_vec v u = e.derivInv I v (hcov.lift_vec v.proj (e v).2 u) := by + apply (cov.lift_vec_eq_iff' _ _).mpr โŸจ?_, ?_โŸฉ + ยท rw [cov.mem_horiz_iff_exists] + have hcov := cov.isCovariantDerivativeOn_pushCovDer e + have := hcov.lift_vec_mem_horiz v.proj (e v).2 u + rw [hcov.mem_horiz_iff_exists] at this + have proj_lift : (hcov.lift_vec v.proj (e v).2 u).1 = u := by simp + rcases this with โŸจs, sdiff, sval, mfderivs, covsโŸฉ + -- TODO: cleanup the proof below and see how to factor stuff in + -- `CovariantDerivative.mem_horiz_iff_exists` + use e.funToSec s, ?_, ?_, ?_, ?_ + ยท exact e.mdifferentiableAt_funToSec hv sdiff + ยท simp [sval, hv] + ยท rw [e.mfderiv_total_funToSec sdiff hv] + simp only [TotalSpace.proj_mk', ContinuousLinearMap.coe_comp', Function.comp_apply, + ContinuousLinearMap.prod_apply, ContinuousLinearMap.coe_id', id_eq] + congr 2 + ยท simp [e.funToSec_proj_eq hv sval] + ยท simp [e.mfderiv_proj_fst_deriv, hv] + ยท simp only [hv, e.mfderiv_proj_derivInv_apply, ContinuousLinearMap.coe_neg, + LinearMap.neg_apply, ContinuousLinearMap.coe_coe] + rw [proj_lift] at mfderivs โŠข + erw [mfderivs] + simp + ยท rw [proj_lift] at covs + simp [e.pushCovDer_funToSec cov, e.mfderiv_proj_fst_deriv hv, e.deriv_derivInv_apply hv, covs, + e.symm_map_zero ๐•œ] + ยท simp [hv] + +end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean new file mode 100644 index 00000000000000..7f9e7ae75a2757 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -0,0 +1,291 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang, Heather Macbeth +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace + +/-! # Metric connections + +This file defines connections on a Riemannian vector bundle which are compatible with the ambient +metric. A bundled connection `โˆ‡` on a Riemannian vector bundle `(V, g)` is compatible with the +metric `g` if and only if the differentiated metric tensor `โˆ‡ g` (defined by +`(X, ฯƒ, ฯ„) โ†ฆ โˆ‡_X g(ฯƒ, ฯ„) - g(โˆ‡_X ฯƒ, ฯ„) - g(ฯƒ, โˆ‡_X ฯ„)`) vanishes on all differentiable vector fields +`X` and differentiable sections `ฯƒ`, `ฯ„`. + +## Main definitions and results + +* `CovariantDerivative.compatibilityTensor`: the tensor + `(X, ฯƒ, ฯ„) โ†ฆ X g(ฯƒ, ฯ„) - g(โˆ‡_X ฯƒ, ฯ„) - g(ฯƒ, โˆ‡_X ฯ„)` defining when a connection `โˆ‡` on a Riemannian + vector bundle `(V, g)` is compatible with the metric `g`. +* `CovariantDerivative.compatibilityTensor_apply` and + `CovariantDerivative.compatibilityTensor_apply` give formulas for applying the compatibility + tensor at `x` to vector fields and sections which are differentiable at `x`, + resp. to extensions of tangent vectors and sections at `x` to differentiable vector fields and + sections near `x`. +* `CovariantDerivative.IsCompatible`: predicate for a connection to be metric, namely that + `โˆ‡` is metric iff its `compatibilityTensor` vanishes + +## TODO + +* When Mathlib has a notion of parallel transport, prove the equivalence of + `CovariantDerivative.IsCompatible` with the characterisation that parallel transport be an + isometry. + +* Given connections on bundles `V` and `W`, there is an induced connnection on the bundle Hom(V, W). + When this induced connection has been defined in Mathlib, rephrase the definition of + `CovariantDerivative.compatibilityTensor`, to be simply the covariant derivative of the metric + tensor (considered as a section of Hom(V, Hom(V, โ„))). + +-/ +open Bundle NormedSpace +open scoped Manifold ContDiff + +@[expose] public section + +-- TODO: revisit and fix this once the dust has settled +set_option backward.isDefEq.respectTransparency false + +variable + -- Let `M` be a `C^k` real manifold modeled on `(E, H)` + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners โ„ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + -- Let `V` be a bundle over `M`, endowed with a Riemannian metric. + (F : Type*) [NormedAddCommGroup F] [NormedSpace โ„ F] + {V : M โ†’ Type*} [TopologicalSpace (TotalSpace F V)] + [โˆ€ x, AddCommGroup (V x)] [โˆ€ x, Module โ„ (V x)] + [โˆ€ x : M, TopologicalSpace (V x)] + [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul โ„ (V x)] + [FiberBundle F V] [RiemannianBundle V] + +/-! # Compatible connections + +A connection on `V` is compatible with the metric on `V` iff `X โŸจฯƒ, ฯ„โŸฉ = โŸจโˆ‡_X ฯƒ, ฯ„โŸฉ + โŸจฯƒ, โˆ‡_X ฯ„โŸฉ` +holds for all sufficiently nice vector fields `X` on `M` and sections `ฯƒ`, `ฯ„` of `V`. +The left hand side is the pushforward of the function `โŸจฯƒ, ฯ„โŸฉ` along the vector field `X`: +the left hand side at `x` is `df(X x)`, where `f := โŸจฯƒ, ฯ„โŸฉ` (ie. `X` is seen a derivation on +the algebra of function on the base manifold acting on the function `โŸจฯƒ, ฯ„โŸฉ`). +In our definition, we ask for this identity to at each `x : M`, whenever `X`, `ฯƒ` and `ฯ„` are +differentiable at `x`. +-/ + +variable {ฯƒ ฯƒ' ฯƒ'' ฯ„ ฯ„' ฯ„'' : ฮ  x : M, V x} + +-- set_option trace.profiler true +-- set_option profiler.threshold 500 + +/-- The scalar product of two sections. -/ +noncomputable abbrev product (ฯƒ ฯ„ : ฮ  x : M, V x) : M โ†’ โ„ := + fun x โ†ฆ inner โ„ (ฯƒ x) (ฯ„ x) + +-- `product` is C^k if ฯƒ and ฯ„ are: this is shown in `Riemannian.lean` + +local notation "โŸช" ฯƒ ", " ฯ„ "โŸซ" => product ฯƒ ฯ„ + +-- Basic API for the product of two sections. +section product + +omit [TopologicalSpace M] + +lemma product_apply (x) : โŸชฯƒ, ฯ„โŸซ x = inner โ„ (ฯƒ x) (ฯ„ x) := rfl + +variable (ฯƒ ฯƒ' ฯ„) + +lemma product_swap : โŸชฯ„, ฯƒโŸซ = โŸชฯƒ, ฯ„โŸซ := by + ext x + apply real_inner_comm + +@[simp] +lemma product_zero_left : โŸช0, ฯƒโŸซ = 0 := by + ext x + simp only [product, Pi.zero_apply, inner_zero_left] + +@[simp] +lemma product_zero_right : โŸชฯƒ, 0โŸซ = 0 := by rw [product_swap, product_zero_left] + +lemma product_add_left : โŸชฯƒ + ฯƒ', ฯ„โŸซ = โŸชฯƒ, ฯ„โŸซ + โŸชฯƒ', ฯ„โŸซ := by + ext x + simp [product, InnerProductSpace.add_left] + +@[simp] +lemma product_add_left_apply (x) : โŸชฯƒ + ฯƒ', ฯ„โŸซ x = โŸชฯƒ, ฯ„โŸซ x + โŸชฯƒ', ฯ„โŸซ x := by + simp [product, InnerProductSpace.add_left] + +lemma product_add_right : โŸชฯƒ, ฯ„ + ฯ„'โŸซ = โŸชฯƒ, ฯ„โŸซ + โŸชฯƒ, ฯ„'โŸซ := by + rw [product_swap, product_swap ฯ„, product_swap ฯ„', product_add_left] + +@[simp] +lemma product_add_right_apply (x) : โŸชฯƒ, ฯ„ + ฯ„'โŸซ x = โŸชฯƒ, ฯ„โŸซ x + โŸชฯƒ, ฯ„'โŸซ x := by + rw [product_swap, product_swap ฯ„, product_swap ฯ„', product_add_left_apply] + +@[simp] lemma product_neg_left : โŸช-ฯƒ, ฯ„โŸซ = -โŸชฯƒ, ฯ„โŸซ := by ext x; simp [product] + +@[simp] lemma product_neg_right : โŸชฯƒ, -ฯ„โŸซ = -โŸชฯƒ, ฯ„โŸซ := by ext x; simp [product] + +lemma product_sub_left : โŸชฯƒ - ฯƒ', ฯ„โŸซ = โŸชฯƒ, ฯ„โŸซ - โŸชฯƒ', ฯ„โŸซ := by + ext x + simp [product, inner_sub_left] + +lemma product_sub_right : โŸชฯƒ, ฯ„ - ฯ„'โŸซ = โŸชฯƒ, ฯ„โŸซ - โŸชฯƒ, ฯ„'โŸซ := by + ext x + simp [product, inner_sub_right] + +lemma product_smul_left (f : M โ†’ โ„) : product (f โ€ข ฯƒ) ฯ„ = f โ€ข product ฯƒ ฯ„ := by + ext x + simp [product, real_inner_smul_left] + +@[simp] +lemma product_smul_const_left (a : โ„) : product (a โ€ข ฯƒ) ฯ„ = a โ€ข product ฯƒ ฯ„ := by + ext x + simp [product, real_inner_smul_left] + +lemma product_smul_right (f : M โ†’ โ„) : product ฯƒ (f โ€ข ฯ„) = f โ€ข product ฯƒ ฯ„ := by + ext x + simp [product, real_inner_smul_right] + +@[simp] +lemma product_smul_const_right (a : โ„) : product ฯƒ (a โ€ข ฯ„) = a โ€ข product ฯƒ ฯ„ := by + ext x + simp [product, real_inner_smul_right] + +end product + +-- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) +-- only hold point-wise. They abstract the expanding and unexpanding of `product`. +omit [TopologicalSpace M] in +lemma product_congr_left {x} (h : ฯƒ x = ฯƒ' x) : product ฯƒ ฯ„ x = product ฯƒ' ฯ„ x := by + rw [product_apply, h, โ† product_apply] + +omit [TopologicalSpace M] in +lemma product_congr_leftโ‚‚ {x} (h : ฯƒ x = ฯƒ' x + ฯƒ'' x) : + product ฯƒ ฯ„ x = product ฯƒ' ฯ„ x + product ฯƒ'' ฯ„ x := by + rw [product_apply, h, inner_add_left, โ† product_apply] +omit [TopologicalSpace M] in +lemma product_congr_right {x} (h : ฯ„ x = ฯ„' x) : product ฯƒ ฯ„ x = product ฯƒ ฯ„' x := by + rw [product_apply, h, โ† product_apply] + +omit [TopologicalSpace M] in +lemma product_congr_rightโ‚‚ {x} (h : ฯ„ x = ฯ„' x + ฯ„'' x) : + product ฯƒ ฯ„ x = product ฯƒ ฯ„' x + product ฯƒ ฯ„'' x := by + rw [product_apply, h, inner_add_right, โ† product_apply] + +namespace CovariantDerivative + +-- Let `cov` be a covariant derivative on `V`. +-- TODO: include in cheat sheet! +variable (cov : CovariantDerivative I F V) + + +/-- Local notation for a covariant derivative on a vector bundle acting on a vector field and a +section. -/ +local syntax "โˆ‡" term:arg term : term +local macro_rules | `(โˆ‡ $X $ฯƒ) => `(fun (x : M) โ†ฆ cov $ฯƒ x ($X x)) + +variable {F} + +/-- The function defining the compatibility tensor for `โˆ‡` w.r.t. `g`: +prefer using `compatibilityTensor` instead -/ +noncomputable def compatibilityTensorAux (ฯƒ ฯ„ : ฮ  x : M, V x) : + ฮ  (x : M), TangentSpace I x โ†’L[โ„] โ„ := fun x โ†ฆ + (NormedSpace.fromTangentSpace _).toContinuousLinearMap โˆ˜L mfderiv% โŸชฯƒ, ฯ„โŸซ x + - ((innerSL โ„ (ฯ„ x)) โˆ˜L (cov ฯƒ x)) - ((innerSL โ„ (ฯƒ x)) โˆ˜L (cov ฯ„ x)) + +lemma compatibilityTensorAux_apply (ฯƒ ฯ„ : ฮ  x : M, V x) + {x : M} (Xโ‚€ : TangentSpace I x) : + compatibilityTensorAux I cov ฯƒ ฯ„ x Xโ‚€ = + NormedSpace.fromTangentSpace _ (mfderiv% โŸชฯƒ, ฯ„โŸซ x Xโ‚€) + - inner โ„ (cov ฯƒ x Xโ‚€) (ฯ„ x) - inner โ„ (ฯƒ x) (cov ฯ„ x Xโ‚€) := by + rw [real_inner_comm] + rfl + +variable [VectorBundle โ„ F V] [IsContMDiffRiemannianBundle I 1 F V] {x : M} + +theorem compatibilityTensorAux_tensorialโ‚ (ฯ„ : ฮ  x, V x) (hฯ„ : MDiffAt (T% ฯ„) x) : + TensorialAt I F (compatibilityTensorAux I cov ยท ฯ„ x) x where + smul hf hฯƒ := by + ext Xโ‚€ + rw [compatibilityTensorAux_apply, product_smul_left, + fromTangentSpace_mfderiv_smul_apply hf (hฯƒ.inner_bundle hฯ„)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hฯƒ hf, inner_add_left, + inner_smul_left] + ring + add hฯƒ hฯƒ' := by + ext Xโ‚€ + rw [compatibilityTensorAux_apply, product_add_left, + fromTangentSpace_mfderiv_add_apply (hฯƒ.inner_bundle hฯ„) (hฯƒ'.inner_bundle hฯ„)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hฯƒ hฯƒ', inner_add_left] + abel + +theorem compatibilityTensorAux_tensorialโ‚‚ (ฯƒ : ฮ  x, V x) (hฯƒ : MDiffAt (T% ฯƒ) x) : + TensorialAt I F (compatibilityTensorAux I cov ฯƒ ยท x) x where + smul hf hฯ„ := by + ext Xโ‚€ + rw [compatibilityTensorAux_apply, product_smul_right, + fromTangentSpace_mfderiv_smul_apply hf (hฯƒ.inner_bundle hฯ„)] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.leibniz hฯ„ hf, inner_add_right, + inner_smul_right] + ring + add hฯ„ hฯ„' := by + ext Xโ‚€ + rw [compatibilityTensorAux_apply, product_add_right, + fromTangentSpace_mfderiv_add_apply (hฯƒ.inner_bundle hฯ„) (hฯƒ.inner_bundle hฯ„')] + simp [compatibilityTensorAux_apply, cov.isCovariantDerivativeOn.add hฯ„ hฯ„', inner_add_right] + abel + +variable {I} [ContMDiffVectorBundle 1 F V I] in +/-- The tensor `(X, ฯƒ, ฯ„) โ†ฆ X g(ฯƒ, ฯ„) - g(โˆ‡_X ฯƒ, ฯ„) - g(ฯƒ, โˆ‡_X ฯ„)` defining when a connection +`โˆ‡` on a Riemannian bundle `(M, V)` is compatible with the metric `g`. -/ +@[no_expose] noncomputable def compatibilityTensor [FiniteDimensional โ„ F] (x : M) : + V x โ†’L[โ„] V x โ†’L[โ„] (TangentSpace I x โ†’L[โ„] โ„) := + TensorialAt.mkHomโ‚‚ (compatibilityTensorAux I cov ยท ยท x) _ + (compatibilityTensorAux_tensorialโ‚ I cov) (compatibilityTensorAux_tensorialโ‚‚ I cov) + +variable {X : ฮ  x : M, TangentSpace I x} + +variable {I} [ContMDiffVectorBundle 1 F V I] in +theorem compatibilityTensor_apply [FiniteDimensional โ„ F] (x : M) + (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯ„ : MDiffAt (T% ฯ„) x) : + cov.compatibilityTensor x (ฯƒ x) (ฯ„ x) (X x) = + fromTangentSpace _ (mfderiv% โŸชฯƒ, ฯ„โŸซ x (X x)) - โŸชโˆ‡ X ฯƒ, ฯ„โŸซ x - โŸชฯƒ, โˆ‡ X ฯ„โŸซ x := by + unfold compatibilityTensor + rw [TensorialAt.mkHomโ‚‚_apply _ _ hฯƒ hฯ„, compatibilityTensorAux_apply] + +variable {I} [ContMDiffVectorBundle 1 F V I] in +theorem compatibilityTensor_apply_eq_extend [FiniteDimensional โ„ F] (Xโ‚€ : TangentSpace I x) + (ฯƒโ‚€ ฯ„โ‚€ : V x) : + cov.compatibilityTensor x ฯƒโ‚€ ฯ„โ‚€ Xโ‚€ = + fromTangentSpace _ (mfderiv% โŸช(FiberBundle.extend F ฯƒโ‚€), (FiberBundle.extend F ฯ„โ‚€)โŸซ x Xโ‚€) + - inner โ„ (cov (FiberBundle.extend F ฯƒโ‚€) x Xโ‚€) ฯ„โ‚€ + - inner โ„ ฯƒโ‚€ (cov (FiberBundle.extend F ฯ„โ‚€) x Xโ‚€) := by + simp [compatibilityTensor, TensorialAt.mkHomโ‚‚_apply_eq_extend, compatibilityTensorAux_apply] + +variable {I} [ContMDiffVectorBundle 1 F V I] in +/-- Predicate saying that a connection `โˆ‡` on a Riemannian bundle `(V, g)` is compatible with the +ambient metric, i.e. for all differentiable vector fields `X` on `M` and sections `ฯƒ` and `ฯ„` of +`V`, we have `X โŸจฯƒ, ฯ„โŸฉ = โŸจโˆ‡_X ฯƒ, ฯ„โŸฉ + โŸจฯƒ, โˆ‡_X ฯ„โŸฉ`. -/ +def IsCompatible [FiniteDimensional โ„ F] : Prop := compatibilityTensor cov = 0 + +variable {I} [IsManifold I 1 M] [ContMDiffVectorBundle 1 F V I] + +lemma isCompatible_iff [FiniteDimensional โ„ F] : + cov.IsCompatible โ†” โˆ€ {x : M} {X : ฮ  x, TangentSpace I x} {ฯƒ ฯ„ : (x : M) โ†’ V x}, + MDiffAt (T% X) x โ†’ MDiffAt (T% ฯƒ) x โ†’ MDiffAt (T% ฯ„) x โ†’ + fromTangentSpace _ (mfderiv% โŸชฯƒ, ฯ„โŸซ x (X x)) = โŸชโˆ‡ X ฯƒ, ฯ„โŸซ x + โŸชฯƒ, โˆ‡ X ฯ„โŸซ x := by + refine โŸจfun hcov x X ฯƒ ฯ„ hX hฯƒ hฯ„ โ†ฆ ?_, fun h โ†ฆ ?_โŸฉ + ยท have H := congr($hcov x (ฯƒ x) (ฯ„ x) (X x)) + simp [compatibilityTensor_apply _ _ hฯƒ hฯ„] at H + linear_combination H + ext x ฯƒโ‚€ ฯ„โ‚€ Xโ‚€ + rw [compatibilityTensor_apply_eq_extend] + have h' := h (FiberBundle.mdifferentiableAt_extend I E Xโ‚€) + (FiberBundle.mdifferentiableAt_extend I F ฯƒโ‚€) (FiberBundle.mdifferentiableAt_extend I F ฯ„โ‚€) + simp [product] at h' โŠข + linear_combination (norm := skip) h' + ring_nf + +end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean new file mode 100644 index 00000000000000..502b34ec1bc402 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -0,0 +1,230 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Geometry.Manifold.MFDeriv.Atlas +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable + +/-! +# Supporting lemmas for CovariantDerivative.Basic + +TODO: PR all this to appropriate places. + +-/ + +open Bundle Filter Module Topology Set +open scoped Bundle Manifold ContDiff + +@[expose] public section tangent_bundle_normedSpace + +variable (F : Type*) [NormedAddCommGroup F] [NormedSpace โ„ F] + +instance (f : F) : CoeOut (TangentSpace ๐“˜(โ„, F) f) F := + โŸจfun x โ†ฆ xโŸฉ + +end tangent_bundle_normedSpace + +@[expose] public section mfderiv + +open Function + +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners ๐•œ E' H'} + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +-- unused; could move to `SpecificFunctions` +lemma injective_mfderiv_of_eventually_leftInverse + {f : M โ†’ M'} (x : M) {g : M' โ†’ M} + (hg : MDiffAt g (f x)) (hf : MDiffAt f x) + (hfg : g โˆ˜ f =แถ [๐“ x] id) : Injective (mfderiv% f x) := by + have := mfderiv_comp x hg hf + rw [hfg.mfderiv_eq] at this + have : LeftInverse (mfderiv% g (f x)) (mfderiv% f x) := by + intro u + simpa using congr($this u).symm + exact LeftInverse.injective this + +-- unused; could move to `SpecificFunctions` +lemma surjective_mfderiv_of_eventually_rightInverse + {f : M โ†’ M'} {x : M} {y : M'} (hxy : y = f x) {g : M' โ†’ M} + (hg : MDiffAt g y) (hf : MDiffAt f x) + (hfg : g โˆ˜ f =แถ [๐“ x] id) : Surjective (mfderiv% g y) := by + rw [hxy] at hg + have := mfderiv_comp x hg hf + rw [hfg.mfderiv_eq] at this + have : RightInverse (mfderiv% f x) (mfderiv% g (f x)) := by + intro u + simpa using congr($this u).symm + rw [โ† hxy] at this + exact RightInverse.surjective this + +end mfderiv + +@[expose] public section -- TODO: think if we want to expose all definitions! + +section general_lemmas -- those lemmas should move + +section linear_algebra +variable (๐•œ : Type*) [Field ๐•œ] + {E : Type*} [AddCommGroup E] [Module ๐•œ E] + {E' : Type*} [AddCommGroup E'] [Module ๐•œ E'] + +lemma exists_map_of (u : E) (u' : E') : + โˆƒ ฯ† : E โ†’โ‚—[๐•œ] E', (u = 0 โ†’ u' = 0) โ†’ ฯ† u = u' := by + by_cases h : u = 0 + ยท simp [h] + tauto + ยท have indep : LinearIndepOn ๐•œ id {u} := LinearIndepOn.singleton h + let s := indep.extend (subset_univ _) + have hus : u โˆˆ s := singleton_subset_iff.mp <| indep.subset_extend (subset_univ _) + use (Basis.extend indep).constr (M' := E') (S := ๐•œ) fun _ โ†ฆ u' + simpa [h, Basis.extend_apply_self] using (Basis.extend indep).constr_basis _ _ โŸจu, husโŸฉ + +open Classical in +noncomputable def map_of (u : E) (u' : E') : E โ†’โ‚—[๐•œ] E' := (exists_map_of ๐•œ u u').choose + +variable {๐•œ} +lemma map_of_spec (u : E) (u' : E') (h : u = 0 โ†’ u' = 0) : map_of ๐•œ u u' u = u' := + (exists_map_of ๐•œ u u').choose_spec h +end linear_algebra + +section +variable + {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] -- [IsManifold I 0 M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners ๐•œ E' H'} + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + +variable (๐•œ) in +noncomputable def map_of_loc_one_jet (e u : E) (e' u' : E') : E โ†’ E' := + fun x โ†ฆ e' + map_of ๐•œ u u' (x - e) + +lemma map_of_loc_one_jet_spec [CompleteSpace ๐•œ] [FiniteDimensional ๐•œ E] + (e u : E) (e' u' : E') (hu : u = 0 โ†’ u' = 0) : + map_of_loc_one_jet ๐•œ e u e' u' e = e' โˆง + DifferentiableAt ๐•œ (map_of_loc_one_jet ๐•œ e u e' u') e โˆง + fderiv ๐•œ (map_of_loc_one_jet ๐•œ e u e' u') e u = u' := by + unfold map_of_loc_one_jet + let ฯ† := (map_of ๐•œ u u').toContinuousLinearMap + have diff : Differentiable ๐•œ (map_of ๐•œ u u') := + (map_of ๐•œ u u').toContinuousLinearMap.differentiable + refine โŸจby simp, ?_, ?_โŸฉ + ยท apply (differentiableAt_const e').add + apply diff.differentiableAt.comp + fun_prop + ยท simp only [map_sub, fderiv_const_add] + rw [fderiv_sub_const] + change (fderiv ๐•œ ฯ† e) u = _ + rw [ฯ†.hasFDerivAt.fderiv] + exact map_of_spec u u' hu + +noncomputable +def map_of_one_jet {x : M} (u : TangentSpace I x) {x' : M'} (u' : TangentSpace I' x') : + M โ†’ M' := + letI ฯˆ := extChartAt I' x' + letI ฯ† := extChartAt I x + ฯˆ.symm โˆ˜ + (map_of_loc_one_jet ๐•œ (ฯ† x) (mfderiv% ฯ† x u) (ฯˆ x') (mfderiv% ฯˆ x' u')) โˆ˜ + ฯ† + +-- TODO: version assuming `x` and `x'` are in the interior, or maybe `x` is enough. + +/-- For any `(x, u) โˆˆ TM` and `(x', u') โˆˆ TM'`, `map_of_one_jet u u'` sends `x` to `x'` and +its derivative sends `u` to `u'`. We need to assume the target manifold `M'` has no boundary +since we cannot hope the result is `x` and `x'` are boundary points and `u` is inward +while `u'` is outward. +-/ +lemma map_of_one_jet_spec [IsManifold I 1 M] [IsManifold I' 1 M'] + [BoundarylessManifold I' M'] + [CompleteSpace ๐•œ] [FiniteDimensional ๐•œ E] + {x : M} (u : TangentSpace I x) {x' : M'} + (u' : TangentSpace I' x') (hu : u = 0 โ†’ u' = 0) : + map_of_one_jet u u' x = x' โˆง + MDiffAt (map_of_one_jet u u') x โˆง + mfderiv% (map_of_one_jet u u') x u = u' := by + let ฯˆ := extChartAt I' x' + let ฯ† := extChartAt I x + let g := map_of_loc_one_jet ๐•œ (ฯ† x) (mfderiv% ฯ† x u) (ฯˆ x') (mfderiv% ฯˆ x' u') + have hฯˆ : MDiffAt ฯˆ x' := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x') + have hฯ† : MDiffAt ฯ† x := mdifferentiableAt_extChartAt (ChartedSpace.mem_chart_source x) + replace hu : mfderiv% ฯ† x u = 0 โ†’ mfderiv% ฯˆ x' u' = 0 := by + have : Function.Injective (mfderiv% ฯ† x) := + (isInvertible_mfderiv_extChartAt (mem_extChartAt_source x)).injective + rw [injective_iff_map_eq_zero] at this + have := map_zero (mfderiv% ฯˆ x') + grind + rcases map_of_loc_one_jet_spec (๐•œ := ๐•œ) (ฯ† x) (mfderiv% ฯ† x u) (ฯˆ x') (mfderiv% ฯˆ x' u') hu with + โŸจh : g (ฯ† x) = ฯˆ x', h', h''โŸฉ + have hg : MDiffAt g (ฯ† x) := mdifferentiableAt_iff_differentiableAt.mpr h' + have hgฯ† : MDiffAt (g โˆ˜ ฯ†) x := h'.comp_mdifferentiableAt hฯ† + let ฮจi : E' โ†’ M' := ฯˆ.symm -- FIXME: this is working around a limitation of MDiffAt elaborator + have hฯˆi : MDiffAt ฮจi (g (ฯ† x)) := by + rw [h] + have := mdifferentiableWithinAt_extChartAt_symm (I := I') (mem_extChartAt_target x') + exact this.mdifferentiableAt (range_mem_nhds_isInteriorPoint <| + BoundarylessManifold.isInteriorPoint' x') + unfold map_of_one_jet + refold_let g ฯ† ฯˆ at * + refine โŸจby simp [h, ฯˆ], hฯˆi.comp x hgฯ†, ?_โŸฉ + rw [mfderiv_comp x hฯˆi hgฯ†, mfderiv_comp x hg hฯ†, mfderiv_eq_fderiv] + change (mfderiv% ฮจi (g (ฯ† x))) (fderiv ๐•œ g (ฯ† x) <| mfderiv% ฯ† x u) = u' + rw [h] at hฯˆi + rw [h'', h, โ† mfderiv_comp_apply x' hฯˆi hฯˆ] + have : ฮจi โˆ˜ ฯˆ =แถ [๐“ x'] id := by + have : โˆ€แถ  z in ๐“ x', z โˆˆ ฯˆ.source := extChartAt_source_mem_nhds x' + filter_upwards [this] with z hz + exact ฯˆ.left_inv hz + simp [this.mfderiv_eq] + rfl +end + +end general_lemmas + +section linear_algebra_isCompl +lemma LinearMap.comap_isCompl {R Rโ‚‚ M Mโ‚‚ : Type*} + [Semiring R] [AddCommMonoid M] [Module R M] [Semiring Rโ‚‚] + {ฯƒโ‚โ‚‚ : R โ†’+* Rโ‚‚} {ฯƒโ‚‚โ‚ : Rโ‚‚ โ†’+* R} [RingHomInvPair ฯƒโ‚โ‚‚ ฯƒโ‚‚โ‚] [RingHomInvPair ฯƒโ‚‚โ‚ ฯƒโ‚โ‚‚] + [AddCommMonoid Mโ‚‚] [Module Rโ‚‚ Mโ‚‚] + {f : M โ†’โ‚›โ‚—[ฯƒโ‚โ‚‚] Mโ‚‚} (hf : Function.Bijective f) + {p q : Submodule Rโ‚‚ Mโ‚‚} (h : IsCompl p q) : + IsCompl (Submodule.comap f p) (Submodule.comap f q) := by + rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * + constructor + ยท rw [โ† Submodule.comap_inf, h.1] + simp [LinearMap.ker_eq_bot_of_injective hf.1] + ยท rw [โ† Submodule.comap_sup_of_injective, h.2] + ยท exact Submodule.comap_top f + ยท exact hf.1 + ยท intro x hx + exact hf.2 x + ยท intro x hx + exact hf.2 x + +lemma LinearEquiv.comap_isCompl {R Rโ‚‚ M Mโ‚‚ : Type*} + [Semiring R] [AddCommMonoid M] [Module R M] [Semiring Rโ‚‚] + {ฯƒโ‚โ‚‚ : R โ†’+* Rโ‚‚} {ฯƒโ‚‚โ‚ : Rโ‚‚ โ†’+* R} [RingHomInvPair ฯƒโ‚โ‚‚ ฯƒโ‚‚โ‚] [RingHomInvPair ฯƒโ‚‚โ‚ ฯƒโ‚โ‚‚] + [AddCommMonoid Mโ‚‚] [Module Rโ‚‚ Mโ‚‚] + (f : M โ‰ƒโ‚›โ‚—[ฯƒโ‚โ‚‚] Mโ‚‚) {p q : Submodule Rโ‚‚ Mโ‚‚} (h : IsCompl p q) : + IsCompl (Submodule.comap f.toLinearMap p) (Submodule.comap f.toLinearMap q) := by + rw [isCompl_iff, disjoint_iff, codisjoint_iff] at * + constructor + ยท rw [โ† Submodule.comap_inf, h.1] + simp + ยท rw [โ† Submodule.comap_sup_of_injective, h.2] + ยท exact Submodule.comap_top f.toLinearMap + ยท exact f.injective + ยท simp + ยท simp + +end linear_algebra_isCompl diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean new file mode 100644 index 00000000000000..ab4ad9662c7ae8 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion2.lean @@ -0,0 +1,116 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame + +/-! +# More properties about torsion of a covariant derivative + +- might and should be refactored! +- prove: torsion-freeness on `s` can be checked using a local frame on `s` + +TODO: add a more complete doc-string + +-/ + +@[expose] public section -- TODO: think if we want to expose all definitions! + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] {H : Type*} [TopologicalSpace H] + {I : ModelWithCorners โ„ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + {F : Type*} [NormedAddCommGroup F] [NormedSpace โ„ F] (n : WithTop โ„•โˆž) {V : M โ†’ Type*} + [TopologicalSpace (TotalSpace F V)] [โˆ€ x, AddCommGroup (V x)] [โˆ€ x, Module โ„ (V x)] + [โˆ€ x : M, TopologicalSpace (V x)] [FiberBundle F V] + +variable + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)} + {X X' Y : ฮ  x : M, TangentSpace I x} + +namespace CovariantDerivative + +variable [IsManifold I โˆž M] +-- The torsion tensor of a covariant derivative on the tangent bundle `TM`. +variable {cov : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)} + {U : Set M} (hf : IsCovariantDerivativeOn E cov U) + +-- variable {n} in +-- lemma aux1 {ฮน : Type*} [Fintype ฮน] +-- {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)} +-- {U : Set M} {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} (hs : IsLocalFrameOn I E n s U) (hx : x โˆˆ U) +-- (X Y : (x : M) โ†’ TangentSpace I x) : +-- torsion f X Y x = โˆ‘ i, (hs.coeff i) x (X x) โ€ข torsion f (s i) Y x := +-- have hU : U โˆˆ ๐“ x := sorry +-- have aux := hs.eventually_eq_sum_coeff_smul X hU +-- have hX : X x = โˆ‘ i, (hs.coeff i) x (X x) โ€ข s i x := sorry +-- calc torsion f X Y x +-- _ = torsion f (fun x โ†ฆ โˆ‘ i, (hs.coeff i) x (X x) โ€ข s i x) Y x := by +-- sorry -- tensoriality and [hX] +-- _ = โˆ‘ i, (torsion f (fun x โ†ฆ (hs.coeff i) x (X x) โ€ข s i x) Y x) := sorry +-- _ = โˆ‘ i, (hs.coeff i) x (X x) โ€ข (torsion f (s i) Y x) := sorry +-- +-- -- Weaker hypotheses possible, e.g. local frame on U โˆˆ ๐“ x, while a cov. derivative on s โˆ‹ x +-- variable {n} in +-- lemma aux2 {ฮน : Type*} [Fintype ฮน] [CompleteSpace E] +-- {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)} +-- {U : Set M} {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} +-- (hf : IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) (hx : x โˆˆ U) +-- (X Y : (x : M) โ†’ TangentSpace I x) : +-- torsion f X Y x = โˆ‘ i, (hs.coeff i) x (Y x) โ€ข torsion f X (s i) x := +-- have hU : U โˆˆ ๐“ x := sorry +-- have aux := hs.eventually_eq_sum_coeff_smul Y hU +-- have hY : Y x = โˆ‘ i, (hs.coeff i) x (Y x) โ€ข s i x := hs.coeff_sum_eq Y hx +-- calc torsion f X Y x +-- _ = torsion f X (fun x โ†ฆ โˆ‘ i, (hs.coeff i) x (Y x) โ€ข s i x) x := by +-- sorry -- tensoriality and [hY] +-- _ = โˆ‘ i, (torsion f X (fun x โ†ฆ (hs.coeff i) x (Y x) โ€ข s i x) x) := sorry +-- _ = โˆ‘ i, (hs.coeff i) x (Y x) โ€ข (torsion f X (s i) x) := by +-- congr with i +-- have hsi : MDiffAt (LinearMap.piApply (hs.coeff i) Y) x := sorry +-- have hsi' : MDiffAt (T% (s i)) x := sorry +-- have := hf.torsion_smul_right_apply X (f := LinearMap.piApply (hs.coeff i) Y) hsi hsi' +-- erw [โ† this] +-- congr +-- +-- /-- We can test torsion-freeness on a set using a local frame. -/ +-- lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame +-- {ฮน : Type*} [Fintype ฮน] [CompleteSpace E] +-- {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[โ„] TangentSpace I x)} +-- {U : Set M} {s : ฮน โ†’ (x : M) โ†’ TangentSpace I x} +-- (hf: IsCovariantDerivativeOn E f U) (hs : IsLocalFrameOn I E n s U) : +-- IsTorsionFreeOn f U โ†” โˆ€ i j, โˆ€ x โˆˆ U, torsion f (s i) (s j) x = 0 := by +-- rw [IsTorsionFreeOn] +-- refine โŸจfun h i j x hx โ†ฆ h x hx (s i) (s j), fun h โ†ฆ ?_โŸฉ +-- intro x hx X Y +-- rw [aux1 hs hx] +-- calc +-- _ = โˆ‘ i, (hs.coeff i) x (X x) โ€ข โˆ‘ j, (hs.coeff j) x (Y x) โ€ข torsion f (s i) (s j) x := by +-- congr! +-- rw [aux2 hf hs hx] +-- _ = โˆ‘ i, (hs.coeff i) x (X x) โ€ข โˆ‘ j, (hs.coeff j) x (Y x) โ€ข 0 := by +-- congr! with i _ j _ +-- exact h i j x hx +-- _ = 0 := by simp + +-- lemma the trivial connection on a normed space is torsion-free +-- lemma trivial.isTorsionFree : IsTorsionFree (TangentBundle ๐“˜(โ„, E) E) := sorry + +-- lemma: tangent bundle of E is trivial -> there exists a single trivialisation with baseSet univ +-- make a new abbrev Bundle.Trivial.globalFrame --- which is localFrame for the std basis of F, +-- w.r.t. to this trivialisation +-- add lemmas: globalFrame is contMDiff globally + +-- proof of above lemma: write sections s and t in the global frame above +-- by linearity (proven above), suffices to consider s = s^i and t = s^j (two sections in the frame) +-- compute: their Lie bracket is zero +-- compute: the other two terms cancel, done + +end CovariantDerivative diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean new file mode 100644 index 00000000000000..8446549efaf9c8 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/TrivPrelim.lean @@ -0,0 +1,641 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary +public import Mathlib.Geometry.Manifold.MFDeriv.Atlas +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable +public import Mathlib.Geometry.Manifold.Notation + +/-! +# Supporting lemmas for CovariantDerivative.Basic trivialization stuff + +TODO: PR all this to appropriate places. + +-/ + +@[expose] public section + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +namespace Bundle.Trivialization + +section trivilization_topology + +variable {B F Z : Type*} [TopologicalSpace B] + [TopologicalSpace F] + +section any_proj + +variable [TopologicalSpace Z] {proj : Z โ†’ B} (e : Trivialization F proj) +lemma baseSet_mem_nhds {x : B} (hx : x โˆˆ e.baseSet) : e.baseSet โˆˆ ๐“ x := + e.open_baseSet.mem_nhds_iff.mpr hx + +lemma baseSet_prod_univ_mem_nhds {v : Z} + (hv : proj v โˆˆ e.baseSet) : e.baseSet ร—หข univ โˆˆ ๐“ (e v) := by + rw [โ† e.mk_proj_snd' hv] + exact prod_mem_nhds (e.baseSet_mem_nhds hv) univ_mem + +lemma comp_invFun_eventuallyEq + {v : Z} (hv : proj v โˆˆ e.baseSet) : e โˆ˜ e.invFun =แถ [๐“ (e v)] id := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with p hp + simp [(e.mem_target).2 hp.1] + +end any_proj + +section fiber_bundle +variable {E : B โ†’ Type*} [TopologicalSpace (TotalSpace F E)] + (e : Trivialization F (ฯ€ F E)) + +lemma proj_invFun_eventuallyEq + {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) : + (TotalSpace.proj โˆ˜ e.invFun) =แถ [๐“ (e v)] Prod.fst := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with โŸจx, fโŸฉ โŸจhx, hfโŸฉ + simp [hx] + +lemma injective_symm [(x : B) โ†’ Zero (E x)] + {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) : + Function.Injective (e.symm v.proj) := by + intro f f' hff' + simpa [hv] using congr(e $hff') + +lemma surjective_symm [(x : B) โ†’ Zero (E x)] + {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) : + Function.Surjective (e.symm v.proj) := + fun u โ†ฆ โŸจ(e u).2, by simp [hv]โŸฉ + +lemma bijective_symm [(x : B) โ†’ Zero (E x)] + {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) : + Function.Bijective (e.symm v.proj) := + โŸจe.injective_symm hv, e.surjective_symm hvโŸฉ + +/-- Turn sections of a fiber bundle into function into the model fiber using a trivialization. -/ +def secToFun (ฯƒ : (b : B) โ†’ E b) : B โ†’ F := + fun b โ†ฆ e (ฯƒ b) |>.2 + +@[simp] +lemma secToFun_apply_of_eq {ฯƒ : (b : B) โ†’ E b} {v : TotalSpace F E} (h : ฯƒ v.proj = v) : + e.secToFun ฯƒ v.proj = (e v).2 := by + simp [secToFun, h] + +lemma secToFun_congr {ฯƒ ฯƒ' : (b : B) โ†’ E b} {b : B} (h : ฯƒ b = ฯƒ' b) : + e.secToFun ฯƒ b = e.secToFun ฯƒ' b := by + simp [secToFun, h] + +lemma apply_total_eventuallyEq + {x : B} (hx : x โˆˆ e.baseSet) (ฯƒ : ฮ  x, E x) : + e โˆ˜ T%ฯƒ =แถ [๐“ x] fun x โ†ฆ (x, e.secToFun ฯƒ x) := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + ext + ยท exact e.coe_coe_fst hy + ยท simp [secToFun] + +-- @[congr] +-- lemma secToFun_congr {ฯƒ ฯƒ' : (b : B) โ†’ E b} {b : B} (h : โˆ€ x, x = b โ†’ ฯƒ x = ฯƒ' x) : +-- e.secToFun ฯƒ b = e.secToFun ฯƒ' b := by +-- simp [secToFun, h] +-- +-- example {ฯƒ ฯƒ' : (b : B) โ†’ E b} {b : B} (h : โˆ€ x, x = b โ†’ ฯƒ x = ฯƒ' x) : +-- e.secToFun ฯƒ b = e.secToFun ฯƒ' b := by +-- simp? +contextual [h] +section +variable [(x : B) โ†’ Zero (E x)] + +/-- Turn functions into the model fiber of a fiber bundle into sections using a trivialization. -/ +noncomputable def funToSec (s : B โ†’ F) : (b : B) โ†’ E b := + fun b โ†ฆ e.symm b (s b) + +lemma totalSpace_mk_funToSec {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + T% (e.funToSec s) =แถ [๐“ x] e.invFun โˆ˜ fun x โ†ฆ (x, s x) := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + exact mk_symm e hy (s y) + +@[simp] +lemma apply_funToSec {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + e โŸจx, e.funToSec s xโŸฉ = (x, s x) := by + simp [funToSec, e.apply_mk_symm hx] + +lemma snd_apply_funToSec {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + (e โŸจx, e.funToSec s xโŸฉ).2 = s x := by + simp [funToSec, e.apply_mk_symm hx] + +@[simp] +lemma funToSec_proj_eq {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) {s : B โ†’ F} + (hsv : s v.proj = (e v).2) : + e.funToSec s v.proj = v.2 := by + simp [funToSec, hsv, e.symm_proj_apply v hv] + +@[simp] +lemma mk_funToSec_of_eq {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) {s : B โ†’ F} + (h : s v.proj = (e v).2) : (โŸจv.proj, e.funToSec s v.projโŸฉ : TotalSpace F E) = v := by + simp [funToSec, h, hv] + +lemma funToSec_congr {s s' : B โ†’ F} {b : B} (h : s b = s' b) : + e.funToSec s b = e.funToSec s' b := by + simp [funToSec, h] + +@[simp] +lemma secToFun_funToSec_eventuallyEq {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + e.secToFun (e.funToSec s) =แถ [๐“ x] s := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma secToFun_funToSec {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + e.secToFun (e.funToSec s) x = s x := + (e.secToFun_funToSec_eventuallyEq hx s).eq_of_nhds + -- TODO: understand why the following fails + -- by + -- have := e.secToFun_funToSec_eventuallyEq hx s + -- apply? + +@[simp] +lemma funToSec_secToFun_eventually_eq {x : B} (hx : x โˆˆ e.baseSet) (ฯƒ : (b : B) โ†’ E b) : + โˆ€แถ  x' in ๐“ x, e.funToSec (e.secToFun ฯƒ) x' = ฯƒ x' := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma funToSec_secToFun {x : B} (hx : x โˆˆ e.baseSet) (ฯƒ : (b : B) โ†’ E b) : + e.funToSec (e.secToFun ฯƒ) x = ฯƒ x := + (e.funToSec_secToFun_eventually_eq hx ฯƒ).self_of_nhds + +section +variable (ฯƒ : (b : B) โ†’ E b) + +@[simp] +lemma total_funToSec_secToFun_eventuallyEq {x : B} (hx : x โˆˆ e.baseSet) (ฯƒ : (b : B) โ†’ E b) : + T% (e.funToSec <| e.secToFun ฯƒ) =แถ [๐“ x] T% ฯƒ := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma total_funToSec_secToFun_eq {x : B} (hx : x โˆˆ e.baseSet) (ฯƒ : (b : B) โ†’ E b) : + T% (e.funToSec <| e.secToFun ฯƒ) x = T% ฯƒ x := + e.total_funToSec_secToFun_eventuallyEq hx ฯƒ |>.self_of_nhds + +end + +@[simp] +lemma total_secToFun_funToSeq_eventually_eq {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + โˆ€แถ  x' in ๐“ x, T% (e.secToFun <| e.funToSec s) x' = T% s x' := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + simp [secToFun, funToSec, hy] + +@[simp] +lemma total_secToFun_funToSeq {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + T% (e.secToFun <| e.funToSec s) x = T% s x := + e.total_secToFun_funToSeq_eventually_eq hx s |>.self_of_nhds + +end + +variable [(b : B) โ†’ TopologicalSpace (E b)] [FiberBundle F E] + +lemma preimage_baseSet_mem_nhds + {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) : + TotalSpace.proj โปยน' e.baseSet โˆˆ ๐“ v := + FiberBundle.continuous_proj F E |>.continuousAt <| e.baseSet_mem_nhds hv + +lemma fst_comp_eventuallyEq + {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) : + Prod.fst โˆ˜ e =แถ [๐“ v] (ฯ€ F E) := by + filter_upwards [preimage_baseSet_mem_nhds e hv] with y hy using e.coe_fst' hy + +lemma invFun_comp_eventuallyEq + {v : TotalSpace F E} (hv : v.proj โˆˆ e.baseSet) : + e.invFun โˆ˜ e =แถ [๐“ v] id := by + filter_upwards [e.preimage_baseSet_mem_nhds hv] with w hw + simp [e.mem_source.mpr hw] + +end fiber_bundle + +section +variable {B F : Type*} {E : B โ†’ Type*} [TopologicalSpace B] + [TopologicalSpace F] [TopologicalSpace (TotalSpace F E)] + [(x : B) โ†’ Zero (E x)] + (e : Trivialization F (ฯ€ F E)) + +lemma eq_of {x : B} {v v' : E x} (hx : x โˆˆ e.baseSet) (hvv' : (e v).2 = (e v').2) : + v = v' := by + have := e.symm_proj_apply v hx + rw [hvv'] at this + grind [e.symm_proj_apply v' hx] + +end + +end trivilization_topology + +section topological_vector_bundle + +section +variable {R B F : Type*} {E : B โ†’ Type*} [Semiring R] + [TopologicalSpace F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + (e : Trivialization F (ฯ€ F E)) + [AddCommMonoid F] [Module R F] [(x : B) โ†’ AddCommMonoid (E x)] [(x : B) โ†’ Module R (E x)] + +@[simp] +lemma linearMapAt_funToSec [Trivialization.IsLinear R e] {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + (Trivialization.linearMapAt R e x) (e.funToSec s x) = s x := by + simp [funToSec, hx] + +lemma map_smul [Trivialization.IsLinear R e] + {b : B} (hb : b โˆˆ e.baseSet) (a : R) (v : E b) : + (e โŸจb, a โ€ข vโŸฉ).2 = a โ€ข (e โŸจb, vโŸฉ).2 := + e.linear R hb |>.map_smul a v + +lemma secToFun_map_smul [Trivialization.IsLinear R e] {ฯƒ : (b : B) โ†’ E b} + {b : B} (hb : b โˆˆ e.baseSet) (a : R) : + e.secToFun (a โ€ข ฯƒ) b = a โ€ข e.secToFun ฯƒ b := by + simp [secToFun, e.map_smul hb] + +variable (R) + +lemma map_add [Trivialization.IsLinear R e] + {b : B} (hb : b โˆˆ e.baseSet) (v v' : E b) : + (e โŸจb, v + v'โŸฉ).2 = (e โŸจb, vโŸฉ).2 + (e โŸจb, v'โŸฉ).2 := + e.linear R hb |>.map_add v v' + +lemma secToFun_map_add [Trivialization.IsLinear R e] (ฯƒ ฯƒ' : (b : B) โ†’ E b) + {b : B} (hb : b โˆˆ e.baseSet) : + e.secToFun (ฯƒ + ฯƒ') b = e.secToFun ฯƒ b + e.secToFun ฯƒ' b := by + simp [secToFun, e.map_add R hb] + +lemma map_zero [Trivialization.IsLinear R e] + {b : B} (hb : b โˆˆ e.baseSet) : + (e โŸจb, 0โŸฉ).2 = 0 := + e.linear R hb |>.map_zero + +lemma secToFun_map_zero [Trivialization.IsLinear R e] {b : B} (hb : b โˆˆ e.baseSet) : + e.secToFun 0 b = 0 := by + simp [secToFun, e.map_zero R hb] +end + +section + +variable (R : Type*) {B F : Type*} {E : B โ†’ Type*} + [NontriviallyNormedField R] [(x : B) โ†’ AddCommMonoid (E x)] + [(x : B) โ†’ Module R (E x)] [NormedAddCommGroup F] + [NormedSpace R F] [TopologicalSpace B] [TopologicalSpace (TotalSpace F E)] + [(x : B) โ†’ TopologicalSpace (E x)] + [FiberBundle F E] (e : Trivialization F (ฯ€ F E)) + +lemma symm_map_add [Trivialization.IsLinear R e] {x : B} + (f f' : F) : + e.symm x (f + f') = e.symm x f + e.symm x f' := + (e.symmL R x).map_add f f' + +lemma funToSec_map_add [Trivialization.IsLinear R e] {s s' : B โ†’ F} : + e.funToSec (s + s') = e.funToSec s + e.funToSec s' := by + ext b + simp [funToSec, e.symm_map_add R] + +@[simp] +lemma symm_map_zero [Trivialization.IsLinear R e] {x : B} : + e.symm x 0 = 0 := + (e.symmL R x).map_zero + +@[simp] +lemma funToSec_map_zero [Trivialization.IsLinear R e] : + e.funToSec (0 : B โ†’ F) = 0 := by + ext b + simp [funToSec, e.symm_map_zero R] + +variable {R} + +lemma symm_map_smul [Trivialization.IsLinear R e] {x : B} (a : R) (f : F) : + e.symm x (a โ€ข f) = a โ€ข e.symm x f := + (e.symmL R x).map_smul a f + +lemma funToSec_map_smul_const [Trivialization.IsLinear R e] (a : R) (s : B โ†’ F) : + e.funToSec (a โ€ข s) = a โ€ข e.funToSec s := by + ext b + simp [funToSec, e.symm_map_smul] + +lemma funToSec_map_smul [Trivialization.IsLinear R e] (a : B โ†’ R) (s : B โ†’ F) : + e.funToSec (a โ€ข s) = a โ€ข e.funToSec s := by + ext b + simp [funToSec, e.symm_map_smul] + +end + +end topological_vector_bundle + +section to_trivialization +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + -- `F` model fiber + (n : WithTop โ„•โˆž) + {V : M โ†’ Type*} [TopologicalSpace (TotalSpace F V)] + [โˆ€ x, AddCommGroup (V x)] [โˆ€ x, Module ๐•œ (V x)] + [โˆ€ x : M, TopologicalSpace (V x)] + [FiberBundle F V] + +@[simp] +lemma _root_.mdifferentiableAt_total_trivial_iff {s : M โ†’ F} {x : M} : + MDiffAt (T% s) x โ†” MDiffAt s x := by + rw [mdifferentiableAt_section I] + simp + +@[simp] +lemma _root_.mdifferentiableAt_section_trivial_iff {ฯƒ : (x : M) โ†’ Trivial M F x} {x : M} : + MDiffAt (T% ฯƒ) x โ†” MDifferentiableAt I ๐“˜(๐•œ, F) ฯƒ x := by + rw [mdifferentiableAt_section I] + simp + +variable (e : Trivialization F (ฯ€ F V)) [MemTrivializationAtlas e] + +lemma mdifferentiableAt + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x โˆˆ e.baseSet) (v : V x) : + MDifferentiableAt (I.prod ๐“˜(๐•œ, F)) (I.prod ๐“˜(๐•œ, F)) e v := by + have : โŸจx, vโŸฉ โˆˆ e.source := e.coe_mem_source.mpr hx + have foo := e.contMDiffOn (IB := I) (n := 1) v this + have := foo.contMDiffAt (e.open_source.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + +lemma mdifferentiableAt_invFun + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x โˆˆ e.baseSet) (f : F) : + MDifferentiableAt (I.prod ๐“˜(๐•œ, F)) (I.prod ๐“˜(๐•œ, F)) e.invFun (x, f) := by + have : โŸจx, fโŸฉ โˆˆ e.target := e.mk_mem_target.mpr hx + have foo := e.contMDiffOn_symm (IB := I) (n := 1) _ this + have := foo.contMDiffAt (e.open_target.mem_nhds this) + exact this.mdifferentiableAt zero_ne_one.symm + +-- Note: The definition below (ab)uses definitional +-- equality of `TangentSpace (I.prod ๐“˜(๐•œ, F)) (โ†‘t v)` +-- which is $T_{t(v)} (M ร— F)$ and `TM v.proj ร— F` +-- which is $T_{ฯ€(v)} M ร— F$. +variable (I) in +noncomputable +def deriv (v : TotalSpace F V) : + TangentSpace (I.prod ๐“˜(๐•œ, F)) v โ†’L[๐•œ] TangentSpace I v.proj ร— F := + mfderiv (I.prod ๐“˜(๐•œ, F)) (I.prod ๐“˜(๐•œ, F)) e v + +variable (I) in +noncomputable +def derivInv (v : TotalSpace F V) : + TangentSpace I v.proj ร— F โ†’L[๐•œ] TangentSpace (I.prod ๐“˜(๐•œ, F)) v := + mfderiv (I.prod ๐“˜(๐•œ, F)) (I.prod ๐“˜(๐•œ, F)) e.invFun (e v) + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma derivInv_deriv + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) : + (e.derivInv I v) โˆ˜L (e.deriv I v) = .id ๐•œ _ := by + have Dโ‚ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + have Dโ‚‚ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + have D1' := Dโ‚ + simp only [PartialEquiv.invFun_as_coe, OpenPartialHomeomorph.coe_coe_symm] at D1' + rw [e.mk_proj_snd' hv] at Dโ‚ + have comp := mfderiv_comp v Dโ‚ Dโ‚‚ + rw [(invFun_comp_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp + simp [deriv, derivInv, comp] + +@[simp] +lemma derivInv_deriv_apply + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) + (u : TangentSpace (I.prod ๐“˜(๐•œ, F)) v) : + (e.derivInv I v (e.deriv I v u)) = u := + show ((e.derivInv I v) โˆ˜L (e.deriv I v)) u = u by simp [hv] + +@[simp] +lemma mfderiv_proj_fst_deriv + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) + (u : TangentSpace (I.prod ๐“˜(๐•œ, F)) v) : + mfderiv (I.prod ๐“˜(๐•œ, F)) I TotalSpace.proj v u = (e.deriv I v u).1 := by + have := e.fst_comp_eventuallyEq hv + rw [โ† this.mfderiv_eq, mfderiv_comp v mdifferentiableAt_fst (e.mdifferentiableAt (I := I) hv v.2)] + simp + rfl -- TODO: understand why `simp` does not handle `ContinuousLinearMap.fst` + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma mfderiv_proj_derivInv_apply + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) + (u : TangentSpace (I.prod ๐“˜(๐•œ, F)) v) : + mfderiv (I.prod ๐“˜(๐•œ, F)) I TotalSpace.proj v (e.derivInv I v u) = u.1 := by + have Dโ‚ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + rw [e.mk_proj_snd' hv] at Dโ‚ + have diff : MDifferentiableAt (I.prod ๐“˜(๐•œ, F)) I TotalSpace.proj v := + mdifferentiableAt_proj _ + have eq : e.invFun (e v) = v := by simp [e.mem_source.mpr hv] + rw [โ† eq] at diff + have := mfderiv_comp (e v) diff Dโ‚ + have C : (TotalSpace.proj โˆ˜ e.invFun) =แถ [๐“ (e v)] Prod.fst := by + filter_upwards [e.baseSet_prod_univ_mem_nhds hv] with โŸจx, fโŸฉ โŸจhx, hfโŸฉ + simp [hx] + rw [C.mfderiv_eq, eq] at this + have := congr($this u).symm + change mfderiv (I.prod ๐“˜(๐•œ, F)) I TotalSpace.proj v _ = _ at this + -- Why all this pain?? + convert this + ext x + simp + rfl + +set_option backward.isDefEq.respectTransparency false in +@[simp] +lemma deriv_derivInv + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) : + (e.deriv I v) โˆ˜L (e.derivInv I v) = .id ๐•œ _ := by + have Dโ‚ := e.mdifferentiableAt_invFun (I := I) hv (e v).2 + rw [e.mk_proj_snd' hv] at Dโ‚ + have Dโ‚‚ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + have : e.invFun (e v) = v := by simp [e.mem_source.mpr hv] + rw [โ† this] at Dโ‚‚ + have comp := mfderiv_comp (e v) Dโ‚‚ Dโ‚ + rw [(comp_invFun_eventuallyEq e hv).mfderiv_eq, mfderiv_id] at comp + symm + convert comp <;> rw [this] + +@[simp] +lemma deriv_derivInv_apply + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) + (u : TangentSpace I v.proj ร— F) : + e.deriv I v (e.derivInv I v u) = u := + show ((e.deriv I v) โˆ˜L (e.derivInv I v)) u = u by simp [hv] + +lemma bijective_deriv + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) : + Function.Bijective (e.deriv I v) := by + refine Function.bijective_iff_has_inverse.mpr ?_ + use e.derivInv I v + constructor + all_goals { intro u; simp [hv] } + +lemma mdifferentiableAt_funToSec + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x โˆˆ e.baseSet) {s : M โ†’ F} + (hs : MDiffAt s x) : + MDiffAt (T% (e.funToSec s)) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] + change MDiffAt (e.secToFun <| e.funToSec s) x + have := e.secToFun_funToSec_eventuallyEq hx s + exact hs.congr_of_eventuallyEq this + +lemma mdifferentiableAt_funToSec' + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x โˆˆ e.baseSet) {s : M โ†’ F} + (hs : MDiffAt (T% s) x) : + MDiffAt (T% (e.funToSec s)) x := by + rw [mdifferentiableAt_total_trivial_iff] at hs + apply mdifferentiableAt_funToSec _ hx hs + +lemma mdifferentiableAt_secToFun + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x โˆˆ e.baseSet) {ฯƒ : (x : M) โ†’ V x} + (hฯƒ : MDiffAt (T% ฯƒ) x) : + MDiffAt (e.secToFun ฯƒ) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] at hฯƒ + exact hฯƒ + +lemma mdifferentiableAt_total_secToFun + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x โˆˆ e.baseSet) {ฯƒ : (x : M) โ†’ V x} + (hฯƒ : MDiffAt (T% ฯƒ) x) : + MDiffAt (T% (e.secToFun ฯƒ)) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] at hฯƒ + exact (mdifferentiableAt_section I _).mpr hฯƒ + +omit [MemTrivializationAtlas e] [(x : M) โ†’ Module ๐•œ (V x)] in +@[simp] +lemma mdifferentiableAt_total_funToSec_secToFun + {x : M} (hx : x โˆˆ e.baseSet) {ฯƒ : (x : M) โ†’ V x} : + MDiffAt (T% (e.funToSec <| e.secToFun ฯƒ)) x โ†” MDiffAt (T%ฯƒ) x := by + rw [e.total_funToSec_secToFun_eventuallyEq hx ฯƒ |>.mdifferentiableAt_iff] + +omit [(x : M) โ†’ Module ๐•œ (V x)] [(x : M) โ†’ TopologicalSpace (V x)] + [FiberBundle F V] [MemTrivializationAtlas e] in +@[simp] +lemma mdifferentiableAt_secToFun_funToSec + {x : M} (hx : x โˆˆ e.baseSet) {s : M โ†’ F} : + MDiffAt (e.secToFun <| e.funToSec s) x โ†” MDiffAt s x := + e.secToFun_funToSec_eventuallyEq hx s |>.mdifferentiableAt_iff + +lemma mfderiv_total_funToSec + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {s : M โ†’ F} {x : M} (hs : MDiffAt s x) + (hx : x โˆˆ e.baseSet) : + mfderiv% (T% (e.funToSec s)) x = + e.derivInv I (e.funToSec s x) โˆ˜L .prod (.id ๐•œ <| TangentSpace I x) (mfderiv% s x) := by + -- TODO build a world where this proof is not pure pain. + rw [(e.totalSpace_mk_funToSec hx s).mfderiv_eq, + mfderiv_comp x (e.mdifferentiableAt_invFun (I := I) hx (s x))] + ยท congr 2 + ยท simp [hx] + ยท rw [mfderiv_prodMk] + ยท erw [mfderiv_id] + rfl + ยท exact mdifferentiableAt_id + ยท exact hs + ยท exact mdifferentiableAt_id.prodMk hs + + + +noncomputable def _root_.Bundle.vert (v : TotalSpace F V) : + Submodule ๐•œ (TangentSpace (I.prod ๐“˜(๐•œ, F)) v) := + (mfderiv (I.prod ๐“˜(๐•œ, F)) I Bundle.TotalSpace.proj v).ker + +lemma comap_vert + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {v : TotalSpace F V} (hv : v.proj โˆˆ e.baseSet) : + Bundle.vert v = Submodule.comap (e.deriv I v).toLinearMap + (Submodule.prod โŠฅ โŠค) := by + ext x + have : Prod.fst โˆ˜ e =แถ [๐“ v] TotalSpace.proj := e.fst_comp_eventuallyEq hv + unfold vert + rw [โ† this.mfderiv_eq] + have mdiffe : MDifferentiableAt (I.prod ๐“˜(๐•œ, F)) (I.prod ๐“˜(๐•œ, F)) e v := + e.mdifferentiableAt hv _ + rw [mfderiv_comp v mdifferentiableAt_fst mdiffe] + simp + rfl + +lemma mfderiv_comp_section + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {ฯƒ : ฮ  x : M, V x} {x : M} (hฯƒ : MDiffAt T%ฯƒ x) + (u : TangentSpace I x) (hx : x โˆˆ e.baseSet) : + e.deriv I (ฯƒ x) ((mfderiv% T%ฯƒ x) u) = (u, mfderiv% (e.secToFun ฯƒ) x u) := by + have mdiffe : MDifferentiableAt (I.prod ๐“˜(๐•œ, F)) (I.prod ๐“˜(๐•œ, F)) e (ฯƒ x) := + e.mdifferentiableAt hx _ + have : mfderiv% (e โˆ˜ T%ฯƒ) x = (e.deriv I (ฯƒ x)) โˆ˜L (mfderiv% T%ฯƒ x) := + mfderiv_comp x mdiffe hฯƒ + have : mfderiv% (e โˆ˜ T%ฯƒ) x u = e.deriv I (ฯƒ x) ((mfderiv% T%ฯƒ x) u) := by + rw [this] + rfl + erw [โ† this] + rw [(e.apply_total_eventuallyEq hx _).mfderiv_eq] + erw [mfderiv_prodMk, mfderiv_id] + ยท -- TODO make sure the `change` below isnโ€™t needed. + -- Uncommenting the next lines is meant to help understanding the issue. + -- have : ((ContinuousLinearMap.id ๐•œ (TangentSpace I x)).prod + -- (mfderiv I ๐“˜(๐•œ, F) (e.secToFun ฯƒ) x)) u = + -- (u, (mfderiv I ๐“˜(๐•œ, F) (e.secToFun ฯƒ) x) u) := sorry + -- with_reducible exact this + change (ContinuousLinearMap.id _ _).prod _ _ = _ + simp + ยท apply mdifferentiableAt_id + ยท exact (e.mdifferentiableAt_section_iff I ฯƒ hx).mp hฯƒ + +lemma mfderiv_secToFun_apply + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {ฯƒ : (x : M) โ†’ V x} {x : M} (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ e.baseSet) + (u : TangentSpace I x) : + mfderiv% (e.secToFun ฯƒ) x u = + (e.deriv I (ฯƒ x) (mfderiv% T%ฯƒ x u)).2 := by + -- TODO: Fix the erw + -- instModuleTangentSpace ๐“˜(๐•œ, F) (e.secToFun (E := V) ฯƒ x) + -- and + -- NormedSpace.toModule + -- are not defeq, but they are at default transparency. + -- Does it mean the statement of this lemma is bad? + erw [ContinuousLinearMap.comp_apply, ContinuousLinearMap.comp_apply] + exact congr(Prod.snd $(e.mfderiv_comp_section hฯƒ u hx)).symm + +lemma mfderiv_secToFun + [VectorBundle ๐•œ F V] [ContMDiffVectorBundle 1 F V I] + {ฯƒ : (x : M) โ†’ V x} {x : M} (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ e.baseSet) : + mfderiv% (e.secToFun ฯƒ) x = + .snd ๐•œ (TangentSpace I x) F โˆ˜L (e.deriv I (ฯƒ x)) โˆ˜L (mfderiv% T%ฯƒ x) := + ContinuousLinearMap.ext fun u โ†ฆ mfderiv_secToFun_apply e hฯƒ hx u + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + +@[simp] +theorem Bundle.Trivial.mdifferentiableAt_iff (ฯƒ : (x : E) โ†’ Trivial E E' x) (e : E) : + MDiffAt (T% ฯƒ) e โ†” DifferentiableAt ๐•œ ฯƒ e := by + simp [mdifferentiableAt_totalSpace, mdifferentiableAt_iff_differentiableAt] + +-- unused but we need all combinations at some point. +@[simp] +theorem Bundle.Trivial.contMDiffOn_iff {n : WithTop โ„•โˆž} {ฯƒ : (x : E) โ†’ Trivial E E' x} {s : Set E} : + ContMDiffOn ๐“˜(๐•œ, E) (๐“˜(๐•œ, E).prod ๐“˜(๐•œ, E')) n (T% ฯƒ) s โ†” + ContDiffOn ๐•œ n ฯƒ s := by + sorry + +end to_trivialization +end Bundle.Trivialization + +section +@[simp] +lemma Bundle.TotalSpace.proj_mk' {B : Type*} {F : Type*} {E : B โ†’ Type*} (b : B) (e : E b) : + proj (TotalSpace.mk' F b e) = b := rfl +end diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean new file mode 100644 index 00000000000000..ec9809c44c54b4 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Trivial.lean @@ -0,0 +1,175 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.TrivPrelim + +/-! +# Everything you always wanted to know about covariant derivatives on the trivial bundle + +Don't be afraid to ask. TODO! + +-/ + +open Bundle Filter Module NormedSpace Topology Set +open scoped Manifold ContDiff + +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + +@[expose] public section + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] (n : WithTop โ„•โˆž) + {V : M โ†’ Type*} [TopologicalSpace (TotalSpace F V)] [โˆ€ x, AddCommGroup (V x)] + [โˆ€ x, Module ๐•œ (V x)] [โˆ€ x, TopologicalSpace (V x)] [โˆ€ x, IsTopologicalAddGroup (V x)] + [โˆ€ x, ContinuousSMul ๐•œ (V x)] [FiberBundle F V] + [IsManifold I 1 M] + +namespace IsCovariantDerivativeOn + +section trivial_bundle + +set_option backward.isDefEq.respectTransparency false in +variable (I M F) in +@[simps] +noncomputable def trivial [IsManifold I 1 M] : + IsCovariantDerivativeOn F (V := Trivial M F) (fun s x โ†ฆ mfderiv I ๐“˜(๐•œ, F) s x) univ where + add hฯƒ hฯƒ' hx := by + rw [mdifferentiableAt_section_trivial_iff] at hฯƒ hฯƒ' + rw [mfderiv_add hฯƒ hฯƒ'] + leibniz hฯƒ hf hx := by + rw [mdifferentiableAt_section] at hฯƒ + ext1 Xโ‚€ + exact fromTangentSpace_mfderiv_smul_apply hf hฯƒ Xโ‚€ + +lemma of_endomorphism (A : (x : M) โ†’ F โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] F) : + IsCovariantDerivativeOn F + (fun (s : M โ†’ F) x โ†ฆ (fromTangentSpace (๐•œ := ๐•œ) (s x) โˆ˜L mfderiv% s x) + A x (s x)) univ := + trivial I M F |>.add_one_form A + +end trivial_bundle + +end IsCovariantDerivativeOn + +namespace CovariantDerivative + +section trivial_bundle + +variable (I M F) in +@[simps] +noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where + toFun s x := mfderiv I ๐“˜(๐•œ, F) s x + isCovariantDerivativeOnUniv := IsCovariantDerivativeOn.trivial .. + +end trivial_bundle + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + +-- TODO: does it make sense to speak of analytic connections? if so, change the definition of +-- regularity and use โˆž from `open scoped ContDiff` instead. + +/-- The trivial connection on the trivial bundle is smooth -/ +lemma trivial_isSmooth : + ContMDiffCovariantDerivative (๐•œ := ๐•œ) (trivial ๐“˜(๐•œ, E) E E') (โŠค : โ„•โˆž) where + contMDiff := โŸจby + intro ฯƒ hฯƒ + dsimp only [trivial] + sorry /- + -- except for local trivialisations, contDiff_infty_iff_fderiv covers this well + simp only [trivial] + -- use a local trivialisation + intro x + specialize hX x + -- TODO: use contMDiffOn instead, to get something like + -- have hX' : ContMDiffOn ๐“˜(๐•œ, E) (๐“˜(๐•œ, E).prod ๐“˜(๐•œ, E')) (โˆž + 1) + -- (T% ฯƒ) (trivializationAt x).baseSet := hX.contMDiffOn + -- then want a version contMDiffOn_totalSpace + rw [contMDiffAt_totalSpace] at hX โŠข + simp only [Trivial.fiberBundle_trivializationAt', Trivial.trivialization_apply] + refine โŸจcontMDiff_id _, ?_โŸฉ + obtain โŸจhโ‚, hโ‚‚โŸฉ := hX + -- ... hopefully telling me + -- have hโ‚‚scifi : ContMDiffOn ๐“˜(๐•œ, E) ๐“˜(๐•œ, E') โˆž + -- (fun x โ†ฆ ฯƒ x) (trivializationAt _).baseSet_ := sorry + simp at hโ‚‚ + -- now use ContMDiffOn.congr and contDiff_infty_iff_fderiv, + -- or perhaps a contMDiffOn version of this lemma? + sorry -/โŸฉ + +noncomputable def of_endomorphism (A : E โ†’ E' โ†’L[๐•œ] E โ†’L[๐•œ] E') : + CovariantDerivative ๐“˜(๐•œ, E) E' (Trivial E E') where + toFun ฯƒ := fun x โ†ฆ fderiv ๐•œ ฯƒ x + A x (ฯƒ x) + isCovariantDerivativeOnUniv := by + convert IsCovariantDerivativeOn.of_endomorphism (I := ๐“˜(๐•œ, E)) A + simp [mfderiv_eq_fderiv, NormedSpace.fromTangentSpace] + rfl + +end CovariantDerivative + +section + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + -- `F` model fiber + (n : WithTop โ„•โˆž) + {V : M โ†’ Type*} [TopologicalSpace (TotalSpace F V)] + [โˆ€ x, AddCommGroup (V x)] [โˆ€ x, Module ๐•œ (V x)] + [โˆ€ x : M, TopologicalSpace (V x)] [FiberBundle F V] + -- `V` vector bundle + +namespace IsCovariantDerivativeOn + +-- The classification of real connections over a trivial bundle +section classification + +variable [CompleteSpace ๐•œ] [FiniteDimensional ๐•œ F] [IsManifold I 1 M] + +/-- Classification of covariant derivatives over a trivial vector bundle: every connection +is of the form `D + A`, where `D` is the trivial covariant derivative, and `A` a zeroth-order term +-/ +lemma exists_one_form {cov : (M โ†’ F) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : + โˆƒ (A : (x : M) โ†’ F โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] F), + โˆ€ ฯƒ : M โ†’ F, โˆ€ x โˆˆ s, MDiffAt (T% ฯƒ) x โ†’ + letI d : TangentSpace I x โ†’L[๐•œ] F := mfderiv I ๐“˜(๐•œ, F) ฯƒ x + cov ฯƒ x = d + A x (ฯƒ x) := by + use hcov.difference (trivial I M F |>.mono <| subset_univ s) + intro ฯƒ x hx hฯƒ + rw [hcov.difference_apply _ (by trivial) hฯƒ] + module + +noncomputable def one_form {cov : (M โ†’ F) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : + ฮ  x : M, F โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] F := + hcov.exists_one_form.choose + +lemma eq_one_form {cov : (M โ†’ F) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + {ฯƒ : M โ†’ F} + {x : M} (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ s := by trivial) : + letI d : TangentSpace I x โ†’L[๐•œ] F := mfderiv I ๐“˜(๐•œ, F) ฯƒ x + cov ฯƒ x = d + hcov.one_form x (ฯƒ x) := + hcov.exists_one_form.choose_spec ฯƒ x hx hฯƒ + +lemma _root_.CovariantDerivative.exists_one_form + (cov : CovariantDerivative I F (Bundle.Trivial M F)) : + โˆƒ (A : (x : M) โ†’ F โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] F), + โˆ€ ฯƒ : M โ†’ F, โˆ€ x, MDiffAt (T% ฯƒ) x โ†’ + letI d : TangentSpace I x โ†’L[๐•œ] F := mfderiv I ๐“˜(๐•œ, F) ฯƒ x + cov ฯƒ x = d + A x (ฯƒ x) := by + simpa using cov.isCovariantDerivativeOnUniv.exists_one_form + +end classification + +end IsCovariantDerivativeOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean new file mode 100644 index 00000000000000..874c1a5e272fdb --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/GramSchmidtOrtho.lean @@ -0,0 +1,410 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Analysis.InnerProductSpace.GramSchmidtOrtho +public import Mathlib.Analysis.SpecialFunctions.Sqrt +public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +public import Mathlib.Geometry.Manifold.VectorBundle.SmoothSection +public import Mathlib.Geometry.Manifold.Notation + +/-! +# Gram-Schmidt orthonormalisation on sections of Riemannian vector bundles + +In this file, we provide a version of the Gram-Schmidt orthonormalisation procedure +for sections of Riemannian vector bundles: this produces a system of sections which orthogonal +with respect to the bundle metric. If the initial sections were linearly independent resp. +formed a basis at the point, so do the normalised sections. + +If the bundle metric is `C^k`, then the procedure preserves regularity of sections: +if all sections are `C^k`, so are their normalised versions. + +This is used in `OrthonormalFrame.lean` to convert a local frame to a local orthonormal frame. + +## Implementation note + + +## Tags +vector bundle, bundle metric, orthonormal frame, Gram-Schmidt + +-/ + +open Manifold Bundle ContinuousLinearMap ENat Bornology +open scoped ContDiff Topology + +@[expose] public section -- FIXME: re-consider if we really want to expose all definitions + +-- Let `V` be a smooth vector bundle with a `C^n` Riemannian structure over a `C^k` manifold `B`. +variable + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace โ„ EB] + {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners โ„ EB HB} {n : WithTop โ„•โˆž} + {B : Type*} [TopologicalSpace B] [ChartedSpace HB B] + {F : Type*} [NormedAddCommGroup F] [NormedSpace โ„ F] + {E : B โ†’ Type*} [TopologicalSpace (TotalSpace F E)] [โˆ€ x, NormedAddCommGroup (E x)] + [โˆ€ x, InnerProductSpace โ„ (E x)] [FiberBundle F E] [VectorBundle โ„ F E] + [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] + +variable {ฮน : Type*} [LinearOrder ฮน] [LocallyFiniteOrderBot ฮน] [WellFoundedLT ฮน] + +attribute [local instance] IsWellOrder.toHasWellFounded + +local notation "โŸช" x ", " y "โŸซ" => inner โ„ x y + +open Finset + +namespace VectorBundle + +open Submodule + +/-- The Gram-Schmidt process takes a set of sections as input +and outputs a set of sections which are point-wise orthogonal with the same span. +Basically, we apply the Gram-Schmidt algorithm point-wise. -/ +noncomputable def gramSchmidt [WellFoundedLT ฮน] + (s : ฮน โ†’ (x : B) โ†’ E x) (n : ฮน) : (x : B) โ†’ E x := fun x โ†ฆ + InnerProductSpace.gramSchmidt โ„ (s ยท x) n + +-- Let `s i` be a collection of sections in `E`, indexed by `ฮน`. +variable {s : ฮน โ†’ (x : B) โ†’ E x} + +omit [TopologicalSpace B] + +variable (s) in +/-- This lemma uses `โˆ‘ i in` instead of `โˆ‘ i :`. -/ +theorem gramSchmidt_def (n : ฮน) (x) : + gramSchmidt s n x = s n x - โˆ‘ i โˆˆ Iio n, (โ„ โˆ™ gramSchmidt s i x).starProjection (s n x) := by + rw [gramSchmidt, InnerProductSpace.gramSchmidt_def] + congr + +variable (s) in +theorem gramSchmidt_def' (n : ฮน) (x) : + s n x = gramSchmidt s n x + โˆ‘ i โˆˆ Iio n, (โ„ โˆ™ gramSchmidt s i x).starProjection (s n x) := by + rw [gramSchmidt_def, sub_add_cancel] + +variable (s) in +theorem gramSchmidt_def'' (n : ฮน) (x) : + s n x = gramSchmidt s n x + โˆ‘ i โˆˆ Iio n, + (โŸชgramSchmidt s i x, s n xโŸซ / (โ€–gramSchmidt s i xโ€–) ^ 2) โ€ข gramSchmidt s i x := + InnerProductSpace.gramSchmidt_def'' โ„ (s ยท x) n + +variable (s) in +@[simp] +lemma gramSchmidt_apply (n : ฮน) (x) : + gramSchmidt s n x = InnerProductSpace.gramSchmidt โ„ (s ยท x) n := rfl + +variable (s) in +@[simp] +theorem gramSchmidt_bot {ฮน : Type*} [LinearOrder ฮน] [LocallyFiniteOrder ฮน] [OrderBot ฮน] + [WellFoundedLT ฮน] (s : ฮน โ†’ (x : B) โ†’ E x) : gramSchmidt s โŠฅ = s โŠฅ := by + ext x + apply InnerProductSpace.gramSchmidt_bot + +@[simp] +theorem gramSchmidt_zero (n : ฮน) : gramSchmidt (0 : ฮน โ†’ (x : B) โ†’ E x) n = 0 := by + ext x + simpa using InnerProductSpace.gramSchmidt_zero .. + +variable (s) in +/-- **Gram-Schmidt Orthogonalisation**: `gramSchmidt` produces a point-wise orthogonal system +of sections. -/ +theorem gramSchmidt_orthogonal {a b : ฮน} (hโ‚€ : a โ‰  b) (x) : + โŸชgramSchmidt s a x, gramSchmidt s b xโŸซ = 0 := + InnerProductSpace.gramSchmidt_orthogonal _ _ hโ‚€ + +variable (s) in +/-- This is another version of `gramSchmidt_orthogonal` using `Pairwise` instead. -/ +theorem gramSchmidt_pairwise_orthogonal (x) : + Pairwise fun a b โ†ฆ โŸชgramSchmidt s a x, gramSchmidt s b xโŸซ = 0 := + fun _ _ h โ†ฆ gramSchmidt_orthogonal s h _ + +variable (s) in +theorem gramSchmidt_inv_triangular {i j : ฮน} (hij : i < j) (x) : + โŸชgramSchmidt s j x, s i xโŸซ = 0 := + InnerProductSpace.gramSchmidt_inv_triangular _ _ hij + +open Submodule Set Order + +variable (s) in +theorem mem_span_gramSchmidt {i j : ฮน} (hij : i โ‰ค j) (x) : + s i x โˆˆ span โ„ ((gramSchmidt s ยท x) '' Set.Iic j) := + InnerProductSpace.mem_span_gramSchmidt _ _ hij + +variable (s) in +theorem gramSchmidt_mem_span (x) : + โˆ€ {j i}, i โ‰ค j โ†’ gramSchmidt s i x โˆˆ span โ„ ((s ยท x) '' Set.Iic j) := + InnerProductSpace.gramSchmidt_mem_span _ _ + +variable (s) in +theorem span_gramSchmidt_Iic (c : ฮน) (x) : + span โ„ ((gramSchmidt s ยท x) '' Set.Iic c) = span โ„ ((s ยท x) '' Set.Iic c) := + InnerProductSpace.span_gramSchmidt_Iic .. + +variable (s) in +theorem span_gramSchmidt_Iio (c : ฮน) (x) : + span โ„ ((gramSchmidt s ยท x) '' Set.Iio c) = span โ„ ((s ยท x) '' Set.Iio c) := + InnerProductSpace.span_gramSchmidt_Iio _ _ _ + +variable (s) in +/-- `gramSchmidt` preserves the point-wise span of sections. -/ +theorem span_gramSchmidt (x : B) : + span โ„ (range (gramSchmidt s ยท x)) = Submodule.span โ„ (range (s ยท x)) := + InnerProductSpace.span_gramSchmidt โ„ (s ยท x) + +/-- If the section values `s i x` are orthogonal, `gramSchmidt` yields the same values at `x`. -/ +theorem gramSchmidt_of_orthogonal {x} (hs : Pairwise fun i j โ†ฆ โŸชs i x, s j xโŸซ = 0) : + โˆ€ iโ‚€, gramSchmidt s iโ‚€ x = s iโ‚€ x:= by + simp_rw [gramSchmidt] + exact fun i โ†ฆ congrFun (InnerProductSpace.gramSchmidt_of_orthogonal โ„ hs) i + +theorem gramSchmidt_ne_zero_coe (n : ฮน) (x) + (hโ‚€ : LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic n โ†’ ฮน))) : gramSchmidt s n x โ‰  0 := + InnerProductSpace.gramSchmidt_ne_zero_coe _ hโ‚€ + +variable (s) in +/-- If the input sections of `gramSchmidt` are point-wise linearly independent, +the resulting sections are non-zero. -/ +theorem gramSchmidt_ne_zero (n : ฮน) {x} (hโ‚€ : LinearIndependent โ„ (s ยท x)) : + gramSchmidt s n x โ‰  0 := + InnerProductSpace.gramSchmidt_ne_zero _ hโ‚€ + +-- No version of `gramSchmidt_triangular` at the moment, for technical reasons: it would expect a +-- `Basis` (of vectors in `E x`) as input, whereas we would want a hypothesis "the section values +-- `s i x` form a basis" instead. + +/-- `gramSchmidt` produces point-wise linearly independent sections when given linearly +independent sections. -/ +theorem gramSchmidt_linearIndependent {x} (hโ‚€ : LinearIndependent โ„ (s ยท x)) : + LinearIndependent โ„ (gramSchmidt s ยท x) := + InnerProductSpace.gramSchmidt_linearIndependent hโ‚€ + +/-- When the sections `s` form a basis at `x`, so do the sections `gramSchmidt s`. -/ +noncomputable def gramSchmidtBasis {x} (hs : LinearIndependent โ„ (s ยท x)) + (hs' : โŠค โ‰ค Submodule.span โ„ (Set.range (s ยท x))) : + Module.Basis ฮน โ„ (E x) := + Module.Basis.mk (gramSchmidt_linearIndependent hs) + ((span_gramSchmidt s x).trans (eq_top_iff'.mpr fun _ โ†ฆ hs' trivial)).ge + +theorem coe_gramSchmidtBasis {x} (hs : LinearIndependent โ„ (s ยท x)) + (hs' : โŠค โ‰ค Submodule.span โ„ (Set.range (s ยท x))) : + (gramSchmidtBasis hs hs') = (gramSchmidt s ยท x) := + Module.Basis.coe_mk _ _ + +noncomputable def gramSchmidtNormed [WellFoundedLT ฮน] + (s : ฮน โ†’ (x : B) โ†’ E x) (n : ฮน) : (x : B) โ†’ E x := fun x โ†ฆ + InnerProductSpace.gramSchmidtNormed โ„ (s ยท x) n + +lemma gramSchmidtNormed_coe {n : ฮน} {x} : + gramSchmidtNormed s n x = โ€–gramSchmidt s n xโ€–โปยน โ€ข gramSchmidt s n x := by + simp [gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed] + +variable {x} + +theorem gramSchmidtNormed_unit_length_coe (n : ฮน) + (hโ‚€ : LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic n โ†’ ฮน))) : + โ€–gramSchmidtNormed s n xโ€– = 1 := + InnerProductSpace.gramSchmidtNormed_unit_length_coe n hโ‚€ + +theorem gramSchmidtNormed_unit_length (n : ฮน) (hโ‚€ : LinearIndependent โ„ (s ยท x)) : + โ€–gramSchmidtNormed s n xโ€– = 1 := + InnerProductSpace.gramSchmidtNormed_unit_length n hโ‚€ + +theorem gramSchmidtNormed_unit_length' {n : ฮน} (hn : gramSchmidtNormed s n x โ‰  0) : + โ€–gramSchmidtNormed s n xโ€– = 1 := + InnerProductSpace.gramSchmidtNormed_unit_length' hn + +/-- **Gram-Schmidt Orthonormalization**: `gramSchmidtNormed` applied to a point-wise linearly +independent set of sections produces a point-wise orthornormal system of sections. -/ +theorem gramSchmidtNormed_orthonormal (hโ‚€ : LinearIndependent โ„ (s ยท x)) : + Orthonormal โ„ (gramSchmidtNormed s ยท x) := + InnerProductSpace.gramSchmidtNormed_orthonormal hโ‚€ + +variable (s) in +/-- **Gram-Schmidt Orthonormalization**: `gramSchmidtNormed` produces a point-wise orthornormal +system of sections after removing the sections which become zero in the process. -/ +theorem gramSchmidtNormed_orthonormal' (x) : + Orthonormal โ„ fun i : { i | gramSchmidtNormed s i x โ‰  0 } => gramSchmidtNormed s i x := + InnerProductSpace.gramSchmidtNormed_orthonormal' _ + +open Submodule Set Order + +variable (s) in +theorem span_gramSchmidtNormed (t : Set ฮน) (x) : + span โ„ ((gramSchmidtNormed s ยท x) '' t) = span โ„ ((gramSchmidt s ยท x) '' t) := + InnerProductSpace.span_gramSchmidtNormed (s ยท x) t + +variable (s) in +theorem span_gramSchmidtNormed_range (x) : + span โ„ (range (gramSchmidtNormed s ยท x)) = span โ„ (range (gramSchmidt s ยท x)) := by + simpa only [image_univ.symm] using span_gramSchmidtNormed s Set.univ x + +/-- `gramSchmidtNormed` applied to linearly independent sections at a point `x` produces +sections which are linearly independent at `x`. -/ +theorem gramSchmidtNormed_linearIndependent (hโ‚€ : LinearIndependent โ„ (s ยท x)) : + LinearIndependent โ„ (gramSchmidtNormed s ยท x) := by + simp [gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed_linearIndependent hโ‚€] + +lemma gramSchmidtNormed_apply_of_orthogonal (hs : Pairwise fun i j โ†ฆ โŸชs i x, s j xโŸซ = 0) {i : ฮน} : + gramSchmidtNormed s i x = (โ€–s i xโ€–โปยน : โ„) โ€ข s i x := by + simp_rw [gramSchmidtNormed_coe, gramSchmidt_of_orthogonal hs i] + +/-- If the section values `s i x` are orthonormal, applying `gramSchmidtNormed` yields the same +values at `x`. -/ +lemma gramSchmidtNormed_apply_of_orthonormal {x} (hs : Orthonormal โ„ (s ยท x)) (i : ฮน) : + gramSchmidtNormed s i x = s i x := by + simp [gramSchmidtNormed_apply_of_orthogonal hs.2, hs.1 i] + +-- TODO: comment on the different design compared to `InnerProductSpace.gramSchmidtOrthonormalBasis` + +/-- When the sections `s` form a basis at `x`, so do the sections `gramSchmidtNormed s`. + +Prefer using `gramSchmidtOrthonormalBasis` over this declaration. -/ +noncomputable def gramSchmidtNormedBasis {x} (hs : LinearIndependent โ„ (s ยท x)) + (hs' : โŠค โ‰ค Submodule.span โ„ (Set.range (s ยท x))) : + Module.Basis ฮน โ„ (E x) := + Module.Basis.mk (v := fun i โ†ฆ gramSchmidtNormed s i x) (gramSchmidtNormed_linearIndependent hs) + (by rw [span_gramSchmidtNormed_range s x, span_gramSchmidt s x]; exact hs') + +/-- Prefer using `gramSchmidtOrthonormalBasis` over this declaration. -/ +@[simp] +theorem coe_gramSchmidtNormedBasis {x} (hs : LinearIndependent โ„ (s ยท x)) + (hs' : โŠค โ‰ค Submodule.span โ„ (Set.range (s ยท x))) : + (gramSchmidtNormedBasis hs hs' : ฮน โ†’ E x) = (gramSchmidtNormed s ยท x) := + Module.Basis.coe_mk _ _ + +noncomputable def gramSchmidtOrthonormalBasis {x} [Fintype ฮน] + (hs : LinearIndependent โ„ (s ยท x)) (hs' : โŠค โ‰ค Submodule.span โ„ (Set.range (s ยท x))) : + OrthonormalBasis ฮน โ„ (E x) := by + apply (gramSchmidtNormedBasis hs hs').toOrthonormalBasis + simp [gramSchmidtNormed_orthonormal hs] + +@[simp] +theorem gramSchmidtOrthonormalBasis_coe [Fintype ฮน] {x} (hs : LinearIndependent โ„ (s ยท x)) + (hs' : โŠค โ‰ค Submodule.span โ„ (Set.range (s ยท x))) : + (gramSchmidtOrthonormalBasis hs hs' : ฮน โ†’ E x) = (gramSchmidtNormed s ยท x) := by + simp [gramSchmidtOrthonormalBasis] + +theorem gramSchmidtOrthonormalBasis_apply_of_orthonormal [Fintype ฮน] {x} + (hs : Orthonormal โ„ (s ยท x)) (hs' : โŠค โ‰ค Submodule.span โ„ (Set.range (s ยท x))) : + (gramSchmidtOrthonormalBasis hs.linearIndependent hs') = (s ยท x) := by + simp [gramSchmidtNormed_apply_of_orthonormal hs] + +end VectorBundle + +/-! The Gram-Schmidt process preserves smoothness of sections -/ + +variable {n : WithTop โ„•โˆž} + +variable [IsContMDiffRiemannianBundle IB n F E] + +section helper + +variable {s t : (x : B) โ†’ E x} {u : Set B} {x : B} + +-- TODO: give a much better name! +lemma contMDiffWithinAt_aux + (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x โ‰  0) : + CMDiffAt[u] n (fun x โ†ฆ โŸชs x, t xโŸซ / (โ€–s xโ€– ^ 2)) x := by + have := (hs.inner_bundle ht).smul ((hs.inner_bundle hs).invโ‚€ (inner_self_ne_zero.mpr hs')) + apply this.congr + ยท intro y hy + congr + simp [inner_self_eq_norm_sq_to_K] + ยท congr + rw [โ† real_inner_self_eq_norm_sq] + +lemma contMDiffAt_aux (hs : CMDiffAt n (T% s) x) (ht : CMDiffAt n (T% t) x) (hs' : s x โ‰  0) : + CMDiffAt n (fun x โ†ฆ โŸชs x, t xโŸซ / (โ€–s xโ€– ^ 2)) x := by + rw [โ† contMDiffWithinAt_univ] at hs ht โŠข + exact contMDiffWithinAt_aux hs ht hs' + +def ContMDiffWithinAt.orthogonalProjection + (hs : CMDiffAt[u] n (T% s) x) (ht : CMDiffAt[u] n (T% t) x) (hs' : s x โ‰  0) : + CMDiffAt[u] n (T% (fun x โ†ฆ (Submodule.span โ„ {s x}).starProjection (t x))) x := by + simp_rw [Submodule.starProjection_singleton] + exact (contMDiffWithinAt_aux hs ht hs').smul_section hs + +lemma contMDiffWithinAt_inner (hs : CMDiffAt[u] n (T% s) x) (hs' : s x โ‰  0) : + CMDiffAt[u] n (โ€–s ยทโ€–) x := by + let F (x) := โŸชs x, s xโŸซ + have aux : CMDiffAt[u] n (Real.sqrt โˆ˜ F) x := by + have h1 : CMDiffAt[(F '' u)] n (Real.sqrt) (F x) := by + apply ContMDiffAt.contMDiffWithinAt + rw [contMDiffAt_iff_contDiffAt] + exact Real.contDiffAt_sqrt (by simp [F, hs']) + exact h1.comp x (hs.inner_bundle hs) (Set.mapsTo_image _ u) + convert aux + simp [F] + +end helper + +variable {s : ฮน โ†’ (x : B) โ†’ E x} {u : Set B} {x : B} {i : ฮน} + +lemma gramSchmidt_contMDiffWithinAt (hs : โˆ€ i, CMDiffAt[u] n (T% (s i)) x) + {i : ฮน} (hs' : LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) : + CMDiffAt[u] n (T% (VectorBundle.gramSchmidt s i)) x := by + -- XXX: this `suffices` used to be just `simp only [VectorBundle.gramSchmidt_def]` + suffices CMDiffAt[u] n (T% (fun x โ†ฆ s i x - โˆ‘ j โˆˆ Iio i, + (โ„ โˆ™ VectorBundle.gramSchmidt s j x).starProjection (s i x))) x by + simp_rw [VectorBundle.gramSchmidt] + apply this.congr + ยท intro x hx + rw [InnerProductSpace.gramSchmidt_def]; simp + ยท rw [InnerProductSpace.gramSchmidt_def]; simp + apply (hs i).sub_section + apply ContMDiffWithinAt.sum_section + intro i' hi' + let aux : { x // x โˆˆ Set.Iic i' } โ†’ { x // x โˆˆ Set.Iic i } := + fun โŸจx, hxโŸฉ โ†ฆ โŸจx, hx.trans (Finset.mem_Iio.mp hi').leโŸฉ + have : LinearIndependent โ„ ((fun x_1 โ†ฆ s x_1 x) โˆ˜ @Subtype.val ฮน fun x โ†ฆ x โˆˆ Set.Iic i') := by + apply hs'.comp aux + intro โŸจx, hxโŸฉ โŸจx', hx'โŸฉ h + simp_all only [Subtype.mk.injEq, aux] + apply ContMDiffWithinAt.orthogonalProjection (gramSchmidt_contMDiffWithinAt hs this) (hs i) + apply VectorBundle.gramSchmidt_ne_zero_coe _ _ this +termination_by i +decreasing_by exact (LocallyFiniteOrderBot.finset_mem_Iio i i').mp hi' + +lemma gramSchmidt_contMDiffAt (hs : โˆ€ i, CMDiffAt n (T% (s i)) x) + (hs' : LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) : + CMDiffAt n (T% (VectorBundle.gramSchmidt s i)) x := + contMDiffWithinAt_univ.mpr <| gramSchmidt_contMDiffWithinAt (fun i โ†ฆ hs i) hs' + +lemma gramSchmidt_contMDiffOn (hs : โˆ€ i, CMDiff[u] n (T% (s i))) + (hs' : โˆ€ x โˆˆ u, LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) : + CMDiff[u] n (T% (VectorBundle.gramSchmidt s i)) := + fun x hx โ†ฆ gramSchmidt_contMDiffWithinAt (fun i โ†ฆ hs i x hx) (hs' _ hx) + +lemma gramSchmidt_contMDiff (hs : โˆ€ i, CMDiff n (T% (s i))) + (hs' : โˆ€ x, LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) : + CMDiff n (T% (VectorBundle.gramSchmidt s i)) := + fun x โ†ฆ gramSchmidt_contMDiffAt (fun i โ†ฆ hs i x) (hs' x) + +lemma gramSchmidtNormed_contMDiffWithinAt (hs : โˆ€ i, CMDiffAt[u] n (T% (s i)) x) + (hs' : LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) : + CMDiffAt[u] n (T% (VectorBundle.gramSchmidtNormed s i)) x := by + have : CMDiffAt[u] n (T% + (fun x โ†ฆ โ€–VectorBundle.gramSchmidt s i xโ€–โปยน โ€ข VectorBundle.gramSchmidt s i x)) x := by + refine ContMDiffWithinAt.smul_section ?_ (gramSchmidt_contMDiffWithinAt hs hs') + refine ContMDiffWithinAt.invโ‚€ ?_ ?_ + ยท refine contMDiffWithinAt_inner (gramSchmidt_contMDiffWithinAt hs hs') ?_ + simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' + ยท simpa using InnerProductSpace.gramSchmidt_ne_zero_coe i hs' + exact this.congr (fun y hy โ†ฆ by congr) (by congr) + +lemma gramSchmidtNormed_contMDiffAt (hs : โˆ€ i, CMDiffAt n (T% (s i)) x) + (hs' : LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) + : CMDiffAt n (T% (VectorBundle.gramSchmidtNormed s i)) x := + contMDiffWithinAt_univ.mpr <| gramSchmidtNormed_contMDiffWithinAt (fun i โ†ฆ hs i) hs' + +lemma gramSchmidtNormed_contMDiffOn (hs : โˆ€ i, CMDiff[u] n (T% (s i))) + (hs' : โˆ€ x โˆˆ u, LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) : + CMDiff[u] n (T% (VectorBundle.gramSchmidtNormed s i)) := + fun x hx โ†ฆ gramSchmidtNormed_contMDiffWithinAt (fun i โ†ฆ hs i x hx) (hs' _ hx) + +lemma gramSchmidtNormed_contMDiff (hs : โˆ€ i, CMDiff n (T% (s i))) + (hs' : โˆ€ x, LinearIndependent โ„ ((s ยท x) โˆ˜ ((โ†‘) : Set.Iic i โ†’ ฮน))) : + CMDiff n (T% (VectorBundle.gramSchmidtNormed s i)) := + fun x โ†ฆ gramSchmidtNormed_contMDiffAt (fun i โ†ฆ hs i x) (hs' x) diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean index be3e858a823f63..c33a2f36d88ea6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Hom.lean @@ -6,6 +6,7 @@ Authors: Floris van Doorn module public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality public import Mathlib.Topology.VectorBundle.Hom public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable public import Mathlib.Geometry.Manifold.Notation @@ -304,6 +305,22 @@ lemma ContMDiff.clm_bundle_apply ContMDiff IM (IB.prod ๐“˜(๐•œ, Fโ‚‚)) n (fun m โ†ฆ TotalSpace.mk' Fโ‚‚ (b m) (ฯ• m (v m))) := fun x โ†ฆ (hฯ• x).clm_bundle_apply (hv x) +/-- Criterion for a section of a Hom-bundle constructed using the tensoriality criterion to be +smooth. -/ +theorem TensorialAt.contMDiff_mkHom [CompleteSpace ๐•œ] [IsManifold IB 1 B] + [FiniteDimensional ๐•œ Fโ‚] + [โˆ€ (x : B), IsTopologicalAddGroup (Eโ‚ x)] [โˆ€ (x : B), ContinuousSMul ๐•œ (Eโ‚ x)] + [ContMDiffVectorBundle 1 Fโ‚ Eโ‚ IB] + (ฯ† : (ฮ  x : B, Eโ‚ x) โ†’ (ฮ  x, Eโ‚‚ x)) + (hฯ† : โˆ€ x, TensorialAt IB Fโ‚ (ฯ† ยท x) x) + -- hopefully this is the correct smoothness criterion! + {k} (ฯ†_contMDiff : โˆ€ (ฯƒ : ฮ  x : B, Eโ‚ x), CMDiff k (T% ฯƒ) โ†’ CMDiff k (T% (ฯ† ฯƒ))) : + -- elaborators not working here + let T (x : B) : TotalSpace (Fโ‚ โ†’L[๐•œ] Fโ‚‚) (fun x โ†ฆ Eโ‚ x โ†’L[๐•œ] Eโ‚‚ x) := + โŸจx, TensorialAt.mkHom (ฯ† ยท x) x (hฯ† x)โŸฉ + ContMDiff IB (IB.prod ๐“˜(๐•œ, Fโ‚ โ†’L[๐•œ] Fโ‚‚)) k T := by + sorry + end OneVariable section OneVariable' diff --git a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index 81da73c9e73b5f..d1213dd5361671 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean @@ -32,8 +32,8 @@ complete field). In the planned file `Mathlib/Geometry/Manifold/VectorBundle/Ort metric. This includes bundles of finite rank, modelled on a Hilbert space or on a Banach space which has smooth partitions of unity. -We will use this to construct local extensions of a vector to a section which is smooth on the -trivialisation domain. +We also use this to extend a vector in a single fiber `V x` to a section near `x` which is +smooth on the trivialisation domain. ## Main definitions and results @@ -83,6 +83,18 @@ the model fiber `F`. * `e.contMDiffOn_iff_localFrame_coeff b`: a section `s` is `C^k` on an open set `t โІ e.baseSet` iff all of its frame coefficients are +A local frame can be used to extend any single vector `v : V x` to a section which is smooth near +`x`, such that the construction is linear in `v`. +* `localExtensionOn b e v`: given a basis `b` and a compatible trivialisation `e` of `V` near `x`, + extend the vector `v : V x` to a section of `V` which is smooth on `e.baseSet` +* `localExtensionOn_apply_self`: `localExtensionOn b e v x = v`, i.e. we really extend `v` at `x` +* `contMDiffOn_localExtensionOn`: `localExtensionOn b e v` is `C^n` on `e.baseSet` +* `localExtensionOn_localFrame_coeff`: `localExtensionOn` has constant frame coefficients + (knowing this is sometimes useful when working with local extensions for covariant derivatives) +* `localExtensionOn_add`, `localExtensionOn_zero` and `localExtensionOn_smul` prove that + `v โ†ฆ localExtensionON b e v` is a linear map. + + ## Note This file proves smoothness criteria in terms of coefficients for local frames induced by a @@ -93,8 +105,15 @@ trivialization. A fully frame-intrinsic converse for `IsLocalFrameOn` will be ad Local frames use the junk value pattern: they are defined on all of `M`, but their value is only meaningful on the set on which they are a local frame. +Note that `localExtensionOn` need not be smooth globally; in turn, this definition makes sense over +any field. In contrast, an extension to a global holomorphic vector field is more delicate for +complex vector bundles (whereas *locally* holomorphic sections always exist). +For real bundles, global extensions always exist and can be constructed by scalar multiplication +of a local extension with a smooth bump function of sufficiently small support. + + ## Tags -vector bundle, local frame, smoothness +vector bundle, local frame, smoothness, local extension of section -/ @@ -569,3 +588,76 @@ lemma mdifferentiableAt_iff_localFrame_coeff (hx : x' โˆˆ e.baseSet) : end MDifferentiable end + +-- local extension of a vector field in a trivialisation's base set +section localExtensionOn + +variable {e : Trivialization F (TotalSpace.proj : TotalSpace F V โ†’ M)} [MemTrivializationAtlas e] + {ฮน : Type*} [Fintype ฮน] {b : Basis ฮน ๐•œ F} {x x' : M} + [VectorBundle ๐•œ F V] + +open scoped Classical in +/-- Extend a vector `v โˆˆ V x` to a section `s` of the bundle `V` which is smooth near `x`, +such that `s x = v` and this construction is linear in `v`. + +The details of this extension are unspecified (and could be subject to change). +Currently, we construct this extension using a local frame induced by a choose of basis of the +fibre `F` and a compatible trivialisation `e` of `V` around `x`. +(Allowing any local frame near `x` would be easy to implement.) +Our construction has constant coefficients on `e.baseSet` w.r.t. this local frame, and is zero +otherwise. In particular, it is smooth on `e.baseSet`, and (globally) linear in `v`. + +We choose an extension with these particularly nice properties because this simplifies later +constructions on covariant derivatives (and in this context, the value at `s` at points other than +`x` does not matter, but constant frame coefficients are useful). +-/ +-- XXX: we could generalise this definition to any local frame on `U โˆ‹ x`, with smoothness on `U`. +-- Would this be useful? Should do this? +noncomputable def localExtensionOn (b : Basis ฮน ๐•œ F) + (e : Trivialization F (TotalSpace.proj : TotalSpace F V โ†’ M)) [MemTrivializationAtlas e] + {x : M} : V x โ†’โ‚—[๐•œ] ((x' : M) โ†’ V x') where + toFun v := open scoped Classical in + fun x' โ†ฆ if hx : x โˆˆ e.baseSet then โˆ‘ i, (e.basisAt b hx).repr v i โ€ข e.localFrame b i x' else 0 + map_add' v v' := by + ext x' + by_cases hx: x โˆˆ e.baseSet; swap + ยท simp [hx] + ยท simp [hx, add_smul, Finset.sum_add_distrib] + map_smul' a v := by + ext x' + by_cases hx: x โˆˆ e.baseSet; swap + ยท simp [hx] + ยท simp +contextual [hx, Finset.smul_sum, mul_smul a (((e.basisAt b hx).repr v) _)] + +variable (b e) in +@[simp] +lemma localExtensionOn_apply_self (hx : x โˆˆ e.baseSet) (v : V x) : + (localExtensionOn b e v) x = v := by + simp [localExtensionOn, hx] + +variable (b) in +/-- A local extension has constant frame coefficients within its defining trivialisation. -/ +lemma localExtensionOn_localFrame_coeff [ContMDiffVectorBundle 1 F V I] + (hx : x โˆˆ e.baseSet) (hx' : x' โˆˆ e.baseSet) (v : V x) (i : ฮน) : + (Trivialization.localFrame_coeff I e b i x') ((localExtensionOn b e) v x') = + (Trivialization.localFrame_coeff I e b i x) ((localExtensionOn b e) v x) := by + -- Combining these into one `simp` call makes these lemmas never fire. + rw [e.localFrame_coeff_apply_of_mem_baseSet b hx ((localExtensionOn b e) v) i, + e.localFrame_coeff_apply_of_mem_baseSet b hx' ((localExtensionOn b e) v) i] + simp [localExtensionOn, hx, hx'] + +variable (F) in +lemma contMDiffOn_localExtensionOn [FiniteDimensional ๐•œ F] [CompleteSpace ๐•œ] + {x : M} (hx : x โˆˆ e.baseSet) (v : V x) [ContMDiffVectorBundle โˆž F V I] : + CMDiff[e.baseSet] โˆž (T% (localExtensionOn b e v)) := by + -- The local frame coefficients of `localExtensionOn` w.r.t. the frame induced by `e` are + -- constant, hence smoothness follows. + rw [contMDiffOn_baseSet_iff_localFrame_coeff b] + intro i + simp only [LinearMap.piApply_apply] + apply (contMDiffOn_const + (c := (Trivialization.localFrame_coeff I e b i x) ((localExtensionOn b e) v x))).congr + intro y hy + rw [localExtensionOn_localFrame_coeff b hx hy v i] + +end localExtensionOn diff --git a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean index aec2e6a784de3f..9eaa0acf875db6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -17,9 +17,8 @@ import Mathlib.Geometry.Manifold.Notation public section -open Bundle Set OpenPartialHomeomorph ContinuousLinearMap Pretrivialization Filter - -open scoped Manifold Bundle Topology +open Bundle Set ContinuousLinearMap Pretrivialization Filter +open scoped Manifold Topology section diff --git a/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean new file mode 100644 index 00000000000000..c40c1046cd0331 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean @@ -0,0 +1,243 @@ +/- +Copyright (c) 2025 Michael Rothgang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.VectorBundle.GramSchmidtOrtho +public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame + +/-! +# Existence of orthonormal frames on Riemannian vector bundles + +In this file, we prove that a Riemannian vector bundle has orthonormal frames near each point. +These are constructed by taking any local frame, and applying Gram-Schmidt orthonormalisation +to it (point-wise). If the bundle metric is `C^k`, the resulting orthonormal frame also is. + +TODO: add main results, etc + +## Implementation note + +Like local frames, orthonormal frames use the junk value pattern: their value is meaningless +outside of the `baseSet` of the trivialisation used to define them. + +## Tags +vector bundle, local frame, smoothness + +-/ + +open Manifold Bundle ContinuousLinearMap ENat Bornology +open scoped ContDiff Topology + +-- Let `V` be a smooth vector bundle with a `C^n` Riemannian structure over a `C^k` manifold `B`. +variable + {EB : Type*} [NormedAddCommGroup EB] [NormedSpace โ„ EB] + {HB : Type*} [TopologicalSpace HB] {IB : ModelWithCorners โ„ EB HB} + {B : Type*} [TopologicalSpace B] [ChartedSpace HB B] + {F : Type*} [NormedAddCommGroup F] [NormedSpace โ„ F] + {E : B โ†’ Type*} [TopologicalSpace (TotalSpace F E)] [โˆ€ x, NormedAddCommGroup (E x)] + [โˆ€ x, InnerProductSpace โ„ (E x)] [FiberBundle F E] [VectorBundle โ„ F E] {n : WithTop โ„•โˆž} + [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] + +@[expose] public section -- FIXME: think if expose is desired! + +local notation "โŸช" x ", " y "โŸซ" => inner โ„ x y + +variable {ฮน : Type*} [LinearOrder ฮน] [LocallyFiniteOrderBot ฮน] [WellFoundedLT ฮน] + +variable {s : ฮน โ†’ (x : B) โ†’ E x} {u u' : Set B} + +variable (IB F n) in +structure IsOrthonormalFrameOn (s : ฮน โ†’ (x : B) โ†’ E x) (u : Set B) + extends IsLocalFrameOn IB F n s u where + orthonormal {x} : x โˆˆ u โ†’ Orthonormal โ„ (s ยท x) + -- /-- Any two distinct sections are point-wise orthogonal on `u`. -/ + -- orthogonal {i j : ฮน} {x : B} : i โ‰  j โ†’ x โˆˆ u โ†’ โŸชs i x, s j xโŸซ = 0 + -- normalised {i : ฮน} {x : B} : x โˆˆ u โ†’ โ€–s i xโ€– = 1 + +omit [VectorBundle โ„ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] + [LinearOrder ฮน] [LocallyFiniteOrderBot ฮน] [WellFoundedLT ฮน] in +lemma IsOrthonormalFrameOn.mono (hs : IsOrthonormalFrameOn IB F n s u) (huu' : u' โІ u) : + IsOrthonormalFrameOn IB F n s u' where + toIsLocalFrameOn := hs.toIsLocalFrameOn.mono huu' + orthonormal hx := hs.orthonormal (huu' hx) + +/-- Applying the Gram-Schmidt procedure to a local frame yields an orthonormal local frame. -/ +def IsLocalFrameOn.gramSchmidtNormed (hs : IsLocalFrameOn IB F n s u) : + IsOrthonormalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u where + linearIndependent := by + intro x hx + exact VectorBundle.gramSchmidtNormed_linearIndependent <| hs.linearIndependent hx + generating := by + intro x hx + simpa only [VectorBundle.span_gramSchmidtNormed_range, VectorBundle.gramSchmidt_apply, + InnerProductSpace.span_gramSchmidt] using hs.generating hx + contMDiffOn i := gramSchmidtNormed_contMDiffOn (fun i โ†ฆ hs.contMDiffOn i) <| + fun x hx โ†ฆ (hs.linearIndependent hx).comp _ Subtype.val_injective + orthonormal hx := (VectorBundle.gramSchmidtNormed_orthonormal (hs.linearIndependent hx)) + +-- XXX: is this one necessary? +/-- Applying the normalised Gram-Schmidt procedure to an orthonormal local frame yields +another orthonormal local frame. -/ +def IsOrthonormalFrameOn.gramSchmidtNormed (hs : IsOrthonormalFrameOn IB F n s u) : + IsOrthonormalFrameOn IB F n (VectorBundle.gramSchmidtNormed s) u := + hs.toIsLocalFrameOn.gramSchmidtNormed + +/-! # Determining smoothness of a section via its local frame coefficients + +We show that for any orthogonal local frame `{s i}` on `u โІ B`, a section `t` is smooth on `u` +if and only if its coefficients in `{s i}` are. This argument crucially depends on the existence of +a smooth bundle metric on `V` (which always holds in finite dimensions, and in certain important +infinite-dimensional cases). + +See `LocalFrame.lean` for a similar statement, about local frames induced by a local trivialisation +on finite rank bundles over any complete field. + +The orthogonality requirement can be removed, with additional technical effort: see the comment +below for details. It simplifies the proofs as the local frame coefficients take a particularly +simple form in orthgonal frames. +-/ + +section smoothness + +namespace IsOrthonormalFrameOn + +omit [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] +variable [Fintype ฮน] + +variable (hs : IsOrthonormalFrameOn IB F n s u) {t : (x : B) โ†’ E x} {x : B} + +omit [VectorBundle โ„ F E] [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] + [IsContMDiffRiemannianBundle IB n F E] in +variable (t) in +lemma coeff_eq_inner' (hs : IsOrthonormalFrameOn IB F n s u) (hx : x โˆˆ u) (i : ฮน) : + hs.coeff i x (t x) = โŸชs i x, t xโŸซ := by + let b := VectorBundle.gramSchmidtOrthonormalBasis (hs.linearIndependent hx) (hs.generating hx) + have beq (i : ฮน) : b i = s i x := by + simp [b, VectorBundle.gramSchmidtNormed_apply_of_orthonormal (hs.orthonormal hx) i] + have heq' : b.toBasis = hs.toBasisAt hx := by + ext i + simp [b, VectorBundle.gramSchmidtNormed_apply_of_orthonormal (hs.orthonormal hx) i] + have aux := b.repr_apply_apply (t x) i + rw [beq] at aux + simp [โ† aux, IsLocalFrameOn.coeff, hx, โ† heq'] + +-- This lemma would hold more generally for an *orthogonal frame*. +-- variable (t) in +-- lemma coeff_eq_inner (hs : IsOrthonormalFrameOn IB F n s u) (hx : x โˆˆ u) (i : ฮน) : +-- hs.coeff i t x = โŸชs i x, t xโŸซ / (โ€–s i xโ€– ^ 2) := by +-- sorry -- need a version of b.repr_apply_apply for *orthogonal* bases + +/-- If `t` is `C^k` at `x`, so is its coefficient `hs.coeff i t` in a local frame s near `x` -/ +lemma contMDiffWithinAt_coeff (ht : CMDiffAt[u] n (T% t) x) (hx : x โˆˆ u) (i : ฮน) : + CMDiffAt[u] n (LinearMap.piApply (hs.coeff i) t) x := + ((hs.contMDiffOn i x hx).inner_bundle ht).congr_of_mem (fun _ hy โ†ฆ hs.coeff_eq_inner' _ hy _) hx + +omit [IsManifold IB n B] [ContMDiffVectorBundle n F E IB] in +/-- If `t` is `C^k` at `x`, so is its coefficient `hs.coeff i t` in a local frame s near `x` -/ +lemma contMDiffAt_coeff (hu : u โˆˆ ๐“ x) (ht : CMDiffAt n (T% t) x) (i : ฮน) : + CMDiffAt n (LinearMap.piApply (hs.coeff i) t) x := + (((hs.contMDiffOn i).contMDiffAt hu).inner_bundle ht).congr_of_eventuallyEq <| + Filter.eventually_of_mem hu fun _ hx โ†ฆ hs.coeff_eq_inner' _ hx _ + +-- Future: prove the same result for all local frames +-- if `{s i}` is a local frame on `u`, and `{s' i}` are the corresponding orthogonalised frame, +-- for each `x โˆˆ u` the vectors `{s i x}` and `{s' i x}` are bases of `E x`, +-- and the coefficients w.r.t. `s i` and `s' i x` are related by the base change matrix. +-- This matrix depends smoothly on `x`, hence the frame coefficients w.r.t. `{s i}` are smooth iff +-- those w.r.t. `{s' i}` are. + +/-- If `{s i}` is an orthogonal local frame on a neighbourhood `u` of `x` and `t` is `C^k` on `u`, +so is its coefficient in the frame `{s i}`. -/ +lemma contMDiffOn_coeff (ht : CMDiff[u] n (T% t)) (i : ฮน) : + CMDiff[u] n (LinearMap.piApply (hs.coeff i) t) := + fun x' hx โ†ฆ hs.contMDiffWithinAt_coeff (ht x' hx) hx _ + +/-- A section `s` of `V` is `C^k` at `x` iff each of its coefficients in an orthogonal +local frame near `x` is. -/ +lemma contMDiffAt_iff_coeff [FiniteDimensional โ„ F] (hu : u โˆˆ ๐“ x) : + CMDiffAt n (T% t) x โ†” โˆ€ i, CMDiffAt n (LinearMap.piApply (hs.coeff i) t) x := + โŸจfun h i โ†ฆ hs.contMDiffAt_coeff hu h i, fun h โ†ฆ hs.contMDiffAt_of_coeff h huโŸฉ + +/-- If `{s i}` is an orthogonal local frame on `s`, a section `s` of `V` is `C^k` on `u` iff +each of its coefficients `hs.coeff i s` w.r.t. the local frame `{s i}` is. -/ +lemma contMDiffOn_iff_coeff [FiniteDimensional โ„ F] : + CMDiff[u] n (T% t) โ†” โˆ€ i, CMDiff[u] n (LinearMap.piApply (hs.coeff i) t) := + โŸจfun h i โ†ฆ hs.contMDiffOn_coeff h i, fun hi โ†ฆ hs.contMDiffOn_of_coeff hiโŸฉ + +-- unused, just stating for convenience/nice API +include hs in +lemma contMDiffAt_iff_coeff' [FiniteDimensional โ„ F] (hu : u โˆˆ ๐“ x) : + CMDiffAt n (T% t) x โ†” โˆ€ i, CMDiffAt n (fun x โ†ฆ โŸชs i x, t xโŸซ) x := by + rw [hs.contMDiffAt_iff_coeff hu] + have (i : ฮน) := Filter.eventually_of_mem hu fun x hx โ†ฆ (hs.coeff_eq_inner' t hx i) + exact โŸจfun h i โ†ฆ (h i).congr_of_eventuallyEq <| Filter.EventuallyEq.symm (this i), + fun h i โ†ฆ (h i).congr_of_eventuallyEq (this i)โŸฉ + +-- unused, just stating for convenience/nice API +lemma contMDiffOn_iff_coeff' : + CMDiff[u] n (T% t) โ†” โˆ€ i, CMDiff[u] n (fun x โ†ฆ โŸชs i x, t xโŸซ) := + sorry -- similar to the above lemma + +end IsOrthonormalFrameOn + +end smoothness + +namespace Module.Basis + +variable {b : Basis ฮน โ„ F} + {e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E โ†’ B)} + [MemTrivializationAtlas e] {x : B} -- (hx : x โˆˆ e.baseSet) + +variable (b e) in +/-- The orthonormal frame associated to the basis `b` and the trivialisation `e`: +this is obtained by applying the Gram-Schmidt orthonormalisation procedure to `b.localFrame e`. +In particular, if x is outside of `e.baseSet`, this returns the junk value 0. -/ +noncomputable def orthonormalFrame : ฮน โ†’ (x : B) โ†’ E x := + VectorBundle.gramSchmidtNormed (e.localFrame b) + +omit [IsManifold IB n B] in +variable (b e) in +/-- An orthonormal frame w.r.t. a local trivialisation is an orthonormal local frame. -/ +lemma orthonormalFrame_isOrthonormalFrameOn : + IsOrthonormalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := + (e.isLocalFrameOn_localFrame_baseSet IB n b).gramSchmidtNormed + +omit [IsManifold IB n B] in +variable (b e) in +/-- Each orthonormal frame `s^i โˆˆ ฮ“(E)` of a `C^k` vector bundle, defined by a local +trivialisation `e`, is `C^k` on `e.baseSet`. -/ +lemma contMDiffOn_orthonormalFrame_baseSet (i : ฮน) : + CMDiff[e.baseSet] n (T% (b.orthonormalFrame e i)) := by + apply IsLocalFrameOn.contMDiffOn + exact (b.orthonormalFrame_isOrthonormalFrameOn e).toIsLocalFrameOn + +omit [IsManifold IB n B] in +variable (b e) in +lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ฮน) {x : B} (hx : x โˆˆ e.baseSet) : + CMDiffAt n (T% (b.orthonormalFrame e i)) x := + -- bug: if I change this to a by apply, and put #check after the `by`, it works, but #check' fails + -- #check' contMDiffOn_orthonormalFrame_baseSet + (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx + +-- TODO: add more variants with mdifferentiable! +omit [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in +variable [ContMDiffVectorBundle 1 F E IB] [IsContMDiffRiemannianBundle IB 1 F E] in +variable (b e) in +lemma _root_.mdifferentiableAt_orthonormalFrame_of_mem (i : ฮน) {x : B} (hx : x โˆˆ e.baseSet) : + MDiffAt (T% (b.orthonormalFrame e i)) x := by + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx + +@[simp] +lemma orthonormalFrame_apply_of_notMem {i : ฮน} (hx : x โˆ‰ e.baseSet) : + b.orthonormalFrame e i x = 0 := by + simp only [orthonormalFrame, VectorBundle.gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed, + RCLike.ofReal_real_eq_id, id_eq, smul_eq_zero, inv_eq_zero, norm_eq_zero, or_self] + convert InnerProductSpace.gramSchmidt_zero โ„ i + exact e.localFrame_apply_of_notMem b hx + +end Module.Basis diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 12d21cd26fce89..3eb794b53d0b3f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -7,9 +7,9 @@ module public import Mathlib.Geometry.Manifold.Algebra.LieGroup public import Mathlib.Geometry.Manifold.MFDeriv.Basic -public import Mathlib.Topology.ContinuousMap.Basic -public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Topology.ContinuousMap.Basic /-! # `C^n` sections @@ -194,6 +194,16 @@ lemma ContMDiffOn.smul_section_of_tsupport {s : ฮ  (x : M), V x} {ฯˆ : M โ†’ simp [image_eq_zero_of_notMem_tsupport hy, zeroSection] ยท exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr ht' +-- unused +/-- The scalar product `ฯˆ โ€ข s` of a `C^k` function `ฯˆ: M โ†’ ๐•œ` and a section `s` of a vector +bundle `V โ†’ M` is `C^k` once `s` is `C^k` at each point in `tsupport ฯˆ`. + +This is a vector bundle analogue of `contMDiff_of_tsupport`. -/ +lemma ContMDiff.smul_section_of_tsupport' {s : ฮ  (x : M), V x} {ฯˆ : M โ†’ ๐•œ} {u : Set M} + (hs : โˆ€ x โˆˆ tsupport ฯˆ, CMDiffAt n (T% (ฯˆ โ€ข s)) x) : + CMDiff n (T% (ฯˆ โ€ข s)) := by + sorry + /-- The sum of a locally finite collection of sections is `C^k` iff each section is. Version at a point within a set. -/ lemma ContMDiffWithinAt.sum_section_of_locallyFinite diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index ef3646bfea0e0c..72d93c26d1cd4a 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -59,6 +59,12 @@ variable [โˆ€ x, AddCommGroup (V' x)] [โˆ€ x, Module ๐•œ (V' x)] [โˆ€ x : M, TopologicalSpace (V' x)] [FiberBundle F' V'] +variable + (F'' : Type*) [NormedAddCommGroup F''] [NormedSpace ๐•œ F''] + {V'' : M โ†’ Type*} [TopologicalSpace (TotalSpace F'' V'')] + [โˆ€ x, AddCommGroup (V'' x)] [โˆ€ x, Module ๐•œ (V'' x)] [โˆ€ x : M, TopologicalSpace (V'' x)] + [FiberBundle F'' V''] + variable {A : Type*} [AddCommGroup A] [Module ๐•œ A] /-- An operation `ฮฆ` on sections of a vector bundle `V` over `M` is *tensorial* at `x : M`, if it @@ -68,7 +74,7 @@ structure TensorialAt (ฮฆ : (ฮ  x : M, V x) โ†’ A) (x : M) : Prop where add : โˆ€ {ฯƒ ฯƒ'}, MDiffAt (T% ฯƒ) x โ†’ MDiffAt (T% ฯƒ') x โ†’ ฮฆ (ฯƒ + ฯƒ') = ฮฆ ฯƒ + ฮฆ ฯƒ' variable {ฮฆ : (ฮ  x : M, V x) โ†’ A} {x : M} -variable {I F F'} +variable {I F F' F''} namespace TensorialAt @@ -96,7 +102,7 @@ protected theorem ยซlocalยป (hฮฆ : TensorialAt I F ฮฆ x) {ฯƒ ฯƒ' : ฮ  x : M, V x _ = ฮฆ (ฯˆ โ€ข ฯƒ') := by rw [funext this] _ = ฮฆ ฯƒ' := by simp [hฮฆ.smul hฯˆ' hฯƒ', hฯˆx] -variable [VectorBundle ๐•œ F V] [VectorBundle ๐•œ F' V'] +variable [VectorBundle ๐•œ F V] [VectorBundle ๐•œ F' V'] [VectorBundle ๐•œ F'' V''] /-- A tensorial operation on sections of a vector bundle respects zero (since it respects scalar multiplication). -/ @@ -120,8 +126,10 @@ theorem sum (hฮฆ : TensorialAt I F ฮฆ x) {ฮน : Type*} {s : Finset ฮน} (ฯƒ : ฮน simp only [Finset.sum_insert ha, โ† h] exact hฮฆ.add (hฯƒ a) (.sum_section hฯƒ) -variable [CompleteSpace ๐•œ] [FiniteDimensional ๐•œ F] [FiniteDimensional ๐•œ F'] +variable [CompleteSpace ๐•œ] + [FiniteDimensional ๐•œ F] [FiniteDimensional ๐•œ F'] [FiniteDimensional ๐•œ F''] [ContMDiffVectorBundle 1 F V I] [ContMDiffVectorBundle 1 F' V' I] + [ContMDiffVectorBundle 1 F'' V'' I] /-- If the operation `ฮฆ` on sections of a vector bundle `V` is tensorial at `x`, then it depends only on the value of the section at `x`. -/ @@ -285,4 +293,38 @@ theorem mkHomโ‚‚_apply_eq_extend mkHomโ‚‚ ฮฆ x hฮฆโ‚ hฮฆโ‚‚ ฯƒ ฯ„ = ฮฆ (extend F ฯƒ) (extend F' ฯ„) := rfl +/-- Given an `A`-valued operation `ฮฆ` on sections of vector bundles `V`, `V'` and `V''` which is +tensorial at `x` in each argument, the construction `TensorialAt.mkHomโ‚ƒ` provides the associated +continuous linear map `V x โ†’L[๐•œ] V' x โ†’L[๐•œ] V'' x โ†’L[๐•œ] A`. -/ +noncomputable def mkHomโ‚ƒ + -- `ฮฆ` and `x` explicit to make it easier to generate the side conditions at point of use + (ฮฆ : (ฮ  x : M, V x) โ†’ (ฮ  x : M, V' x) โ†’ (ฮ  x : M, V'' x) โ†’ A) (x : M) + -- TODO: may require further differentiability conditions here, or not! + -- if so, propagate down below + (hฮฆโ‚ : โˆ€ ฯ„ ฯ„', MDiffAt (T% ฯ„) x โ†’ TensorialAt I F (ฮฆ ยท ฯ„ ฯ„') x) + (hฮฆโ‚‚ : โˆ€ ฯƒ ฯ„', MDiffAt (T% ฯƒ) x โ†’ TensorialAt I F' (ฮฆ ฯƒ ยท ฯ„') x) + (hฮฆโ‚ƒ : โˆ€ ฯƒ ฯ„, MDiffAt (T% ฯƒ) x โ†’ TensorialAt I F'' (ฮฆ ฯƒ ฯ„ ยท) x) : + V x โ†’L[๐•œ] V' x โ†’L[๐•œ] V'' x โ†’L[๐•œ] A := + sorry -- TODO: prove mutatis mutandis + +theorem mkHomโ‚ƒ_apply + {ฮฆ : (ฮ  x : M, V x) โ†’ (ฮ  x : M, V' x) โ†’ (ฮ  x : M, V'' x) โ†’ A} {x} + (hฮฆโ‚ : โˆ€ ฯ„ ฯ„', MDiffAt (T% ฯ„) x โ†’ TensorialAt I F (ฮฆ ยท ฯ„ ฯ„') x) + (hฮฆโ‚‚ : โˆ€ ฯƒ ฯ„', MDiffAt (T% ฯƒ) x โ†’ TensorialAt I F' (ฮฆ ฯƒ ยท ฯ„') x) + (hฮฆโ‚ƒ : โˆ€ ฯƒ ฯ„, MDiffAt (T% ฯƒ) x โ†’ TensorialAt I F'' (ฮฆ ฯƒ ฯ„ ยท) x) + {ฯƒ : ฮ  x : M, V x} (hฯƒ : MDiffAt (T% ฯƒ) x) {ฯ„ : ฮ  x : M, V' x} (hฯ„ : MDiffAt (T% ฯ„) x) + {ฯ„' : ฮ  x : M, V'' x} (hฯ„ : MDiffAt (T% ฯ„') x) : + mkHomโ‚ƒ ฮฆ x hฮฆโ‚ hฮฆโ‚‚ hฮฆโ‚ƒ (ฯƒ x) (ฯ„ x) (ฯ„' x) = ฮฆ ฯƒ ฯ„ ฯ„' := + sorry -- mkHomโ‚‚_apply mutatis mutandis + +theorem mkHomโ‚ƒ_apply_eq_extend + {ฮฆ : (ฮ  x : M, V x) โ†’ (ฮ  x : M, V' x) โ†’ (ฮ  x : M, V'' x) โ†’ A} {x} + (hฮฆโ‚ : โˆ€ ฯ„ ฯ„', MDiffAt (T% ฯ„) x โ†’ TensorialAt I F (ฮฆ ยท ฯ„ ฯ„') x) + (hฮฆโ‚‚ : โˆ€ ฯƒ ฯ„', MDiffAt (T% ฯƒ) x โ†’ TensorialAt I F' (ฮฆ ฯƒ ยท ฯ„') x) + (hฮฆโ‚ƒ : โˆ€ ฯƒ ฯ„, MDiffAt (T% ฯƒ) x โ†’ TensorialAt I F'' (ฮฆ ฯƒ ฯ„ ยท) x) + (ฯƒ : V x) (ฯ„ : V' x) (ฯ„' : V'' x) : + mkHomโ‚ƒ ฮฆ x hฮฆโ‚ hฮฆโ‚‚ hฮฆโ‚ƒ ฯƒ ฯ„ ฯ„' = + ฮฆ (FiberBundle.extend F ฯƒ) (FiberBundle.extend F' ฯ„) (FiberBundle.extend F'' ฯ„') := + sorry -- once the above proofs are filled in, this should be try by `rfl` + end TensorialAt diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Unused.lean b/Mathlib/Geometry/Manifold/VectorBundle/Unused.lean new file mode 100644 index 00000000000000..38cb8f2b526a18 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Unused.lean @@ -0,0 +1,60 @@ +/- +Copyright (c) 2025 Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Patrick Massot, Michael Rothgang +-/ +module + +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable + +/-! +# Miscellaneous pre-requisites for covariant derivatives + +TODO: this file should not exist; move everything in here to a proper place +(and PR it accordingly) + +-/ + +@[expose] public section -- TODO: think if we want to expose all definitions! + +section prerequisites + +open Bundle Filter Function Topology Set + +open scoped Bundle Manifold ContDiff + +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + +variable {E : Type*} [NormedAddCommGroup E] + [NormedSpace ๐•œ E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + {V : M โ†’ Type*} [TopologicalSpace (TotalSpace F V)] + [โˆ€ x : M, TopologicalSpace (V x)] [FiberBundle F V] + + + +/-- If two sections `ฯƒ` and `ฯƒ'` are equal on a neighbourhood `s` of `x`, +if one is differentiable at `x` then so is the other. +Issue: EventuallyEq does not work for dependent functions. -/ +lemma mdifferentiableAt_dependent_congr {ฯƒ ฯƒ' : ฮ  x : M, V x} {x : M} {s : Set M} (hs : s โˆˆ nhds x) + (hฯƒโ‚ : MDiffAt (T% ฯƒ) x) (hฯƒโ‚‚ : โˆ€ x โˆˆ s, ฯƒ x = ฯƒ' x) : + MDiffAt (T% ฯƒ') x := by + apply MDifferentiableAt.congr_of_eventuallyEq hฯƒโ‚ + -- TODO: split off a lemma? + apply Set.EqOn.eventuallyEq_of_mem _ hs + intro x hx + simp [hฯƒโ‚‚, hx] + +/-- If two sections `ฯƒ` and `ฯƒ'` are equal on a neighbourhood `s` of `x`, +one is differentiable at `x` iff the other is. -/ +lemma mdifferentiable_dependent_congr_iff {ฯƒ ฯƒ' : ฮ  x : M, V x} {x : M} {s : Set M} + (hs : s โˆˆ nhds x) (hฯƒ : โˆ€ x โˆˆ s, ฯƒ x = ฯƒ' x) : + MDiffAt (T% ฯƒ) x โ†” MDiffAt (T% ฯƒ') x := + โŸจfun h โ†ฆ mdifferentiableAt_dependent_congr hs h hฯƒ, + fun h โ†ฆ mdifferentiableAt_dependent_congr hs h (fun x hx โ†ฆ (hฯƒ x hx).symm)โŸฉ + +end prerequisites