diff --git a/Mathlib.lean b/Mathlib.lean index a5667796804c28..16abf706f5a11c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4601,6 +4601,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 @@ -4611,16 +4612,31 @@ public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.VectorBundle.ContMDiffSection 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..2bf65c1fdd8f33 --- /dev/null +++ b/Mathlib/Geometry/Manifold/CheatSheet.md @@ -0,0 +1,130 @@ +## 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... + + +-- Let `cov` be a covariant derivative on `V`. + + + +**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 10786df6b91450..8810c5a4330ed3 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/NormedSpace.lean @@ -17,8 +17,13 @@ providing the same statements for higher smoothness. In this file, we do the sam differentiability. In addition to the above, this file provides -* results about the differentiability of scalar multiplication (`mfderiv_smul` and friends), and -* `extDerivFun`: the exterior derivative of a scalar function, as a section of the cotangent bundle +* results about the differentiability of scalar multiplication (`mfderiv_smul` and friends), +* `mvfderiv`: the exterior derivative of a vector-valued function, as a section of the + cotangent bundle; adds notation `d% f` for `mvfderiv I f` via a custom elaborator scoped to the + `Manifold` namespace, with a corresponding delaborator, and + adds basic lemmas about `mvfderiv` (such as addition, subtraction, multiplication and constants). +* `mvfderivWithin` with notation `d[s]f` for `mvfderivWithin I f s` in the `Manifold` namespace: + the analogous concept within a set, with analogous API lemmas -/ @@ -84,7 +89,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} @@ -102,7 +107,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 -/ @@ -257,6 +262,36 @@ open NormedSpace ContinuousLinearMap variable {V : Type*} [NormedAddCommGroup V] [NormedSpace ๐•œ V] variable {f : M โ†’ ๐•œ} {g : M โ†’ V} +/-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, if +at some point `x`, `f` has differential `f' : TangentSpace I x โ†’L[๐•œ] ๐•œ` and `g` has differential +`g' : TangentSpace I x โ†’L[๐•œ] V` within `s` (both phrased using the predicate `HasMFDerivWithinAt`), +it follows that their scalar multiplication `f โ€ข g` has differential +`f x โ€ข g' + toSpanSingleton ๐•œ (g x) โˆ˜L f'`. + +In fact, the statement above is not literally true, because, for example, the differential of `g` +really takes values in the tangent space to `V` at `g x`, rather than in `V` itself. Of course, this +tangent space can be canonically identified with `V`. + +This lemma phrases the formula using the equiv `NormedSpace.fromTangentSpace`, which provides this +canonical identification. (It would also be possible to phrase the formula without this equiv, +instead using casting and definitional abuse.) -/ +lemma HasMFDerivWithinAt.smul + {f' : TangentSpace I x โ†’L[๐•œ] ๐•œ} + (hs : HasMFDerivAt[s] f x ((fromTangentSpace (f x)).symm.toContinuousLinearMap โˆ˜L f')) + {g' : TangentSpace I x โ†’L[๐•œ] V} + (hg : HasMFDerivAt[s] g x ((fromTangentSpace (g x)).symm.toContinuousLinearMap โˆ˜L g')) : + -- canonically identify `g'` with a linear map into the tangent space at `(f โ€ข g) x` + letI g'_ : TangentSpace I x โ†’L[๐•œ] TangentSpace ๐“˜(๐•œ, V) ((f โ€ข g) x) := + (fromTangentSpace _).symm.toContinuousLinearMap โˆ˜L g' + -- canonically identify `g x` with a linear map into a tangent space at `(f โ€ข g) x` + letI gx : ๐•œ โ†’L[๐•œ] TangentSpace ๐“˜(๐•œ, V) ((f โ€ข g) x) := + toSpanSingleton ๐•œ ((fromTangentSpace _).symm (g x)) + -- now the main statement typechecks + HasMFDerivAt[s] (f โ€ข g) x (f x โ€ข g'_ + gx โˆ˜L f') := by + constructor + ยท exact hs.1.smul hg.1 + ยท simpa using hs.2.smul hg.2 + /-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, if at some point `x`, `f` has differential `f' : TangentSpace I x โ†’L[๐•œ] ๐•œ` and `g` has differential `g' : TangentSpace I x โ†’L[๐•œ] V` (both phrased using the predicate `HasMFDerivAt`), it follows that @@ -303,6 +338,34 @@ theorem MDifferentiableOn.smul (hf : MDiff[s] f) theorem MDifferentiable.smul (hf : MDiff f) (hg : MDiff g) : MDiff fun p โ†ฆ f p โ€ข g p := fun x โ†ฆ (hf x).smul (hg x) +/-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, the +formula for the `mfderivWithin` (differential) of their scalar multiplication `f โ€ข g` within `s`. + +Mathematically speaking the formula is `d(f โ€ข g) = f โ€ข dg + df โŠ— g`, i.e. +`mfderiv[s] (f โ€ข g) x = f x โ€ข mfderiv[s] g x + toSpanSingleton ๐•œ (g x) โˆ˜L mfderiv[s] f x`, +but this doesn't typecheck because `mfderiv[s] (f โ€ข g) x` and `mfderiv[s]% g x` take values in +different tangent spaces --- respectively the tangent spaces to `V` at `(f โ€ข g) x` and `g x`. +Of course, both these tangent spaces can be canonically identified with `V`. + +This lemma phrases the formula using the equiv `NormedSpace.fromTangentSpace`, which provides this +canonical identification. (It would also be possible to phrase the formula without this equiv, +instead using casting and definitional abuse.) + +It is good practice to use the equiv `NormedSpace.fromTangentSpace` throughout a computation. If +this is done, typically `mfderiv[s] (f โ€ข g) x` will only turn up paired with this equiv (i.e., in an +expression `(fromTangentSpace _) โˆ˜L mfderiv[s] (f โ€ข g) x` or `d[s] (f โ€ข g) x`), +and the more convenient lemma `mvderiv_smul` (see below) can be used instead. + +This lemma is private: external users should use `mvfderiv_smul` instead. -/ +private lemma mfderivWithin_smul + (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) (hs : UniqueMDiffWithinAt I s x) : + mfderiv[s] (f โ€ข g) x + = f x โ€ข (fromTangentSpace _).symm.toContinuousLinearMap โˆ˜L + ((fromTangentSpace (g x)).toContinuousLinearMap โˆ˜L mfderiv[s] g x) + + toSpanSingleton ๐•œ ((fromTangentSpace _).symm (g x)) โˆ˜L + ((fromTangentSpace (f x)).toContinuousLinearMap โˆ˜L mfderiv[s] f x) := + (hf.hasMFDerivWithinAt.smul hg.hasMFDerivWithinAt).mfderivWithin hs + /-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, the formula for the `mfderiv` (differential) of their scalar multiplication `f โ€ข g`. @@ -319,8 +382,10 @@ instead using casting and definitional abuse.) It is good practice to use the equiv `NormedSpace.fromTangentSpace` throughout a computation. If this is done, typically `mfderiv% (f โ€ข g) x` will only turn up paired with this equiv (i.e., in an expression `(fromTangentSpace _) โˆ˜L mfderiv% (f โ€ข g) x`), and the more convenient lemma -`fromTangentSpace_mfderiv_smul` (see below) can be used instead. -/ -lemma mfderiv_smul (hf : MDiffAt f x) (hg : MDiffAt g x) : +`fromTangentSpace_mfderiv_smul` (see below) can be used instead. + +This lemma is private: external users should use `mvfderiv_smul` instead. -/ +private lemma mfderiv_smul (hf : MDiffAt f x) (hg : MDiffAt g x) : mfderiv% (f โ€ข g) x = f x โ€ข (fromTangentSpace _).symm.toContinuousLinearMap โˆ˜L ((fromTangentSpace (g x)).toContinuousLinearMap โˆ˜L mfderiv% g x) @@ -339,7 +404,9 @@ these tangent spaces can be canonically identified with `V`. This lemma phrases the formula using the equiv `NormedSpace.fromTangentSpace`, which provides this canonical identification. (It would also be possible to phrase the formula without this equiv, -instead using casting and definitional abuse.) -/ +instead using casting and definitional abuse.) + +This lemma is private: external users should use `mvfderiv_smul` instead. -/ lemma fromTangentSpace_mfderiv_smul (hf : MDiffAt f x) (hg : MDiffAt g x) : (fromTangentSpace ((f โ€ข g) x)).toContinuousLinearMap โˆ˜L mfderiv% (f โ€ข g) x = f x โ€ข (fromTangentSpace _).toContinuousLinearMap โˆ˜L mfderiv% g x @@ -347,6 +414,7 @@ lemma fromTangentSpace_mfderiv_smul (hf : MDiffAt f x) (hg : MDiffAt g x) : rw [mfderiv_smul hf hg] rfl +-- now unused, given that we're using mvfderiv instead \o/ /-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, the formula for the `mfderiv` (differential) of their scalar multiplication `f โ€ข g`. @@ -363,6 +431,42 @@ lemma fromTangentSpace_mfderiv_smul' (hf : MDiffAt f x) (hg : MDiffAt g x) : + toSpanSingleton ๐•œ (g x) โˆ˜L (fromTangentSpace _).toContinuousLinearMap โˆ˜L mfderiv% f x := fromTangentSpace_mfderiv_smul hf hg +/-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, the +formula for the `mfderiv[s]` (differential) of their scalar multiplication `f โ€ข g` within `s` +in the direction of the tangent vector `v`. + +Mathematically speaking the formula is `d(f โ€ข g)(v) = f โ€ข dg(v) + df(v) โ€ข g`, but to get it to +typecheck we need a phrasing involving the canonical identification `NormedSpace.fromTangentSpace` +between the vector space `V` and the tangent space to this vector space at any point. This is +because two different tangent spaces (at `(f โ€ข g) x` and `g x`) appear in the equation. + +This lemma is private: use `mvfderivWithin_smul` instead. -/ +private lemma fromTangentSpace_mfderivWithin_smul_apply (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) + (hs : UniqueMDiffWithinAt I s x) (v : TangentSpace I x) : + fromTangentSpace _ (mfderiv[s] (f โ€ข g) x v) + = f x โ€ข fromTangentSpace _ (mfderiv[s] g x v) + + fromTangentSpace _ (mfderiv[s] f x v) โ€ข g x := by + rw [mfderivWithin_smul hf hg hs] + rfl + +-- now unused, given that we're using mvfderiv instead \o/ +/-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, the +formula for the `mfderiv` (differential) of their scalar multiplication `f โ€ข g` within `s` +in the direction of the tangent vector `v`. + +Mathematically speaking the formula is `d(f โ€ข g)(v) = f โ€ข dg(v) + df(v) โ€ข g`, but to get it to +typecheck we need a phrasing involving the canonical identification `NormedSpace.fromTangentSpace` +between the vector space `V` and the tangent space to this vector space at any point. This is +because two different tangent spaces (at `(f โ€ข g) x` and `g x`) appear in the equation. + +This is a defeq variant of the main lemma `fromTangentSpace_mfderivWithin_smul_apply`, in which +we work in the tangent space at `f x โ€ข g x` (the simp-normal form) rather than at `(f โ€ข g) x`. -/ +private lemma fromTangentSpace_mfderivWithin_smul_apply' (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) + (hs : UniqueMDiffWithinAt I s x) (v : TangentSpace I x) : + fromTangentSpace (f x โ€ข g x) (mfderiv[s] (f โ€ข g) x v) + = f x โ€ข fromTangentSpace _ (mfderiv[s] g x v) + fromTangentSpace _ (mfderiv[s] f x v) โ€ข g x := + fromTangentSpace_mfderivWithin_smul_apply hf hg hs v + /-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, the formula for the `mfderiv` (differential) of their scalar multiplication `f โ€ข g` in the direction of the tangent vector `v`. @@ -370,13 +474,16 @@ the tangent vector `v`. Mathematically speaking the formula is `d(f โ€ข g)(v) = f โ€ข dg(v) + df(v) โ€ข g`, but to get it to typecheck we need a phrasing involving the canonical identification `NormedSpace.fromTangentSpace` between the vector space `V` and the tangent space to this vector space at any point. This is -because two different tangent spaces (at `(f โ€ข g) x` and `g x`) appear in the equation. -/ -lemma fromTangentSpace_mfderiv_smul_apply (hf : MDiffAt f x) (hg : MDiffAt g x) +because two different tangent spaces (at `(f โ€ข g) x` and `g x`) appear in the equation. + +This lemma is private: use `mvfderiv_smul` instead (or create an applied version if you need). -/ +private lemma fromTangentSpace_mfderiv_smul_apply (hf : MDiffAt f x) (hg : MDiffAt g x) (v : TangentSpace I x) : fromTangentSpace _ (mfderiv% (f โ€ข g) x v) = f x โ€ข fromTangentSpace _ (mfderiv% g x v) + fromTangentSpace _ (mfderiv% f x v) โ€ข g x := by simpa using congr($(fromTangentSpace_mfderiv_smul hf hg) v) +-- now unused, given that we're using mvfderiv instead \o/ /-- Given maps `f`, `g` from a manifold into a field `๐•œ` and `๐•œ`-vector space `V`, respectively, the formula for the `mfderiv` (differential) of their scalar multiplication `f โ€ข g` in the direction of the tangent vector `v`. @@ -388,7 +495,7 @@ because two different tangent spaces (at `(f โ€ข g) x` and `g x`) appear in the This is a defeq variant of the main lemma `fromTangentSpace_mfderiv_smul_apply`, in which we work in the tangent space at `f x โ€ข g x` (the simp-normal form) rather than at `(f โ€ข g) x`. -/ -lemma fromTangentSpace_mfderiv_smul_apply' (hf : MDiffAt f x) (hg : MDiffAt g x) +private lemma fromTangentSpace_mfderiv_smul_apply' (hf : MDiffAt f x) (hg : MDiffAt g x) (v : TangentSpace I x) : fromTangentSpace (f x โ€ข g x) (mfderiv% (f โ€ข g) x v) = f x โ€ข fromTangentSpace _ (mfderiv% g x v) + fromTangentSpace _ (mfderiv% f x v) โ€ข g x := @@ -396,23 +503,211 @@ lemma fromTangentSpace_mfderiv_smul_apply' (hf : MDiffAt f x) (hg : MDiffAt g x) end smul -/-! ### Exterior derivative of a scalar function -/ +/-! ### Exterior derivative of a vector-valued function -/ + +variable (I) in +/-- The exterior derivative of a vector-valued function on `M` within a set, +as a section of the cotangent bundle. -/-- 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[๐•œ] ๐•œ := +Future: this could be generalised to functions into additive torsors over abelian Lie groups +-/ +@[expose] +noncomputable def mvfderivWithin (g : M โ†’ F) (s : Set M) : + ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F := + fun x โ†ฆ (NormedSpace.fromTangentSpace <| g x).toContinuousLinearMap โˆ˜L (mfderiv[s] g x) + +variable (I) in +/-- The exterior derivative of a vector-valued function on `M`, +as a section of the cotangent bundle. + +Future: this could be generalised to functions into additive torsors over abelian Lie groups +-/ +@[expose] +noncomputable def mvfderiv (g : M โ†’ F) : + ฮ  x : M, TangentSpace I x โ†’L[๐•œ] F := fun x โ†ฆ (NormedSpace.fromTangentSpace <| g x).toContinuousLinearMap โˆ˜L (mfderiv% g x) +namespace Manifold +open scoped Bundle Manifold ContDiff + +open Lean Meta Elab Tactic + +/-- `d[s] f x` (scoped to the `Manifold` namespace) elaborates to `mvfderivWithin I J f s x`, +trying to determine `I` and `J` from the local context. -/ +scoped elab:max "d[" s:term "]" ppSpace t:term:arg : term => do + let es โ† Term.elabTerm s none + let e โ† ensureIsFunction <| โ† Term.elabTerm t none + let (srcI, _tgtI) โ† findModels e none + mkAppM ``mvfderivWithin #[srcI, e, es] + +-- Options for this case +-- * doc-string for Y is "given text" prepended to the doc-string of X +-- * hover is able to recursively specify +-- * toss the hover information to the infoview (where we can recursively specify) +set_option doc.verso true in +/-- Given {given}`f` and {given}`x`, +`d% f x` (scoped to the {lit}`Manifold` namespace) elaborates to {name}`mvfderiv`, +trying to determine `I` and `J` from the local context. -/ +scoped elab:max "d%" ppSpace t:term:arg : term => do + let e โ† ensureIsFunction <| โ† Term.elabTerm t none + let (srcI, _tgtI) โ† findModels e none + mkAppM ``mvfderiv #[srcI, e] + +open Bundle PrettyPrinter Delaborator SubExpr + +/-- Delaborator for `mvfderivWithin`. -/ +-- There is no need to special-case any arguments which could use the T% s elaborator: +-- the argument to `mvfderivWithin` is a vector-valued function, which a map to a total space +-- can never be. +@[app_delab mvfderivWithin] meta def delab_mvfderivWithin : Delab := do + whenPPOption getPPNotation do + withOverApp 16 do + let ss โ† withAppArg delab + let fs โ† withNaryArg 14 <| delab + `(d[$ss] $fs) >>= annotateGoToSyntaxDef + +/-- Delaborator for `mvfderiv`. -/ +-- There is no need to special-case any arguments which could use the T% s elaborator: +-- the argument to `mvfderivWithin` is a vector-valued function, which a map to a total space +-- can never be. +@[app_delab mvfderiv] meta def delab_mvfderiv : Delab := do + whenPPOption getPPNotation do + withOverApp 15 do + let fs โ† withAppArg delab + `(d% $fs) >>= annotateGoToSyntaxDef + +section tests + +variable {f : M โ†’ ๐•œ} + +/-- info: d[s] f : (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check mvfderivWithin I f s +/-- info: d[s] f x : TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check mvfderivWithin I f s x + +/-- info: d[s] f : (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check d[s] f +/-- info: d[s] f x : TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check d[s] f x + +/-- info: d% f : (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check mvfderiv I f +/-- info: d% f : (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check d% f + +/-- info: d% f x : TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check mvfderiv I f x + +/-- info: d% f x : TangentSpace I x โ†’L[๐•œ] ๐•œ -/ +#guard_msgs in +#check d% f x + +end tests + +end Manifold + +@[simp, mfld_simps] lemma mvfderivWithin_univ {f : M โ†’ F} : d[(univ : Set M)] f = d% f := by + ext X + simp [mvfderiv, mvfderivWithin] + +lemma mvfderivWithin_const (c : F) {x : M} : d[s] (fun _ : M โ†ฆ c) x = 0 := by + simp [mvfderivWithin, mfderivWithin_const] + +@[simp, to_fun mvfderivWithin_fun_add] +lemma mvfderivWithin_add {g g' : M โ†’ F} {x : M} + (hg : MDiffAt[s] g x) (hg' : MDiffAt[s] g' x) (hs : UniqueMDiffWithinAt I s x) : + d[s](g + g') x = d[s]g x + d[s]g' x := by + simp [mvfderivWithin, mfderivWithin_add hg hg' hs] + rfl + +@[simp, to_fun mvfderivWithin_fun_sub] +lemma mvfderivWithin_sub {g g' : M โ†’ F} {x : M} + (hg : MDiffAt[s] g x) (hg' : MDiffAt[s] g' x) (hs : UniqueMDiffWithinAt I s x) : + d[s](g - g') x = d[s]g x - d[s]g' x := by + simp [mvfderivWithin, mfderivWithin_sub hg hg' hs] + rfl + +@[simp, to_fun mvfderivWithin_fun_neg] +lemma mvfderivWithin_neg {g : M โ†’ F} {x : M} (hs : UniqueMDiffWithinAt I s x) : + d[s](-g) x = -d[s]g x := by + simp [mvfderivWithin, mfderivWithin_neg hs] + rfl + +@[simp, to_fun mvfderivWithin_fun_smul] +lemma mvfderivWithin_smul {a : M โ†’ ๐•œ} (ha : MDiffAt[s] a x) {g : M โ†’ F} (hg : MDiffAt[s] g x) + (hs : UniqueMDiffWithinAt I s x) : + d[s](a โ€ข g) x = + a x โ€ข d[s] g x + (d[s] a x).smulRight (g x) := by + ext v + simp [mvfderivWithin, -Pi.smul_apply', -Pi.smul_apply, + fromTangentSpace_mfderivWithin_smul_apply ha hg hs] + rfl + +@[simp, to_fun mvfderivWithin_fun_mul] +lemma mvfderivWithin_mul {f g : M โ†’ ๐•œ} {x : M} (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) + (hs : UniqueMDiffWithinAt I s x) : + d[s](f * g) x = f x โ€ข d[s]g x + (g x) โ€ข (d[s]f x) := by + ext v + simp [mvfderivWithin, -Pi.smul_apply', -Pi.smul_apply, โ† smul_eq_mul, mfderivWithin_smul hf hg hs] + simp [mul_comm _ (g x)] + @[simp] -lemma extDerivFun_add {g g' : M โ†’ ๐•œ} {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 +lemma mvfderivWithin_zero {s : Set M} (hs : UniqueMDiffWithinAt I s x) : + d[s] (0 : M โ†’ F) x = 0 := by + have : d[s] (0 : M โ†’ F) x + d[s] (0 : M โ†’ F) x = d[s] (0 : M โ†’ F) x := by + rw [โ† mvfderivWithin_add (by exact mdifferentiableWithinAt_const) + (by exact mdifferentiableWithinAt_const) hs] + simp + simpa using this + +lemma mvfderiv_const (c : F) {x : M} : d% (fun _ : M โ†ฆ c) x = 0 := by + simp [mvfderiv, mfderiv_const] + +@[simp, to_fun mvfderiv_fun_add] +lemma mvfderiv_add {g g' : M โ†’ F} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) : + d% (g + g') x = d% g x + d% g' x := by + simp [mvfderiv, mfderiv_add hg hg'] + rfl + +@[simp, to_fun mvfderiv_fun_sub] +lemma mvfderiv_sub {g g' : M โ†’ F} {x : M} (hg : MDiffAt g x) (hg' : MDiffAt g' x) : + d% (g - g') x = d% g x - d% g' x := by + simp [mvfderiv, mfderiv_sub hg hg'] + rfl + +@[simp, to_fun mvfderiv_fun_neg] +lemma mvfderiv_neg {g : M โ†’ F} {x : M} : + d% (-g) x = -d% g x := by + simp [mvfderiv, mfderiv_neg] + rfl + +@[simp, to_fun mvfderiv_fun_smul] +lemma mvfderiv_smul {x : M} {a : M โ†’ ๐•œ} (ha : MDiffAt a x) {g : M โ†’ F} (hg : MDiffAt g x) : + d% (a โ€ข g) x = + a x โ€ข d% g x + (d% a x).smulRight (g x) := by + ext v + simp [mvfderiv, -Pi.smul_apply', -Pi.smul_apply, fromTangentSpace_mfderiv_smul_apply ha hg] + rfl + +@[simp, to_fun mvfderiv_fun_mul] +lemma mvfderiv_mul {f g : M โ†’ ๐•œ} {x : M} (hf : MDiffAt f x) (hg : MDiffAt g x) : + d% (f * g) x = f x โ€ข d% g x + (g x) โ€ข (d% f x) := by + ext v + simp [mvfderiv, -Pi.smul_apply', -Pi.smul_apply, โ† smul_eq_mul, mfderiv_smul hf hg] + simp [mul_comm _ (g x)] @[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 - rw [โ† extDerivFun_add (by exact mdifferentiable_const ..) (by exact mdifferentiable_const ..)] +lemma mvfderiv_zero {x : M} : d% (0 : M โ†’ F) x = 0 := by + have : d% (0 : M โ†’ F) x + d% (0 : M โ†’ F) x = d% (0 : M โ†’ F) x := by + rw [โ† mvfderiv_add (by exact mdifferentiable_const ..) (by exact mdifferentiable_const ..)] simp simpa using this + +@[deprecated (since := "2026-05-17")] alias extDerivFun_zero := mvfderiv_zero diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 7f4ad4775d421d..6d9320215c76cd 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -796,6 +796,20 @@ theorem mfderivWithin_add (hf : MDiffAt[s] f z) (hg : MDiffAt[s] g z) (by exact mfderiv[s] f z) + (by exact mfderiv[s] g z) := (hf.hasMFDerivWithinAt.add hg.hasMFDerivWithinAt).mfderivWithin hs +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'} @@ -878,15 +892,15 @@ theorem mdifferentiableAt_neg : MDiffAt (-f) z โ†” MDiffAt f z := theorem MDifferentiable.neg (hf : MDiff f) : MDiff (-f) := fun x โ†ฆ (hf x).neg set_option backward.isDefEq.respectTransparency false in -theorem mfderivWithin_neg (f : M โ†’ E') (x : M) (hs : UniqueMDiffWithinAt I s x) : +theorem mfderivWithin_neg (hs : UniqueMDiffWithinAt I s x) : mfderiv[s] (-f) x = -mfderiv[s] f x := by simp_rw [mfderivWithin] by_cases hf : MDiffAt[s] f x ยท exact hf.hasMFDerivWithinAt.neg.mfderivWithin hs ยท rw [if_neg hf]; rw [โ† mdifferentiableWithinAt_neg] at hf; rw [if_neg hf, neg_zero] -theorem mfderiv_neg (f : M โ†’ E') (x : M) : mfderiv% (-f) x = -mfderiv% f x := by - rw [โ† mfderivWithin_univ, mfderivWithin_neg _ _ (uniqueMDiffWithinAt_univ I), mfderivWithin_univ] +theorem mfderiv_neg : mfderiv% (-f) x = -mfderiv% f x := by + rw [โ† mfderivWithin_univ, mfderivWithin_neg (uniqueMDiffWithinAt_univ I), mfderivWithin_univ] theorem HasMFDerivWithinAt.sub (hf : HasMFDerivAt[s] f z f') (hg : HasMFDerivAt[s] g z g') : HasMFDerivAt[s] (f - g) z (f' - g') := 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 620ac719fb7b7a..817d33fd8910b3 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 : โ„•โˆžฯ‰} {๐•œ B B' F M : Type*} {E : B โ†’ Type*} diff --git a/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean index 6d62722d66f4b5..3de1dcfb16012e 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/ContMDiffSection.lean @@ -195,6 +195,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/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean index a6e5c327c556b2..7b41053f0d5930 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -96,7 +96,7 @@ structure IsCovariantDerivativeOn cov (ฯƒ + ฯƒ') x = cov ฯƒ x + cov ฯƒ' x leibniz {ฯƒ : ฮ  x : M, V x} {g : M โ†’ ๐•œ} {x} (hฯƒ : MDiffAt (T% ฯƒ) x) (hg : MDiffAt g x) (hx : x โˆˆ s := by trivial) : - cov (g โ€ข ฯƒ) x = g x โ€ข cov ฯƒ x + (extDerivFun g x).smulRight (ฯƒ x) + cov (g โ€ข ฯƒ) x = g x โ€ข cov ฯƒ x + (d% g x).smulRight (ฯƒ x) /-- A covariant derivative โˆ‡ is called of class `C^k` iff, whenever `X` is a `C^k` section and `ฯƒ` a @@ -104,12 +104,15 @@ A covariant derivative โˆ‡ is called of class `C^k` iff, whenever `X` is a `C^k` deduce this automatically. We will prove in a later file that any `C^(k+1)` covariant derivative is `C^k`. -/ +-- Is this framing correct? It is a pretty weak condition if the space of C^k sections over `u` is +-- small, which e.g. could happen over `โ„‚` when `u` is compact. Not sure whether this definition +-- retrieves the correct notion of "holomorphic connection" in this case. class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] [VectorBundle ๐•œ F V] (k : โ„•โˆžฯ‰) (cov : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)) (u : Set M) where contMDiff : โˆ€ {ฯƒ : ฮ  x : M, V x}, CMDiff[u] (k + 1) (T% ฯƒ) โ†’ - letI cov (x : M) : TotalSpace (E โ†’L[๐•œ] F) fun x โ†ฆ TangentSpace I x โ†’L[๐•œ] V x := โŸจx, cov ฯƒ xโŸฉ - ContMDiffOn I (I.prod ๐“˜(๐•œ, E โ†’L[๐•œ] F)) k cov u + letI covฯƒ (x : M) : TotalSpace (E โ†’L[๐•œ] F) fun x โ†ฆ TangentSpace I x โ†’L[๐•œ] V x := โŸจx, cov ฯƒ xโŸฉ + ContMDiffOn I (I.prod ๐“˜(๐•œ, E โ†’L[๐•œ] F)) k covฯƒ u -- TODO elaborators are not working here. We want to use `T% (cov ฯƒ)` and CMDiff[u] k f variable {F} @@ -142,13 +145,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) @@ -176,14 +176,16 @@ lemma congr_of_eqOn -- Then, it's a chain of (dependent) equalities. calc cov ฯƒ x _ = cov ((ฯˆ : M โ†’ ๐•œ) โ€ข ฯƒ) x := by - simp [hcov.leibniz hฯƒ hฯˆ'.mdifferentiableAt, hฯˆx, extDerivFun, hฯˆ'.mfderiv] + simp [hcov.leibniz hฯƒ hฯˆ'.mdifferentiableAt, hฯˆx, mvfderiv, hฯˆ'.mfderiv] _ = cov ((ฯˆ : M โ†’ ๐•œ) โ€ข ฯƒ') x := by rw [funext H] _ = cov ฯƒ' x := by - simp [hcov.leibniz hฯƒ' hฯˆ'.mdifferentiableAt, hฯˆx, extDerivFun, hฯˆ'.mfderiv] + simp [hcov.leibniz hฯƒ' hฯˆ'.mdifferentiableAt, hฯˆx, mvfderiv, hฯˆ'.mfderiv] 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 +197,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,11 +221,25 @@ 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) : cov (a โ€ข ฯƒ) x = a โ€ข cov ฯƒ x := by - simpa [extDerivFun] using hcov.leibniz (g := fun _ โ†ฆ a) hฯƒ mdifferentiableAt_const + simpa [mvfderiv] using hcov.leibniz (g := fun _ โ†ฆ a) hฯƒ mdifferentiableAt_const end computational_properties @@ -270,15 +298,15 @@ lemma finite_affine_combination {ฮน : Type*} {s : Finset ฮน} rw [โ† smul_add, (h i).add hฯƒ hฯƒ' hx] leibniz {ฯƒ g x} hฯƒ hg hx := by calc โˆ‘ i โˆˆ s, f i x โ€ข cov i (g โ€ข ฯƒ) x - _ = โˆ‘ i โˆˆ s, (g x โ€ข f i x โ€ข cov i ฯƒ x + f i x โ€ข (extDerivFun g x).smulRight (ฯƒ x)) := by + _ = โˆ‘ i โˆˆ s, (g x โ€ข f i x โ€ข cov i ฯƒ x + f i x โ€ข (d% g x).smulRight (ฯƒ x)) := by congr! 1 with i hi rw [(h i).leibniz hฯƒ hg] - simp [extDerivFun] + simp [mvfderiv] module _ = g x โ€ข โˆ‘ i โˆˆ s, f i x โ€ข cov i ฯƒ x + - (โˆ‘ i โˆˆ s, f i) x โ€ข (extDerivFun g x).smulRight (ฯƒ x) := by + (โˆ‘ i โˆˆ s, f i) x โ€ข (d% g x).smulRight (ฯƒ x) := by rw [Finset.sum_add_distrib, Finset.smul_sum, Finset.sum_apply, Finset.sum_smul] - _ = g x โ€ข โˆ‘ i โˆˆ s, f i x โ€ข cov i ฯƒ x + (extDerivFun g x).smulRight (ฯƒ x) := by rw [hf]; simp + _ = g x โ€ข โˆ‘ i โˆˆ s, f i x โ€ข cov i ฯƒ x + (d% g x).smulRight (ฯƒ x) := by rw [hf]; simp /-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ lemma _root_.ContMDiffCovariantDerivativeOn.finite_affine_combination [IsManifold I 1 M] @@ -386,6 +414,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..cedbde5b1c4ace --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Curvature.lean @@ -0,0 +1,274 @@ +/- +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: this ought to be true (possibly after improving `[IsManifold I 1 M]` to higher regularity), +-- but maybe the definition of smoothness (i.e. `ContMDiffCovariantDerivativeOn`) needs to be +-- adjusted to get it -- the current definition is potentially very weak if the space of sections of +-- `V` over `u` is small. +-- TODO: move this to `CovariantDerivative.Basic` +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 + +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] [VectorBundle ๐•œ F V] + +/-! ## 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, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)) + +variable {X X' Y : (ฮ  x : M, TangentSpace I x)} (ฯƒ : ฮ  x, V 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 ฯƒ) x = cov ฯƒ 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, V x) โ†’ (ฮ  x : M, V x) := + fun X Y ฯƒ โ†ฆ (โˆ‡ X (โˆ‡ Y ฯƒ)) - (โˆ‡ Y (โˆ‡ X ฯƒ)) - โˆ‡ (VectorField.mlieBracket I X Y) ฯƒ + +variable [IsManifold I 2 M] + {cov cov' : (ฮ  x : M, V x) โ†’ (ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x)} + {X X' Y Z : ฮ  x : M, TangentSpace I x} + +-- TODO: generalise to C^(k + 1) (not just C^2), and move to `CovariantDerivative.Basic` +lemma temp + {cov : ((x : M) โ†’ V x) โ†’ (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] V x} + (hcov : IsCovariantDerivativeOn F cov) + [hcov' : ContMDiffCovariantDerivativeOn F 1 cov univ] -- is this the right regularity? + {x : M} {ฯƒ : ฮ  x, V x} {X : (x : M) โ†’ TangentSpace I x} + (hฯƒ : CMDiffAt 2 (T% ฯƒ) x) (hX : CMDiffAt 1 (T% X) x) : + CMDiffAt 1 (T% (fun x โ†ฆ (cov ฯƒ x) (X x))) x := + (hcov'.contMDiff' hcov hฯƒ).clm_bundle_apply hX + +lemma temp_mdiff + {cov : ((x : M) โ†’ V x) โ†’ (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] V x} + (hcov : IsCovariantDerivativeOn F cov) + [hcov' : ContMDiffCovariantDerivativeOn F 1 cov univ] -- is this the right regularity? + {x : M} {ฯƒ : ฮ  x, V x} {X : (x : M) โ†’ TangentSpace I x} + (hฯƒ : CMDiffAt 2 (T% ฯƒ) x) (hX : MDiffAt (T% X) x) : + MDiffAt (T% (fun x โ†ฆ (cov ฯƒ x) (X x))) x := + -- requires adapting `ContMDiffAt.clm_bundle_apply` to `MDifferentiableAt` hypotheses + sorry + +-- HM: looks false to me +-- lemma temp' -- I suspect this one will also work! +-- {cov : ((x : M) โ†’ V x) โ†’ (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] V x} +-- (hcov : IsCovariantDerivativeOn F cov) +-- {x : M} {ฯƒ : ฮ  x, V x} {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[๐•œ] F)) 1 +-- (fun x โ†ฆ TotalSpace.mk' (E โ†’L[๐•œ] F) x (cov ฯƒ x)) x) : +-- ContMDiffAt I (I.prod ๐“˜(๐•œ, F)) 1 (T% (fun 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 +-/ + +-- HM: don't think this one is needed (or perhaps even true) +-- lemma aux +-- (hcov : IsCovariantDerivativeOn F cov) [hcov' : ContMDiffCovariantDerivativeOn F 1 cov univ] +-- {x : M} {Y Z : (x : M) โ†’ TangentSpace I x} {ฯ„ : ฮ  x, V x} +-- (hฯ„ : CMDiffAt 2 (T% ฯ„) x) : +-- (MDiffAt (T% (fun x โ†ฆ (cov ฯ„ x) (VectorField.mlieBracket I Z Y x)))) x := by +-- apply ContMDiffAt.mdifferentiableAt _ one_ne_zero +-- apply temp' F hcov ?_ (hcov'.contMDiff' hcov hฯ„) +-- apply hฯ„.of_le +-- norm_num + +variable [CompleteSpace E] [VectorBundle ๐•œ F V] + +theorem curvatureTensorAux_tensorialโ‚ (hcov : IsCovariantDerivativeOn F cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn F 1 cov univ] + (Y : (ฮ  x : M, TangentSpace I x)) (ฯ„ : ฮ  x, V x) + (hY : MDiffAt (T% Y) x) + (hฯ„ : CMDiffAt 2 (T% ฯ„) x) : + TensorialAt I E (curvatureTensorAux cov ยท Y ฯ„ x) x where + smul {f X} hf hX := by + unfold curvatureTensorAux + dsimp + sorry + add {X X'} hX hX' := by + unfold curvatureTensorAux + simp only [Pi.add_apply, map_add, Pi.sub_apply] + rw [VectorField.mlieBracket_add_left hX hX'] + simp only [map_add] + set A := cov (fun x โ†ฆ (cov ฯ„ x) (Y x)) x (X x) + set B := cov (fun x โ†ฆ (cov ฯ„ x) (Y x)) x (X' x) + set C := cov (fun x โ†ฆ (cov ฯ„ x) (X x)) x + set D := cov (fun x โ†ฆ (cov ฯ„ x) (X' x)) x + have hฯ„X : MDiffAt (T% (fun x โ†ฆ cov ฯ„ x (X x))) x := temp_mdiff F hcov hฯ„ hX + have hฯ„X' : MDiffAt (T% (fun x โ†ฆ cov ฯ„ x (X' x))) x := temp_mdiff F hcov hฯ„ hX' + conv => + enter [1, 1, 2] + equals (cov (fun x โ†ฆ (cov ฯ„ x) (X x)) x) (Y x) + + (cov (fun x โ†ฆ (cov ฯ„ x) (X' x)) x) (Y x) => + have H := hcov.add hฯ„X hฯ„X' + exact congr($H (Y x)) + abel + +-- update hypotheses to match lemma above, once proven! +theorem curvatureTensorAux_tensorialโ‚‚ (hcov : IsCovariantDerivativeOn F cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn F 1 cov univ] + (X : (ฮ  x : M, TangentSpace I x)) (ฯƒ : ฮ  x, V x) : + TensorialAt I E (curvatureTensorAux cov X ยท ฯƒ x) x := + -- proof is analogous to the version in X + sorry + +-- update hypotheses to match lemma above, once proven! +theorem curvatureTensorAux_tensorialโ‚ƒ (hcov : IsCovariantDerivativeOn F cov) (x : M) + [hcov' : ContMDiffCovariantDerivativeOn F 1 cov univ] + (X Y : (ฮ  x : M, TangentSpace I x)) : + TensorialAt I F (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 F cov) (x : M) + [ContMDiffCovariantDerivativeOn F 1 cov univ] : + TangentSpace I x โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] V x โ†’L[๐•œ] V x := + TensorialAt.mkHomโ‚ƒ (curvatureTensorAux cov ยท ยท ยท x) x + (fun X ฯ„ hX hฯ„ โ†ฆ hcov.curvatureTensorAux_tensorialโ‚ F x X ฯ„ hX sorry) + -- `hฯ„` not good enough for the `sorry` above + -- HM: looks like we may need a version of `TensorialAt.mkHomโ‚ƒ` in which the tensoriality + -- conditions are only proved for C^2 (or C^k) sections + (fun X ฯ„ _ _ โ†ฆ hcov.curvatureTensorAux_tensorialโ‚‚ F x X ฯ„) + (fun X Y _ _ โ†ฆ hcov.curvatureTensorAux_tensorialโ‚ƒ F x X Y) + +variable [ContMDiffCovariantDerivativeOn F 1 cov univ] + +-- lemmas: curvatureEndomorphismTensor_apply and curvatureEndomorphismTensor_apply_extend + +variable (X) in +@[simp] +lemma curvatureEndomorphismTensor_self (hcov : IsCovariantDerivativeOn F cov) + (Xโ‚€ : TangentSpace I x) : + hcov.curvatureEndomorphismTensor F x Xโ‚€ Xโ‚€ = 0 := by + sorry + +variable (X Y) in +lemma curvatureEndomorphismTensor_swap (hcov : IsCovariantDerivativeOn F cov) + (Xโ‚€ Yโ‚€ : TangentSpace I x) : + hcov.curvatureEndomorphismTensor F x Xโ‚€ Yโ‚€ = - hcov.curvatureEndomorphismTensor F 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. + +-- this is the thing whose cohomology class gives a definition of characteristic classes +-- do something similar (but swap the argument order of the full curvature tensor) for the +-- Levi-Civita connection to get Ricci curvature +def traceCurvature [CompleteSpace ๐•œ] [FiniteDimensional ๐•œ F] [FiniteDimensional ๐•œ E] + (hcov : IsCovariantDerivativeOn F cov) (x : M) : + TangentSpace I x โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] ๐•œ := + have : T2Space (V x) := (VectorBundle.continuousLinearEquivAt ๐•œ F V x).toHomeomorph.symm.t2Space + have : FiniteDimensional ๐•œ (V x) := VectorBundle.finiteDimensional ๐•œ F V x + have : FiniteDimensional ๐•œ (TangentSpace I x) := + VectorBundle.finiteDimensional ๐•œ E (TangentSpace I) x + let tr : (TangentSpace I x โ†’โ‚—[๐•œ] V x โ†’L[๐•œ] V x) โ†’โ‚—[๐•œ] TangentSpace I x โ†’โ‚—[๐•œ] ๐•œ := + LinearMap.llcomp ๐•œ (TangentSpace I x) _ _ + (LinearMap.trace ๐•œ (V x) โˆ˜โ‚— ContinuousLinearMap.coeLM ๐•œ) + let Tr : (TangentSpace I x โ†’L[๐•œ] V x โ†’L[๐•œ] V x) โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] ๐•œ := + (LinearMap.toContinuousLinearMap.toLinearMap โˆ˜โ‚— + (tr โˆ˜โ‚— ContinuousLinearMap.coeLM ๐•œ)).toContinuousLinearMap + Tr โˆ˜L curvatureEndomorphismTensor F hcov x + +-- scalar curvature left to the reader +-- (for this construction need to set up the typeclasses for a Riemannian manifold) + +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..2f3a5f6f9a91e3 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Ehresmann.lean @@ -0,0 +1,393 @@ +/- +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 + +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..067dea7d41362c --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -0,0 +1,355 @@ +/- +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 + +This file defines the Levi-Civita connection on a (finite-dimensional) Riemannian manifold `(M, g)`. +A connection `โˆ‡` on the tangent bundle of a Riemannian manifold `(M, g)` is called a +*Levi-Civita connection* 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 VectorField + +open scoped Manifold ContDiff + +section funpropsetup +-- In the medium term, `fun_prop` should support `MDifferentiable`, `ContMDiff` and friends fully. +-- This will require adding a custom discharger for models with corners. +-- In the mean-time, add the following attributes in this file, as they are too useful to not use. + +attribute [fun_prop] MDifferentiable MDifferentiableAt + MDifferentiable.add MDifferentiableAt.add + mdifferentiableAt_fun_add_section MDifferentiableAt.fun_smul_section + +end funpropsetup + +-- Let `M` be a `C^2` manifold modeled on `(E, H)`. +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners โ„ E H) + +-- move this +variable {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 1 M] in +lemma injective_eval_mdifferentiableAt_vectorField (V : Type*) [AddCommGroup V] [Module โ„ V] [TopologicalSpace V] + (x : M) : + Function.Injective + (fun A : TangentSpace I x โ†’L[โ„] V โ†ฆ + fun (Z : ฮ  x, TangentSpace I x) (_ : MDiffAt (T% Z) x) โ†ฆ A (Z x)) := + VectorBundle.injective_eval_mdifferentiableAt_sec .. + +variable {M : Type*} [EMetricSpace M] [ChartedSpace H M] [IsManifold I 2 M] + +-- From now on, `M` is endowed with a Riemannian metric. +variable + [RiemannianBundle (fun (x : M) โ†ฆ TangentSpace I x)] + {X X' X'' Y Y' Y'' Z Z' : ฮ  x : M, TangentSpace I x} + +open scoped RealInnerProductSpace + +-- move this, and think whether it could be more general +-- Note that Mathlib/Topology/FiberBundle/Basic.lean has a lot of similar lemma but far from enough +-- imports. +lemma VectorBundle.completeSpace (R : Type*) [NontriviallyNormedField R] + {B : Type*} [TopologicalSpace B] + (E : B โ†’ Type*) [(x : B) โ†’ AddCommGroup (E x)] [(x : B) โ†’ Module R (E x)] + (F : Type*) [NormedAddCommGroup F] [NormedSpace R F] [CompleteSpace F] + [TopologicalSpace (TotalSpace F E)] [(x : B) โ†’ UniformSpace (E x)] + [(x : B) โ†’ IsUniformAddGroup (E x)] [FiberBundle F E] [VectorBundle R F E] (b : B) : + CompleteSpace (E b) := by + let e := VectorBundle.continuousLinearEquivAt R F E b + rwa [completeSpace_congr (e := e.toEquiv) e.isUniformEmbedding] + +-- move this, also perhaps generalize to general Riemannian vector bundles, +-- and write a variant for `CMDiffAt n` +lemma injective_inner_mdifferentiableAt_vectorField [CompleteSpace E] (x : M) : + Function.Injective + (fun Xโ‚€ : TangentSpace I x โ†ฆ + fun (Z : ฮ  x, TangentSpace I x) (_ : MDiffAt (T% Z) x) โ†ฆ (โŸชXโ‚€, Z xโŸซ)) := by + have := VectorBundle.completeSpace โ„ (TangentSpace I (M := M)) E + set ฮฆ := InnerProductSpace.toDual โ„ (TangentSpace I x) + exact (injective_eval_mdifferentiableAt_vectorField I โ„ x).comp ฮฆ.injective + +-- Let `cov` and `cov'` be covariant derivatives on `TM`. +variable (cov cov' : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)) + +/-- Local notation for a covariant derivative on a vector bundle acting on a vector field and a +section. -/ +local syntax:max "โˆ‡" term:arg term:arg : term +local macro_rules | `(โˆ‡ $X $ฯƒ) => `(fun (x : M) โ†ฆ cov $ฯƒ x ($X x)) +local syntax:max "โˆ‡'" term:arg term:arg : term +local macro_rules | `(โˆ‡' $X $ฯƒ) => `(fun (x : M) โ†ฆ cov' $ฯƒ x ($X x)) + +-- From now on, we assume the Riemannian metric on `M` is `Cยน`. +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] + +-- Local notation for pointwise inner products of vector fields. +-- Note this does not cause ambiguity with the notation obtained +-- with `open scoped RealInnerProductSpace.` +local notation "โŸช" X ", " Y "โŸซ" => fun x โ†ฆ inner โ„ (X x) (Y x) + +/- TODO: The next two lemmas are workaround for some version of Lean 4 #9077 +(Instance synthesis sees through type synonyms). They should be removed when that issue will +be fully solved. -/ + +variable {I} in +@[fun_prop] 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 +@[fun_prop] 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 + +namespace CovariantDerivative +variable {x : M} + +/-- A covariant derivative on a Riemannian bundle `TM` is called a **Levi-Civita connection** +if it is torsion-free and compatible with `g`. +Note that the bundle metric on `TM` is implicitly hidden in this definition. +-/ +@[expose] public def IsLeviCivitaConnection [FiniteDimensional โ„ E] : Prop := + cov.IsCompatible โˆง cov.torsion = 0 + +section uniqueness + +variable {cov cov'} + +/-- 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 `โˆ‡`. -/ +public lemma IsLeviCivitaConnection.apply_eq [FiniteDimensional โ„ E] + (h : cov.IsLeviCivitaConnection) + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + โŸชโˆ‡ X Y, ZโŸซ x = + (d% โŸชY, ZโŸซ x (X x) + d% โŸชZ, XโŸซ x (Y x) - d% โŸชX, YโŸซ x (Z x) + - โŸชY ,(VectorField.mlieBracket I X Z)โŸซ x + - โŸชZ, (VectorField.mlieBracket I Y X)โŸซ x + + โŸชX, (VectorField.mlieBracket I Z Y)โŸซ x) / 2 := by + -- use the compatibility in three ways + have eq1a := h.1.mvfderiv_inner_eq X hY hZ + have eq2a := h.1.mvfderiv_inner_eq Y hZ hX + have eq3a := h.1.mvfderiv_inner_eq Z hX hY + -- use the torsion-freeness in three ways + have eq1b := congr(inner โ„ (Y x) ($(h.2) x (X x) (Z x))) + have eq2b := congr(inner โ„ (Z x) ($(h.2) x (Y x) (X x))) + have eq3b := congr(inner โ„ (X x) ($(h.2) x (Z x) (Y x))) + -- combine + simp (disch := fun_prop) [real_inner_comm, inner_sub_right, torsion_apply] at * + linear_combination - (eq1a + eq1b + eq2a + eq2b - eq3a - eq3b) / 2 + +/-- The Levi-Civita connection on `(M, g)` is uniquely determined on differentiable vector fields. + +Note that the differentiability hypotheses are required, since `CovariantDerivative` objects are +unconstrained in their behaviour on non-differentiable vector fields. -/ +public theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional โ„ E] + (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) : + โˆ‡ X Y x = โˆ‡' X Y x := by + apply injective_inner_mdifferentiableAt_vectorField; ext Z hZ + exact (hcov.apply_eq I hX hY hZ).trans <| hcov'.apply_eq I hX hY hZ |>.symm + +end uniqueness + +section existence + +variable (X Y Z) in +/-- Auxiliary quantity for the construction of the Levi-Civita connection: +If `โˆ‡` is the Levi-Civita connection on `TM`, this formula will express `โŸจโˆ‡ X Y, ZโŸฉ`. -/ +noncomputable def leviCivitaAux (x : M) : โ„ := + (d% โŸชY, ZโŸซ x (X x) + d% โŸชZ, XโŸซ x (Y x) - d% โŸชX, YโŸซ x (Z x) + - โŸชY ,(VectorField.mlieBracket I X Z)โŸซ x + - โŸชZ, (VectorField.mlieBracket I Y X)โŸซ x + + โŸชX, (VectorField.mlieBracket I Z Y)โŸซ x) / 2 + +/-- `leviCivitaAux` is tensorial with respect to its first argument. -/ +theorem leviCivitaAux_tensorialโ‚ [FiniteDimensional โ„ E] + {Y : ฮ  x : M, TangentSpace I x} (x : M) (hY : MDiffAt (T% Y) x) {Z : ฮ  x, TangentSpace I x} + (hZ : MDiffAt (T% Z) x) : + TensorialAt I E (leviCivitaAux I ยท Y Z x) x where + smul hf hX := by + simp (disch := fun_prop) [leviCivitaAux, mvfderiv_fun_mul, + mlieBracket_smul_left, mlieBracket_smul_right, + inner_add_right, inner_smul_left, inner_smul_right, real_inner_comm] + ring + add hXโ‚ hXโ‚‚ := by + simp (disch := fun_prop) [leviCivitaAux, mlieBracket_add_right, mlieBracket_add_left, + mvfderiv_fun_add, inner_add_left, inner_add_right] + ring + +/-- `leviCivitaAux` is tensorial with respect to its second argument. -/ +theorem leviCivitaAux_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 (leviCivitaAux I X Y ยท x) x where + smul hf hZ := by + simp (disch := fun_prop) [leviCivitaAux, + mlieBracket_smul_right, mlieBracket_smul_left, + mvfderiv_fun_mul, + inner_smul_left, inner_smul_right, inner_add_right, real_inner_comm] + ring + add hZโ‚ hZโ‚‚ := by + simp (disch := fun_prop) [leviCivitaAux, + mlieBracket_add_right, mlieBracket_add_left, + mvfderiv_fun_add, + inner_add_left, inner_add_right] + ring + +/-- Almost the underlying function underlying our construction of the Levi-Civita connection: +this is the desired `(1,1)`-tensor, but without considerations to the junk value when +applied to non-differentiable vector fields. -/ +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 + (TensorialAt.mkHomโ‚‚ _ (x := x) + (fun _Z hZ โ†ฆ leviCivitaAux_tensorialโ‚ _ _ hY hZ) + (fun _X hX โ†ฆ leviCivitaAux_tensorialโ‚‚ _ _ hY hX)) + +set_option backward.isDefEq.respectTransparency false in +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โŸซ = leviCivitaAux I X Y Z x := by + unfold lcAuxโ‚ + simp [TensorialAt.mkHomโ‚‚_apply _ _ hX hZ] + +open scoped Classical in +/-- The function underlying our construction of the Levi-Civita connection on `(M,g)` -/ +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) : + โŸชlcAux I Y x (X x), Z xโŸซ = leviCivitaAux I X Y Z x := by + simpa [lcAux, dif_pos hY] using lcAuxโ‚_apply I hX hY hZ + +set_option backward.isDefEq.respectTransparency false in +lemma isCovariantDerivativeOn_lcAux [FiniteDimensional โ„ E] : + IsCovariantDerivativeOn E (lcAux I (M := M)) where + add {Y Y'} x hY hY' _ := by + apply injective_eval_mdifferentiableAt_vectorField; ext X hX + apply injective_inner_mdifferentiableAt_vectorField; ext Z hZ + simp (disch := fun_prop) [lcAux, dif_pos, TensorialAt.mkHomโ‚‚_apply, lcAuxโ‚, + leviCivitaAux, mvfderiv_fun_add, + mlieBracket_add_left, mlieBracket_add_right, + inner_add_left, inner_add_right] + ring + leibniz {Y f x} hY hf _ := by + apply injective_eval_mdifferentiableAt_vectorField; ext X hX + apply injective_inner_mdifferentiableAt_vectorField; ext Z hZ + simp (disch := fun_prop) [lcAux, dif_pos, lcAuxโ‚, TensorialAt.mkHomโ‚‚_apply, + leviCivitaAux, mvfderiv_fun_mul, + mlieBracket_smul_left, mlieBracket_smul_right, + inner_add_left, inner_add_right, inner_smul_left, inner_smul_right, real_inner_comm] + ring + +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. -/ +public noncomputable def leviCivitaConnection [FiniteDimensional โ„ E] : + CovariantDerivative I E (TangentSpace I : M โ†’ Type _) where + toFun := lcAux I + isCovariantDerivativeOnUniv := isCovariantDerivativeOn_lcAux I + +public 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) : + โŸชleviCivitaConnection I M Y x (X x), Z xโŸซ = + (d% โŸชY, ZโŸซ x (X x) + d% โŸชZ, XโŸซ x (Y x) - d% โŸชX, YโŸซ x (Z x) + - โŸชY, VectorField.mlieBracket I X ZโŸซ x + - โŸชZ, VectorField.mlieBracket I Y XโŸซ x + + โŸชX, VectorField.mlieBracket I Z YโŸซ x) / 2 := + lcAux_apply _ hX hY hZ + +public theorem leviCivitaConnection_apply_right [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) : + โŸชX x, leviCivitaConnection I M Y x (Z x)โŸซ = + (d% โŸชY, XโŸซ x (Z x) + d% โŸชX, ZโŸซ x (Y x) - d% โŸชZ, YโŸซ x (X x) + - โŸชY ,VectorField.mlieBracket I Z XโŸซ x + - โŸชX, VectorField.mlieBracket I Y ZโŸซ x + + โŸชZ, VectorField.mlieBracket I X YโŸซ x) / 2 := by + rw [real_inner_comm] + exact lcAux_apply _ hZ hY hX + +public lemma leviCivitaConnection_isCompatible [FiniteDimensional โ„ E] : + (leviCivitaConnection I M).IsCompatible := by + rw [isCompatible_iff] + intro x X Y Z hX hY hZ + -- Normalise the expressions by swapping arguments for inner product and mlieBracket, + -- until the swappable arguments are in order X < Y < Z. + simp (disch := fun_prop) [leviCivitaConnection_apply_right, + fun x โ†ฆ real_inner_comm (Z x), + fun x โ†ฆ real_inner_comm (Y x) (X x), + mlieBracket_swap (V := Z), + mlieBracket_swap (V := Y) (W := X)] + ring + +public lemma leviCivitaConnection_torsion_eq_zero [FiniteDimensional โ„ E] : + (leviCivitaConnection I M).torsion = 0 := by + rw [CovariantDerivative.torsion_eq_zero_iff] + intro X Y x hX hY + apply injective_inner_mdifferentiableAt_vectorField; ext Z hZ + simp (disch := fun_prop) [leviCivitaConnection_apply I, + mlieBracket_swap (V := Y) (W := X), mlieBracket_swap (V := Z) (W := X), + mlieBracket_swap (V := Z) (W := Y), + real_inner_comm, inner_sub_left] + ring + +/-- `leviCivitaConnection` is a Levi-Civita connection (i.e., compatible and torsion-free) -/ +public lemma leviCivitaConnection_isLeviCivitaConnection [FiniteDimensional โ„ E] : + (leviCivitaConnection I M).IsLeviCivitaConnection := + โŸจleviCivitaConnection_isCompatible I, leviCivitaConnection_torsion_eq_zero IโŸฉ + +end existence + +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..3c9a64ae1af920 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Metric.lean @@ -0,0 +1,187 @@ +/- +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 + +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} + +local notation "โŸช" ฯƒ ", " ฯ„ "โŸซ" => fun x โ†ฆ inner โ„ (ฯƒ x) (ฯ„ x) + +namespace CovariantDerivative + +-- Let `cov` be a covariant derivative on `V`. +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[โ„] โ„ := + d% โŸชฯƒ, ฯ„โŸซ x - innerSL โ„ (ฯ„ x) โˆ˜L cov ฯƒ x - innerSL โ„ (ฯƒ x) โˆ˜L cov ฯ„ x + +@[simp] +lemma compatibilityTensorAux_apply (ฯƒ ฯ„ : ฮ  x : M, V x) {x : M} (Xโ‚€ : TangentSpace I x) : + compatibilityTensorAux I cov ฯƒ ฯ„ x Xโ‚€ = + d% โŸชฯƒ, ฯ„โŸซ 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โ‚€ + simp [mvfderiv_fun_mul hf (hฯƒ.inner_bundle hฯ„), + cov.isCovariantDerivativeOn.leibniz hฯƒ hf, inner_add_left, inner_smul_left] + ring + add hฯƒ hฯƒ' := by + ext Xโ‚€ + simp [mvfderiv_fun_add (hฯƒ.inner_bundle hฯ„) (hฯƒ'.inner_bundle hฯ„), + 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โ‚€ + simp [mvfderiv_fun_mul hf (hฯƒ.inner_bundle hฯ„), + cov.isCovariantDerivativeOn.leibniz hฯ„ hf, inner_add_right, inner_smul_right] + ring + add hฯ„ hฯ„' := by + ext Xโ‚€ + simp [mvfderiv_fun_add (hฯƒ.inner_bundle hฯ„) (hฯƒ.inner_bundle hฯ„'), + 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`. -/ +public 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 +public theorem compatibilityTensor_apply [FiniteDimensional โ„ F] (x : M) + (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯ„ : MDiffAt (T% ฯ„) x) : + cov.compatibilityTensor x (ฯƒ x) (ฯ„ x) (X x) = + d% โŸชฯƒ, ฯ„โŸซ 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 +public theorem compatibilityTensor_apply_eq_extend [FiniteDimensional โ„ F] (Xโ‚€ : TangentSpace I x) + (ฯƒโ‚€ ฯ„โ‚€ : V x) : + cov.compatibilityTensor x ฯƒโ‚€ ฯ„โ‚€ Xโ‚€ = + d% โŸช(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] + +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 ฯ„โŸฉ`. -/ +public def IsCompatible [FiniteDimensional โ„ F] : Prop := compatibilityTensor cov = 0 + +variable {I} [ContMDiffVectorBundle 1 F V I] + +variable {cov} in +public lemma IsCompatible.mvfderiv_inner_eq [FiniteDimensional โ„ F] (hcov : cov.IsCompatible) + {x : M} (X : ฮ  x, TangentSpace I x) {ฯƒ ฯ„ : (x : M) โ†’ V x} + (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯ„ : MDiffAt (T% ฯ„) x) : + d% โŸชฯƒ, ฯ„โŸซ x (X x) = โŸชโˆ‡ X ฯƒ, ฯ„โŸซ x + โŸชฯƒ, โˆ‡ X ฯ„โŸซ x := by + have H := congr($hcov x (ฯƒ x) (ฯ„ x) (X x)) + simp [compatibilityTensor_apply _ _ hฯƒ hฯ„] at H + linear_combination H + +variable [IsManifold I 1 M] + +public 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 โ†’ + d% โŸชฯƒ, ฯ„โŸซ x (X x) = โŸชโˆ‡ X ฯƒ, ฯ„โŸซ x + โŸชฯƒ, โˆ‡ X ฯ„โŸซ x := by + refine โŸจfun hcov x X ฯƒ ฯ„ hX โ†ฆ hcov.mvfderiv_inner_eq X, fun h โ†ฆ ?_โŸฉ + ext1 x + apply VectorBundle.injective_eval_mdifferentiableAt_sec I F; ext1 ฯƒ; ext1 hฯƒ + apply VectorBundle.injective_eval_mdifferentiableAt_sec I F; ext1 ฯ„; ext1 hฯ„ + apply VectorBundle.injective_eval_mdifferentiableAt_sec I E (TangentSpace I); ext X hX + simp (disch := assumption) [compatibilityTensor_apply] + linear_combination h hX hฯƒ hฯ„ + +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..e48e1836f40927 --- /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 โ†ฆ mvfderiv I s x) univ where + add hฯƒ hฯƒ' hx := by + rw [mdifferentiableAt_section_trivial_iff] at hฯƒ hฯƒ' + rw [mvfderiv_add hฯƒ hฯƒ'] + leibniz hฯƒ hg hx := by + rw [mdifferentiableAt_section] at hฯƒ + ext1 Xโ‚€ + simp at hฯƒ + simp [mvfderiv_smul hg hฯƒ] + +lemma of_endomorphism (A : (x : M) โ†’ F โ†’L[๐•œ] TangentSpace I x โ†’L[๐•œ] F) : + IsCovariantDerivativeOn F (fun (s : M โ†’ F) x โ†ฆ d% 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 + ext X -- TODO: missing API lemma, without the ext cannot see through mvfderiv... + simp [mvfderiv, 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 โ†’ cov ฯƒ x = mvfderiv I ฯƒ x + 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ฯƒ] + simp only [mvfderiv] + 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 20f7437e4eace3..8d04df0f38f6cb 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 ecff97d02c97fe..abd9ab5bfd2313 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 2f1636e1a92737..d9f604c3919dc4 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 @@ -358,11 +357,14 @@ lemma mdifferentiableWithinAt_add_section ยท exact fun x hx โ†ฆ (e.linear ๐•œ hx).1 .. ยท exact (e.linear ๐•œ (FiberBundle.mem_baseSet_trivializationAt' xโ‚€)).1 .. +@[to_fun] lemma mdifferentiableAt_add_section (hs : MDiffAt (T% s) xโ‚€) (ht : MDiffAt (T% t) xโ‚€) : MDiffAt (T% (s + t)) xโ‚€ := by rw [โ† mdifferentiableWithinAt_univ] at hs ht โŠข apply mdifferentiableWithinAt_add_section hs ht +-- TODO: remove this once to_fun outputs can be named! +alias mdifferentiableAt_fun_add_section := fun_mdifferentiableAt_add_section lemma mdifferentiableOn_add_section (hs : MDiff[u] (T% s)) (ht : MDiff[u] (T% t)) : MDiff[u] (T% (s + t)) := @@ -426,6 +428,7 @@ lemma MDifferentiableWithinAt.smul_section ยท exact fun x hx โ†ฆ (e.linear ๐•œ hx).2 .. ยท apply (e.linear ๐•œ (FiberBundle.mem_baseSet_trivializationAt' xโ‚€)).2 +@[to_fun] lemma MDifferentiableAt.smul_section (hf : MDiffAt f xโ‚€) (hs : MDiffAt (T% s) xโ‚€) : MDiffAt (T% (f โ€ข s)) xโ‚€ := by rw [โ† mdifferentiableWithinAt_univ] at hs โŠข @@ -715,5 +718,25 @@ lemma mdifferentiableAt_extend {x : M} (ฯƒโ‚€ : V x) : MDiffAt (T% (extend F ฯƒโ‚€)) x := (contMDiffAt_extend' (k := 1) I F ฯƒโ‚€).mdifferentiableAt one_ne_zero +variable (V) in +lemma _root_.VectorBundle.injective_eval_mdifferentiableAt_sec [โˆ€ x, Module ๐•œ (V x)] + (W : Type*) [AddCommGroup W] [Module ๐•œ W] [TopologicalSpace W] (x : M) : + Function.Injective + (fun A : V x โ†’L[๐•œ] W โ†ฆ + fun (Z : ฮ  x, V x) (_ : MDiffAt (T% Z) x) โ†ฆ A (Z x)) := by + intro X X' h + ext ฯƒโ‚€ + simpa using congr($h (extend F ฯƒโ‚€) (mdifferentiableAt_extend ..)) + +variable (V) in +lemma _root_.VectorBundle.injective_eval_contMDiffAt_sec {n : WithTop โ„•โˆž} [โˆ€ x, Module ๐•œ (V x)] + (W : Type*) [AddCommGroup W] [Module ๐•œ W] [TopologicalSpace W] (x : M) : + Function.Injective + (fun A : V x โ†’L[๐•œ] W โ†ฆ + fun (Z : ฮ  x, V x) (_ : CMDiffAt n (T% Z) x) โ†ฆ A (Z x)) := by + intro X X' h + ext ฯƒโ‚€ + simpa using congr($h (extend F ฯƒโ‚€) (contMDiffAt_extend' ..)) + end FiberBundle end extend 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/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean index bca580206860da..43fa17d32469b3 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 โ†’ MDiffAt (T% ฯ…) x โ†’ TensorialAt I F (ฮฆ ยท ฯ„ ฯ…) x) + (hฮฆโ‚‚ : โˆ€ ฯƒ ฯ…, MDiffAt (T% ฯƒ) x โ†’ MDiffAt (T% ฯ…) x โ†’ TensorialAt I F' (ฮฆ ฯƒ ยท ฯ…) x) + (hฮฆโ‚ƒ : โˆ€ ฯƒ ฯ„, MDiffAt (T% ฯƒ) x โ†’ 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 โ†’ MDiffAt (T% ฯ…) x โ†’ TensorialAt I F (ฮฆ ยท ฯ„ ฯ…) x) + (hฮฆโ‚‚ : โˆ€ ฯƒ ฯ…, MDiffAt (T% ฯƒ) x โ†’ MDiffAt (T% ฯ…) x โ†’ TensorialAt I F' (ฮฆ ฯƒ ยท ฯ…) x) + (hฮฆโ‚ƒ : โˆ€ ฯƒ ฯ„, MDiffAt (T% ฯƒ) x โ†’ 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 โ†’ MDiffAt (T% ฯ…) x โ†’ TensorialAt I F (ฮฆ ยท ฯ„ ฯ…) x) + (hฮฆโ‚‚ : โˆ€ ฯƒ ฯ…, MDiffAt (T% ฯƒ) x โ†’ MDiffAt (T% ฯ…) x โ†’ TensorialAt I F' (ฮฆ ฯƒ ยท ฯ…) x) + (hฮฆโ‚ƒ : โˆ€ ฯƒ ฯ„, MDiffAt (T% ฯƒ) x โ†’ 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 diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 1053c4a7ac2823..b23b72b0fe42ae 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -361,8 +361,7 @@ lemma mlieBracketWithin_smul_right {f : M โ†’ ๐•œ} (hf : MDiffAt[s] f x) (hW : MDiffAt[s] (fun x โ†ฆ (W x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I V (f โ€ข W) s x = - (fromTangentSpace (f x) (mfderiv[s] f x (V x))) โ€ข (W x) - + (f x) โ€ข mlieBracketWithin I V W s x := by + (d[s] f x (V x)) โ€ข (W x) + (f x) โ€ข mlieBracketWithin I V W s x := by simp only [mlieBracketWithin, mpullbackWithin_smul] -- Simplify local notation a bit. set V' := mpullbackWithin ๐“˜(๐•œ, E) I (extChartAt I x).symm V (range I) @@ -391,10 +390,9 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a lemma mlieBracket_smul_right {f : M โ†’ ๐•œ} (hf : MDiffAt f x) (hW : MDiffAt (fun x โ†ฆ (W x : TangentBundle I M)) x) : mlieBracket I V (f โ€ข W) x = - (fromTangentSpace (f x) (mfderiv% f x (V x))) โ€ข (W x) - + (f x) โ€ข mlieBracket I V W x := by + d% f x (V x) โ€ข (W x) + (f x) โ€ข mlieBracket I V W x := by rw [โ† mdifferentiableWithinAt_univ] at hf hW - rw [โ† mlieBracketWithin_univ, โ† mfderivWithin_univ] + rw [โ† mlieBracketWithin_univ, โ† mvfderivWithin_univ] exact mlieBracketWithin_smul_right hf hW (uniqueMDiffWithinAt_univ I) /-- @@ -405,8 +403,7 @@ lemma mlieBracketWithin_smul_left {f : M โ†’ ๐•œ} (hf : MDiffAt[s] f x) (hV : MDiffAt[s] (fun x โ†ฆ (V x : TangentBundle I M)) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (f โ€ข V) W s x = - -(fromTangentSpace (f x) (mfderiv[s] f x (W x))) โ€ข (V x) - + (f x) โ€ข mlieBracketWithin I V W s x := by + - d[s] f x (W x) โ€ข (V x) + (f x) โ€ข mlieBracketWithin I V W s x := by rw [mlieBracketWithin_swap, Pi.neg_apply, mlieBracketWithin_smul_right hf hV (V := W) hs, mlieBracketWithin_swap] simp; abel @@ -418,16 +415,15 @@ Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a lemma mlieBracket_smul_left {f : M โ†’ ๐•œ} (hf : MDiffAt f x) (hV : MDiffAt (fun x โ†ฆ (V x : TangentBundle I M)) x) : mlieBracket I (f โ€ข V) W x = - - (fromTangentSpace (f x) (mfderiv% f x (W x))) โ€ข (V x) - + (f x) โ€ข mlieBracket I V W x := by + - (d% f x (W x)) โ€ข (V x) + (f x) โ€ข mlieBracket I V W x := by rw [โ† mdifferentiableWithinAt_univ] at hf hV - rw [โ† mlieBracketWithin_univ, โ† mfderivWithin_univ] + rw [โ† mlieBracketWithin_univ, mvfderiv, โ† mfderivWithin_univ] exact mlieBracketWithin_smul_left hf hV (uniqueMDiffWithinAt_univ I) lemma mlieBracketWithin_const_smul_left (hV : MDiffAt[s] (T% V) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I (c โ€ข V) W s x = c โ€ข mlieBracketWithin I V W s x := by - simpa [mfderivWithin_const] using + simpa [mfderivWithin_const, mvfderivWithin] using mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs lemma mlieBracket_const_smul_left (hV : MDiffAt (T% V) x) : @@ -438,7 +434,7 @@ lemma mlieBracket_const_smul_left (hV : MDiffAt (T% V) x) : lemma mlieBracketWithin_const_smul_right (hW : MDiffAt[s] (T% W) x) (hs : UniqueMDiffWithinAt I s x) : mlieBracketWithin I V (c โ€ข W) s x = c โ€ข mlieBracketWithin I V W s x := by - simpa [mfderivWithin_const] using + simpa [mfderivWithin_const, mvfderivWithin] using mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs lemma mlieBracket_const_smul_right (hW : MDiffAt (T% W) x) :