diff --git a/Mathlib.lean b/Mathlib.lean index a52b2d3816d854..92156ce96df213 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4397,6 +4397,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 @@ -4405,14 +4406,23 @@ public import Mathlib.Geometry.Manifold.SmoothApprox public import Mathlib.Geometry.Manifold.SmoothEmbedding public import Mathlib.Geometry.Manifold.StructureGroupoid public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Basic +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.LeviCivita +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Lift +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Prelim +public import Mathlib.Geometry.Manifold.VectorBundle.CovariantDerivative.Torsion 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.Misc +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.VectorField.LieBracket public import Mathlib.Geometry.Manifold.VectorField.Pullback public import Mathlib.Geometry.Manifold.WhitneyEmbedding diff --git a/Mathlib/Geometry/Manifold/CheatSheet.md b/Mathlib/Geometry/Manifold/CheatSheet.md new file mode 100644 index 00000000000000..ede331a4011da6 --- /dev/null +++ b/Mathlib/Geometry/Manifold/CheatSheet.md @@ -0,0 +1,127 @@ +## Differential geometry cheat sheet + +How do I say certain basic things in Lean? +For each of them, include a variable block. Can verso do this already? + + +Let M be a C^k manifold. +``` +variable {๐•œ E M H : Type*} [NontriviallyNormedField ๐•œ] [NormedAddCommGroup E] + [NormedSpace ๐•œ E] [TopologicalSpace H] [TopologicalSpace M] {k : โ„•} -- more general: take k : WithTop โ„•โˆž, allows smooth and analytic; remove WithTop to exclude analyticity + {I : ModelWithCorners ๐•œ E H} [ChartedSpace H M] [IsManifold I k M] +``` + +Let M be a smooth manifold +``` +variable {๐•œ E M H : Type*} [NontriviallyNormedField ๐•œ] [NormedAddCommGroup E] + [NormedSpace ๐•œ E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners ๐•œ E H} [ChartedSpace H M] [IsManifold I โˆž M] +``` + +Let M be a smooth real manifold. +``` +variable {E M H : Type*} [NormedAddCommGroup E] + [NormedSpace โ„ E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners โ„ E H} [ChartedSpace H M] [IsManifold I โˆž M] -- test, needs open scoped Manifold?? +``` + +Let M be an analytic manifold +``` +open scoped Manifold -- test, necessary? + +variable {๐•œ E M H : Type*} [NontriviallyNormedField ๐•œ] [NormedAddCommGroup E] + [NormedSpace ๐•œ E] [TopologicalSpace H] [TopologicalSpace M] + {I : ModelWithCorners ๐•œ E H} [ChartedSpace H M] [IsManifold I ฯ‰ M] +``` + +Differentiability of functions between manifolds +``` +import Mathlib.Geometry.Manifold.MFDeriv.Defs +import Mathlib.Geometry.Manifold.ContMDiff.Defs + +variable + -- Given a non-trivially normed field ๐•œ + {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + -- A manifold M over ๐•œ + {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners ๐•œ E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + -- A manifold M' over ๐•œ + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners ๐•œ E' H') + {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + -- A function from M to M' and x in M + (f : M โ†’ M') (x : M) + +variable (x : M) in +-- f is differentiable at x +#check MDifferentiableAt I I' f x + +variable (n : WithTop โ„•โˆž) in -- A natural number or โˆž or ฯ‰ +#check ContMDiff I I' n f + + +variable + {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + (g : M โ†’ F) in +open scoped Manifold in +#check ContMDiff I ๐“˜(๐•œ, F) n g -- g is n times continuously differentiable +``` + +Consider the product manifold M \times N. + + +Let \phi be the preferred chart at x\in M. + +Let \phi be any (compatible) chart on M. + +-------- + +Let E\to M be a topological vector bundle. + +Let E\to M be a smooth vector bundle. + +Let s be a section of E. +``` +variable (s : ฮ  x : M, V x) +``` +Let X be a vector field on `M` +``` +(X : ฮ  x : M, TangentSpace I x) +``` + +Let s be a C^k section of E. / The section s of E is C^k. +``` +ContMDiff I (I.prod ๐“˜(๐•œ, F)) (k + 1) (fun x โ†ฆ TotalSpace.mk' F x (ฯƒ x)) +``` + +Let `X` be a C^k vector field on M. +``` +variable {X : ฮ  x : M, TangentSpace I x} +-- TODO: this doesn't work! +-- variable (___hX: ContMDiff I I.tangent 2 (fun x โ†ฆ (X x : TangentBundle I M))) +``` + +Let \phi be the preferred local trivialisation at x\in E. +Let \phi be any compatible trivialisation on M. + +Consider the tangent bundle TM of M. + +Let X be a C^k vector field on M. + +explain TotalSpace.mk' somewhere in here... + + + +**Basic API lemmas** +- testing smoothness of a map in charts: the standard charts; any charts + +- testing smoothness of a section in trivialisations: the standard charts; any charts + + +**constructions** +- product manifold (tricky!) +- disjoint union + +- product bundle (how difficult?) +- Lie bracket of vector fields diff --git a/Mathlib/Geometry/Manifold/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 5a9508233dce83..a928c9066135d6 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Basic.lean @@ -61,6 +61,18 @@ fields, etc. @[expose] public section +-- Kyleโ€™s #check' command. This has nothing to do here but will be convenient for us +open Lean Elab Command PrettyPrinter Delaborator in +elab tk:"#check' " name:ident : command => runTermElabM fun _ => do + for c in (โ† realizeGlobalConstWithInfos name) do + addCompletionInfo <| .id name name.getId (danglingDot := false) {} none + let info โ† getConstInfo c + let delab : Delab := do + delabForallParamsWithSignature fun binders type => do + let binders := binders.filter fun binder => binder.raw.isOfKind ``Parser.Term.explicitBinder + return โŸจโ† `(declSigWithId| $(mkIdent c) $binders* : $type)โŸฉ + logInfoAt tk <| .ofFormatWithInfosM (PrettyPrinter.ppExprWithInfos (delab := delab) info.type) + assert_not_exists mfderiv open Bundle Set OpenPartialHomeomorph diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean new file mode 100644 index 00000000000000..c13639bb638a7b --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Basic.lean @@ -0,0 +1,1237 @@ +/- +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.SmoothSection +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Misc +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.Prelim + +/-! +# Covariant derivatives + +TODO: add a more complete doc-string + +-/ + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + + + +variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] + +@[expose] public section -- TODO: think if we want to expose all definitions! + +section any_field +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] -- [FiniteDimensional ๐•œ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ๐•œ E H} + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + +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)] + -- [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul ๐•œ (V x)] + [FiberBundle F V] --[VectorBundle ๐•œ F V] + -- `V` vector bundle + +structure IsCovariantDerivativeOn [IsManifold I 1 M] + (f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)) + (s : Set M := Set.univ) : Prop where + -- All the same axioms as CovariantDerivative, but restricted to the set s. + addX (f) {X X' : ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} {x : M} + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) (hฯƒ : MDiffAt (T% ฯƒ) x) + (hx : x โˆˆ s := by trivial) : + f (X + X') ฯƒ x = f X ฯƒ x + f X' ฯƒ x + smulX {X : ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} {g : M โ†’ ๐•œ} {x : M} + (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) (hg : MDiffAt g x) (hx : x โˆˆ s := by trivial) : + f (g โ€ข X) ฯƒ x = g x โ€ข f X ฯƒ x + addฯƒ {X : ฮ  x : M, TangentSpace I x} {ฯƒ ฯƒ' : ฮ  x : M, V x} {x} + (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯƒ' : MDiffAt (T% ฯƒ') x) + (hx : x โˆˆ s := by trivial) : + f X (ฯƒ + ฯƒ') x = f X ฯƒ x + f X ฯƒ' x + leibniz {X : ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} {g : M โ†’ ๐•œ} {x} + (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) (hg : MDiffAt g x) (hx : x โˆˆ s := by trivial): + f X (g โ€ข ฯƒ) x = (g โ€ข f X ฯƒ) x + ((bar _).toFun (mfderiv% g x (X x))) โ€ข ฯƒ x + smul_const_ฯƒ {X : ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} {x} (a : ๐•œ) + (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ s := by trivial) : + f X (a โ€ข ฯƒ) x = a โ€ข f X ฯƒ x + +/-- +A covariant derivative โˆ‡ is called of class `C^k` iff, +whenever `X` is a `C^k` section and `ฯƒ` a `C^{k+1}` section, the result `โˆ‡ X ฯƒ` is a `C^k` section. +This is a class so typeclass inference can deduce this automatically. +-/ +class ContMDiffCovariantDerivativeOn [IsManifold I 1 M] (k : โ„•โˆž) + (cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)) + (u : Set M) where + contMDiff : โˆ€ {X : ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x}, + CMDiff[u] (k + 1) (T% ฯƒ) โ†’ CMDiff[u] k (T% X) โ†’ + CMDiff[u] k (T% (cov X ฯƒ)) + +variable {F} + +namespace IsCovariantDerivativeOn + +variable [IsManifold I 1 M] + +variable (E) in +/-- If `E` is the trivial vector space, the axioms of a covariant derivative are vacuous. -/ +lemma of_subsingleton [hE : Subsingleton E] + (f : ((x : M) โ†’ TangentSpace I x) โ†’ ((x : M) โ†’ TangentSpace I x) โ†’ + ((x : M) โ†’ TangentSpace I x)) : + IsCovariantDerivativeOn E f Set.univ := by + have (X) (Y) (x) : f X Y x = 0 := by + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + exact Subsingleton.eq_zero _ + exact { + addX {_X _X' _ฯƒ x} hX hX' hฯƒ hx := by simp [this] + smulX {_X _ฯƒ _g _x} hX hฯƒ hg hx := by simp [this] + smul_const_ฯƒ {X _ฯƒ x} a hX hฯƒ hx := by simp [this] + addฯƒ {X ฯƒ ฯƒ' x} hX hฯƒ hฯƒ' hx := by simp [this] + leibniz {X ฯƒ g x} hX hฯƒ hg hx := by + have hฯƒ : ฯƒ x = 0 := by + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + exact Subsingleton.eq_zero _ + simp [this, hฯƒ] } + +section changing_set +/-! Changing set + +In this changing we change `s` in `IsCovariantDerivativeOn F f s`. + +-/ +lemma mono + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} {s t : Set M} + (hf : IsCovariantDerivativeOn F f t) (hst : s โІ t) : IsCovariantDerivativeOn F f s where + addX {_X _X' _ฯƒ} _x hX hX' hฯƒ hx := hf.addX hX hX' hฯƒ (hst hx) + smulX {_X _ฯƒ _g} _x hX hฯƒ hg hx := hf.smulX hX hฯƒ hg (hst hx) + addฯƒ {_X _ฯƒ _ฯƒ' _x} hX hฯƒ hฯƒ' hx := hf.addฯƒ hX hฯƒ hฯƒ' (hst hx) + leibniz {_X _ฯƒ _f _x} hX hฯƒ hf' hx := hf.leibniz hX hฯƒ hf' (hst hx) + smul_const_ฯƒ {_X _ฯƒ _x} a hX hฯƒ hx := hf.smul_const_ฯƒ a hX hฯƒ (hst hx) + +lemma iUnion {ฮน : Type*} + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} {s : ฮน โ†’ Set M} + (hf : โˆ€ i, IsCovariantDerivativeOn F f (s i)) : IsCovariantDerivativeOn F f (โ‹ƒ i, s i) where + addX {_X _X' _ฯƒ _x} hX hX' hฯƒ hx := by + obtain โŸจsi, โŸจi, rflโŸฉ, hxsiโŸฉ := hx + exact (hf i).addX hX hX' hฯƒ hxsi + smulX {_X _ฯƒ _g _x} hX hฯƒ hg hx := by + obtain โŸจsi, โŸจi, rflโŸฉ, hxsiโŸฉ := hx + exact (hf i).smulX hX hฯƒ hg hxsi + addฯƒ {_X _ฯƒ _ฯƒ' _x} hX hฯƒ hฯƒ' hx := by + obtain โŸจsi, โŸจi, rflโŸฉ, hxsiโŸฉ := hx + exact (hf i).addฯƒ hX hฯƒ hฯƒ' + leibniz {X ฯƒ f x} hX hฯƒ hf' hx := by + obtain โŸจsi, โŸจi, rflโŸฉ, hxsiโŸฉ := hx + exact (hf i).leibniz hX hฯƒ hf' + smul_const_ฯƒ {_X _ฯƒ _x} a hX hฯƒ hx := by + obtain โŸจsi, โŸจi, rflโŸฉ, hxsiโŸฉ := hx + exact (hf i).smul_const_ฯƒ _ hX hฯƒ + +end changing_set + +/- Congruence properties -/ +section + +lemma congr {f g : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} {s : Set M} + (hf : IsCovariantDerivativeOn F f s) + -- Is this too strong? Will see! + (hfg : โˆ€ {X : ฮ  x : M, TangentSpace I x}, + โˆ€ {ฯƒ : ฮ  x : M, V x}, โˆ€ {x}, x โˆˆ s โ†’ f X ฯƒ x = g X ฯƒ x) : + IsCovariantDerivativeOn F g s where + addX hX hX' hฯƒ hx := by simp [โ† hfg hx, hf.addX hX hX' hฯƒ] + smulX hX hฯƒ hg hx := by simp [โ† hfg hx, hf.smulX hX hฯƒ hg] + addฯƒ hX hฯƒ hฯƒ' hx := by simp [โ† hfg hx, hf.addฯƒ hX hฯƒ hฯƒ'] + leibniz hX hฯƒ hf' hx := by simp [โ† hfg hx, hf.leibniz hX hฯƒ hf'] + smul_const_ฯƒ a hX hฯƒ hx := by simp [โ† hfg hx, hf.smul_const_ฯƒ a hX hฯƒ] + +end + +section computational_properties + +lemma smul_const_X + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {s : Set M} (h : IsCovariantDerivativeOn F f s) {x} (a : ๐•œ) + {X : ฮ  x, TangentSpace I x} {ฯƒ : ฮ  x, V x} (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) + (hx : x โˆˆ s := by trivial) : + f (a โ€ข X) ฯƒ x = a โ€ข f X ฯƒ x := + h.smulX hX hฯƒ mdifferentiableAt_const + +variable {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} {s : Set M} + +@[simp] +lemma zeroX (hf : IsCovariantDerivativeOn F f s) + {x : M} (hx : x โˆˆ s := by trivial) + {ฯƒ : ฮ  x : M, V x} (hฯƒ : MDiffAt (T% ฯƒ) x) : f 0 ฯƒ x = 0 := by + -- TODO: writing MDiffAt here yields an error! + have : MDifferentiableAt I (I.prod ๐“˜(๐•œ, E)) (T% (fun x โ†ฆ (0 : TangentSpace I x))) x := + -- TODO: add mdifferentiable{,At}_zeroSection + (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero + simpa using IsCovariantDerivativeOn.addX f hf (X := 0) this this hฯƒ + +@[simp] +lemma zeroฯƒ [VectorBundle ๐•œ F V] (hf : IsCovariantDerivativeOn F f s) + {X : ฮ  x : M, TangentSpace I x} {x} (hX : MDiffAt (T% X) x) (hx : x โˆˆ s := by trivial) : + f X 0 x = 0 := by + simpa using (hf.addฯƒ hX (mdifferentiableAt_zeroSection ..) + (mdifferentiableAt_zeroSection ..) : f X (0 + 0) x = _) + +lemma sum_X (hf : IsCovariantDerivativeOn F f s) + {ฮน : Type*} {u : Finset ฮน} {X : ฮน โ†’ ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} + {x} (hx : x โˆˆ s) (hX : โˆ€ i, MDiffAt (T% (X i)) x) (hฯƒ : MDiffAt (T% ฯƒ) x) : + f (โˆ‘ i โˆˆ u, X i) ฯƒ x = โˆ‘ i โˆˆ u, f (X i) ฯƒ x := by + classical + have := hf.zeroX hx hฯƒ + induction u using Finset.induction_on with + | empty => simp [hf.zeroX hx hฯƒ] + | insert a u ha h => + have : MDiffAt (T% (โˆ‘ i โˆˆ u, X i)) x := by simpa using MDifferentiableAt.sum_section (s := u) hX + simp [Finset.sum_insert ha, โ† h, hf.addX (hX a) this hฯƒ hx] + +end computational_properties + +section operations + +variable {s : Set M} + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + +/-- An affine combination of covariant derivatives is a covariant derivative. -/ +@[simps] +def affineCombination + {f' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + (hf : IsCovariantDerivativeOn F f s) (hf' : IsCovariantDerivativeOn F f' s) (g : M โ†’ ๐•œ) : + IsCovariantDerivativeOn F (fun X ฯƒ โ†ฆ (g โ€ข (f X ฯƒ)) + (1 - g) โ€ข (f' X ฯƒ)) s where + addX {X X' ฯƒ} x hX hX' hฯƒ hx := by simp [hf.addX hX hX' hฯƒ, hf'.addX hX hX' hฯƒ]; module + smulX {_X _ฯƒ _ฯ†} x hX hฯƒ hฯ† hx := by simp [hf.smulX hX hฯƒ hฯ†, hf'.smulX hX hฯƒ hฯ†]; module + addฯƒ {_X _ฯƒ _ฯƒ' x} hX hฯƒ hฯƒ' hx := by + simp [hf.addฯƒ hX hฯƒ hฯƒ', hf'.addฯƒ hX hฯƒ hฯƒ'] + module + smul_const_ฯƒ {_X _ฯƒ _x} a hX hฯƒ hx := by + simp [hf.smul_const_ฯƒ a hX hฯƒ, hf'.smul_const_ฯƒ a hX hฯƒ] + module + leibniz {X ฯƒ ฯ† x} hX hฯƒ hฯ† hx := by + simp [hf.leibniz hX hฯƒ hฯ†, hf'.leibniz hX hฯƒ hฯ†] + module + +/-- An affine combination of two `C^k` connections is a `C^k` connection. -/ +lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination + [VectorBundle ๐•œ F V] + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {u: Set M} {f : M โ†’ ๐•œ} {n : โ„•โˆž} (hf : CMDiff[u] n f) + (Hcov : ContMDiffCovariantDerivativeOn (F := F) n cov u) + (Hcov' : ContMDiffCovariantDerivativeOn (F := F) n cov' u) : + ContMDiffCovariantDerivativeOn F n (fun X ฯƒ โ†ฆ (f โ€ข (cov X ฯƒ)) + (1 - f) โ€ข (cov' X ฯƒ)) u where + contMDiff hX hฯƒ := by + apply ContMDiffOn.add_section + ยท exact hf.smul_section <| Hcov.contMDiff hX hฯƒ + ยท exact (contMDiffOn_const.sub hf).smul_section <| Hcov'.contMDiff hX hฯƒ + +/-- A finite affine combination of covariant derivatives is a covariant derivative. -/ +def affineCombination' {ฮน : Type*} {s : Finset ฮน} [Nonempty s] + {u : Set M} {cov : ฮน โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + (h : โˆ€ i, IsCovariantDerivativeOn F (cov i) u) {f : ฮน โ†’ M โ†’ ๐•œ} (hf : โˆ‘ i โˆˆ s, f i = 1) : + IsCovariantDerivativeOn F (fun X ฯƒ x โ†ฆ โˆ‘ i โˆˆ s, (f i x) โ€ข (cov i) X ฯƒ x) u where + addX {_X _X' _ฯƒ} x hx hX hX' hฯƒ := by + rw [โ† Finset.sum_add_distrib] + congr + ext i + simp [(h i).addX hx hX hX' hฯƒ] + smulX {_X _ฯƒ _g} x hx hX hฯƒ hg := by + rw [Finset.smul_sum] + congr + ext i + simp [(h i).smulX hx hX hฯƒ hg] + module + addฯƒ {_X _ฯƒ _ฯƒ' _x} hX hฯƒ hฯƒ' hx := by + rw [โ† Finset.sum_add_distrib] + congr + ext i + rw [โ† smul_add, (h i).addฯƒ hX hฯƒ hฯƒ' hx] + smul_const_ฯƒ {_X _ฯƒ _x} a hX hฯƒ hx := by + rw [Finset.smul_sum] + congr + ext i + simp [(h i).smul_const_ฯƒ a hX hฯƒ] + module + leibniz {X ฯƒ g x} hX hฯƒ hg hx := by + calc โˆ‘ i โˆˆ s, f i x โ€ข (cov i) X (g โ€ข ฯƒ) x + _ = โˆ‘ i โˆˆ s, ((g โ€ข (f i โ€ข (cov i) X ฯƒ)) x + + f i x โ€ข (bar (g x)) ((mfderiv% g x) (X x)) โ€ข ฯƒ x) := by + congr + ext i + rw [(h i).leibniz hX hฯƒ hg] + simp_rw [Pi.smul_apply', smul_add] + dsimp + rw [smul_comm] + _ = โˆ‘ i โˆˆ s, ((g โ€ข (f i โ€ข (cov i) X ฯƒ)) x) + + โˆ‘ i โˆˆ s, f i x โ€ข (bar (g x)) ((mfderiv% g x) (X x)) โ€ข ฯƒ x := by + rw [Finset.sum_add_distrib] + _ = (g โ€ข โˆ‘ i โˆˆ s, f i โ€ข (cov i) X ฯƒ) x + (bar (g x)) ((mfderiv% g x) (X x)) โ€ข ฯƒ x := by + -- There has to be a shorter proof! + simp only [Finset.smul_sum, Pi.smul_apply', Finset.sum_apply, add_right_inj] + set B := (bar (g x)) ((mfderiv% g x) (X x)) โ€ข ฯƒ x + trans (โˆ‘ i โˆˆ s, f i x) โ€ข B + ยท rw [Finset.sum_smul] + have : โˆ‘ i โˆˆ s, f i x = 1 := by convert congr_fun hf x; simp + rw [this, one_smul] + simp + +/-- An affine combination of finitely many `C^k` connections on `u` is a `C^k` connection on `u`. -/ +lemma _root_.ContMDiffCovariantDerivativeOn.affineCombination' {n : โ„•โˆž} + [VectorBundle ๐•œ F V] {ฮน : Type*} {s : Finset ฮน} {u : Set M} + {cov : ฮน โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + (hcov : โˆ€ i โˆˆ s, ContMDiffCovariantDerivativeOn F n (cov i) u) + {f : ฮน โ†’ M โ†’ ๐•œ} (hf : โˆ€ i โˆˆ s, CMDiff[u] n (f i)) : + ContMDiffCovariantDerivativeOn F n (fun X ฯƒ x โ†ฆ โˆ‘ i โˆˆ s, (f i x) โ€ข (cov i) X ฯƒ x) u where + contMDiff hฯƒ hX := + ContMDiffOn.sum_section (fun i hi โ†ฆ (hf i hi).smul_section <| (hcov i hi).contMDiff hฯƒ hX) + +variable {s : Set M} + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + +lemma add_one_form [โˆ€ (x : M), IsTopologicalAddGroup (V x)] + [โˆ€ (x : M), ContinuousSMul ๐•œ (V x)] (hf : IsCovariantDerivativeOn F f s) + (A : ฮ  x : M, TangentSpace I x โ†’L[๐•œ] V x โ†’L[๐•œ] V x) : + IsCovariantDerivativeOn F (fun X ฯƒ x โ†ฆ f X ฯƒ x + A x (X x) (ฯƒ x)) s where + addX {_X _X' _ฯƒ} x hx hX hX' hฯƒ := by + simp [hf.addX hx hX hX' hฯƒ] + abel + smulX {_X _ฯƒ _g} x hx hX hฯƒ hg := by + simp [hf.smulX hx hX hฯƒ hg] + addฯƒ {_X _ฯƒ _ฯƒ' _x} hX hฯƒ hฯƒ' hx := by + simp [hf.addฯƒ hX hฯƒ hฯƒ'] + abel + smul_const_ฯƒ {_X _ฯƒ _x} a hX hฯƒ hx := by simp [hf.smul_const_ฯƒ a hX hฯƒ] + leibniz {X ฯƒ g x} hX hฯƒ hg hx := by + simp [hf.leibniz hX hฯƒ hg] + module + +end operations + +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) + -- TODO: mfderiv% does not work here; `s` is a section into the trivial bundle + (fun X s x โ†ฆ mfderiv I ๐“˜(๐•œ, F) s x (X x)) univ where + addX {_X _X' _ฯƒ} x _ hX hX' hฯƒ := by simp + smulX {_X _ฯƒ} c' x _ := by simp + addฯƒ {_X ฯƒ ฯƒ' x} hX hฯƒ hฯƒ' hx := by + rw [mdifferentiableAt_section] at hฯƒ hฯƒ' + -- TODO: specialize mdifferentiableAt_section to trivial bundles? + change MDifferentiableAt I ๐“˜(๐•œ, F) ฯƒ x at hฯƒ + change MDifferentiableAt I ๐“˜(๐•œ, F) ฯƒ' x at hฯƒ' + rw [mfderiv_add hฯƒ hฯƒ'] + rfl + smul_const_ฯƒ {_X _ฯƒ _x} a hX hฯƒ hx := by rw [mfderiv_const_smul] + leibniz {X ฯƒ f x} hX hฯƒ hf hx := by + rw [mdifferentiableAt_section] at hฯƒ + exact mfderiv_smul hฯƒ hf (X x) + +lemma of_endomorphism (A : (x : M) โ†’ TangentSpace I x โ†’L[๐•œ] F โ†’L[๐•œ] F) : + IsCovariantDerivativeOn F + (fun (X : ฮ  x : M, TangentSpace I x) (s : M โ†’ F) x โ†ฆ + letI d : F := mfderiv% s x (X x) + d + A x (X x) (s x)) univ := + trivial I M F |>.add_one_form A + +end trivial_bundle + +end IsCovariantDerivativeOn + +/-! Bundled global covariant derivatives -/ + +variable (I F V) in +@[ext] +structure CovariantDerivative [IsManifold I 1 M] where + toFun : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x) + isCovariantDerivativeOn : IsCovariantDerivativeOn F toFun Set.univ + +namespace CovariantDerivative + +attribute [coe] toFun + +variable [IsManifold I 1 M] + +/-- Coercion of a `CovariantDerivative` to function -/ +instance : CoeFun (CovariantDerivative I F V) + fun _ โ†ฆ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x) := + โŸจfun e โ†ฆ e.toFunโŸฉ + +instance (cov : CovariantDerivative I F V) {s : Set M} : + IsCovariantDerivativeOn F cov s := by + apply cov.isCovariantDerivativeOn.mono (fun โฆƒaโฆ„ a โ†ฆ trivial) + +/-- If `f : Vec(M) ร— ฮ“(E) โ†’ Vec(M)` 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} + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + (hf : โˆ€ i, IsCovariantDerivativeOn F f (s i)) (hs : โ‹ƒ i, s i = Set.univ) : + CovariantDerivative I F V := + โŸจf, hs โ–ธ IsCovariantDerivativeOn.iUnion hfโŸฉ + +@[simp] +lemma of_isCovariantDerivativeOn_of_open_cover_coe {ฮน : Type*} {s : ฮน โ†’ Set M} + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + (hf : โˆ€ i, IsCovariantDerivativeOn F f (s i)) (hs : โ‹ƒ i, s i = Set.univ) : + of_isCovariantDerivativeOn_of_open_cover hf hs = f := rfl + + +/-- +A covariant derivative โˆ‡ is called of class `C^k` iff, +whenever `X` is a `C^k` section and `ฯƒ` a `C^{k+1}` section, the result `โˆ‡ X ฯƒ` is a `C^k` section. +This is a class so typeclass inference can deduce this automatically. +-/ +class ContMDiffCovariantDerivative (cov : CovariantDerivative I F V) (k : โ„•โˆž) where + contMDiff : ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ + +@[simp] +lemma contMDiffCovariantDerivativeOn_univ_iff {cov : CovariantDerivative I F V} {k : โ„•โˆž} : + ContMDiffCovariantDerivativeOn F k cov.toFun Set.univ โ†” ContMDiffCovariantDerivative cov k := + โŸจfun h โ†ฆ โŸจhโŸฉ, fun h โ†ฆ h.contMDiffโŸฉ + +-- future: if g is a C^k metric on a manifold M, the corresponding Levi-Civita connection +-- is of class C^k (up to off-by-one errors) + +section computational_properties + +@[simp] +lemma zeroX (cov : CovariantDerivative I F V) {ฯƒ : ฮ  x : M, V x} (hฯƒ : MDiff (T% ฯƒ)) : + cov 0 ฯƒ = 0 := by + ext x + exact cov.isCovariantDerivativeOn.zeroX (by trivial) (hฯƒ x) + +@[simp] +lemma zeroฯƒ [VectorBundle ๐•œ F V] (cov : CovariantDerivative I F V) + {X : ฮ  x : M, TangentSpace I x} (hX : MDiff (T% X)) : cov X 0 = 0 := by + ext x + exact cov.isCovariantDerivativeOn.zeroฯƒ (hX x) + +lemma sum_X (cov : CovariantDerivative I F V) + {ฮน : Type*} {s : Finset ฮน} {X : ฮน โ†’ ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} + (hX : โˆ€ i, MDiff (T% (X i))) (hฯƒ : MDiff (T% ฯƒ)): + cov (โˆ‘ i โˆˆ s, X i) ฯƒ = โˆ‘ i โˆˆ s, cov (X i) ฯƒ := by + ext x + simpa using cov.isCovariantDerivativeOn.sum_X trivial (fun i โ†ฆ hX i x) (hฯƒ x) + +end computational_properties + +section operations + +/-- An affine combination of covariant derivatives is a covariant derivative. -/ +@[simps] +def affineCombination (cov cov' : CovariantDerivative I F V) (g : M โ†’ ๐•œ) : + CovariantDerivative I F V where + toFun := fun X ฯƒ โ†ฆ (g โ€ข (cov X ฯƒ)) + (1 - g) โ€ข (cov' X ฯƒ) + isCovariantDerivativeOn := + cov.isCovariantDerivativeOn.affineCombination cov'.isCovariantDerivativeOn _ + +/-- A finite affine combination of covariant derivatives is a covariant derivative. -/ +def affineCombination' {ฮน : Type*} {s : Finset ฮน} [Nonempty s] + (cov : ฮน โ†’ CovariantDerivative I F V) {f : ฮน โ†’ M โ†’ ๐•œ} (hf : โˆ‘ i โˆˆ s, f i = 1) : + CovariantDerivative I F V where + toFun X t x := โˆ‘ i โˆˆ s, (f i x) โ€ข (cov i) X t x + isCovariantDerivativeOn := IsCovariantDerivativeOn.affineCombination' + (fun i โ†ฆ (cov i).isCovariantDerivativeOn) hf + +/-- An affine combination of two `C^k` connections is a `C^k` connection. -/ +lemma ContMDiffCovariantDerivative.affineCombination [VectorBundle ๐•œ F V] + (cov cov' : CovariantDerivative I F V) + {f : M โ†’ ๐•œ} {n : โ„•โˆž} (hf : ContMDiff I ๐“˜(๐•œ) n f) + (hcov : ContMDiffCovariantDerivative cov n) (hcov' : ContMDiffCovariantDerivative cov' n) : + ContMDiffCovariantDerivative (affineCombination cov cov' f) n where + contMDiff := + ContMDiffCovariantDerivativeOn.affineCombination hf.contMDiffOn hcov.contMDiff hcov'.contMDiff + +/-- An affine combination of finitely many `C^k` connections is a `C^k` connection. -/ +lemma ContMDiffCovariantDerivative.affineCombination' [VectorBundle ๐•œ F V] + {ฮน : Type*} {s : Finset ฮน} [Nonempty s] + (cov : ฮน โ†’ CovariantDerivative I F V) {f : ฮน โ†’ M โ†’ ๐•œ} (hf : โˆ‘ i โˆˆ s, f i = 1) {n : โ„•โˆž} + (hf' : โˆ€ i โˆˆ s, ContMDiff I ๐“˜(๐•œ) n (f i)) + (hcov : โˆ€ i โˆˆ s, ContMDiffCovariantDerivative (cov i) n) : + ContMDiffCovariantDerivative (affineCombination' cov hf) n where + contMDiff := + ContMDiffCovariantDerivativeOn.affineCombination' + (fun i hi โ†ฆ (hcov i hi).contMDiff) (fun i hi โ†ฆ (hf' i hi).contMDiffOn) + +-- Future: prove a version with a locally finite sum, and deduce that C^k connections always +-- exist (using a partition of unity argument) + +end operations + +section trivial_bundle + +set_option backward.isDefEq.respectTransparency false in +variable (I M F) in +@[simps] +noncomputable def trivial [IsManifold I 1 M] : CovariantDerivative I F (Trivial M F) where + toFun X s x := mfderiv I ๐“˜(๐•œ, F) s x (X x) + isCovariantDerivativeOn := -- TODO use previous work + { addX {_X _X' _ฯƒ} x _ hX hX' hฯƒ := by simp + smulX {_X _ฯƒ} c' x _ := by simp + addฯƒ {_X ฯƒ ฯƒ' x} hX hฯƒ hฯƒ' hx := by + rw [mdifferentiableAt_section] at hฯƒ hฯƒ' + -- TODO: specialize mdifferentiableAt_section to trivial bundles? + change MDifferentiableAt I ๐“˜(๐•œ, F) ฯƒ x at hฯƒ + change MDifferentiableAt I ๐“˜(๐•œ, F) ฯƒ' x at hฯƒ' + rw [mfderiv_add hฯƒ hฯƒ'] + rfl + smul_const_ฯƒ {_X _ฯƒ _x} a hX hฯƒ hx := by rw [mfderiv_const_smul] + leibniz {X ฯƒ f x} hX hฯƒ hf hx := by + rw [mdifferentiableAt_section] at hฯƒ + exact mfderiv_smul hฯƒ hf (X x) } + +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 -- {X ฯƒ} hX hฯƒ + 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 X ฯƒ := fun x โ†ฆ fderiv ๐•œ ฯƒ x (X x) + A x (X x) (ฯƒ x) + isCovariantDerivativeOn := by + convert IsCovariantDerivativeOn.of_endomorphism (I := ๐“˜(๐•œ, E)) A + ext f x v + rw [mfderiv_eq_fderiv] +end CovariantDerivative +end any_field + +section real + +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 + +/-- `cov X ฯƒ x` only depends on `X` via `X x` -/ +lemma congr_X_at [FiniteDimensional โ„ E] [T2Space M] [IsManifold I โˆž M] [VectorBundle โ„ F V] + {cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + {X X' : ฮ  x : M, TangentSpace I x} + {ฯƒ : ฮ  x : M, V x} {x : M} + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hฯƒ : MDiffAt (T% ฯƒ) x) + (hx : x โˆˆ u) (hXX' : X x = X' x) : + cov X ฯƒ x = cov X' ฯƒ x := by + refine tensoriality_criterion I E (TangentSpace I) (ฯ† := fun X โ†ฆ cov X ฯƒ) F V hX hX' hXX' ?_ ?_ + ยท intro f X hf hX + exact hcov.smulX hX hฯƒ hf hx + ยท intro X X' hX hX' + exact hcov.addX hX hX' hฯƒ hx + +lemma congr_ฯƒ_smoothBumpFunction [T2Space M] [IsManifold I โˆž M] + [FiniteDimensional โ„ E] + {cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (X : ฮ  x : M, TangentSpace I x) {ฯƒ : ฮ  x : M, V x} + (hX : MDiffAt (T% X) x) + (hฯƒ : MDiffAt (T% ฯƒ) x) + (f : SmoothBumpFunction I x) + (hx : x โˆˆ u) : + cov X ((f : M โ†’ โ„) โ€ข ฯƒ) x = cov X ฯƒ x := by + have hf : MDiffAt f x := f.contMDiffAt.mdifferentiableAt (by simp) + have := hcov.leibniz hX hฯƒ hf hx + rw [hcov.leibniz hX hฯƒ _ hx] + swap; ยท apply f.contMDiff.mdifferentiable (by norm_num) + calc _ + _ = cov X ฯƒ x + 0 := ?_ + _ = cov X ฯƒ x := by rw [add_zero] + suffices mfderiv% (1 : M โ†’ โ„) x (X x) = 0 โˆจ ฯƒ x = 0 by + simpa [f.eq_one, f.eventuallyEq_one.mfderiv_eq] + rw [show mfderiv I ๐“˜(โ„) 1 x = 0 by apply mfderiv_const] + left + rfl + +lemma congr_ฯƒ_of_eqOn [FiniteDimensional โ„ E] [T2Space M] [IsManifold I โˆž M] [VectorBundle โ„ F V] + {cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + {X : ฮ  x : M, TangentSpace I x} {ฯƒ ฯƒ' : ฮ  x : M, V x} + (hX : MDiffAt (T% X) x) + (hฯƒ : MDiffAt (T% ฯƒ) x) + (hฯƒ' : MDiffAt (T% ฯƒ') x) + (hxs : s โˆˆ ๐“ x) + (hฯƒฯƒ' : โˆ€ x โˆˆ s, ฯƒ x = ฯƒ' x) : + cov X ฯƒ x = cov X ฯƒ' x := by + -- Choose a smooth bump function ฯˆ with support around `x` contained in `s` + obtain โŸจฯˆ, _, hฯˆโŸฉ := (SmoothBumpFunction.nhds_basis_support (I := I) hxs).mem_iff.1 hxs + -- Observe that `ฯˆ โ€ข ฯƒ = ฯˆ โ€ข ฯƒ'` as dependent functions. + have (x : M) : ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x = ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by + by_cases h : x โˆˆ s + ยท simp [hฯƒฯƒ' x h] + ยท simp [Function.notMem_support.mp fun a โ†ฆ h (hฯˆ a)] + -- Then, it's a chain of (dependent) equalities. + calc cov X ฯƒ x + _ = cov X ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x := by + rw [hcov.congr_ฯƒ_smoothBumpFunction X hX hฯƒ ฯˆ (mem_of_mem_nhds hxs)] + _ = cov X ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by rw [funext this] + _ = cov X ฯƒ' x := by + rw [hcov.congr_ฯƒ_smoothBumpFunction X hX hฯƒ' ฯˆ (mem_of_mem_nhds hxs)] + +-- TODO: prove that `cov X ฯƒ x` depends on ฯƒ only via ฯƒ(X) and the 1-jet of ฯƒ at x +-- this should be easy using the projection formula below. + +/-- The difference of two covariant derivatives, as a function `ฮ“(TM) ร— ฮ“(E) โ†’ ฮ“(E)`. +Future lemmas will upgrade this to a map `TM โŠ• E โ†’ E`. -/ +def differenceAux (cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)) : + (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x) := + fun X ฯƒ โ†ฆ cov X ฯƒ - cov' X ฯƒ + +omit [(x : M) โ†’ Module โ„ (V x)] [(x : M) โ†’ TopologicalSpace (V x)] in +@[simp] +lemma differenceAux_apply + (cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)) + (X : ฮ  x : M, TangentSpace I x) (ฯƒ : ฮ  x : M, V x) : + differenceAux cov cov' X ฯƒ = cov X ฯƒ - cov' X ฯƒ := rfl + +variable [IsManifold I 1 M] + +lemma differenceAux_smul_eq + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (hcov' : IsCovariantDerivativeOn F cov' u) + {X : ฮ  x : M, TangentSpace I x} (ฯƒ : ฮ  x : M, V x) (f : M โ†’ โ„) + {x : M} (hx : x โˆˆ u := by trivial) + (hX : MDiffAt (T% X) x) + (hฯƒ : MDiffAt (T% ฯƒ) x) + (hf : MDiffAt f x) : + differenceAux cov cov' X ((f : M โ†’ โ„) โ€ข ฯƒ) x = f x โ€ข differenceAux cov cov' X ฯƒ x:= + calc _ + _ = cov X ((f : M โ†’ โ„) โ€ข ฯƒ) x - cov' X ((f : M โ†’ โ„) โ€ข ฯƒ) x := rfl + _ = (f x โ€ข cov X ฯƒ x + ((bar _).toFun <| mfderiv% f x (X x)) โ€ข ฯƒ x) + - (f x โ€ข cov' X ฯƒ x + ((bar _).toFun <| mfderiv% f x (X x)) โ€ข ฯƒ x) := by + simp [hcov.leibniz hX hฯƒ hf, hcov'.leibniz hX hฯƒ hf] + _ = f x โ€ข cov X ฯƒ x - f x โ€ข cov' X ฯƒ x := by simp + _ = f x โ€ข (cov X ฯƒ x - cov' X ฯƒ x) := by simp [smul_sub] + _ = _ := rfl + +lemma differenceAux_smul_eq' + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (hcov' : IsCovariantDerivativeOn F cov' u) + {X : ฮ  x : M, TangentSpace I x} + (hX : MDiffAt (T% X) x) + {ฯƒ : ฮ  x : M, V x} (hฯƒ : MDiffAt (T% ฯƒ) x) + {f : M โ†’ โ„} (hf : MDiffAt f x) + (hx : x โˆˆ u := by trivial) : + differenceAux cov cov' (f โ€ข X) ฯƒ x = f x โ€ข differenceAux cov cov' X ฯƒ x := by + simp [differenceAux, hcov.smulX hX hฯƒ hf, hcov'.smulX hX hฯƒ hf, smul_sub] + +/-- The value of `differenceAux cov cov' X ฯƒ` at `xโ‚€` depends only on `X xโ‚€` and `ฯƒ xโ‚€`. -/ +lemma differenceAux_tensorial + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {u : Set M} (hcov : IsCovariantDerivativeOn F cov u) + (hcov' : IsCovariantDerivativeOn F cov' u) + [T2Space M] [IsManifold I โˆž M] [FiniteDimensional โ„ E] + [FiniteDimensional โ„ F] [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + {X X' : ฮ  x : M, TangentSpace I x} {ฯƒ ฯƒ' : ฮ  x : M, V x} {xโ‚€ : M} + (hX : MDiffAt (T% X) xโ‚€) -- TODO: is this hypotheses truly necessary? + (hX' : MDiffAt (T% X') xโ‚€) + (hฯƒ : MDiffAt (T% ฯƒ) xโ‚€) + (hฯƒ' : MDiffAt (T% ฯƒ') xโ‚€) + (hXX' : X xโ‚€ = X' xโ‚€) (hฯƒฯƒ' : ฯƒ xโ‚€ = ฯƒ' xโ‚€) (hx : xโ‚€ โˆˆ u := by trivial) : + differenceAux cov cov' X ฯƒ xโ‚€ = differenceAux cov cov' X' ฯƒ' xโ‚€ := by + trans differenceAux cov cov' X' ฯƒ xโ‚€ + ยท let ฯ† : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x, V x) := fun X โ†ฆ differenceAux cov cov' X ฯƒ + change ฯ† X xโ‚€ = ฯ† X' xโ‚€ + -- TODO: is there a version of `tensoriality_criterion` which does not require `hX`? + apply tensoriality_criterion (E := E) (I := I) E (TangentSpace I) F V hX hX' hXX' + ยท intro f X hf hX + exact hcov.differenceAux_smul_eq' hcov' hX hฯƒ hf + ยท intro X X' hX hX' + unfold ฯ† differenceAux + simp only [Pi.sub_apply, hcov.addX hX hX' hฯƒ, hcov'.addX hX hX' hฯƒ] + abel + ยท let ฯ† : (ฮ  x : M, V x) โ†’ (ฮ  x, V x) := fun ฯƒ โ†ฆ differenceAux cov cov' X' ฯƒ + change ฯ† ฯƒ xโ‚€ = ฯ† ฯƒ' xโ‚€ + apply tensoriality_criterion (E := E) (I := I) F V F V hฯƒ hฯƒ' hฯƒฯƒ' + ยท intro f ฯƒ x hf + exact hcov.differenceAux_smul_eq hcov' ฯƒ f hx hX' hf x + ยท intro ฯƒ ฯƒ' hฯƒ hฯƒ' + unfold ฯ† differenceAux + simp only [Pi.sub_apply] + rw [hcov.addฯƒ, hcov'.addฯƒ] <;> try assumption + abel + +lemma isBilinearMap_differenceAux + [FiniteDimensional โ„ F] [T2Space M] [FiniteDimensional โ„ E] [IsManifold I โˆž M] + [VectorBundle โ„ F V] [ContMDiffVectorBundle โˆž F V I] {s : Set M} {cov cov'} {x : M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) (hx : x โˆˆ s := by trivial) : + IsBilinearMap โ„ (fun (Xโ‚€ : TangentSpace I x) (ฯƒโ‚€ : V x) โ†ฆ + differenceAux cov cov' (extend I E Xโ‚€) (extend I F ฯƒโ‚€) x) where + add_left u v w := by + simp only [differenceAux, extend_add, Pi.sub_apply] + rw [hcov.addX, hcov'.addX]; ยท abel + all_goals apply mdifferentiable_extend + add_right u v w := by + simp only [differenceAux, extend_add, Pi.sub_apply] + rw [hcov.addฯƒ, hcov'.addฯƒ]; ยท abel + all_goals apply mdifferentiable_extend + smul_left a u v := by + simp only [differenceAux, extend_smul, Pi.sub_apply] + rw [hcov.smul_const_X, hcov'.smul_const_X]; ยท module + all_goals apply mdifferentiable_extend + smul_right a u v := by + simp only [differenceAux, extend_smul, Pi.sub_apply] + rw [hcov.smul_const_ฯƒ, hcov'.smul_const_ฯƒ]; ยท module + all_goals apply mdifferentiable_extend + +variable [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul โ„ (V x)] + +/-- The difference of two covariant derivatives, as a tensorial map -/ +noncomputable def difference [โˆ€ x, FiniteDimensional โ„ (V x)] [โˆ€ x, T2Space (V x)] + [FiniteDimensional โ„ F] [T2Space M] [FiniteDimensional โ„ E] [IsManifold I โˆž M] + [FiniteDimensional โ„ E] [VectorBundle โ„ F V] [ContMDiffVectorBundle โˆž F V I] + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {s : Set M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) + (x : M) : TangentSpace I x โ†’L[โ„] V x โ†’L[โ„] V x := + haveI : FiniteDimensional โ„ (TangentSpace I x) := by assumption + open Classical in + if hx : x โˆˆ s then (isBilinearMap_differenceAux (F := F) hcov hcov').toContinuousLinearMap + else 0 + +lemma difference_def [โˆ€ x, FiniteDimensional โ„ (V x)] [โˆ€ x, T2Space (V x)] + [FiniteDimensional โ„ F] [T2Space M] [IsManifold I โˆž M] [FiniteDimensional โ„ E] + [VectorBundle โ„ F V] [ContMDiffVectorBundle โˆž F V I] + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {s : Set M} {x : M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) + (hx : x โˆˆ s := by trivial) (Xโ‚€ : TangentSpace I x) (ฯƒโ‚€ : V x) : + difference hcov hcov' x Xโ‚€ ฯƒโ‚€ = + cov (extend I E Xโ‚€) (extend I F ฯƒโ‚€) x - cov' (extend I E Xโ‚€) (extend I F ฯƒโ‚€) x := by + simp only [difference, hx, reduceDIte] + rfl + +@[simp] +lemma difference_apply [โˆ€ x, FiniteDimensional โ„ (V x)] [โˆ€ x, T2Space (V x)] + [FiniteDimensional โ„ F] [T2Space M] [IsManifold I โˆž M] [FiniteDimensional โ„ E] + [VectorBundle โ„ F V] [ContMDiffVectorBundle โˆž F V I] + {cov cov' : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + {s : Set M} {x : M} + (hcov : IsCovariantDerivativeOn F cov s) + (hcov' : IsCovariantDerivativeOn F cov' s) + (hx : x โˆˆ s := by trivial) {X : ฮ  x, TangentSpace I x} {ฯƒ : ฮ  x, V x} + (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) : + difference hcov hcov' x (X x) (ฯƒ x) = + cov X ฯƒ x - cov' X ฯƒ x := by + simp only [difference, hx, reduceDIte] + exact hcov.differenceAux_tensorial hcov' (mdifferentiable_extend ..) hX + (mdifferentiable_extend ..) hฯƒ (extend_apply_self _) (extend_apply_self _) hx + +-- The classification of real connections over a trivial bundle +section classification + +variable [FiniteDimensional โ„ E] [FiniteDimensional โ„ F] [T2Space M] [IsManifold I โˆž 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 : (ฮ  x : M, TangentSpace I x) โ†’ (M โ†’ F) โ†’ (M โ†’ F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : + โˆƒ (A : (x : M) โ†’ TangentSpace I x โ†’L[โ„] F โ†’L[โ„] F), + โˆ€ X : (x : M) โ†’ TangentSpace I x, โˆ€ ฯƒ : M โ†’ F, โˆ€ x โˆˆ s, + MDiffAt (T% X) x โ†’ MDiffAt (T% ฯƒ) x โ†’ + letI d : F := mfderiv% ฯƒ x (X x) + cov X ฯƒ x = d + A x (X x) (ฯƒ x) := by + use fun x โ†ฆ hcov.difference (trivial I M F |>.mono <| subset_univ s) x + intro X ฯƒ x hx hX hฯƒ + rw [hcov.difference_apply _ (by trivial) hX hฯƒ] + module + +noncomputable def one_form {cov : (ฮ  x : M, TangentSpace I x) โ†’ (M โ†’ F) โ†’ (M โ†’ F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) : + ฮ  x : M, TangentSpace I x โ†’L[โ„] F โ†’L[โ„] F := + hcov.exists_one_form.choose + +lemma eq_one_form {cov : (ฮ  x : M, TangentSpace I x) โ†’ (M โ†’ F) โ†’ (M โ†’ F)} + {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + {X : (x : M) โ†’ TangentSpace I x} {ฯƒ : M โ†’ F} + {x : M} (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ s := by trivial) : + letI d : F := mfderiv% ฯƒ x (X x) + cov X ฯƒ x = d + hcov.one_form x (X x) (ฯƒ x) := + hcov.exists_one_form.choose_spec X ฯƒ x hx hX hฯƒ + +lemma _root_.CovariantDerivative.exists_one_form + (cov : CovariantDerivative I F (Bundle.Trivial M F)) : + โˆƒ (A : (x : M) โ†’ TangentSpace I x โ†’L[โ„] F โ†’L[โ„] F), + โˆ€ X : (x : M) โ†’ TangentSpace I x, โˆ€ ฯƒ : M โ†’ F, โˆ€ x, + MDiffAt (T% X) x โ†’ MDiffAt (T% ฯƒ) x โ†’ + letI d : F := mfderiv% ฯƒ x (X x) + cov X ฯƒ x = d + A x (X x) (ฯƒ x) := by + simpa using cov.isCovariantDerivativeOn.exists_one_form + +end classification + +section projection_trivial_bundle + +variable [FiniteDimensional โ„ E] [FiniteDimensional โ„ F] + [T2Space M] [IsManifold I โˆž M] + +local notation "TM" => TangentSpace I + +variable {cov : (ฮ  x : M, TangentSpace I x) โ†’ (M โ†’ F) โ†’ (M โ†’ 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 + (evalL โ„ F F f โˆ˜L hcov.one_form x โˆ˜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 v f := rfl + +lemma cov_eq_proj (hcov : IsCovariantDerivativeOn F cov s) (X : ฮ  x : M, TM x) (ฯƒ : M โ†’ F) + {x : M} (hX : MDiffAt (T% X) x) (hฯƒ : MDiffAt (T% ฯƒ) x) (hx : x โˆˆ s := by trivial) : + cov X ฯƒ x = hcov.projection x (ฯƒ x) (X x, mfderiv% ฯƒ x (X x)) := by + simpa using hcov.eq_one_form hX hฯƒ + +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 (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 โ†” + โˆƒ ฯƒ : M โ†’ F, MDiffAt (T% ฯƒ) x โˆง + ฯƒ x = f โˆง + mfderiv% ฯƒ x u = v โˆง + cov (extend I E u) ฯƒ x = 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 [hcov.zeroX, mdifferentiableAt_section, 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'' + ยท rw [hcov.eq_one_form (mdifferentiable_extend ..)] + ยท simp [w, h'', h, huv] + ยท rwa [mdifferentiableAt_section] + ยท rwa [mdifferentiableAt_section] + ยท rintro โŸจฯƒ, ฯƒ_diff, rfl, rfl, covฯƒโŸฉ + simp only [horiz, LinearMap.mem_ker, ContinuousLinearMap.coe_coe, projection_apply, โ† covฯƒ] + rw [hcov.eq_one_form (mdifferentiable_extend ..) ฯƒ_diff, extend_apply_self] + +end projection_trivial_bundle + +end IsCovariantDerivativeOn + +section to_trivialization + +namespace Bundle.Trivialization + +variable (e : Trivialization F (ฯ€ F V)) [MemTrivializationAtlas e] [IsManifold I 1 M] + +noncomputable +def pushCovDer + (cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)) : + (ฮ  x : M, TangentSpace I x) โ†’ (M โ†’ F) โ†’ (M โ†’ F) := + fun X ฯƒ x โ†ฆ e (cov X (fun x' โ†ฆ e.symm x' <| ฯƒ x') x) |>.2 + +omit [MemTrivializationAtlas e] in +lemma pushCovDer_ofSect [FiniteDimensional โ„ E] [FiniteDimensional โ„ F] + [T2Space M] [IsManifold I โˆž M] + [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + {cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + (hcov : IsCovariantDerivativeOn F cov e.baseSet) + {X : ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} {x : M} + (hX : MDiffAt T%X x) (hฯƒ : MDiffAt T%ฯƒ x) + (hx : x โˆˆ e.baseSet := by assumption) : + (e.pushCovDer cov) X (fun x โ†ฆ (e (ฯƒ x)).2) x = (e (cov X ฯƒ x)).2 := by + have : cov X (fun x' โ†ฆ e.symm x' (e (T% ฯƒ x')).2) x = cov X ฯƒ x := by + apply hcov.congr_ฯƒ_of_eqOn hX _ hฯƒ (e.baseSet_mem_nhds hx) + ยท exact fun y hy โ†ฆ by simp [hy] --FIXME extract as lemma? + ยท rwa [(e.symm_apply_apply_mk_eventuallyEq hx ฯƒ).mdifferentiableAt_iff] + unfold pushCovDer + rw [this] + + +variable {cov : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x)} + -- {s : Set M} (hcov : IsCovariantDerivativeOn F cov s) + +lemma pushCovDer_isCovariantDerivativeOn + [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + {u : Set M} (hu : u โІ e.baseSet) + (hcov : IsCovariantDerivativeOn F cov u) : + IsCovariantDerivativeOn F (e.pushCovDer cov) u where + addX {X X' ฯƒ x} hX hX' hฯƒ hx := by + set s := (fun x' โ†ฆ e.symm x' (ฯƒ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hฯƒ + unfold pushCovDer + rw [hcov.addX hX hX' hs, e.map_add โ„ (hu hx)] + smulX {X ฯƒ g x} hX hฯƒ hg hx := by + set s := (fun x' โ†ฆ e.symm x' (ฯƒ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hฯƒ + unfold pushCovDer + rw [hcov.smulX hX hs hg, e.map_smul (hu hx)] + smul_const_ฯƒ {X ฯƒ x} a hX hฯƒ hx := by + set s := (fun x' โ†ฆ e.symm x' (ฯƒ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hฯƒ + unfold pushCovDer + rw [โ† e.map_smul (hu hx), โ† hcov.smul_const_ฯƒ a hX hs hx] + congr + ext y + simp [e.symm_map_smul, s] + addฯƒ {X ฯƒ ฯƒ' x} hX hฯƒ hฯƒ' hx := by + set s := (fun x' โ†ฆ e.symm x' (ฯƒ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hฯƒ + set s' := (fun x' โ†ฆ e.symm x' (ฯƒ' x')) + have hs' : MDiffAt (T% s') x := + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 + hฯƒ' + unfold pushCovDer + rw [โ† e.map_add โ„ (hu hx)] + congr + rw [โ† hcov.addฯƒ hX hs hs' hx] + congr + ext y + simp [e.symm_map_add โ„, s, s'] + leibniz {X ฯƒ g x} hX hฯƒ hg hx := by + set s := (fun x' โ†ฆ e.symm x' (ฯƒ x')) + have hs : MDiffAt (T% s) x := + e.mdifferentiableAt_section_of_function (hu hx) <| mdifferentiableAt_section_trivial_iff.1 hฯƒ + unfold pushCovDer + have : (fun x' โ†ฆ e.symm x' ((g โ€ข ฯƒ) x')) = g โ€ข s := by + ext y + simp [s, e.symm_map_smul] + rw [this, hcov.leibniz hX hs hg hx] + suffices g x โ€ข (e โŸจx, cov X s xโŸฉ).2 + (bar (g x)) ((mfderiv% g x) (X x)) โ€ข (e โŸจx, s xโŸฉ).2 = + g x โ€ข (e โŸจx, cov X (fun x' โ†ฆ e.symm x' (ฯƒ x')) xโŸฉ).2 + + (bar (g x)) ((mfderiv% g x) (X x)) โ€ข ฯƒ x by simpa [e.map_add โ„ (hu hx), e.map_smul (hu hx)] + congr + rw [e.apply_mk_symm (hu hx)] + +variable {e} in +lemma coordChangeL_pushCovDer + [FiniteDimensional โ„ E] [T2Space M] [IsManifold I โˆž M] + {e' : Trivialization F (ฯ€ F V)} [MemTrivializationAtlas e'] + [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet โˆฉ e'.baseSet) + {x : M} (hx : x โˆˆ e.baseSet โˆฉ e'.baseSet) + {X : ฮ  x : M, TangentSpace I x} (hX : MDiffAt (T% X) x) + {s : M โ†’ F} (hs : MDiffAt s x) : + e.coordChangeL โ„ e' x (e.pushCovDer cov X s x) = + e'.pushCovDer cov X (fun x โ†ฆ e.coordChangeL โ„ e' x (s x)) x := by + unfold pushCovDer + let ฯƒ := (fun x' โ†ฆ e.symm x' (s x')) + rw [coordChangeL_apply e e' hx] + refold_let ฯƒ + have : e.symm x (e โŸจx, cov X ฯƒ xโŸฉ).2 = cov X ฯƒ x := by simp [hx.1] + rw [this] + -- TODO: extract lemma? + have : โˆ€ x' โˆˆ e.baseSet โˆฉ e'.baseSet, ฯƒ x' = + e'.symm x' ((fun x โ†ฆ (coordChangeL โ„ e e' x) (s x)) x') := by + rintro x' โŸจhx'e, hx'e'โŸฉ + simp only + rw [coordChangeL_apply e e' โŸจhx'e, hx'e'โŸฉ] + -- simp [hx'e'] -- TODO doesnโ€™t work + rw [symm_apply_apply_mk e' hx'e'] + have mem : e.baseSet โˆฉ e'.baseSet โˆˆ ๐“ x := by + -- FIXME: make sure grind can do this proof + exact inter_mem (baseSet_mem_nhds e (mem_of_mem_inter_left hx)) + (baseSet_mem_nhds e' (mem_of_mem_inter_right hx)) + have hฯƒ : MDiffAt (T% ฯƒ) x := + mdifferentiableAt_section_of_function e hx.1 hs + rw [hcov.congr_ฯƒ_of_eqOn hX hฯƒ ?_ mem this] + -- TODO have automatation doing the next three linesโ€ฆ + apply mdifferentiableAt_section_of_function e' hx.2 + have := contMDiffAt_coordChangeL (n := 1) (IB := I) hx.1 hx.2 + exact this.mdifferentiableAt (zero_ne_one.symm) |>.clm_apply hs + +variable {e} in +lemma coordChangeL_mem_horiz + [FiniteDimensional โ„ E] [T2Space M] [IsManifold I โˆž M] [FiniteDimensional โ„ F] + {e' : Trivialization F (ฯ€ F V)} [MemTrivializationAtlas e'] + [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet โˆฉ e'.baseSet) + {x : M} (hx : x โˆˆ e.baseSet โˆฉ e'.baseSet) {u : TangentSpace I x} {v w : F} : + haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + (u, w) โˆˆ hcove.horiz x v โ†’ + (u, e.coordChangeL โ„ e' x w) โˆˆ hcove'.horiz x (e.coordChangeL โ„ e' x v) := by + have hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + have hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + rw [hcove.mem_horiz_iff_exists, hcove'.mem_horiz_iff_exists] + rintro โŸจs, sdiff, sxv, sxuw, covsโŸฉ + use fun x โ†ฆ e.coordChangeL โ„ e' x (s x), ?_, ?_, ?_ + ยท let X := extend I E u + have hX : MDiffAt (T% X) x := by + -- TODO: extract as lemma? + exact (mdifferentiable_extend I E u).mdifferentiableAt + -- TODO: investigate whether the following line comes from inconsistent ways to + -- state assumptions + rw [mdifferentiableAt_section_trivial_iff] at sdiff + rw [โ† e.coordChangeL_pushCovDer hcov hx hX sdiff, covs] + simp + ยท sorry + ยท congr + ยท rw [โ† sxuw] + sorry + +-- This is PAIIIIINNNN +variable {e} in +lemma coordChangeL_coordChangeL + [VectorBundle โ„ F V] + {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 + +variable {e} in +lemma coordChangeL_mem_horiz_iff + [FiniteDimensional โ„ E] [T2Space M] [IsManifold I โˆž M] [FiniteDimensional โ„ F] + {e' : Trivialization F (ฯ€ F V)} [MemTrivializationAtlas e'] + [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + (hcov : IsCovariantDerivativeOn F cov <| e.baseSet โˆฉ e'.baseSet) + {x : M} (hx : x โˆˆ e.baseSet โˆฉ e'.baseSet) {u : TangentSpace I x} {v w : F} : + haveI hcove := e.pushCovDer_isCovariantDerivativeOn inter_subset_left hcov + haveI hcove' := e'.pushCovDer_isCovariantDerivativeOn inter_subset_right hcov + (u, w) โˆˆ hcove.horiz x v โ†” + (u, e.coordChangeL โ„ e' x w) โˆˆ hcove'.horiz x (e.coordChangeL โ„ e' x v) := by + refine โŸจe.coordChangeL_mem_horiz hcov hx, fun hu โ†ฆ ?_โŸฉ + let v' := e.coordChangeL โ„ e' x v + let w' := e.coordChangeL โ„ e' x w + rw [inter_comm] at hx hcov + have hx' := inter_comm _ _ โ–ธ hx + have hvv' : v = e'.coordChangeL โ„ e x v' := (coordChangeL_coordChangeL hx' v).symm + have hww' : w = e'.coordChangeL โ„ e x w' := (coordChangeL_coordChangeL hx' w).symm + have key := e'.coordChangeL_mem_horiz hcov hx (w := w') (u := u) (v := v') ?_ + ยท rw [โ† hvv', โ† hww'] at key + convert key using 2 + apply inter_comm + ยท convert hu using 2 + apply inter_comm + +end Bundle.Trivialization + +end to_trivialization + +section horiz +namespace CovariantDerivative + +variable [FiniteDimensional โ„ E] [FiniteDimensional โ„ F] + [T2Space M] [IsManifold I โˆž M] + [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + +local notation "TM" => TangentSpace I + +-- FIXMEโ€ฏthe statement of CovariantDerivative.isCovariantDerivativeOn should work on any set + +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.mono fun _ _ โ†ฆ mem_univ _) + 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 โ„ E] [FiniteDimensional โ„ F] [T2Space 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 [IsManifold I 1 M] +variable {cov : CovariantDerivative I F V} + +set_option backward.isDefEq.respectTransparency false in +omit [ContMDiffVectorBundle 1 F V I] in +lemma proj_mderiv [ContMDiffVectorBundle 1 F V I] + {X : ฮ  x : M, TangentSpace I x} {ฯƒ : ฮ  x : M, V x} (x : M) + (hX : MDiffAt (T% X) x) + (hฯƒ : MDiffAt (T% ฯƒ) x) : + cov X ฯƒ x = cov.proj (ฯƒ x) (mfderiv% (T% ฯƒ) x (X x)) := by + let t := trivializationAt F V x + let s := fun x โ†ฆ (t (ฯƒ x)).2 + let Tฯƒx := mfderiv% (T% ฯƒ) x + -- FIXME `mfderiv%` fails on the next line + let Ttฯƒx := mfderiv (I.prod ๐“˜(โ„, F)) (I.prod ๐“˜(โ„, F)) t (ฯƒ x) + change cov X ฯƒ x = (cov.proj (T% ฯƒ x)) ((mfderiv% (T% ฯƒ) x) (X x)) + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + have hx := mem_baseSet_trivializationAt F V x + have hs : MDiffAt (T% s) x := by + rw [t.mdifferentiableAt_section_iff I ฯƒ hx] at hฯƒ + exact (mdifferentiableAt_section I s).mpr hฯƒ + apply t.eq_of hx + erw [cov.snd_triv_proj (T% ฯƒ x), + โ† t.pushCovDer_ofSect (cov.isCovariantDerivativeOn.mono fun _ _ โ†ฆ mem_univ _) hX hฯƒ, + hcov.cov_eq_proj X s hX hs, t.mfderiv_comp_section hฯƒ _ hx] + +end CovariantDerivative +end horiz + +end real + +-- 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_const_ฯƒ X ฯƒ 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 } diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean new file mode 100644 index 00000000000000..925230013ea061 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/LeviCivita.lean @@ -0,0 +1,1188 @@ +/- +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.CovariantDerivative.Torsion +public import Mathlib.Geometry.Manifold.VectorBundle.OrthonormalFrame +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.VectorBundle.Riemannian +public import Mathlib.Util.PrintSorries + +/-! +# The Levi-Civita connection + +This file will define the Levi-Civita connection on any Riemannian manifold. +Details to be written! + +TODO: refactor this file, to make Levi-Civita take a Riemannian metric instead! + + +TODO: more generally, define a notion of metric connections (e.g., those whose parallel transport +is an isometry) and prove the Levi-Civita connection is a metric connection + +-/ + +open Bundle Filter Function Module Topology + +open scoped Bundle Manifold ContDiff + +@[expose] public section -- TODO: think if we want to expose all definitions! + +-- TODO: investigate the need for this option, once the dust has settled and we are happy with +-- how this file has been refactored +set_option backward.isDefEq.respectTransparency false + +-- Let M be a C^k real manifold modeled on (E, H), endowed with a Riemannian metric. +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 โˆž M] + [RiemannianBundle (fun (x : M) โ†ฆ TangentSpace I x)] + -- don't need this assumption (yet?) + -- [IsRiemannianManifold I M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace โ„ E'] + +/-! Compatible connections: a connection on TM is compatible with the metric on M iff +`โˆ‡ X โŸจY, ZโŸฉ = โŸจโˆ‡ X Y, ZโŸฉ + โŸจY, โˆ‡ X ZโŸฉ` holds for all vector fields X, Y and Z on `M`. +The left hand side is the pushforward of the function `โŸจY, ZโŸฉ` along the vector field `X`: +the left hand side at `X` is `df(X x)`, where `f := โŸจY, ZโŸฉ`. -/ + +variable {X X' X'' Y Y' Y'' Z Z' : ฮ  x : M, TangentSpace I x} + +/-- The scalar product of two vector fields -/ +noncomputable abbrev product (X Y : ฮ  x : M, TangentSpace I x) : M โ†’ โ„ := + fun x โ†ฆ inner โ„ (X x) (Y x) +-- Riemannian.lean shows that `product` is C^k if X and Y are + +local notation "โŸช" X ", " Y "โŸซ" => product I X Y + +-- Basic API for the product of two vector fields. +section product + +omit [IsManifold I โˆž M] + +lemma product_apply (x) : โŸชX, YโŸซ x = inner โ„ (X x) (Y x) := rfl + +variable (X Y) in +lemma product_swap : โŸชY, XโŸซ = โŸชX, YโŸซ := by + ext x + apply real_inner_comm + +variable (X) in +@[simp] +lemma product_zero_left : โŸช0, XโŸซ = 0 := by + ext x + simp [product] + +@[simp] +lemma product_zero_right : โŸชX, 0โŸซ = 0 := by rw [product_swap, product_zero_left] + +variable (X X' Y) in +lemma product_add_left : โŸชX + X', YโŸซ = โŸชX, YโŸซ + โŸชX', YโŸซ := by + ext x + simp [product, InnerProductSpace.add_left] + +variable (X X' Y) in +@[simp] +lemma product_add_left_apply (x) : โŸชX + X', YโŸซ x = โŸชX, YโŸซ x + โŸชX', YโŸซ x := by + simp [product, InnerProductSpace.add_left] + +variable (X Y Y') in +lemma product_add_right : โŸชX, Y + Y'โŸซ = โŸชX, YโŸซ + โŸชX, Y'โŸซ := by + rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left] + +variable (X X' Y) in +@[simp] +lemma product_add_right_apply (x) : โŸชX, Y + Y'โŸซ x = โŸชX, YโŸซ x + โŸชX, Y'โŸซ x := by + rw [product_swap, product_swap _ Y, product_swap _ Y', product_add_left_apply] + +variable (X Y) in +@[simp] lemma product_neg_left : โŸช-X, YโŸซ = -โŸชX, YโŸซ := by ext x; simp [product] + +variable (X Y) in +@[simp] lemma product_neg_right : โŸชX, -YโŸซ = -โŸชX, YโŸซ := by ext x; simp [product] + +variable (X X' Y) in +lemma product_sub_left : โŸชX - X', YโŸซ = โŸชX, YโŸซ - โŸชX', YโŸซ := by + ext x + simp [product, inner_sub_left] + +variable (X Y Y') in +lemma product_sub_right : โŸชX, Y - Y'โŸซ = โŸชX, YโŸซ - โŸชX, Y'โŸซ := by + ext x + simp [product, inner_sub_right] + +variable (X Y) in +lemma product_smul_left (f : M โ†’ โ„) : product I (f โ€ข X) Y = f โ€ข product I X Y := by + ext x + simp [product, real_inner_smul_left] + +variable (X Y) in +@[simp] +lemma product_smul_const_left (a : โ„) : product I (a โ€ข X) Y = a โ€ข product I X Y := by + ext x + simp [product, real_inner_smul_left] + +variable (X Y) in +lemma product_smul_right (f : M โ†’ โ„) : product I X (f โ€ข Y) = f โ€ข product I X Y := by + ext x + simp [product, real_inner_smul_right] + +variable (X Y) in +@[simp] +lemma product_smul_const_right (a : โ„) : product I X (a โ€ข Y) = a โ€ข product I X Y := by + ext x + simp [product, real_inner_smul_right] + +end product + +-- These lemmas are necessary as my Lie bracket identities (assuming minimal differentiability) +-- only hold point-wise. They abstract the expanding and unexpanding of `product`. +omit [IsManifold I โˆž M] in +lemma product_congr_left {x} (h : X x = X' x) : product I X Y x = product I X' Y x := by + rw [product_apply, h, โ† product_apply] + +omit [IsManifold I โˆž M] in +lemma product_congr_leftโ‚‚ {x} (h : X x = X' x + X'' x) : + product I X Y x = product I X' Y x + product I X'' Y x := by + rw [product_apply, h, inner_add_left, โ† product_apply] +omit [IsManifold I โˆž M] in +lemma product_congr_right {x} (h : Y x = Y' x) : product I X Y x = product I X Y' x := by + rw [product_apply, h, โ† product_apply] + +omit [IsManifold I โˆž M] in +lemma product_congr_rightโ‚‚ {x} (h : Y x = Y' x + Y'' x) : + product I X Y x = product I X Y' x + product I X Y'' x := by + rw [product_apply, h, inner_add_right, โ† product_apply] + +/- XXX: writing `hY.inner_bundle hZ` or writing `by apply MDifferentiable.inner_bundle hY hZ` +yields an error +synthesized type class instance is not definitionally equal to expression inferred by typing rules, +synthesized + fun x โ†ฆ instNormedAddCommGroupOfRiemannianBundle x +inferred + fun b โ†ฆ instโœโท -/ +-- TODO: diagnose and fix this, and replace by `MDifferentiable(At).inner_bundle! + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] {I} in +lemma MDifferentiable.inner_bundle' (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : MDiff โŸชY, ZโŸซ := + MDifferentiable.inner_bundle hY hZ + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] {I} in +lemma MDifferentiableAt.inner_bundle' {x} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + MDiffAt โŸชY, ZโŸซ x := + MDifferentiableAt.inner_bundle hY hZ + +namespace CovariantDerivative + +-- Let `cov` be a covariant derivative on `TM`. +-- TODO: include in cheat sheet! +variable (cov : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)) + +/-- Predicate saying for a connection `โˆ‡` on a Riemannian manifold `M` to be compatible with the +ambient metric, i.e. for all smooth vector fields `X`, `Y` and `Z` on `M`, we have +`X โŸจY, ZโŸฉ = โŸจโˆ‡ X Y, ZโŸฉ + โŸจY, โˆ‡ X ZโŸฉ`. -/ +def IsCompatible : Prop := + โˆ€ X Y Z : ฮ  x : M, TangentSpace I x, -- XXX: missing differentiability hypotheses! + โˆ€ x : M, + mfderiv% โŸชY, ZโŸซ x (X x) = โŸชcov X Y, ZโŸซ x + โŸชY, cov X ZโŸซ x + +/-- A covariant derivative on a Riemannian bundle `TM` is called the **Levi-Civita connection** +iff it is torsion-free and compatible with `g`. +Note that the bundle metric on `TM` is implicitly hidden in this definition. See `TODO` for a +version depending on a choice of Riemannian metric on `M`. +-/ +def IsLeviCivitaConnection : Prop := cov.IsCompatible โˆง cov.IsTorsionFree + +variable (X Y Z) in +/-- The first term in the definition of the candidate Levi-Civita connection: +`rhs_aux I X Y Z = X โŸจY, ZโŸฉ = x โ†ฆ d(โŸจY, ZโŸฉ)_x (X x)`. + +This definition contains mild defeq abuse, which is invisible on paper: +The function `โŸจY, ZโŸฉ` maps `M` into `โ„`, hence its differential at a point `x` maps `T_p M` +to an element of the tangent space of `โ„`. A summand `โŸจY, [X, Z]โŸฉ`, however, yields an honest +real number: Lean complains that these have different types. +Fortunately, `โ„` is defeq to its own tangent space; casting `rhs_aux` to the real numbers +allows the addition to type-check. -/ +noncomputable abbrev rhs_aux : M โ†’ โ„ := fun x โ†ฆ (mfderiv% โŸชY, ZโŸซ x (X x)) + +section rhs_aux + +variable (Y Z) in +omit [IsManifold I โˆž M] in +lemma rhs_aux_swap : rhs_aux I X Y Z = rhs_aux I X Z Y := by + ext x + simp only [rhs_aux] + congr 2 + exact product_swap I Z Y + +omit [IsManifold I โˆž M] in +variable (X X' Y Z) in +lemma rhs_aux_addX : rhs_aux I (X + X') Y Z = rhs_aux I X Y Z + rhs_aux I X' Y Z := by + ext x + simp [rhs_aux] + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] {x} + +variable (X) in +@[simp] +lemma rhs_aux_addY_apply (hY : MDiffAt (T% Y) x) (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X (Y + Y') Z x = rhs_aux I X Y Z x + rhs_aux I X Y' Z x := by + simp only [rhs_aux] + rw [product_add_left, mfderiv_add (hY.inner_bundle' hZ) (hY'.inner_bundle' hZ)] + simp; congr + +variable (X) in +lemma rhs_aux_addY (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : + rhs_aux I X (Y + Y') Z = rhs_aux I X Y Z + rhs_aux I X Y' Z := by + ext x + exact rhs_aux_addY_apply I X (hY x) (hY' x) (hZ x) + +variable (X) in +@[simp] +lemma rhs_aux_addZ_apply (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + rhs_aux I X Y (Z + Z') x = rhs_aux I X Y Z x + rhs_aux I X Y Z' x := by + unfold rhs_aux + rw [product_add_right, mfderiv_add (hY.inner_bundle' hZ) (hY.inner_bundle' hZ')]; simp; congr + +variable (X) in +lemma rhs_aux_addZ (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + rhs_aux I X Y (Z + Z') = rhs_aux I X Y Z + rhs_aux I X Y Z' := by + ext x + exact rhs_aux_addZ_apply I X (hY x) (hZ x) (hZ' x) + +omit [IsManifold I โˆž M] in +variable (X Y Z) in +lemma rhs_aux_smulX_apply (f : M โ†’ โ„) (x) : rhs_aux I (f โ€ข X) Y Z x = f x โ€ข rhs_aux I X Y Z x := by + simp [rhs_aux] + +omit [IsManifold I โˆž M] in +variable (X Y Z) in +lemma rhs_aux_smulX (f : M โ†’ โ„) : rhs_aux I (f โ€ข X) Y Z = f โ€ข rhs_aux I X Y Z := by + ext x + exact rhs_aux_smulX_apply .. + +variable (X) in +lemma rhs_aux_smulY_apply {f : M โ†’ โ„} + (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + letI A (x) : โ„ := (mfderiv% f x) (X x) + rhs_aux I X (f โ€ข Y) Z x = f x โ€ข rhs_aux I X Y Z x + A x โ€ข โŸชY, ZโŸซ x := by + rw [rhs_aux, product_smul_left, mfderiv_smul (hY.inner_bundle' hZ) hf] + +variable (X) in +lemma rhs_aux_smulY {f : M โ†’ โ„} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + letI A (x) : โ„ := (mfderiv% f x) (X x) + rhs_aux I X (f โ€ข Y) Z = f โ€ข rhs_aux I X Y Z + A โ€ข โŸชY, ZโŸซ := by + ext x + simp [rhs_aux_smulY_apply I X (hf x) (hY x) (hZ x)] + +variable (X) in +lemma rhs_aux_smulY_const_apply {a : โ„} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X (a โ€ข Y) Z x = a โ€ข rhs_aux I X Y Z x := by + let f : M โ†’ โ„ := fun _ โ†ฆ a + have h1 : rhs_aux I X (a โ€ข Y) Z x = rhs_aux I X (f โ€ข Y) Z x := by simp only [f]; congr + rw [h1, rhs_aux_smulY_apply I X mdifferentiableAt_const hY hZ] + simp [mfderiv_const] + +variable (X) in +lemma rhs_aux_smulY_const {a : โ„} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + rhs_aux I X (a โ€ข Y) Z = a โ€ข rhs_aux I X Y Z := by + ext x + apply rhs_aux_smulY_const_apply I X (hY x) (hZ x) + +variable (X) in +lemma rhs_aux_smulZ_apply {f : M โ†’ โ„} + (hf : MDiffAt f x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + letI A (x) : โ„ := (mfderiv% f x) (X x) + rhs_aux I X Y (f โ€ข Z) x = f x โ€ข rhs_aux I X Y Z x + A x โ€ข โŸชY, ZโŸซ x := by + rw [rhs_aux_swap, rhs_aux_smulY_apply, rhs_aux_swap, product_swap] + exacts [hf, hZ, hY] + +variable (X) in +lemma rhs_aux_smulZ {f : M โ†’ โ„} (hf : MDiff f) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + letI A (x) : โ„ := (mfderiv% f x) (X x) + rhs_aux I X Y (f โ€ข Z) = f โ€ข rhs_aux I X Y Z + A โ€ข โŸชY, ZโŸซ := by + rw [rhs_aux_swap, rhs_aux_smulY, rhs_aux_swap, product_swap] + exacts [hf, hZ, hY] + +variable (X) in +lemma rhs_aux_smulZ_const_apply {a : โ„} (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + rhs_aux I X Y (a โ€ข Z) x = a โ€ข rhs_aux I X Y Z x := by + let f : M โ†’ โ„ := fun _ โ†ฆ a + have h1 : rhs_aux I X Y (a โ€ข Z) x = rhs_aux I X Y (f โ€ข Z) x := by simp only [f]; congr + rw [h1, rhs_aux_smulZ_apply I X mdifferentiableAt_const hY hZ] + simp [mfderiv_const] + +variable (X) in +lemma rhs_aux_smulZ_const {a : โ„} (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + rhs_aux I X Y (a โ€ข Z) = a โ€ข rhs_aux I X Y Z := by + ext x + exact rhs_aux_smulZ_const_apply I X (hY x) (hZ x) + +end rhs_aux + +variable {x : M} + +variable (X Y Z) in +/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: +If โˆ‡ is a Levi-Civita connection on `TM`, then +`2 โŸจโˆ‡ X Y, ZโŸฉ = leviCivitaRhs' I X Y Z` for all vector fields `Z`. -/ +noncomputable def leviCivitaRhs' : M โ†’ โ„ := + rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y + - โŸชY ,(VectorField.mlieBracket I X Z)โŸซ + - โŸชZ, (VectorField.mlieBracket I Y X)โŸซ + + โŸชX, (VectorField.mlieBracket I Z Y)โŸซ + +variable (X Y Z) in +/-- Auxiliary quantity used in the uniqueness proof of the Levi-Civita connection: +If `โˆ‡` is a Levi-Civita connection on `TM`, then +`โŸจโˆ‡ X Y, ZโŸฉ = leviCivitaRhs I X Y Z` for all smooth vector fields `X`, `Y` and `Z`. -/ +noncomputable def leviCivitaRhs : M โ†’ โ„ := (1 / 2 : โ„) โ€ข leviCivitaRhs' I X Y Z + +omit [IsManifold I โˆž M] in +lemma leviCivitaRhs_apply : leviCivitaRhs I X Y Z x = (1 / 2 : โ„) โ€ข leviCivitaRhs' I X Y Z x := + rfl + +section leviCivitaRhs + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] + +@[simp] +lemma leviCivitaRhs'_addX_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I (X + X') Y Z x = + leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X' Y Z x := by + simp only [leviCivitaRhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply] + -- We have to rewrite back and forth: the Lie bracket is only additive at x, + -- as we are only asking for differentiability at x. + -- Fortunately, the `product_congr_rightโ‚‚` lemma abstracts this very well. + rw [product_congr_rightโ‚‚ I (VectorField.mlieBracket_add_right (V := Y) hX hX'), + product_congr_rightโ‚‚ I (VectorField.mlieBracket_add_left (W := Z) hX hX'), + product_add_left_apply, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + abel + +lemma leviCivitaRhs'_addX [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs' I (X + X') Y Z = + leviCivitaRhs' I X Y Z + leviCivitaRhs' I X' Y Z := by + ext x + simp [leviCivitaRhs'_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] + +lemma leviCivitaRhs_addX_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) + (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I (X + X') Y Z x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X' Y Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_addX_apply I hX hX' hY hZ, left_distrib] + +lemma leviCivitaRhs_addX [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I (X + X') Y Z = leviCivitaRhs I X Y Z + leviCivitaRhs I X' Y Z := by + ext x + simp [leviCivitaRhs_addX_apply _ (hX x) (hX' x) (hY x) (hZ x)] + +open VectorField + +variable {I} in +lemma leviCivitaRhs'_smulX_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I (f โ€ข X) Y Z x = f x โ€ข leviCivitaRhs' I X Y Z x := by + unfold leviCivitaRhs' + simp only [Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_smulX, rhs_aux_smulY_apply, rhs_aux_smulZ_apply] <;> try assumption + -- TODO: add the right congr_right lemma to avoid the product_apply, โ† product_apply dance! + simp only [product_apply, mlieBracket_smul_left (W := Z) hf hX, + mlieBracket_smul_right (V := Y) hf hX, inner_add_right] + -- Combining this line with the previous one fails. + simp only [โ† product_apply, neg_smul, inner_neg_right] + have h1 : + letI dfZ : โ„ := (mfderiv% f x) (Z x); + inner โ„ (Y x) ((mfderiv% f x) (Z x) โ€ข X x) = dfZ * โŸชX, YโŸซ x := by + simp only [product] + rw [โ† real_inner_smul_left, real_inner_smul_right, real_inner_smul_left, real_inner_comm] + have h2 : + letI dfZ : โ„ := (mfderiv% f x) (Y x); + inner โ„ (Z x) ((mfderiv% f x) (Y x) โ€ข X x) = dfZ * โŸชZ, XโŸซ x := by + simp only [product] + rw [โ† real_inner_smul_left, real_inner_smul_right, real_inner_smul_left] + simp only [h1, h2] + set dfY : โ„ := (mfderiv% f x) (Y x) + set dfZ : โ„ := (mfderiv% f x) (Z x) + have h3 : โŸชf โ€ข X, mlieBracket I Z YโŸซ x = f x * โŸชX, mlieBracket I Z YโŸซ x := by + rw [product_apply, Pi.smul_apply', real_inner_smul_left] + have h4 : inner โ„ (Z x) (f x โ€ข mlieBracket I Y X x) = f x * โŸชZ, mlieBracket I Y XโŸซ x := by + rw [product_apply, real_inner_smul_right] + rw [real_inner_smul_right (Y x), h3]--, h4] + -- set A := โŸชY, mlieBracket I X ZโŸซ with hA + -- set B := โŸชZ, mlieBracket I X YโŸซ + -- set C := โŸชX, mlieBracket I Z YโŸซ + -- set R := dfZ * โŸชX, YโŸซ x with hR + -- set R' := dfY * โŸชZ, XโŸซ x with hR' + -- set E := rhs_aux I X Y Z x + -- set F := rhs_aux I Y Z X x + -- set G := rhs_aux I Z X Y x + -- Push all applications of `x` inwards, then it's indeed obvious. + simp + ring_nf + congr + +variable {I} in +lemma leviCivitaRhs_smulX_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I (f โ€ข X) Y Z x = f x โ€ข leviCivitaRhs I X Y Z x := by + simp only [leviCivitaRhs, one_div, Pi.smul_apply, smul_eq_mul] + simp_rw [leviCivitaRhs'_smulX_apply (I := I) hf hX hY hZ] + rw [โ† mul_assoc, mul_comm (f x), smul_eq_mul] + ring + +variable {I} in +lemma leviCivitaRhs_smulX [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I (f โ€ข X) Y Z = f โ€ข leviCivitaRhs I X Y Z := by + ext x + exact leviCivitaRhs_smulX_apply (hf x) (hX x) (hY x) (hZ x) + +lemma leviCivitaRhs'_addY_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (Y + Y') Z x = leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X Y' Z x := by + simp only [leviCivitaRhs', Pi.add_apply, Pi.sub_apply, product_add_left_apply] + rw [rhs_aux_addX, rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + -- We have to rewrite back and forth: the Lie bracket is only additive at x, + -- as we are only asking for differentiability at x. + rw [product_congr_rightโ‚‚ I (mlieBracket_add_left (W := X) hY hY')] + rw [product_congr_rightโ‚‚ I (VectorField.mlieBracket_add_right (V := Z) hY hY')] + simp only [Pi.add_apply] + abel + +lemma leviCivitaRhs_addY_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hY' : MDiffAt (T% Y') x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (Y + Y') Z x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X Y' Z x := by + simp [leviCivitaRhs, leviCivitaRhs'_addY_apply I hX hY hY' hZ, left_distrib] + +lemma leviCivitaRhs_addY [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hY' : MDiff (T% Y')) (hZ : MDiff (T% Z)) : + leviCivitaRhs I X (Y + Y') Z = leviCivitaRhs I X Y Z + leviCivitaRhs I X Y' Z := by + ext x + simp [leviCivitaRhs_addY_apply I (hX x) (hY x) (hY' x) (hZ x)] + +variable {I} in +lemma leviCivitaRhs'_smulY_const_apply [CompleteSpace E] {a : โ„} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (a โ€ข Y) Z x = a โ€ข leviCivitaRhs' I X Y Z x := by + simp only [leviCivitaRhs'] + simp only [product_smul_const_left, Pi.add_apply, Pi.sub_apply, Pi.smul_apply] + rw [rhs_aux_smulY_const_apply I X hY hZ] + -- TODO: clean up this proof! + let f : M โ†’ โ„ := fun _ โ†ฆ a + have : rhs_aux I (a โ€ข Y) Z X x = a โ€ข rhs_aux I Y Z X x := by + trans rhs_aux I (f โ€ข Y) Z X x + ยท rfl + rw [rhs_aux_smulX I Y (f := f) (Y := Z) (Z := X)] + rfl + rw [this, rhs_aux_smulZ_const_apply I _ hX hY] + -- is there a better abstraction for "Lie bracket conv mode"? + have : โŸชZ, mlieBracket I (a โ€ข Y) XโŸซ x = a โ€ข โŸชZ, mlieBracket I Y XโŸซ x := by + simp_rw [product_apply, mlieBracket_const_smul_left (W := X) hY, inner_smul_right_eq_smul] + rw [this] + have aux2 : โŸชX, mlieBracket I Z (a โ€ข Y)โŸซ x = a โ€ข โŸชX, mlieBracket I Z YโŸซ x := by + simp_rw [product_apply, mlieBracket_const_smul_right (V := Z) hY, inner_smul_right_eq_smul] + rw [aux2] + simp + ring + +variable {I} in +lemma leviCivitaRhs_smulY_const_apply [CompleteSpace E] {a : โ„} + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (a โ€ข Y) Z x = a โ€ข leviCivitaRhs I X Y Z x := by + simp_rw [leviCivitaRhs, Pi.smul_apply]; rw [smul_comm] + congr + exact leviCivitaRhs'_smulY_const_apply hX hY hZ + +variable {I} in +lemma leviCivitaRhs_smulY_const [CompleteSpace E] {a : โ„} + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I X (a โ€ข Y) Z = a โ€ข leviCivitaRhs I X Y Z := by + ext x + exact leviCivitaRhs_smulY_const_apply (hX x) (hY x) (hZ x) + +lemma leviCivitaRhs'_smulY_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X (f โ€ข Y) Z x = + f x โ€ข leviCivitaRhs' I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) โ€ข 2 * โŸชY, ZโŸซ x := by + simp only [leviCivitaRhs'] + simp_rw [rhs_aux_smulX I Y Z X f] + simp only [product_smul_left, Pi.add_apply, Pi.sub_apply, smul_eq_mul, Pi.mul_apply] + rw [rhs_aux_smulY_apply I X hf hY hZ, rhs_aux_smulZ_apply I Z hf hX hY] + -- TODO: is there a better abstraction for this kind of "Lie bracket conv mode"? + have h1 : โŸชZ, mlieBracket I (f โ€ข Y) XโŸซ x = + - (bar _).toFun (((mfderiv% f x) (X x))) โ€ข โŸชZ, YโŸซ x + f x โ€ข โŸชZ, mlieBracket I Y XโŸซ x := by + simp_rw [product_apply, mlieBracket_smul_left (W := X) hf hY, inner_add_right] + congr + ยท simp only [neg_smul, inner_neg_right, bar, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul, + neg_mul, neg_inj] + rw [real_inner_smul_right] + ยท rw [inner_smul_right_eq_smul] + have h2 : โŸชX, mlieBracket I Z (f โ€ข Y)โŸซ x = + (bar _).toFun (((mfderiv% f x) (Z x))) โ€ข โŸชX, YโŸซ x + f x โ€ข โŸชX, mlieBracket I Z YโŸซ x := by + simp_rw [product_apply, mlieBracket_smul_right (V := Z) hf hY, inner_add_right] + congr + ยท simp only [bar, AddHom.toFun_eq_coe, AddHom.coe_mk, smul_eq_mul]; rw [real_inner_smul_right] + ยท rw [inner_smul_right_eq_smul] + rw [h1, h2, product_swap I Y Z] + set A := rhs_aux I X Y Z x + set B := rhs_aux I Y Z X x + set C := rhs_aux I Z X Y x + set D := โŸชY, mlieBracket I X ZโŸซ x + set E := โŸชZ, mlieBracket I Y XโŸซ x + set F := โŸชX, mlieBracket I Z YโŸซ x + set G1 := โŸชY, ZโŸซ x + set G2 := โŸชX, YโŸซ x + set dfx := (mfderiv% f x) + set H := (bar (f x)) (dfx (X x)) with H_eq + set K := (bar (f x)) (dfx (Z x)) with K_eq + change f x * A + (bar _).toFun (dfx (X x)) * G1 + f x * B + - (f x * C + (bar _).toFun (dfx (Z x)) * G2) + - f x * D - (-H * G1 + f x * E) + (K * G2 + f x * F) = _ + dsimp + rw [โ† H_eq, โ† K_eq] + ring + +lemma leviCivitaRhs_smulY_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs I X (f โ€ข Y) Z x = + f x โ€ข leviCivitaRhs I X Y Z x + ((bar _).toFun <| mfderiv% f x (X x)) โ€ข โŸชY, ZโŸซ x := by + simp only [leviCivitaRhs, Pi.smul_apply, leviCivitaRhs'_smulY_apply I hf hX hY hZ] + rw [smul_add, smul_comm] + congr 1 + rw [โ† smul_eq_mul] + dsimp + field_simp + +lemma leviCivitaRhs'_addZ_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + leviCivitaRhs' I X Y (Z + Z') x = + leviCivitaRhs' I X Y Z x + leviCivitaRhs' I X Y Z' x := by + simp only [leviCivitaRhs', rhs_aux_addX, Pi.add_apply, Pi.sub_apply, product_add_left_apply] + rw [product_congr_rightโ‚‚ I (VectorField.mlieBracket_add_right (V := X) hZ hZ'), + product_congr_rightโ‚‚ I (VectorField.mlieBracket_add_left (W := Y) hZ hZ'), + rhs_aux_addY_apply, rhs_aux_addZ_apply] <;> try assumption + abel + +lemma leviCivitaRhs'_addZ [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + leviCivitaRhs' I X Y (Z + Z') = + leviCivitaRhs' I X Y Z + leviCivitaRhs' I X Y Z' := by + ext x + exact leviCivitaRhs'_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) + +lemma leviCivitaRhs_addZ_apply [CompleteSpace E] + (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) + (hZ : MDiffAt (T% Z) x) (hZ' : MDiffAt (T% Z') x) : + leviCivitaRhs I X Y (Z + Z') x = leviCivitaRhs I X Y Z x + leviCivitaRhs I X Y Z' x := by + simp [leviCivitaRhs, leviCivitaRhs'_addZ_apply I hX hY hZ hZ', left_distrib] + +lemma leviCivitaRhs_addZ [CompleteSpace E] + (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) (hZ' : MDiff (T% Z')) : + leviCivitaRhs I X Y (Z + Z') = leviCivitaRhs I X Y Z + leviCivitaRhs I X Y Z' := by + ext x + exact leviCivitaRhs_addZ_apply I (hX x) (hY x) (hZ x) (hZ' x) + +lemma leviCivitaRhs'_smulZ_apply [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) (hY : MDiffAt (T% Y) x) (hZ : MDiffAt (T% Z) x) : + leviCivitaRhs' I X Y (f โ€ข Z) x = f x โ€ข leviCivitaRhs' I X Y Z x := by + simp only [leviCivitaRhs', rhs_aux_smulX, Pi.add_apply, Pi.sub_apply] + rw [rhs_aux_smulY_apply _ _ hf hZ hX, rhs_aux_smulZ_apply _ _ hf hY hZ] + -- Apply the product rule for the lie bracket. + -- Let's encapsulate the going into the product and back out again. + have h1 : โŸชY, mlieBracket I X (f โ€ข Z)โŸซ x = + f x โ€ข โŸชY, mlieBracket I X ZโŸซ x + โŸชY, mfderiv% f x (X x) โ€ข ZโŸซ x := by + rw [product_apply, VectorField.mlieBracket_smul_right hf hZ, inner_add_right, add_comm, + inner_smul_right] + congr + have h2 : letI dfY : โ„ := (mfderiv% f x) (Y x); + โŸชX, mlieBracket I (f โ€ข Z) YโŸซ x = - dfY โ€ข โŸชX, ZโŸซ x + f x โ€ข โŸชX, mlieBracket I Z YโŸซ x := by + rw [product_apply, VectorField.mlieBracket_smul_left hf hZ, inner_add_right, inner_smul_right, + inner_smul_right] + congr + rw [h1, h2, product_smul_left, product_swap I X Z] + erw [product_smul_right] + simp + -- set A := rhs_aux I X Y Z x + -- set B := rhs_aux I Y Z X x + -- set C := rhs_aux I Z X Y x + -- set D := โŸชY, mlieBracket I X ZโŸซ x + -- set E := โŸชZ, mlieBracket I Y XโŸซ x with E_eq + -- set F := โŸชX, mlieBracket I Z YโŸซ x + -- letI dfX : โ„ := (mfderiv% f x) (X x) + -- set G := dfX * โŸชY, ZโŸซ x + -- letI dfY : โ„ := (mfderiv% f x) (Y x) + -- set H := dfY * โŸชX, ZโŸซ x + ring + +lemma leviCivitaRhs'_smulZ [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs' I X Y (f โ€ข Z) = f โ€ข leviCivitaRhs' I X Y Z := by + ext x + exact leviCivitaRhs'_smulZ_apply I (hf x) (hX x) (hY x) (hZ x) + +lemma leviCivitaRhs_smulZ [CompleteSpace E] {f : M โ†’ โ„} + (hf : MDiff f) (hX : MDiff (T% X)) (hY : MDiff (T% Y)) (hZ : MDiff (T% Z)) : + leviCivitaRhs I X Y (f โ€ข Z) = f โ€ข leviCivitaRhs I X Y Z := by + simp only [leviCivitaRhs] + rw [smul_comm, leviCivitaRhs'_smulZ I hf hX hY hZ] + +end leviCivitaRhs + +variable (X Y Z) in +lemma aux (h : cov.IsLeviCivitaConnection) : rhs_aux I X Y Z = + โŸชcov X Y, ZโŸซ + โŸชY, cov Z XโŸซ + โŸชY, VectorField.mlieBracket I X ZโŸซ := by + trans โŸชcov X Y, ZโŸซ + โŸชY, cov X ZโŸซ + ยท ext x + exact h.1 X Y Z x + ยท simp [โ† isTorsionFree_iff.mp h.2 X Z, product_sub_right] + +lemma isolate_aux {ฮฑ : Type*} [AddCommGroup ฮฑ] + (A D E F X Y Z : ฮฑ) (h : X + Y - Z = A + A + D + E - F) : + A + A = X + Y - Z - D - E + F := by + rw [h]; abel + +variable (X Y Z) {cov} in +/-- Auxiliary lemma towards the uniquness of the Levi-Civita connection: expressing the term +โŸจโˆ‡ X Y, ZโŸฉ for all differentiable vector fields X, Y and Z, without reference to โˆ‡. -/ +lemma IsLeviCivitaConnection.eq_leviCivitaRhs (h : cov.IsLeviCivitaConnection) : + โŸชcov X Y, ZโŸซ = leviCivitaRhs I X Y Z := by + set A := โŸชcov X Y, ZโŸซ + set B := โŸชcov Z X, YโŸซ + set C := โŸชcov Y Z, XโŸซ + set D := โŸชY, VectorField.mlieBracket I X ZโŸซ with D_eq + set E := โŸชZ, VectorField.mlieBracket I Y XโŸซ with E_eq + set F := โŸชX, VectorField.mlieBracket I Z YโŸซ with F_eq + have eq1 : rhs_aux I X Y Z = A + B + D := by + simp only [aux I X Y Z cov h, A, B, D, product_swap _ Y (cov Z X)] + have eq2 : rhs_aux I Y Z X = C + A + E := by + simp only [aux I Y Z X cov h, A, C, E, product_swap _ (cov X Y) Z] + have eq3 : rhs_aux I Z X Y = B + C + F := by + simp only [aux I Z X Y cov h, B, C, F, product_swap _ X (cov Y Z)] + -- Add eq1 and eq2 and subtract eq3. + have : rhs_aux I X Y Z + rhs_aux I Y Z X - rhs_aux I Z X Y = A + A + D + E - F := by + rw [eq1, eq2, eq3]; abel + -- Solve for โŸชcov X Y, ZโŸซ and obtain the claim. + have almost := isolate_aux A D E F (rhs_aux I X Y Z) (rhs_aux I Y Z X) (rhs_aux I Z X Y) + (by simp [this]) + have almoster : A + A = leviCivitaRhs' I X Y Z := by simp only [leviCivitaRhs', *] + simp only [leviCivitaRhs, โ† almoster, smul_add] + ext; simp; ring + +section + +attribute [local instance] Fintype.toOrderBot Fintype.toLocallyFiniteOrder + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] + +variable {I} in +/-- If two vector fields `X` and `X'` on `M` satisfy the relation `โŸจX, ZโŸฉ = โŸจX', ZโŸฉ` for all +vector fields `Z`, then `X = X'`. XXX up to differentiability? -/ +-- TODO: is this true if E is infinite-dimensional? trace the origin of the `Fintype` assumptions! +lemma congr_of_forall_product [FiniteDimensional โ„ E] + (h : โˆ€ Z : ฮ  x : M, TangentSpace I x, โŸชX, ZโŸซ = โŸชX', ZโŸซ) : X = X' := by + obtain (_hE | hE) := subsingleton_or_nontrivial E + ยท ext x + have : Subsingleton (TangentSpace I x) := inferInstanceAs (Subsingleton E) + apply Subsingleton.allEq _ + ext x + let b := Basis.ofVectorSpace โ„ E + let t := trivializationAt E (TangentSpace I : M โ†’ Type _) x + have hx : x โˆˆ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x + have : Nonempty โ†‘(Basis.ofVectorSpaceIndex โ„ E) := 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 โ†‘(Basis.ofVectorSpaceIndex โ„ E) := by + choose r wo using exists_wellOrder _ + exact r + have : LocallyFiniteOrderBot โ†‘(Basis.ofVectorSpaceIndex โ„ E) := inferInstance + -- Choose an orthonormal frame (s i) near x w.r.t. to this trivialisation, and the metric g + let real := b.orthonormalFrame t + have hframe := b.orthonormalFrame_isOrthonormalFrameOn t (F := E) (IB := I) (n := 1) + rw [hframe.eq_iff_coeff hx] + intro i + have hโ‚ : โŸชX, real iโŸซ x = hframe.coeff i x (X x) := by + rw [hframe.coeff_eq_inner' _ hx] + simp [real, real_inner_comm] + have hโ‚‚ : โŸชX', real iโŸซ x = hframe.coeff i x (X' x) := by + rw [hframe.coeff_eq_inner' _ hx] + simp [real, real_inner_comm] + rw [โ† hโ‚, โ† hโ‚‚, h (real i)] + +/-- The Levi-Civita connection on `(M, g)` is uniquely determined, +at least on differentiable vector fields. -/ +-- (probably not everywhere, as addition rules apply only for differentiable vector fields?) +theorem IsLeviCivitaConnection.uniqueness [FiniteDimensional โ„ E] + {cov cov' : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)} + (hcov : cov.IsLeviCivitaConnection) (hcov' : cov'.IsLeviCivitaConnection) : + -- almost, only agree on smooth functions + cov = cov' := by + ext X ฯƒ x + apply congrFun + apply congr_of_forall_product fun Z โ†ฆ ?_ + trans leviCivitaRhs I X ฯƒ Z + ยท exact hcov.eq_leviCivitaRhs I X ฯƒ Z + ยท exact (hcov'.eq_leviCivitaRhs I X ฯƒ Z ).symm + +/-- Auxiliary definition towards defining the Levi-Civita connection on `M`: +given a trivialisation `e` and a choice `o` of linear order on the standard basis of `E`, +we take the expression defined by the Koszul formula (using the orthonormal frame determined by `e` +and `o`). -/ +noncomputable def lcCandidateAux [FiniteDimensional โ„ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M โ†’ M)) [MemTrivializationAtlas e] + (o : LinearOrder โ†‘(Basis.ofVectorSpaceIndex โ„ E)) : + ((x : M) โ†’ TangentSpace I x) โ†’ ((x : M) โ†’ TangentSpace I x) โ†’ (x : M) โ†’ TangentSpace I x := + open scoped Classical in + fun X Y x โ†ฆ + if hE : Subsingleton E then X x else + -- Choose a trivialisation of `TM` near `x`. + -- Since `E` is non-trivial, `b` is non-empty. + let b := Basis.ofVectorSpace โ„ E + have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + have : Nonempty โ†‘(Basis.ofVectorSpaceIndex โ„ E) := b.index_nonempty + have : LocallyFiniteOrderBot โ†‘(Basis.ofVectorSpaceIndex โ„ E) := inferInstance + letI frame := b.orthonormalFrame e + -- The coefficient of the desired tangent vector `โˆ‡ X Y x` w.r.t. `s i` + -- is given by `leviCivitaRhs X Y (s i)`. + โˆ‘ i, ((leviCivitaRhs I X Y (frame i)) x) โ€ข (frame i x) + +variable (M) in +-- TODO: make g part of the notation! +/-- Given two vector fields X and Y on TM, compute +the candidate definition for the Levi-Civita connection on `TM`. -/ +noncomputable def lcCandidate [FiniteDimensional โ„ E] + (o : LinearOrder โ†‘(Basis.ofVectorSpaceIndex โ„ E)) : + (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) := + -- Use the preferred trivialisation at `x` to write down a candidate for the existence. + fun X Y x โ†ฆ lcCandidateAux I (trivializationAt E (TangentSpace I : M โ†’ Type _) x) o X Y x + +variable (X Y) in +/-- The definition `lcCandidate` behaves well: for each compatible trivialisation `e`, +the candidate definition using `e` agrees with `lcCandidate` on `e.baseSet`. -/ +lemma lcCandidate_eq_lcCandidateAux [FiniteDimensional โ„ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M โ†’ M)) [MemTrivializationAtlas e] + {o : LinearOrder โ†‘(Basis.ofVectorSpaceIndex โ„ E)} {x : M} (hx : x โˆˆ e.baseSet) : + lcCandidate I M o X Y x = lcCandidateAux I e o X Y x := by + by_cases hE : Subsingleton E + ยท simp [lcCandidate, lcCandidateAux, hE] + ยท simp only [lcCandidate, lcCandidateAux, hE, โ†“reduceDIte] + -- Now, start the real proof. + sorry + +lemma isCovariantDerivativeOn_lcCandidateAux_of_nonempty [FiniteDimensional โ„ E] + (hE : ยฌ(Subsingleton E)) [Nontrivial E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M โ†’ M)) [MemTrivializationAtlas e] + {o : LinearOrder โ†‘(Basis.ofVectorSpaceIndex โ„ E)} : + IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet where + addX {_X _X' _ฯƒ x} hX hX' hฯƒ hx := by + simp only [lcCandidateAux, hE, โ†“reduceDIte] + simp only [โ† Finset.sum_add_distrib, โ† add_smul] + congr; ext i + rw [leviCivitaRhs_addX_apply] <;> try assumption + let b := Basis.ofVectorSpace โ„ E + have : Nonempty โ†‘(Basis.ofVectorSpaceIndex โ„ E) := b.index_nonempty + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx + smulX {_X _ฯƒ _g _x} hX hฯƒ hg hx := by + simp only [lcCandidateAux, hE, โ†“reduceDIte] + rw [Finset.smul_sum] + congr; ext i + rw [leviCivitaRhs_smulX_apply] <;> try assumption + ยท simp [โ† smul_assoc] + ยท let b := Basis.ofVectorSpace โ„ E + have : Nonempty โ†‘(Basis.ofVectorSpaceIndex โ„ E) := b.index_nonempty + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx + smul_const_ฯƒ {X _ฯƒ x} a hX hฯƒ hx := by + simp only [lcCandidateAux, hE, โ†“reduceDIte] + rw [Finset.smul_sum]; congr; ext i + rw [leviCivitaRhs_smulY_const_apply hX hฯƒ, โ† smul_assoc] + ยท let b := Basis.ofVectorSpace โ„ E + have : Nonempty โ†‘(Basis.ofVectorSpaceIndex โ„ E) := b.index_nonempty + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx + addฯƒ {X ฯƒ ฯƒ' x} hX hฯƒ hฯƒ' hx := by + simp only [lcCandidateAux, hE, โ†“reduceDIte] + simp only [โ† Finset.sum_add_distrib, โ† add_smul] + congr; ext i + rw [leviCivitaRhs_addY_apply] <;> try assumption + let b := Basis.ofVectorSpace โ„ E + have : Nonempty โ†‘(Basis.ofVectorSpaceIndex โ„ E) := b.index_nonempty + exact mdifferentiableAt_orthonormalFrame_of_mem b e i hx + leibniz {X ฯƒ g x} hX hฯƒ hg hx := by + simp only [lcCandidateAux, hE, โ†“reduceDIte] + let b := Basis.ofVectorSpace โ„ E + have : Nonempty โ†‘(Basis.ofVectorSpaceIndex โ„ E) := b.index_nonempty + let Z (i : (Basis.ofVectorSpaceIndex โ„ E)) := ((Basis.ofVectorSpace โ„ E).orthonormalFrame e i) + have hZ : IsOrthonormalFrameOn I E 1 Z e.baseSet := + (Basis.ofVectorSpace โ„ E).orthonormalFrame_isOrthonormalFrameOn e + have hZ' : โˆ‘ i, โŸชฯƒ, Z iโŸซ x โ€ข Z i x = ฯƒ x := by + calc _ + _ = โˆ‘ i, hZ.coeff i x (ฯƒ x) โ€ข Z i x := by + congr; ext i + rw [hZ.coeff_eq_inner' ฯƒ hx i, product_swap] + _ = ฯƒ x := (hZ.toIsLocalFrameOn.coeff_sum_eq _ hx).symm + trans โˆ‘ i, leviCivitaRhs I X (g โ€ข ฯƒ) (Z i) x โ€ข (Z i) x + ยท congr + have (i : (Basis.ofVectorSpaceIndex โ„ E)) : MDiffAt (T% (Z i)) x := + mdifferentiableAt_orthonormalFrame_of_mem _ _ i hx + have aux (i) := leviCivitaRhs_smulY_apply I hg hX hฯƒ (this i) + simp_rw [aux] + trans โˆ‘ i, (g x โ€ข leviCivitaRhs I X ฯƒ (Z i) x โ€ข Z i x) + + โˆ‘ i, ((bar (g x)) ((mfderiv% g x) (X x)) โ€ข โŸชฯƒ, Z iโŸซ x) โ€ข Z i x + ยท simp only [โ† Finset.sum_add_distrib, add_smul, smul_assoc] + dsimp + have : โˆ‘ i, g x โ€ข leviCivitaRhs I X ฯƒ (Z i) x โ€ข Z i x = (g โ€ข lcCandidateAux I e o X ฯƒ) x := by + simp only [lcCandidateAux, hE, โ†“reduceDIte, Pi.smul_apply', Finset.smul_sum] + congr + rw [this] + simp_rw [โ† hZ', smul_assoc, Finset.smul_sum] + dsimp + +/-- The candidate definition `lcCandidateAux` is a covariant derivative +on each local trivialisation's domain. -/ +lemma isCovariantDerivativeOn_lcCandidateAux [FiniteDimensional โ„ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M โ†’ M)) [MemTrivializationAtlas e] + {o : LinearOrder โ†‘(Basis.ofVectorSpaceIndex โ„ E)} : + IsCovariantDerivativeOn E (lcCandidateAux I (M := M) e o) e.baseSet := by + by_cases hE : Subsingleton E + ยท exact (IsCovariantDerivativeOn.of_subsingleton E _).mono (Set.subset_univ _) + ยท have : Nontrivial E := not_subsingleton_iff_nontrivial.mp hE + exact isCovariantDerivativeOn_lcCandidateAux_of_nonempty I hE e + +-- The candidate definition is a covariant derivative on each local frame's domain. +lemma isCovariantDerivativeOn_lcCandidate [FiniteDimensional โ„ E] + (e : Trivialization E (TotalSpace.proj : TangentBundle I M โ†’ M)) [MemTrivializationAtlas e] + {o : LinearOrder โ†‘(Basis.ofVectorSpaceIndex โ„ E)} : + IsCovariantDerivativeOn E (lcCandidate I M o) e.baseSet := by + apply IsCovariantDerivativeOn.congr (isCovariantDerivativeOn_lcCandidateAux I e (o := o)) + intro X ฯƒ x hx + exact (lcCandidate_eq_lcCandidateAux I X ฯƒ e hx).symm + +end + +variable [IsContMDiffRiemannianBundle I 1 E (fun (x : M) โ†ฆ TangentSpace I x)] + +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. -/ +@[no_expose] noncomputable def LeviCivitaConnection_aux [FiniteDimensional โ„ E] + (o : LinearOrder โ†‘(Basis.ofVectorSpaceIndex โ„ E)) : + CovariantDerivative I E (TangentSpace I : M โ†’ Type _) where + -- This is the existence part of the proof: take the formula derived above + -- and prove it satisfies all the conditions. + toFun := lcCandidate I M o + isCovariantDerivativeOn := by + rw [โ† iUnion_source_chartAt H M] + let t := fun x โ†ฆ trivializationAt E (TangentSpace I : M โ†’ Type _) x + apply IsCovariantDerivativeOn.iUnion (s := fun i โ†ฆ (t i).baseSet) fun i โ†ฆ ?_ + exact isCovariantDerivativeOn_lcCandidate I _ + +-- TODO: make g part of the notation! +variable (M) in +/-- A choice of Levi-Civita connection on the tangent bundle `TM` of a Riemannian manifold `(M, g)`: +this is unique up to the value on non-differentiable vector fields. +If you know the Levi-Civita connection already, you can use `IsLeviCivitaConnection` instead. -/ +noncomputable def LeviCivitaConnection [FiniteDimensional โ„ E] : + CovariantDerivative I E (TangentSpace I : M โ†’ Type _) := + LeviCivitaConnection_aux I M (Classical.choose (exists_wellOrder _)) + +-- 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) โ†’ (ฮ  x : M, 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)) (f (s i) (s j)) + +-- special case of `foobar` below; needed? +lemma ChristoffelSymbol.sum_eq + (f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, 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) (s j) x = โˆ‘ k, (ChristoffelSymbol I f hs i j k x) โ€ข (s k) x := by + simp only [ChristoffelSymbol] + exact hs.coeff_sum_eq _ hx + +variable {U : Set M} + {f g : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, 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 = โŸชf (s i) (s j), (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 + dsimp [ChristoffelSymbol] -- simplify the piApply in the definition above + rw [hs.coeff_eq_inner' (f (s i) (s j)) hx k, real_inner_comm] + +-- 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 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 Y x = f X (fun x โ†ฆ โˆ‘ i, hs.coeff i x (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 Y x = g 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 Y x = g 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 + ext; 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) โ†’ (ฮ  x : M, TangentSpace I x)} + +-- 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*} [Finite ฮน] + [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 + have := Fintype.ofFinite ฮน + 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) (s j) x - f (s j) (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) := (t x).isLocalFrameOn_localFrame_baseSet I 1 (Basis.ofVectorSpace โ„ E) + + -- 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 [lcCandidateAux, hE, โ†“reduceDIte] + + letI t := trivializationAt E (TangentSpace I) x; + letI hs := t.isLocalFrameOn_localFrame_baseSet I 1 (Basis.ofVectorSpace โ„ E) + 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 [lcCandidateAux, 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'] says + simp only [one_div, leviCivitaRhs', Pi.smul_apply, Pi.add_apply, Pi.sub_apply, smul_eq_mul, + mul_eq_mul_left_iff, inv_eq_zero, OfNat.ofNat_ne_zero, or_false] + 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 + +lemma baz [FiniteDimensional โ„ E] : (LeviCivitaConnection I M).IsLeviCivitaConnection := by + -- If `E` is trivial, the Levi-Civita connection is always zero and all proofs are trivial. + 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 + refine โŸจ?_, ?_โŸฉ + ยท intro X Y Z x + simp only [LeviCivitaConnection, LeviCivitaConnection_aux] + unfold lcCandidate + simp [this] + ยท simp only [isTorsionFree_def, LeviCivitaConnection, LeviCivitaConnection_aux] + unfold lcCandidate torsion + ext; simp [this] + refine โŸจ?_, ?_โŸฉ + ยท intro X Y Z x + unfold LeviCivitaConnection LeviCivitaConnection_aux lcCandidate + simp only [lcCandidateAux, hE, โ†“reduceDIte] + --simp [product_apply] + sorry -- compatible + ยท let s : M โ†’ Set M := fun x โ†ฆ (trivializationAt E (fun (x : M) โ†ฆ TangentSpace I x) x).baseSet + apply (LeviCivitaConnection I M).of_isTorsionFreeOn_of_open_cover (s := s) ?_ (by aesop) + intro x + simp only [s] + set t := fun x โ†ฆ trivializationAt E (TangentSpace I : M โ†’ Type _) x with t_eq + have : IsCovariantDerivativeOn E (LeviCivitaConnection I M) (t x).baseSet := + isCovariantDerivativeOn_lcCandidate _ (t x) + rw [isTorsionFree_iff_christoffelSymbols' _ this] + intro x' hx' i j k + -- Now, compute christoffel symbols and be happy. + have := LeviCivitaConnection.christoffelSymbol_symm I x x' hx' i j k + sorry -- almost there, except x vs x' convert this + +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..83b5d8e281e722 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Lift.lean @@ -0,0 +1,382 @@ +/- +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.IntegralCurve.Basic +/-! +# Lifting vectors using covariant derivatives + +TODO: add a more complete doc-string + +-/ + +@[expose] public section + +@[expose] public section delaborators + +-- TODO: decide whether we want this and move +-- This delaborates `TotalSpace.mk x v` to `โŸจx, vโŸฉ` +open Lean PrettyPrinter Delaborator SubExpr + +@[app_delab mfderiv] meta def delab_mfderiv : Delab := do + whenPPOption getPPNotation do + let args := (โ† getExpr).getAppArgs + if args.size < 22 then failure + let pt : Term โ† withNaryArg 21 <| delab + let f := args[20]! + let m := mkIdent (.mkSimple "mfderiv%") + let T := mkIdent (.mkSimple "T%") + try + if let .lam _ _ b _ := f then + if b.isAppOf ``Bundle.TotalSpace.mk' then + let s := b.getAppArgs[4]!.getAppFn + if s matches .fvar .. then + let ss โ† PrettyPrinter.delab s + return โ† `($m ($T $ss) $pt) + throwError "nope" + catch _ => + let x : Term โ† withNaryArg 20 <| delab + return โ† `($m $x $pt) + +@[app_delab Bundle.TotalSpace.mk'] meta def delabTotalSpace_mk' : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (โ† getExpr).getAppArgs | failure + let bd : Term โ† withNaryArg 3 <| delab + let vd : Term โ† withNaryArg 4 <| delab + `(โŸจ$bd, $vdโŸฉ) + +end delaborators + +open Bundle Filter Module Topology Set + +open scoped Bundle Manifold ContDiff + +section +variable {B : Type*} (E : B โ†’ Type*) {F : Type*} + +/-- Given a bundle `ฯ€ : E โ†’ B`, the diagonal section of `ฯ€^*E โ†’ E`. -/ +def Bundle.pullback_diag (e : TotalSpace F E) : (TotalSpace.proj *แต– E) e := + e.2 +end + + +section +variable + {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 โ„ E] + [FiniteDimensional โ„ F] [T2Space M] [IsManifold I โˆž M] + {cov : ((x : M) โ†’ TangentSpace I x) โ†’ (M โ†’ F) โ†’ M โ†’ 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 โ„ _) (-evalL โ„ F F f โˆ˜L hcov.one_form x) + +@[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 u f) := + 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_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 +{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] [FiniteDimensional โ„ E] + [FiniteDimensional โ„ F] [T2Space M] + [IsManifold I โˆž 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 + +/-- 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 {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 + rw [cov.lift_vec_apply] + set t := trivializationAt F V v.proj + have hcov := cov.isCovariantDerivativeOn_pushCovDer t + refold_let t + sorry + +@[simp] +lemma CovariantDerivative.lift_vec_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_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] + +-- noncomputable +-- def CovariantDerivative.lift_vec' +-- (p : TotalSpace E ((TotalSpace.proj : (TotalSpace F V โ†’ M)) *แต– (TangentSpace I))) : +-- TangentSpace (I.prod ๐“˜(โ„, F)) p.1 := +-- letI t := trivializationAt F V p.1.proj +-- haveI d_covDerOn := t.pushCovDer_isCovariantDerivativeOn +-- (cov.isCovariantDerivativeOn.mono fun _ _ โ†ฆ mem_univ _) +-- letI tlift := d_covDerOn.lift_vec p.1.proj (t p.1).2 +-- t.derivInv I p.1 (tlift p.2) +end + +section integralCurve +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 โˆž 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 + +end integralCurve + +section geodesics + +variable + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] [FiniteDimensional โ„ E] + {H : Type*} [TopologicalSpace H] {I : ModelWithCorners โ„ E H} {M : Type*} [TopologicalSpace M] + [ChartedSpace H M] [T2Space M] + [IsManifold I โˆž M] + (cov : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)) + +-- FIXME: bug in `mfderiv%`? +-- FIXME: missing elaborator support to find I.tangent +omit [FiniteDimensional โ„ E] [T2Space M] in +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 + +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 X (ฮณ tโ‚€) := by + rw [hฮณX.acceleration hX, cov.proj_mderiv _ hX hX] + +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 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] + +end geodesics diff --git a/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean new file mode 100644 index 00000000000000..562acf24f90785 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Prelim.lean @@ -0,0 +1,783 @@ +/- +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.SmoothSection +public import Mathlib.Geometry.Manifold.VectorBundle.Tangent +public import Mathlib.Geometry.Manifold.MFDeriv.FDeriv +public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +public import Mathlib.Geometry.Manifold.BumpFunction +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Misc +public import Mathlib.Geometry.Manifold.VectorBundle.Tensoriality +public import Mathlib.Geometry.Manifold.VectorField.LieBracket +public import Mathlib.Geometry.Manifold.IsManifold.InteriorBoundary + +/-! +# 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 delaborators + +-- TODO: decide whether we want this and move +-- This delaborates `TotalSpace.mk x v` to `โŸจx, vโŸฉ` +open Lean PrettyPrinter Delaborator SubExpr + +@[app_delab TotalSpace.mk] meta def delabTotalSpace_mk : Delab := do + whenPPOption getPPNotation do + let #[_B, _F, _E, _b, _v] := (โ† getExpr).getAppArgs | failure + let bd : Term โ† withNaryArg 3 <| delab + let vd : Term โ† withNaryArg 4 <| delab + `(โŸจ$bd, $vdโŸฉ) + +@[app_delab MDifferentiableAt] meta def delabMDifferentiableAt : Delab := do + whenPPOption getPPNotation do + let args := (โ† getExpr).getAppArgs + if args.size < 22 then failure + let pt : Term โ† withNaryArg 21 <| delab + let f := args[20]! + try + if let .lam _ _ b _ := f then + if b.isAppOf ``Bundle.TotalSpace.mk' then + let s := b.getAppArgs[4]!.getAppFn + if s matches .fvar .. then + let ss โ† PrettyPrinter.delab s + return โ† `(MDiffAt (T% $ss) $pt) + throwError "nope" + catch _ => + let x : Term โ† withNaryArg 20 <| delab + return โ† `(MDiffAt $x $pt) + +end delaborators + +@[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 + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] + +set_option backward.isDefEq.respectTransparency false in +-- cleaned up and PRed in #34262 +lemma mfderiv_const_smul (s : M โ†’ F) {x : M} (a : ๐•œ) (v : TangentSpace I x) : + mfderiv% (a โ€ข s) x v = a โ€ข mfderiv% s x v := by + by_cases hs : MDiffAt s x + ยท have hs' := hs.const_smul a + suffices + (fderivWithin ๐•œ ((a โ€ข s) โˆ˜ (chartAt H x).symm โˆ˜ I.symm) (range I) (I ((chartAt H x) x))) v = + a โ€ข (fderivWithin ๐•œ (s โˆ˜ (chartAt H x).symm โˆ˜ I.symm) (range I) + (I ((chartAt H x) x))) v by simpa [mfderiv, hs, hs'] + change fderivWithin ๐•œ (a โ€ข (s โˆ˜ โ†‘(chartAt H x).symm โˆ˜ โ†‘I.symm)) _ _ _ = _ + rw [fderivWithin_const_smul_field _ I.uniqueDiffWithinAt_image ] + rfl + ยท by_cases ha : a = 0 + ยท have : a โ€ข s = 0 := by ext; simp [ha] + rw [this, ha] + change (mfderiv I ๐“˜(๐•œ, F) (fun _ โ†ฆ 0) x) v = _ + simp + have hs' : ยฌ MDiffAt (a โ€ข s) x := + fun h โ†ฆ hs (by simpa [ha] using h.const_smul aโปยน) + rw [mfderiv_zero_of_not_mdifferentiableAt hs, mfderiv_zero_of_not_mdifferentiableAt hs'] + simp + rfl + +-- PRed and cleaned up in #34263 +set_option linter.flexible false in -- FIXME +lemma mfderiv_smul [IsManifold I 1 M] {f : M โ†’ F} {s : M โ†’ ๐•œ} {x : M} (hf : MDiffAt f x) + (hs : MDiffAt s x) (v : TangentSpace I x) : + letI dsxv : ๐•œ := mfderiv% s x v + letI dfxv : F := mfderiv% f x v + mfderiv% (s โ€ข f) x v = (s x) โ€ข dfxv + dsxv โ€ข f x := by + set ฯ† := chartAt H x + -- TODO: the next two have should be special cases of the same lemma + have hs' : DifferentiableWithinAt ๐•œ (s โˆ˜ ฯ†.symm โˆ˜ I.symm) (range I) (I (ฯ† x)) := by + have hฯ† := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [โ† this] at hs + have := hs.comp_mdifferentiableWithinAt (extChartAt I x x) hฯ† + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hf' : DifferentiableWithinAt ๐•œ (f โˆ˜ ฯ†.symm โˆ˜ I.symm) (range I) (I (ฯ† x)) := by + have hฯ† := mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) (I := I) + have : (extChartAt I x).symm (extChartAt I x x) = x := extChartAt_to_inv x + rw [โ† this] at hf + have := hf.comp_mdifferentiableWithinAt (extChartAt I x x) hฯ† + exact mdifferentiableWithinAt_iff_differentiableWithinAt.mp this + have hsf : MDiffAt (s โ€ข f) x := hs.smul hf + simp [mfderiv, hsf, hs, hf] + have uniq : UniqueDiffWithinAt ๐•œ (range I) (I (ฯ† x)) := + ModelWithCorners.uniqueDiffWithinAt_image I + erw [fderivWithin_smul uniq hs' hf'] + simp [ฯ†.left_inv (ChartedSpace.mem_chart_source x)] + rfl +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 extend +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] [FiniteDimensional โ„ 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] [VectorBundle โ„ F V] + -- `V` vector bundle + +-- TODO: either change `localFrame` to make sure it is everywhere smooth +-- or introduce a cut-off here. First option is probaly better. +-- TODO: comment why we chose the second option in the end, and adapt the definition accordingly +-- new definition: smooth a bump function, then smul with localExtensionOn +/-- Extend a vector `v โˆˆ V x` to a section of the bundle `V`, whose value at `x` is `v`. +The details of the extension are mostly unspecified: for covariant derivatives, the value of +`s` at points other than `x` will not matter (except for shorter proofs). +Thus, we choose `s` to be somewhat nice: our chosen construction is linear in `v`. +-/ +noncomputable def extend [FiniteDimensional โ„ F] [T2Space M] {x : M} (v : V x) : + (x' : M) โ†’ V x' := + letI b := Basis.ofVectorSpace โ„ F + letI t := trivializationAt F V x + -- Choose a smooth bump function ฯˆ near `x`, supported within t.baseSet + -- and return ฯˆ โ€ข Vโ‚€ instead. + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + let ฯˆ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + ฯˆ.toFun โ€ข localExtensionOn b t v + +variable {I F} + +-- NB. These two lemmas don't hold for *any* choice of extension of `v`, but they hold for +-- *well-chosen* extensions (such as ours). +-- so, one may argue this is mathematically wrong, but it encodes the "choice some extension +-- with this and that property" nicely +-- a different proof would be to argue only the value at a point matters for cov +@[simp] +lemma extend_add [FiniteDimensional โ„ F] [T2Space M] {x : M} (v v' : V x) : + extend I F (v + v') = extend I F v + extend I F v' := by + simp [extend] + +@[simp] +lemma extend_smul [FiniteDimensional โ„ F] [T2Space M] {a : โ„} {x : M} (v : V x) : + extend I F (a โ€ข v) = a โ€ข extend I F v := by simp [extend]; module + +@[simp] +lemma extend_zero [FiniteDimensional โ„ F] [T2Space M] (x : M) : + extend I F (0 : V x) = 0 := by simp [extend] + +@[simp] lemma extend_apply_self [FiniteDimensional โ„ F] [T2Space M] {x : M} (v : V x) : + extend I F v x = v := by + simpa [extend] using + localExtensionOn_apply_self _ _ (FiberBundle.mem_baseSet_trivializationAt' x) v + +variable (I F) + +lemma contMDiff_extend [IsManifold I โˆž M] [FiniteDimensional โ„ F] [T2Space M] + [ContMDiffVectorBundle โˆž F V I] {x : M} (ฯƒโ‚€ : V x) : + CMDiff โˆž (T% (extend I F ฯƒโ‚€)) := by + letI t := trivializationAt F V x + letI ht := t.open_baseSet.mem_nhds (FiberBundle.mem_baseSet_trivializationAt' x) + have hx : x โˆˆ t.baseSet := FiberBundle.mem_baseSet_trivializationAt' x + let ฯˆ := Classical.choose <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + let hฯˆ := + Classical.choose_spec <| (SmoothBumpFunction.nhds_basis_support (I := I) ht).mem_iff.1 ht + exact ContMDiffOn.smul_section_of_tsupport ฯˆ.contMDiff.contMDiffOn t.open_baseSet hฯˆ.1 + (contMDiffOn_localExtensionOn _ hx _) + +lemma mdifferentiable_extend [IsManifold I โˆž M] [FiniteDimensional โ„ F] [T2Space M] + [ContMDiffVectorBundle โˆž F V I] {x : M} (ฯƒโ‚€ : V x) : + MDiff (T% (extend I F ฯƒโ‚€)) := + contMDiff_extend I F ฯƒโ‚€ |>.mdifferentiable (by simp) + +theorem contDiff_extend + {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] [FiniteDimensional โ„ E] + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace โ„ E'] [FiniteDimensional โ„ E'] + (x : E) (y : E') : ContDiff โ„ โˆž (extend ๐“˜(โ„, E) E' y (x := x)) := by + rw [contDiff_iff_contDiffAt] + intro x' + rw [โ† contMDiffAt_iff_contDiffAt] + simpa [contMDiffAt_section] using contMDiff_extend (V := Trivial E E') _ _ y x' + +end extend + +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 [โ† mk_proj_snd' e 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 + using by simp [(mem_target e).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 [*]โŸฉ + +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โŸฉ + +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 coe_fst' e 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 using + by simp [(mem_source e).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] + +@[simp] +lemma apply_symm_eventuallyEq {x : B} (hx : x โˆˆ e.baseSet) (s : B โ†’ F) : + (fun x โ†ฆ (e โŸจx, e.symm x (s x)โŸฉ).2) =แถ [๐“ x] s := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy using by simp [hy] + +variable [(b : B) โ†’ TopologicalSpace (E b)] [FiberBundle F E] + +-- FIXME super weird elaborator bug: removing the +-- omitted assumption from the variable line breaks the lemma +omit [(b : B) โ†’ TopologicalSpace (E b)] [FiberBundle F E] in +lemma symm_apply_apply_mk_eventuallyEq + {b : B} (hb : b โˆˆ e.baseSet) (ฯƒ : ฮ  x, E x) : + (T% fun x' โ†ฆ e.symm x' (e (T% ฯƒ x')).2) =แถ [๐“ b] T% ฯƒ := by + filter_upwards [e.baseSet_mem_nhds hb] with y hy using by simp [*] + +-- FIXME super weird elaborator bug: removing the +-- omitted assumption from the variable line breaks the lemma +omit [(x : B) โ†’ Zero (E x)] [(b : B) โ†’ TopologicalSpace (E b)] [FiberBundle F E] in +lemma apply_section_eventuallyEq + {x : B} (hx : x โˆˆ e.baseSet) (ฯƒ : ฮ  x, E x) : + e โˆ˜ T%ฯƒ =แถ [๐“ x] fun x โ†ฆ โŸจx, (e (ฯƒ x)).2โŸฉ := by + filter_upwards [e.baseSet_mem_nhds hx] with y hy + ext + ยท exact coe_coe_fst e hy + ยท simp + +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)] + +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 + +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' + +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' := + (symmL R e x).map_add f f' + +@[simp] +lemma symm_map_zero [Trivialization.IsLinear R e] {x : B} : + e.symm x 0 = 0 := + (symmL R e x).map_zero + +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 := + (symmL R e x).map_smul a f + +end + +end topological_vector_bundle + +section to_trivialization +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] + -- `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] + +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 := (coe_mem_source e).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 := (mk_mem_target e).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) + +@[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 [mk_proj_snd' e 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] + rfl + +@[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 [mk_proj_snd' e hv] at Dโ‚ + have diff : MDifferentiableAt (I.prod ๐“˜(โ„, F)) I TotalSpace.proj v := + mdifferentiableAt_proj _ + have eq : e.invFun (e v) = v := by simp [((mem_source e).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 [mk_proj_snd' e hv] at Dโ‚ + have Dโ‚‚ : MDifferentiableAt _ _ e v := e.mdifferentiableAt (I := I) hv v.2 + have : e.invFun (e v) = v := by simp [(mem_source e).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_section_of_function + [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + {x : M} (hx : x โˆˆ e.baseSet) {s : M โ†’ F} + (hs : MDiffAt s x) : + MDiffAt ((fun x' โ†ฆ (โŸจx', e.symm x' (s x')โŸฉ : TotalSpace F V))) x := by + rw [e.mdifferentiableAt_section_iff (IB := I) _ hx] + have := e.apply_symm_eventuallyEq hx s + exact hs.congr_of_eventuallyEq this + +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) : + letI s := fun x โ†ฆ (e (ฯƒ x)).2 + (e.deriv I (ฯƒ x)).toLinearMap ((mfderiv% T%ฯƒ x) u) = (u, mfderiv% s 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] + let s := fun x โ†ฆ (e (ฯƒ x)).2 + change mfderiv% (e โˆ˜ T%ฯƒ) x u = (u, mfderiv% s x u) + rw [(e.apply_section_eventuallyEq hx _).mfderiv_eq] + erw [mfderiv_prodMk, mfderiv_id] + ยท change (ContinuousLinearMap.id _ _).prod (mfderiv% s x) u = _ + simp + ยท apply mdifferentiableAt_id + ยท exact (mdifferentiableAt_section_iff I e ฯƒ hx).mp hฯƒ + +@[simp] +lemma _root_.mdifferentiableAt_section_trivial_iff {s : M โ†’ F} {x : M} : + MDiffAt (T% s) x โ†” MDiffAt s x := by + rw [mdifferentiableAt_section I] + simp + +end to_trivialization + +end Bundle.Trivialization + +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/Torsion.lean b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean new file mode 100644 index 00000000000000..84b37aba789f3b --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/CovariantDerivative/Torsion.lean @@ -0,0 +1,320 @@ +/- +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 + +/-! +# Torsion of a covariant derivative + +- define torsion of a covariant derivative (and its local version) +- torsion-free ness (local and global version) +- 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] + +-- TODO: where is a good namespace for this? +/-- The torsion of a covariant derivative on the tangent bundle `TM` -/ +noncomputable def Bundle.torsion + (f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x)) : + (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) := + fun X Y โ†ฆ f X Y - f Y X - VectorField.mlieBracket I X Y + +variable + {f g : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x)} + {X X' Y : ฮ  x : M, TangentSpace I x} + +variable (f X) in +lemma torsion_self : torsion f X X = 0 := by + simp [torsion] + +variable (X Y) in +lemma torsion_antisymm : torsion f X Y = - torsion f Y X := by + simp only [torsion] + rw [VectorField.mlieBracket_swap] + module + +namespace IsCovariantDerivativeOn + +variable [h : IsManifold I โˆž M] +variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) + +variable (Y) in +lemma torsion_add_left_apply [CompleteSpace E] + (hf : IsCovariantDerivativeOn E f U) (hx : x โˆˆ U) + (hX : MDiffAt (T% X) x) (hX' : MDiffAt (T% X') x) : + torsion f (X + X') Y x = torsion f X Y x + torsion f X' Y x := by + sorry -- simp [torsion, hf.addX (x := x) (hx := sorry) hX hX'] + -- rw [hf.addฯƒ Y hX hX', VectorField.mlieBracket_add_left hX hX'] + -- module + +lemma torsion_add_right_apply [CompleteSpace E] (hf : IsCovariantDerivativeOn E f U) (hx : x โˆˆ U) + (hX : MDiffAt (T% X) x) + (hX' : MDiffAt (T% X') x) : + torsion f Y (X + X') x = torsion f Y X x + torsion f Y X' x := by + rw [torsion_antisymm, Pi.neg_apply, + hf.torsion_add_left_apply _ hx hX hX', torsion_antisymm Y, torsion_antisymm Y] + simp; abel + +variable (Y) in +lemma torsion_smul_left_apply [CompleteSpace E] + {F : ((x : M) โ†’ TangentSpace I x) โ†’ ((x : M) โ†’ TangentSpace I x) โ†’ (x : M) โ†’ TangentSpace I x} + (hF : IsCovariantDerivativeOn E F U) (hx : x โˆˆ U) + -- TODO: making hx an auto-param := by trivial doesn't fire at the application sites below + {f : M โ†’ โ„} (hf : MDiffAt f x) (hX : MDiffAt (T% X) x) : + torsion F (f โ€ข X) Y x = f x โ€ข torsion F X Y x := by + sorry /-simp only [torsion, Pi.sub_apply, hF.smulX (X := X) (ฯƒ := Y) (f := f)] + rw [hF.leibniz Y hX hf hx, VectorField.mlieBracket_smul_left hf hX] + simp [bar, smul_sub] + abel -/ + +variable (X) in +lemma torsion_smul_right_apply [CompleteSpace E] + {F : ((x : M) โ†’ TangentSpace I x) โ†’ ((x : M) โ†’ TangentSpace I x) โ†’ (x : M) โ†’ TangentSpace I x} + (hF : IsCovariantDerivativeOn E F U) (hx : x โˆˆ U) + {f : M โ†’ โ„} (hf : MDiffAt f x) (hX : MDiffAt (T% Y) x) : + torsion F X (f โ€ข Y) x = f x โ€ข torsion F X Y x := by + rw [torsion_antisymm, Pi.neg_apply, hF.torsion_smul_left_apply X hx hf hX, torsion_antisymm X] + simp + +end IsCovariantDerivativeOn + +/-- `f` is torsion-free on `U` if its torsion vanishes at each `x โˆˆ U` -/ +noncomputable def IsTorsionFreeOn + (f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x)) + (U : Set M) : Prop := + โˆ€ x โˆˆ U, โˆ€ X Y : ฮ  x : M, TangentSpace I x, torsion f 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 f (โ‹ƒ i, s i) := by + rintro x โŸจsi, โŸจi, hiโŸฉ, hxsiโŸฉ X Y + exact hf i x (by simp [hi, hxsi]) X Y + +end changing_set + +/- Congruence properties -/ +section + +-- unused? +lemma congr {s : Set M} (h : IsTorsionFreeOn f s) + (hfg : โˆ€ {X Y : ฮ  x : M, TangentSpace I x}, โˆ€ {x}, x โˆˆ s โ†’ f X Y x = g X Y x) : + IsTorsionFreeOn g s := by + intro x hx X Y + specialize h x hx X Y + -- now, use torsion congruence lemma, i.e. tensoriality of sorts! + -- TODO: generalise tensoriality to the local setting! + sorry + +end + +end IsTorsionFreeOn + +namespace CovariantDerivative + +variable [h : IsManifold I โˆž M] +-- The torsion tensor of a covariant derivative on the tangent bundle `TM`. +variable {cov : CovariantDerivative I E (TangentSpace I : M โ†’ Type _)} + +variable {U : Set M} (hf : IsCovariantDerivativeOn E f U) + +-- TODO: prove applied versions of these, for IsCovariantDerivativeOn --- using tensoriality, later! +variable (f) in +@[simp] +lemma torsion_zero (hX : MDiff T% X) : torsion cov 0 X = 0 := by + simp [torsion, cov.zeroX hX, cov.zeroฯƒ hX] + + +@[simp] +lemma torsion_zero' (hX : MDiff T% X) : torsion cov X 0 = 0 := by + rw [torsion_antisymm, torsion_zero hX]; simp + +variable (Y) in +lemma torsion_add_left [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : + torsion cov (X + X') Y = torsion cov X Y + torsion cov X' Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) (hX x) (hX' x) + +lemma torsion_add_right [CompleteSpace E] + (hX : MDiff (T% X)) (hX' : MDiff (T% X')) : + torsion cov Y (X + X') = torsion cov Y X + torsion cov Y X' := by + rw [torsion_antisymm, torsion_add_left _ hX hX', torsion_antisymm X, torsion_antisymm X']; module + +variable (Y) in +lemma torsion_smul_left [CompleteSpace E] {f : M โ†’ โ„} (hf : MDiff f) (hX : MDiff (T% X)) : + torsion cov (f โ€ข X) Y = f โ€ข torsion cov X Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) (hf x) (hX x) + +variable (X) in +lemma torsion_smul_right [CompleteSpace E] {f : M โ†’ โ„} (hf : MDiff f) (hY : MDiff (T% Y)) : + torsion cov X (f โ€ข Y) = f โ€ข torsion cov X Y := by + ext x + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) (hf x) (hY x) + +/-- The torsion of a covariant derivative is tensorial: +the value of `torsion cov X Y` at `xโ‚€` depends only on `X xโ‚€` and `Y xโ‚€`. -/ +def torsion_tensorial [T2Space M] [IsManifold I โˆž M] [FiniteDimensional โ„ E] + [FiniteDimensional โ„ F] [VectorBundle โ„ F V] [ContMDiffVectorBundle 1 F V I] + {X X' Y Y' : ฮ  x : M, TangentSpace I x} {xโ‚€ : M} + (hX : MDiffAt (T% X) xโ‚€) (hX' : MDiffAt (T% X') xโ‚€) + (hY : MDiffAt (T% Y) xโ‚€) (hY' : MDiffAt (T% Y') xโ‚€) + (hXX' : X xโ‚€ = X' xโ‚€) (hYY' : Y xโ‚€ = Y' xโ‚€) : + (torsion cov X Y) xโ‚€ = (torsion cov X' Y') xโ‚€ := by + apply tensoriality_criterionโ‚‚ I E (TangentSpace I) E (TangentSpace I) hX hX' hY hY' hXX' hYY' + ยท intro f ฯƒ ฯ„ hf hฯƒ + exact cov.isCovariantDerivativeOn.torsion_smul_left_apply _ (by trivial) hf hฯƒ + ยท intro ฯƒ ฯƒ' ฯ„ hฯƒ hฯƒ' + exact cov.isCovariantDerivativeOn.torsion_add_left_apply _ (by trivial) hฯƒ hฯƒ' + ยท intros f ฯƒ ฯƒ' hf hฯƒ' + exact cov.isCovariantDerivativeOn.torsion_smul_right_apply _ (by trivial) hf hฯƒ' + ยท intro ฯƒ ฯ„ ฯ„' hฯ„ hฯ„' + exact cov.isCovariantDerivativeOn.torsion_add_right_apply (by trivial) hฯ„ hฯ„' + +-- TODO: define a torsion tensor of a covariant derivative, +-- and related torsion-freeness to this +-- (That will not work for torsion-freeness on a set, though.) + +-- TODO: generalise tensoriality result above to `IsCovariantDerivativeOn`, +-- so it would apply here as well + +variable (cov) in +/-- A covariant derivation is called **torsion-free** iff its torsion tensor vanishes. -/ +def IsTorsionFree : Prop := torsion cov = 0 + +@[simp] +lemma isTorsionFreeOn_univ : IsTorsionFreeOn cov univ โ†” IsTorsionFree cov := by + simp only [IsTorsionFree, IsTorsionFreeOn] + refine โŸจfun h โ†ฆ ?_, fun h โ†ฆ by simp [h]โŸฉ + ext X Y x + simp [h x] + +/-- If a covariant derivative `cov` is torsion-free on each set in an open cover, +it is torsion-free. -/ +def of_isTorsionFreeOn_of_open_cover {ฮน : Type*} {s : ฮน โ†’ Set M} + (hf : โˆ€ i, IsTorsionFreeOn cov (s i)) (hs : โ‹ƒ i, s i = Set.univ) : + IsTorsionFree cov := by + rw [โ† isTorsionFreeOn_univ, โ† hs] + exact IsTorsionFreeOn.iUnion hf + +lemma isTorsionFree_def : IsTorsionFree cov โ†” torsion cov = 0 := by simp [IsTorsionFree] + +-- This should be obvious; am I doing something wrong? +lemma isTorsionFree_iff : IsTorsionFree cov โ†” + โˆ€ X Y, cov X Y - cov Y X = VectorField.mlieBracket I X Y := by + simp only [IsTorsionFree] + constructor + ยท intro h X Y + have : torsion cov X Y = 0 := by simp [h] + -- XXX: abel, ring, module and grind all fail here + exact eq_of_sub_eq_zero this + ยท intro h + ext X Y x + specialize h X Y + apply congr_fun + simp_all [torsion] + +variable {n} in +lemma aux1 {ฮน : Type*} [Fintype ฮน] + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, 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 := by + 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) โ†’ (ฮ  x : M, 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 := X) (Y := s i) + (f := (LinearMap.piApply (hs.coeff i)) Y) hx hsi hsi' + dsimp at this + rw [โ† this] + congr + +/-- We can test torsion-freeness on a set using a local frame. -/ +lemma _root_.IsCovariantDerivativeOn.isTorsionFreeOn_iff_localFrame + {ฮน : Type*} [Finite ฮน] [CompleteSpace E] + {f : (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, TangentSpace I x) โ†’ (ฮ  x : M, 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 + have := Fintype.ofFinite ฮน + 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/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/LocalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/LocalFrame.lean index e97d641a462961..16743c15ea6d1d 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 -/ @@ -568,3 +587,79 @@ 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] + +-- TODO: fix this proof! +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 : ฮน) (y : M) : + (Trivialization.localFrame_coeff I e b i y) ((localExtensionOn b e) v y) = + (Trivialization.localFrame_coeff I e b i x) ((localExtensionOn b e) v x) := by +-- statement used to be +-- e.localFrame_coeff I b i (LinearMap.piApply (localExtensionOn b e v)) x' = +-- e.localFrame_coeff I b i (localExtensionOn b e v) x := by + simp [localExtensionOn, hx] + -- XXX: original proof passed hx' and was done now + sorry + +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 1ceadc7c458466..7ce86f5133c466 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/MDifferentiable.lean @@ -6,8 +6,10 @@ Authors: Sรฉbastien Gouรซzel, Patrick Massot, Michael Rothgang module public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Geometry.Manifold.Algebra.Monoid public import Mathlib.Geometry.Manifold.MFDeriv.NormedSpace public import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +public import Mathlib.Geometry.Manifold.Notation /-! # Differentiability of functions in vector bundles @@ -63,15 +65,14 @@ theorem mdifferentiableWithinAt_totalSpace (f : M โ†’ TotalSpace F E) {s : Set M Version at a point -/ theorem mdifferentiableAt_totalSpace (f : M โ†’ TotalSpace F E) {xโ‚€ : M} : MDifferentiableAt IM (IB.prod ๐“˜(๐•œ, F)) f xโ‚€ โ†” - MDifferentiableAt IM IB (fun x => (f x).proj) xโ‚€ โˆง - MDifferentiableAt IM ๐“˜(๐•œ, F) - (fun x โ†ฆ (trivializationAt F E (f xโ‚€).proj (f x)).2) xโ‚€ := by + MDiffAt (fun x => (f x).proj) xโ‚€ โˆง + MDiffAt (fun x โ†ฆ (trivializationAt F E (f xโ‚€).proj (f x)).2) xโ‚€ := by simpa [โ† mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_totalSpace _ f /-- Characterization of differentiable sections of a vector bundle at a point within a set in terms of the preferred trivialization at that point. -/ theorem mdifferentiableWithinAt_section (s : ฮ  b, E b) {u : Set B} {bโ‚€ : B} : - MDifferentiableWithinAt IB (IB.prod ๐“˜(๐•œ, F)) (fun b โ†ฆ TotalSpace.mk' F b (s b)) u bโ‚€ โ†” + MDifferentiableWithinAt IB (IB.prod ๐“˜(๐•œ, F)) (T% s) u bโ‚€ โ†” MDifferentiableWithinAt IB ๐“˜(๐•œ, F) (fun b โ†ฆ (trivializationAt F E bโ‚€ (s b)).2) u bโ‚€ := by rw [mdifferentiableWithinAt_totalSpace] change MDifferentiableWithinAt _ _ id _ _ โˆง _ โ†” _ @@ -80,8 +81,7 @@ theorem mdifferentiableWithinAt_section (s : ฮ  b, E b) {u : Set B} {bโ‚€ : B} : /-- Characterization of differentiable sections of a vector bundle at a point within a set in terms of the preferred trivialization at that point. -/ theorem mdifferentiableAt_section (s : ฮ  b, E b) {bโ‚€ : B} : - MDifferentiableAt IB (IB.prod ๐“˜(๐•œ, F)) (fun b โ†ฆ TotalSpace.mk' F b (s b)) bโ‚€ โ†” - MDifferentiableAt IB ๐“˜(๐•œ, F) (fun b โ†ฆ (trivializationAt F E bโ‚€ (s b)).2) bโ‚€ := by + MDiffAt (T% s) bโ‚€ โ†” MDiffAt (fun b โ†ฆ (trivializationAt F E bโ‚€ (s b)).2) bโ‚€ := by simpa [โ† mdifferentiableWithinAt_univ] using mdifferentiableWithinAt_section _ _ namespace Bundle @@ -108,7 +108,7 @@ theorem mdifferentiableWithinAt_proj {s : Set (TotalSpace F E)} {p : TotalSpace variable (๐•œ) [โˆ€ x, AddCommMonoid (E x)] variable [โˆ€ x, Module ๐•œ (E x)] [VectorBundle ๐•œ F E] -theorem mdifferentiable_zeroSection : MDifferentiable IB (IB.prod ๐“˜(๐•œ, F)) (zeroSection F E) := by +theorem mdifferentiable_zeroSection : MDiff (zeroSection F E) := by intro x unfold zeroSection rw [mdifferentiableAt_section] @@ -117,16 +117,14 @@ theorem mdifferentiable_zeroSection : MDifferentiable IB (IB.prod ๐“˜(๐•œ, F)) (mem_baseSet_trivializationAt F E x)] with y hy using congr_arg Prod.snd <| (trivializationAt F E x).zeroSection ๐•œ hy -theorem mdifferentiableOn_zeroSection {t : Set B} : - MDifferentiableOn IB (IB.prod ๐“˜(๐•œ, F)) (zeroSection F E) t := +theorem mdifferentiableOn_zeroSection {t : Set B} : MDiff[t] (zeroSection F E) := (mdifferentiable_zeroSection _ _).mdifferentiableOn -theorem mdifferentiableAt_zeroSection {x : B} : - MDifferentiableAt IB (IB.prod ๐“˜(๐•œ, F)) (zeroSection F E) x := +theorem mdifferentiableAt_zeroSection {x : B} : MDiffAt (zeroSection F E) x := (mdifferentiable_zeroSection _ _).mdifferentiableAt theorem mdifferentiableWithinAt_zeroSection {t : Set B} {x : B} : - MDifferentiableWithinAt IB (IB.prod ๐“˜(๐•œ, F)) (zeroSection F E) t x := + MDiffAt[t] (zeroSection F E) x := (mdifferentiable_zeroSection _ _ x).mdifferentiableWithinAt end Bundle @@ -157,14 +155,14 @@ theorem mdifferentiableAt_coordChangeL {x : B} variable {s : Set M} {f : M โ†’ B} {g : M โ†’ F} {x : M} -protected theorem MDifferentiableWithinAt.coordChangeL (hf : MDifferentiableWithinAt IM IB f s x) +protected theorem MDifferentiableWithinAt.coordChangeL (hf : MDiffAt[s] f x) (he : f x โˆˆ e.baseSet) (he' : f x โˆˆ e'.baseSet) : MDifferentiableWithinAt IM ๐“˜(๐•œ, F โ†’L[๐•œ] F) (fun y โ†ฆ (e.coordChangeL ๐•œ e' (f y) : F โ†’L[๐•œ] F)) s x := (mdifferentiableAt_coordChangeL he he').comp_mdifferentiableWithinAt _ hf protected theorem MDifferentiableAt.coordChangeL - (hf : MDifferentiableAt IM IB f x) (he : f x โˆˆ e.baseSet) (he' : f x โˆˆ e'.baseSet) : + (hf : MDiffAt f x) (he : f x โˆˆ e.baseSet) (he' : f x โˆˆ e'.baseSet) : MDifferentiableAt IM ๐“˜(๐•œ, F โ†’L[๐•œ] F) (fun y โ†ฆ (e.coordChangeL ๐•œ e' (f y) : F โ†’L[๐•œ] F)) x := MDifferentiableWithinAt.coordChangeL hf he he' @@ -174,14 +172,14 @@ protected theorem MDifferentiableOn.coordChangeL fun x hx โ†ฆ (hf x hx).coordChangeL (he hx) (he' hx) protected theorem MDifferentiable.coordChangeL - (hf : MDifferentiable IM IB f) (he : โˆ€ x, f x โˆˆ e.baseSet) (he' : โˆ€ x, f x โˆˆ e'.baseSet) : + (hf : MDiff f) (he : โˆ€ x, f x โˆˆ e.baseSet) (he' : โˆ€ x, f x โˆˆ e'.baseSet) : MDifferentiable IM ๐“˜(๐•œ, F โ†’L[๐•œ] F) (fun y โ†ฆ (e.coordChangeL ๐•œ e' (f y) : F โ†’L[๐•œ] F)) := fun x โ†ฆ (hf x).coordChangeL (he x) (he' x) protected theorem MDifferentiableWithinAt.coordChange - (hf : MDifferentiableWithinAt IM IB f s x) (hg : MDifferentiableWithinAt IM ๐“˜(๐•œ, F) g s x) + (hf : MDiffAt[s] f x) (hg : MDiffAt[s] g x) (he : f x โˆˆ e.baseSet) (he' : f x โˆˆ e'.baseSet) : - MDifferentiableWithinAt IM ๐“˜(๐•œ, F) (fun y โ†ฆ e.coordChange e' (f y) (g y)) s x := by + MDiffAt[s] (fun y โ†ฆ e.coordChange e' (f y) (g y)) x := by refine ((hf.coordChangeL he he').clm_apply hg).congr_of_eventuallyEq ?_ ?_ ยท have : e.baseSet โˆฉ e'.baseSet โˆˆ ๐“ (f x) := (e.open_baseSet.inter e'.open_baseSet).mem_nhds โŸจhe, he'โŸฉ @@ -190,21 +188,20 @@ protected theorem MDifferentiableWithinAt.coordChange ยท exact (Trivialization.coordChangeL_apply' e e' โŸจhe, he'โŸฉ (g x)).symm protected theorem MDifferentiableAt.coordChange - (hf : MDifferentiableAt IM IB f x) (hg : MDifferentiableAt IM ๐“˜(๐•œ, F) g x) + (hf : MDiffAt f x) (hg : MDiffAt g x) (he : f x โˆˆ e.baseSet) (he' : f x โˆˆ e'.baseSet) : - MDifferentiableAt IM ๐“˜(๐•œ, F) (fun y โ†ฆ e.coordChange e' (f y) (g y)) x := + MDiffAt (fun y โ†ฆ e.coordChange e' (f y) (g y)) x := MDifferentiableWithinAt.coordChange hf hg he he' protected theorem MDifferentiableOn.coordChange - (hf : MDifferentiableOn IM IB f s) (hg : MDifferentiableOn IM ๐“˜(๐•œ, F) g s) + (hf : MDiff[s] f) (hg : MDiff[s] g) (he : MapsTo f s e.baseSet) (he' : MapsTo f s e'.baseSet) : - MDifferentiableOn IM ๐“˜(๐•œ, F) (fun y โ†ฆ e.coordChange e' (f y) (g y)) s := fun x hx โ†ฆ + MDiff[s] (fun y โ†ฆ e.coordChange e' (f y) (g y)) := fun x hx โ†ฆ (hf x hx).coordChange (hg x hx) (he hx) (he' hx) protected theorem MDifferentiable.coordChange - (hf : MDifferentiable IM IB f) (hg : MDifferentiable IM ๐“˜(๐•œ, F) g) - (he : โˆ€ x, f x โˆˆ e.baseSet) (he' : โˆ€ x, f x โˆˆ e'.baseSet) : - MDifferentiable IM ๐“˜(๐•œ, F) (fun y โ†ฆ e.coordChange e' (f y) (g y)) := fun x โ†ฆ + (hf : MDiff f) (hg : MDiff g) (he : โˆ€ x, f x โˆˆ e.baseSet) (he' : โˆ€ x, f x โˆˆ e'.baseSet) : + MDiff (fun y โ†ฆ e.coordChange e' (f y) (g y)) := fun x โ†ฆ (hf x).coordChange (hg x) (he x) (he' x) end coordChange @@ -216,10 +213,9 @@ lemma MDifferentiableWithinAt.change_section_trivialization {e : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] {e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e'] {f : M โ†’ TotalSpace F E} {s : Set M} {xโ‚€ : M} - (hf : MDifferentiableWithinAt IM IB (ฯ€ F E โˆ˜ f) s xโ‚€) - (he'f : MDifferentiableWithinAt IM ๐“˜(๐•œ, F) (fun x โ†ฆ (e (f x)).2) s xโ‚€) + (hf : MDiffAt[s] (ฯ€ F E โˆ˜ f) xโ‚€) (he'f : MDiffAt[s] (fun x โ†ฆ (e (f x)).2) xโ‚€) (he : f xโ‚€ โˆˆ e.source) (he' : f xโ‚€ โˆˆ e'.source) : - MDifferentiableWithinAt IM ๐“˜(๐•œ, F) (fun x โ†ฆ (e' (f x)).2) s xโ‚€ := by + MDiffAt[s] (fun x โ†ฆ (e' (f x)).2) xโ‚€ := by rw [Trivialization.mem_source] at he he' refine (hf.coordChange he'f he he').congr_of_eventuallyEq ?_ ?_ ยท filter_upwards [hf.continuousWithinAt (e.open_baseSet.mem_nhds he)] with y hy @@ -232,9 +228,8 @@ theorem mdifferentiableWithinAt_snd_comp_iffโ‚‚ {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M โ†’ TotalSpace F E} {s : Set M} {xโ‚€ : M} (hexโ‚€ : f xโ‚€ โˆˆ e.source) (he'xโ‚€ : f xโ‚€ โˆˆ e'.source) - (hf : MDifferentiableWithinAt IM IB (ฯ€ F E โˆ˜ f) s xโ‚€) : - MDifferentiableWithinAt IM ๐“˜(๐•œ, F) (fun x โ†ฆ (e (f x)).2) s xโ‚€ โ†” - MDifferentiableWithinAt IM ๐“˜(๐•œ, F) (fun x โ†ฆ (e' (f x)).2) s xโ‚€ := + (hf : MDiffAt[s] (ฯ€ F E โˆ˜ f) xโ‚€) : + MDiffAt[s] (fun x โ†ฆ (e (f x)).2) xโ‚€ โ†” MDiffAt[s] (fun x โ†ฆ (e' (f x)).2) xโ‚€ := โŸจ(hf.change_section_trivialization IB ยท hexโ‚€ he'xโ‚€), (hf.change_section_trivialization IB ยท he'xโ‚€ hexโ‚€)โŸฉ @@ -244,9 +239,8 @@ theorem mdifferentiableAt_snd_comp_iffโ‚‚ {e e' : Trivialization F TotalSpace.proj} [MemTrivializationAtlas e] [MemTrivializationAtlas e'] {f : M โ†’ TotalSpace F E} {xโ‚€ : M} (he : f xโ‚€ โˆˆ e.source) (he' : f xโ‚€ โˆˆ e'.source) - (hf : MDifferentiableAt IM IB (fun x โ†ฆ (f x).proj) xโ‚€) : - MDifferentiableAt IM ๐“˜(๐•œ, F) (fun x โ†ฆ (e (f x)).2) xโ‚€ โ†” - MDifferentiableAt IM ๐“˜(๐•œ, F) (fun x โ†ฆ (e' (f x)).2) xโ‚€ := by + (hf : MDiffAt (fun x โ†ฆ (f x).proj) xโ‚€) : + MDiffAt (fun x โ†ฆ (e (f x)).2) xโ‚€ โ†” MDiffAt (fun x โ†ฆ (e' (f x)).2) xโ‚€ := by simpa [โ† mdifferentiableWithinAt_univ] using e.mdifferentiableWithinAt_snd_comp_iffโ‚‚ IB he he' hf @@ -257,9 +251,7 @@ theorem mdifferentiableWithinAt_totalSpace_iff (f : M โ†’ TotalSpace F E) {s : Set M} {xโ‚€ : M} (he : f xโ‚€ โˆˆ e.source) : MDifferentiableWithinAt IM (IB.prod ๐“˜(๐•œ, F)) f s xโ‚€ โ†” - MDifferentiableWithinAt IM IB (fun x => (f x).proj) s xโ‚€ โˆง - MDifferentiableWithinAt IM ๐“˜(๐•œ, F) - (fun x โ†ฆ (e (f x)).2) s xโ‚€ := by + MDiffAt[s] (fun x => (f x).proj) xโ‚€ โˆง MDiffAt[s] (fun x โ†ฆ (e (f x)).2) xโ‚€ := by rw [mdifferentiableWithinAt_totalSpace] apply and_congr_right intro hf @@ -273,9 +265,7 @@ theorem mdifferentiableAt_totalSpace_iff (f : M โ†’ TotalSpace F E) {xโ‚€ : M} (he : f xโ‚€ โˆˆ e.source) : MDifferentiableAt IM (IB.prod ๐“˜(๐•œ, F)) f xโ‚€ โ†” - MDifferentiableAt IM IB (fun x => (f x).proj) xโ‚€ โˆง - MDifferentiableAt IM ๐“˜(๐•œ, F) - (fun x โ†ฆ (e (f x)).2) xโ‚€ := by + MDiffAt (fun x => (f x).proj) xโ‚€ โˆง MDiffAt (fun x โ†ฆ (e (f x)).2) xโ‚€ := by rw [mdifferentiableAt_totalSpace] apply and_congr_right intro hf @@ -288,8 +278,7 @@ theorem mdifferentiableWithinAt_section_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E โ†’ B)) [MemTrivializationAtlas e] (s : ฮ  b : B, E b) {u : Set B} {bโ‚€ : B} (hexโ‚€ : bโ‚€ โˆˆ e.baseSet) : - MDifferentiableWithinAt IB (IB.prod ๐“˜(๐•œ, F)) (fun b โ†ฆ TotalSpace.mk' F b (s b)) u bโ‚€ โ†” - MDifferentiableWithinAt IB ๐“˜(๐•œ, F) (fun x โ†ฆ (e (s x)).2) u bโ‚€ := by + MDiffAt[u] (T% s) bโ‚€ โ†” MDiffAt[u] (fun x โ†ฆ (e (s x)).2) bโ‚€ := by rw [e.mdifferentiableWithinAt_totalSpace_iff IB] ยท change MDifferentiableWithinAt IB IB id u bโ‚€ โˆง _ โ†” _ simp [mdifferentiableWithinAt_id] @@ -301,8 +290,7 @@ theorem mdifferentiableAt_section_iff (e : Trivialization F (TotalSpace.proj : TotalSpace F E โ†’ B)) [MemTrivializationAtlas e] (s : ฮ  b : B, E b) {bโ‚€ : B} (hexโ‚€ : bโ‚€ โˆˆ e.baseSet) : - MDifferentiableAt IB (IB.prod ๐“˜(๐•œ, F)) (fun b โ†ฆ TotalSpace.mk' F b (s b)) bโ‚€ โ†” - MDifferentiableAt IB ๐“˜(๐•œ, F) (fun x โ†ฆ (e (s x)).2) bโ‚€ := by + MDiffAt (T% s) bโ‚€ โ†” MDiffAt (fun x โ†ฆ (e (s x)).2) bโ‚€ := by simpa [โ† mdifferentiableWithinAt_univ] using e.mdifferentiableWithinAt_section_iff IB s hexโ‚€ variable {IB} in @@ -311,7 +299,7 @@ using any trivialisation whose `baseSet` contains `s`. -/ theorem mdifferentiableOn_section_iff {s : โˆ€ x, E x} {a : Set B} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E โ†’ B)) [MemTrivializationAtlas e] (ha : IsOpen a) (ha' : a โІ e.baseSet) : - MDifferentiableOn IB (IB.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) a โ†” + MDifferentiableOn IB (IB.prod ๐“˜(๐•œ, F)) (T% s) a โ†” MDifferentiableOn IB ๐“˜(๐•œ, F) (fun x โ†ฆ (e โŸจx, s xโŸฉ).2) a := by refine โŸจfun h x hx โ†ฆ ?_, fun h x hx โ†ฆ ?_โŸฉ <;> have := (h x hx).mdifferentiableAt <| ha.mem_nhds hx @@ -324,7 +312,7 @@ can be determined using `e`. -/ theorem mdifferentiableOn_section_baseSet_iff {s : โˆ€ x, E x} (e : Trivialization F (Bundle.TotalSpace.proj : Bundle.TotalSpace F E โ†’ B)) [MemTrivializationAtlas e] : - MDifferentiableOn IB (IB.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) e.baseSet โ†” + MDifferentiableOn IB (IB.prod ๐“˜(๐•œ, F)) (T% s) e.baseSet โ†” MDifferentiableOn IB ๐“˜(๐•œ, F) (fun x โ†ฆ (e โŸจx, s xโŸฉ).2) e.baseSet := e.mdifferentiableOn_section_iff e.open_baseSet subset_rfl @@ -367,9 +355,8 @@ variable variable {f : B โ†’ ๐•œ} {a : ๐•œ} {s t : ฮ  x : B, E x} {u : Set B} {xโ‚€ : B} lemma mdifferentiableWithinAt_add_section - (hs : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u xโ‚€) - (ht : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s + t) x)) u xโ‚€ := by + (hs : MDiffAt[u] (T% s) xโ‚€) (ht : MDiffAt[u] (T% t) xโ‚€) : + MDiffAt[u] (T% (s + t)) xโ‚€ := by rw [mdifferentiableWithinAt_section] at hs ht โŠข set e := trivializationAt F E xโ‚€ refine (hs.add ht).congr_of_eventuallyEq ?_ ?_ @@ -380,27 +367,21 @@ lemma mdifferentiableWithinAt_add_section ยท exact (e.linear ๐•œ (FiberBundle.mem_baseSet_trivializationAt' xโ‚€)).1 .. lemma mdifferentiableAt_add_section - (hs : MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) xโ‚€) - (ht : MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s + t) x)) xโ‚€ := by + (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 lemma mdifferentiableOn_add_section - (hs : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u) - (ht : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s + t) x)) u := + (hs : MDiff[u] (T% s)) (ht : MDiff[u] (T% t)) : MDiff[u] (T% (s + t)) := fun xโ‚€ hxโ‚€ โ†ฆ mdifferentiableWithinAt_add_section (hs xโ‚€ hxโ‚€) (ht xโ‚€ hxโ‚€) lemma mdifferentiable_add_section - (hs : MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x))) - (ht : MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s + t) x)) := + (hs : MDiff (T% s)) (ht : MDiff (T% t)) : MDiff (T% (s + t)) := fun xโ‚€ โ†ฆ mdifferentiableAt_add_section (hs xโ‚€) (ht xโ‚€) lemma mdifferentiableWithinAt_neg_section - (hs : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (- s x)) u xโ‚€ := by + (hs : MDiffAt[u] (T% s) xโ‚€) : MDiffAt[u] (T% (-s)) xโ‚€ := by rw [mdifferentiableWithinAt_section] at hs โŠข set e := trivializationAt F E xโ‚€ refine hs.neg.congr_of_eventuallyEq ?_ ?_ @@ -411,51 +392,39 @@ lemma mdifferentiableWithinAt_neg_section ยท exact (e.linear ๐•œ (FiberBundle.mem_baseSet_trivializationAt' xโ‚€)).map_neg .. lemma mdifferentiableAt_neg_section - (hs : MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (- s x)) xโ‚€ := by + (hs : MDiffAt (T% s) xโ‚€) : MDiffAt (T% (-s)) xโ‚€ := by rw [โ† mdifferentiableWithinAt_univ] at hs โŠข exact mdifferentiableWithinAt_neg_section hs lemma mdifferentiableOn_neg_section - (hs : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (-s x)) u := + (hs : MDiff[u] (T% s)) : MDiff[u] (T% (-s)) := fun xโ‚€ hxโ‚€ โ†ฆ mdifferentiableWithinAt_neg_section (hs xโ‚€ hxโ‚€) -lemma mdifferentiable_neg_section - (hs : MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (-s x)) := +lemma mdifferentiable_neg_section (hs : MDiff (T% s)) : MDiff (T% (-s)) := fun xโ‚€ โ†ฆ mdifferentiableAt_neg_section (hs xโ‚€) lemma mdifferentiableWithinAt_sub_section - (hs : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u xโ‚€) - (ht : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s - t) x)) u xโ‚€ := by + (hs : MDiffAt[u] (T% s) xโ‚€) (ht : MDiffAt[u] (T% t) xโ‚€) : + MDiffAt[u] (T% (s - t)) xโ‚€ := by rw [sub_eq_add_neg] apply mdifferentiableWithinAt_add_section hs <| mdifferentiableWithinAt_neg_section ht lemma mdifferentiableAt_sub_section - (hs : MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) xโ‚€) - (ht : MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s - t) x)) xโ‚€ := by + (hs : MDiffAt (T% s) xโ‚€) (ht : MDiffAt (T% t) xโ‚€) : + MDiffAt (T% (s - t)) xโ‚€ := by rw [sub_eq_add_neg] apply mdifferentiableAt_add_section hs <| mdifferentiableAt_neg_section ht lemma mDifferentiableOn_sub_section - (hs : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u) - (ht : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s - t) x)) u := + (hs : MDiff[u] (T% s)) (ht : MDiff[u] (T% t)) : MDiff[u] (T% (s - t)) := fun xโ‚€ hxโ‚€ โ†ฆ mdifferentiableWithinAt_sub_section (hs xโ‚€ hxโ‚€) (ht xโ‚€ hxโ‚€) lemma mdifferentiable_sub_section - (hs : MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x))) - (ht : MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x ((s - t) x)) := + (hs : MDiff (T% s)) (ht : MDiff (T% t)) : MDiff (T% (s - t)) := fun xโ‚€ โ†ฆ mdifferentiableAt_sub_section (hs xโ‚€) (ht xโ‚€) lemma MDifferentiableWithinAt.smul_section - (hf : MDifferentiableWithinAt I ๐“˜(๐•œ) f u xโ‚€) - (hs : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (f x โ€ข s x)) u xโ‚€ := by + (hf : MDiffAt[u] f xโ‚€) (hs : MDiffAt[u] (T% s) xโ‚€) : MDiffAt[u] (T% (f โ€ข s)) xโ‚€ := by rw [mdifferentiableWithinAt_section] at hs โŠข set e := trivializationAt F E xโ‚€ refine (hf.smul hs).congr_of_eventuallyEq ?_ ?_ @@ -465,47 +434,39 @@ lemma MDifferentiableWithinAt.smul_section ยท exact fun x hx โ†ฆ (e.linear ๐•œ hx).2 .. ยท apply (e.linear ๐•œ (FiberBundle.mem_baseSet_trivializationAt' xโ‚€)).2 -lemma MDifferentiableAt.smul_section (hf : MDifferentiableAt I ๐“˜(๐•œ) f xโ‚€) - (hs : MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (f x โ€ข s x)) xโ‚€ := by +lemma MDifferentiableAt.smul_section + (hf : MDiffAt f xโ‚€) (hs : MDiffAt (T% s) xโ‚€) : MDiffAt (T% (f โ€ข s)) xโ‚€ := by rw [โ† mdifferentiableWithinAt_univ] at hs โŠข exact .smul_section hf hs -lemma MDifferentiableOn.smul_section (hf : MDifferentiableOn I ๐“˜(๐•œ) f u) - (hs : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (f x โ€ข s x)) u := +lemma MDifferentiableOn.smul_section + (hf : MDiff[u] f) (hs : MDiff[u] (T% s)) : MDiff[u] (T% (f โ€ข s)) := fun xโ‚€ hxโ‚€ โ†ฆ .smul_section (hf xโ‚€ hxโ‚€) (hs xโ‚€ hxโ‚€) -lemma mdifferentiable_smul_section (hf : MDifferentiable I ๐“˜(๐•œ) f) - (hs : MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (f x โ€ข s x)) := +lemma mdifferentiable_smul_section + (hf : MDiff f) (hs : MDiff (T% s)) : MDiff (T% (f โ€ข s)) := fun xโ‚€ โ†ฆ (hf xโ‚€).smul_section (hs xโ‚€) lemma mdifferentiableWithinAt_smul_const_section - (hs : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (a โ€ข s x)) u xโ‚€ := + (hs : MDiffAt[u] (T% s) xโ‚€) : + MDiffAt[u] (T% (a โ€ข s)) xโ‚€ := .smul_section mdifferentiableWithinAt_const hs lemma MDifferentiableAt.smul_const_section - (hs : MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (a โ€ข s x)) xโ‚€ := + (hs : MDiffAt (T% s) xโ‚€) : MDiffAt (T% (a โ€ข s)) xโ‚€ := .smul_section mdifferentiableAt_const hs lemma MDifferentiableOn.smul_const_section - (hs : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (a โ€ข s x)) u := + (hs : MDiff[u] (T% s)) : MDiff[u] (T% (a โ€ข s)) := .smul_section mdifferentiableOn_const hs lemma mdifferentiable_smul_const_section - (hs : MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (a โ€ข s x)) := + (hs : MDiff (T% s)) : MDiff (T% (a โ€ข s)) := fun xโ‚€ โ†ฆ (hs xโ‚€).smul_const_section lemma MDifferentiableWithinAt.sum_section {ฮน : Type*} {s : Finset ฮน} {t : ฮน โ†’ (x : B) โ†’ E x} - (hs : โˆ€ i, MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) - (fun x โ†ฆ TotalSpace.mk' F x (t i x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) - (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) u xโ‚€ := by + (hs : โˆ€ i, MDiffAt[u] (T% (t i ยท)) xโ‚€) : + MDiffAt[u] (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) xโ‚€ := by classical induction s using Finset.induction_on with | empty => simpa using (contMDiffWithinAt_zeroSection ๐•œ E).mdifferentiableWithinAt one_ne_zero @@ -513,19 +474,19 @@ lemma MDifferentiableWithinAt.sum_section {ฮน : Type*} {s : Finset ฮน} {t : ฮน simpa [Finset.sum_insert hi] using mdifferentiableWithinAt_add_section (hs i) h lemma MDifferentiableAt.sum_section {ฮน : Type*} {s : Finset ฮน} {t : ฮน โ†’ (x : B) โ†’ E x} {xโ‚€ : B} - (hs : โˆ€ i, MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) xโ‚€ := by + (hs : โˆ€ i, MDiffAt (T% (t i ยท)) xโ‚€) : + MDiffAt (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) xโ‚€ := by simp_rw [โ† mdifferentiableWithinAt_univ] at hs โŠข exact MDifferentiableWithinAt.sum_section hs lemma MDifferentiableOn.sum_section {ฮน : Type*} {s : Finset ฮน} {t : ฮน โ†’ (x : B) โ†’ E x} - (hs : โˆ€ i, MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) u := + (hs : โˆ€ i, MDiff[u] (T% (t i ยท))) : + MDiff[u] (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) := fun xโ‚€ hxโ‚€ โ†ฆ .sum_section fun i โ†ฆ hs i xโ‚€ hxโ‚€ lemma MDifferentiable.sum_section {ฮน : Type*} {s : Finset ฮน} {t : ฮน โ†’ (x : B) โ†’ E x} - (hs : โˆ€ i, MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) := + (hs : โˆ€ i, MDiff (T% (t i ยท))) : + MDiff (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) := fun xโ‚€ โ†ฆ .sum_section fun i โ†ฆ (hs i) xโ‚€ /-- The scalar product `ฯˆ โ€ข s` of a differentiable function `ฯˆ : M โ†’ ๐•œ` and a section `s` of a @@ -534,9 +495,8 @@ vector bundle `V โ†’ M` is differentiable once `s` is differentiable on an open See `ContMDiffOn.smul_section_of_tsupport` for the analogous result about `C^n` sections. -/ lemma MDifferentiableOn.smul_section_of_tsupport {s : ฮ  (x : B), E x} {ฯˆ : B โ†’ ๐•œ} - (hฯˆ : MDifferentiableOn I ๐“˜(๐•œ) ฯˆ u) (ht : IsOpen u) (ht' : tsupport ฯˆ โІ u) - (hs : MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (s x)) u) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (ฯˆ x โ€ข s x)) := by + (hฯˆ : MDiff[u] ฯˆ) (ht : IsOpen u) (ht' : tsupport ฯˆ โІ u) (hs : MDiff[u] (T% s)) : + MDiff (T% (ฯˆ โ€ข s)) := by apply mdifferentiable_of_mdifferentiableOn_union_of_isOpen (hฯˆ.smul_section hs) ?_ ?_ ht (isOpen_compl_iff.mpr <| isClosed_tsupport ฯˆ) ยท apply ((mdifferentiable_zeroSection _ _).mdifferentiableOn (s := (tsupport ฯˆ)แถœ)).congr @@ -552,18 +512,15 @@ open Function Version at a point within a set. -/ lemma MDifferentiableWithinAt.sum_section_of_locallyFinite (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) - (fun x โ†ฆ TotalSpace.mk' F x (t i x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) - (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) u xโ‚€ := by + (ht' : โˆ€ i, MDiffAt[u] (T% (t i ยท)) xโ‚€) : + MDiffAt[u] (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) xโ‚€ := by obtain โŸจu', hu', hfinโŸฉ := ht xโ‚€ -- All sections `t i` but a finite set `s` vanish near `xโ‚€`: choose a neighbourhood `u` of `xโ‚€` -- and a finite set `s` of sections which don't vanish. let s := {i | ((fun i โ†ฆ {x | t i x โ‰  0}) i โˆฉ u').Nonempty} have := hfin.fintype - have : MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) - (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) (u โˆฉ u') xโ‚€ := - MDifferentiableWithinAt.sum_section fun i โ†ฆ ((ht' i).mono inter_subset_left) + have : MDiffAt[u โˆฉ u'] (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘ i โˆˆ s, (t i x))) xโ‚€ := + .sum_section fun i โ†ฆ ((ht' i).mono inter_subset_left) apply (mdifferentiableWithinAt_inter hu').mp apply this.congr' (fun y hy โ†ฆ ?_) inter_subset_right (mem_of_mem_nhds hu') rw [TotalSpace.mk_inj, tsum_eq_sum'] @@ -580,8 +537,8 @@ lemma MDifferentiableWithinAt.sum_section_of_locallyFinite if each section is. -/ lemma MDifferentiableAt.sum_section_of_locallyFinite (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) xโ‚€ := by + (ht' : โˆ€ i, MDiffAt (T% (t i ยท)) xโ‚€) : + MDiffAt (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) xโ‚€ := by simp_rw [โ† mdifferentiableWithinAt_univ] at ht' โŠข exact .sum_section_of_locallyFinite ht ht' @@ -589,22 +546,20 @@ lemma MDifferentiableAt.sum_section_of_locallyFinite if each section is. -/ lemma MDifferentiableOn.sum_section_of_locallyFinite (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) u := + (ht' : โˆ€ i, MDiff[u] (T% (t i ยท))) : + MDiff[u] (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) := fun x hx โ†ฆ .sum_section_of_locallyFinite ht (ht' ยท x hx) /-- The sum of a locally finite collection of sections is differentiable if each section is. -/ lemma MDifferentiable.sum_section_of_locallyFinite (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) := + (ht' : โˆ€ i, MDiff (T% (t i ยท))) : + MDiff (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘' i, (t i x))) := fun x โ†ฆ .sum_section_of_locallyFinite ht fun i โ†ฆ ht' i x lemma MDifferentiableWithinAt.finsum_section_of_locallyFinite (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) - (fun x โ†ฆ TotalSpace.mk' F x (t i x)) u xโ‚€) : - MDifferentiableWithinAt I (I.prod ๐“˜(๐•œ, F)) - (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) u xโ‚€ := by + (ht' : โˆ€ i, MDiffAt[u] (T% (t i ยท)) xโ‚€) : + MDiffAt[u] (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) xโ‚€ := by apply (MDifferentiableWithinAt.sum_section_of_locallyFinite ht ht').congr' (t := Set.univ) (fun y hy โ†ฆ ?_) (by grind) trivial choose U hu hfin using ht y @@ -617,21 +572,19 @@ lemma MDifferentiableWithinAt.finsum_section_of_locallyFinite lemma MDifferentiableAt.finsum_section_of_locallyFinite (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x)) xโ‚€) : - MDifferentiableAt I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) xโ‚€ := by + (ht' : โˆ€ i, MDiffAt (T% (t i ยท)) xโ‚€) : + MDiffAt (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) xโ‚€ := by simp_rw [โ† mdifferentiableWithinAt_univ] at ht' โŠข exact .finsum_section_of_locallyFinite ht ht' lemma MDifferentiableOn.finsum_section_of_locallyFinite - (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x)) u) : - MDifferentiableOn I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) u := + (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) (ht' : โˆ€ i, MDiff[u] (T% (t i ยท))) : + MDiff[u] (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) := fun x hx โ†ฆ .finsum_section_of_locallyFinite ht fun i โ†ฆ ht' i x hx lemma MDifferentiable.finsum_section_of_locallyFinite - (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) - (ht' : โˆ€ i, MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (t i x))) : - MDifferentiable I (I.prod ๐“˜(๐•œ, F)) (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) := + (ht : LocallyFinite fun i โ†ฆ {x : B | t i x โ‰  0}) (ht' : โˆ€ i, MDiff (T% (t i ยท))) : + MDiff (fun x โ†ฆ TotalSpace.mk' F x (โˆ‘แถ  i, t i x)) := fun x โ†ฆ .finsum_section_of_locallyFinite ht fun i โ†ฆ ht' i x end operations @@ -680,7 +633,7 @@ lemma MDifferentiableWithinAt.clm_apply_of_inCoordinates (hฯ• : MDifferentiableWithinAt IM ๐“˜(๐•œ, Fโ‚ โ†’L[๐•œ] Fโ‚‚) (fun m โ†ฆ inCoordinates Fโ‚ Eโ‚ Fโ‚‚ Eโ‚‚ (bโ‚ mโ‚€) (bโ‚ m) (bโ‚‚ mโ‚€) (bโ‚‚ m) (ฯ• m)) s mโ‚€) (hv : MDifferentiableWithinAt IM (IBโ‚.prod ๐“˜(๐•œ, Fโ‚)) (fun m โ†ฆ (v m : TotalSpace Fโ‚ Eโ‚)) s mโ‚€) - (hbโ‚‚ : MDifferentiableWithinAt IM IBโ‚‚ bโ‚‚ s mโ‚€) : + (hbโ‚‚ : MDiffAt[s] bโ‚‚ mโ‚€) : MDifferentiableWithinAt IM (IBโ‚‚.prod ๐“˜(๐•œ, Fโ‚‚)) (fun m โ†ฆ (ฯ• m (v m) : TotalSpace Fโ‚‚ Eโ‚‚)) s mโ‚€ := by rw [mdifferentiableWithinAt_totalSpace] at hv โŠข @@ -715,7 +668,7 @@ lemma MDifferentiableAt.clm_apply_of_inCoordinates (hฯ• : MDifferentiableAt IM ๐“˜(๐•œ, Fโ‚ โ†’L[๐•œ] Fโ‚‚) (fun m โ†ฆ inCoordinates Fโ‚ Eโ‚ Fโ‚‚ Eโ‚‚ (bโ‚ mโ‚€) (bโ‚ m) (bโ‚‚ mโ‚€) (bโ‚‚ m) (ฯ• m)) mโ‚€) (hv : MDifferentiableAt IM (IBโ‚.prod ๐“˜(๐•œ, Fโ‚)) (fun m โ†ฆ (v m : TotalSpace Fโ‚ Eโ‚)) mโ‚€) - (hbโ‚‚ : MDifferentiableAt IM IBโ‚‚ bโ‚‚ mโ‚€) : + (hbโ‚‚ : MDiffAt bโ‚‚ mโ‚€) : MDifferentiableAt IM (IBโ‚‚.prod ๐“˜(๐•œ, Fโ‚‚)) (fun m โ†ฆ (ฯ• m (v m) : TotalSpace Fโ‚‚ Eโ‚‚)) mโ‚€ := by rw [โ† mdifferentiableWithinAt_univ] at hฯ• hv hbโ‚‚ โŠข exact MDifferentiableWithinAt.clm_apply_of_inCoordinates hฯ• hv hbโ‚‚ diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean new file mode 100644 index 00000000000000..f751f402d1a17a --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Misc.lean @@ -0,0 +1,152 @@ +/- +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 -- Building continuous bilinear maps + +structure IsBilinearMap (R : Type*) {E F G : Type*} [Semiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] (f : E โ†’ F โ†’ G) : Prop where + add_left : โˆ€ (xโ‚ xโ‚‚ : E) (y : F), f (xโ‚ + xโ‚‚) y = f xโ‚ y + f xโ‚‚ y + smul_left : โˆ€ (c : R) (x : E) (y : F), f (c โ€ข x) y = c โ€ข f x y + add_right : โˆ€ (x : E) (yโ‚ yโ‚‚ : F), f x (yโ‚ + yโ‚‚) = f x yโ‚ + f x yโ‚‚ + smul_right : โˆ€ (c : R) (x : E) (y : F), f x (c โ€ข y) = c โ€ข f x y + +def IsBilinearMap.toLinearMap {R : Type*} {E F G : Type*} [CommSemiring R] + [AddCommMonoid E] [AddCommMonoid F] [AddCommMonoid G] + [Module R E] [Module R F] [Module R G] {f : E โ†’ F โ†’ G} (hf : IsBilinearMap R f) : + E โ†’โ‚—[R] F โ†’โ‚—[R] G := + LinearMap.mkโ‚‚ _ f hf.add_left hf.smul_left hf.add_right hf.smul_right + +lemma isBilinearMap_eval (R : Type*) (E F : Type*) [CommSemiring R] + [AddCommMonoid E] [AddCommMonoid F] [Module R E] [Module R F] : + IsBilinearMap R (fun (e : E) (ฯ† : E โ†’โ‚—[R] F) โ†ฆ ฯ† e) := by + constructor <;> simp + +def IsBilinearMap.toContinuousLinearMap + {๐•œ : Type*} [NontriviallyNormedField ๐•œ] [CompleteSpace ๐•œ] + {E : Type*} [AddCommGroup E] [Module ๐•œ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ๐•œ E] [FiniteDimensional ๐•œ E] + [T2Space E] + {F : Type*} [AddCommGroup F] [Module ๐•œ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ๐•œ F] [FiniteDimensional ๐•œ F] + [T2Space F] + {G : Type*} [AddCommGroup G] [Module ๐•œ G] [TopologicalSpace G] + [IsTopologicalAddGroup G] [ContinuousSMul ๐•œ G] + {f : E โ†’ F โ†’ G} (h : IsBilinearMap ๐•œ f) : E โ†’L[๐•œ] F โ†’L[๐•œ] G := + IsLinearMap.mk' (fun x : E โ†ฆ h.toLinearMap x |>.toContinuousLinearMap) + (by constructor <;> (intros;simp)) |>.toContinuousLinearMap + +def isBilinearMap_evalL + (๐•œ : Type*) [NontriviallyNormedField ๐•œ] [CompleteSpace ๐•œ] + (E : Type*) [AddCommGroup E] [Module ๐•œ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ๐•œ E] [FiniteDimensional ๐•œ E] + [T2Space E] + (F : Type*) [AddCommGroup F] [Module ๐•œ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ๐•œ F] [FiniteDimensional ๐•œ F] + [T2Space F] : + IsBilinearMap ๐•œ (fun (e : E) (ฯ† : E โ†’L[๐•œ] F) โ†ฆ ฯ† e) := by + constructor <;> simp + +def evalL + (๐•œ : Type*) [NontriviallyNormedField ๐•œ] [CompleteSpace ๐•œ] + (E : Type*) [AddCommGroup E] [Module ๐•œ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ๐•œ E] [FiniteDimensional ๐•œ E] + [T2Space E] + (F : Type*) [AddCommGroup F] [Module ๐•œ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ๐•œ F] [FiniteDimensional ๐•œ F] + [T2Space F] : E โ†’L[๐•œ] (E โ†’L[๐•œ] F) โ†’L[๐•œ] F := + (isBilinearMap_evalL ๐•œ E F).toContinuousLinearMap +end + +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] [IsManifold I 0 M] + +variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ๐•œ E'] + +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)] [โˆ€ x, IsTopologicalAddGroup (V x)] + [โˆ€ x, ContinuousSMul ๐•œ (V x)] + [FiberBundle F V] [VectorBundle ๐•œ F V] + -- `V` vector bundle + +set_option backward.isDefEq.respectTransparency false in +def bar (a : ๐•œ) : TangentSpace ๐“˜(๐•œ) a โ‰ƒL[๐•œ] ๐•œ where + toFun v := v + invFun v := v + map_add' := by simp + map_smul' := by simp + +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] + +attribute [simp] mdifferentiableAt_iff_differentiableAt + +lemma FiberBundle.trivializationAt.baseSet_mem_nhds {B : Type*} (F : Type*) + [TopologicalSpace B] [TopologicalSpace F] + (E : B โ†’ Type*) [TopologicalSpace (TotalSpace F E)] [(b : B) โ†’ TopologicalSpace (E b)] + [FiberBundle F E] (b : B) : (trivializationAt F E b |>.baseSet) โˆˆ ๐“ b := + (trivializationAt F E b).open_baseSet.eventually_mem (FiberBundle.mem_baseSet_trivializationAt' b) + +omit [IsManifold I 0 M] [โˆ€ (x : M), IsTopologicalAddGroup (V x)] [(x : M) โ†’ Module ๐•œ (V x)] + [(x : M) โ†’ AddCommGroup (V x)] + [โˆ€ (x : M), ContinuousSMul ๐•œ (V x)] [VectorBundle ๐•œ F V] in +variable {I F V x} in +/-- 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} {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] + +omit [IsManifold I 0 M] [โˆ€ (x : M), IsTopologicalAddGroup (V x)] [(x : M) โ†’ Module ๐•œ (V x)] + [โˆ€ (x : M), ContinuousSMul ๐•œ (V x)] [VectorBundle ๐•œ F V] [(x : M) โ†’ AddCommGroup (V x)] in +variable {I F V x} in +/-- 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} {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/VectorBundle/OrthonormalFrame.lean b/Mathlib/Geometry/Manifold/VectorBundle/OrthonormalFrame.lean new file mode 100644 index 00000000000000..40bbe8f86cc012 --- /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 [Finite ฮน] (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 := Fintype.ofFinite ฮน + 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} + +variable (b e) in +/-- The orthonormal frame associated to the basis `b` and the trivialisation `e`: +this is obtained by applying the Gram-Schmidt orthonormalisation procedure to `b.localFrame e`. +In particular, if x is outside of `e.baseSet`, this returns the junk value 0. -/ +noncomputable def orthonormalFrame : ฮน โ†’ (x : B) โ†’ E x := + VectorBundle.gramSchmidtNormed (e.localFrame b) + +omit [IsManifold IB n B] in +variable (b e) in +/-- An orthonormal frame w.r.t. a local trivialisation is an orthonormal local frame. -/ +lemma orthonormalFrame_isOrthonormalFrameOn : + IsOrthonormalFrameOn IB F n (b.orthonormalFrame e) e.baseSet := + (e.isLocalFrameOn_localFrame_baseSet IB n b).gramSchmidtNormed + +omit [IsManifold IB n B] in +variable (b e) in +/-- Each orthonormal frame `s^i โˆˆ ฮ“(E)` of a `C^k` vector bundle, defined by a local +trivialisation `e`, is `C^k` on `e.baseSet`. -/ +lemma contMDiffOn_orthonormalFrame_baseSet (i : ฮน) : + CMDiff[e.baseSet] n (T% (b.orthonormalFrame e i)) := by + apply IsLocalFrameOn.contMDiffOn + exact (b.orthonormalFrame_isOrthonormalFrameOn e).toIsLocalFrameOn + +omit [IsManifold IB n B] in +variable (b e) in +lemma _root_.contMDiffAt_orthonormalFrame_of_mem (i : ฮน) {x : B} (hx : x โˆˆ e.baseSet) : + CMDiffAt n (T% (b.orthonormalFrame e i)) x := + -- bug: if I change this to a by apply, and put #check after the `by`, it works, but #check' fails + -- #check' contMDiffOn_orthonormalFrame_baseSet + (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx + +-- TODO: add more variants with mdifferentiable! +omit [ContMDiffVectorBundle n F E IB] [IsContMDiffRiemannianBundle IB n F E] in +variable [ContMDiffVectorBundle 1 F E IB] [IsContMDiffRiemannianBundle IB 1 F E] in +variable (b e) in +lemma _root_.mdifferentiableAt_orthonormalFrame_of_mem (i : ฮน) {x : B} (hx : x โˆˆ e.baseSet) : + MDiffAt (T% (b.orthonormalFrame e i)) x := by + apply ContMDiffAt.mdifferentiableAt _ one_ne_zero + exact (contMDiffOn_orthonormalFrame_baseSet b e i).contMDiffAt <| e.open_baseSet.mem_nhds hx + +@[simp] +lemma orthonormalFrame_apply_of_notMem {i : ฮน} (hx : x โˆ‰ e.baseSet) : + b.orthonormalFrame e i x = 0 := by + simp only [orthonormalFrame, VectorBundle.gramSchmidtNormed, InnerProductSpace.gramSchmidtNormed, + RCLike.ofReal_real_eq_id, id_eq, smul_eq_zero, inv_eq_zero, norm_eq_zero, or_self] + convert InnerProductSpace.gramSchmidt_zero โ„ i + exact e.localFrame_apply_of_notMem b hx + +end Module.Basis diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 12d21cd26fce89..3eb794b53d0b3f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -7,9 +7,9 @@ module public import Mathlib.Geometry.Manifold.Algebra.LieGroup public import Mathlib.Geometry.Manifold.MFDeriv.Basic -public import Mathlib.Topology.ContinuousMap.Basic -public import Mathlib.Geometry.Manifold.VectorBundle.Basic public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.Basic +public import Mathlib.Topology.ContinuousMap.Basic /-! # `C^n` sections @@ -194,6 +194,16 @@ lemma ContMDiffOn.smul_section_of_tsupport {s : ฮ  (x : M), V x} {ฯˆ : M โ†’ simp [image_eq_zero_of_notMem_tsupport hy, zeroSection] ยท exact Set.compl_subset_iff_union.mp <| Set.compl_subset_compl.mpr ht' +-- unused +/-- The scalar product `ฯˆ โ€ข s` of a `C^k` function `ฯˆ: M โ†’ ๐•œ` and a section `s` of a vector +bundle `V โ†’ M` is `C^k` once `s` is `C^k` at each point in `tsupport ฯˆ`. + +This is a vector bundle analogue of `contMDiff_of_tsupport`. -/ +lemma ContMDiff.smul_section_of_tsupport' {s : ฮ  (x : M), V x} {ฯˆ : M โ†’ ๐•œ} {u : Set M} + (hs : โˆ€ x โˆˆ tsupport ฯˆ, CMDiffAt n (T% (ฯˆ โ€ข s)) x) : + CMDiff n (T% (ฯˆ โ€ข s)) := by + sorry + /-- The sum of a locally finite collection of sections is `C^k` iff each section is. Version at a point within a set. -/ lemma ContMDiffWithinAt.sum_section_of_locallyFinite diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean new file mode 100644 index 00000000000000..e8e4c370b175d6 --- /dev/null +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tensoriality.lean @@ -0,0 +1,268 @@ +/- +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.BumpFunction +public import Mathlib.Geometry.Manifold.MFDeriv.Basic +public import Mathlib.Geometry.Manifold.Notation +public import Mathlib.Geometry.Manifold.VectorBundle.LocalFrame +public import Mathlib.Geometry.Manifold.VectorBundle.MDifferentiable + +/-! +# The tensoriality criterion + +-/ +open Bundle Filter Function Topology Module + +open scoped Bundle Manifold ContDiff + +@[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] [IsManifold I 1 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)] + -- [โˆ€ x, IsTopologicalAddGroup (V x)] [โˆ€ x, ContinuousSMul โ„ (V x)] + [FiberBundle F V] [VectorBundle โ„ F V] + -- `V` vector bundle + +variable (F' : Type*) [NormedAddCommGroup F'] [NormedSpace โ„ F'] + (m : WithTop โ„•โˆž) + (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)] + +omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle โ„ F V] in +lemma tensoriality_criterion [FiberBundle F V] [VectorBundle โ„ F V] + [ContMDiffVectorBundle 1 F V I] [FiniteDimensional โ„ E] + [FiniteDimensional โ„ F] [FiberBundle F' V'] [VectorBundle โ„ F' V'] [T2Space M] + [IsManifold I โˆž M] + {ฯ† : (ฮ  x : M, V x) โ†’ (ฮ  x, V' x)} {x} + {ฯƒ ฯƒ' : ฮ  x : M, V x} (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯƒ' : MDiffAt (T% ฯƒ') x) + (hฯƒฯƒ' : ฯƒ x = ฯƒ' x) + (ฯ†_smul : โˆ€ f : M โ†’ โ„, โˆ€ ฯƒ, MDiffAt f x โ†’ MDiffAt (T% ฯƒ) x โ†’ + ฯ† (f โ€ข ฯƒ) x = f x โ€ข ฯ† ฯƒ x) + (ฯ†_add : โˆ€ ฯƒ ฯƒ', MDiffAt (T% ฯƒ) x โ†’ MDiffAt (T% ฯƒ') x โ†’ + ฯ† (ฯƒ + ฯƒ') x = ฯ† ฯƒ x + ฯ† ฯƒ' x) : ฯ† ฯƒ x = ฯ† ฯƒ' x := by + have locality {ฯƒ ฯƒ'} (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯƒ' : MDiffAt (T% ฯƒ') x) + (hฯƒฯƒ' : โˆ€แถ  x' in ๐“ x, ฯƒ x' = ฯƒ' x') : ฯ† ฯƒ x = ฯ† ฯƒ' x := by + obtain โŸจฯˆ, _, hฯˆโŸฉ := (SmoothBumpFunction.nhds_basis_support (I := I) hฯƒฯƒ').mem_iff.1 hฯƒฯƒ' + have (x : M) : ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x = ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by + by_cases h : ฯƒ x = ฯƒ' x + ยท rw [Pi.smul_apply', Pi.smul_apply', h] + ยท simp [notMem_support.mp fun a โ†ฆ h (hฯˆ a)] + have hฯˆ' : MDifferentiableAt I ๐“˜(โ„) ฯˆ x := + ฯˆ.contMDiffAt.mdifferentiableAt (by simp) + calc ฯ† ฯƒ x + _ = ฯ† ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x := by simp [ฯ†_smul _ _ hฯˆ' hฯƒ] + _ = ฯ† ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by rw [funext this] + _ = ฯ† ฯƒ' x := by simp [ฯ†_smul _ _ hฯˆ' hฯƒ'] + let ฮน : Type _ := Basis.ofVectorSpaceIndex โ„ F + classical + have sum_phi {s : Finset ฮน} (ฯƒ : ฮน โ†’ ฮ  x : M, V x) + (hฯƒ : โˆ€ i, MDiffAt (T% (ฯƒ i)) x): + ฯ† (fun x' โ†ฆ โˆ‘ i โˆˆ s, ฯƒ i x') x = โˆ‘ i โˆˆ s, ฯ† (ฯƒ i) x := by + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + have hโ‚ : MDiffAt (fun x' : M โ†ฆ (0 : โ„)) x := mdifferentiableAt_const + rw [show (fun x' : M โ†ฆ (0 : V x')) = (0 : M โ†’ โ„) โ€ข fun x' โ†ฆ 0 by simp;rfl] + rw [ฯ†_smul] + ยท simp + ยท exact hโ‚ + -- TODO: add mdifferentiable_zeroSection and/or use it! + apply (contMDiff_zeroSection _ _).mdifferentiableAt one_ne_zero + | insert a s ha h => + change ฯ† (fun x' : M โ†ฆ โˆ‘ i โˆˆ (insert a s : Finset ฮน), ฯƒ i x') x = _ + simp only [Finset.sum_insert ha, โ† h] + exact ฯ†_add _ _ (hฯƒ a) (.sum_section hฯƒ) + have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) + let b := Basis.ofVectorSpace โ„ F + let t := trivializationAt F V x + let s := t.localFrame b + let c := t.localFrame_coeff I b + have hs (i) : MDiffAt (T% (s i)) x:= + (contMDiffAt_localFrame_of_mem 1 _ b i x_mem).mdifferentiableAt (by simp) + have hc {ฯƒ : (x : M) โ†’ V x} (hฯƒ : MDiffAt (T% ฯƒ) x) (i) : + MDiffAt ((LinearMap.piApply (c i)) ฯƒ) x := + mdifferentiableAt_localFrame_coeff b x_mem hฯƒ i + have hฯ† {ฯƒ : (x : M) โ†’ V x} (hฯƒ : MDiffAt (T% ฯƒ) x) : + ฯ† ฯƒ x = ฯ† (fun x' โ†ฆ โˆ‘ i, c i x' (ฯƒ x') โ€ข s i x') x := by + exact + locality hฯƒ + (.sum_section fun i โ†ฆ (hc hฯƒ i).smul_section (hs i)) + (t.eventually_eq_localFrame_sum_coeff_smul b x_mem) + rw [hฯ† hฯƒ, hฯ† hฯƒ', sum_phi, sum_phi] + ยท change โˆ‘ i, ฯ† (((LinearMap.piApply (c i)) ฯƒ) โ€ข (s i)) x = + โˆ‘ i, ฯ† (((LinearMap.piApply (c i)) ฯƒ') โ€ข (s i)) x + congr + ext i + rw [ฯ†_smul _ _ (hc hฯƒ i) (hs i), ฯ†_smul _ _ (hc hฯƒ' i) (hs i)] + simp [hฯƒฯƒ'] + ยท exact fun i โ†ฆ (hc hฯƒ' i).smul_section (hs i) + ยท exact fun i โ†ฆ (hc hฯƒ i).smul_section (hs i) + +include I in +omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle โ„ F V] in +lemma tensoriality_criterion' [FiberBundle F V] [VectorBundle โ„ F V] [FiniteDimensional โ„ E] + [FiniteDimensional โ„ F] [FiberBundle F' V'] [VectorBundle โ„ F' V'] [T2Space M] + [ContMDiffVectorBundle 1 F V I] + {ฯ† : (ฮ  x : M, V x) โ†’ (ฮ  x, V' x)} {x} + {ฯƒ ฯƒ' : ฮ  x : M, V x} + (hฯƒฯƒ' : ฯƒ x = ฯƒ' x) + (ฯ†_smul : โˆ€ f : M โ†’ โ„, โˆ€ ฯƒ, ฯ† (f โ€ข ฯƒ) x = f x โ€ข ฯ† ฯƒ x) + (ฯ†_add : โˆ€ ฯƒ ฯƒ', ฯ† (ฯƒ + ฯƒ') x = ฯ† ฯƒ x + ฯ† ฯƒ' x) : ฯ† ฯƒ x = ฯ† ฯƒ' x := by + have locality {ฯƒ ฯƒ'} (hฯƒฯƒ' : โˆ€แถ  x' in ๐“ x, ฯƒ x' = ฯƒ' x') : + ฯ† ฯƒ x = ฯ† ฯƒ' x := by + obtain โŸจฯˆ, _, hฯˆโŸฉ := (SmoothBumpFunction.nhds_basis_support (I := I) hฯƒฯƒ').mem_iff.1 hฯƒฯƒ' + have (x : M) : ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x = ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by + by_cases h : ฯƒ x = ฯƒ' x + ยท rw [Pi.smul_apply', Pi.smul_apply', h] + ยท simp [notMem_support.mp fun a โ†ฆ h (hฯˆ a)] + calc ฯ† ฯƒ x + _ = ฯ† ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x := by simp [ฯ†_smul] + _ = ฯ† ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by rw [funext this] + _ = ฯ† ฯƒ' x := by simp [ฯ†_smul] + let ฮน : Type _ := Basis.ofVectorSpaceIndex โ„ F + classical + have sum_phi {s : Finset ฮน} (ฯƒ : ฮน โ†’ ฮ  x : M, V x) : + ฯ† (fun x' โ†ฆ โˆ‘ i โˆˆ s, ฯƒ i x') x = โˆ‘ i โˆˆ s, ฯ† (ฯƒ i) x := by + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + rw [show (fun x' : M โ†ฆ (0 : V x')) = (0 : M โ†’ โ„) โ€ข fun x' โ†ฆ 0 by simp;rfl, ฯ†_smul] + simp + | insert a s ha h => + change ฯ† (fun x' : M โ†ฆ โˆ‘ i โˆˆ (insert a s : Finset ฮน), ฯƒ i x') x = _ + simp only [Finset.sum_insert ha, โ† h] + erw [ฯ†_add] + have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) + let b := Basis.ofVectorSpace โ„ F + let t := trivializationAt F V x + let s := t.localFrame b + let c := t.localFrame_coeff (I := I) b + rw [locality (t.eventually_eq_localFrame_sum_coeff_smul (I := I) b x_mem)] + nth_rw 2 [locality (t.eventually_eq_localFrame_sum_coeff_smul (I := I) b x_mem)] + rw [sum_phi, sum_phi] + -- FIXME: the `erw` below can be made an `rw` by uncommenting this `change` + --change โˆ‘ i, ฯ† (((LinearMap.piApply (c i)) ฯƒ) โ€ข (s i)) x = + -- โˆ‘ i, ฯ† (((LinearMap.piApply (c i)) ฯƒ') โ€ข (s i)) x + congr with i + -- `erw?` says this is because of smul with a constant vs. a function `M โ†’ โ„` + erw [ฯ†_smul, ฯ†_smul] + congr + +include I in +omit [IsManifold I 1 M] [FiberBundle F V] [VectorBundle โ„ F V] in +lemma tensoriality_criterionโ‚‚' [FiberBundle F V] [VectorBundle โ„ F V] + [FiniteDimensional โ„ E] [FiniteDimensional โ„ F] [T2Space M] [ContMDiffVectorBundle 1 F V I] + [FiberBundle F' V'] [VectorBundle โ„ F' V'] + {ฯ† : (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x, V' x)} {x} + {ฯƒ ฯƒ' ฯ„ ฯ„' : ฮ  x : M, V x} + (hฯƒฯƒ' : ฯƒ x = ฯƒ' x) + (hฯ„ฯ„' : ฯ„ x = ฯ„' x) + (ฯ†_smul : โˆ€ f : M โ†’ โ„, โˆ€ ฯƒ ฯ„, ฯ† (f โ€ข ฯƒ) ฯ„ x = f x โ€ข ฯ† ฯƒ ฯ„ x) + (ฯ†_add : โˆ€ ฯƒ ฯƒ' ฯ„, ฯ† (ฯƒ + ฯƒ') ฯ„ x = ฯ† ฯƒ ฯ„ x + ฯ† ฯƒ' ฯ„ x) + (ฯ„_smul : โˆ€ f : M โ†’ โ„, โˆ€ ฯƒ ฯ„, ฯ† ฯƒ (f โ€ข ฯ„) x = f x โ€ข ฯ† ฯƒ ฯ„ x) + (ฯ„_add : โˆ€ ฯƒ ฯ„ ฯ„', ฯ† ฯƒ (ฯ„ + ฯ„') x = ฯ† ฯƒ ฯ„ x + ฯ† ฯƒ ฯ„' x) : ฯ† ฯƒ ฯ„ x = ฯ† ฯƒ' ฯ„' x := by + trans ฯ† ฯƒ' ฯ„ x + ยท let ฯ†1 : (ฮ  x : M, V x) โ†’ (ฮ  x, V' x) := fun X โ†ฆ ฯ† X ฯ„ + change ฯ†1 ฯƒ x = ฯ†1 ฯƒ' x + exact tensoriality_criterion' I F V F' V' hฯƒฯƒ' (by simp [ฯ†_smul, ฯ†1]) (by simp [ฯ†_add, ฯ†1]) + ยท let ฯ†1 : (ฮ  x : M, V x) โ†’ (ฮ  x, V' x) := fun X โ†ฆ ฯ† ฯƒ' X + change ฯ†1 ฯ„ x = ฯ†1 ฯ„' x + exact tensoriality_criterion' I F V F' V' hฯ„ฯ„' (by simp [ฯ„_smul, ฯ†1]) (by simp [ฯ„_add, ฯ†1]) + +include I in +omit [IsManifold I 1 M] in +lemma tensoriality_criterionโ‚‚ [ContMDiffVectorBundle 1 F V I] [IsManifold I โˆž M] + [FiniteDimensional โ„ E] [FiniteDimensional โ„ F] [T2Space M] + [FiberBundle F' V'] [VectorBundle โ„ F' V'] + {ฯ† : (ฮ  x : M, V x) โ†’ (ฮ  x : M, V x) โ†’ (ฮ  x, V' x)} {x} + {ฯƒ ฯƒ' ฯ„ ฯ„' : ฮ  x : M, V x} + (hฯƒ : MDiffAt (T% ฯƒ) x) (hฯƒ' : MDiffAt (T% ฯƒ') x) + (hฯ„ : MDiffAt (T% ฯ„) x) (hฯ„' : MDiffAt (T% ฯ„') x) + (hฯƒฯƒ' : ฯƒ x = ฯƒ' x) + (hฯ„ฯ„' : ฯ„ x = ฯ„' x) + (ฯ†_smul : โˆ€ {f : M โ†’ โ„}, โˆ€ {ฯƒ ฯ„}, MDiffAt f x โ†’ MDiffAt (T% ฯƒ) x โ†’ + ฯ† (f โ€ข ฯƒ) ฯ„ x = f x โ€ข ฯ† ฯƒ ฯ„ x) + (ฯ†_add : โˆ€ {ฯƒ ฯƒ' ฯ„}, MDiffAt (T% ฯƒ) x โ†’ MDiffAt (T% ฯƒ') x โ†’ + ฯ† (ฯƒ + ฯƒ') ฯ„ x = ฯ† ฯƒ ฯ„ x + ฯ† ฯƒ' ฯ„ x) + (ฯ„_smul : โˆ€ {f : M โ†’ โ„}, โˆ€ {ฯƒ ฯ„}, MDiffAt f x โ†’ MDiffAt (T% ฯ„) x โ†’ + ฯ† ฯƒ (f โ€ข ฯ„) x = f x โ€ข ฯ† ฯƒ ฯ„ x) + (ฯ„_add : โˆ€ {ฯƒ ฯ„ ฯ„'}, MDiffAt (T% ฯ„) x โ†’ MDiffAt (T% ฯ„') x โ†’ + ฯ† ฯƒ (ฯ„ + ฯ„') x = ฯ† ฯƒ ฯ„ x + ฯ† ฯƒ ฯ„' x) : ฯ† ฯƒ ฯ„ x = ฯ† ฯƒ' ฯ„' x := by + trans ฯ† ฯƒ' ฯ„ x + ยท let ฯ†1 : (ฮ  x : M, V x) โ†’ (ฮ  x, V' x) := fun X โ†ฆ ฯ† X ฯ„ + change ฯ†1 ฯƒ x = ฯ†1 ฯƒ' x + apply tensoriality_criterion I F V F' V' hฯƒ hฯƒ' hฯƒฯƒ' + exacts [fun f ฯƒ hf hฯƒ โ†ฆ ฯ†_smul hf hฯƒ, fun ฯƒ ฯƒ' hฯƒ hฯƒ' โ†ฆ ฯ†_add hฯƒ hฯƒ'] + ยท let ฯ†1 : (ฮ  x : M, V x) โ†’ (ฮ  x, V' x) := fun X โ†ฆ ฯ† ฯƒ' X + change ฯ†1 ฯ„ x = ฯ†1 ฯ„' x + apply tensoriality_criterion I F V F' V' hฯ„ hฯ„' hฯ„ฯ„' + exacts [fun f ฯ„ hf hฯ„ โ†ฆ ฯ„_smul hf hฯ„, fun ฯ„ ฯ„' hฯ„ hฯ„' โ†ฆ ฯ„_add hฯ„ hฯ„'] + +/- include I in +lemma tensoriality_criterion'' [FiberBundle F V] [VectorBundle โ„ F V] [FiniteDimensional โ„ E] + [FiniteDimensional โ„ F] [FiberBundle F' V'] [VectorBundle โ„ F' V'] [T2Space M] + {ฯ† : (ฮ  x : M, V x) โ†’ (ฮ  x, V' x)} {x} + {ฯƒ ฯƒ' : ฮ  x : M, V x} + {Pฯƒ : (ฮ  x : M, V x) โ†’ Prop} + {Pฯƒ_loc : โˆ€ ฯƒ ฯƒ', (โˆ€แถ  x' in ๐“ x, ฯƒ x' = ฯƒ' x') โ†’ Pฯƒ ฯƒ โ†’ Pฯƒ ฯƒ'} + (hฯƒ : Pฯƒ ฯƒ) + (hฯƒ' : Pฯƒ ฯƒ') + {Pf : (M โ†’ โ„) โ†’ Prop} + {Pf_loc : โˆ€ f f', (โˆ€แถ  x' in ๐“ x, f x' = f' x') โ†’ Pf f โ†’ Pf f'} + (Pf_smooth : โˆ€ f, MDifferentiableAt I ๐“˜(โ„) f x โ†’ Pf f) + (hฯƒฯƒ' : ฯƒ x = ฯƒ' x) + (ฯ†_smul : โˆ€ f : M โ†’ โ„, โˆ€ ฯƒ, Pf f โ†’ Pฯƒ ฯƒ โ†’ ฯ† (f โ€ข ฯƒ) x = f x โ€ข ฯ† ฯƒ x) + (ฯ†_add : โˆ€ ฯƒ ฯƒ', Pฯƒ ฯƒ โ†’ Pฯƒ ฯƒ โ†’ ฯ† (ฯƒ + ฯƒ') x = ฯ† ฯƒ x + ฯ† ฯƒ' x) : ฯ† ฯƒ x = ฯ† ฯƒ' x := by + have locality {ฯƒ ฯƒ'} (hฯƒฯƒ' : โˆ€แถ  x' in ๐“ x, ฯƒ x' = ฯƒ' x') : + ฯ† ฯƒ x = ฯ† ฯƒ' x := by + obtain โŸจฯˆ, _, hฯˆโŸฉ := (SmoothBumpFunction.nhds_basis_support (I := I) hฯƒฯƒ').mem_iff.1 hฯƒฯƒ' + have (x : M) : ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x = ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by + by_cases h : ฯƒ x = ฯƒ' x + ยท rw [Pi.smul_apply', Pi.smul_apply', h] + ยท simp [notMem_support.mp fun a โ†ฆ h (hฯˆ a)] + calc ฯ† ฯƒ x + _ = ฯ† ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ) x := by simp [ฯ†_smul] + _ = ฯ† ((ฯˆ : M โ†’ โ„) โ€ข ฯƒ') x := by rw [funext this] + _ = ฯ† ฯƒ' x := by simp [ฯ†_smul] + let ฮน : Type _ := Basis.ofVectorSpaceIndex โ„ F + classical + have sum_phi {s : Finset ฮน} (ฯƒ : ฮน โ†’ ฮ  x : M, V x) : + ฯ† (fun x' โ†ฆ โˆ‘ i โˆˆ s, ฯƒ i x') x = โˆ‘ i โˆˆ s, ฯ† (ฯƒ i) x := by + induction s using Finset.induction_on with + | empty => + simp only [Finset.sum_empty] + rw [show (fun x' : M โ†ฆ (0 : V x')) = (0 : M โ†’ โ„) โ€ข fun x' โ†ฆ 0 by simp;rfl, ฯ†_smul] + simp + | insert a s ha h => + change ฯ† (fun x' : M โ†ฆ โˆ‘ i โˆˆ (insert a s : Finset ฮน), ฯƒ i x') x = _ + simp [Finset.sum_insert ha, Finset.sum_insert ha, โ† h] + erw [ฯ†_add] + have x_mem := (FiberBundle.mem_baseSet_trivializationAt F V x) + let b := Basis.ofVectorSpace โ„ F + let t := trivializationAt F V x + let s := b.localFrame (trivializationAt F V x) + let c := Basis.localFrame_coeff t b + rw [locality (b.localFrame_eventually_eq_sum_coeff_smul x_mem ฯƒ), + locality (b.localFrame_eventually_eq_sum_coeff_smul x_mem ฯƒ'), sum_phi, sum_phi] + change โˆ‘ i, ฯ† ((c i ฯƒ) โ€ข (s i)) x = โˆ‘ i, ฯ† ((c i ฯƒ') โ€ข (s i)) x + congr + ext i + rw [ฯ†_smul, ฯ†_smul] + congr + apply b.localFrame_coeff_congr + assumption + -/ diff --git a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean index 818e52d1557644..766e8dabaf7713 100644 --- a/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean +++ b/Mathlib/Geometry/Manifold/VectorField/LieBracket.lean @@ -314,14 +314,200 @@ lemma _root_.MDifferentiableWithinAt.differentiableWithinAt_mpullbackWithin_vect exact ((contMDiff_snd_tangentBundle_modelSpace E ๐“˜(๐•œ, E)).contMDiffAt.mdifferentiableAt one_ne_zero).comp_mdifferentiableWithinAt _ this +variable (W x) in +omit [CompleteSpace E] in +lemma aux_computation : + (mfderiv I ๐“˜(๐•œ, E) (extChartAt I x) x).inverse + ((mfderivWithin ๐“˜(๐•œ, E) I ((extChartAt I x).symm) (range I) ((extChartAt I x) x)).inverse + (W ((extChartAt I x).symm ((extChartAt I x) x)))) + = W x := by + set ฯ† := extChartAt I x + set x' := (extChartAt I x) x + rw [extChartAt_to_inv x] + calc + _ = ((mfderiv I ๐“˜(๐•œ, E) ฯ† x).inverse.comp + (mfderivWithin ๐“˜(๐•œ, E) I ฯ†.symm (range I) x').inverse) (W x) := rfl + _ = (ContinuousLinearMap.id ๐•œ _) (W x) := by + congr + rw [โ† ContinuousLinearMap.IsInvertible.inverse_comp_of_left, + โ† ContinuousLinearMap.inverse_id, + mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt' (mem_extChartAt_source x)] + ยท rfl + exact isInvertible_mfderivWithin_extChartAt_symm (mem_extChartAt_target x) + _ = W x := by simp + +-- does this version suffice for my purposes below? +variable (x V) in +omit [CompleteSpace E] in +lemma aux_computation2' : + letI ฯ† := extChartAt I x + (mfderivWithin ๐“˜(๐•œ, E) I ฯ†.symm ฯ†.target (ฯ† x)).inverse (V x) = V x := by + set ฯ† := extChartAt I x + set x' := (extChartAt I x) x + have : mfderivWithin ๐“˜(๐•œ, E) I ฯ†.symm ฯ†.target (ฯ† x) = ContinuousLinearMap.id ๐•œ _ := by + rw [mfderivWithin] + have : MDifferentiableWithinAt ๐“˜(๐•œ, E) I ฯ†.symm ฯ†.target (ฯ† x) := by + have := mdifferentiableWithinAt_extChartAt_symm (I := I) (mem_extChartAt_target x) + exact this.mono (extChartAt_target_subset_range x) + simp only [this, โ†“reduceIte, writtenInExtChartAt, extChartAt, OpenPartialHomeomorph.extend, + PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, + OpenPartialHomeomorph.toFun_eq_coe, modelWithCornersSelf_coe, range_id, inter_univ] + rw [extChartAt_to_inv x, โ† extChartAt_coe] + -- debug why this line is needed! + change fderivWithin ๐•œ (โ†‘(extChartAt I x) โˆ˜ โ†‘ฯ†.symm) (extChartAt I x).target (ฯ† x) = _ + have : fderivWithin ๐•œ (ฯ† โˆ˜ ฯ†.symm) (extChartAt I x).target (ฯ† x) = + fderivWithin ๐•œ id (extChartAt I x).target (ฯ† x) := + fderivWithin_congr' (fun x' hx' โ†ฆ PartialEquiv.right_inv ฯ† hx') (mem_extChartAt_target x) + rw [this] + exact fderivWithin_id (uniqueDiffWithinAt_extChartAt_target x) + rw [this] + erw [ContinuousLinearMap.inverse_id] + rfl + +set_option backward.isDefEq.respectTransparency false in +variable (x V) in +omit [CompleteSpace E] in +lemma aux_computation2 : + letI ฯ† := extChartAt I x + (mfderivWithin ๐“˜(๐•œ, E) I ฯ†.symm (range I) (ฯ† x)).inverse (V x) = V x := by + set ฯ† := extChartAt I x + set x' := (extChartAt I x) x + -- this is almost true: it is true within a smaller set (namely extChartAt I x).target... + have : mfderivWithin ๐“˜(๐•œ, E) I ฯ†.symm (range I) (ฯ† x) = ContinuousLinearMap.id ๐•œ _ := by + rw [mfderivWithin] + have : MDifferentiableWithinAt ๐“˜(๐•œ, E) I (โ†‘ฯ†.symm) (range โ†‘I) (ฯ† x) := + mdifferentiableWithinAt_extChartAt_symm (mem_extChartAt_target x) + simp only [this, โ†“reduceIte, writtenInExtChartAt, extChartAt, OpenPartialHomeomorph.extend, + PartialEquiv.coe_trans, ModelWithCorners.toPartialEquiv_coe, + OpenPartialHomeomorph.toFun_eq_coe, OpenPartialHomeomorph.refl_partialEquiv, + PartialEquiv.refl_source, OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, + modelWithCornersSelf_partialEquiv, PartialEquiv.trans_refl, PartialEquiv.refl_symm, + PartialEquiv.refl_coe, CompTriple.comp_eq, preimage_id_eq, id_eq, modelWithCornersSelf_coe, + range_id, inter_univ] + rw [extChartAt_to_inv x, โ† extChartAt_coe] + have : fderivWithin ๐•œ (ฯ† โˆ˜ ฯ†.symm) (range I) (ฯ† x) = fderivWithin ๐•œ id (range I) (ฯ† x) := by + refine fderivWithin_congr' ?_ ?_ + ยท intro x' hx' + simp only [comp_apply, id_eq] + refine PartialEquiv.right_inv ฯ† ?_ + rw [extChartAt_target] + refine โŸจ?_, hx'โŸฉ + rw [mem_preimage] -- not necessarily true, though... + sorry + ยท sorry + rw [this] + exact fderivWithin_id <| I.uniqueDiffOn.uniqueDiffWithinAt (mem_range_self _) + rw [this, ContinuousLinearMap.inverse_id] + exact rfl + +set_option backward.isDefEq.respectTransparency false in +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M โ†’ ๐•œ`, we have `[V, f โ€ข W] = (df V) โ€ข W + f โ€ข [V, W]`. Version within a set. +-/ +lemma mlieBracketWithin_smul_right {f : M โ†’ ๐•œ} (hf : MDifferentiableWithinAt I ๐“˜(๐•œ) f s x) + (hW : MDifferentiableWithinAt I I.tangent (fun x โ†ฆ (W x : TangentBundle I M)) s x) + (hs : UniqueMDiffWithinAt I s x) : + mlieBracketWithin I V (f โ€ข W) s x = + (mfderivWithin I ๐“˜(๐•œ) f s x) (V x) โ€ข (W x) + (f x) โ€ข mlieBracketWithin I V W s x := by + simp only [mlieBracketWithin] + rw [mpullbackWithin_smul] + -- Simplify local notation a bit. + set V' := mpullbackWithin ๐“˜(๐•œ, E) I (extChartAt I x).symm V (range I) + set W' := mpullbackWithin ๐“˜(๐•œ, E) I (extChartAt I x).symm W (range I) + set f' := f โˆ˜ (extChartAt I x).symm + set s' := (extChartAt I x).symm โปยน' s โˆฉ range I + set x' := (extChartAt I x) x + change mpullback I ๐“˜(๐•œ, E) ((extChartAt I x)) (lieBracketWithin ๐•œ V' (fun y โ†ฆ f' y โ€ข W' y) s') x = + (mfderivWithin I ๐“˜(๐•œ, ๐•œ) f s x) (V x) โ€ข W x + + f x โ€ข mpullback I ๐“˜(๐•œ, E) ((extChartAt I x)) (lieBracketWithin ๐•œ V' W' s') x + -- Step 1: rewrite using lieBracketWithin_smul_right + have hf' : DifferentiableWithinAt ๐•œ f' s' x' := by + -- Is this worth a separate lemma? + obtain โŸจ_, hfโŸฉ := mdifferentiableWithinAt_iff.mp hf + rwa [extChartAt_self_eq] at hf + let aux := lieBracketWithin_smul_right (V := V') hf' + hW.differentiableWithinAt_mpullbackWithin_vectorField hs + -- rw [โ† Pi.smul_def'] + -- We need the cast, since on the nose `B` is a map `E โ†’ E`, + -- while we need a map between tangent spaces. + let A (xโ‚€) := (fderivWithin ๐•œ f' s' xโ‚€) (V' xโ‚€) โ€ข W' xโ‚€ + let B (xโ‚€) : TangentSpace ๐“˜(๐•œ, E) xโ‚€ := f' xโ‚€ โ€ข lieBracketWithin ๐•œ V' W' s' xโ‚€ + trans mpullback I ๐“˜(๐•œ, E) ((extChartAt I x)) (fun y โ†ฆ A y + B y) x + ยท simp only [mpullback_apply] + congr + -- We prove the equality of each summand separately. + rw [โ† Pi.add_def, mpullback_add_apply]; congr; swap + ยท simp [B, โ† Pi.smul_def', mpullback_smul (V := lieBracketWithin ๐•œ V' W' s'), f'] + -- This part is still TODO/ in progress!! + unfold A + simp only [mpullback, extChartAt.eq_1, OpenPartialHomeomorph.extend.eq_1, PartialEquiv.coe_trans, + ModelWithCorners.toPartialEquiv_coe, OpenPartialHomeomorph.toFun_eq_coe, comp_apply, extChartAt, + OpenPartialHomeomorph.extend, map_smul, mfderivWithin, hf, โ†“reduceIte, writtenInExtChartAt, + OpenPartialHomeomorph.refl_partialEquiv, PartialEquiv.refl_source, + OpenPartialHomeomorph.singletonChartedSpace_chartAt_eq, modelWithCornersSelf_partialEquiv, + PartialEquiv.trans_refl, PartialEquiv.refl_coe, PartialEquiv.coe_trans_symm, + OpenPartialHomeomorph.coe_coe_symm, ModelWithCorners.toPartialEquiv_coe_symm, + CompTriple.comp_eq] + have cleanup1 : I ((chartAt H x) x) = x' := rfl + have cleanup2 : f โˆ˜ (chartAt H x).symm โˆ˜ I.symm = f' := rfl + rw [cleanup1, cleanup2, โ† aux_computation x W] + congr -- congr 1 is less strong + -- This statement is not fully true, but I only need a weaker version... + -- if V' x' is a tangent vector within s, i.e. my aux_computation' should suffice! + -- Make this intuition hunch rigorous! + have : V' x' = V x := by + simp only [V', x', mpullbackWithin] + rw [extChartAt_to_inv x] + exact aux_computation2 x V + exact this + +set_option backward.isDefEq.respectTransparency false in +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M โ†’ ๐•œ`, we have `[V, f โ€ข W] = (df V) โ€ข W + f โ€ข [V, W]`. +-/ +lemma mlieBracket_smul_right {f : M โ†’ ๐•œ} (hf : MDifferentiableAt I ๐“˜(๐•œ) f x) + (hW : MDifferentiableAt I I.tangent (fun x โ†ฆ (W x : TangentBundle I M)) x) : + mlieBracket I V (f โ€ข W) x = + (mfderiv I ๐“˜(๐•œ) 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] + exact mlieBracketWithin_smul_right hf hW (uniqueMDiffWithinAt_univ I) + +set_option backward.isDefEq.respectTransparency false in +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M โ†’ ๐•œ`, we have `[f โ€ข V, W] = -(df W) โ€ข V + f โ€ข [V, W]`. Version within a set. +-/ +lemma mlieBracketWithin_smul_left {f : M โ†’ ๐•œ} (hf : MDifferentiableWithinAt I ๐“˜(๐•œ) f s x) + (hV : MDifferentiableWithinAt I I.tangent (fun x โ†ฆ (V x : TangentBundle I M)) s x) + (hs : UniqueMDiffWithinAt I s x) : + mlieBracketWithin I (f โ€ข V) W s x = + -(mfderivWithin I ๐“˜(๐•œ) f s 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 + +set_option backward.isDefEq.respectTransparency false in +/-- +Product rule for Lie brackets: given two vector fields `V` and `W` on `M` and a function +`f : M โ†’ ๐•œ`, we have `[f โ€ข V, W] = -(df W) โ€ข V + f โ€ข [V, W]`. +-/ +lemma mlieBracket_smul_left {f : M โ†’ ๐•œ} (hf : MDifferentiableAt I ๐“˜(๐•œ) f x) + (hV : MDifferentiableAt I I.tangent (fun x โ†ฆ (V x : TangentBundle I M)) x) : + mlieBracket I (f โ€ข V) W x = + -(mfderiv I ๐“˜(๐•œ) 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] + exact mlieBracketWithin_smul_left hf hV (uniqueMDiffWithinAt_univ I) + set_option backward.isDefEq.respectTransparency false in 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 - simp only [mlieBracketWithin_apply] - rw [โ† map_smul, mpullbackWithin_smul, lieBracketWithin_const_smul_left] - ยท exact hV.differentiableWithinAt_mpullbackWithin_vectorField - ยท exact uniqueMDiffWithinAt_iff_inter_range.1 hs + have aux := mlieBracketWithin_smul_left (mdifferentiableWithinAt_const (c := c)) (W := W) hV hs + simpa [mfderivWithin_const] using aux lemma mlieBracket_const_smul_left (hV : MDiffAt (T% V) x) : mlieBracket I (c โ€ข V) W x = c โ€ข mlieBracket I V W x := by @@ -332,10 +518,8 @@ set_option backward.isDefEq.respectTransparency false in 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 - simp only [mlieBracketWithin_apply] - rw [โ† map_smul, mpullbackWithin_smul, lieBracketWithin_const_smul_right] - ยท exact hW.differentiableWithinAt_mpullbackWithin_vectorField - ยท exact uniqueMDiffWithinAt_iff_inter_range.1 hs + have aux := mlieBracketWithin_smul_right (mdifferentiableWithinAt_const (c := c)) (V := V) hW hs + simpa [mfderivWithin_const] using aux lemma mlieBracket_const_smul_right (hW : MDiffAt (T% W) x) : mlieBracket I V (c โ€ข W) x = c โ€ข mlieBracket I V W x := by diff --git a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean index 7aa48da602a394..88351e95ab0cfb 100644 --- a/Mathlib/Geometry/Manifold/VectorField/Pullback.lean +++ b/Mathlib/Geometry/Manifold/VectorField/Pullback.lean @@ -109,15 +109,23 @@ def mpullback (f : M โ†’ M') (V : ฮ  (x : M'), TangentSpace I' x) (x : M) : lemma mpullbackWithin_apply : mpullbackWithin I I' f V s x = (mfderivWithin I I' f s x).inverse (V (f x)) := rfl -lemma mpullbackWithin_smul_apply : +lemma mpullbackWithin_const_smul_apply : mpullbackWithin I I' f (c โ€ข V) s x = c โ€ข mpullbackWithin I I' f V s x := by simp [mpullbackWithin_apply] -lemma mpullbackWithin_smul : +lemma mpullbackWithin_smul_apply {g : M' โ†’ ๐•œ} : + mpullbackWithin I I' f (g โ€ข V) s x = g (f x) โ€ข mpullbackWithin I I' f V s x := by + simp [mpullbackWithin_apply] + +lemma mpullbackWithin_const_smul : mpullbackWithin I I' f (c โ€ข V) s = c โ€ข mpullbackWithin I I' f V s := by ext x simp [mpullbackWithin_apply] +lemma mpullbackWithin_smul {g : M' โ†’ ๐•œ} : + mpullbackWithin I I' f (g โ€ข V) s = (g โˆ˜ f) โ€ข mpullbackWithin I I' f V s := by + ext; simp [mpullbackWithin_apply] + lemma mpullbackWithin_add_apply : mpullbackWithin I I' f (V + Vโ‚) s x = mpullbackWithin I I' f V s x + mpullbackWithin I I' f Vโ‚ s x := by @@ -151,15 +159,24 @@ lemma mpullbackWithin_id {V : ฮ  (x : M), TangentSpace I x} (h : UniqueMDiffWith lemma mpullback_apply : mpullback I I' f V x = (mfderiv I I' f x).inverse (V (f x)) := rfl -lemma mpullback_smul_apply : +lemma mpullback_const_smul_apply : mpullback I I' f (c โ€ข V) x = c โ€ข mpullback I I' f V x := by simp [mpullback] -lemma mpullback_smul : +lemma mpullback_const_smul : mpullback I I' f (c โ€ข V) = c โ€ข mpullback I I' f V := by ext x simp [mpullback_apply] +lemma mpullback_smul_apply {g : M' โ†’ ๐•œ} : + mpullback I I' f (g โ€ข V) x = g (f x) โ€ข mpullback I I' f V x := by + simp [mpullback] + +lemma mpullback_smul {g : M' โ†’ ๐•œ} : + mpullback I I' f (g โ€ข V) = (g โˆ˜ f) โ€ข mpullback I I' f V := by + ext x + simp [mpullback_apply] + lemma mpullback_add_apply : mpullback I I' f (V + Vโ‚) x = mpullback I I' f V x + mpullback I I' f Vโ‚ x := by simp [mpullback_apply]