diff --git a/LeanPool/LCAnalysis.lean b/LeanPool/LCAnalysis.lean new file mode 100644 index 0000000000..7fa4acc5fc --- /dev/null +++ b/LeanPool/LCAnalysis.lean @@ -0,0 +1,24 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import LeanPool.LCAnalysis.BoundedBelow +public import LeanPool.LCAnalysis.MackeyLipschitz +public import LeanPool.LCAnalysis.Rules + +/-! +# Michal–Bastiani Calculus on Locally Convex Spaces + +Source: arxiv:2602.12362, url:https://github.com/glaroton/LCAnalysis +Authors: Gabriel Larotonda +Status: verified +Main declarations: `LCAnalysis.ContDiffMBOn.comp`, + `LCAnalysis.ContDiffMBOn.exists_iteratedDMB_multilinear`, `LCAnalysis.smoothMBOn_iff_contDiffOn`, + `LCAnalysis.exists_hasWeakIntegral`, `LCAnalysis.mackeyComplete_iff_integratesLipschitzCurves`, + `LCAnalysis.ContDiffMBOn.of_comp_of_boundedBelow` +Tags: functional-analysis, locally-convex-spaces, calculus, weak-integrals +MSC: 46T20, 46A03, 58B10 +-/ diff --git a/LeanPool/LCAnalysis/BoundedBelow.lean b/LeanPool/LCAnalysis/BoundedBelow.lean new file mode 100644 index 0000000000..193b3aafa8 --- /dev/null +++ b/LeanPool/LCAnalysis/BoundedBelow.lean @@ -0,0 +1,397 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import Mathlib.Analysis.Calculus.ContDiff.RCLike + +public import LeanPool.LCAnalysis.MBFrechet +public import LeanPool.LCAnalysis.Higher + +/-! +# Maps with bounded below derivative reflect smoothness + +Let `j : E → F` be a smooth map from a Banach space `E` (complete) to a normed space `F` +(complete or not) whose derivative is bounded below on an +open set `U`: `m ‖v‖ ≤ ‖dj(x) v‖` for `x ∈ U`. No complement of the range of `dj(x)` is +assumed. Then `j` reflects smoothness of continuous maps: if `γ : W → U` is continuous on an open +subset `W` of a locally convex space and `j ∘ γ` is `C^k` in the sense of Michal–Bastiani, then so +is `γ` (`ContDiffMBOn.of_comp_of_boundedBelow`). + +The proof bootstraps a linear version (`ContDiffMBOn.of_fderiv_eq_of_boundedBelow`): if +`dj(γ q)(z q) = w q` with `γ, w` of class `C^k` and `z` continuous, then `z` is `C^k`. The +derivative of `z` is obtained as a limit of difference quotients, which are Cauchy because +`dj(γ q)` is bounded below and `E` is complete. + +**Subtleties.** + +* The Michal–Bastiani definition gives joint continuity of `(x, v) ↦ dj(x) v`, not continuity + of `x ↦ dj(x)` in the operator norm. The proof needs the latter, to keep the lower bound near a + point. For normed spaces it follows from Michal–Bastiani `C^{k+1}` ⇒ Fréchet `C^k` + (`ContDiffMBOn.contDiffOn`). For Fréchet or more general locally convex models the result is + open. +* The test domain `W` may be any open subset of a locally convex space: only lines through its + points are used to differentiate, and joint continuity comes from the lower bound. +-/ + +@[expose] public section + +open Set Filter Function +open scoped Topology NNReal ContDiff + +noncomputable section + +namespace LCAnalysis + +universe u v w + +/-! ### Normed preliminaries -/ + +section Normed + +variable {E : Type v} [NormedAddCommGroup E] [NormedSpace ℝ E] + {F : Type w} [NormedAddCommGroup F] [NormedSpace ℝ F] + +/-- If `A` is bounded below and `A z_t → R`, then `z_t` converges to a solution of `A D = R`. -/ +theorem exists_tendsto_of_boundedBelow [CompleteSpace E] {A : E →L[ℝ] F} {m : ℝ} (hm : 0 < m) + (hA : ∀ v, m * ‖v‖ ≤ ‖A v‖) {ι : Type*} {l : Filter ι} [l.NeBot] {z : ι → E} {R : F} + (h : Tendsto (fun i ↦ A (z i)) l (𝓝 R)) : ∃ D, Tendsto z l (𝓝 D) ∧ A D = R := by + have hanti : AntilipschitzWith (Real.toNNReal m⁻¹) A := by + refine A.antilipschitz_of_bound fun v ↦ ?_ + rw [Real.coe_toNNReal _ (inv_nonneg.mpr hm.le)] + calc ‖v‖ = m⁻¹ * (m * ‖v‖) := by field_simp + _ ≤ m⁻¹ * ‖A v‖ := by gcongr; exact hA v + have hui := hanti.isUniformInducing A.uniformContinuous + have hc : Cauchy (map z l) := by + rw [← hui.cauchy_map_iff, map_map] + exact h.cauchy_map + obtain ⟨D, hD⟩ := CompleteSpace.complete hc + refine ⟨D, hD, ?_⟩ + exact tendsto_nhds_unique ((A.continuous.tendsto D).comp hD) h + +/-- Solutions of `A(q) z(q) = r(q)` are continuous when `A` is continuous in the operator norm +and uniformly bounded below, and `r` is continuous. -/ +theorem continuousOn_of_boundedBelow {X : Type*} [TopologicalSpace X] {W : Set X} + {A : X → E →L[ℝ] F} (hA : ContinuousOn A W) {m : ℝ} (hm : 0 < m) + (hbd : ∀ q ∈ W, ∀ v, m * ‖v‖ ≤ ‖A q v‖) {z : X → E} {r : X → F} (hr : ContinuousOn r W) + (heq : ∀ q ∈ W, A q (z q) = r q) : ContinuousOn z W := by + intro q hq + rw [ContinuousWithinAt, tendsto_iff_norm_sub_tendsto_zero] + -- `‖z q' - z q‖ ≤ m⁻¹ ‖(r q' - r q) - (A q' - A q)(z q)‖` + have hlim : Tendsto (fun q' ↦ m⁻¹ * ‖(r q' - r q) - (A q' - A q) (z q)‖) (𝓝[W] q) (𝓝 0) := by + have h1 : Tendsto (fun q' ↦ (r q' - r q) - (A q' - A q) (z q)) (𝓝[W] q) (𝓝 0) := by + have hr' : Tendsto (fun q' ↦ r q' - r q) (𝓝[W] q) (𝓝 0) := by + simpa using (hr q hq).sub_const (r q) + have h0 : Tendsto (fun q' ↦ A q' - A q) (𝓝[W] q) (𝓝 0) := by + simpa using (hA q hq).sub_const (A q) + have hA' : Tendsto (fun q' ↦ (A q' - A q) (z q)) (𝓝[W] q) (𝓝 0) := by + have := ((ContinuousLinearMap.apply ℝ F (z q)).continuous.tendsto 0).comp h0 + simp only [map_zero] at this + exact this + simpa using hr'.sub hA' + simpa using (h1.norm.const_mul m⁻¹) + refine squeeze_zero' (Eventually.of_forall fun _ ↦ norm_nonneg _) ?_ hlim + filter_upwards [self_mem_nhdsWithin] with q' hq' + have h := hbd q' hq' (z q' - z q) + have e : A q' (z q' - z q) = (r q' - r q) - (A q' - A q) (z q) := by + rw [map_sub, heq q' hq', sub_apply, heq q hq] + abel + rw [e] at h + calc ‖z q' - z q‖ = m⁻¹ * (m * ‖z q' - z q‖) := by field_simp + _ ≤ m⁻¹ * ‖(r q' - r q) - (A q' - A q) (z q)‖ := by gcongr + +/-- A continuous linear map between normed spaces which is a topological embedding is bounded +below. -/ +theorem exists_boundedBelow_of_isEmbedding {L : E →L[ℝ] F} (hL : Topology.IsEmbedding L) : + ∃ m > 0, ∀ v, m * ‖v‖ ≤ ‖L v‖ := by + have hball : Metric.ball (0 : E) 1 ∈ 𝓝 (0 : E) := Metric.ball_mem_nhds 0 one_pos + rw [hL.isInducing.nhds_eq_comap, map_zero] at hball + obtain ⟨t, ht, hts⟩ := hball + obtain ⟨δ, hδ, hδt⟩ := Metric.mem_nhds_iff.mp ht + have key : ∀ v, ‖L v‖ < δ → ‖v‖ < 1 := fun v hv ↦ by + have := hts (hδt (by simpa using hv)) + simpa using this + refine ⟨δ / 2, by positivity, fun v ↦ ?_⟩ + by_cases hv : L v = 0 + · have : v = 0 := hL.injective (by rw [hv, map_zero]) + simp [this] + · have hLv : 0 < ‖L v‖ := norm_pos_iff.mpr hv + set c := δ / (2 * ‖L v‖) with hcdef + have hc : 0 < c := by positivity + have h1 : ‖L (c • v)‖ < δ := by + rw [map_smul, norm_smul, Real.norm_of_nonneg hc.le] + have : c * ‖L v‖ = δ / 2 := by rw [hcdef]; field_simp + linarith + have h2 := key _ h1 + rw [norm_smul, Real.norm_of_nonneg hc.le] at h2 + have : δ / 2 * ‖v‖ = c * ‖v‖ * ‖L v‖ := by rw [hcdef]; field_simp + rw [this] + nlinarith [norm_nonneg v] + +/-- The lower bound of the derivative propagates to a neighborhood. -/ +theorem exists_nhds_boundedBelow {j : E → F} {U : Set E} (hU : IsOpen U) + (hj : ContinuousOn (fderiv ℝ j) U) {x₀ : E} (hx₀ : x₀ ∈ U) {m : ℝ} (hm : 0 < m) + (hbd : ∀ v, m * ‖v‖ ≤ ‖fderiv ℝ j x₀ v‖) : + ∃ V ⊆ U, IsOpen V ∧ Convex ℝ V ∧ x₀ ∈ V ∧ ∀ x ∈ V, ∀ v, m / 2 * ‖v‖ ≤ ‖fderiv ℝ j x v‖ := by + have hc := hj.continuousAt (hU.mem_nhds hx₀) + obtain ⟨δ, hδ, hball⟩ := Metric.mem_nhds_iff.mp + (hc (Metric.ball_mem_nhds (fderiv ℝ j x₀) (half_pos hm))) + obtain ⟨ε, hε, hεU⟩ := Metric.isOpen_iff.mp hU x₀ hx₀ + refine ⟨Metric.ball x₀ (min δ ε), (Metric.ball_subset_ball (min_le_right _ _)).trans hεU, + Metric.isOpen_ball, convex_ball _ _, Metric.mem_ball_self (lt_min hδ hε), fun x hx v ↦ ?_⟩ + have hx' : fderiv ℝ j x ∈ Metric.ball (fderiv ℝ j x₀) (m / 2) := + hball (Metric.ball_subset_ball (min_le_left _ _) hx) + rw [Metric.mem_ball, dist_eq_norm] at hx' + have h1 : ‖(fderiv ℝ j x - fderiv ℝ j x₀) v‖ ≤ m / 2 * ‖v‖ := + ((fderiv ℝ j x - fderiv ℝ j x₀).le_opNorm v).trans (by gcongr) + have h2 : ‖fderiv ℝ j x₀ v‖ ≤ ‖fderiv ℝ j x v‖ + ‖(fderiv ℝ j x - fderiv ℝ j x₀) v‖ := by + calc ‖fderiv ℝ j x₀ v‖ = ‖fderiv ℝ j x v - (fderiv ℝ j x - fderiv ℝ j x₀) v‖ := by + rw [sub_apply, sub_sub_cancel] + _ ≤ _ := norm_sub_le _ _ + linarith [hbd v] + +end Normed + +/-! ### Bootstrapping -/ + +section Bootstrap + +variable {E : Type v} [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] + {F : Type w} [NormedAddCommGroup F] [NormedSpace ℝ F] {j : E → F} {U : Set E} + +omit [CompleteSpace E] in +/-- A directional derivative into a normed space is the derivative of the line. -/ +theorem hasDerivAt_line_of_hasDirDerivAt {H : Type u} [AddCommGroup H] [Module ℝ H] + {γ : H → E} {q h : H} {y : E} (hγ : HasDirDerivAt γ q h y) : + HasDerivAt (fun t : ℝ ↦ γ (q + t • h)) y 0 := by + rw [hasDerivAt_iff_tendsto_slope] + refine (show Tendsto (fun t : ℝ ↦ t⁻¹ • (γ (q + t • h) - γ q)) (𝓝[≠] 0) (𝓝 y) from hγ).congr + fun t ↦ ?_ + simp [slope_def_module] + +omit [CompleteSpace E] in +/-- The Fréchet derivatives of a Michal–Bastiani smooth map. -/ +theorem SmoothMBOn.fderiv_facts (hU : IsOpen U) (hj : SmoothMBOn j U) : + ContDiffOn ℝ ∞ j U ∧ ContDiffOn ℝ ∞ (fderiv ℝ j) U ∧ + SmoothMBOn (fun p : E × (E × E) ↦ fderiv ℝ (fderiv ℝ j) p.1 p.2.1 p.2.2) (U ×ˢ univ) := by + have hjF : ContDiffOn ℝ ∞ j U := (smoothMBOn_iff_contDiffOn hU).mp hj + have hD1 : ContDiffOn ℝ ∞ (fderiv ℝ j) U := hjF.fderiv_of_isOpen hU (by simp) + have hD2 : ContDiffOn ℝ ∞ (fderiv ℝ (fderiv ℝ j)) U := hD1.fderiv_of_isOpen hU (by simp) + refine ⟨hjF, hD1, ?_⟩ + rw [smoothMBOn_iff_contDiffOn (hU.prod isOpen_univ)] + have h1 : ContDiffOn ℝ ∞ (fun p : E × (E × E) ↦ fderiv ℝ (fderiv ℝ j) p.1) (U ×ˢ univ) := + hD2.comp contDiff_fst.contDiffOn fun p hp ↦ hp.1 + exact (h1.clm_apply (contDiff_fst.comp contDiff_snd).contDiffOn).clm_apply + (contDiff_snd.comp contDiff_snd).contDiffOn + +/-- **Linear bootstrap.** If `dj` is bounded below on `U` and `dj(γ q)(z q) = w q` on `W`, with +`γ` and `w` of class `C^k` and `z` continuous, then `z` is of class `C^k`. -/ +theorem ContDiffMBOn.of_fderiv_eq_of_boundedBelow (hU : IsOpen U) (hj : SmoothMBOn j U) + {m : ℝ} (hm : 0 < m) (hbd : ∀ x ∈ U, ∀ v, m * ‖v‖ ≤ ‖fderiv ℝ j x v‖) : + ∀ (k : ℕ) {H : Type u} [AddCommGroup H] [Module ℝ H] [TopologicalSpace H] + [IsTopologicalAddGroup H] [ContinuousSMul ℝ H] [LocallyConvexSpace ℝ H] [T2Space H] + {W : Set H} {γ z : H → E} {w : H → F}, IsOpen W → ContDiffMBOn k γ W → MapsTo γ W U → + ContinuousOn z W → ContDiffMBOn k w W → (∀ q ∈ W, fderiv ℝ j (γ q) (z q) = w q) → + ContDiffMBOn k z W := by + obtain ⟨-, hD1, hG⟩ := hj.fderiv_facts hU + have hcont : ContinuousOn (fderiv ℝ j) U := hD1.continuousOn + have hdiff : ∀ x ∈ U, HasFDerivAt (fderiv ℝ j) (fderiv ℝ (fderiv ℝ j) x) x := fun x hx ↦ + ((hD1.contDiffAt (hU.mem_nhds hx)).differentiableAt (by simp)).hasFDerivAt + intro k + induction k with + | zero => + intro H _ _ _ _ _ _ _ W γ z w hW hγ hγU hz hw heq + exact hz + | succ k ih => + intro H _ _ _ _ _ _ _ W γ z w hW hγ hγU hz hw heq + have hzk : ContDiffMBOn k z W := ih hW hγ.of_succ hγU hz hw.of_succ heq + have hγ1 : ContDiffMBOn 1 γ W := hγ.of_le (by omega) + have hw1 : ContDiffMBOn 1 w W := hw.of_le (by omega) + -- the derivative of `z`, as a limit of difference quotients + have hder : ∀ q ∈ W, ∀ h : H, ∃ D : E, HasDirDerivAt z q h D ∧ + fderiv ℝ j (γ q) D = + dMB w (q, h) - fderiv ℝ (fderiv ℝ j) (γ q) (dMB γ (q, h)) (z q) := by + intro q hq h + have hγq := hγU hq + have hline : Tendsto (fun t : ℝ ↦ q + t • h) (𝓝[≠] 0) (𝓝 q) := by + have : Continuous fun t : ℝ ↦ q + t • h := by fun_prop + simpa using (this.tendsto 0).mono_left nhdsWithin_le_nhds + have hev : ∀ᶠ t in 𝓝[≠] (0 : ℝ), q + t • h ∈ W := hline (hW.mem_nhds hq) + have hcurve := hasDerivAt_line_of_hasDirDerivAt (hγ1.hasDirDerivAt hq h) + have hAline : HasDerivAt (fun t : ℝ ↦ fderiv ℝ j (γ (q + t • h))) + (fderiv ℝ (fderiv ℝ j) (γ q) (dMB γ (q, h))) 0 := by + have h1 : HasFDerivAt (fderiv ℝ j) (fderiv ℝ (fderiv ℝ j) (γ q)) + (γ (q + (0 : ℝ) • h)) := by simpa using hdiff _ hγq + simpa [Function.comp_def] using h1.comp_hasDerivAt (0 : ℝ) hcurve + have hAslope : Tendsto (fun t : ℝ ↦ t⁻¹ • (fderiv ℝ j (γ (q + t • h)) - fderiv ℝ j (γ q))) + (𝓝[≠] 0) (𝓝 (fderiv ℝ (fderiv ℝ j) (γ q) (dMB γ (q, h)))) := by + simpa using hAline.tendsto_slope_zero + have hzline : Tendsto (fun t : ℝ ↦ z (q + t • h)) (𝓝[≠] 0) (𝓝 (z q)) := + ((hz.continuousAt (hW.mem_nhds hq)).tendsto).comp hline + have hwline : Tendsto (fun t : ℝ ↦ t⁻¹ • (w (q + t • h) - w q)) (𝓝[≠] 0) + (𝓝 (dMB w (q, h))) := hw1.hasDirDerivAt hq h + have hprod : Tendsto (fun t : ℝ ↦ + (t⁻¹ • (fderiv ℝ j (γ (q + t • h)) - fderiv ℝ j (γ q))) (z (q + t • h))) (𝓝[≠] 0) + (𝓝 (fderiv ℝ (fderiv ℝ j) (γ q) (dMB γ (q, h)) (z q))) := + (isBoundedBilinearMap_apply.continuous.tendsto _).comp (hAslope.prodMk_nhds hzline) + have hkey : Tendsto (fun t : ℝ ↦ fderiv ℝ j (γ q) (t⁻¹ • (z (q + t • h) - z q))) (𝓝[≠] 0) + (𝓝 (dMB w (q, h) - fderiv ℝ (fderiv ℝ j) (γ q) (dMB γ (q, h)) (z q))) := by + refine (hwline.sub hprod).congr' ?_ + filter_upwards [hev] with t ht + simp only [map_smul, map_sub, smul_apply, sub_apply] + rw [← heq _ ht, ← heq q hq, ← smul_sub] + congr 1 + abel + obtain ⟨D, hD, hAD⟩ := exists_tendsto_of_boundedBelow hm (hbd _ hγq) hkey + exact ⟨D, hD, hAD⟩ + have hdz : ∀ p ∈ W ×ˢ (univ : Set H), fderiv ℝ j (γ p.1) (dMB z p) = + dMB w p - fderiv ℝ (fderiv ℝ j) (γ p.1) (dMB γ p) (z p.1) := by + rintro ⟨q, h⟩ ⟨hq, -⟩ + obtain ⟨D, hD, hAD⟩ := hder q hq h + rw [hD.dMB_eq] + exact hAD + -- the data of the induction step, on `W × H` + have hW2 : IsOpen (W ×ˢ (univ : Set H)) := hW.prod isOpen_univ + have hfst : ∀ (n : ℕ), ContDiffMBOn n (fun p : H × H ↦ p.1) (W ×ˢ univ) := fun n ↦ + (ContinuousLinearMap.fst ℝ H H).contDiffMBOn n _ + have hγfst : ContDiffMBOn k (fun p : H × H ↦ γ p.1) (W ×ˢ univ) := + ContDiffMBOn.comp (g := γ) (f := fun p : H × H ↦ p.1) hW2 hW hγ.of_succ (hfst k) + fun p hp ↦ hp.1 + have hzfst : ContDiffMBOn k (fun p : H × H ↦ z p.1) (W ×ˢ univ) := + ContDiffMBOn.comp (g := z) (f := fun p : H × H ↦ p.1) hW2 hW hzk (hfst k) fun p hp ↦ hp.1 + have hdγ : ContDiffMBOn k (dMB γ) (W ×ˢ univ) := hγ.2.2 + have hdw : ContDiffMBOn k (dMB w) (W ×ˢ univ) := hw.2.2 + have htriple : ContDiffMBOn k (fun p : H × H ↦ (γ p.1, (dMB γ p, z p.1))) (W ×ˢ univ) := + ContDiffMBOn.prodMk hW2 hγfst (ContDiffMBOn.prodMk hW2 hdγ hzfst) + have hGk : ContDiffMBOn k (fun p : H × H ↦ + fderiv ℝ (fderiv ℝ j) (γ p.1) (dMB γ p) (z p.1)) (W ×ˢ univ) := + ContDiffMBOn.comp (g := fun p : E × (E × E) ↦ fderiv ℝ (fderiv ℝ j) p.1 p.2.1 p.2.2) + (f := fun p : H × H ↦ (γ p.1, (dMB γ p, z p.1))) hW2 (hU.prod isOpen_univ) (hG k) + htriple fun p hp ↦ ⟨hγU hp.1, mem_univ _⟩ + have hw' : ContDiffMBOn k (fun p : H × H ↦ + dMB w p - fderiv ℝ (fderiv ℝ j) (γ p.1) (dMB γ p) (z p.1)) (W ×ˢ univ) := + ContDiffMBOn.comp (F₁ := F × F) hW2 isOpen_univ + ((ContinuousLinearMap.fst ℝ F F - ContinuousLinearMap.snd ℝ F F).contDiffMBOn k univ) + (ContDiffMBOn.prodMk hW2 hdw hGk) (mapsTo_univ _ _) + have hAc : ContinuousOn (fun p : H × H ↦ fderiv ℝ j (γ p.1)) (W ×ˢ univ) := + hcont.comp hγfst.continuousOn fun p hp ↦ hγU hp.1 + have hdzc : ContinuousOn (dMB z) (W ×ˢ univ) := + continuousOn_of_boundedBelow hAc hm (fun p hp ↦ hbd _ (hγU hp.1)) hw'.continuousOn hdz + have hdzk := ih hW2 hγfst (fun p hp ↦ hγU hp.1) hdzc hw' hdz + refine ⟨hz, fun q hq h ↦ ?_, hdzk⟩ + obtain ⟨D, hD, -⟩ := hder q hq h + rw [hD.dMB_eq] + exact hD + +/-- **Maps with bounded below derivative reflect smoothness.** If `dj` is bounded below on the +open set `U` and `γ : W → U` is continuous with `j ∘ γ` of class `C^k`, then `γ` is of class +`C^k`. -/ +theorem ContDiffMBOn.of_comp_of_boundedBelow (hU : IsOpen U) (hj : SmoothMBOn j U) + {m : ℝ} (hm : 0 < m) (hbd : ∀ x ∈ U, ∀ v, m * ‖v‖ ≤ ‖fderiv ℝ j x v‖) : + ∀ (k : ℕ) {H : Type u} [AddCommGroup H] [Module ℝ H] [TopologicalSpace H] + [IsTopologicalAddGroup H] [ContinuousSMul ℝ H] [LocallyConvexSpace ℝ H] [T2Space H] + {W : Set H} {γ : H → E}, IsOpen W → ContinuousOn γ W → MapsTo γ W U → + ContDiffMBOn k (j ∘ γ) W → ContDiffMBOn k γ W := by + obtain ⟨hjF, hD1, -⟩ := hj.fderiv_facts hU + have hcont : ContinuousOn (fderiv ℝ j) U := hD1.continuousOn + intro k + induction k with + | zero => + intro H _ _ _ _ _ _ _ W γ hW hγc hγU hjγ + exact hγc + | succ k ih => + intro H _ _ _ _ _ _ _ W γ hW hγc hγU hjγ + have hγk : ContDiffMBOn k γ W := ih hW hγc hγU hjγ.of_succ + have hjγ1 : ContDiffMBOn 1 (j ∘ γ) W := hjγ.of_le (by omega) + -- the derivative of `γ` + have hder : ∀ q ∈ W, ∀ h : H, ∃ D : E, HasDirDerivAt γ q h D ∧ + fderiv ℝ j (γ q) D = dMB (j ∘ γ) (q, h) := by + intro q hq h + have hγq := hγU hq + set A := fderiv ℝ j (γ q) + set R := dMB (j ∘ γ) (q, h) + have hline : Tendsto (fun t : ℝ ↦ q + t • h) (𝓝[≠] 0) (𝓝 q) := by + have : Continuous fun t : ℝ ↦ q + t • h := by fun_prop + simpa using (this.tendsto 0).mono_left nhdsWithin_le_nhds + have hγline : Tendsto (fun t : ℝ ↦ γ (q + t • h)) (𝓝[≠] 0) (𝓝 (γ q)) := + ((hγc.continuousAt (hW.mem_nhds hq)).tendsto).comp hline + have hpair : Tendsto (fun t : ℝ ↦ (γ (q + t • h), γ q)) (𝓝[≠] 0) (𝓝 (γ q, γ q)) := + hγline.prodMk_nhds tendsto_const_nhds + have ha : Tendsto (fun t : ℝ ↦ t⁻¹ • (j (γ (q + t • h)) - j (γ q))) (𝓝[≠] 0) (𝓝 R) := + hjγ1.hasDirDerivAt hq h + have hS : HasStrictFDerivAt j A (γ q) := + (hjF.contDiffAt (hU.mem_nhds hγq)).hasStrictFDerivAt (by simp) + have hlo := hasStrictFDerivAt_iff_isLittleO.mp hS + -- `A (γ_t) - a_t → 0`, where `γ_t, a_t` are the difference quotients + have hsmall : Tendsto (fun t : ℝ ↦ A (t⁻¹ • (γ (q + t • h) - γ q)) - + t⁻¹ • (j (γ (q + t • h)) - j (γ q))) (𝓝[≠] 0) (𝓝 0) := by + rw [Metric.tendsto_nhds] + intro η hη + set c := min (m / 2) (η * m / (4 * (‖R‖ + 1))) with hcdef + have hR1 : 0 < ‖R‖ + 1 := by positivity + have hc : 0 < c := lt_min (by positivity) (by positivity) + have hcm : c ≤ m / 2 := min_le_left _ _ + have hcη : c ≤ η * m / (4 * (‖R‖ + 1)) := min_le_right _ _ + have hb := hpair.eventually (hlo.bound hc) + have hR : ∀ᶠ t in 𝓝[≠] (0 : ℝ), ‖t⁻¹ • (j (γ (q + t • h)) - j (γ q))‖ < ‖R‖ + 1 := + ha.norm.eventually (gt_mem_nhds (lt_add_one _)) + filter_upwards [hb, hR] with t hbt hRt + set d := γ (q + t • h) - γ q + set a := t⁻¹ • (j (γ (q + t • h)) - j (γ q)) + -- `‖A (t⁻¹ d) - a‖ ≤ c ‖t⁻¹ d‖` + have he : ‖A (t⁻¹ • d) - a‖ ≤ c * ‖t⁻¹ • d‖ := by + have : A (t⁻¹ • d) - a = -(t⁻¹ • (j (γ (q + t • h)) - j (γ q) - A d)) := by + simp only [map_smul, a, smul_sub] + abel + rw [this, norm_neg, norm_smul, norm_smul] + calc ‖t⁻¹‖ * ‖j (γ (q + t • h)) - j (γ q) - A d‖ ≤ ‖t⁻¹‖ * (c * ‖d‖) := by + gcongr + _ = c * (‖t⁻¹‖ * ‖d‖) := by ring + -- `‖t⁻¹ d‖ ≤ (2 / m) ‖a‖` + have hz : ‖t⁻¹ • d‖ ≤ 2 / m * ‖a‖ := by + have h1 := hbd _ hγq (t⁻¹ • d) + have h2 : ‖A (t⁻¹ • d)‖ ≤ ‖a‖ + c * ‖t⁻¹ • d‖ := by + calc ‖A (t⁻¹ • d)‖ = ‖(A (t⁻¹ • d) - a) + a‖ := by rw [sub_add_cancel] + _ ≤ ‖A (t⁻¹ • d) - a‖ + ‖a‖ := norm_add_le _ _ + _ ≤ c * ‖t⁻¹ • d‖ + ‖a‖ := by gcongr + _ = ‖a‖ + c * ‖t⁻¹ • d‖ := by ring + rw [div_mul_eq_mul_div, le_div_iff₀ hm] + nlinarith [norm_nonneg (t⁻¹ • d), norm_nonneg a] + rw [dist_zero_right] + calc ‖A (t⁻¹ • d) - a‖ ≤ c * ‖t⁻¹ • d‖ := he + _ ≤ c * (2 / m * ‖a‖) := by gcongr + _ ≤ (η * m / (4 * (‖R‖ + 1))) * (2 / m * (‖R‖ + 1)) := by gcongr + _ = η / 2 := by field_simp; ring + _ < η := by linarith + have hkey : Tendsto (fun t : ℝ ↦ A (t⁻¹ • (γ (q + t • h) - γ q))) (𝓝[≠] 0) (𝓝 R) := by + have := hsmall.add ha + simpa using this + obtain ⟨D, hD, hAD⟩ := exists_tendsto_of_boundedBelow hm (hbd _ hγq) hkey + exact ⟨D, hD, hAD⟩ + -- the derivative satisfies a linear equation; bootstrap it + have hdγ : ∀ p ∈ W ×ˢ (univ : Set H), fderiv ℝ j (γ p.1) (dMB γ p) = dMB (j ∘ γ) p := by + rintro ⟨q, h⟩ ⟨hq, -⟩ + obtain ⟨D, hD, hAD⟩ := hder q hq h + rw [hD.dMB_eq] + exact hAD + have hW2 : IsOpen (W ×ˢ (univ : Set H)) := hW.prod isOpen_univ + have hγfst : ContDiffMBOn k (fun p : H × H ↦ γ p.1) (W ×ˢ univ) := + ContDiffMBOn.comp (g := γ) (f := fun p : H × H ↦ p.1) hW2 hW hγk + ((ContinuousLinearMap.fst ℝ H H).contDiffMBOn k _) fun p hp ↦ hp.1 + have hdjγ : ContDiffMBOn k (dMB (j ∘ γ)) (W ×ˢ univ) := hjγ.2.2 + have hAc : ContinuousOn (fun p : H × H ↦ fderiv ℝ j (γ p.1)) (W ×ˢ univ) := + hcont.comp hγfst.continuousOn fun p hp ↦ hγU hp.1 + have hdγc : ContinuousOn (dMB γ) (W ×ˢ univ) := + continuousOn_of_boundedBelow hAc hm (fun p hp ↦ hbd _ (hγU hp.1)) hdjγ.continuousOn hdγ + have hdγk := ContDiffMBOn.of_fderiv_eq_of_boundedBelow hU hj hm hbd k hW2 hγfst + (fun p hp ↦ hγU hp.1) hdγc hdjγ hdγ + refine ⟨hγc, fun q hq h ↦ ?_, hdγk⟩ + obtain ⟨D, hD, -⟩ := hder q hq h + rw [hD.dMB_eq] + exact hD + +end Bootstrap + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/FundamentalTheorem.lean b/LeanPool/LCAnalysis/FundamentalTheorem.lean new file mode 100644 index 0000000000..f2fc4eefa3 --- /dev/null +++ b/LeanPool/LCAnalysis/FundamentalTheorem.lean @@ -0,0 +1,238 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.IntegrationByParts + +public import LeanPool.LCAnalysis.IntegralExistence + +/-! +# Calculus with weak integrals: algebra, change of variables, fundamental theorem + +For curves in a locally convex space `F` (Glöckner–Neeb, §1.1): + +* Algebraic rules: weak integrals are additive in the integrand and in the interval, and + commute with continuous linear maps. +* Change of variables: for a `C^1` real function `φ`, + `∫_a^b φ'(t) • γ(φ t) dt = ∫_{φ a}^{φ b} γ`, as an equivalence of the two existence statements. +* Fundamental theorem of calculus, first part (Glöckner–Neeb, Prop. 1.1.5): if `γ` has a + continuous derivative `γ'`, then `γ b - γ a` is the weak integral of `γ'` over `[a, b]`; no + completeness assumption on `F` is needed. The same holds for `t ↦ df(x + t h)(h)` when `f` is + `C^1` on a set containing the segment (the mean value theorem, Glöckner–Neeb, Prop. 1.2.6). +* Fundamental theorem of calculus, second part (Glöckner–Neeb, Prop. 1.1.12): if the weak + integrals `η s = ∫_a^s γ` of a continuous curve exist, then `η` is differentiable with + derivative `γ`. In a sequentially complete space they always exist. +-/ + +@[expose] public section + +open Set Filter Function +open scoped Topology Pointwise + +noncomputable section + +namespace LCAnalysis + +universe u v w + +variable {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + {G : Type w} [AddCommGroup G] [Module ℝ G] [TopologicalSpace G] + {γ η : ℝ → F} {a b c : ℝ} {y z : F} + +/-! ### Algebraic rules -/ + +theorem HasWeakIntegral.neg (hy : HasWeakIntegral γ a b y) : + HasWeakIntegral (fun t ↦ -γ t) a b (-y) := by + intro φ + simp only [map_neg] + rw [intervalIntegral.integral_neg, hy φ] + +theorem HasWeakIntegral.add (hγ : ContinuousOn γ (uIcc a b)) (hη : ContinuousOn η (uIcc a b)) + (hy : HasWeakIntegral γ a b y) (hz : HasWeakIntegral η a b z) : + HasWeakIntegral (fun t ↦ γ t + η t) a b (y + z) := by + intro φ + have i₁ : IntervalIntegrable (fun t ↦ φ (γ t)) MeasureTheory.volume a b := + (φ.continuous.comp_continuousOn hγ).intervalIntegrable + have i₂ : IntervalIntegrable (fun t ↦ φ (η t)) MeasureTheory.volume a b := + (φ.continuous.comp_continuousOn hη).intervalIntegrable + simp only [map_add] + rw [intervalIntegral.integral_add i₁ i₂, hy φ, hz φ] + +theorem hasWeakIntegral_const (v : F) (a b : ℝ) : + HasWeakIntegral (fun _ ↦ v) a b ((b - a) • v) := by + intro φ + simp [map_smul, smul_eq_mul] + +/-- Weak integrals commute with continuous linear maps. -/ +theorem HasWeakIntegral.map (hy : HasWeakIntegral γ a b y) (L : F →L[ℝ] G) : + HasWeakIntegral (fun t ↦ L (γ t)) a b (L y) := + fun φ ↦ hy (φ.comp L) + +/-- Additivity in the interval. -/ +theorem HasWeakIntegral.add_adjacent (hγab : ContinuousOn γ (uIcc a b)) + (hγbc : ContinuousOn γ (uIcc b c)) (hy : HasWeakIntegral γ a b y) + (hz : HasWeakIntegral γ b c z) : HasWeakIntegral γ a c (y + z) := by + intro φ + have i₁ : IntervalIntegrable (fun t ↦ φ (γ t)) MeasureTheory.volume a b := + (φ.continuous.comp_continuousOn hγab).intervalIntegrable + have i₂ : IntervalIntegrable (fun t ↦ φ (γ t)) MeasureTheory.volume b c := + (φ.continuous.comp_continuousOn hγbc).intervalIntegrable + rw [map_add, hy φ, hz φ, intervalIntegral.integral_add_adjacent_intervals i₁ i₂] + +/-! ### Change of variables -/ + +/-- Change of variables in weak integrals: if `φ` is `C^1` on `[a, b]` and `γ` is continuous on +`φ '' [a, b]`, then `y` is a weak integral of `γ` over `[φ a, φ b]` if and only if it is a weak +integral of `t ↦ φ' t • γ (φ t)` over `[a, b]`. -/ +theorem hasWeakIntegral_comp_smul_deriv_iff {φ φ' : ℝ → ℝ} + (hφ : ∀ t ∈ uIcc a b, HasDerivAt φ (φ' t) t) (hφ' : ContinuousOn φ' (uIcc a b)) + (hγ : ContinuousOn γ (φ '' uIcc a b)) : + HasWeakIntegral (fun t ↦ φ' t • γ (φ t)) a b y ↔ HasWeakIntegral γ (φ a) (φ b) y := by + have key : ∀ ψ : F →L[ℝ] ℝ, + ∫ t in a..b, ψ (φ' t • γ (φ t)) = ∫ t in φ a..φ b, ψ (γ t) := fun ψ ↦ by + rw [← intervalIntegral.integral_comp_mul_deriv' (g := fun x ↦ ψ (γ x)) hφ hφ' + (ψ.continuous.comp_continuousOn hγ)] + simp [map_smul, smul_eq_mul, mul_comm] + exact forall_congr' fun ψ ↦ by rw [key] + +/-- The affine case: `∫_t^{t+s} γ = s • ∫_0^1 γ(t + s r) dr`. -/ +theorem hasWeakIntegral_affine_iff {t s : ℝ} (hγ : ContinuousOn γ (uIcc t (t + s))) : + HasWeakIntegral (fun r ↦ s • γ (t + s * r)) 0 1 y ↔ HasWeakIntegral γ t (t + s) y := by + have hmaps : (fun r ↦ t + s * r) '' uIcc 0 1 ⊆ uIcc t (t + s) := by + rintro _ ⟨r, hr, rfl⟩ + rw [uIcc_of_le zero_le_one] at hr + rcases le_total 0 s with hs | hs + · rw [uIcc_of_le (by linarith)] + constructor <;> nlinarith [hr.1, hr.2] + · rw [uIcc_of_ge (by linarith)] + constructor <;> nlinarith [hr.1, hr.2] + have := hasWeakIntegral_comp_smul_deriv_iff (y := y) (a := 0) (b := 1) + (φ := fun r ↦ t + s * r) (φ' := fun _ ↦ s) + (fun r _ ↦ by simpa using ((hasDerivAt_id r).const_mul s).const_add t) + continuousOn_const (hγ.mono hmaps) + simpa using this + +/-! ### The fundamental theorem of calculus -/ + +/-- Fundamental theorem of calculus, first part: if `γ` has a continuous derivative `γ'` on +`[a, b]`, then `γ b - γ a` is the weak integral of `γ'` over `[a, b]`. No completeness of `F` is +needed. -/ +theorem hasWeakIntegral_sub_of_hasDirDerivAt {γ' : ℝ → F} + (hγ : ∀ t ∈ uIcc a b, HasDirDerivAt γ t 1 (γ' t)) (hγ' : ContinuousOn γ' (uIcc a b)) : + HasWeakIntegral γ' a b (γ b - γ a) := by + intro φ + have hd : ∀ t ∈ uIcc a b, HasDerivAt (fun s ↦ φ (γ s)) (φ (γ' t)) t := fun t ht ↦ by + have := (show HasDirDerivAt γ (0 + t • (1 : ℝ)) 1 (γ' t) by simpa using hγ t ht) + |>.hasDerivAt_clm φ + simpa using this + rw [map_sub, intervalIntegral.integral_eq_sub_of_hasDerivAt hd + (φ.continuous.comp_continuousOn hγ').intervalIntegrable] + +/-- Fundamental theorem of calculus along a segment: if `f` is `C^1` on a set containing the +segment `[x, x + h]`, then `f (x + h) - f x = ∫₀¹ df(x + t h)(h) dt`, the weak integral existing +in `F` (no completeness assumption). -/ +theorem ContDiffMBOn.hasWeakIntegral_dMB {E : Type u} [AddCommGroup E] [Module ℝ E] + [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] + {f : E → F} {U : Set E} (hf : ContDiffMBOn 1 f U) {x h : E} + (hxh : ∀ t ∈ Icc (0 : ℝ) 1, x + t • h ∈ U) : + HasWeakIntegral (fun t ↦ dMB f (x + t • h, h)) 0 1 (f (x + h) - f x) := fun φ ↦ by + rw [map_sub, hf.integral_dMB hxh φ] + +variable [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] + +/-- For a neighborhood `N` of `0` there is a closed convex neighborhood `W` of `0` with +`2 • W ⊆ N`. -/ +theorem exists_closed_convex_two_smul_subset {N : Set F} (hN : N ∈ 𝓝 (0 : F)) : + ∃ W ∈ 𝓝 (0 : F), IsClosed W ∧ Convex ℝ W ∧ (2 : ℝ) • W ⊆ N := by + have h2 : (2 : ℝ)⁻¹ • N ∈ 𝓝 (0 : F) := (set_smul_mem_nhds_zero_iff (by norm_num)).mpr hN + obtain ⟨W, hW, hWc, hWconv, hWN⟩ := exists_closed_convex_nhds_subset h2 + refine ⟨W, hW, hWc, hWconv, ?_⟩ + calc (2 : ℝ) • W ⊆ (2 : ℝ) • (2 : ℝ)⁻¹ • N := smul_set_mono hWN + _ = N := by rw [smul_smul, mul_inv_cancel₀ (by norm_num), one_smul] + +variable [T2Space F] + +theorem weakIntegral_eq_sub_of_hasDirDerivAt {γ' : ℝ → F} + (hγ : ∀ t ∈ uIcc a b, HasDirDerivAt γ t 1 (γ' t)) (hγ' : ContinuousOn γ' (uIcc a b)) : + weakIntegral γ' a b = γ b - γ a := + (hasWeakIntegral_sub_of_hasDirDerivAt hγ hγ').weakIntegral_eq + +/-- Fundamental theorem of calculus, second part: if `γ` is continuous on an open interval `I` +and the weak integrals `∫_a^s γ` exist for `s ∈ I`, then `s ↦ ∫_a^s γ` is differentiable on `I`, +with derivative `γ`. -/ +theorem hasDirDerivAt_weakIntegral_right_of_exists {I : Set ℝ} (hI : IsOpen I) + (hIc : I.OrdConnected) (hγ : ContinuousOn γ I) (ha : a ∈ I) + (hex : ∀ s ∈ I, ∃ y, HasWeakIntegral γ a s y) {t : ℝ} (ht : t ∈ I) : + HasDirDerivAt (fun s ↦ weakIntegral γ a s) t 1 (γ t) := by + have hex : ∀ s ∈ I, HasWeakIntegral γ a s (weakIntegral γ a s) := fun s hs ↦ + hasWeakIntegral_weakIntegral (hex s hs) + unfold HasDirDerivAt + rw [← tendsto_sub_nhds_zero_iff] + intro N hN + rw [Filter.mem_map] + obtain ⟨W, hW, hWc, hWconv, hWN⟩ := exists_closed_convex_two_smul_subset hN + obtain ⟨ε, hε, hεI, hεW⟩ : ∃ ε > 0, Metric.ball t ε ⊆ I ∧ + ∀ u ∈ Metric.ball t ε, γ u - γ t ∈ W := by + have hcont : ContinuousAt (fun u ↦ γ u - γ t) t := + ((hγ.continuousAt (hI.mem_nhds ht)).sub continuousAt_const) + have h1 : ∀ᶠ u in 𝓝 t, γ u - γ t ∈ W := + hcont.eventually_mem (by simpa using hW) + obtain ⟨ε₁, hε₁, h₁⟩ := Metric.mem_nhds_iff.mp (hI.mem_nhds ht) + obtain ⟨ε₂, hε₂, h₂⟩ := Metric.mem_nhds_iff.mp h1 + exact ⟨min ε₁ ε₂, lt_min hε₁ hε₂, + (Metric.ball_subset_ball (min_le_left _ _)).trans h₁, + fun u hu ↦ h₂ (Metric.ball_subset_ball (min_le_right _ _) hu)⟩ + filter_upwards [self_mem_nhdsWithin, nhdsWithin_le_nhds (Metric.ball_mem_nhds (0 : ℝ) hε)] + with s (hs0 : s ≠ 0) hsε + simp only [smul_eq_mul, mul_one, Set.mem_preimage] + have hsε' : |s| < ε := by simpa using hsε + -- the segment `[t, t + s]` lies in the ball + have hseg : uIcc t (t + s) ⊆ Metric.ball t ε := fun u hu ↦ by + rw [Metric.mem_ball, Real.dist_eq] + rcases le_total 0 s with h | h + · rw [uIcc_of_le (by linarith)] at hu + rw [abs_lt]; constructor <;> linarith [hu.1, hu.2, abs_of_nonneg h] + · rw [uIcc_of_ge (by linarith)] at hu + rw [abs_lt]; constructor <;> linarith [hu.1, hu.2, abs_of_nonpos h] + have hγseg : ContinuousOn γ (uIcc t (t + s)) := hγ.mono (hseg.trans hεI) + have hts : t + s ∈ I := hεI (hseg right_mem_uIcc) + -- `∫_a^{t+s} γ - ∫_a^t γ` is a weak integral of `γ` over `[t, t + s]` + set z := weakIntegral γ a (t + s) - weakIntegral γ a t + have hz : HasWeakIntegral γ t (t + s) z := fun φ ↦ by + have i : ∀ u ∈ I, IntervalIntegrable (fun r ↦ φ (γ r)) MeasureTheory.volume a u := fun u hu ↦ + (φ.continuous.comp_continuousOn (hγ.mono (hIc.uIcc_subset ha hu))).intervalIntegrable + rw [map_sub, hex _ hts φ, hex t ht φ, + intervalIntegral.integral_interval_sub_left (i _ hts) (i t ht)] + -- `s⁻¹ • ∫_t^{t+s} γ - γ t = ∫₀¹ (γ (t + s r) - γ t) dr` + have hcurve : ContinuousOn (fun r ↦ γ (t + s * r)) (Icc 0 1) := by + refine hγseg.comp (by fun_prop) fun r hr ↦ ?_ + rcases le_total 0 s with h | h + · rw [uIcc_of_le (by linarith)]; constructor <;> nlinarith [hr.1, hr.2] + · rw [uIcc_of_ge (by linarith)]; constructor <;> nlinarith [hr.1, hr.2] + have hz' : HasWeakIntegral (fun r ↦ γ (t + s * r)) 0 1 (s⁻¹ • z) := by + have := ((hasWeakIntegral_affine_iff hγseg).mpr hz).const_smul s⁻¹ + simpa [smul_smul, inv_mul_cancel₀ hs0] using this + have hdiff : HasWeakIntegral (fun r ↦ γ (t + s * r) - γ t) 0 1 (s⁻¹ • z - γ t) := by + have := hz'.sub zero_le_one hcurve continuousOn_const (hasWeakIntegral_const (γ t) 0 1) + simpa using this + have hmem : s⁻¹ • z - γ t ∈ (1 - 0 + 1 : ℝ) • W := + hdiff.mem_smul zero_le_one (hcurve.sub continuousOn_const) hWconv hWc + (mem_of_mem_nhds hW) fun r hr ↦ hεW _ (hseg (by + rcases le_total 0 s with h | h + · rw [uIcc_of_le (by linarith)]; constructor <;> nlinarith [hr.1, hr.2] + · rw [uIcc_of_ge (by linarith)]; constructor <;> nlinarith [hr.1, hr.2])) + exact hWN (by norm_num at hmem ⊢; exact hmem) + +/-- Fundamental theorem of calculus, second part, in a sequentially complete space: the indefinite +integral of a curve that is continuous on an open interval `I` is differentiable on `I`, with +derivative the curve itself. -/ +theorem hasDirDerivAt_weakIntegral_right [SeqComplete F] {I : Set ℝ} (hI : IsOpen I) + (hIc : I.OrdConnected) (hγ : ContinuousOn γ I) (ha : a ∈ I) {t : ℝ} (ht : t ∈ I) : + HasDirDerivAt (fun s ↦ weakIntegral γ a s) t 1 (γ t) := + hasDirDerivAt_weakIntegral_right_of_exists hI hIc hγ ha + (fun _ hs ↦ exists_hasWeakIntegral (hγ.mono (hIc.uIcc_subset ha hs))) ht + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/Higher.lean b/LeanPool/LCAnalysis/Higher.lean new file mode 100644 index 0000000000..4e1ca7050d --- /dev/null +++ b/LeanPool/LCAnalysis/Higher.lean @@ -0,0 +1,633 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import Mathlib.GroupTheory.Perm.Sign +public import Mathlib.Analysis.Normed.Module.Multilinear.Basic + +public import LeanPool.LCAnalysis.MichalBastiani + +/-! +# Higher differentials + +Glöckner–Neeb, *Infinite-Dimensional Lie Groups* (arXiv:2602.12362), §1.3. + +The `k`-th differential of `f : E → F` is +`d^(k) f (x, y₁, …, yₖ) = (D_{yₖ} ⋯ D_{y₁} f)(x)` (`iteratedDMB`). We show: + +* Proposition 1.3.10: `f` is `C^k` in the recursive sense of `ContDiffMBOn` if and only if `f` + is continuous and the differentials `d^(j) f` exist and are continuous on `U × E^j` for + `j ≤ k` (the original definition of Bastiani and Neeb, `HasContIterDerivOn`). +* Remark 1.3.13: if `f` is `C^r`, then `d^(k) f` is `C^{r-k}` on `U × E^k`. +* Proposition 1.3.17 (Schwarz): for `f` of class `C^k`, `d^(k) f (x, ·)` is a continuous, + symmetric `k`-linear map. +-/ + +@[expose] public section + +open Set Filter Function +open scoped Topology + + +noncomputable section + +namespace LCAnalysis + +universe u v + +variable {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] + {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] [ContinuousSMul ℝ F] + +/-- The `k`-th differential `d^(k) f (x, y) = (D_{y (k-1)} ⋯ D_{y 0} f)(x)` +(junk values where the derivatives do not exist). -/ +def iteratedDMB : (k : ℕ) → (E → F) → E × (Fin k → E) → F + | 0, f, p => f p.1 + | k + 1, f, p => dMB (fun z ↦ iteratedDMB k f (z, Fin.init p.2)) (p.1, p.2 (Fin.last k)) + +/-- Neeb's definition of `C^k` maps: the iterated directional derivatives `d^(j) f` exist for +`j ≤ k` and are continuous on `U × E^j` (for `j = 0`, this is the continuity of `f`). -/ +def HasContIterDerivOn (k : ℕ) (f : E → F) (U : Set E) : Prop := + (∀ j < k, ∀ x ∈ U, ∀ v : Fin (j + 1) → E, HasDirDerivAt (fun z ↦ iteratedDMB j f (z, Fin.init v)) + x (v (Fin.last j)) (iteratedDMB (j + 1) f (x, v))) ∧ + ∀ j ≤ k, ContinuousOn (iteratedDMB j f) (U ×ˢ univ) + +/-! ### Algebraic identities -/ + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +theorem iteratedDMB_zero (f : E → F) (p : E × (Fin 0 → E)) : iteratedDMB 0 f p = f p.1 := rfl + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +theorem iteratedDMB_one (f : E → F) (x : E) (v : Fin 1 → E) : + iteratedDMB 1 f (x, v) = dMB f (x, v 0) := rfl + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +theorem iteratedDMB_succ (k : ℕ) (f : E → F) (x : E) (v : Fin (k + 1) → E) : + iteratedDMB (k + 1) f (x, v) = + dMB (fun z ↦ iteratedDMB k f (z, Fin.init v)) (x, v (Fin.last k)) := rfl + +private theorem init_cons {n : ℕ} {α : Type*} (a : α) (v : Fin (n + 1) → α) : + Fin.init (Fin.cons a v : Fin (n + 2) → α) = Fin.cons a (Fin.init v) := by + funext i + refine Fin.cases ?_ (fun i ↦ ?_) i <;> rfl + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +/-- Peeling off the first direction: +`d^(k+1) f (x, y, v) = d^(k) (df(·, y)) (x, v)`. -/ +theorem iteratedDMB_cons : ∀ (k : ℕ) (f : E → F) (y x : E) (v : Fin k → E), + iteratedDMB (k + 1) f (x, Fin.cons y v) = iteratedDMB k (fun z ↦ dMB f (z, y)) (x, v) + | 0, _, _, _, _ => rfl + | k + 1, f, y, x, v => by + rw [iteratedDMB_succ, iteratedDMB_succ, init_cons] + simp only [iteratedDMB_cons k] + rfl + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +theorem dMB_slice {E' : Type*} [AddCommGroup E'] [Module ℝ E'] + (g : E × E' → F) (x h : E) (a : E') : + dMB g ((x, a), (h, 0)) = dMB (fun z ↦ g (z, a)) (x, h) := by + simp only [dMB, Prod.smul_mk, smul_zero, Prod.mk_add_mk, add_zero] + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +/-- Derivatives in directions `(0, b)` are derivatives of the second slice. -/ +theorem dMB_slice₂ {E' : Type*} [AddCommGroup E'] [Module ℝ E'] + (g : E × E' → F) (x : E) (a b : E') : + dMB g ((x, a), (0, b)) = dMB (fun w ↦ g (x, w)) (a, b) := by + simp only [dMB, Prod.smul_mk, smul_zero, Prod.mk_add_mk, add_zero] + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +theorem hasDirDerivAt_slice {E' : Type*} [AddCommGroup E'] [Module ℝ E'] + {g : E × E' → F} {x h : E} {a : E'} {y : F} : + HasDirDerivAt g (x, a) (h, 0) y ↔ HasDirDerivAt (fun z ↦ g (z, a)) x h y := by + simp only [HasDirDerivAt, Prod.smul_mk, smul_zero, Prod.mk_add_mk, add_zero] + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +/-- Differentials of a slice `z ↦ g (z, a)` are differentials of `g` in directions `(y, 0)`. -/ +theorem iteratedDMB_slice {E' : Type*} [AddCommGroup E'] [Module ℝ E'] [TopologicalSpace E'] : + ∀ (k : ℕ) (g : E × E' → F) (a : E') (x : E) (v : Fin k → E), + iteratedDMB k (fun z ↦ g (z, a)) (x, v) = iteratedDMB k g ((x, a), fun i ↦ (v i, 0)) + | 0, _, _, _, _ => rfl + | k + 1, g, a, x, v => by + rw [iteratedDMB_succ, iteratedDMB_succ, dMB_slice] + simp only [iteratedDMB_slice k] + rfl + +omit [ContinuousSMul ℝ F] in +/-- Glöckner–Neeb (1.36): `d^(k+1) f (x, y₀, …, yₖ) = d^(k) (df) ((x, y₀), (y₁, 0), …, (yₖ, 0))`. -/ +theorem iteratedDMB_succ_eq_dMB (k : ℕ) (f : E → F) (x : E) (v : Fin (k + 1) → E) : + iteratedDMB (k + 1) f (x, v) = iteratedDMB k (dMB f) ((x, v 0), fun i ↦ (v i.succ, 0)) := by + rw [← Fin.cons_self_tail v, iteratedDMB_cons, iteratedDMB_slice] + rfl + +/-! ### Proposition 1.3.10, first half -/ + +omit [ContinuousSMul ℝ F] in +theorem ContinuousOn.iteratedDMB_zero {f : E → F} {U : Set E} (hf : ContinuousOn f U) : + ContinuousOn (iteratedDMB 0 f) (U ×ˢ univ) := + hf.comp continuousOn_fst fun _ hp ↦ hp.1 + +omit [ContinuousSMul ℝ F] in +/-- A `C^k` map has continuous differentials `d^(j) f` for `j ≤ k`. -/ +theorem ContDiffMBOn.hasContIterDerivOn : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] + [Module ℝ E₁] [TopologicalSpace E₁] {f : E₁ → F} {U : Set E₁}, + ContDiffMBOn k f U → HasContIterDerivOn k f U := by + intro k + induction k with + | zero => + intro E₁ _ _ _ f U hf + refine ⟨fun j hj ↦ absurd hj (Nat.not_lt_zero j), fun j hj ↦ ?_⟩ + obtain rfl : j = 0 := Nat.le_zero.mp hj + exact ContinuousOn.iteratedDMB_zero hf + | succ k ih => + intro E₁ _ _ _ f U hf + obtain ⟨hc, hd, hdf⟩ := hf + obtain ⟨N₁, N₂⟩ := ih hdf + refine ⟨fun j hj x hx v ↦ ?_, fun j hj ↦ ?_⟩ + · cases j with + | zero => exact hd x hx (v (Fin.last 0)) + | succ j => + have h1 := N₁ j (by omega) (x, v 0) ⟨hx, mem_univ _⟩ (fun i ↦ (v i.succ, 0)) + rw [← iteratedDMB_succ_eq_dMB] at h1 + have h2 := hasDirDerivAt_slice.mp h1 + have e : (fun z ↦ iteratedDMB (j + 1) f (z, Fin.init v)) = + fun z ↦ iteratedDMB j (dMB f) ((z, v 0), Fin.init fun i ↦ (v i.succ, (0 : E₁))) := + funext fun z ↦ iteratedDMB_succ_eq_dMB j f z _ + rw [e] + exact h2 + · cases j with + | zero => exact ContinuousOn.iteratedDMB_zero hc + | succ j => + have h1 : ContinuousOn (iteratedDMB j (dMB f)) ((U ×ˢ univ) ×ˢ univ) := N₂ j (by omega) + have e : iteratedDMB (j + 1) f = + fun p ↦ iteratedDMB j (dMB f) ((p.1, p.2 0), fun i ↦ (p.2 i.succ, (0 : E₁))) := + funext fun p ↦ iteratedDMB_succ_eq_dMB j f p.1 p.2 + rw [e] + exact h1.comp (by fun_prop) fun p hp ↦ ⟨⟨hp.1, mem_univ _⟩, mem_univ _⟩ + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] in +theorem hasDirDerivAt_slice₂ {E' : Type*} [AddCommGroup E'] [Module ℝ E'] + {g : E × E' → F} {x : E} {a h : E'} {y : F} : + HasDirDerivAt g (x, a) (0, h) y ↔ HasDirDerivAt (fun w ↦ g (x, w)) a h y := by + simp only [HasDirDerivAt, Prod.smul_mk, smul_zero, Prod.mk_add_mk, add_zero] + +omit [ContinuousSMul ℝ F] in +/-- The directional derivative of a continuous map that is additive and homogeneous in each +variable separately: `D_h M (w) = ∑ᵢ M (w₁, …, hᵢ, …, wₗ)`. -/ +theorem hasDirDerivAt_of_multilinear {ℓ : ℕ} {M : (Fin ℓ → E) → F} + [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [IsTopologicalAddGroup F] (hM : Continuous M) + (hadd : ∀ w i (a b : E), M (update w i (a + b)) = M (update w i a) + M (update w i b)) + (hsmul : ∀ w i (c : ℝ) (a : E), M (update w i (c • a)) = c • M (update w i a)) + (w h : Fin ℓ → E) : HasDirDerivAt M w h (∑ i, M (update w i (h i))) := by + let m : ℝ → ℕ → Fin ℓ → E := fun t n j ↦ if (j : ℕ) < n then w j + t • h j else w j + have hm : ∀ n, Continuous fun t ↦ m t n := fun n ↦ continuous_pi fun j ↦ by + by_cases hj : (j : ℕ) < n + · simp only [m, hj, ite_true]; fun_prop + · simp only [m, hj, ite_false]; fun_prop + have hstep : ∀ t (i : Fin ℓ), M (m t (i + 1)) - M (m t i) = t • M (update (m t i) i (h i)) := by + intro t i + have e1 : m t (i + 1) = update (m t i) i (w i + t • h i) := by + funext j + by_cases hj : j = i + · subst hj; simp [m] + · have : ((j : ℕ) < i + 1 ↔ (j : ℕ) < i) := by + have := Fin.val_ne_of_ne hj; omega + simp only [m, update_of_ne hj, this] + have e2 : m t i = update (m t i) i (w i) := by + conv_lhs => rw [← update_eq_self i (m t i)] + simp [m] + rw [e1, hadd, hsmul, ← e2, add_sub_cancel_left] + have hkey : ∀ t, M (w + t • h) - M w = t • ∑ i : Fin ℓ, M (update (m t i) i (h i)) := by + intro t + have hl : m t ℓ = w + t • h := by funext j; simp [m, j.isLt] + have h0 : m t 0 = w := by funext j; simp [m] + rw [Finset.smul_sum, ← hl, ← h0, ← Finset.sum_range_sub (fun n ↦ M (m t n)), + ← Fin.sum_univ_eq_sum_range (fun n ↦ M (m t (n + 1)) - M (m t n))] + exact Finset.sum_congr rfl fun i _ ↦ hstep t i + have hc : Continuous fun t ↦ ∑ i : Fin ℓ, M (update (m t i) i (h i)) := + continuous_finsetSum _ fun i _ ↦ hM.comp ((hm i).update i continuous_const) + have h0 : (∑ i : Fin ℓ, M (update (m 0 i) i (h i))) = ∑ i, M (update w i (h i)) := by + congr 1; funext i; congr 2; funext j; simp [m] + rw [HasDirDerivAt, ← h0] + refine ((hc.tendsto 0).mono_left nhdsWithin_le_nhds).congr' ?_ + filter_upwards [self_mem_nhdsWithin] with t (ht : t ≠ 0) + rw [hkey, smul_smul, inv_mul_cancel₀ ht, one_smul] + +omit [ContinuousSMul ℝ F] in +theorem HasDirDerivAt.add {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] + [IsTopologicalAddGroup F] {f g : E₁ → F} {x h : E₁} {a b : F} (hf : HasDirDerivAt f x h a) + (hg : HasDirDerivAt g x h b) : HasDirDerivAt (fun y ↦ f y + g y) x h (a + b) := + (Filter.Tendsto.add hf hg).congr fun t ↦ by simp only [← smul_add]; congr 1; abel + +theorem HasDirDerivAt.const_smul {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] + {f : E₁ → F} {x h : E₁} {a : F} (hf : HasDirDerivAt f x h a) (c : ℝ) : + HasDirDerivAt (fun y ↦ c • f y) x h (c • a) := + (Filter.Tendsto.const_smul hf c).congr fun t ↦ by + beta_reduce; rw [smul_comm c t⁻¹, smul_sub] + +/-! ### Proposition 1.3.10, second half -/ + +section LocallyConvex + +variable [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +theorem contDiffMBOn_const : ∀ (k : ℕ) {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] (c : F) (U : Set E₁), + ContDiffMBOn k (fun _ : E₁ ↦ c) U := by + intro k + induction k with + | zero => intro E₁ _ _ _ _ _ _ _ c U; exact continuousOn_const + | succ k ih => + intro E₁ _ _ _ _ _ _ _ c U + have hd : ∀ x h : E₁, HasDirDerivAt (fun _ : E₁ ↦ c) x h 0 := fun x h ↦ by + simp only [HasDirDerivAt, sub_self, smul_zero]; exact tendsto_const_nhds + have heq : dMB (fun _ : E₁ ↦ c) = fun _ ↦ 0 := funext fun p ↦ (hd p.1 p.2).dMB_eq + refine ⟨continuousOn_const, fun x _ h ↦ ?_, ?_⟩ + · rw [heq]; exact hd x h + · rw [heq]; exact ih 0 _ + +theorem ContDiffMBOn.add {k : ℕ} {f g : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn k f U) (hg : ContDiffMBOn k g U) : ContDiffMBOn k (fun x ↦ f x + g x) U := + ContDiffMBOn.comp (F₁ := F × F) hU isOpen_univ + ((ContinuousLinearMap.fst ℝ F F + ContinuousLinearMap.snd ℝ F F).contDiffMBOn k univ) + (ContDiffMBOn.prodMk hU hf hg) (mapsTo_univ _ _) + +theorem ContDiffMBOn.sum {k : ℕ} {ι : Type*} (s : Finset ι) {f : ι → E → F} {U : Set E} + (hU : IsOpen U) (hf : ∀ i ∈ s, ContDiffMBOn k (f i) U) : + ContDiffMBOn k (fun x ↦ ∑ i ∈ s, f i x) U := by + classical + induction s using Finset.induction_on with + | empty => simpa using contDiffMBOn_const k (0 : F) U + | insert a s ha ih => + simp only [Finset.sum_insert ha] + exact (hf a (Finset.mem_insert_self a s)).add hU + (ih fun i hi ↦ hf i (Finset.mem_insert_of_mem hi)) + +/-- `((x, w), (y, h)) ↦ (x, w₁, …, hᵢ, …, wₗ)`. -/ +private def updateCLM (ℓ : ℕ) (i : Fin ℓ) : + (E × (Fin ℓ → E)) × (E × (Fin ℓ → E)) →L[ℝ] E × (Fin ℓ → E) where + toFun q := (q.1.1, update q.1.2 i (q.2.2 i)) + map_add' q q' := by + refine Prod.ext rfl (funext fun j ↦ ?_) + simp only [Prod.fst_add, Prod.snd_add, Pi.add_apply, update_apply] + split_ifs <;> rfl + map_smul' c q := by + refine Prod.ext rfl (funext fun j ↦ ?_) + simp only [Prod.smul_fst, Prod.smul_snd, Pi.smul_apply, update_apply, RingHom.id_apply] + split_ifs <;> rfl + cont := (continuous_fst.comp continuous_fst).prodMk ((continuous_snd.comp continuous_fst).update i + ((continuous_apply i).comp (continuous_snd.comp continuous_snd))) + +omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] in +@[simp] private theorem updateCLM_apply (ℓ : ℕ) (i : Fin ℓ) (q) : + updateCLM (E := E) ℓ i q = (q.1.1, update q.1.2 i (q.2.2 i)) := rfl + +/-- `((x, w), (y, h)) ↦ (x, y, w₁, …, wₗ)`. -/ +private def consCLM (ℓ : ℕ) : + (E × (Fin ℓ → E)) × (E × (Fin ℓ → E)) →L[ℝ] E × (Fin (ℓ + 1) → E) where + toFun q := (q.1.1, Fin.cons q.2.1 q.1.2) + map_add' q q' := by + refine Prod.ext rfl (funext fun j ↦ ?_) + refine Fin.cases ?_ (fun j ↦ ?_) j <;> simp + map_smul' c q := by + refine Prod.ext rfl (funext fun j ↦ ?_) + refine Fin.cases ?_ (fun j ↦ ?_) j <;> simp + cont := (continuous_fst.comp continuous_fst).prodMk + (Continuous.finCons (continuous_fst.comp continuous_snd) (continuous_snd.comp continuous_fst)) + +omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] in +@[simp] private theorem consCLM_apply (ℓ : ℕ) (q) : + consCLM (E := E) ℓ q = (q.1.1, Fin.cons q.2.1 q.1.2) := rfl + +/-- Glöckner–Neeb, Lemma 1.3.12: a map `f : U × E^ℓ → F` that is `ℓ`-linear in the second +variable and has continuous differentials `d^(j)` in the first variable for `j ≤ r` is `C^r`. -/ +theorem contDiffMBOn_of_multilinear {U : Set E} (hU : IsOpen U) : ∀ (r ℓ : ℕ) + (f : E × (Fin ℓ → E) → F), + (∀ x ∈ U, ∀ w i (a b : E), + f (x, update w i (a + b)) = f (x, update w i a) + f (x, update w i b)) → + (∀ x ∈ U, ∀ w i (c : ℝ) (a : E), f (x, update w i (c • a)) = c • f (x, update w i a)) → + (∀ j < r, ∀ x ∈ U, ∀ w, ∀ v : Fin (j + 1) → E, + HasDirDerivAt (fun z ↦ iteratedDMB j (fun z' ↦ f (z', w)) (z, Fin.init v)) x (v (Fin.last j)) + (iteratedDMB (j + 1) (fun z' ↦ f (z', w)) (x, v))) → + (∀ j ≤ r, ContinuousOn (fun q : (E × (Fin ℓ → E)) × (Fin j → E) ↦ + iteratedDMB j (fun z ↦ f (z, q.1.2)) (q.1.1, q.2)) ((U ×ˢ univ) ×ˢ univ)) → + ContDiffMBOn r f (U ×ˢ univ) := by + have hc0 : ∀ (ℓ : ℕ) (f : E × (Fin ℓ → E) → F), ContinuousOn + (fun q : (E × (Fin ℓ → E)) × (Fin 0 → E) ↦ iteratedDMB 0 (fun z ↦ f (z, q.1.2)) (q.1.1, q.2)) + ((U ×ˢ univ) ×ˢ univ) → ContinuousOn f (U ×ˢ univ) := fun ℓ f h ↦ + h.comp (continuous_id.prodMk continuous_const).continuousOn + fun p hp ↦ ⟨hp, mem_univ (Fin.elim0 : Fin 0 → E)⟩ + intro r + induction r with + | zero => intro ℓ f _ _ _ hcont; exact hc0 ℓ f (hcont 0 le_rfl) + | succ r ih => + intro ℓ f hadd hsmul hex hcont + have hc : ContinuousOn f (U ×ˢ univ) := hc0 ℓ f (hcont 0 (Nat.zero_le _)) + have hUW : IsOpen (U ×ˢ (univ : Set (Fin ℓ → E))) := hU.prod isOpen_univ + have hd1 : ∀ x ∈ U, ∀ w y, HasDirDerivAt (fun z ↦ f (z, w)) x y + (dMB (fun z ↦ f (z, w)) (x, y)) := + fun x hx w y ↦ hex 0 (Nat.succ_pos r) x hx w (fun _ ↦ y) + have hφ1 : Continuous fun q : (E × (Fin ℓ → E)) × E ↦ (q.1, fun _ : Fin 1 ↦ q.2) := by + fun_prop + have hc1' := (hcont 1 (by omega)).comp hφ1.continuousOn + fun q (hq : q ∈ (U ×ˢ univ) ×ˢ (univ : Set E)) ↦ ⟨hq.1, mem_univ _⟩ + have hc1 : ContinuousOn + (fun q : (E × (Fin ℓ → E)) × E ↦ dMB (fun z ↦ f (z, q.1.2)) (q.1.1, q.2)) + ((U ×ˢ univ) ×ˢ univ) := hc1'.congr fun q _ ↦ by + simp only [Function.comp_apply, iteratedDMB_one] + have hslice : ∀ w, ContDiffMBOn 1 (fun z ↦ f (z, w)) U := by + intro w + have e1 : Continuous fun z : E ↦ (z, w) := by fun_prop + have e2 : Continuous fun p : E × E ↦ ((p.1, w), p.2) := by fun_prop + refine ⟨hc.comp e1.continuousOn fun z hz ↦ ⟨hz, mem_univ _⟩, fun x hx y ↦ hd1 x hx w y, ?_⟩ + change ContinuousOn (dMB fun z ↦ f (z, w)) (U ×ˢ univ) + refine (hc1.comp e2.continuousOn ?_).congr fun p _ ↦ ?_ + · intro p hp; exact ⟨⟨hp.1, mem_univ _⟩, mem_univ _⟩ + · rfl + have dadd : ∀ x ∈ U, ∀ w i (a b y : E), dMB (fun z ↦ f (z, update w i (a + b))) (x, y) = + dMB (fun z ↦ f (z, update w i a)) (x, y) + dMB (fun z ↦ f (z, update w i b)) (x, y) := by + intro x hx w i a b y + have hs : HasDirDerivAt (fun z ↦ f (z, update w i a) + f (z, update w i b)) x y + (dMB (fun z ↦ f (z, update w i a)) (x, y) + dMB (fun z ↦ f (z, update w i b)) (x, y)) := + (hd1 x hx _ y).add (hd1 x hx _ y) + have heq : (fun z ↦ f (z, update w i a) + f (z, update w i b)) =ᶠ[𝓝 x] + fun z ↦ f (z, update w i (a + b)) := by + filter_upwards [hU.mem_nhds hx] with z hz + exact (hadd z hz w i a b).symm + exact (hs.congr_of_eventuallyEq heq).dMB_eq + have dsmul : ∀ x ∈ U, ∀ w i (c : ℝ) (a y : E), dMB (fun z ↦ f (z, update w i (c • a))) (x, y) = + c • dMB (fun z ↦ f (z, update w i a)) (x, y) := by + intro x hx w i c a y + have hs : HasDirDerivAt (fun z ↦ c • f (z, update w i a)) x y + (c • dMB (fun z ↦ f (z, update w i a)) (x, y)) := (hd1 x hx _ y).const_smul c + have heq : (fun z ↦ c • f (z, update w i a)) =ᶠ[𝓝 x] fun z ↦ f (z, update w i (c • a)) := by + filter_upwards [hU.mem_nhds hx] with z hz + exact (hsmul z hz w i c a).symm + exact (hs.congr_of_eventuallyEq heq).dMB_eq + obtain ⟨h1, hdf⟩ := contDiffMBOn_one_of_partials hUW + (d₁ := fun p y ↦ dMB (fun z ↦ f (z, p.2)) (p.1, y)) + (d₂ := fun p h ↦ ∑ i, f (p.1, update p.2 i (h i))) + (fun p hp y ↦ hasDirDerivAt_slice.mpr (hd1 p.1 hp.1 p.2 y)) + (fun p hp h ↦ hasDirDerivAt_slice₂.mpr (hasDirDerivAt_of_multilinear + (M := fun w ↦ f (p.1, w)) + (hc.comp_continuous (by fun_prop : Continuous fun w : Fin ℓ → E ↦ (p.1, w)) + fun w ↦ ⟨hp.1, mem_univ w⟩) + (hadd p.1 hp.1) (hsmul p.1 hp.1) p.2 h)) + hc1 + (continuousOn_finsetSum _ fun i _ ↦ hc.comp ((continuous_fst.comp continuous_fst).prodMk + ((continuous_snd.comp continuous_fst).update i + ((continuous_apply i).comp continuous_snd))).continuousOn + fun q hq ↦ ⟨hq.1.1, mem_univ _⟩) + refine ⟨hc, h1.2.1, ?_⟩ + have hfr : ContDiffMBOn r f (U ×ˢ univ) := + ih ℓ f hadd hsmul (fun j hj ↦ hex j (by omega)) (fun j hj ↦ hcont j (by omega)) + have hgr : ContDiffMBOn r + (fun p : E × (Fin (ℓ + 1) → E) ↦ dMB (fun z ↦ f (z, Fin.tail p.2)) (p.1, p.2 0)) + (U ×ˢ univ) := by + refine ih (ℓ + 1) _ ?_ ?_ ?_ ?_ + · intro x hx w' i a b + refine Fin.cases ?_ (fun i ↦ ?_) i + · simp only [Fin.tail_update_zero, update_self] + exact (hslice _).dMB_add hU hx a b + · simp only [Fin.tail_update_succ] + exact dadd x hx _ i a b _ + · intro x hx w' i c a + refine Fin.cases ?_ (fun i ↦ ?_) i + · simp only [Fin.tail_update_zero, update_self] + exact (hslice _).dMB_smul hx c a + · simp only [Fin.tail_update_succ] + exact dsmul x hx _ i c a _ + · intro j hj x hx w' v + have := hex (j + 1) (by omega) x hx (Fin.tail w') (Fin.cons (w' 0) v) + rw [init_cons] at this + simp only [iteratedDMB_cons] at this + exact this + · intro j hj + have hcj := hcont (j + 1) (by omega) + have hφ : Continuous fun q : (E × (Fin (ℓ + 1) → E)) × (Fin j → E) ↦ + ((q.1.1, Fin.tail q.1.2), (Fin.cons (q.1.2 0) q.2 : Fin (j + 1) → E)) := by + refine ((continuous_fst.comp continuous_fst).prodMk ?_).prodMk ?_ + · exact continuous_pi fun i ↦ (continuous_apply i.succ).comp + (continuous_snd.comp continuous_fst) + · exact Continuous.finCons ((continuous_apply 0).comp + (continuous_snd.comp continuous_fst)) continuous_snd + refine (hcj.comp hφ.continuousOn fun q (hq : q ∈ (U ×ˢ (univ : Set (Fin (ℓ + 1) → E))) ×ˢ + (univ : Set (Fin j → E))) ↦ ⟨⟨hq.1.1, mem_univ _⟩, mem_univ _⟩).congr fun q _ ↦ ?_ + simp only [Function.comp_apply, iteratedDMB_cons] + have hG := ContDiffMBOn.comp_clm (consCLM ℓ) (hU.prod isOpen_univ) hgr + have hF := fun i ↦ ContDiffMBOn.comp_clm (updateCLM ℓ i) hUW hfr + have hpre₁ : (consCLM (E := E) ℓ) ⁻¹' (U ×ˢ univ) = (U ×ˢ univ) ×ˢ univ := by ext; simp + have hpre₂ : ∀ i, (updateCLM (E := E) ℓ i) ⁻¹' (U ×ˢ univ) = (U ×ˢ univ) ×ˢ univ := by + intro i; ext; simp + rw [hpre₁] at hG + simp only [hpre₂] at hF + have hΦ := hG.add (hUW.prod isOpen_univ) + (ContDiffMBOn.sum Finset.univ (hUW.prod isOpen_univ) fun i _ ↦ hF i) + refine ContDiffMBOn.congr_of_isOpen (hUW.prod isOpen_univ) (fun q hq ↦ ?_) hΦ + have := hdf q.1 hq.1 q.2.1 q.2.2 + simp only [Prod.mk.eta] at this + rw [this] + simp [Fin.tail_cons] + +/-- Glöckner–Neeb, Proposition 1.3.10: Neeb's definition of `C^k` implies the recursive one. -/ +theorem HasContIterDerivOn.contDiffMBOn {k : ℕ} {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : HasContIterDerivOn k f U) : ContDiffMBOn k f U := by + have h := contDiffMBOn_of_multilinear hU k 0 (fun p ↦ f p.1) (fun _ _ _ i ↦ i.elim0) + (fun _ _ _ i ↦ i.elim0) (fun j hj x hx _ v ↦ hf.1 j hj x hx v) + (fun j hj ↦ (hf.2 j hj).comp + (by fun_prop : Continuous fun q : (E × (Fin 0 → E)) × (Fin j → E) ↦ (q.1.1, q.2)).continuousOn + fun q hq ↦ ⟨hq.1.1, mem_univ _⟩) + have h2 := ContDiffMBOn.comp_clm (ContinuousLinearMap.inl ℝ E (Fin 0 → E)) (hU.prod isOpen_univ) h + have hpre : (ContinuousLinearMap.inl ℝ E (Fin 0 → E)) ⁻¹' (U ×ˢ univ) = U := by ext; simp + rw [hpre] at h2 + exact h2 + +/-- Glöckner–Neeb, Proposition 1.3.10: the recursive definition of `C^k` agrees with Neeb's. -/ +theorem contDiffMBOn_iff_hasContIterDerivOn {k : ℕ} {f : E → F} {U : Set E} (hU : IsOpen U) : + ContDiffMBOn k f U ↔ HasContIterDerivOn k f U := + ⟨ContDiffMBOn.hasContIterDerivOn, HasContIterDerivOn.contDiffMBOn hU⟩ + +/-! ### Remark 1.3.13: the differentials of a `C^r` map are `C^{r-k}` -/ + +/-- `(x, y₀, …, yₖ) ↦ ((x, y₀), (y₁, 0), …, (yₖ, 0))`, see (1.36). -/ +private def shiftCLM (k : ℕ) : E × (Fin (k + 1) → E) →L[ℝ] (E × E) × (Fin k → E × E) where + toFun p := ((p.1, p.2 0), fun i ↦ (p.2 i.succ, 0)) + map_add' p q := by ext <;> simp + map_smul' c p := by ext <;> simp + cont := by fun_prop + +omit [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [ContinuousSMul ℝ F] in +theorem ContDiffMBOn.contDiffMBOn_iteratedDMB : ∀ (k : ℕ) {r : ℕ} {E₁ : Type u} + [AddCommGroup E₁] [Module ℝ E₁] [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] + [ContinuousSMul ℝ E₁] [LocallyConvexSpace ℝ E₁] [T2Space E₁] {f : E₁ → F} {U : Set E₁}, + IsOpen U → ContDiffMBOn (k + r) f U → ContDiffMBOn r (iteratedDMB k f) (U ×ˢ univ) := by + intro k + induction k with + | zero => + intro r E₁ _ _ _ _ _ _ _ f U hU hf + rw [zero_add] at hf + have h := ContDiffMBOn.comp_clm (ContinuousLinearMap.fst ℝ E₁ (Fin 0 → E₁)) hU hf + have hpre : (ContinuousLinearMap.fst ℝ E₁ (Fin 0 → E₁)) ⁻¹' U = U ×ˢ univ := by ext; simp + rw [hpre] at h + exact h + | succ k ih => + intro r E₁ _ _ _ _ _ _ _ f U hU hf + rw [show k + 1 + r = (k + r) + 1 by omega] at hf + have h1 := ih (hU.prod isOpen_univ) hf.2.2 + have h2 := ContDiffMBOn.comp_clm (shiftCLM k) ((hU.prod isOpen_univ).prod isOpen_univ) h1 + have hpre : (shiftCLM (E := E₁) k) ⁻¹' ((U ×ˢ univ) ×ˢ univ) = U ×ˢ univ := by + ext; simp [shiftCLM] + rw [hpre] at h2 + have e : iteratedDMB (k + 1) f = iteratedDMB k (dMB f) ∘ shiftCLM k := + funext fun p ↦ iteratedDMB_succ_eq_dMB k f p.1 p.2 + rw [e] + exact h2 + +/-- For fixed directions `w`, the map `x ↦ d^(k) f (x, w)` is `C^r` if `f` is `C^{k+r}`. -/ +theorem ContDiffMBOn.contDiffMBOn_iteratedDMB_slice {k r : ℕ} {f : E → F} {U : Set E} + (hU : IsOpen U) (hf : ContDiffMBOn (k + r) f U) (w : Fin k → E) : + ContDiffMBOn r (fun z ↦ iteratedDMB k f (z, w)) U := by + have hp : ContDiffMBOn r (fun z : E ↦ (z, w)) U := + ContDiffMBOn.prodMk hU ((ContinuousLinearMap.id ℝ E).contDiffMBOn r U) + (contDiffMBOn_const r w U) + exact ContDiffMBOn.comp hU (hU.prod isOpen_univ) (hf.contDiffMBOn_iteratedDMB k hU) hp + fun z hz ↦ ⟨hz, mem_univ _⟩ + +/-! ### Proposition 1.3.17: Schwarz's theorem -/ + +omit [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ E] [T2Space E] [IsTopologicalAddGroup F] + [LocallyConvexSpace ℝ F] [T2Space F] in +theorem dMB_congr_of_eventuallyEq {f₁ f₂ : E → F} {x : E} (h : f₁ =ᶠ[𝓝 x] f₂) (v : E) : + dMB f₁ (x, v) = dMB f₂ (x, v) := by + have hl : Tendsto (fun t : ℝ ↦ x + t • v) (𝓝[≠] 0) (𝓝 x) := by + have : Continuous fun t : ℝ ↦ x + t • v := by fun_prop + simpa using (this.tendsto 0).mono_left nhdsWithin_le_nhds + simp only [dMB, limUnder] + congr 1 + refine Filter.map_congr ?_ + filter_upwards [hl.eventually h] with t ht + simp only [ht, h.eq_of_nhds] + +omit [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] + [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] + [ContinuousSMul ℝ F] in +theorem iteratedDMB_add_two (k : ℕ) (f : E → F) (x : E) (v : Fin (k + 2) → E) : + iteratedDMB (k + 2) f (x, v) = dMB (dMB fun z ↦ iteratedDMB k f (z, Fin.init (Fin.init v))) + ((x, v (Fin.last k).castSucc), (v (Fin.last (k + 1)), 0)) := by + rw [dMB_slice] + rfl + +/-- Swapping two adjacent directions does not change `d^(k+1) f`. -/ +theorem ContDiffMBOn.iteratedDMB_swap {m : ℕ} {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn m f U) : ∀ (k : ℕ), k + 1 ≤ m → ∀ x ∈ U, ∀ (v : Fin (k + 1) → E) + (i : Fin k), iteratedDMB (k + 1) f (x, v ∘ Equiv.swap i.castSucc i.succ) = + iteratedDMB (k + 1) f (x, v) := by + intro k + induction k with + | zero => intro _ x _ v i; exact i.elim0 + | succ k ih => + intro hk x hx v i + by_cases hi : i = Fin.last k + · subst hi + rw [iteratedDMB_add_two, iteratedDMB_add_two] + have hg : ContDiffMBOn 2 (fun z ↦ iteratedDMB k f (z, Fin.init (Fin.init v))) U := + (hf.of_le (show k + 2 ≤ m by omega)).contDiffMBOn_iteratedDMB_slice (k := k) (r := 2) hU _ + have e1 : Fin.init (Fin.init (v ∘ Equiv.swap (Fin.last k).castSucc (Fin.last k).succ)) = + Fin.init (Fin.init v) := by + funext j + simp only [Fin.init, Function.comp_apply] + rw [Equiv.swap_apply_of_ne_of_ne] <;> (apply Fin.ne_of_val_ne; simp; omega) + rw [e1] + simp only [Function.comp_apply, Equiv.swap_apply_left, Fin.succ_last, + Equiv.swap_apply_right] + exact hg.dMB_dMB_symm hU hx _ _ + · obtain ⟨j, rfl⟩ := Fin.exists_castSucc_eq.mpr hi + rw [iteratedDMB_succ, iteratedDMB_succ] + have e1 : Fin.init (v ∘ Equiv.swap j.castSucc.castSucc j.castSucc.succ) = + Fin.init v ∘ Equiv.swap j.castSucc j.succ := by + funext m + simp only [Fin.init, Function.comp_apply, Fin.succ_castSucc] + rw [(Fin.castSucc_injective _).swap_apply] + have e2 : (v ∘ Equiv.swap j.castSucc.castSucc j.castSucc.succ) (Fin.last (k + 1)) = + v (Fin.last (k + 1)) := by + simp only [Function.comp_apply] + rw [Equiv.swap_apply_of_ne_of_ne] <;> (apply Fin.ne_of_val_ne; simp; omega) + rw [e1, e2] + apply dMB_congr_of_eventuallyEq + filter_upwards [hU.mem_nhds hx] with z hz + exact ih (by omega) z hz (Fin.init v) j + +/-- Proposition 1.3.17: `d^(k) f (x, ·)` is symmetric. -/ +theorem ContDiffMBOn.iteratedDMB_perm {m k : ℕ} {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn m f U) (hk : k ≤ m) {x : E} (hx : x ∈ U) (v : Fin k → E) + (σ : Equiv.Perm (Fin k)) : iteratedDMB k f (x, v ∘ σ) = iteratedDMB k f (x, v) := by + cases k with + | zero => congr 2; funext i; exact i.elim0 + | succ k => + have hσ : σ ∈ Submonoid.closure (Set.range fun i : Fin k ↦ Equiv.swap i.castSucc i.succ) := by + rw [Equiv.Perm.mclosure_swap_castSucc_succ]; trivial + induction hσ using Submonoid.closure_induction generalizing v with + | mem τ hτ => + obtain ⟨i, rfl⟩ := hτ + exact hf.iteratedDMB_swap hU k hk x hx v i + | one => rfl + | mul τ ρ _ _ hτ hρ => + rw [Equiv.Perm.coe_mul, ← Function.comp_assoc, hρ, hτ] + +/-- Linearity of `d^(k+1) f (x, ·)` in the last direction. -/ +theorem ContDiffMBOn.iteratedDMB_snoc_add {m k : ℕ} {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn m f U) (hk : k + 1 ≤ m) {x : E} (hx : x ∈ U) (v : Fin k → E) (a b : E) : + iteratedDMB (k + 1) f (x, Fin.snoc v (a + b)) = + iteratedDMB (k + 1) f (x, Fin.snoc v a) + iteratedDMB (k + 1) f (x, Fin.snoc v b) := by + simp only [iteratedDMB_succ, Fin.init_snoc, Fin.snoc_last] + exact ((hf.of_le hk).contDiffMBOn_iteratedDMB_slice hU v).dMB_add hU hx a b + +theorem ContDiffMBOn.iteratedDMB_snoc_smul {m k : ℕ} {f : E → F} {U : Set E} + (hU : IsOpen U) (hf : ContDiffMBOn m f U) (hk : k + 1 ≤ m) {x : E} (hx : x ∈ U) + (v : Fin k → E) (c : ℝ) (a : E) : + iteratedDMB (k + 1) f (x, Fin.snoc v (c • a)) = + c • iteratedDMB (k + 1) f (x, Fin.snoc v a) := by + simp only [iteratedDMB_succ, Fin.init_snoc, Fin.snoc_last] + exact ((hf.of_le hk).contDiffMBOn_iteratedDMB_slice hU v).dMB_smul hx c a + +/-- Proposition 1.3.17: for `f` of class `C^k` and `x ∈ U`, `d^(k) f (x, ·)` is a continuous +symmetric `k`-linear map. -/ +theorem ContDiffMBOn.exists_iteratedDMB_multilinear {k : ℕ} {f : E → F} {U : Set E} + (hU : IsOpen U) (hf : ContDiffMBOn k f U) {x : E} (hx : x ∈ U) : + ∃ M : ContinuousMultilinearMap ℝ (fun _ : Fin k ↦ E) F, + (∀ v, M v = iteratedDMB k f (x, v)) ∧ ∀ (σ : Equiv.Perm (Fin k)) v, M (v ∘ σ) = M v := by + have hcont : Continuous fun v : Fin k → E ↦ iteratedDMB k f (x, v) := + (hf.hasContIterDerivOn.2 k le_rfl).comp_continuous (by fun_prop) fun v ↦ ⟨hx, mem_univ v⟩ + cases k with + | zero => + refine ⟨ContinuousMultilinearMap.constOfIsEmpty ℝ _ (f x), fun v ↦ rfl, fun _ _ ↦ rfl⟩ + | succ k => + have key : ∀ (v : Fin (k + 1) → E) (i : Fin (k + 1)) (d : E), + iteratedDMB (k + 1) f (x, update v i d) = + iteratedDMB (k + 1) f (x, Fin.snoc (Fin.init (v ∘ Equiv.swap i (Fin.last k))) d) := by + intro v i d + rw [← hf.iteratedDMB_perm hU le_rfl hx _ (Equiv.swap i (Fin.last k))] + congr 2 + rw [Function.update_comp_equiv, Equiv.symm_swap, Equiv.swap_apply_left] + conv_lhs => rw [← Fin.snoc_init_self (v ∘ Equiv.swap i (Fin.last k))] + rw [Fin.update_snoc_last] + refine ⟨{ toFun := fun v ↦ iteratedDMB (k + 1) f (x, v) + map_update_add' := ?_ + map_update_smul' := ?_ + cont := hcont }, fun v ↦ rfl, fun σ v ↦ hf.iteratedDMB_perm hU le_rfl hx v σ⟩ + · intro inst v i a b + obtain rfl : inst = instDecidableEqFin (k + 1) := Subsingleton.elim _ _ + simp only [key] + exact hf.iteratedDMB_snoc_add hU le_rfl hx _ a b + · intro inst v i c a + obtain rfl : inst = instDecidableEqFin (k + 1) := Subsingleton.elim _ _ + simp only [key] + exact hf.iteratedDMB_snoc_smul hU le_rfl hx _ c a + +end LocallyConvex + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/Imports.lean b/LeanPool/LCAnalysis/Imports.lean new file mode 100644 index 0000000000..17ff34c053 --- /dev/null +++ b/LeanPool/LCAnalysis/Imports.lean @@ -0,0 +1,18 @@ +/- +Copyright (c) 2026 Lean Pool contributors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Lean Pool contributors +-/ +module -- shake: keep-all --deprecated_module: ignore + +-- Generated project imports; run `lake exe mk_all`. +public import LeanPool.LCAnalysis +public import LeanPool.LCAnalysis.BoundedBelow +public import LeanPool.LCAnalysis.FundamentalTheorem +public import LeanPool.LCAnalysis.Higher +public import LeanPool.LCAnalysis.Integral +public import LeanPool.LCAnalysis.IntegralExistence +public import LeanPool.LCAnalysis.MBFrechet +public import LeanPool.LCAnalysis.MackeyLipschitz +public import LeanPool.LCAnalysis.MichalBastiani +public import LeanPool.LCAnalysis.Rules diff --git a/LeanPool/LCAnalysis/Integral.lean b/LeanPool/LCAnalysis/Integral.lean new file mode 100644 index 0000000000..846ecc89f8 --- /dev/null +++ b/LeanPool/LCAnalysis/Integral.lean @@ -0,0 +1,231 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import LeanPool.LCAnalysis.Higher + +/-! +# Weak integrals of curves and parameter-dependent integrals + +For a curve `γ : ℝ → F` in a locally convex space, `y` is a weak integral of `γ` over `[a, b]` +if `φ y = ∫_a^b φ (γ t) dt` for every continuous linear functional `φ` (Glöckner–Neeb, §1.1). +It is unique when it exists (Hahn–Banach), but in general it need not exist in `F`. + +* Mean value inclusion: if `γ` takes values in a closed convex set `W ∋ 0`, then + `y ∈ (b - a + 1) • W`; so weak integrals of uniformly small curves are small. +* Continuity of parameter-dependent weak integrals. +* Differentiation under the integral sign: if `f (x, t)` has jointly continuous partial + derivatives in `x` and the relevant weak integrals exist, then + `d(∫_a^b f(·, t) dt)(x)(h) = ∫_a^b d₁f((x, t), h) dt`. + +Existence of weak integrals under completeness hypotheses is in `LCAnalysis.IntegralExistence`. +-/ + +@[expose] public section + +open Set Filter Function +open scoped Topology Pointwise + +noncomputable section + +namespace LCAnalysis + +universe u v + +variable {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] + +/-- `y` is a weak integral of `γ` over `[a, b]`. -/ +def HasWeakIntegral (γ : ℝ → F) (a b : ℝ) (y : F) : Prop := + ∀ φ : F →L[ℝ] ℝ, φ y = ∫ t in a..b, φ (γ t) + +variable {γ η : ℝ → F} {a b : ℝ} {y z : F} + +theorem HasWeakIntegral.unique (hy : HasWeakIntegral γ a b y) (hz : HasWeakIntegral γ a b z) : + y = z := + (SeparatingDual.eq_iff_forall_dual_eq (R := ℝ)).mpr fun φ ↦ by rw [hy φ, hz φ] + +omit [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem HasWeakIntegral.sub (hab : a ≤ b) (hγ : ContinuousOn γ (Icc a b)) + (hη : ContinuousOn η (Icc a b)) (hy : HasWeakIntegral γ a b y) + (hz : HasWeakIntegral η a b z) : HasWeakIntegral (fun t ↦ γ t - η t) a b (y - z) := by + intro φ + have i₁ : IntervalIntegrable (fun t ↦ φ (γ t)) MeasureTheory.volume a b := + (φ.continuous.comp_continuousOn hγ).intervalIntegrable_of_Icc hab + have i₂ : IntervalIntegrable (fun t ↦ φ (η t)) MeasureTheory.volume a b := + (φ.continuous.comp_continuousOn hη).intervalIntegrable_of_Icc hab + simp only [map_sub] + rw [intervalIntegral.integral_sub i₁ i₂, hy φ, hz φ] + +omit [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem HasWeakIntegral.const_smul (hy : HasWeakIntegral γ a b y) (c : ℝ) : + HasWeakIntegral (fun t ↦ c • γ t) a b (c • y) := by + intro φ + simp only [map_smul, smul_eq_mul] + rw [intervalIntegral.integral_const_mul, hy φ] + +omit [T2Space F] in +/-- Mean value inclusion for weak integrals. -/ +theorem HasWeakIntegral.mem_smul (hab : a ≤ b) (hγ : ContinuousOn γ (Icc a b)) + (hy : HasWeakIntegral γ a b y) {W : Set F} (hWc : Convex ℝ W) (hWcl : IsClosed W) + (hW0 : (0 : F) ∈ W) (hγW : ∀ t ∈ Icc a b, γ t ∈ W) : y ∈ (b - a + 1) • W := by + have hc : (0 : ℝ) < b - a + 1 := by linarith + by_contra hnot + obtain ⟨φ, u, hlt, hgt⟩ := geometric_hahn_banach_closed_point (hWc.smul (b - a + 1)) + (hWcl.smul_of_ne_zero hc.ne') hnot + have hu : 0 < u := by + simpa using hlt 0 (by simpa using Set.smul_mem_smul_set (a := b - a + 1) hW0) + have hbound : ∀ t ∈ Icc a b, φ (γ t) ≤ u / (b - a + 1) := by + intro t ht + have := hlt _ (Set.smul_mem_smul_set (a := b - a + 1) (hγW t ht)) + rw [map_smul, smul_eq_mul] at this + rw [le_div_iff₀ hc] + linarith + have hle : ∫ t in a..b, φ (γ t) ≤ (b - a) * u / (b - a + 1) := by + have := intervalIntegral.integral_mono_on (μ := MeasureTheory.volume) hab + ((φ.continuous.comp_continuousOn hγ).intervalIntegrable_of_Icc hab) + (continuousOn_const.intervalIntegrable_of_Icc (μ := MeasureTheory.volume) hab) hbound + simpa using this + have hle' : (b - a) * u / (b - a + 1) ≤ u := by + rw [div_le_iff₀ hc] + nlinarith + rw [← hy φ] at hle + linarith + +omit [T2Space F] in +/-- Weak integrals of uniformly small curves are small. -/ +theorem exists_nhds_weakIntegral_mem (hab : a ≤ b) {N : Set F} (hN : N ∈ 𝓝 (0 : F)) : + ∃ W ∈ 𝓝 (0 : F), ∀ (γ : ℝ → F) (y : F), ContinuousOn γ (Icc a b) → + HasWeakIntegral γ a b y → (∀ t ∈ Icc a b, γ t ∈ W) → y ∈ N := by + have hc : b - a + 1 ≠ 0 := by linarith + have hM : (b - a + 1)⁻¹ • N ∈ 𝓝 (0 : F) := + (set_smul_mem_nhds_zero_iff (inv_ne_zero hc)).mpr hN + obtain ⟨W, hW, hWcl, hWc, hWM⟩ := exists_closed_convex_nhds_subset hM + refine ⟨W, hW, fun γ y hγ hy hγW ↦ ?_⟩ + have h1 := hy.mem_smul hab hγ hWc hWcl (mem_of_mem_nhds hW) hγW + have h2 := Set.smul_set_mono (a := b - a + 1) hWM h1 + rwa [smul_inv_smul₀ hc] at h2 + +omit [T2Space F] in +/-- Parameter-dependent weak integrals of continuous maps are continuous. -/ +theorem continuousOn_weakIntegral {X : Type*} [TopologicalSpace X] {f : X × ℝ → F} + {U : Set X} {T : Set ℝ} (hU : IsOpen U) (hT : IsOpen T) (hab : a ≤ b) + (hTab : Icc a b ⊆ T) (hf : ContinuousOn f (U ×ˢ T)) {I : X → F} + (hI : ∀ x ∈ U, HasWeakIntegral (fun t ↦ f (x, t)) a b (I x)) : ContinuousOn I U := by + have hcurve : ∀ x ∈ U, ContinuousOn (fun t ↦ f (x, t)) (Icc a b) := fun x hx ↦ + hf.comp (by fun_prop : Continuous fun t : ℝ ↦ (x, t)).continuousOn + fun t ht ↦ ⟨hx, hTab ht⟩ + intro x₀ hx₀ + refine ContinuousAt.continuousWithinAt (Filter.tendsto_def.mpr fun N hN ↦ ?_) + have hN' : (fun z ↦ I x₀ + z) ⁻¹' N ∈ 𝓝 (0 : F) := + (continuous_const.add continuous_id).continuousAt.preimage_mem_nhds (by simpa using hN) + obtain ⟨W, hW, hsmall⟩ := exists_nhds_weakIntegral_mem hab hN' + have htube : ∀ᶠ x in 𝓝 x₀, ∀ t ∈ Icc a b, x ∈ U ∧ f (x, t) - f (x₀, t) ∈ W := by + refine isCompact_Icc.eventually_forall_of_forall_eventually fun t₀ ht₀ ↦ ?_ + have hopen : U ×ˢ T ∈ 𝓝 (x₀, t₀) := prod_mem_nhds (hU.mem_nhds hx₀) (hT.mem_nhds (hTab ht₀)) + have h1 : ContinuousAt f (x₀, t₀) := hf.continuousAt hopen + have h2 : ContinuousAt (fun z : X × ℝ ↦ f (x₀, z.2)) (x₀, t₀) := + ContinuousAt.comp (f := fun z : X × ℝ ↦ (x₀, z.2)) (hf.continuousAt + (prod_mem_nhds (hU.mem_nhds hx₀) (hT.mem_nhds (hTab ht₀)))) (by fun_prop) + have h3 : ContinuousAt (fun z : X × ℝ ↦ f z - f (x₀, z.2)) (x₀, t₀) := h1.sub h2 + have h4 : (fun z : X × ℝ ↦ f z - f (x₀, z.2)) (x₀, t₀) = 0 := sub_self _ + have h5 := h3.eventually_mem (h4 ▸ hW : W ∈ 𝓝 ((fun z : X × ℝ ↦ f z - f (x₀, z.2)) (x₀, t₀))) + filter_upwards [h5, prod_mem_nhds (hU.mem_nhds hx₀) univ_mem] with z hz hzU + exact ⟨hzU.1, hz⟩ + filter_upwards [htube] with x hx + have hxU : x ∈ U := (hx a ⟨le_rfl, hab⟩).1 + have := hsmall _ _ ((hcurve x hxU).sub (hcurve x₀ hx₀)) + ((hI x hxU).sub hab (hcurve x hxU) (hcurve x₀ hx₀) (hI x₀ hx₀)) fun t ht ↦ (hx t ht).2 + simpa using this + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- Differentiation under the integral sign, for weak integrals. -/ +theorem hasDirDerivAt_weakIntegral {f : E × ℝ → F} {U : Set E} {T : Set ℝ} (hU : IsOpen U) + (hT : IsOpen T) (hab : a ≤ b) (hTab : Icc a b ⊆ T) (hf : ContinuousOn f (U ×ˢ T)) + {D : E × ℝ → E → F} (hd : ∀ p ∈ U ×ˢ T, ∀ h, HasDirDerivAt f p (h, 0) (D p h)) + (hD : ContinuousOn (fun q : (E × ℝ) × E ↦ D q.1 q.2) ((U ×ˢ T) ×ˢ univ)) {I : E → F} + (hI : ∀ x ∈ U, HasWeakIntegral (fun t ↦ f (x, t)) a b (I x)) {x : E} (hx : x ∈ U) (h : E) + {J : F} (hJ : HasWeakIntegral (fun t ↦ D (x, t) h) a b J) : HasDirDerivAt I x h J := by + have hcurve : ∀ x ∈ U, ContinuousOn (fun t ↦ f (x, t)) (Icc a b) := fun x hx ↦ + hf.comp (by fun_prop : Continuous fun t : ℝ ↦ (x, t)).continuousOn + fun t ht ↦ ⟨hx, hTab ht⟩ + have hDcurve : ContinuousOn (fun t ↦ D (x, t) h) (Icc a b) := + hD.comp (by fun_prop : Continuous fun t : ℝ ↦ ((x, t), h)).continuousOn + fun t ht ↦ ⟨⟨hx, hTab ht⟩, mem_univ _⟩ + refine Filter.tendsto_def.mpr fun N hN ↦ ?_ + have hN' : (fun z ↦ J + z) ⁻¹' N ∈ 𝓝 (0 : F) := + (continuous_const.add continuous_id).continuousAt.preimage_mem_nhds (by simpa using hN) + obtain ⟨W, hW, hsmall⟩ := exists_nhds_weakIntegral_mem hab hN' + have hUT : IsOpen (U ×ˢ T) := hU.prod hT + -- the difference quotients converge to `D`, locally uniformly + have hloc : ∀ t₀ ∈ Icc a b, ∀ᶠ z : ℝ × ℝ in 𝓝 (0, t₀), z.1 ≠ 0 → + z.1⁻¹ • (f (x + z.1 • h, z.2) - f (x, z.2)) - D (x, z.2) h ∈ W := by + intro t₀ ht₀ + have hp : (x, t₀) ∈ U ×ˢ T := ⟨hx, hTab ht₀⟩ + have hq := tendsto_quotient_of_hasDirDerivAt hUT (w := ((h, 0) : E × ℝ)) + (D := fun q ↦ D q h) (fun q hq ↦ hd q hq h) + (hD.comp (by fun_prop : Continuous fun q : E × ℝ ↦ (q, h)).continuousOn + fun q hq ↦ ⟨hq, mem_univ _⟩) hp + have hDc : Tendsto (fun r : (E × ℝ) × ℝ ↦ D r.1 h) (𝓝[{r | r.2 ≠ 0}] ((x, t₀), 0)) + (𝓝 (D (x, t₀) h)) := by + have : ContinuousAt (fun r : (E × ℝ) × ℝ ↦ D r.1 h) ((x, t₀), 0) := + ContinuousAt.comp (f := fun r : (E × ℝ) × ℝ ↦ (r.1, h)) + (hD.continuousAt (prod_mem_nhds (hUT.mem_nhds hp) univ_mem)) (by fun_prop) + exact this.tendsto.mono_left nhdsWithin_le_nhds + have hdiff := hq.sub hDc + rw [sub_self] at hdiff + have hev := eventually_nhdsWithin_iff.mp (hdiff.eventually (mem_of_superset hW subset_rfl)) + have hmap : Tendsto (fun z : ℝ × ℝ ↦ ((x, z.2), z.1)) (𝓝 (0, t₀)) (𝓝 ((x, t₀), 0)) := + (by fun_prop : Continuous fun z : ℝ × ℝ ↦ ((x, z.2), z.1)).tendsto' _ _ rfl + filter_upwards [hmap.eventually hev] with z hz hz0 + have := hz hz0 + change W _ + simpa only [Prod.smul_mk, Prod.mk_add_mk, smul_zero, add_zero] using this + have htube := isCompact_Icc.eventually_forall_of_forall_eventually + (P := fun s t ↦ s ≠ 0 → s⁻¹ • (f (x + s • h, t) - f (x, t)) - D (x, t) h ∈ W) hloc + have hxU : ∀ᶠ s : ℝ in 𝓝 0, x + s • h ∈ U := by + have : Continuous fun s : ℝ ↦ x + s • h := by fun_prop + exact this.continuousAt.eventually_mem (by simpa using hU.mem_nhds hx) + filter_upwards [nhdsWithin_le_nhds htube, nhdsWithin_le_nhds hxU, self_mem_nhdsWithin] + with s hs hsU (hs0 : s ≠ 0) + have hint : HasWeakIntegral + (fun t ↦ s⁻¹ • (f (x + s • h, t) - f (x, t)) - D (x, t) h) a b + (s⁻¹ • (I (x + s • h) - I x) - J) := + (((hI _ hsU).sub hab (hcurve _ hsU) (hcurve x hx) (hI x hx)).const_smul s⁻¹).sub hab + (((hcurve _ hsU).sub (hcurve x hx)).const_smul s⁻¹) hDcurve hJ + have hcont : ContinuousOn (fun t ↦ s⁻¹ • (f (x + s • h, t) - f (x, t)) - D (x, t) h) + (Icc a b) := (((hcurve _ hsU).sub (hcurve x hx)).const_smul s⁻¹).sub hDcurve + have := hsmall _ _ hcont hint fun t ht ↦ hs t ht hs0 + simpa using this + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- Parameter-dependent weak integrals of `C^1` maps are `C^1`, provided the weak integrals of the +partial derivatives exist: `d(∫_a^b f(·, t) dt)(x)(h) = ∫_a^b d₁f((x, t), h) dt`. -/ +theorem ContDiffMBOn.contDiffMBOn_one_of_hasWeakIntegral {f : E × ℝ → F} {U : Set E} + {T : Set ℝ} (hU : IsOpen U) (hT : IsOpen T) (hab : a ≤ b) (hTab : Icc a b ⊆ T) + (hf : ContDiffMBOn 1 f (U ×ˢ T)) + {I : E → F} (hI : ∀ x ∈ U, HasWeakIntegral (fun t ↦ f (x, t)) a b (I x)) {J : E × E → F} + (hJ : ∀ x ∈ U, ∀ h, HasWeakIntegral (fun t ↦ dMB f ((x, t), (h, 0))) a b (J (x, h))) : + ContDiffMBOn 1 I U ∧ ∀ x ∈ U, ∀ h, dMB I (x, h) = J (x, h) := by + have hdf : ContinuousOn (dMB f) ((U ×ˢ T) ×ˢ univ) := hf.2.2 + have hD : ContinuousOn (fun q : (E × ℝ) × E ↦ dMB f (q.1, (q.2, 0))) ((U ×ˢ T) ×ˢ univ) := + hdf.comp (by fun_prop) fun q hq ↦ ⟨hq.1, mem_univ _⟩ + have hdir : ∀ x ∈ U, ∀ h, HasDirDerivAt I x h (J (x, h)) := fun x hx h ↦ + hasDirDerivAt_weakIntegral hU hT hab hTab hf.continuousOn + (D := fun p h ↦ dMB f (p, (h, 0))) (fun p hp h ↦ hf.2.1 p hp (h, 0)) hD hI hx h (hJ x hx h) + have heq : ∀ x ∈ U, ∀ h, dMB I (x, h) = J (x, h) := fun x hx h ↦ (hdir x hx h).dMB_eq + have hJc : ContinuousOn J (U ×ˢ univ) := + continuousOn_weakIntegral (f := fun r : (E × E) × ℝ ↦ dMB f ((r.1.1, r.2), (r.1.2, 0))) + (hU.prod isOpen_univ) hT hab hTab + (hdf.comp (by fun_prop) fun r hr ↦ ⟨⟨hr.1.1, hr.2⟩, mem_univ _⟩) + fun q hq ↦ hJ q.1 hq.1 q.2 + refine ⟨⟨continuousOn_weakIntegral hU hT hab hTab hf.continuousOn hI, + fun x hx h ↦ by rw [heq x hx h]; exact hdir x hx h, ?_⟩, heq⟩ + exact hJc.congr fun q hq ↦ heq q.1 hq.1 q.2 + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/IntegralExistence.lean b/LeanPool/LCAnalysis/IntegralExistence.lean new file mode 100644 index 0000000000..fa0c7e339d --- /dev/null +++ b/LeanPool/LCAnalysis/IntegralExistence.lean @@ -0,0 +1,558 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import LeanPool.LCAnalysis.Integral + +/-! +# Existence of weak integrals + +Weak integrals of continuous curves need not exist in a general locally convex space; they do +under completeness hypotheses (Glöckner–Neeb, §1.1; Kriegl–Michor, §2): + +* if `F` is sequentially complete, every continuous curve `[a, b] → F` has a weak integral; +* if `F` is Mackey complete, every `C^1` curve has a weak integral. + +In both cases the integral is the limit of the dyadic Riemann sums. Mackey completeness is +strictly weaker than sequential completeness, and it is the natural hypothesis for smooth +calculus. As an application, parameter-dependent integrals of `C^k` maps are `C^k` +(sequentially complete case), or `C^k` maps give `C^{k-1}` integrals (Mackey complete case), +with no existence hypotheses. + +Completeness notions are stated directly in terms of the topological vector space structure +(`u n - u m` eventually in every neighborhood of `0`), so no uniform structure is needed; for a +uniform additive group, completeness implies sequential completeness. +-/ + +@[expose] public section + +open Set Filter Function Finset +open scoped Topology Pointwise + + +noncomputable section + +namespace LCAnalysis + +universe u v + +/-- A topological vector space is sequentially complete if every Cauchy sequence converges. -/ +class SeqComplete (F : Type*) [AddCommGroup F] [TopologicalSpace F] : Prop where + exists_tendsto : ∀ u : ℕ → F, (∀ W ∈ 𝓝 (0 : F), ∃ N, ∀ m ≥ N, ∀ n ≥ N, u n - u m ∈ W) → + ∃ y, Tendsto u atTop (𝓝 y) + +/-- A topological vector space is Mackey complete if every Mackey–Cauchy sequence converges: +`u l - u k ∈ r k • B` for `k ≤ l`, with `B` bounded and `r k → 0`. -/ +class MackeyComplete (F : Type*) [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] : Prop where + exists_tendsto : ∀ (u : ℕ → F) (B : Set F) (r : ℕ → ℝ), Bornology.IsVonNBounded ℝ B → + Tendsto r atTop (𝓝 0) → (∀ k l, k ≤ l → u l - u k ∈ r k • B) → ∃ y, Tendsto u atTop (𝓝 y) + +section Cauchy + +variable {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] + +omit [Module ℝ F] in +/-- A one-sided Cauchy condition implies the two-sided one. -/ +theorem cauchy_of_forall_ge {u : ℕ → F} + (h : ∀ V ∈ 𝓝 (0 : F), ∃ K, ∀ k ≥ K, ∀ l ≥ k, u l - u k ∈ V) : + ∀ W ∈ 𝓝 (0 : F), ∃ N, ∀ m ≥ N, ∀ n ≥ N, u n - u m ∈ W := by + intro W hW + obtain ⟨V, hV, hVW⟩ := exists_nhds_zero_half hW + obtain ⟨K, hK⟩ := h (V ∩ -V) (inter_mem hV (neg_mem_nhds_zero F hV)) + refine ⟨K, fun m hm n hn ↦ ?_⟩ + have h1 := hK K le_rfl n hn + have h2 := hK K le_rfl m hm + have := hVW _ h1.1 _ (show -(u m - u K) ∈ V from h2.2) + convert this using 1 + abel + +instance (priority := 100) SeqComplete.mackeyComplete [SeqComplete F] : + MackeyComplete F where + exists_tendsto u B r hB hr hu := by + refine SeqComplete.exists_tendsto u (cauchy_of_forall_ge fun V hV ↦ ?_) + have hev := hr.eventually ((hB hV).eventually_nhds_zero (mem_of_mem_nhds hV)) + obtain ⟨K, hK⟩ := eventually_atTop.mp hev + exact ⟨K, fun k hk l hl ↦ by + obtain ⟨b, hb, he⟩ := hu k l hl + rw [← he]; exact hK k hk hb⟩ + +/-- Complete uniform additive groups are sequentially complete. -/ +instance (priority := 100) SeqComplete.of_completeSpace {G : Type*} [AddCommGroup G] + [UniformSpace G] [IsUniformAddGroup G] [CompleteSpace G] : SeqComplete G where + exists_tendsto u hu := by + refine ⟨_, (cauchySeq_tendsto_of_complete ?_).choose_spec⟩ + rw [cauchySeq_iff_tendsto, uniformity_eq_comap_nhds_zero G, tendsto_comap_iff] + refine Filter.tendsto_def.mpr fun W hW ↦ ?_ + obtain ⟨N, hN⟩ := hu W hW + rw [← prod_atTop_atTop_eq] + exact mem_of_superset (prod_mem_prod (Ici_mem_atTop N) (Ici_mem_atTop N)) + fun p (hp : p ∈ Ici N ×ˢ Ici N) ↦ hN p.1 hp.1 p.2 hp.2 + +end Cauchy + +/-! ### Riemann sums -/ + +section Riemann + +variable {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] + {γ : ℝ → F} {a b : ℝ} + +/-- The Riemann sum of `γ` over `[a, b]` with `N` equal subintervals and left endpoints. -/ +def riemannSum (γ : ℝ → F) (a b : ℝ) (N : ℕ) : F := + ((b - a) / N) • ∑ i ∈ range N, γ (a + i * ((b - a) / N)) + +omit [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] in +theorem map_riemannSum {G : Type*} [AddCommGroup G] [Module ℝ G] [TopologicalSpace G] + (φ : F →L[ℝ] G) (N : ℕ) : + φ (riemannSum γ a b N) = riemannSum (fun t ↦ φ (γ t)) a b N := by + simp [riemannSum, map_sum] + +omit [Module ℝ F] [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] in +private theorem sum_range_mul (g : ℕ → F) (N m : ℕ) : + ∑ j ∈ range (N * m), g j = ∑ i ∈ range N, ∑ r ∈ range m, g (i * m + r) := by + induction N with + | zero => simp + | succ N ih => rw [Nat.succ_mul, Finset.sum_range_add, ih, Finset.sum_range_succ] + +/-- The points of the refined partition lie close to the left endpoints of the coarse one. -/ +theorem riemann_points (hab : a ≤ b) {N m i r : ℕ} (hm : 0 < m) (hi : i < N) (hr : r < m) : + a + i * ((b - a) / N) ∈ Icc a b ∧ + a + ((i * m + r : ℕ) : ℝ) * ((b - a) / (N * m : ℕ)) ∈ Icc a b ∧ + a + i * ((b - a) / N) ≤ a + ((i * m + r : ℕ) : ℝ) * ((b - a) / (N * m : ℕ)) ∧ + a + ((i * m + r : ℕ) : ℝ) * ((b - a) / (N * m : ℕ)) - (a + i * ((b - a) / N)) ≤ + (b - a) / N := by + have hN : (0 : ℝ) < N := by exact_mod_cast (show 0 < N by omega) + have hm' : (0 : ℝ) < m := by exact_mod_cast hm + set h := (b - a) / N with hh + have h0 : 0 ≤ h := div_nonneg (by linarith) hN.le + have hs : ((i * m + r : ℕ) : ℝ) * ((b - a) / (N * m : ℕ)) = i * h + (r / m) * h := by + rw [hh]; push_cast; field_simp + have hr1 : (r : ℝ) / m ≤ 1 := by + rw [div_le_one hm']; exact_mod_cast hr.le + have hr0 : 0 ≤ (r : ℝ) / m := by positivity + have hi1 : (i : ℝ) + 1 ≤ N := by exact_mod_cast hi + have hNh : (N : ℝ) * h = b - a := by rw [hh]; field_simp + have hi0 : (0 : ℝ) ≤ i := by positivity + rw [hs] + refine ⟨⟨by nlinarith, by nlinarith⟩, ⟨by nlinarith, by nlinarith⟩, by nlinarith, by nlinarith⟩ + +omit [TopologicalSpace F] [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] in +/-- Comparison of a Riemann sum with a refinement: if the increments of `γ` over steps of +length at most `(b - a) / N` lie in a convex set `V`, then the difference lies in `(b - a) • V`. -/ +theorem riemannSum_mul_sub_mem (hab : a ≤ b) {N m : ℕ} (hN : 0 < N) (hm : 0 < m) {V : Set F} + (hV : Convex ℝ V) + (hγV : ∀ s ∈ Icc a b, ∀ t ∈ Icc a b, t ≤ s → s - t ≤ (b - a) / N → γ s - γ t ∈ V) : + riemannSum γ a b (N * m) - riemannSum γ a b N ∈ (b - a) • V := by + have hN' : (0 : ℝ) < N := by exact_mod_cast hN + have hm' : (0 : ℝ) < m := by exact_mod_cast hm + set fine : ℕ × ℕ → ℝ := fun p ↦ a + ((p.1 * m + p.2 : ℕ) : ℝ) * ((b - a) / (N * m : ℕ)) + set coarse : ℕ → ℝ := fun i ↦ a + i * ((b - a) / N) + have key : riemannSum γ a b (N * m) - riemannSum γ a b N = (b - a) • + ∑ p ∈ range N ×ˢ range m, (1 / ((N : ℝ) * m)) • (γ (fine p) - γ (coarse p.1)) := by + simp only [riemannSum, sum_range_mul, Finset.sum_product, smul_sub, Finset.sum_sub_distrib, + Finset.sum_const, Finset.card_range, ← Finset.smul_sum, smul_smul] + congr 1 + · congr 1 + push_cast; field_simp + · rw [Finset.smul_sum, ← Nat.cast_smul_eq_nsmul ℝ, Finset.smul_sum, Finset.smul_sum] + refine Finset.sum_congr rfl fun i _ ↦ ?_ + rw [smul_smul, show (b - a) * (1 / ((N : ℝ) * m)) * m = (b - a) / N by field_simp] + rw [key] + refine smul_mem_smul_set (hV.sum_mem (fun _ _ ↦ by positivity) ?_ fun p hp ↦ ?_) + · rw [Finset.sum_const, Finset.card_product, Finset.card_range, Finset.card_range, + nsmul_eq_mul] + push_cast; field_simp + · rw [Finset.mem_product, Finset.mem_range, Finset.mem_range] at hp + obtain ⟨h1, h2, h3, h4⟩ := riemann_points hab hm hp.1 hp.2 + exact hγV _ h2 _ h1 h3 h4 + +/-- Riemann sums of a continuous real function converge to its integral. -/ +theorem tendsto_riemannSum_real {g : ℝ → ℝ} {a b : ℝ} (hab : a ≤ b) + (hg : ContinuousOn g (Icc a b)) : + Tendsto (riemannSum g a b) atTop (𝓝 (∫ t in a..b, g t)) := by + rw [Metric.tendsto_atTop] + intro ε hε + set ε' := ε / (2 * (b - a + 1)) + have hε' : 0 < ε' := by positivity + obtain ⟨δ, hδ, hgδ⟩ := Metric.uniformContinuousOn_iff_le.mp + (isCompact_Icc.uniformContinuousOn_of_continuous hg) ε' hε' + obtain ⟨N₀, hN₀⟩ := exists_nat_gt ((b - a) / δ) + refine ⟨N₀ + 1, fun N hN ↦ ?_⟩ + have hNpos : (0 : ℝ) < N := by exact_mod_cast (show 0 < N by omega) + set h := (b - a) / N with hh + have h0 : 0 ≤ h := div_nonneg (by linarith) hNpos.le + have hhδ : h ≤ δ := by + rw [hh, div_le_iff₀ hNpos] + rw [div_lt_iff₀ hδ] at hN₀ + have : (N₀ : ℝ) + 1 ≤ N := by exact_mod_cast hN + nlinarith + set t : ℕ → ℝ := fun i ↦ a + i * h with ht + have htN : t N = b := by simp only [ht, hh]; field_simp; ring + have hsub : ∀ i < N, Icc (t i) (t (i + 1)) ⊆ Icc a b := by + intro i hi x hx + have hi1 : (i : ℝ) + 1 ≤ N := by exact_mod_cast hi + have hi0 : (0 : ℝ) ≤ i := by positivity + simp only [ht, Nat.cast_add, Nat.cast_one] at hx + have hNh : (N : ℝ) * h = b - a := by rw [hh]; field_simp + constructor <;> nlinarith [hx.1, hx.2] + have hle : ∀ i < N, t i ≤ t (i + 1) := fun i _ ↦ by + simp only [ht, Nat.cast_add, Nat.cast_one]; nlinarith + have hint : ∀ i < N, IntervalIntegrable g MeasureTheory.volume (t i) (t (i + 1)) := + fun i hi ↦ (hg.mono (hsub i hi)).intervalIntegrable_of_Icc (hle i hi) + have hsum := intervalIntegral.sum_integral_adjacent_intervals hint + have ht0 : t 0 = a := by simp [ht] + rw [ht0, htN] at hsum + have hR : riemannSum g a b N = ∑ i ∈ range N, ∫ x in t i..t (i + 1), g (t i) := by + simp only [riemannSum, smul_eq_mul, Finset.mul_sum, intervalIntegral.integral_const] + refine Finset.sum_congr rfl fun i _ ↦ ?_ + simp only [ht, Nat.cast_add, Nat.cast_one, ← hh] + ring + rw [Real.dist_eq, hR, ← hsum, ← Finset.sum_sub_distrib] + have hbound : ∀ i ∈ range N, |(∫ x in t i..t (i + 1), g (t i)) - ∫ x in t i..t (i + 1), g x| ≤ + ε' * h := by + intro i hi + rw [Finset.mem_range] at hi + rw [← intervalIntegral.integral_sub intervalIntegrable_const (hint i hi)] + have := intervalIntegral.norm_integral_le_of_norm_le_const (a := t i) (b := t (i + 1)) + (C := ε') (f := fun x ↦ g (t i) - g x) fun x hx ↦ by + rw [uIoc_of_le (hle i hi)] at hx + have hxI := hsub i hi (Ioc_subset_Icc_self hx) + have htI := hsub i hi (left_mem_Icc.mpr (hle i hi)) + have := hgδ (t i) htI x hxI (by + rw [Real.dist_eq, abs_sub_comm, abs_of_nonneg (by linarith [hx.1])] + have : t (i + 1) - t i = h := by simp only [ht, Nat.cast_add, Nat.cast_one]; ring + linarith [hx.2]) + rwa [Real.dist_eq] at this + have hti : t (i + 1) - t i = h := by simp only [ht, Nat.cast_add, Nat.cast_one]; ring + rw [Real.norm_eq_abs, hti, abs_of_nonneg h0] at this + exact this + calc |∑ i ∈ range N, ((∫ x in t i..t (i + 1), g (t i)) - ∫ x in t i..t (i + 1), g x)| + ≤ ∑ i ∈ range N, |(∫ x in t i..t (i + 1), g (t i)) - ∫ x in t i..t (i + 1), g x| := + Finset.abs_sum_le_sum_abs _ _ + _ ≤ ∑ _i ∈ range N, ε' * h := Finset.sum_le_sum hbound + _ = ε' * (b - a) := by + rw [Finset.sum_const, Finset.card_range, nsmul_eq_mul, hh]; field_simp + _ < ε := by + rw [show ε' = ε / (2 * (b - a + 1)) from rfl, div_mul_eq_mul_div, + div_lt_iff₀ (by positivity)] + nlinarith + +end Riemann + +/-! ### Existence of weak integrals -/ + +section Existence + +variable {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] + {γ : ℝ → F} {a b : ℝ} {y : F} + +omit [LocallyConvexSpace ℝ F] [T2Space F] [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] in +/-- If the dyadic Riemann sums of a continuous curve converge, the limit is its weak integral. -/ +theorem hasWeakIntegral_of_tendsto (hab : a ≤ b) (hγ : ContinuousOn γ (Icc a b)) + (h : Tendsto (fun k : ℕ ↦ riemannSum γ a b (2 ^ k)) atTop (𝓝 y)) : + HasWeakIntegral γ a b y := by + intro φ + have h1 : Tendsto (fun k : ℕ ↦ riemannSum (fun t ↦ φ (γ t)) a b (2 ^ k)) atTop (𝓝 (φ y)) := by + exact ((φ.continuous.tendsto y).comp h).congr fun k ↦ map_riemannSum φ _ + have h2 := (tendsto_riemannSum_real hab (φ.continuous.comp_continuousOn hγ)).comp + (tendsto_atTop_mono (fun k ↦ (Nat.lt_two_pow_self (n := k)).le) tendsto_id) + exact tendsto_nhds_unique h1 h2 + +omit [Module ℝ F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] in +/-- Uniform continuity of continuous curves on compact intervals. -/ +theorem exists_pos_forall_sub_mem (hγ : ContinuousOn γ (Icc a b)) {W : Set F} + (hW : W ∈ 𝓝 (0 : F)) : + ∃ δ > 0, ∀ s ∈ Icc a b, ∀ t ∈ Icc a b, |s - t| < δ → γ s - γ t ∈ W := by + let := IsTopologicalAddGroup.rightUniformSpace F + have hu := isCompact_Icc.uniformContinuousOn_of_continuous hγ + have hmem : {p : F × F | p.2 + -p.1 ∈ W} ∈ uniformity F := by + rw [uniformity_eq_comap_nhds_zero']; exact preimage_mem_comap hW + have h1 := hu hmem + rw [Filter.mem_map, mem_inf_principal] at h1 + obtain ⟨δ, hδ, hδs⟩ := Metric.mem_uniformity_dist.mp h1 + refine ⟨δ, hδ, fun s hs t ht hst ↦ ?_⟩ + have := hδs (a := t) (b := s) (by rwa [Real.dist_eq, abs_sub_comm]) ⟨ht, hs⟩ + simpa [sub_eq_add_neg] using this + +omit [T2Space F] in +/-- In a sequentially complete space, continuous curves have weak integrals. -/ +theorem exists_hasWeakIntegral_of_le [SeqComplete F] (hab : a ≤ b) + (hγ : ContinuousOn γ (Icc a b)) : ∃ y, HasWeakIntegral γ a b y := by + suffices hC : ∀ V ∈ 𝓝 (0 : F), ∃ K, ∀ k ≥ K, ∀ l ≥ k, + riemannSum γ a b (2 ^ l) - riemannSum γ a b (2 ^ k) ∈ V by + obtain ⟨y, hy⟩ := SeqComplete.exists_tendsto _ (cauchy_of_forall_ge hC) + exact ⟨y, hasWeakIntegral_of_tendsto hab hγ hy⟩ + intro V hV + have hc : b - a + 1 ≠ 0 := by linarith + obtain ⟨W, hW, -, hWc, hWV⟩ := exists_closed_convex_nhds_subset + ((set_smul_mem_nhds_zero_iff (inv_ne_zero hc)).mpr hV) + obtain ⟨δ, hδ, hγδ⟩ := exists_pos_forall_sub_mem hγ hW + obtain ⟨K, hK⟩ := exists_nat_gt ((b - a) / δ) + refine ⟨K, fun k hk l hl ↦ ?_⟩ + have hpow : (2 : ℕ) ^ l = 2 ^ k * 2 ^ (l - k) := by rw [← pow_add]; congr 1; omega + have h2k : ((b - a) / δ) < (2 : ℝ) ^ k := by + calc (b - a) / δ < K := hK + _ ≤ (2 : ℝ) ^ K := by exact_mod_cast (Nat.lt_two_pow_self).le + _ ≤ 2 ^ k := pow_le_pow_right₀ one_le_two hk + have hmem := riemannSum_mul_sub_mem (γ := γ) hab (N := 2 ^ k) (m := 2 ^ (l - k)) + (by positivity) (by positivity) hWc fun s hs t ht hts hst ↦ hγδ s hs t ht (by + rw [abs_of_nonneg (by linarith)] + refine lt_of_le_of_lt hst ?_ + push_cast + rw [div_lt_iff₀ (by positivity)] + rw [div_lt_iff₀ hδ] at h2k + linarith) + simp only [hpow] + -- `(b - a) • W ⊆ (b - a + 1) • W ⊆ V` + obtain ⟨w, hw, hw'⟩ := hmem + rw [← hw'] + have hc' : 0 < b - a + 1 := by linarith + have hw2 : ((b - a) / (b - a + 1)) • w ∈ W := hWc.smul_mem_of_zero_mem (mem_of_mem_nhds hW) hw + ⟨div_nonneg (by linarith) hc'.le, (div_le_one hc').mpr (by linarith)⟩ + have := hWV hw2 + rw [mem_smul_set_iff_inv_smul_mem₀ (inv_ne_zero hc), inv_inv, smul_smul] at this + rwa [show (b - a + 1) * ((b - a) / (b - a + 1)) = b - a by field_simp] at this + +omit [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem HasWeakIntegral.symm (hy : HasWeakIntegral γ a b y) : HasWeakIntegral γ b a (-y) := by + intro φ + rw [map_neg, hy φ, intervalIntegral.integral_symm, neg_neg] + +omit [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem hasWeakIntegral_same (γ : ℝ → F) (a : ℝ) : HasWeakIntegral γ a a 0 := by + intro φ; simp + +omit [T2Space F] in +/-- In a sequentially complete space, continuous curves have weak integrals. -/ +theorem exists_hasWeakIntegral [SeqComplete F] (hγ : ContinuousOn γ (uIcc a b)) : + ∃ y, HasWeakIntegral γ a b y := by + rcases le_total a b with hab | hba + · exact exists_hasWeakIntegral_of_le hab (by rwa [uIcc_of_le hab] at hγ) + · obtain ⟨y, hy⟩ := exists_hasWeakIntegral_of_le hba (by rwa [uIcc_of_ge hba] at hγ) + exact ⟨-y, hy.symm⟩ + +omit [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [T2Space F] in +/-- In a locally convex space, the convex hull of a bounded set is bounded. -/ +theorem isVonNBounded_convexHull {B : Set F} (hB : Bornology.IsVonNBounded ℝ B) : + Bornology.IsVonNBounded ℝ (convexHull ℝ B) := by + intro V hV + obtain ⟨W, ⟨hW, hWc⟩, hWV⟩ := (LocallyConvexSpace.convex_basis (𝕜 := ℝ) (0 : F)).mem_iff.mp hV + exact Absorbs.mono_left (Filter.Eventually.mono (hB hW) fun c hc ↦ + convexHull_min hc (hWc.smul c)) hWV + +/-- Mean value inclusion for curves: increments over steps of length at most `h` lie in +`h • B`, where `B` is the closed convex hull of `[0, 1] • γ'([a, b])`. -/ +theorem sub_mem_smul_closure_convexHull {γ' : ℝ → F} (hγ' : ContinuousOn γ' (Icc a b)) + (hd : ∀ t ∈ Icc a b, HasDirDerivAt γ t 1 (γ' t)) {h : ℝ} (hh : 0 < h) {s t : ℝ} + (hs : s ∈ Icc a b) (ht : t ∈ Icc a b) (hts : t ≤ s) (hst : s - t ≤ h) : + γ s - γ t ∈ h • closure (convexHull ℝ + ((fun p : ℝ × ℝ ↦ p.1 • γ' p.2) '' (Set.Icc 0 1 ×ˢ Set.Icc a b))) := by + set B := + closure (convexHull ℝ ((fun p : ℝ × ℝ ↦ p.1 • γ' p.2) '' (Set.Icc 0 1 ×ˢ Set.Icc a b))) + have hpt : ∀ σ ∈ Icc (0 : ℝ) 1, t + σ • (s - t) ∈ Icc a b := fun σ hσ ↦ by + rw [smul_eq_mul] + constructor <;> nlinarith [hσ.1, hσ.2, hs.1, hs.2, ht.1, ht.2] + have hd' : ∀ σ ∈ Icc (0 : ℝ) 1, HasDirDerivAt γ (t + σ • (s - t)) (s - t) + ((s - t) • γ' (t + σ • (s - t))) := fun σ hσ ↦ by + have := (hd _ (hpt σ hσ)).smul_dir (s - t) + simpa only [smul_eq_mul, mul_one] using this + have hD : ContinuousOn (fun σ : ℝ ↦ (s - t) • γ' (t + σ • (s - t))) (Icc 0 1) := + (continuous_const_smul _).comp_continuousOn + (hγ'.comp (by fun_prop : Continuous fun σ : ℝ ↦ t + σ • (s - t)).continuousOn hpt) + have := sub_mem_of_hasDirDerivAt (W := h • B) hd' hD ((convex_convexHull ℝ _).closure.smul h) + (isClosed_closure.smul_of_ne_zero hh.ne') fun σ hσ ↦ by + have hmem : ((s - t) / h, t + σ • (s - t)) ∈ Set.Icc (0 : ℝ) 1 ×ˢ Set.Icc a b := + ⟨⟨div_nonneg (sub_nonneg.mpr hts) hh.le, (div_le_one hh).mpr hst⟩, hpt σ hσ⟩ + have hB : ((s - t) / h) • γ' (t + σ • (s - t)) ∈ B := subset_closure (subset_convexHull ℝ _ + (Set.mem_image_of_mem (fun p : ℝ × ℝ ↦ p.1 • γ' p.2) hmem)) + refine (mem_smul_set_iff_inv_smul_mem₀ hh.ne' _ _).mpr ?_ + convert hB using 1 + rw [smul_smul]; congr 1; field_simp + rwa [add_sub_cancel] at this + +/-- In a Mackey complete space, `C^1` curves have weak integrals. -/ +theorem exists_hasWeakIntegral_of_hasDirDerivAt_of_le [MackeyComplete F] (hab : a ≤ b) + (hγ : ContinuousOn γ (Icc a b)) {γ' : ℝ → F} (hγ' : ContinuousOn γ' (Icc a b)) + (hd : ∀ t ∈ Icc a b, HasDirDerivAt γ t 1 (γ' t)) : ∃ y, HasWeakIntegral γ a b y := by + rcases hab.eq_or_lt with rfl | hlt + · exact ⟨0, hasWeakIntegral_same γ a⟩ + set C := (fun p : ℝ × ℝ ↦ p.1 • γ' p.2) '' (Set.Icc 0 1 ×ˢ Set.Icc a b) + have hC : IsCompact C := (isCompact_Icc.prod isCompact_Icc).image_of_continuousOn + (continuous_fst.continuousOn.smul (hγ'.comp continuous_snd.continuousOn fun p hp ↦ hp.2)) + have hB : Bornology.IsVonNBounded ℝ (closure (convexHull ℝ C)) := + (isVonNBounded_convexHull (hC.isVonNBounded (𝕜 := ℝ))).closure + have hr : Tendsto (fun k : ℕ ↦ (b - a) * ((b - a) / 2 ^ k)) atTop (𝓝 0) := by + simpa using tendsto_const_nhds.mul (tendsto_const_nhds.div_atTop + (tendsto_pow_atTop_atTop_of_one_lt (one_lt_two (α := ℝ)))) + obtain ⟨y, hy⟩ := MackeyComplete.exists_tendsto (fun k : ℕ ↦ riemannSum γ a b (2 ^ k)) _ _ hB hr + fun k l hkl ↦ by + have hpow : (2 : ℕ) ^ l = 2 ^ k * 2 ^ (l - k) := by rw [← pow_add]; congr 1; omega + have hk : (0 : ℝ) < (b - a) / 2 ^ k := div_pos (by linarith) (by positivity) + have hmem := riemannSum_mul_sub_mem (γ := γ) hab (N := 2 ^ k) (m := 2 ^ (l - k)) + (by positivity) (by positivity) ((convex_convexHull ℝ C).closure.smul ((b - a) / 2 ^ k)) + fun s hs t ht hts hst ↦ sub_mem_smul_closure_convexHull hγ' hd hk hs ht hts + (by push_cast at hst; exact hst) + simp only [hpow] + rwa [smul_smul] at hmem + exact ⟨y, hasWeakIntegral_of_tendsto hab hγ hy⟩ + +/-- In a Mackey complete space, `C^1` curves have weak integrals. -/ +theorem ContDiffMBOn.exists_hasWeakIntegral [MackeyComplete F] {T : Set ℝ} + (hTab : uIcc a b ⊆ T) (hγ : ContDiffMBOn 1 γ T) : ∃ y, HasWeakIntegral γ a b y := by + have h2 : ContinuousOn (dMB γ) (T ×ˢ univ) := hγ.2.2 + have hγ' : ContinuousOn (fun t ↦ dMB γ (t, 1)) T := + h2.comp (by fun_prop : Continuous fun t : ℝ ↦ (t, (1 : ℝ))).continuousOn + fun t ht ↦ ⟨ht, mem_univ _⟩ + rcases le_total a b with hab | hba + · rw [uIcc_of_le hab] at hTab + exact exists_hasWeakIntegral_of_hasDirDerivAt_of_le hab (hγ.continuousOn.mono hTab) + (hγ'.mono hTab) fun t ht ↦ hγ.2.1 t (hTab ht) 1 + · rw [uIcc_of_ge hba] at hTab + obtain ⟨y, hy⟩ := exists_hasWeakIntegral_of_hasDirDerivAt_of_le hba + (hγ.continuousOn.mono hTab) (hγ'.mono hTab) fun t ht ↦ hγ.2.1 t (hTab ht) 1 + exact ⟨-y, hy.symm⟩ + +end Existence + +/-! ### Parameter-dependent integrals -/ + +section Param + +variable {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] + {γ : ℝ → F} {a b : ℝ} {y : F} + +/-- The weak integral of `γ` over `[a, b]` (junk value `0` if it does not exist). -/ +def weakIntegral (γ : ℝ → F) (a b : ℝ) : F := + open Classical in + if h : ∃ y, HasWeakIntegral γ a b y then h.choose else 0 + +theorem HasWeakIntegral.weakIntegral_eq (hy : HasWeakIntegral γ a b y) : + weakIntegral γ a b = y := by + have h : ∃ y, HasWeakIntegral γ a b y := ⟨y, hy⟩ + rw [weakIntegral, dite_eq_left_of_eq_true (eq_true h)] + exact h.choose_spec.unique hy + +theorem hasWeakIntegral_weakIntegral (h : ∃ y, HasWeakIntegral γ a b y) : + HasWeakIntegral γ a b (weakIntegral γ a b) := by + obtain ⟨y, hy⟩ := h + rwa [hy.weakIntegral_eq] + +/-- `φ (∫_a^b γ) = ∫_a^b φ ∘ γ`, when the weak integral exists. -/ +theorem map_weakIntegral (h : ∃ y, HasWeakIntegral γ a b y) (φ : F →L[ℝ] ℝ) : + φ (weakIntegral γ a b) = ∫ t in a..b, φ (γ t) := + hasWeakIntegral_weakIntegral h φ + +/-- The induction behind the `C^k` results: if every `C^m` map on `U ×ˢ T` has weak integrals +along `[a, b]` in the second variable, then `C^(k + m)` maps give `C^k` integrals. -/ +theorem contDiffMBOn_weakIntegral_of_exists {T : Set ℝ} (hT : IsOpen T) (hab : a ≤ b) + (hTab : Icc a b ⊆ T) (m : ℕ) + (hP : ∀ {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + (f : E × ℝ → F) (U : Set E), IsOpen U → ContDiffMBOn m f (U ×ˢ T) → + ∀ x ∈ U, ∃ y, HasWeakIntegral (fun t ↦ f (x, t)) a b y) : + ∀ (k : ℕ) {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + {f : E × ℝ → F} {U : Set E}, IsOpen U → ContDiffMBOn (k + m) f (U ×ˢ T) → + ContDiffMBOn k (fun x ↦ weakIntegral (fun t ↦ f (x, t)) a b) U := by + intro k + induction k with + | zero => + intro E _ _ _ _ _ _ _ f U hU hf + rw [zero_add] at hf + exact continuousOn_weakIntegral hU hT hab hTab hf.continuousOn + fun x hx ↦ hasWeakIntegral_weakIntegral (hP f U hU hf x hx) + | succ k ih => + intro E _ _ _ _ _ _ _ f U hU hf + have hf' : ContDiffMBOn (k + m + 1) f (U ×ˢ T) := by + rwa [show k + m + 1 = k + 1 + m by omega] + have hI : ∀ x ∈ U, HasWeakIntegral (fun t ↦ f (x, t)) a b + (weakIntegral (fun t ↦ f (x, t)) a b) := fun x hx ↦ + hasWeakIntegral_weakIntegral (hP f U hU (hf.of_le (by omega)) x hx) + -- the partial derivative, as a map on `(E × E) × ℝ` + let L : (E × E) × ℝ →L[ℝ] (E × ℝ) × (E × ℝ) := + (((ContinuousLinearMap.fst ℝ E E).comp (ContinuousLinearMap.fst ℝ (E × E) ℝ)).prod + (ContinuousLinearMap.snd ℝ (E × E) ℝ)).prod + (((ContinuousLinearMap.snd ℝ E E).comp (ContinuousLinearMap.fst ℝ (E × E) ℝ)).prod 0) + have hL : ∀ q, L q = ((q.1.1, q.2), (q.1.2, 0)) := fun q ↦ rfl + have hpre : L ⁻¹' ((U ×ˢ T) ×ˢ univ) = (U ×ˢ univ) ×ˢ T := by + ext q; simp [hL] + have hg := ContDiffMBOn.comp_clm L ((hU.prod hT).prod isOpen_univ) hf'.2.2 + rw [hpre] at hg + have hJ := ih (hU.prod isOpen_univ) hg + have hJex : ∀ x ∈ U, ∀ h, HasWeakIntegral (fun t ↦ dMB f ((x, t), (h, 0))) a b + (weakIntegral (fun t ↦ dMB f ((x, t), (h, 0))) a b) := fun x hx h ↦ + hasWeakIntegral_weakIntegral (hP _ _ (hU.prod isOpen_univ) (hg.of_le (by omega)) (x, h) + ⟨hx, mem_univ _⟩) + obtain ⟨hC1, heq⟩ := ContDiffMBOn.contDiffMBOn_one_of_hasWeakIntegral hU hT hab hTab + (hf.of_le (by omega)) hI + (J := fun q ↦ weakIntegral (fun t ↦ dMB f ((q.1, t), (q.2, 0))) a b) hJex + refine ⟨hC1.1, hC1.2.1, ContDiffMBOn.congr_of_isOpen (hU.prod isOpen_univ) + (fun q hq ↦ (heq q.1 hq.1 q.2).symm) ?_⟩ + exact hJ + +/-- Parameter-dependent integrals in sequentially complete spaces: if `f` is `C^k` on +`U ×ˢ T`, then `x ↦ ∫_a^b f (x, t) dt` is `C^k` on `U`. -/ +theorem ContDiffMBOn.contDiffMBOn_weakIntegral [SeqComplete F] {T : Set ℝ} (hT : IsOpen T) + (hab : a ≤ b) (hTab : Icc a b ⊆ T) {k : ℕ} {f : E × ℝ → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn k f (U ×ˢ T)) : + ContDiffMBOn k (fun x ↦ weakIntegral (fun t ↦ f (x, t)) a b) U := + contDiffMBOn_weakIntegral_of_exists hT hab hTab 0 + (fun f U _ hf x hx ↦ exists_hasWeakIntegral_of_le hab + (hf.continuousOn.comp (by fun_prop : Continuous fun t : ℝ ↦ (x, t)).continuousOn + fun t ht ↦ ⟨hx, hTab ht⟩)) k hU hf + +/-- Parameter-dependent integrals in Mackey complete spaces: if `f` is `C^(k+1)` on +`U ×ˢ T`, then `x ↦ ∫_a^b f (x, t) dt` is `C^k` on `U`. -/ +theorem ContDiffMBOn.contDiffMBOn_weakIntegral_of_mackey [MackeyComplete F] {T : Set ℝ} + (hT : IsOpen T) (hab : a ≤ b) (hTab : Icc a b ⊆ T) {k : ℕ} {f : E × ℝ → F} {U : Set E} + (hU : IsOpen U) (hf : ContDiffMBOn (k + 1) f (U ×ˢ T)) : + ContDiffMBOn k (fun x ↦ weakIntegral (fun t ↦ f (x, t)) a b) U := by + refine contDiffMBOn_weakIntegral_of_exists hT hab hTab 1 + (@fun E' _ _ _ _ _ _ _ f U _ hf x hx ↦ ?_) k hU hf + have h2 : ContinuousOn (dMB f) ((U ×ˢ T) ×ˢ univ) := hf.2.2 + refine exists_hasWeakIntegral_of_hasDirDerivAt_of_le hab + (hf.continuousOn.comp (by fun_prop : Continuous fun t : ℝ ↦ (x, t)).continuousOn + fun t ht ↦ ⟨hx, hTab ht⟩) + (γ' := fun t ↦ dMB f ((x, t), (0, 1))) + (h2.comp (by fun_prop : Continuous fun t : ℝ ↦ ((x, t), ((0 : E'), (1 : ℝ)))).continuousOn + fun t ht ↦ ⟨⟨hx, hTab ht⟩, mem_univ _⟩) fun t ht ↦ ?_ + exact (hf.2.1 (x, t) ⟨hx, hTab ht⟩ (0, 1)).congr fun s ↦ by simp + +/-- Smooth parameter-dependent integrals in Mackey complete spaces. -/ +theorem SmoothMBOn.smoothMBOn_weakIntegral [MackeyComplete F] {T : Set ℝ} (hT : IsOpen T) + (hab : a ≤ b) (hTab : Icc a b ⊆ T) {f : E × ℝ → F} {U : Set E} (hU : IsOpen U) + (hf : SmoothMBOn f (U ×ˢ T)) : + SmoothMBOn (fun x ↦ weakIntegral (fun t ↦ f (x, t)) a b) U := fun k ↦ + ContDiffMBOn.contDiffMBOn_weakIntegral_of_mackey hT hab hTab hU (hf (k + 1)) + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- Differentiation under the integral sign, sequentially complete case: +`d(∫_a^b f(·, t) dt)(x)(h) = ∫_a^b d₁f((x, t), h) dt` for `f` of class `C^1`. -/ +theorem ContDiffMBOn.dMB_weakIntegral [SeqComplete F] {T : Set ℝ} (hT : IsOpen T) + (hab : a ≤ b) (hTab : Icc a b ⊆ T) {f : E × ℝ → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn 1 f (U ×ˢ T)) {x : E} (hx : x ∈ U) (h : E) : + dMB (fun x ↦ weakIntegral (fun t ↦ f (x, t)) a b) (x, h) = + weakIntegral (fun t ↦ dMB f ((x, t), (h, 0))) a b := by + have hcurve : ∀ x ∈ U, ContinuousOn (fun t ↦ f (x, t)) (Icc a b) := fun x hx ↦ + hf.continuousOn.comp (by fun_prop : Continuous fun t : ℝ ↦ (x, t)).continuousOn + fun t ht ↦ ⟨hx, hTab ht⟩ + have h2 : ContinuousOn (dMB f) ((U ×ˢ T) ×ˢ univ) := hf.2.2 + refine (ContDiffMBOn.contDiffMBOn_one_of_hasWeakIntegral hU hT hab hTab hf + (fun x hx ↦ hasWeakIntegral_weakIntegral (exists_hasWeakIntegral_of_le hab (hcurve x hx))) + (J := fun q ↦ weakIntegral (fun t ↦ dMB f ((q.1, t), (q.2, 0))) a b) + (fun x hx h ↦ hasWeakIntegral_weakIntegral (exists_hasWeakIntegral_of_le hab + (h2.comp (by fun_prop : Continuous fun t : ℝ ↦ ((x, t), (h, (0 : ℝ)))).continuousOn + fun t ht ↦ ⟨⟨hx, hTab ht⟩, mem_univ _⟩)))).2 x hx h + +end Param + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/MBFrechet.lean b/LeanPool/LCAnalysis/MBFrechet.lean new file mode 100644 index 0000000000..b2ba6c8865 --- /dev/null +++ b/LeanPool/LCAnalysis/MBFrechet.lean @@ -0,0 +1,512 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import Mathlib.Analysis.Calculus.ContDiff.Operations +public import LeanPool.LCAnalysis.MichalBastiani + +/-! +# Michal–Bastiani `C^{k+1}` maps between normed spaces are Fréchet `C^k` + +Neeb–Glöckner, *Infinite-Dimensional Lie Groups* (arXiv:2602.12362), Proposition 2.3.17 (b). +Their proof goes through the compact-open topology on `L(E, F)` and the exponential law +(Theorem 1.7.30). Here we give a proof that stays in normed spaces: derivatives are tracked as +continuous multilinear maps with the operator norm. We show, by induction on `k` and for all `m` +simultaneously: + +> if `g : U → L^m(E; F)` is such that `(x, v₁, …, vₘ) ↦ g x (v₁, …, vₘ)` is `C^{k+1}` in the +> sense of Michal–Bastiani, then `g` is Fréchet `C^k`. + +The derivative of `g` is `curryLeft ∘ B`, where `B y (w, v) = d(ĝ)((y, v), (w, 0))` is +`(m + 1)`-multilinear and is handled by the case `(k, m + 1)`. For `m = 0` we get the result for +maps `f : U → F`. +-/ + +@[expose] public section + +open Set Filter +open scoped Topology ContDiff + +noncomputable section + +namespace LCAnalysis + +universe u v + +variable {E : Type u} [NormedAddCommGroup E] [NormedSpace ℝ E] + {F : Type v} [NormedAddCommGroup F] [NormedSpace ℝ F] + +/-- The uncurried version `(x, v) ↦ g x v` of `g : E → L^m(E; F)`. -/ +def unc {m : ℕ} (g : E → ContinuousMultilinearMap ℝ (fun _ : Fin m ↦ E) F) : + E × (Fin m → E) → F := + fun p ↦ g p.1 p.2 + +/-- `B y u = d(ĝ)((y, tail u), (u 0, 0))`: the derivative of `ĝ` in the base direction `u 0`. -/ +def secondB {m : ℕ} (g : E → ContinuousMultilinearMap ℝ (fun _ : Fin m ↦ E) F) (y : E) + (u : Fin (m + 1) → E) : F := + dMB (unc g) ((y, Fin.tail u), (u 0, 0)) + +/-! ### Comparison with Fréchet differentiability (Remark I.2.2) + +On normed spaces, `C^{k+1}_{MB} ⇒ C^k` (Fréchet) `⇒ C^k_{MB}`; in particular both notions of +smoothness agree. -/ + +section Normed + +variable {E' : Type u} {F' : Type v} [NormedAddCommGroup E'] [NormedSpace ℝ E'] + [NormedAddCommGroup F'] [NormedSpace ℝ F'] + +/-- A Fréchet derivative gives the directional derivatives. -/ +theorem _root_.HasFDerivAt.hasDirDerivAt {E₁ : Type*} [NormedAddCommGroup E₁] [NormedSpace ℝ E₁] + {f : E₁ → F'} {L : E₁ →L[ℝ] F'} {x : E₁} (hf : HasFDerivAt f L x) (h : E₁) : + HasDirDerivAt f x h (L h) := by + have hline : HasDerivAt (fun t : ℝ ↦ x + t • h) h 0 := by + simpa using ((hasDerivAt_id (0 : ℝ)).smul_const h).const_add x + have hc : HasDerivAt (fun t : ℝ ↦ f (x + t • h)) (L h) 0 := by + have hf' : HasFDerivAt f L (x + (0 : ℝ) • h) := by simpa using hf + simpa [Function.comp_def] using HasFDerivAt.comp_hasDerivAt (0 : ℝ) hf' hline + simpa [HasDirDerivAt] using hc.tendsto_slope_zero + +/-- Remark I.2.2: Fréchet `C^k` maps are `C^k` in the sense of Michal–Bastiani. -/ +theorem ContDiffOn.contDiffMBOn : ∀ {k : ℕ} {E₁ : Type u} [NormedAddCommGroup E₁] + [NormedSpace ℝ E₁] {f : E₁ → F'} {U : Set E₁}, IsOpen U → ContDiffOn ℝ k f U → + ContDiffMBOn k f U := by + intro k + induction k with + | zero => + intro E₁ _ _ f U hU hf + exact hf.continuousOn + | succ k ih => + intro E₁ _ _ f U hU hf + have hdiff : ∀ x ∈ U, HasFDerivAt f (fderiv ℝ f x) x := fun x hx ↦ + ((hf.differentiableOn (by simp) x hx).differentiableAt (hU.mem_nhds hx)).hasFDerivAt + have hd : ∀ x ∈ U, ∀ h, HasDirDerivAt f x h (fderiv ℝ f x h) := + fun x hx h ↦ (hdiff x hx).hasDirDerivAt h + have heq : EqOn (fun p : E₁ × E₁ ↦ fderiv ℝ f p.1 p.2) (dMB f) (U ×ˢ univ) := + fun p hp ↦ ((hd p.1 hp.1 p.2).dMB_eq).symm + have hfd : ContDiffOn ℝ k (fun y ↦ fderiv ℝ f y) U := + hf.fderiv_of_isOpen hU (by push_cast; exact le_rfl) + have hc : ContDiffOn ℝ k (fun p : E₁ × E₁ ↦ fderiv ℝ f p.1 p.2) (U ×ˢ univ) := + (hfd.comp contDiffOn_fst fun p (hp : p ∈ U ×ˢ (univ : Set E₁)) ↦ hp.1).clm_apply + contDiffOn_snd + refine ⟨hf.continuousOn, fun x hx h ↦ ?_, + ContDiffMBOn.congr_of_isOpen (hU.prod isOpen_univ) heq (ih (hU.prod isOpen_univ) hc)⟩ + rw [← heq ⟨hx, mem_univ h⟩] + exact hd x hx h + +end Normed + +section Structure + +variable {m : ℕ} {g : E → ContinuousMultilinearMap ℝ (fun _ : Fin m ↦ E) F} + +theorem unc_line (y w : E) (V : Fin m → E) (t : ℝ) : + unc g ((y, V) + t • (w, (0 : Fin m → E))) = g (y + t • w) V := by + simp [unc] + +theorem hasDirDerivAt_unc_add {y w : E} {V V₁ V₂ : Fin m → E} {a b : F} + (h : ∀ z, g z V = g z V₁ + g z V₂) (h₁ : HasDirDerivAt (unc g) (y, V₁) (w, 0) a) + (h₂ : HasDirDerivAt (unc g) (y, V₂) (w, 0) b) : + HasDirDerivAt (unc g) (y, V) (w, 0) (a + b) := by + refine (Filter.Tendsto.add h₁ h₂).congr fun t ↦ ?_ + simp only [unc_line] + simp only [unc, h, ← smul_add] + congr 1 + abel + +theorem hasDirDerivAt_unc_smul {y w : E} {V V₁ : Fin m → E} {a : F} (c : ℝ) + (h : ∀ z, g z V = c • g z V₁) (h₁ : HasDirDerivAt (unc g) (y, V₁) (w, 0) a) : + HasDirDerivAt (unc g) (y, V) (w, 0) (c • a) := by + refine (h₁.const_smul c).congr fun t ↦ ?_ + simp only [unc_line] + simp only [unc, h, smul_sub, smul_comm c t⁻¹] + +variable {U : Set E} + +/-- For `y ∈ U`, `secondB g y` is `(m + 1)`-multilinear. -/ +def secondBML (hU : IsOpen U) (hg : ContDiffMBOn 1 (unc g) (U ×ˢ univ)) {y : E} (hy : y ∈ U) : + MultilinearMap ℝ (fun _ : Fin (m + 1) ↦ E) F where + toFun := secondB g y + map_update_add' := by + intro inst u i a b + obtain rfl : inst = instDecidableEqFin (m + 1) := Subsingleton.elim _ _ + have hd : ∀ (V : Fin m → E) (w : E), + HasDirDerivAt (unc g) (y, V) (w, 0) (dMB (unc g) ((y, V), (w, 0))) := + fun V w ↦ hg.2.1 _ ⟨hy, mem_univ _⟩ _ + cases i using Fin.cases with + | zero => + simp only [secondB, Fin.tail_update_zero, Function.update_self] + rw [show ((a + b, 0) : E × (Fin m → E)) = (a, 0) + (b, 0) by simp] + exact hg.dMB_add (hU.prod isOpen_univ) ⟨hy, mem_univ _⟩ _ _ + | succ j => + simp only [secondB, Fin.tail_update_succ, + Function.update_of_ne (Fin.succ_ne_zero j).symm] + exact (hasDirDerivAt_unc_add (fun z ↦ (g z).map_update_add _ _ _ _) + (hd _ _) (hd _ _)).dMB_eq + map_update_smul' := by + intro inst u i c a + obtain rfl : inst = instDecidableEqFin (m + 1) := Subsingleton.elim _ _ + cases i using Fin.cases with + | zero => + simp only [secondB, Fin.tail_update_zero, Function.update_self] + rw [show ((c • a, 0) : E × (Fin m → E)) = c • (a, 0) by simp] + exact hg.dMB_smul ⟨hy, mem_univ _⟩ _ _ + | succ j => + simp only [secondB, Fin.tail_update_succ, + Function.update_of_ne (Fin.succ_ne_zero j).symm] + exact (hasDirDerivAt_unc_smul c (fun z ↦ (g z).map_update_smul _ _ _ _) + (hg.2.1 _ ⟨hy, mem_univ _⟩ _)).dMB_eq + +theorem secondBML_apply (hU : IsOpen U) (hg : ContDiffMBOn 1 (unc g) (U ×ˢ univ)) {y : E} + (hy : y ∈ U) (u : Fin (m + 1) → E) : secondBML hU hg hy u = secondB g y u := rfl + +theorem continuousOn_secondB (hg : ContDiffMBOn 1 (unc g) (U ×ˢ univ)) : + ContinuousOn (fun p : E × (Fin (m + 1) → E) ↦ secondB g p.1 p.2) (U ×ˢ univ) := by + have h0 : ContinuousOn (dMB (unc g)) ((U ×ˢ univ) ×ˢ univ) := hg.2.2 + have hΛ : Continuous fun p : E × (Fin (m + 1) → E) ↦ + ((p.1, Fin.tail p.2), (p.2 0, (0 : Fin m → E))) := by + unfold Fin.tail; fun_prop + exact h0.comp hΛ.continuousOn fun p hp ↦ ⟨⟨hp.1, mem_univ _⟩, mem_univ _⟩ + +/-- Local uniform bound for `secondB`. -/ +theorem secondB_bound (hU : IsOpen U) (hg : ContDiffMBOn 1 (unc g) (U ×ˢ univ)) {x : E} + (hx : x ∈ U) : ∃ δ > 0, ∃ C ≥ 0, ∀ y, ‖y - x‖ < δ → y ∈ U ∧ + ∀ u, ‖secondB g y u‖ ≤ C * ∏ i, ‖u i‖ := by + have hzero : secondB g x 0 = 0 := by + rw [← secondBML_apply hU hg hx]; exact (secondBML hU hg hx).map_zero + have hc : ContinuousAt (fun p : E × (Fin (m + 1) → E) ↦ secondB g p.1 p.2) (x, 0) := + (continuousOn_secondB hg).continuousAt (prod_mem_nhds (hU.mem_nhds hx) univ_mem) + obtain ⟨δ₀, hδ₀, hball⟩ := Metric.continuousAt_iff.mp hc 1 one_pos + obtain ⟨δ₁, hδ₁, hδ₁U⟩ := Metric.isOpen_iff.mp hU x hx + set δ := min δ₀ δ₁ + have hδ : 0 < δ := lt_min hδ₀ hδ₁ + refine ⟨δ, hδ, (2 / δ) ^ (m + 1), by positivity, fun y hy ↦ ?_⟩ + have hyU : y ∈ U := hδ₁U (by + rw [Metric.mem_ball, dist_eq_norm]; exact lt_of_lt_of_le hy (min_le_right _ _)) + refine ⟨hyU, fun u ↦ ?_⟩ + rw [← secondBML_apply hU hg hyU] + refine (secondBML hU hg hyU).bound_of_shell (ε := fun _ ↦ δ) (c := fun _ ↦ (2 : ℝ)) + (fun _ ↦ hδ) (fun _ ↦ by norm_num) (fun u hlo hhi ↦ ?_) u + have hlt : ‖secondB g y u‖ < 1 := by + have := hball (x := (y, u)) (by + rw [Prod.dist_eq, dist_eq_norm, dist_eq_norm, sub_zero] + refine max_lt (lt_of_lt_of_le hy (min_le_left _ _)) ?_ + refine (pi_norm_lt_iff hδ₀).mpr fun i ↦ lt_of_lt_of_le (hhi i) (min_le_left _ _)) + simpa [hzero] using this + rw [secondBML_apply] + have hprod : (δ / 2) ^ (m + 1) ≤ ∏ i, ‖u i‖ := by + have := Finset.prod_le_prod₀ (s := Finset.univ) (f := fun _ : Fin (m + 1) ↦ δ / 2) + (g := fun i ↦ ‖u i‖) (fun _ _ ↦ by positivity) + (fun i _ ↦ by simpa using hlo i) + simpa [div_pow] using this + calc ‖secondB g y u‖ ≤ 1 := hlt.le + _ = (2 / δ) ^ (m + 1) * (δ / 2) ^ (m + 1) := by + rw [← mul_pow]; field_simp; simp + _ ≤ (2 / δ) ^ (m + 1) * ∏ i, ‖u i‖ := by gcongr + +theorem hasDirDerivAt_unc_base (hg : ContDiffMBOn 1 (unc g) (U ×ˢ univ)) {p : E} (hp : p ∈ U) + (V : Fin m → E) (w : E) : + HasDirDerivAt (fun z ↦ g z V) p w (secondB g p (Fin.cons w V)) := by + have := hg.2.1 (p, V) ⟨hp, mem_univ _⟩ (w, 0) + simp only [secondB, Fin.tail_cons, Fin.cons_zero] + refine this.congr fun t ↦ ?_ + simp only [unc_line] + rfl + +omit [NormedSpace ℝ E] in +theorem norm_prod_cons (w : E) (V : Fin m → E) : + ∏ i, ‖(Fin.cons w V : Fin (m + 1) → E) i‖ = ‖w‖ * ∏ i, ‖V i‖ := by + rw [Fin.prod_univ_succ] + simp + +/-- `g` is locally Lipschitz in the operator norm. -/ +theorem lipschitz_of_unc (hU : IsOpen U) (hg : ContDiffMBOn 1 (unc g) (U ×ˢ univ)) {x : E} + (hx : x ∈ U) : ∃ δ > 0, ∃ C ≥ 0, ∀ y, ‖y - x‖ < δ → y ∈ U ∧ ‖g y - g x‖ ≤ C * ‖y - x‖ := by + obtain ⟨δ, hδ, C, hC, hb⟩ := secondB_bound hU hg hx + refine ⟨δ, hδ, C, hC, fun y hy ↦ ⟨(hb y hy).1, ?_⟩⟩ + have hseg : ∀ s ∈ Icc (0 : ℝ) 1, ‖x + s • (y - x) - x‖ < δ := fun s hs ↦ by + rw [add_sub_cancel_left, norm_smul, Real.norm_of_nonneg hs.1] + calc s * ‖y - x‖ ≤ 1 * ‖y - x‖ := by gcongr; exact hs.2 + _ < δ := by simpa using hy + refine ContinuousMultilinearMap.opNorm_le_bound (mul_nonneg hC (norm_nonneg _)) fun V ↦ ?_ + have hφ : Continuous fun s : ℝ ↦ + (x + s • (y - x), (Fin.cons (y - x) V : Fin (m + 1) → E)) := by fun_prop + have hDc' := (continuousOn_secondB (g := g) hg).comp hφ.continuousOn + (fun s (hs : s ∈ Icc (0 : ℝ) 1) ↦ ⟨(hb _ (hseg s hs)).1, mem_univ _⟩) + have hDc : ContinuousOn (fun s : ℝ ↦ secondB g (x + s • (y - x)) (Fin.cons (y - x) V)) + (Icc 0 1) := hDc' + have hmem := sub_mem_of_hasDirDerivAt (f := fun z ↦ g z V) (z := x) (w := y - x) + (fun s hs ↦ hasDirDerivAt_unc_base hg (hb _ (hseg s hs)).1 V (y - x)) hDc + (convex_closedBall 0 (C * ‖y - x‖ * ∏ i, ‖V i‖)) Metric.isClosed_closedBall + (fun s hs ↦ by + rw [mem_closedBall_zero_iff] + refine ((hb _ (hseg s hs)).2 _).trans (le_of_eq ?_) + rw [norm_prod_cons]; ring) + rw [mem_closedBall_zero_iff, add_sub_cancel] at hmem + rw [sub_apply] + exact hmem + +end Structure + +/-- The main induction: if `(x, v) ↦ g x v` is `C^{k+1}` in the sense of Michal–Bastiani, then +`g : U → L^m(E; F)` is Fréchet `C^k`. -/ +theorem contDiffOn_of_unc : ∀ (k m : ℕ) {g : E → ContinuousMultilinearMap ℝ (fun _ : Fin m ↦ E) F} + {U : Set E}, IsOpen U → ContDiffMBOn (k + 1) (unc g) (U ×ˢ univ) → ContDiffOn ℝ k g U := by + intro k + induction k with + | zero => + intro m g U hU hg + rw [Nat.cast_zero, contDiffOn_zero] + intro x hx + obtain ⟨δ, hδ, C, hC, hb⟩ := lipschitz_of_unc hU hg hx + refine Metric.continuousWithinAt_iff.mpr fun ε hε ↦ ⟨min δ (ε / (C + 1)), + lt_min hδ (by positivity), fun {y} _ hy ↦ ?_⟩ + rw [dist_eq_norm] at hy ⊢ + calc ‖g y - g x‖ ≤ C * ‖y - x‖ := (hb y (lt_of_lt_of_le hy (min_le_left _ _))).2 + _ ≤ (C + 1) * ‖y - x‖ := by gcongr; linarith + _ < (C + 1) * (ε / (C + 1)) := by gcongr; exact lt_of_lt_of_le hy (min_le_right _ _) + _ = ε := by field_simp + | succ k ih => + intro m g U hU hg + have hg1 : ContDiffMBOn 1 (unc g) (U ×ˢ univ) := hg.of_le (by omega) + classical + -- the second derivative as a continuous multilinear map + let Bc : E → ContinuousMultilinearMap ℝ (fun _ : Fin (m + 1) ↦ E) F := fun y ↦ + if hy : y ∈ U then + (secondBML hU hg1 hy).mkContinuous (secondB_bound hU hg1 hy).choose_spec.2.choose + fun u ↦ ((secondB_bound hU hg1 hy).choose_spec.2.choose_spec.2 y + (by simpa using (secondB_bound hU hg1 hy).choose_spec.1)).2 u + else 0 + have hBc : ∀ y ∈ U, ∀ u, Bc y u = secondB g y u := fun y hy u ↦ by + simp only [Bc, hy, ↓reduceDIte] + rfl + -- its uncurried version is `C^{k+1}` + have hBcMB : ContDiffMBOn (k + 1) (unc Bc) (U ×ˢ univ) := by + let P := Fin (m + 1) → E + let Λ : E × P →L[ℝ] (E × (Fin m → E)) × (E × (Fin m → E)) := + ((ContinuousLinearMap.fst ℝ E P).prod + ((ContinuousLinearMap.pi fun j : Fin m ↦ ContinuousLinearMap.proj (R := ℝ) + (φ := fun _ : Fin (m + 1) ↦ E) j.succ).comp (ContinuousLinearMap.snd ℝ E P))).prod + (((ContinuousLinearMap.proj (R := ℝ) (φ := fun _ : Fin (m + 1) ↦ E) 0).comp + (ContinuousLinearMap.snd ℝ E P)).prod 0) + have h2 : ContDiffMBOn (k + 1) (dMB (unc g)) ((U ×ˢ univ) ×ˢ univ) := hg.2.2 + have h3 := ContDiffMBOn.comp_clm Λ ((hU.prod isOpen_univ).prod isOpen_univ) h2 + have hpre : Λ ⁻¹' ((U ×ˢ univ) ×ˢ univ) = U ×ˢ univ := by ext p; simp [Λ] + rw [hpre] at h3 + refine ContDiffMBOn.congr_of_isOpen (hU.prod isOpen_univ) (fun p hp ↦ ?_) h3 + simp only [Function.comp_apply, unc] + rw [hBc p.1 hp.1] + rfl + have hBcC : ContDiffOn ℝ k Bc U := ih (m + 1) hU hBcMB + -- the candidate derivative + let D : E → E →L[ℝ] ContinuousMultilinearMap ℝ (fun _ : Fin m ↦ E) F := fun y ↦ + continuousMultilinearCurryLeftEquiv ℝ (fun _ : Fin (m + 1) ↦ E) F (Bc y) + have hDapply : ∀ y w V, D y w V = Bc y (Fin.cons w V) := fun _ _ _ ↦ rfl + have hder : ∀ y ∈ U, HasFDerivAt g (D y) y := by + intro y hy + refine HasFDerivAt.of_isLittleO (Asymptotics.isLittleO_iff.mpr fun c hc ↦ ?_) + have hcont : ContinuousAt Bc y := + (hBcC.continuousOn.continuousAt (hU.mem_nhds hy)) + have hev : ∀ᶠ p in 𝓝 y, p ∈ U ∧ ‖Bc p - Bc y‖ ≤ c := by + refine (hU.eventually_mem hy).and ?_ + have := Metric.continuousAt_iff.mp hcont c hc + obtain ⟨δ, hδ, hδ'⟩ := this + filter_upwards [Metric.ball_mem_nhds y hδ] with p hp + exact (by simpa [dist_eq_norm] using hδ' hp : ‖Bc p - Bc y‖ < c).le + obtain ⟨δ, hδ, hδ'⟩ := Metric.eventually_nhds_iff.mp hev + filter_upwards [Metric.ball_mem_nhds y hδ] with z hz + have hz' : ‖z - y‖ < δ := by simpa [dist_eq_norm] using hz + have hseg : ∀ s ∈ Icc (0 : ℝ) 1, dist (y + s • (z - y)) y < δ := fun s hs ↦ by + rw [dist_eq_norm, add_sub_cancel_left, norm_smul, Real.norm_of_nonneg hs.1] + calc s * ‖z - y‖ ≤ 1 * ‖z - y‖ := by gcongr; exact hs.2 + _ < δ := by simpa using hz' + refine ContinuousMultilinearMap.opNorm_le_bound (by positivity) fun V ↦ ?_ + let ℓ : E →L[ℝ] F := (ContinuousMultilinearMap.apply ℝ (fun _ : Fin m ↦ E) F V).comp (D y) + have hℓ : ∀ q, ℓ q = Bc y (Fin.cons q V) := fun q ↦ rfl + have hd : ∀ s ∈ Icc (0 : ℝ) 1, HasDirDerivAt (fun q ↦ g q V - ℓ q) (y + s • (z - y)) + (z - y) (secondB g (y + s • (z - y)) (Fin.cons (z - y) V) - ℓ (z - y)) := + fun s hs ↦ (hasDirDerivAt_unc_base hg1 (hδ' (hseg s hs)).1 V (z - y)).sub + (ℓ.hasDirDerivAt _ _) + have hDc : ContinuousOn (fun s : ℝ ↦ + secondB g (y + s • (z - y)) (Fin.cons (z - y) V) - ℓ (z - y)) (Icc 0 1) := + ((continuousOn_secondB hg1).comp + (by fun_prop : Continuous fun s : ℝ ↦ + (y + s • (z - y), (Fin.cons (z - y) V : Fin (m + 1) → E))).continuousOn + fun s hs ↦ ⟨(hδ' (hseg s hs)).1, mem_univ _⟩).sub continuousOn_const + have hmem := sub_mem_of_hasDirDerivAt hd hDc + (convex_closedBall 0 (c * ‖z - y‖ * ∏ i, ‖V i‖)) Metric.isClosed_closedBall + (fun s hs ↦ by + have hp := hδ' (hseg s hs) + rw [mem_closedBall_zero_iff, hℓ, ← hBc _ hp.1, ← sub_apply] + refine ((Bc _ - Bc y).le_opNorm _).trans ?_ + rw [norm_prod_cons] + calc ‖Bc (y + s • (z - y)) - Bc y‖ * (‖z - y‖ * ∏ i, ‖V i‖) + ≤ c * (‖z - y‖ * ∏ i, ‖V i‖) := by gcongr; exact hp.2 + _ = c * ‖z - y‖ * ∏ i, ‖V i‖ := by ring) + rw [mem_closedBall_zero_iff, add_sub_cancel] at hmem + have e : (g z - g y - D y (z - y)) V = g z V - ℓ z - (g y V - ℓ y) := by + simp only [map_sub, sub_apply] + change _ - _ - (ℓ z - ℓ y) = _ + abel + calc ‖(g z - g y - D y (z - y)) V‖ = ‖g z V - ℓ z - (g y V - ℓ y)‖ := by rw [e] + _ ≤ c * ‖z - y‖ * ∏ i, ‖V i‖ := hmem + have hfd : EqOn (fderiv ℝ g) D U := fun y hy ↦ (hder y hy).fderiv + have hDC : ContDiffOn ℝ k D U := + (continuousMultilinearCurryLeftEquiv ℝ (fun _ : Fin (m + 1) ↦ E) F).contDiff.comp_contDiffOn + hBcC + rw [Nat.cast_succ, contDiffOn_succ_iff_fderiv_of_isOpen hU] + exact ⟨fun y hy ↦ (hder y hy).differentiableAt.differentiableWithinAt, by simp, + hDC.congr hfd⟩ + +/-- Neeb–Glöckner, Proposition 2.3.17 (b): `C^{k+1}` maps in the sense of Michal–Bastiani +between open subsets of normed spaces are Fréchet `C^k`. -/ +theorem ContDiffMBOn.contDiffOn {k : ℕ} {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn (k + 1) f U) : ContDiffOn ℝ k f U := by + let g : E → ContinuousMultilinearMap ℝ (fun _ : Fin 0 ↦ E) F := fun x ↦ + (continuousMultilinearCurryFin0 ℝ E F).symm (f x) + have hg : ContDiffMBOn (k + 1) (unc g) (U ×ˢ univ) := by + have h := ContDiffMBOn.comp_clm (ContinuousLinearMap.fst ℝ E (Fin 0 → E)) hU hf + have hpre : (ContinuousLinearMap.fst ℝ E (Fin 0 → E)) ⁻¹' U = U ×ˢ univ := by ext; simp + rw [hpre] at h + exact ContDiffMBOn.congr_of_isOpen (hU.prod isOpen_univ) (fun p _ ↦ rfl) h + have := (continuousMultilinearCurryFin0 ℝ E F).contDiff.comp_contDiffOn + (contDiffOn_of_unc k 0 hU hg) + refine this.congr fun x _ ↦ ?_ + simp [g] + +/-- Smoothness in the sense of Michal–Bastiani and Fréchet agree on normed spaces +(Neeb–Glöckner, Proposition 2.3.17). -/ +theorem smoothMBOn_iff_contDiffOn {f : E → F} {U : Set E} (hU : IsOpen U) : + SmoothMBOn f U ↔ ContDiffOn ℝ ∞ f U := by + rw [contDiffOn_infty] + exact ⟨fun h k ↦ (h (k + 1)).contDiffOn hU, + fun h k ↦ ContDiffOn.contDiffMBOn hU (h k)⟩ + +/-! #### `C^2` maps are Fréchet `C^1` (Neeb–Glöckner, Prop. 2.3.17 (b) for `k = 1`) -/ + +section CTwo + +variable {E' : Type u} {F' : Type v} [NormedAddCommGroup E'] [NormedSpace ℝ E'] + [NormedAddCommGroup F'] [NormedSpace ℝ F'] + +variable {f : E' → F'} {U : Set E'} + +theorem ContDiffMBOn.d2_smul_right (hf : ContDiffMBOn 2 f U) {y : E'} (hy : y ∈ U) (v w : E') + (c : ℝ) : dMB (dMB f) ((y, v), (c • w, 0)) = c • dMB (dMB f) ((y, v), (w, 0)) := by + have hdf : ContDiffMBOn 1 (dMB f) (U ×ˢ univ) := hf.2.2 + have := hdf.dMB_smul (x := (y, v)) ⟨hy, mem_univ _⟩ c (w, 0) + simpa [Prod.smul_mk] using this + +theorem ContDiffMBOn.d2_smul_left (hU : IsOpen U) (hf : ContDiffMBOn 2 f U) {y : E'} + (hy : y ∈ U) (v w : E') (c : ℝ) : + dMB (dMB f) ((y, c • v), (w, 0)) = c • dMB (dMB f) ((y, v), (w, 0)) := by + have hf1 : ContDiffMBOn 1 f U := hf.of_le (by omega) + have hdf : ContDiffMBOn 1 (dMB f) (U ×ˢ univ) := hf.2.2 + have hline : ∀ᶠ t in 𝓝[≠] (0 : ℝ), y + t • w ∈ U := by + have : Tendsto (fun t : ℝ ↦ y + t • w) (𝓝 0) (𝓝 y) := by + have hc : Continuous fun t : ℝ ↦ y + t • w := by fun_prop + simpa using hc.tendsto 0 + exact nhdsWithin_le_nhds (this.eventually (hU.mem_nhds hy)) + have h1 : HasDirDerivAt (dMB f) (y, c • v) (w, 0) (c • dMB (dMB f) ((y, v), (w, 0))) := by + refine ((hdf.2.1 (y, v) ⟨hy, mem_univ _⟩ (w, 0)).const_smul c).congr' ?_ + filter_upwards [hline] with t ht + simp only [Prod.mk_add_mk, Prod.smul_mk, smul_zero, add_zero, smul_sub, smul_comm c t⁻¹] + rw [← hf1.dMB_smul ht, ← hf1.dMB_smul hy] + exact h1.dMB_eq + +/-- Local bilinear bound for the second derivative. -/ +theorem ContDiffMBOn.exists_d2_bound (hU : IsOpen U) (hf : ContDiffMBOn 2 f U) {x : E'} + (hx : x ∈ U) : ∃ δ > 0, ∃ C ≥ 0, ∀ z, ‖z - x‖ < δ → z ∈ U ∧ + ∀ v w, ‖dMB (dMB f) ((z, v), (w, 0))‖ ≤ C * ‖v‖ * ‖w‖ := by + have hdf : ContDiffMBOn 1 (dMB f) (U ×ˢ univ) := hf.2.2 + set g : E' × E' × E' → F' := fun q ↦ dMB (dMB f) ((q.1, q.2.1), (q.2.2, 0)) with hg + have hg0 : g (x, 0, 0) = 0 := by + simp only [hg] + simpa using hf.d2_smul_right hx 0 0 0 + have hgc : ContinuousAt g (x, 0, 0) := by + have h0 : ContinuousOn (dMB (dMB f)) ((U ×ˢ univ) ×ˢ univ) := hdf.2.2 + have h1 : ContinuousAt (dMB (dMB f)) ((x, (0 : E')), ((0 : E'), (0 : E'))) := + h0.continuousAt (prod_mem_nhds (prod_mem_nhds (hU.mem_nhds hx) univ_mem) univ_mem) + have hφ : Continuous fun q : E' × E' × E' ↦ ((q.1, q.2.1), (q.2.2, (0 : E'))) := by + fun_prop + have h2 := ContinuousAt.comp (x := (x, (0 : E'), (0 : E'))) h1 hφ.continuousAt + exact h2 + obtain ⟨δ₀, hδ₀, hball⟩ := Metric.continuousAt_iff.mp hgc 1 one_pos + obtain ⟨δ₁, hδ₁, hδ₁U⟩ := Metric.isOpen_iff.mp hU x hx + set δ := min δ₀ δ₁ + have hδ : 0 < δ := lt_min hδ₀ hδ₁ + set ρ := δ / 2 + have hρ : 0 < ρ := half_pos hδ + refine ⟨δ, hδ, 1 / (ρ * ρ), by positivity, fun z hz ↦ ⟨hδ₁U ?_, fun v w ↦ ?_⟩⟩ + · rw [Metric.mem_ball, dist_eq_norm]; exact lt_of_lt_of_le hz (min_le_right _ _) + have hzU : z ∈ U := hδ₁U (by + rw [Metric.mem_ball, dist_eq_norm]; exact lt_of_lt_of_le hz (min_le_right _ _)) + rcases eq_or_ne v 0 with rfl | hv + · have := hf.d2_smul_left hU hzU 0 w 0 + simp only [zero_smul] at this + simp [this] + rcases eq_or_ne w 0 with rfl | hw + · have := hf.d2_smul_right hzU v 0 0 + simp only [zero_smul] at this + simp [this] + have hvn : 0 < ‖v‖ := norm_pos_iff.mpr hv + have hwn : 0 < ‖w‖ := norm_pos_iff.mpr hw + set v' := (ρ / ‖v‖) • v + set w' := (ρ / ‖w‖) • w + have hv' : ‖v'‖ = ρ := by simp [v', norm_smul, abs_of_pos hρ, div_mul_cancel₀ _ hvn.ne'] + have hw' : ‖w'‖ = ρ := by simp [w', norm_smul, abs_of_pos hρ, div_mul_cancel₀ _ hwn.ne'] + have hlt : ‖g (z, v', w')‖ < 1 := by + have := hball (x := (z, v', w')) (by + rw [Prod.dist_eq, Prod.dist_eq, dist_eq_norm, dist_eq_norm, dist_eq_norm] + simp only [sub_zero, hv', hw'] + have hρδ : ρ < δ₀ := lt_of_lt_of_le (half_lt_self hδ) (min_le_left _ _) + exact max_lt (lt_of_lt_of_le hz (min_le_left _ _)) (max_lt hρδ hρδ)) + simpa [hg0] using this + have hscale : g (z, v', w') = (ρ / ‖v‖ * (ρ / ‖w‖)) • dMB (dMB f) ((z, v), (w, 0)) := by + simp only [hg, v', w'] + rw [hf.d2_smul_left hU hzU, hf.d2_smul_right hzU, smul_smul] + rw [hscale, norm_smul, Real.norm_of_nonneg (by positivity)] at hlt + have hpos : 0 < ρ / ‖v‖ * (ρ / ‖w‖) := by positivity + rw [← lt_div_iff₀' hpos] at hlt + calc ‖dMB (dMB f) ((z, v), (w, 0))‖ ≤ 1 / (ρ / ‖v‖ * (ρ / ‖w‖)) := hlt.le + _ = 1 / (ρ * ρ) * ‖v‖ * ‖w‖ := by field_simp + +/-- Lipschitz estimate for `x ↦ df(x)(v)`. -/ +theorem ContDiffMBOn.dMB_sub_le (hU : IsOpen U) (hf : ContDiffMBOn 2 f U) {x : E'} + (hx : x ∈ U) : ∃ δ > 0, ∃ C ≥ 0, ∀ y, ‖y - x‖ < δ → y ∈ U ∧ + ∀ v, ‖dMB f (y, v) - dMB f (x, v)‖ ≤ C * ‖v‖ * ‖y - x‖ := by + obtain ⟨δ, hδ, C, hC, hb⟩ := hf.exists_d2_bound hU hx + have hdf : ContDiffMBOn 1 (dMB f) (U ×ˢ univ) := hf.2.2 + refine ⟨δ, hδ, C, hC, fun y hy ↦ ⟨(hb y hy).1, fun v ↦ ?_⟩⟩ + have hseg : ∀ s ∈ Icc (0 : ℝ) 1, ‖x + s • (y - x) - x‖ < δ := fun s hs ↦ by + rw [add_sub_cancel_left, norm_smul, Real.norm_of_nonneg hs.1] + calc s * ‖y - x‖ ≤ 1 * ‖y - x‖ := by gcongr; exact hs.2 + _ < δ := by simpa using hy + have hd : ∀ s ∈ Icc (0 : ℝ) 1, HasDirDerivAt (fun y' ↦ dMB f (y', v)) (x + s • (y - x)) + (y - x) (dMB (dMB f) ((x + s • (y - x), v), (y - x, 0))) := fun s hs ↦ by + refine (hdf.2.1 _ ⟨(hb _ (hseg s hs)).1, mem_univ _⟩ (y - x, 0)).congr fun t ↦ ?_ + simp + have hDc : ContinuousOn (fun s : ℝ ↦ dMB (dMB f) ((x + s • (y - x), v), (y - x, (0 : E')))) + (Icc 0 1) := by + have h0 : ContinuousOn (dMB (dMB f)) ((U ×ˢ univ) ×ˢ univ) := hdf.2.2 + exact h0.comp (by fun_prop : Continuous fun s : ℝ ↦ + ((x + s • (y - x), v), (y - x, (0 : E')))).continuousOn + fun s hs ↦ ⟨⟨(hb _ (hseg s hs)).1, mem_univ _⟩, mem_univ _⟩ + have hmem := sub_mem_of_hasDirDerivAt hd hDc (convex_closedBall 0 (C * ‖v‖ * ‖y - x‖)) + Metric.isClosed_closedBall (fun s hs ↦ by + rw [mem_closedBall_zero_iff]; exact (hb _ (hseg s hs)).2 v (y - x)) + rw [mem_closedBall_zero_iff, add_sub_cancel] at hmem + exact hmem + +/-- Neeb–Glöckner, Proposition 2.3.17 (b) for `k = 1`: a `C^2` map in the sense of +Michal–Bastiani between open subsets of normed spaces is continuously Fréchet differentiable. -/ +theorem ContDiffMBOn.contDiffOn_one (hU : IsOpen U) (hf : ContDiffMBOn 2 f U) : + ContDiffOn ℝ 1 f U := + hf.contDiffOn hU + +end CTwo + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/MackeyLipschitz.lean b/LeanPool/LCAnalysis/MackeyLipschitz.lean new file mode 100644 index 0000000000..d970b1e108 --- /dev/null +++ b/LeanPool/LCAnalysis/MackeyLipschitz.lean @@ -0,0 +1,533 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import Mathlib.Analysis.SpecialFunctions.Integrals.Basic + +public import LeanPool.LCAnalysis.FundamentalTheorem + +/-! +# Mackey completeness through Lipschitz curves + +Glöckner–Neeb (Definition 1.1.17) call a curve `γ : [a, b] → E` *Lipschitz* if its difference +quotients `(γ s - γ t) / (s - t)` form a bounded set, and call `E` *Mackey complete* if every +Lipschitz curve has a weak integral. This file proves that this agrees with `MackeyComplete`, +defined through Mackey–Cauchy sequences (Glöckner–Neeb, Remark 1.1.18(e); Kriegl–Michor, 2.2 and +2.14): + +* `MackeyComplete.exists_hasWeakIntegral_of_isLipschitzCurve`: if Mackey–Cauchy sequences + converge, Lipschitz curves have weak integrals (the dyadic Riemann sums of a Lipschitz curve + form a Mackey–Cauchy sequence); +* `MackeyComplete.of_integratesLipschitzCurves`: conversely, if Lipschitz curves have weak + integrals, Mackey–Cauchy sequences converge. Given a Mackey–Cauchy sequence `u`, we pass to a + fast subsequence `u (n j)` and place the increments `u (n (j + 1)) - u (n j)` on tents supported + on the intervals `[1 - 2⁻ʲ, 1 - 2⁻ʲ⁻¹]`. The resulting curve is Lipschitz on `[0, 1]`, and its + weak integral is `lim u (n j) - u (n 0)`. +* `mackeyComplete_iff_integratesLipschitzCurves`: the equivalence. +-/ + +@[expose] public section + +open Set Filter Function +open scoped Topology Pointwise + +noncomputable section + +namespace LCAnalysis + +universe v + +variable {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + {γ : ℝ → F} {a b : ℝ} + +/-- The difference quotients of `γ` on `[a, b]`. -/ +def diffQuot (γ : ℝ → F) (a b : ℝ) : Set F := + {v | ∃ s ∈ Icc a b, ∃ t ∈ Icc a b, s ≠ t ∧ v = (s - t)⁻¹ • (γ s - γ t)} + +/-- A Lipschitz curve on `[a, b]` (Glöckner–Neeb, Definition 1.1.17(a)): its difference quotients +form a bounded set. -/ +def IsLipschitzCurve (γ : ℝ → F) (a b : ℝ) : Prop := + Bornology.IsVonNBounded ℝ (diffQuot γ a b) + +/-- Mackey completeness in the sense of Glöckner–Neeb, Definition 1.1.17(b): Lipschitz curves +have weak integrals. -/ +def IntegratesLipschitzCurves (F : Type v) [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] : + Prop := + ∀ (γ : ℝ → F) (a b : ℝ), a < b → IsLipschitzCurve γ a b → ∃ y, HasWeakIntegral γ a b y + +omit [TopologicalSpace F] in +theorem sub_eq_smul_diffQuot {s t : ℝ} (hs : s ∈ Icc a b) (ht : t ∈ Icc a b) (hst : s ≠ t) : + ∃ q ∈ diffQuot γ a b, γ s - γ t = (s - t) • q := + ⟨(s - t)⁻¹ • (γ s - γ t), ⟨s, hs, t, ht, hst, rfl⟩, + (smul_inv_smul₀ (sub_ne_zero.mpr hst) _).symm⟩ + +section Lipschitz + +variable [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] + +omit [ContinuousSMul ℝ F] in +/-- Lipschitz curves are continuous. -/ +theorem IsLipschitzCurve.continuousOn (h : IsLipschitzCurve γ a b) : + ContinuousOn γ (Icc a b) := by + intro t ht + rw [ContinuousWithinAt, ← tendsto_sub_nhds_zero_iff] + intro W hW + rw [Filter.mem_map] + have hev : ∀ᶠ c in 𝓝 (0 : ℝ), MapsTo (c • ·) (diffQuot γ a b) W := + (h hW).eventually_nhds_zero (mem_of_mem_nhds hW) + have hlim : Tendsto (fun s : ℝ ↦ s - t) (𝓝[Icc a b] t) (𝓝 0) := by + have : Tendsto (fun s : ℝ ↦ s - t) (𝓝 t) (𝓝 (t - t)) := tendsto_id.sub tendsto_const_nhds + simpa using this.mono_left (nhdsWithin_le_nhds (s := Icc a b)) + filter_upwards [hlim.eventually hev, self_mem_nhdsWithin] with s hs hsI + change γ s - γ t ∈ W + rcases eq_or_ne s t with rfl | hne + · rw [sub_self]; exact mem_of_mem_nhds hW + · obtain ⟨q, hq, he⟩ := sub_eq_smul_diffQuot (γ := γ) hsI ht hne + rw [he] + exact hs hq + +omit [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [TopologicalSpace F] in +/-- Increments of a curve over steps of length at most `h` lie in `h • convexHull (insert 0 D)`, +where `D` is the set of difference quotients. -/ +theorem sub_mem_smul_convexHull_diffQuot {h : ℝ} (hh : 0 < h) {s t : ℝ} (hs : s ∈ Icc a b) + (ht : t ∈ Icc a b) (hts : t ≤ s) (hst : s - t ≤ h) : + γ s - γ t ∈ h • convexHull ℝ (insert 0 (diffQuot γ a b)) := by + have h0 : (0 : F) ∈ convexHull ℝ (insert 0 (diffQuot γ a b)) := + subset_convexHull ℝ _ (mem_insert _ _) + rcases eq_or_ne s t with rfl | hne + · rw [sub_self]; exact ⟨0, h0, smul_zero h⟩ + obtain ⟨q, hq, he⟩ := sub_eq_smul_diffQuot (γ := γ) hs ht hne + have hmem : ((s - t) / h) • q ∈ convexHull ℝ (insert 0 (diffQuot γ a b)) := + (convex_convexHull ℝ _).smul_mem_of_zero_mem h0 + (subset_convexHull ℝ _ (mem_insert_of_mem _ hq)) + ⟨div_nonneg (sub_nonneg.mpr hts) hh.le, (div_le_one hh).mpr hst⟩ + convert smul_mem_smul_set (a := h) hmem using 1 + rw [he, smul_smul, mul_div_cancel₀ _ hh.ne'] + +variable [LocallyConvexSpace ℝ F] [T2Space F] + +omit [T2Space F] in +/-- In a Mackey complete space, Lipschitz curves have weak integrals. -/ +theorem MackeyComplete.exists_hasWeakIntegral_of_isLipschitzCurve [MackeyComplete F] + (hab : a < b) (hγ : IsLipschitzCurve γ a b) : ∃ y, HasWeakIntegral γ a b y := by + set K := convexHull ℝ (insert 0 (diffQuot γ a b)) + have hK : Bornology.IsVonNBounded ℝ K := isVonNBounded_convexHull (hγ.insert 0) + have hr : Tendsto (fun k : ℕ ↦ (b - a) * ((b - a) / 2 ^ k)) atTop (𝓝 0) := by + simpa using tendsto_const_nhds.mul (tendsto_const_nhds.div_atTop + (tendsto_pow_atTop_atTop_of_one_lt (one_lt_two (α := ℝ)))) + obtain ⟨y, hy⟩ := MackeyComplete.exists_tendsto (fun k : ℕ ↦ riemannSum γ a b (2 ^ k)) _ _ hK hr + fun k l hkl ↦ by + have hpow : (2 : ℕ) ^ l = 2 ^ k * 2 ^ (l - k) := by rw [← pow_add]; congr 1; omega + have hk : (0 : ℝ) < (b - a) / 2 ^ k := div_pos (by linarith) (by positivity) + have hmem := riemannSum_mul_sub_mem (γ := γ) hab.le (N := 2 ^ k) (m := 2 ^ (l - k)) + (by positivity) (by positivity) ((convex_convexHull ℝ _).smul ((b - a) / 2 ^ k)) + fun s hs t ht hts hst ↦ sub_mem_smul_convexHull_diffQuot hk hs ht hts + (by push_cast at hst; exact hst) + simp only [hpow] + rwa [smul_smul] at hmem + exact ⟨y, hasWeakIntegral_of_tendsto hab.le hγ.continuousOn hy⟩ + +omit [T2Space F] in +theorem MackeyComplete.integratesLipschitzCurves [MackeyComplete F] : + IntegratesLipschitzCurves F := + fun _ _ _ hab hγ ↦ MackeyComplete.exists_hasWeakIntegral_of_isLipschitzCurve hab hγ + +end Lipschitz + +/-! ### Tents -/ + +/-- Left endpoint `1 - 2⁻ʲ` of the `j`-th interval. -/ +def tentLeft (j : ℕ) : ℝ := 1 - (1 / 2) ^ j + +/-- Width `2⁻ʲ⁻¹` of the `j`-th interval. -/ +def tentWidth (j : ℕ) : ℝ := (1 / 2) ^ (j + 1) + +/-- The tent of height `tentWidth j / 2` on `[tentLeft j, tentLeft (j + 1)]`. -/ +def tent (j : ℕ) (t : ℝ) : ℝ := max 0 (tentWidth j / 2 - |t - (tentLeft j + tentWidth j / 2)|) + +theorem tentLeft_succ (j : ℕ) : tentLeft (j + 1) = tentLeft j + tentWidth j := by + simp only [tentLeft, tentWidth, pow_succ]; ring + +theorem tentWidth_pos (j : ℕ) : 0 < tentWidth j := by unfold tentWidth; positivity + +theorem tentWidth_le (j : ℕ) : tentWidth j ≤ 1 / 2 := by + unfold tentWidth + calc (1 / 2 : ℝ) ^ (j + 1) ≤ (1 / 2) ^ 1 := pow_le_pow_of_le_one (by norm_num) (by norm_num) + (by omega) + _ = 1 / 2 := pow_one _ + +theorem tentLeft_mono : Monotone tentLeft := fun i j hij ↦ by + unfold tentLeft + linarith [pow_le_pow_of_le_one (by norm_num : (0 : ℝ) ≤ 1 / 2) (by norm_num) hij] + +theorem tentLeft_nonneg (j : ℕ) : 0 ≤ tentLeft j := by + unfold tentLeft; linarith [pow_le_one₀ (by norm_num : (0 : ℝ) ≤ 1 / 2) (by norm_num) (n := j)] + +theorem tentLeft_lt_one (j : ℕ) : tentLeft j < 1 := by + unfold tentLeft; linarith [pow_pos (by norm_num : (0 : ℝ) < 1 / 2) j] + +theorem tent_nonneg (j : ℕ) (t : ℝ) : 0 ≤ tent j t := le_max_left _ _ + +theorem tent_le_one (j : ℕ) (t : ℝ) : tent j t ≤ 1 := by + have h1 := abs_nonneg (t - (tentLeft j + tentWidth j / 2)) + have h2 := tentWidth_le j + exact max_le zero_le_one (by linarith) + +theorem tent_eq_zero_of_le {j : ℕ} {t : ℝ} (ht : t ≤ tentLeft j) : tent j t = 0 := + max_eq_left (by linarith [neg_le_abs (t - (tentLeft j + tentWidth j / 2))]) + +theorem tent_eq_zero_of_ge {j : ℕ} {t : ℝ} (ht : tentLeft (j + 1) ≤ t) : tent j t = 0 := by + rw [tentLeft_succ] at ht + exact max_eq_left (by linarith [le_abs_self (t - (tentLeft j + tentWidth j / 2))]) + +theorem abs_tent_sub_le (j : ℕ) (s t : ℝ) : |tent j s - tent j t| ≤ |s - t| := by + set m := tentLeft j + tentWidth j / 2 + calc |tent j s - tent j t| + ≤ |(tentWidth j / 2 - |s - m|) - (tentWidth j / 2 - |t - m|)| := by + rw [tent, tent, max_comm 0, max_comm 0]; exact abs_max_sub_max_le_abs _ _ _ + _ = abs (|t - m| - |s - m|) := by ring_nf + _ ≤ |(t - m) - (s - m)| := abs_abs_sub_abs_le_abs_sub _ _ + _ = |s - t| := by rw [abs_sub_comm]; ring_nf + +theorem tent_eq_left {j : ℕ} {t : ℝ} (ht : t ∈ Icc (tentLeft j) (tentLeft j + tentWidth j / 2)) : + tent j t = t - tentLeft j := by + rw [tent, abs_of_nonpos (by linarith [ht.2]), max_eq_right (by linarith [ht.1])] + ring + +theorem tent_eq_right {j : ℕ} {t : ℝ} + (ht : t ∈ Icc (tentLeft j + tentWidth j / 2) (tentLeft j + tentWidth j)) : + tent j t = tentLeft j + tentWidth j - t := by + rw [tent, abs_of_nonneg (by linarith [ht.1]), max_eq_right (by linarith [ht.2])] + ring + +theorem continuous_tent (j : ℕ) : Continuous (tent j) := + continuous_const.max (continuous_const.sub ((continuous_id.sub continuous_const).abs)) + +theorem integral_tent (j : ℕ) : ∫ t in (0 : ℝ)..1, tent j t = tentWidth j ^ 2 / 4 := by + have hw : 0 < tentWidth j := tentWidth_pos j + have h0l : 0 ≤ tentLeft j := tentLeft_nonneg j + set l := tentLeft j + set w := tentWidth j + set m := l + w / 2 with hm + have hr1 : l + w ≤ 1 := by rw [← tentLeft_succ]; exact (tentLeft_lt_one _).le + have ii : ∀ x y : ℝ, IntervalIntegrable (tent j) MeasureTheory.volume x y := + fun x y ↦ (continuous_tent j).intervalIntegrable x y + have e1 : ∫ t in (0 : ℝ)..l, tent j t = 0 := by + have : EqOn (tent j) (fun _ ↦ 0) (uIcc 0 l) := fun t ht ↦ by + rw [uIcc_of_le h0l] at ht; exact tent_eq_zero_of_le ht.2 + rw [intervalIntegral.integral_congr this]; simp + have e4 : ∫ t in (l + w)..1, tent j t = 0 := by + have : EqOn (tent j) (fun _ ↦ 0) (uIcc (l + w) 1) := fun t ht ↦ by + rw [uIcc_of_le hr1] at ht + exact tent_eq_zero_of_ge (by rw [tentLeft_succ]; exact ht.1) + rw [intervalIntegral.integral_congr this]; simp + have e2 : ∫ t in l..m, tent j t = w ^ 2 / 8 := by + have : EqOn (tent j) (fun t ↦ t - l) (uIcc l m) := fun t ht ↦ by + rw [uIcc_of_le (by rw [hm]; linarith)] at ht + exact tent_eq_left ht + rw [intervalIntegral.integral_congr this, intervalIntegral.integral_comp_sub_right + (fun x ↦ x), integral_id] + rw [hm]; ring + have e3 : ∫ t in m..(l + w), tent j t = w ^ 2 / 8 := by + have : EqOn (tent j) (fun t ↦ (l + w) - t) (uIcc m (l + w)) := fun t ht ↦ by + rw [uIcc_of_le (by rw [hm]; linarith)] at ht + exact tent_eq_right ht + rw [intervalIntegral.integral_congr this, intervalIntegral.integral_comp_sub_left + (fun x ↦ x), integral_id] + rw [hm]; ring + rw [← intervalIntegral.integral_add_adjacent_intervals (ii 0 l) (ii l 1), + ← intervalIntegral.integral_add_adjacent_intervals (ii l m) (ii m 1), + ← intervalIntegral.integral_add_adjacent_intervals (ii m (l + w)) (ii (l + w) 1), + e1, e2, e3, e4] + ring + +/-- The partial sums `∑_{j < N} tent j t • e j`. -/ +def tentSum (e : ℕ → F) (N : ℕ) (t : ℝ) : F := ∑ j ∈ Finset.range N, tent j t • e j + +/-- The curve `∑_j tent j t • e j` (a finite sum for each `t`). -/ +def tentCurve (e : ℕ → F) (t : ℝ) : F := + open Classical in + if h : ∃ N, t ≤ tentLeft N then tentSum e (Nat.find h) t else 0 + +omit [TopologicalSpace F] in +theorem tentSum_stable (e : ℕ → F) {M N : ℕ} (hMN : M ≤ N) {t : ℝ} (ht : t ≤ tentLeft M) : + tentSum e N t = tentSum e M t := by + induction N, hMN using Nat.le_induction with + | base => rfl + | succ n hn ih => + rw [tentSum, Finset.sum_range_succ, ← tentSum, ih, + tent_eq_zero_of_le (ht.trans (tentLeft_mono hn)), zero_smul, add_zero] + +omit [TopologicalSpace F] in +theorem tentSum_eq_zero_of_one_le (e : ℕ → F) (N : ℕ) {t : ℝ} (ht : 1 ≤ t) : + tentSum e N t = 0 := + Finset.sum_eq_zero fun j _ ↦ by + rw [tent_eq_zero_of_ge ((tentLeft_lt_one _).le.trans ht), zero_smul] + +omit [TopologicalSpace F] in +theorem eventually_tentCurve_eq (e : ℕ → F) (t : ℝ) : + ∀ᶠ N in atTop, tentCurve e t = tentSum e N t := by + rcases lt_or_ge t 1 with ht | ht + · obtain ⟨N₀, hN₀⟩ : ∃ N, (1 / 2 : ℝ) ^ N < 1 - t := + exists_pow_lt_of_lt_one (by linarith) (by norm_num) + have h : ∃ N, t ≤ tentLeft N := ⟨N₀, by unfold tentLeft; linarith⟩ + filter_upwards [eventually_ge_atTop N₀] with N hN + have htN : t ≤ tentLeft N := by + have : t ≤ tentLeft N₀ := by unfold tentLeft; linarith + exact this.trans (tentLeft_mono hN) + rw [tentCurve, dite_eq_left_of_eq_true (eq_true h)] + exact (tentSum_stable e (Nat.find_min' h htN) (Nat.find_spec h)).symm + · refine Eventually.of_forall fun N ↦ ?_ + rw [tentSum_eq_zero_of_one_le e N ht, tentCurve] + split_ifs with h + · exact tentSum_eq_zero_of_one_le e _ ht + · rfl + +/-! ### Sums in multiples of a convex set -/ + +section ConvexSums + +variable {K : Set F} + +omit [TopologicalSpace F] in +theorem smul_mem_smul_of_abs_le (hK : Convex ℝ K) (h0 : (0 : F) ∈ K) + (hneg : ∀ x ∈ K, -x ∈ K) {x : F} (hx : x ∈ K) {μ c : ℝ} (hμ : |μ| ≤ c) : + μ • x ∈ c • K := by + have hc : 0 ≤ c := (abs_nonneg μ).trans hμ + rcases hc.eq_or_lt with rfl | hc + · rw [abs_nonpos_iff.mp hμ, zero_smul]; exact zero_mem_smul_set h0 + have hμc : |μ / c| ≤ 1 := by rw [abs_div, abs_of_pos hc, div_le_one hc]; exact hμ + have hmem : (μ / c) • x ∈ K := by + rcases le_total 0 (μ / c) with h | h + · exact hK.smul_mem_of_zero_mem h0 hx ⟨h, (le_abs_self _).trans hμc⟩ + · have := hK.smul_mem_of_zero_mem h0 (hneg x hx) ⟨neg_nonneg.mpr h, + (neg_le_abs _).trans hμc⟩ + rwa [smul_neg, ← neg_smul, neg_neg] at this + convert smul_mem_smul_set (a := c) hmem using 1 + rw [smul_smul, mul_div_cancel₀ _ hc.ne'] + +omit [TopologicalSpace F] in +theorem sum_mem_smul (hK : Convex ℝ K) (h0 : (0 : F) ∈ K) {ι : Type*} (s : Finset ι) + {x : ι → F} {c : ι → ℝ} (hc : ∀ i ∈ s, 0 ≤ c i) (hx : ∀ i ∈ s, x i ∈ c i • K) : + ∑ i ∈ s, x i ∈ (∑ i ∈ s, c i) • K := by + classical + induction s using Finset.induction_on with + | empty => simpa using zero_mem_smul_set (a := (0 : ℝ)) h0 + | insert i s hi ih => + rw [Finset.sum_insert hi, Finset.sum_insert hi, + hK.add_smul (hc i (Finset.mem_insert_self i s)) + (Finset.sum_nonneg fun j hj ↦ hc j (Finset.mem_insert_of_mem hj))] + exact add_mem_add (hx i (Finset.mem_insert_self i s)) + (ih (fun j hj ↦ hc j (Finset.mem_insert_of_mem hj)) + fun j hj ↦ hx j (Finset.mem_insert_of_mem hj)) + +omit [TopologicalSpace F] in +theorem mem_smul_of_le (hK : Convex ℝ K) (h0 : (0 : F) ∈ K) {x : F} {c d : ℝ} + (hx : x ∈ c • K) (hc : 0 ≤ c) (hcd : c ≤ d) : x ∈ d • K := by + obtain ⟨k, hk, rfl⟩ := hx + dsimp only + rcases hc.eq_or_lt with rfl | hc' + · rw [zero_smul]; exact zero_mem_smul_set h0 + have hd : 0 < d := hc'.trans_le hcd + have hmem : (c / d) • k ∈ K := hK.smul_mem_of_zero_mem h0 hk + ⟨div_nonneg hc hd.le, (div_le_one hd).mpr hcd⟩ + convert smul_mem_smul_set (a := d) hmem using 1 + simp only [smul_smul, mul_div_cancel₀ _ hd.ne'] + +end ConvexSums + +theorem sum_Ico_half_pow {N M : ℕ} (h : N ≤ M) : + ∑ j ∈ Finset.Ico N M, (1 / 2 : ℝ) ^ (j + 1) = (1 / 2) ^ N - (1 / 2) ^ M := by + induction M, h using Nat.le_induction with + | base => simp + | succ M hM ih => rw [Finset.sum_Ico_succ_top hM, ih]; ring + +/-! ### Mackey–Cauchy sequences with a convergent subsequence -/ + +section Converse + +variable [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] + +omit [ContinuousSMul ℝ F] in +/-- A Mackey–Cauchy sequence with a convergent subsequence converges. -/ +theorem tendsto_of_mackeyCauchy_of_subseq {u : ℕ → F} {B : Set F} {r : ℕ → ℝ} + (hB : Bornology.IsVonNBounded ℝ B) (hr : Tendsto r atTop (𝓝 0)) + (hu : ∀ k l, k ≤ l → u l - u k ∈ r k • B) {n : ℕ → ℕ} (hn : StrictMono n) {x : F} + (hx : Tendsto (fun j ↦ u (n j)) atTop (𝓝 x)) : Tendsto u atTop (𝓝 x) := by + rw [← tendsto_sub_nhds_zero_iff] + intro W hW + rw [Filter.mem_map] + obtain ⟨V, hV, hVW⟩ := exists_nhds_zero_half hW + have hV' : V ∩ -V ∈ 𝓝 (0 : F) := inter_mem hV (neg_mem_nhds_zero F hV) + obtain ⟨K, hK⟩ := eventually_atTop.mp + (hr.eventually ((hB hV').eventually_nhds_zero (mem_of_mem_nhds hV'))) + filter_upwards [eventually_ge_atTop K] with k hk + have h1 : ∀ᶠ j in atTop, u (n j) - x ∈ V := (tendsto_sub_nhds_zero_iff.mpr hx) hV + have h2 : ∀ᶠ j in atTop, k ≤ n j := + (tendsto_atTop_mono hn.id_le tendsto_id).eventually (eventually_ge_atTop k) + obtain ⟨j, hj1, hj2⟩ := (h1.and h2).exists + obtain ⟨b, hb, he⟩ := hu k (n j) hj2 + have hmem := hK k hk hb + simp only at hmem he + rw [he] at hmem + have : u k - x = -(u (n j) - u k) + (u (n j) - x) := by abel + change u k - x ∈ W + rw [this] + exact hVW _ hmem.2 _ hj1 + +variable [LocallyConvexSpace ℝ F] [T2Space F] + +omit [T2Space F] in +/-- If Lipschitz curves have weak integrals, then Mackey–Cauchy sequences converge. -/ +theorem MackeyComplete.of_integratesLipschitzCurves (h : IntegratesLipschitzCurves F) : + MackeyComplete F where + exists_tendsto u B r hB hr hu := by + -- the absolutely convex hull `K` of `B` + set K := convexHull ℝ (insert 0 (B ∪ -B)) + have hKc : Convex ℝ K := convex_convexHull ℝ _ + have h0 : (0 : F) ∈ K := subset_convexHull ℝ _ (mem_insert _ _) + have hBK : B ⊆ K := fun x hx ↦ subset_convexHull ℝ _ (mem_insert_of_mem _ (Or.inl hx)) + have hneg : ∀ x ∈ K, -x ∈ K := fun x hx ↦ by + have hs : -(insert (0 : F) (B ∪ -B)) = insert 0 (B ∪ -B) := by + ext y; simp [or_comm] + have : -x ∈ -K := Set.neg_mem_neg.mpr hx + rwa [← convexHull_neg, hs] at this + have hKb : Bornology.IsVonNBounded ℝ K := + isVonNBounded_convexHull ((hB.union hB.neg).insert 0) + -- a fast subsequence + set c : ℕ → ℝ := fun j ↦ (1 / 2) ^ (j + 1) + have hc : ∀ j, 0 < c j := fun j ↦ by positivity + set ε : ℕ → ℝ := fun j ↦ c j * tentWidth j ^ 2 / 4 + have hε : ∀ j, 0 < ε j := fun j ↦ by + have := tentWidth_pos j; have := hc j; positivity + obtain ⟨n, hn, hnε⟩ := extraction_forall_of_eventually (P := fun j k ↦ |r k| ≤ ε j) + fun j ↦ by + obtain ⟨N, hN⟩ := Metric.tendsto_atTop.mp hr (ε j) (hε j) + exact eventually_atTop.mpr ⟨N, fun k hk ↦ by + have := hN k hk; rw [Real.dist_eq, sub_zero] at this; exact this.le⟩ + -- the increments, rescaled + set d : ℕ → F := fun j ↦ u (n (j + 1)) - u (n j) + set e : ℕ → F := fun j ↦ (4 / tentWidth j ^ 2) • d j + have he : ∀ j, e j ∈ c j • K := fun j ↦ by + obtain ⟨b, hb, hbe⟩ := hu (n j) (n (j + 1)) (hn (Nat.lt_succ_self j)).le + have hw := tentWidth_pos j + have hμ : |4 / tentWidth j ^ 2 * r (n j)| ≤ c j := by + rw [abs_mul, abs_of_pos (by positivity)] + calc 4 / tentWidth j ^ 2 * |r (n j)| ≤ 4 / tentWidth j ^ 2 * ε j := by + gcongr; exact hnε j + _ = c j := by simp only [ε]; field_simp + have := smul_mem_smul_of_abs_le hKc h0 hneg (hBK hb) hμ + simp only [e, d, ← hbe, smul_smul] + exact this + set γ := tentCurve e + have hcont : ∀ N, Continuous (tentSum e N) := fun N ↦ + continuous_finsetSum _ fun j _ ↦ (continuous_tent j).smul continuous_const + -- `γ` is a Lipschitz curve on `[0, 1]` + have hdq : diffQuot γ 0 1 ⊆ K := by + rintro _ ⟨s, -, t, -, hst, rfl⟩ + obtain ⟨N, hNs, hNt⟩ := ((eventually_tentCurve_eq e s).and + (eventually_tentCurve_eq e t)).exists + have hst' : 0 < |s - t| := abs_pos.mpr (sub_ne_zero.mpr hst) + have hsum : (s - t)⁻¹ • (γ s - γ t) = ∑ j ∈ Finset.range N, + ((s - t)⁻¹ * (tent j s - tent j t)) • e j := by + simp only [γ, hNs, hNt, tentSum, ← Finset.sum_sub_distrib, Finset.smul_sum, ← sub_smul, + smul_smul] + rw [hsum] + have hmem := sum_mem_smul hKc h0 (Finset.range N) (fun j _ ↦ (hc j).le) + (x := fun j ↦ ((s - t)⁻¹ * (tent j s - tent j t)) • e j) fun j _ ↦ by + obtain ⟨k, hk, hke⟩ := he j + rw [← hke, smul_smul] + refine smul_mem_smul_of_abs_le hKc h0 hneg hk ?_ + rw [abs_mul, abs_mul, abs_of_pos (hc j)] + refine mul_le_of_le_one_left (hc j).le ?_ + rw [abs_inv, inv_mul_le_one₀ hst'] + exact abs_tent_sub_le j s t + have hle : ∑ j ∈ Finset.range N, c j ≤ 1 := by + have := sum_Ico_half_pow (Nat.zero_le N) + rw [← Finset.range_eq_Ico] at this + simp only [c, this] + linarith [pow_pos (by norm_num : (0 : ℝ) < 1 / 2) N] + simpa using mem_smul_of_le hKc h0 hmem + (Finset.sum_nonneg fun j _ ↦ (hc j).le) hle + have hLip : IsLipschitzCurve γ 0 1 := hKb.subset hdq + obtain ⟨y, hy⟩ := h γ 0 1 zero_lt_one hLip + have hγc : ContinuousOn γ (Icc 0 1) := hLip.continuousOn + -- the weak integral of the partial sums is `u (n N) - u (n 0)` + have hGint : ∀ N, HasWeakIntegral (tentSum e N) 0 1 (u (n N) - u (n 0)) := by + intro N + induction N with + | zero => + have : tentSum e 0 = fun _ ↦ 0 := by funext t; simp [tentSum] + rw [this, sub_self] + simpa using hasWeakIntegral_const (0 : F) 0 1 + | succ N ih => + have hfun : tentSum e (N + 1) = fun t ↦ tentSum e N t + tent N t • e N := by + funext t; simp only [tentSum, Finset.sum_range_succ] + have hterm : HasWeakIntegral (fun t ↦ tent N t • e N) 0 1 (d N) := by + intro φ + simp only [map_smul, smul_eq_mul] + rw [intervalIntegral.integral_mul_const, integral_tent] + have hw := tentWidth_pos N + simp only [e, map_smul, smul_eq_mul] + field_simp + have := ih.add (hcont N).continuousOn + ((continuous_tent N).smul continuous_const).continuousOn hterm + rw [hfun] + convert this using 1 + simp only [d]; abel + -- the subsequence converges to `u (n 0) + y` + have hconv : Tendsto (fun N ↦ u (n N)) atTop (𝓝 (u (n 0) + y)) := by + have hsmall : Tendsto (fun N ↦ y - (u (n N) - u (n 0))) atTop (𝓝 0) := by + intro W hW + rw [Filter.mem_map] + obtain ⟨W', hW', hW'c, hW'conv, hW'W⟩ := exists_closed_convex_two_smul_subset hW + have hev : ∀ᶠ N in atTop, MapsTo (((1 / 2 : ℝ) ^ N) • ·) K W' := + (tendsto_pow_atTop_nhds_zero_of_lt_one (by norm_num) (by norm_num)).eventually + ((hKb hW').eventually_nhds_zero (mem_of_mem_nhds hW')) + filter_upwards [hev] with N hN + have hdiff := hy.sub zero_le_one hγc (hcont N).continuousOn (hGint N) + have hmem := hdiff.mem_smul zero_le_one (hγc.sub (hcont N).continuousOn) hW'conv hW'c + (mem_of_mem_nhds hW') fun t _ ↦ by + obtain ⟨M, hM, hNM⟩ := ((eventually_tentCurve_eq e t).and + (eventually_ge_atTop N)).exists + have hIco : γ t - tentSum e N t = ∑ j ∈ Finset.Ico N M, tent j t • e j := by + simp only [γ, hM, tentSum] + rw [← Finset.sum_range_add_sum_Ico _ hNM, add_sub_cancel_left] + rw [Pi.sub_apply, hIco] + have hmem := sum_mem_smul hKc h0 (Finset.Ico N M) (fun j _ ↦ (hc j).le) + (x := fun j ↦ tent j t • e j) fun j _ ↦ by + obtain ⟨k, hk, hke⟩ := he j + rw [← hke, smul_smul] + refine smul_mem_smul_of_abs_le hKc h0 hneg hk ?_ + rw [abs_mul, abs_of_nonneg (tent_nonneg j t), abs_of_pos (hc j)] + exact mul_le_of_le_one_left (hc j).le (tent_le_one j t) + have hle : ∑ j ∈ Finset.Ico N M, c j ≤ (1 / 2) ^ N := by + simp only [c, sum_Ico_half_pow hNM] + linarith [pow_pos (by norm_num : (0 : ℝ) < 1 / 2) M] + obtain ⟨k, hk, hke⟩ := mem_smul_of_le hKc h0 hmem + (Finset.sum_nonneg fun j _ ↦ (hc j).le) hle + rw [← hke] + exact hN hk + exact hW'W (by norm_num at hmem ⊢; exact hmem) + have := (tendsto_const_nhds (x := u (n 0) + y)).sub hsmall + simp only [sub_zero] at this + convert this using 2 with N + abel + exact ⟨u (n 0) + y, tendsto_of_mackeyCauchy_of_subseq hB hr hu hn hconv⟩ + +end Converse + +variable [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] + +omit [T2Space F] in +/-- Mackey completeness through Mackey–Cauchy sequences agrees with the definition of +Glöckner–Neeb (Definition 1.1.17(b)) through Lipschitz curves. -/ +theorem mackeyComplete_iff_integratesLipschitzCurves : + MackeyComplete F ↔ IntegratesLipschitzCurves F := + ⟨fun _ ↦ MackeyComplete.integratesLipschitzCurves, + MackeyComplete.of_integratesLipschitzCurves⟩ + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/MichalBastiani.lean b/LeanPool/LCAnalysis/MichalBastiani.lean new file mode 100644 index 0000000000..97be2af70b --- /dev/null +++ b/LeanPool/LCAnalysis/MichalBastiani.lean @@ -0,0 +1,888 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import Mathlib.Analysis.Calculus.Deriv.MeanValue +public import Mathlib.Analysis.LocallyConvex.AbsConvexOpen +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.FundThmCalculus +public import Mathlib.Order.CompletePartialOrder + +/-! +# Michal–Bastiani calculus on locally convex spaces + +Reference: K.-H. Neeb, *Towards a Lie theory of locally convex groups*, Jpn. J. Math. 1 (2006), +291–468 (arXiv:1501.06269), §I.2; H. Glöckner, K.-H. Neeb, *Infinite-Dimensional Lie Groups* +(arXiv:2602.12362), Ch. 2. + +For `E`, `F` real topological vector spaces, `U ⊆ E` open and `f : E → F`: +* `dMB f (x, h) = d/dt|_{t=0} f (x + t • h)` is the directional derivative (Definition I.2.1). +* `f` is `C^1` on `U` if all directional derivatives exist on `U` and + `dMB f : E × E → F` is continuous on `U × E`. +* `f` is `C^{k+1}` on `U` if it is `C^1` and `dMB f` is `C^k` on `U × E`. This recursive + definition is equivalent to Neeb's (continuity of all the iterated derivatives `d^j f`, see + `contDiffMBOn_iff_hasContIterDerivOn` in `LCAnalysis.Higher`); + it is the one used by Glöckner, and it avoids `j`-linear maps. + +The directional derivative is defined literally as the limit of difference quotients, so no +normed structure is involved anywhere (Mathlib's `HasDerivAt` makes sense for curves in a +topological vector space, but its API is mostly stated for normed targets). To use the +one-variable calculus of Mathlib we compose with continuous linear functionals `F →L[ℝ] ℝ`. +Local convexity (and `T2`) only appear in the theorems: through Hahn–Banach, functionals +separate points, which is what makes the fundamental theorem of calculus, hence the chain +rule, work (Neeb, Example I.2.5). +-/ + +@[expose] public section + +open Set Filter +open scoped Topology Pointwise + +noncomputable section + +namespace LCAnalysis + +universe u v + +variable {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] + {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] [ContinuousSMul ℝ F] + +/-! ### Directional derivatives and `C^k` maps (Definition I.2.1) -/ + +/-- `f` has derivative `y` at `x` in the direction `h`: +`t⁻¹ • (f (x + t • h) - f x) → y` as `t → 0`, `t ≠ 0`. -/ +def HasDirDerivAt (f : E → F) (x h : E) (y : F) : Prop := + Tendsto (fun t : ℝ ↦ t⁻¹ • (f (x + t • h) - f x)) (𝓝[≠] 0) (𝓝 y) + +/-- The directional derivative `df(x)(h)`, as a function on `E × E` +(junk value where it does not exist). -/ +def dMB (f : E → F) (p : E × E) : F := + limUnder (𝓝[≠] (0 : ℝ)) fun t : ℝ ↦ t⁻¹ • (f (p.1 + t • p.2) - f p.1) + +/-- `C^k` maps in the sense of Michal–Bastiani on a set `U` (meant to be open), `k ∈ ℕ`. -/ +def ContDiffMBOn : ℕ → ∀ {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E], + (E → F) → Set E → Prop + | 0, _, _, _, _, f, U => ContinuousOn f U + | k + 1, _, _, _, _, f, U => + ContinuousOn f U ∧ (∀ x ∈ U, ∀ h, HasDirDerivAt f x h (dMB f (x, h))) ∧ + ContDiffMBOn k (dMB f) (U ×ˢ univ) + +/-- Smooth maps in the sense of Michal–Bastiani. -/ +def SmoothMBOn (f : E → F) (U : Set E) : Prop := ∀ k, ContDiffMBOn k f U + +/-! ### Basic properties -/ + +omit [ContinuousSMul ℝ F] in +theorem ContDiffMBOn.continuousOn {k : ℕ} {f : E → F} {U : Set E} (hf : ContDiffMBOn k f U) : + ContinuousOn f U := by + cases k with + | zero => exact hf + | succ k => exact hf.1 + +omit [ContinuousSMul ℝ F] in +theorem ContDiffMBOn.hasDirDerivAt {k : ℕ} {f : E → F} {U : Set E} + (hf : ContDiffMBOn (k + 1) f U) {x : E} (hx : x ∈ U) (h : E) : + HasDirDerivAt f x h (dMB f (x, h)) := + hf.2.1 x hx h + +omit [ContinuousSMul ℝ F] in +theorem ContDiffMBOn.of_succ : ∀ {k : ℕ} {E : Type u} [AddCommGroup E] [Module ℝ E] + [TopologicalSpace E] {f : E → F} {U : Set E}, ContDiffMBOn (k + 1) f U → ContDiffMBOn k f U + | 0, _, _, _, _, _, _, hf => hf.1 + | _ + 1, _, _, _, _, _, _, hf => ⟨hf.1, hf.2.1, ContDiffMBOn.of_succ hf.2.2⟩ + +omit [ContinuousSMul ℝ F] in +theorem ContDiffMBOn.of_le {k l : ℕ} {f : E → F} {U : Set E} (hf : ContDiffMBOn k f U) + (hlk : l ≤ k) : ContDiffMBOn l f U := by + induction hlk with + | refl => exact hf + | step _ ih => exact ih hf.of_succ + +omit [ContinuousSMul ℝ F] in +theorem SmoothMBOn.contDiffMBOn {f : E → F} {U : Set E} (hf : SmoothMBOn f U) (k : ℕ) : + ContDiffMBOn k f U := + hf k + +section LocallyConvex + +variable [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] + {G : Type*} [AddCommGroup G] [Module ℝ G] [TopologicalSpace G] + [IsTopologicalAddGroup G] [ContinuousSMul ℝ G] [LocallyConvexSpace ℝ G] [T2Space G] + +/-! ### Proposition I.2.3 -/ + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] + [LocallyConvexSpace ℝ E] [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] + [T2Space F] in +/-- Along the line `t ↦ x + t • h`, a directional derivative composed with a continuous +linear functional is an ordinary derivative. -/ +theorem HasDirDerivAt.hasDerivAt_clm {f : E → F} {x h : E} {t : ℝ} {y : F} + (hd : HasDirDerivAt f (x + t • h) h y) (φ : F →L[ℝ] ℝ) : + HasDerivAt (fun s : ℝ ↦ φ (f (x + s • h))) (φ y) t := by + rw [hasDerivAt_iff_tendsto_slope_zero] + refine ((φ.continuous.tendsto y).comp hd).congr fun s ↦ ?_ + simp [add_smul, add_assoc, smul_eq_mul] + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] + [LocallyConvexSpace ℝ E] [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +theorem HasDirDerivAt.dMB_eq {f : E → F} {x h : E} {y : F} (hd : HasDirDerivAt f x h y) : + dMB f (x, h) = y := + hd.limUnder_eq + +omit [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] + [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +/-- Homogeneity of directional derivatives in the direction. -/ +theorem HasDirDerivAt.smul_dir {f : E → F} {x h : E} {y : F} (hd : HasDirDerivAt f x h y) + (c : ℝ) : HasDirDerivAt f x (c • h) (c • y) := by + rcases eq_or_ne c 0 with rfl | hc + · simp [HasDirDerivAt] + · have hm : Tendsto (fun t : ℝ ↦ t * c) (𝓝[≠] 0) (𝓝[≠] 0) := by + refine tendsto_nhdsWithin_iff.mpr ⟨?_, eventually_nhdsWithin_of_forall + fun t ht ↦ mul_ne_zero ht hc⟩ + exact ((continuous_id.mul continuous_const).tendsto' 0 0 (by simp)).mono_left + nhdsWithin_le_nhds + refine ((hd.comp hm).const_smul c).congr fun t ↦ ?_ + change c • ((t * c)⁻¹ • (f (x + (t * c) • h) - f x)) = t⁻¹ • (f (x + t • c • h) - f x) + rw [smul_smul, smul_smul t c h, mul_inv, mul_left_comm, mul_inv_cancel₀ hc, mul_one] + +omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +theorem ContDiffMBOn.dMB_smul {f : E → F} {U : Set E} (hf : ContDiffMBOn 1 f U) {x : E} + (hx : x ∈ U) (c : ℝ) (h : E) : dMB f (x, c • h) = c • dMB f (x, h) := + tendsto_nhds_unique (hf.2.1 x hx (c • h)) ((hf.2.1 x hx h).smul_dir c) + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] + [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] in +/-- `h ↦ df(x)(h)` is continuous. -/ +theorem ContDiffMBOn.continuous_dMB {f : E → F} {U : Set E} (hf : ContDiffMBOn 1 f U) {x : E} + (hx : x ∈ U) : Continuous fun h ↦ dMB f (x, h) := + (hf.2.2 : ContinuousOn (dMB f) (U ×ˢ univ)).comp_continuous (by fun_prop) + fun h ↦ ⟨hx, mem_univ h⟩ + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- Additivity of `df(x)`. The proof applies the mean value theorem to `φ ∘ f` along lines, for +continuous linear functionals `φ`, and uses that these separate points (Hahn–Banach). -/ +theorem ContDiffMBOn.dMB_add {f : E → F} {U : Set E} (hU : IsOpen U) (hf : ContDiffMBOn 1 f U) + {x : E} (hx : x ∈ U) (h k : E) : dMB f (x, h + k) = dMB f (x, h) + dMB f (x, k) := by + rw [SeparatingDual.eq_iff_forall_dual_eq (R := ℝ)] + intro φ + have hφ : ∀ {z v : E} {y : F}, HasDirDerivAt f z v y → + Tendsto (fun t : ℝ ↦ t⁻¹ * (φ (f (z + t • v)) - φ (f z))) (𝓝[≠] 0) (𝓝 (φ y)) := + fun hd ↦ ((φ.continuous.tendsto _).comp hd).congr fun t ↦ by simp [smul_eq_mul] + have hA : Tendsto (fun t : ℝ ↦ t⁻¹ * (φ (f (x + t • h + t • k)) - φ (f (x + t • h)))) + (𝓝[≠] 0) (𝓝 (φ (dMB f (x, k)))) := by + have hD : ContinuousAt (fun z ↦ φ (dMB f (z, k))) x := by + have h1 : ContinuousAt (dMB f) (x, k) := + (hf.2.2 : ContinuousOn (dMB f) (U ×ˢ univ)).continuousAt + (prod_mem_nhds (hU.mem_nhds hx) univ_mem) + exact φ.continuous.continuousAt.comp + (h1.comp (f := fun z : E ↦ (z, k)) (by fun_prop)) + rw [Metric.tendsto_nhdsWithin_nhds] + intro ε hε + have hW : ∀ᶠ z in 𝓝 x, z ∈ U ∧ dist (φ (dMB f (z, k))) (φ (dMB f (x, k))) < ε := + (hU.eventually_mem hx).and (Metric.tendsto_nhds.mp hD ε hε) + have hΦ : Tendsto (fun p : ℝ × ℝ ↦ x + p.1 • h + p.2 • k) (𝓝 0) (𝓝 x) := by + have : Continuous fun p : ℝ × ℝ ↦ x + p.1 • h + p.2 • k := by fun_prop + simpa using this.tendsto 0 + obtain ⟨δ, hδ, hball⟩ := Metric.eventually_nhds_iff.mp (hΦ.eventually hW) + refine ⟨δ, hδ, fun t ht0 htδ ↦ ?_⟩ + have ht : t ≠ 0 := ht0 + have htabs : |t| < δ := by simpa [Real.dist_eq] using htδ + have hseg : ∀ s, |s| ≤ |t| → x + t • h + s • k ∈ U ∧ + dist (φ (dMB f (x + t • h + s • k, k))) (φ (dMB f (x, k))) < ε := by + intro s hs + have hd : dist ((t, s) : ℝ × ℝ) 0 < δ := by + rw [Prod.dist_eq] + exact max_lt (by simpa [Real.dist_eq] using htabs) + (by simpa [Real.dist_eq] using lt_of_le_of_lt hs htabs) + exact @hball (t, s) hd + set g : ℝ → ℝ := fun s ↦ φ (f (x + t • h + s • k)) with hgdef + set g' : ℝ → ℝ := fun s ↦ φ (dMB f (x + t • h + s • k, k)) with hg'def + have hg : ∀ s, |s| ≤ |t| → HasDerivAt g (g' s) s := fun s hs ↦ + (hf.2.1 _ (hseg s hs).1 k).hasDerivAt_clm φ + have key : ∃ ξ, |ξ| ≤ |t| ∧ t⁻¹ * (g t - g 0) = g' ξ := by + rcases lt_or_gt_of_ne ht with htn | htp + · have hab : ∀ s ∈ Icc t 0, |s| ≤ |t| := fun s hs ↦ by + rw [abs_of_nonpos hs.2, abs_of_neg htn]; linarith [hs.1] + obtain ⟨ξ, hξ, heq⟩ := exists_hasDerivAt_eq_slope g g' htn + (fun s hs ↦ (hg s (hab s hs)).continuousAt.continuousWithinAt) + (fun s hs ↦ hg s (hab s (Ioo_subset_Icc_self hs))) + refine ⟨ξ, hab ξ (Ioo_subset_Icc_self hξ), ?_⟩ + rw [heq]; field_simp; ring + · have hab : ∀ s ∈ Icc 0 t, |s| ≤ |t| := fun s hs ↦ by + rw [abs_of_nonneg hs.1, abs_of_pos htp]; exact hs.2 + obtain ⟨ξ, hξ, heq⟩ := exists_hasDerivAt_eq_slope g g' htp + (fun s hs ↦ (hg s (hab s hs)).continuousAt.continuousWithinAt) + (fun s hs ↦ hg s (hab s (Ioo_subset_Icc_self hs))) + refine ⟨ξ, hab ξ (Ioo_subset_Icc_self hξ), ?_⟩ + rw [heq, sub_zero, div_eq_inv_mul] + obtain ⟨ξ, hξ, heq⟩ := key + have hg0 : g 0 = φ (f (x + t • h)) := by simp [hgdef] + rw [← hg0, show φ (f (x + t • h + t • k)) = g t from rfl, heq] + exact (hseg ξ hξ).2 + have hsum := hA.add (hφ (hf.2.1 x hx h)) + have h1 := hφ (hf.2.1 x hx (h + k)) + rw [map_add, add_comm (φ (dMB f (x, h)))] + refine tendsto_nhds_unique h1 (hsum.congr fun t ↦ ?_) + rw [smul_add, ← add_assoc] + ring + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- (i) For a `C^1` map, `df(x)` is a continuous linear map. -/ +theorem ContDiffMBOn.exists_clm {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn 1 f U) {x : E} (hx : x ∈ U) : + ∃ L : E →L[ℝ] F, ∀ h, L h = dMB f (x, h) := + ⟨{ toFun := fun h ↦ dMB f (x, h) + map_add' := hf.dMB_add hU hx + map_smul' := hf.dMB_smul hx + cont := hf.continuous_dMB hx }, fun _ ↦ rfl⟩ + +omit [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ E] [T2Space E] [IsTopologicalAddGroup F] + [LocallyConvexSpace ℝ F] [T2Space F] in +/-- (ii) Fundamental theorem of calculus, in weak form (no completeness assumption on `F`): +for every continuous linear functional `φ`, +`φ (f (x + h)) - φ (f x) = ∫₀¹ φ (df(x + t h)(h)) dt`. -/ +theorem ContDiffMBOn.integral_dMB {f : E → F} {U : Set E} + (hf : ContDiffMBOn 1 f U) {x h : E} (hxh : ∀ t ∈ Icc (0 : ℝ) 1, x + t • h ∈ U) + (φ : F →L[ℝ] ℝ) : + φ (f (x + h)) - φ (f x) = ∫ t in (0 : ℝ)..1, φ (dMB f (x + t • h, h)) := by + have hline : Continuous fun t : ℝ ↦ x + t • h := by fun_prop + have hcont : ContinuousOn (fun t : ℝ ↦ φ (f (x + t • h))) (Icc 0 1) := + φ.continuous.comp_continuousOn (hf.continuousOn.comp hline.continuousOn hxh) + have hd : ContinuousOn (fun t : ℝ ↦ φ (dMB f (x + t • h, h))) (Icc 0 1) := by + have h0 : ContinuousOn (dMB f) (U ×ˢ univ) := hf.2.2 + refine φ.continuous.comp_continuousOn (h0.comp (by fun_prop) fun t ht ↦ ?_) + exact ⟨hxh t ht, mem_univ _⟩ + have := intervalIntegral.integral_eq_sub_of_hasDerivAt_of_le zero_le_one hcont + (fun t ht ↦ (hf.2.1 _ (hxh t (Ioo_subset_Icc_self ht)) h).hasDerivAt_clm φ) + (hd.intervalIntegrable_of_Icc zero_le_one) + simpa using this.symm + +/-! ### The chain rule + +The key step (Glöckner's characterization of `C^1`): the difference quotient +`t⁻¹ • (g (y + t • v) - g y)` extends continuously to `t = 0` by `dg(y)(v)`. The proof combines +the weak fundamental theorem of calculus with Hahn–Banach (the quotient lies in the closed +convex hull of `{dg(y + s t v)(v) : s ∈ [0, 1]}`) and local convexity (closed convex +neighborhoods form a basis). -/ + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- Mean value inclusion: the difference quotient lies in the closed convex hull of the +directional derivatives along the segment. -/ +theorem ContDiffMBOn.quotient_mem_closure_convexHull {g : E → F} {U : Set E} + (hg : ContDiffMBOn 1 g U) {y v : E} {t : ℝ} (ht : t ≠ 0) + (hseg : ∀ s ∈ Icc (0 : ℝ) 1, y + s • (t • v) ∈ U) : + t⁻¹ • (g (y + t • v) - g y) ∈ + closure (convexHull ℝ ((fun s : ℝ ↦ dMB g (y + s • (t • v), v)) '' Icc 0 1)) := by + by_contra hnot + obtain ⟨φ, u, hlt, hgt⟩ := + geometric_hahn_banach_closed_point (convex_convexHull ℝ _).closure isClosed_closure hnot + have hcont : ContinuousOn (fun s : ℝ ↦ φ (dMB g (y + s • (t • v), v))) (Icc 0 1) := by + have h0 : ContinuousOn (dMB g) (U ×ˢ univ) := hg.2.2 + refine φ.continuous.comp_continuousOn (h0.comp (by fun_prop) fun s hs ↦ ?_) + exact ⟨hseg s hs, mem_univ _⟩ + have hle : ∫ s in (0 : ℝ)..1, φ (dMB g (y + s • (t • v), v)) ≤ u := by + have := intervalIntegral.integral_mono_on (μ := MeasureTheory.volume) zero_le_one + (hcont.intervalIntegrable_of_Icc zero_le_one) + (continuousOn_const.intervalIntegrable_of_Icc (μ := MeasureTheory.volume) zero_le_one) + (fun s hs ↦ (hlt _ (subset_closure (subset_convexHull ℝ _ ⟨s, hs, rfl⟩))).le) + simpa using this + have hftc := hg.integral_dMB (x := y) (h := t • v) hseg φ + have hsmul : ∫ s in (0 : ℝ)..1, φ (dMB g (y + s • (t • v), t • v)) = + t * ∫ s in (0 : ℝ)..1, φ (dMB g (y + s • (t • v), v)) := by + rw [← intervalIntegral.integral_const_mul] + refine intervalIntegral.integral_congr fun s hs ↦ ?_ + rw [uIcc_of_le zero_le_one] at hs + simp only [hg.dMB_smul (hseg s hs), map_smul, smul_eq_mul] + have hq : φ (t⁻¹ • (g (y + t • v) - g y)) = + ∫ s in (0 : ℝ)..1, φ (dMB g (y + s • (t • v), v)) := by + rw [map_smul, map_sub, smul_eq_mul, hftc, hsmul, ← mul_assoc, inv_mul_cancel₀ ht, one_mul] + linarith + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- Glöckner's lemma: for `g` of class `C^1`, the difference quotient +`t⁻¹ • (g (y + t • v) - g y)` tends to `dg(y)(v)` as `(y', v', t) → (y, v, 0)` with `t ≠ 0`. -/ +theorem ContDiffMBOn.tendsto_quotient {g : E → F} {U : Set E} (hU : IsOpen U) + (hg : ContDiffMBOn 1 g U) {y v : E} (hy : y ∈ U) : + Tendsto (fun p : E × E × ℝ ↦ p.2.2⁻¹ • (g (p.1 + p.2.2 • p.2.1) - g p.1)) + (𝓝[{p | p.2.2 ≠ 0}] (y, v, 0)) (𝓝 (dMB g (y, v))) := by + refine Filter.tendsto_def.mpr fun N hN ↦ ?_ + obtain ⟨N', ⟨hN', hN'c⟩, hN'N⟩ := (closed_nhds_basis _).mem_iff.mp hN + obtain ⟨C, ⟨hC, hCconv⟩, hCN'⟩ := (LocallyConvexSpace.convex_basis (𝕜 := ℝ) _).mem_iff.mp hN' + have hWN : closure C ⊆ N := (closure_minimal hCN' hN'c).trans hN'N + have hcont : ContinuousAt (dMB g) (y, v) := + (hg.2.2 : ContinuousOn (dMB g) (U ×ˢ univ)).continuousAt + (prod_mem_nhds (hU.mem_nhds hy) univ_mem) + have hev : ∀ᶠ q : E × E in 𝓝 (y, v), q.1 ∈ U ∧ dMB g q ∈ C := + (continuous_fst.continuousAt.eventually_mem (hU.mem_nhds hy)).and + (hcont.eventually_mem hC) + have htube : ∀ᶠ p : E × E × ℝ in 𝓝 (y, v, 0), ∀ s ∈ Icc (0 : ℝ) 1, + p.1 + s • (p.2.2 • p.2.1) ∈ U ∧ dMB g (p.1 + s • (p.2.2 • p.2.1), p.2.1) ∈ C := by + refine isCompact_Icc.eventually_forall_of_forall_eventually fun s _ ↦ ?_ + have hΨ : Continuous fun z : (E × E × ℝ) × ℝ ↦ + (z.1.1 + z.2 • (z.1.2.2 • z.1.2.1), z.1.2.1) := by + fun_prop + have : Tendsto (fun z : (E × E × ℝ) × ℝ ↦ (z.1.1 + z.2 • (z.1.2.2 • z.1.2.1), z.1.2.1)) + (𝓝 ((y, v, 0), s)) (𝓝 (y, v)) := by + simpa using hΨ.tendsto ((y, v, (0 : ℝ)), s) + exact this.eventually hev + refine eventually_nhdsWithin_iff.mpr ?_ + filter_upwards [htube] with p hp hp0 + refine hWN ?_ + have hmem := hg.quotient_mem_closure_convexHull hp0 fun s hs ↦ (hp s hs).1 + refine closure_minimal (convexHull_min ?_ hCconv.closure) isClosed_closure hmem + rintro _ ⟨s, hs, rfl⟩ + exact subset_closure (hp s hs).2 + +omit [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] + [T2Space E] [LocallyConvexSpace ℝ F] [T2Space F] in +/-- Chain rule for directional derivatives. -/ +theorem ContDiffMBOn.hasDirDerivAt_comp {f : E → F} {g : F → G} {V : Set F} (hV : IsOpen V) + (hg : ContDiffMBOn 1 g V) {x h : E} {y : F} (hf : HasDirDerivAt f x h y) (hfx : f x ∈ V) : + HasDirDerivAt (g ∘ f) x h (dMB g (f x, y)) := by + have hq := hg.tendsto_quotient hV hfx (v := y) + have hΔ : Tendsto (fun t : ℝ ↦ (f x, t⁻¹ • (f (x + t • h) - f x), t)) (𝓝[≠] 0) + (𝓝[{p : F × F × ℝ | p.2.2 ≠ 0}] (f x, y, 0)) := by + refine tendsto_nhdsWithin_iff.mpr ⟨?_, eventually_nhdsWithin_of_forall fun t ht ↦ ht⟩ + exact tendsto_const_nhds.prodMk_nhds + (Filter.Tendsto.prodMk_nhds hf (tendsto_id.mono_left nhdsWithin_le_nhds)) + refine (hq.comp hΔ).congr' (eventually_nhdsWithin_of_forall fun t ht ↦ ?_) + have ht : t ≠ 0 := ht + simp [smul_smul, mul_inv_cancel₀ ht] + +omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + [LocallyConvexSpace ℝ F] [T2Space F] in +/-- Chain rule for `C^1` maps, with the formula `d(g ∘ f)(x) = dg(f x) ∘ df(x)`. -/ +theorem ContDiffMBOn.comp_one {f : E → F} {g : F → G} {U : Set E} {V : Set F} + (hV : IsOpen V) (hg : ContDiffMBOn 1 g V) (hf : ContDiffMBOn 1 f U) (hUV : MapsTo f U V) : + ContDiffMBOn 1 (g ∘ f) U ∧ ∀ x ∈ U, ∀ h, dMB (g ∘ f) (x, h) = dMB g (f x, dMB f (x, h)) := by + have hd : ∀ x ∈ U, ∀ h, HasDirDerivAt (g ∘ f) x h (dMB g (f x, dMB f (x, h))) := + fun x hx h ↦ hg.hasDirDerivAt_comp hV (hf.2.1 x hx h) (hUV hx) + have heq : ∀ x ∈ U, ∀ h, dMB (g ∘ f) (x, h) = dMB g (f x, dMB f (x, h)) := + fun x hx h ↦ (hd x hx h).dMB_eq + refine ⟨⟨hg.continuousOn.comp hf.continuousOn hUV, fun x hx h ↦ ?_, ?_⟩, heq⟩ + · rw [heq x hx h]; exact hd x hx h + · have hc : ContinuousOn (fun p : E × E ↦ dMB g (f p.1, dMB f p)) (U ×ˢ univ) := + (hg.2.2 : ContinuousOn (dMB g) (V ×ˢ univ)).comp + ((hf.continuousOn.comp continuousOn_fst + fun p (hp : p ∈ U ×ˢ (univ : Set E)) ↦ hp.1).prodMk hf.2.2) + fun p hp ↦ ⟨hUV hp.1, mem_univ _⟩ + exact hc.congr fun p hp ↦ heq p.1 hp.1 p.2 + +/-! ### Rules for `C^k` maps -/ + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem HasDirDerivAt.congr_of_eventuallyEq {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + {f₁ f₂ : E₁ → F} + {x h : E₁} {y : F} (hd : HasDirDerivAt f₁ x h y) (heq : f₁ =ᶠ[𝓝 x] f₂) : + HasDirDerivAt f₂ x h y := by + have hl : Tendsto (fun t : ℝ ↦ x + t • h) (𝓝[≠] 0) (𝓝 x) := by + have : Continuous fun t : ℝ ↦ x + t • h := by fun_prop + simpa using (this.tendsto 0).mono_left nhdsWithin_le_nhds + refine hd.congr' ?_ + filter_upwards [hl.eventually heq] with t ht + rw [ht, heq.eq_of_nhds] + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +/-- `C^k` only depends on the values on the open set. -/ +theorem ContDiffMBOn.congr_of_isOpen : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] {f₁ f₂ : E₁ → F} + {U : Set E₁}, IsOpen U → EqOn f₁ f₂ U → ContDiffMBOn k f₁ U → ContDiffMBOn k f₂ U := by + intro k + induction k with + | zero => + intro E₁ _ _ _ _ _ _ _ f₁ f₂ U hU heq hf + exact ContinuousOn.congr hf heq.symm + | succ k ih => + intro E₁ _ _ _ _ _ _ _ f₁ f₂ U hU heq hf + have hd : ∀ x ∈ U, ∀ h, HasDirDerivAt f₂ x h (dMB f₁ (x, h)) := fun x hx h ↦ + (hf.2.1 x hx h).congr_of_eventuallyEq (heq.eventuallyEq_of_mem (hU.mem_nhds hx)) + have hdeq : EqOn (dMB f₁) (dMB f₂) (U ×ˢ univ) := fun p hp ↦ + ((hd p.1 hp.1 p.2).dMB_eq).symm + refine ⟨ContinuousOn.congr hf.1 heq.symm, fun x hx h ↦ ?_, + ih (hU.prod isOpen_univ) hdeq hf.2.2⟩ + rw [← hdeq ⟨hx, mem_univ h⟩] + exact hd x hx h + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] + [IsTopologicalAddGroup G] [ContinuousSMul ℝ G] [LocallyConvexSpace ℝ G] [T2Space G] in +theorem HasDirDerivAt.prodMk {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] + {f : E₁ → F} {g : E₁ → G} {x h : E₁} {y : F} {z : G} (hf : HasDirDerivAt f x h y) + (hg : HasDirDerivAt g x h z) : HasDirDerivAt (fun w ↦ (f w, g w)) x h (y, z) := + (hf.prodMk_nhds hg).congr fun t ↦ by simp only [Prod.mk_sub_mk, Prod.smul_mk] + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] + [IsTopologicalAddGroup G] [ContinuousSMul ℝ G] [LocallyConvexSpace ℝ G] in +/-- Pairs of `C^k` maps are `C^k`. -/ +theorem ContDiffMBOn.prodMk : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] {f : E₁ → F} + {g : E₁ → G} {U : Set E₁}, IsOpen U → ContDiffMBOn k f U → ContDiffMBOn k g U → + ContDiffMBOn k (fun w ↦ (f w, g w)) U := by + intro k + induction k with + | zero => + intro E₁ _ _ _ _ _ _ _ f g U hU hf hg + exact ContinuousOn.prodMk hf hg + | succ k ih => + intro E₁ _ _ _ _ _ _ _ f g U hU hf hg + have hd : ∀ x ∈ U, ∀ h, HasDirDerivAt (fun w ↦ (f w, g w)) x h (dMB f (x, h), dMB g (x, h)) := + fun x hx h ↦ (hf.2.1 x hx h).prodMk (hg.2.1 x hx h) + have hdeq : EqOn (fun p ↦ (dMB f p, dMB g p)) (dMB fun w ↦ (f w, g w)) (U ×ˢ univ) := + fun p hp ↦ ((hd p.1 hp.1 p.2).dMB_eq).symm + refine ⟨ContinuousOn.prodMk hf.1 hg.1, fun x hx h ↦ ?_, + ContDiffMBOn.congr_of_isOpen (hU.prod isOpen_univ) hdeq + (ih (hU.prod isOpen_univ) hf.2.2 hg.2.2)⟩ + rw [← hdeq ⟨hx, mem_univ h⟩] + exact hd x hx h + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +/-- Precomposition with a continuous linear map preserves `C^k`. -/ +theorem ContDiffMBOn.comp_clm : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] {E₂ : Type*} + [AddCommGroup E₂] [Module ℝ E₂] [TopologicalSpace E₂] [IsTopologicalAddGroup E₂] + [ContinuousSMul ℝ E₂] [LocallyConvexSpace ℝ E₂] + [T2Space E₂] (L : E₁ →L[ℝ] E₂) {f : E₂ → F} {U : Set E₂}, + IsOpen U → ContDiffMBOn k f U → ContDiffMBOn k (f ∘ L) (L ⁻¹' U) := by + intro k + induction k with + | zero => + intro E₁ _ _ _ _ _ _ _ E₂ _ _ _ _ _ _ _ L f U hU hf + exact ContinuousOn.comp hf L.continuous.continuousOn fun x hx ↦ hx + | succ k ih => + intro E₁ _ _ _ _ _ _ _ E₂ _ _ _ _ _ _ _ L f U hU hf + have hd : ∀ x ∈ L ⁻¹' U, ∀ h, HasDirDerivAt (f ∘ L) x h (dMB f (L x, L h)) := + fun x hx h ↦ (hf.2.1 (L x) hx (L h)).congr fun t ↦ by simp + have hdeq : EqOn (dMB f ∘ L.prodMap L) (dMB (f ∘ L)) ((L ⁻¹' U) ×ˢ univ) := fun p hp ↦ by + simp only [Function.comp_apply, ContinuousLinearMap.coe_prodMap', Prod.map] + exact ((hd p.1 hp.1 p.2).dMB_eq).symm + refine ⟨ContinuousOn.comp hf.1 L.continuous.continuousOn fun x hx ↦ hx, + fun x hx h ↦ ?_, ?_⟩ + · rw [← hdeq ⟨hx, mem_univ h⟩] + exact hd x hx h + · have h2 := ih (L.prodMap L) (hU.prod isOpen_univ) hf.2.2 + have hpre : (L.prodMap L) ⁻¹' (U ×ˢ univ) = (L ⁻¹' U) ×ˢ univ := by ext p; simp + rw [hpre] at h2 + exact ContDiffMBOn.congr_of_isOpen ((hU.preimage L.continuous).prod isOpen_univ) hdeq h2 + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem _root_.ContinuousLinearMap.hasDirDerivAt {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] (L : E₁ →L[ℝ] F) (x h : E₁) : HasDirDerivAt L x h (L h) := by + refine tendsto_nhds_of_eventually_eq ?_ + filter_upwards [self_mem_nhdsWithin] with t (ht : t ≠ 0) + simp [smul_smul, inv_mul_cancel₀ ht] + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +/-- Remark I.2.4: continuous linear maps are `C^k` for every `k`. -/ +theorem _root_.ContinuousLinearMap.contDiffMBOn : ∀ (k : ℕ) {E₁ : Type u} [AddCommGroup E₁] + [Module ℝ E₁] [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] (L : E₁ →L[ℝ] F) (U : Set E₁), + ContDiffMBOn k L U := by + intro k + induction k with + | zero => + intro E₁ _ _ _ _ _ _ _ L U + exact L.continuous.continuousOn + | succ k ih => + intro E₁ _ _ _ _ _ _ _ L U + have heq : dMB L = ⇑(L.comp (ContinuousLinearMap.snd ℝ E₁ E₁)) := funext fun p ↦ by + simp [(L.hasDirDerivAt p.1 p.2).dMB_eq] + refine ⟨L.continuous.continuousOn, fun x _ h ↦ ?_, ?_⟩ + · rw [(L.hasDirDerivAt x h).dMB_eq] + exact L.hasDirDerivAt x h + · rw [heq] + exact ih _ _ + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] in +/-- Remark I.2.4: continuous linear maps are smooth. -/ +theorem _root_.ContinuousLinearMap.smoothMBOn (L : E →L[ℝ] F) (U : Set E) : + SmoothMBOn L U := + fun k ↦ L.contDiffMBOn k U + +theorem smoothMBOn_id (U : Set E) : SmoothMBOn (id : E → E) U := + (ContinuousLinearMap.id ℝ E).smoothMBOn U + +/-- (vi) Chain rule for `C^k` maps. -/ +theorem ContDiffMBOn.comp : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] {F₁ : Type v} + [AddCommGroup F₁] [Module ℝ F₁] [TopologicalSpace F₁] [IsTopologicalAddGroup F₁] + [ContinuousSMul ℝ F₁] [LocallyConvexSpace ℝ F₁] [T2Space F₁] {f : E₁ → F₁} {g : F₁ → G} + {U : Set E₁} {V : Set F₁}, IsOpen U → IsOpen V → ContDiffMBOn k g V → ContDiffMBOn k f U → + MapsTo f U V → ContDiffMBOn k (g ∘ f) U := by + intro k + induction k with + | zero => + intro E₁ _ _ _ _ _ _ _ F₁ _ _ _ _ _ _ _ f g U V hU hV hg hf hUV + exact ContinuousOn.comp hg hf hUV + | succ k ih => + intro E₁ _ _ _ _ _ _ _ F₁ _ _ _ _ _ _ _ f g U V hU hV hg hf hUV + obtain ⟨h1, heq⟩ := ContDiffMBOn.comp_one hV (hg.of_le (by omega)) (hf.of_le (by omega)) hUV + refine ⟨h1.1, h1.2.1, ?_⟩ + have hfst : ContDiffMBOn k (f ∘ ContinuousLinearMap.fst ℝ E₁ E₁) (U ×ˢ univ) := by + have := ContDiffMBOn.comp_clm (ContinuousLinearMap.fst ℝ E₁ E₁) hU hf.of_succ + have hpre : (ContinuousLinearMap.fst ℝ E₁ E₁) ⁻¹' U = U ×ˢ univ := by ext; simp + rwa [hpre] at this + have hP := ContDiffMBOn.prodMk (hU.prod isOpen_univ) hfst hf.2.2 + have hc := ih (hU.prod isOpen_univ) (hV.prod isOpen_univ) hg.2.2 hP + (fun p hp ↦ ⟨hUV hp.1, mem_univ _⟩) + refine ContDiffMBOn.congr_of_isOpen (hU.prod isOpen_univ) (fun p hp ↦ ?_) hc + simp only [Function.comp_apply, ContinuousLinearMap.coe_fst'] + exact (heq p.1 hp.1 p.2).symm + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem ContDiffMBOn.mono : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] {f : E₁ → F} {U V : Set E₁}, + ContDiffMBOn k f U → V ⊆ U → ContDiffMBOn k f V := by + intro k + induction k with + | zero => + intro E₁ _ _ _ _ _ _ _ f U V hf hVU + exact ContinuousOn.mono hf hVU + | succ k ih => + intro E₁ _ _ _ _ _ _ _ f U V hf hVU + exact ⟨hf.1.mono hVU, fun x hx h ↦ hf.2.1 x (hVU hx) h, + ih hf.2.2 (Set.prod_mono hVU subset_rfl)⟩ + +omit [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] [ContinuousSMul ℝ F] in +/-- Being `C^k` is a local property. -/ +theorem ContDiffMBOn.of_local : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] + [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] + [LocallyConvexSpace ℝ E₁] [T2Space E₁] {f : E₁ → F} {U : Set E₁}, IsOpen U → + (∀ x ∈ U, ∃ W, IsOpen W ∧ x ∈ W ∧ ContDiffMBOn k f (U ∩ W)) → ContDiffMBOn k f U := by + have hcont : ∀ {k : ℕ} {E₁ : Type u} [AddCommGroup E₁] [Module ℝ E₁] [TopologicalSpace E₁] + {f : E₁ → F} {U : Set E₁}, IsOpen U → + (∀ x ∈ U, ∃ W, IsOpen W ∧ x ∈ W ∧ ContDiffMBOn k f (U ∩ W)) → ContinuousOn f U := by + intro k E₁ _ _ _ f U hU hloc x hx + obtain ⟨W, hW, hxW, hf⟩ := hloc x hx + exact (hf.continuousOn x ⟨hx, hxW⟩ |>.continuousAt + ((hU.inter hW).mem_nhds ⟨hx, hxW⟩)).continuousWithinAt + intro k + induction k with + | zero => + intro E₁ _ _ _ _ _ _ _ f U hU hloc + exact hcont hU hloc + | succ k ih => + intro E₁ _ _ _ _ _ _ _ f U hU hloc + refine ⟨hcont hU hloc, fun x hx h ↦ ?_, ih (hU.prod isOpen_univ) fun p hp ↦ ?_⟩ + · obtain ⟨W, _, hxW, hf⟩ := hloc x hx + exact hf.2.1 x ⟨hx, hxW⟩ h + · obtain ⟨W, hW, hxW, hf⟩ := hloc p.1 hp.1 + refine ⟨W ×ˢ univ, hW.prod isOpen_univ, ⟨hxW, mem_univ _⟩, ?_⟩ + have := hf.2.2 + rwa [Set.prod_inter_prod, Set.inter_self] + +omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + [LocallyConvexSpace ℝ F] [T2Space F] in +/-- (vi) Chain rule: formula for the derivative. -/ +theorem ContDiffMBOn.dMB_comp {f : E → F} {g : F → G} {U : Set E} {V : Set F} + (hV : IsOpen V) (hg : ContDiffMBOn 1 g V) (hf : ContDiffMBOn 1 f U) + (hUV : MapsTo f U V) {x : E} (hx : x ∈ U) (h : E) : + dMB (g ∘ f) (x, h) = dMB g (f x, dMB f (x, h)) := + (hg.comp_one hV hf hUV).2 x hx h + +/-! ### Mean value inclusion and partial derivatives (Michor 1980, 8.3–8.4) -/ + +omit [T2Space F] in +/-- Closed convex neighborhoods form a basis in a locally convex space. -/ +theorem exists_closed_convex_nhds_subset {a : F} {N : Set F} (hN : N ∈ 𝓝 a) : + ∃ W ∈ 𝓝 a, IsClosed W ∧ Convex ℝ W ∧ W ⊆ N := by + obtain ⟨N', ⟨hN', hN'c⟩, hN'N⟩ := (closed_nhds_basis _).mem_iff.mp hN + obtain ⟨C, ⟨hC, hCconv⟩, hCN'⟩ := (LocallyConvexSpace.convex_basis (𝕜 := ℝ) _).mem_iff.mp hN' + exact ⟨closure C, mem_of_superset hC subset_closure, isClosed_closure, hCconv.closure, + (closure_minimal hCN' hN'c).trans hN'N⟩ + +omit [TopologicalSpace E] [ContinuousSMul ℝ F] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] + [LocallyConvexSpace ℝ E] [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] + [T2Space F] in +/-- Weak fundamental theorem of calculus along a segment, assuming only the directional +derivatives in the direction of the segment. -/ +theorem integral_of_hasDirDerivAt {f : E → F} {z w : E} {D : ℝ → F} + (hd : ∀ s ∈ Icc (0 : ℝ) 1, HasDirDerivAt f (z + s • w) w (D s)) + (hD : ContinuousOn D (Icc 0 1)) (φ : F →L[ℝ] ℝ) : + φ (f (z + w)) - φ (f z) = ∫ s in (0 : ℝ)..1, φ (D s) := by + have hder : ∀ s ∈ Icc (0 : ℝ) 1, HasDerivAt (fun s : ℝ ↦ φ (f (z + s • w))) (φ (D s)) s := + fun s hs ↦ (hd s hs).hasDerivAt_clm φ + have := intervalIntegral.integral_eq_sub_of_hasDerivAt_of_le zero_le_one + (fun s hs ↦ (hder s hs).continuousAt.continuousWithinAt) + (fun s hs ↦ hder s (Ioo_subset_Icc_self hs)) + ((φ.continuous.comp_continuousOn hD).intervalIntegrable_of_Icc zero_le_one) + simpa using this.symm + +omit [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] + [T2Space E] [T2Space F] in +/-- Mean value inclusion (Michor 8.4, remark): the increment along a segment lies in every +closed convex set containing the directional derivatives along the segment. -/ +theorem sub_mem_of_hasDirDerivAt {f : E → F} {z w : E} {D : ℝ → F} + (hd : ∀ s ∈ Icc (0 : ℝ) 1, HasDirDerivAt f (z + s • w) w (D s)) + (hD : ContinuousOn D (Icc 0 1)) {W : Set F} (hWc : Convex ℝ W) (hWcl : IsClosed W) + (hDW : ∀ s ∈ Icc (0 : ℝ) 1, D s ∈ W) : f (z + w) - f z ∈ W := by + by_contra hnot + obtain ⟨φ, u, hlt, hgt⟩ := geometric_hahn_banach_closed_point hWc hWcl hnot + have hle : ∫ s in (0 : ℝ)..1, φ (D s) ≤ u := by + have := intervalIntegral.integral_mono_on (μ := MeasureTheory.volume) zero_le_one + ((φ.continuous.comp_continuousOn hD).intervalIntegrable_of_Icc zero_le_one) + (continuousOn_const.intervalIntegrable_of_Icc (μ := MeasureTheory.volume) zero_le_one) + (fun s hs ↦ (hlt _ (hDW s hs)).le) + simpa using this + have := integral_of_hasDirDerivAt hd hD φ + rw [map_sub] at hgt + linarith + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- Directional difference quotients converge locally uniformly in the base point: if `f` has +directional derivative `D q` in the direction `w` at every `q ∈ U`, with `D` continuous, then +`t⁻¹ • (f (q + t • w) - f q) → D p` as `(q, t) → (p, 0)`, `t ≠ 0`. -/ +theorem tendsto_quotient_of_hasDirDerivAt {f : E → F} {U : Set E} (hU : IsOpen U) {w : E} + {D : E → F} (hd : ∀ q ∈ U, HasDirDerivAt f q w (D q)) (hD : ContinuousOn D U) {p : E} + (hp : p ∈ U) : + Tendsto (fun r : E × ℝ ↦ r.2⁻¹ • (f (r.1 + r.2 • w) - f r.1)) + (𝓝[{r | r.2 ≠ 0}] (p, 0)) (𝓝 (D p)) := by + refine Filter.tendsto_def.mpr fun N hN ↦ ?_ + obtain ⟨W, hW, hWcl, hWc, hWN⟩ := exists_closed_convex_nhds_subset hN + have hev : ∀ᶠ q in 𝓝 p, q ∈ U ∧ D q ∈ W := + (hU.eventually_mem hp).and ((hD.continuousAt (hU.mem_nhds hp)).eventually_mem hW) + have htube : ∀ᶠ r : E × ℝ in 𝓝 (p, 0), ∀ s ∈ Icc (0 : ℝ) 1, + r.1 + (s * r.2) • w ∈ U ∧ D (r.1 + (s * r.2) • w) ∈ W := by + refine isCompact_Icc.eventually_forall_of_forall_eventually fun s _ ↦ ?_ + have hΨ : Continuous fun z : (E × ℝ) × ℝ ↦ z.1.1 + (z.2 * z.1.2) • w := by fun_prop + have : Tendsto (fun z : (E × ℝ) × ℝ ↦ z.1.1 + (z.2 * z.1.2) • w) (𝓝 ((p, 0), s)) (𝓝 p) := by + simpa using hΨ.tendsto ((p, (0 : ℝ)), s) + exact this.eventually hev + refine eventually_nhdsWithin_iff.mpr ?_ + filter_upwards [htube] with r hr hr0 + have ht : r.2 ≠ 0 := hr0 + refine hWN ((Set.mem_smul_set_iff_inv_smul_mem₀ ht W _).mp ?_) + have hpts : ∀ s : ℝ, r.1 + s • (r.2 • w) = r.1 + (s * r.2) • w := fun s ↦ by rw [smul_smul] + have hd' : ∀ s ∈ Icc (0 : ℝ) 1, HasDirDerivAt f (r.1 + s • (r.2 • w)) (r.2 • w) + (r.2 • D (r.1 + (s * r.2) • w)) := fun s hs ↦ by + rw [hpts s]; exact (hd _ (hr s hs).1).smul_dir r.2 + have hD' : ContinuousOn (fun s : ℝ ↦ r.2 • D (r.1 + (s * r.2) • w)) (Icc 0 1) := + (continuous_const_smul _).comp_continuousOn (hD.comp + (by fun_prop : Continuous fun s : ℝ ↦ r.1 + (s * r.2) • w).continuousOn + fun s hs ↦ (hr s hs).1) + exact sub_mem_of_hasDirDerivAt hd' hD' (hWc.smul r.2) (hWcl.smul_of_ne_zero ht) + (fun s hs ↦ Set.smul_mem_smul_set (hr s hs).2) + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- A map with jointly continuous directional derivatives is continuous (Michor 8.1). -/ +theorem continuousOn_of_hasDirDerivAt {f : E → F} {U : Set E} (hU : IsOpen U) + {D : E × E → F} (hd : ∀ q ∈ U, ∀ w, HasDirDerivAt f q w (D (q, w))) + (hD : ContinuousOn D (U ×ˢ univ)) : ContinuousOn f U := by + intro p hp + refine ContinuousAt.continuousWithinAt (Filter.tendsto_def.mpr fun N hN ↦ ?_) + have hD0 : D (p, 0) = 0 := by + refine tendsto_nhds_unique (hd p hp 0) ?_ + simp + have hN0 : (fun z ↦ f p + z) ⁻¹' N ∈ 𝓝 (0 : F) := + (continuous_const.add continuous_id).continuousAt.preimage_mem_nhds (by simpa using hN) + obtain ⟨W, hW, hWcl, hWc, hWN⟩ := exists_closed_convex_nhds_subset hN0 + have hcont : ContinuousAt D (p, 0) := + hD.continuousAt (prod_mem_nhds (hU.mem_nhds hp) univ_mem) + have hev : ∀ᶠ q : E × E in 𝓝 (p, 0), q.1 ∈ U ∧ D q ∈ W := + (continuous_fst.continuousAt.eventually_mem (hU.mem_nhds hp)).and + (hcont.eventually_mem (by rwa [hD0])) + have htube : ∀ᶠ q in 𝓝 p, ∀ s ∈ Icc (0 : ℝ) 1, + p + s • (q - p) ∈ U ∧ D (p + s • (q - p), q - p) ∈ W := by + refine isCompact_Icc.eventually_forall_of_forall_eventually fun s _ ↦ ?_ + have hΨ : Continuous fun z : E × ℝ ↦ (p + z.2 • (z.1 - p), z.1 - p) := by fun_prop + have : Tendsto (fun z : E × ℝ ↦ (p + z.2 • (z.1 - p), z.1 - p)) (𝓝 (p, s)) (𝓝 (p, 0)) := by + simpa using hΨ.tendsto (p, s) + exact this.eventually hev + filter_upwards [htube] with q hq + have hmem := sub_mem_of_hasDirDerivAt (f := f) (z := p) (w := q - p) + (D := fun s ↦ D (p + s • (q - p), q - p)) (fun s hs ↦ hd _ (hq s hs).1 _) + (hD.comp (by fun_prop : Continuous fun s : ℝ ↦ (p + s • (q - p), q - p)).continuousOn + fun s hs ↦ ⟨(hq s hs).1, mem_univ _⟩) hWc hWcl + (fun s hs ↦ (hq s hs).2) + have := hWN hmem + simpa using this + +omit [LocallyConvexSpace ℝ E] [T2Space E] [LocallyConvexSpace ℝ F] [T2Space F] in +/-- Michor 1980, Lemma 8.3: a map on an open subset of `E × F` whose partial directional +derivatives exist and are jointly continuous is `C^1`, with +`df(p)(u, v) = D₁f(p) u + D₂f(p) v`. -/ +theorem contDiffMBOn_one_of_partials {f : E × F → G} {U : Set (E × F)} (hU : IsOpen U) + {d₁ : E × F → E → G} {d₂ : E × F → F → G} + (h₁ : ∀ p ∈ U, ∀ u, HasDirDerivAt f p (u, 0) (d₁ p u)) + (h₂ : ∀ p ∈ U, ∀ v, HasDirDerivAt f p (0, v) (d₂ p v)) + (hc₁ : ContinuousOn (fun q : (E × F) × E ↦ d₁ q.1 q.2) (U ×ˢ univ)) + (hc₂ : ContinuousOn (fun q : (E × F) × F ↦ d₂ q.1 q.2) (U ×ˢ univ)) : + ContDiffMBOn 1 f U ∧ ∀ p ∈ U, ∀ u v, dMB f (p, (u, v)) = d₁ p u + d₂ p v := by + have hd : ∀ p ∈ U, ∀ u v, HasDirDerivAt f p (u, v) (d₁ p u + d₂ p v) := by + intro p hp u v + have hA := tendsto_quotient_of_hasDirDerivAt hU (w := ((u, 0) : E × F)) + (D := fun q ↦ d₁ q u) (fun q hq ↦ h₁ q hq u) + (hc₁.comp (by fun_prop : Continuous fun q : E × F ↦ (q, u)).continuousOn + fun q hq ↦ ⟨hq, mem_univ _⟩) hp + have hr : Tendsto (fun t : ℝ ↦ (p + t • ((0, v) : E × F), t)) (𝓝[≠] 0) + (𝓝[{r : (E × F) × ℝ | r.2 ≠ 0}] (p, 0)) := by + refine tendsto_nhdsWithin_iff.mpr ⟨?_, eventually_nhdsWithin_of_forall fun t ht ↦ ht⟩ + have : Continuous fun t : ℝ ↦ (p + t • ((0, v) : E × F), t) := by fun_prop + simpa using (this.tendsto 0).mono_left nhdsWithin_le_nhds + refine ((hA.comp hr).add (h₂ p hp v)).congr fun t ↦ ?_ + have hpt : p + t • ((0, v) : E × F) + t • ((u, 0) : E × F) = p + t • (u, v) := by + ext <;> simp [add_comm] + simp only [Function.comp_apply, hpt, ← smul_add, sub_add_sub_cancel] + have heq : ∀ p ∈ U, ∀ u v, dMB f (p, (u, v)) = d₁ p u + d₂ p v := + fun p hp u v ↦ (hd p hp u v).dMB_eq + have hDc : ContinuousOn (fun q : (E × F) × (E × F) ↦ d₁ q.1 q.2.1 + d₂ q.1 q.2.2) + (U ×ˢ univ) := + (hc₁.comp (by fun_prop : Continuous fun q : (E × F) × (E × F) ↦ (q.1, q.2.1)).continuousOn + fun q (hq : q ∈ U ×ˢ (univ : Set (E × F))) ↦ ⟨hq.1, mem_univ _⟩).add + (hc₂.comp (by fun_prop : Continuous fun q : (E × F) × (E × F) ↦ (q.1, q.2.2)).continuousOn + fun q (hq : q ∈ U ×ˢ (univ : Set (E × F))) ↦ ⟨hq.1, mem_univ _⟩) + refine ⟨⟨continuousOn_of_hasDirDerivAt hU (fun q hq w ↦ hd q hq w.1 w.2) hDc, + fun p hp w ↦ ?_, ?_⟩, heq⟩ + · rw [heq p hp w.1 w.2]; exact hd p hp w.1 w.2 + · exact hDc.congr fun q hq ↦ heq q.1 hq.1 q.2.1 q.2.2 + +/-! ### Proposition I.2.3 (ii) second part, and (iv) -/ + +omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [T2Space E] in +/-- (ii) A `C^1` map on a connected open set with `df = 0` is constant. -/ +theorem ContDiffMBOn.eqOn_of_dMB_eq_zero {f : E → F} {U : Set E} (hU : IsOpen U) + (hUc : IsPreconnected U) (hf : ContDiffMBOn 1 f U) (h0 : ∀ x ∈ U, ∀ h, dMB f (x, h) = 0) + {x y : E} (hx : x ∈ U) (hy : y ∈ U) : f x = f y := by + have hloc : ∀ p ∈ U, ∀ᶠ q in 𝓝 p, f p = f q := by + intro p hp + obtain ⟨C, ⟨hC, hCconv⟩, hCU⟩ := + (LocallyConvexSpace.convex_basis (𝕜 := ℝ) p).mem_iff.mp (hU.mem_nhds hp) + filter_upwards [hC] with q hq + have hseg : ∀ s ∈ Icc (0 : ℝ) 1, p + s • (q - p) ∈ U := fun s hs ↦ + hCU (hCconv.add_smul_sub_mem (mem_of_mem_nhds hC) hq hs) + have hmem := sub_mem_of_hasDirDerivAt (f := f) (z := p) (w := q - p) (D := fun _ ↦ 0) + (fun s hs ↦ by + have := hf.2.1 _ (hseg s hs) (q - p) + rwa [h0 _ (hseg s hs)] at this) + continuousOn_const (convex_singleton 0) isClosed_singleton (fun _ _ ↦ rfl) + simp only [add_sub_cancel, mem_singleton_iff, sub_eq_zero] at hmem + exact hmem.symm + exact hUc.induction₂ (fun a b ↦ f a = f b) + (fun z hz ↦ nhdsWithin_le_nhds (hloc z hz)) (fun _ _ _ _ _ _ h₁ h₂ ↦ h₁.trans h₂) + (fun _ _ _ _ h ↦ h.symm) hx hy + +omit [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem HasDirDerivAt.sub {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] + {f g : E₁ → F} {x h : E₁} {a b : F} (hf : HasDirDerivAt f x h a) + (hg : HasDirDerivAt g x h b) : HasDirDerivAt (fun y ↦ f y - g y) x h (a - b) := + (Filter.Tendsto.sub hf hg).congr fun t ↦ by simp only [← smul_sub]; congr 1; abel + +omit [ContinuousSMul ℝ F] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] in +theorem HasDirDerivAt.comp_add_const {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] + {f : E₁ → F} {y c w : E₁} {a : F} (hf : HasDirDerivAt f (y + c) w a) : + HasDirDerivAt (fun z ↦ f (z + c)) y w a := + hf.congr fun t ↦ by simp only [add_right_comm] + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- The key estimate for the symmetry of the second derivative: the second difference +`f (x + t h₁ + t h₂) - f (x + t h₁) - f (x + t h₂) + f x`, divided by `t²`, eventually lies in +any closed convex neighborhood of `d²f(x)(h₁, h₂)`. Two applications of the mean value +inclusion. -/ +theorem ContDiffMBOn.second_diff_mem {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn 2 f U) {x : E} (hx : x ∈ U) (h₁ h₂ : E) {W : Set F} + (hW : W ∈ 𝓝 (dMB (dMB f) ((x, h₁), (h₂, 0)))) (hWcl : IsClosed W) (hWc : Convex ℝ W) : + ∀ᶠ t in 𝓝[≠] (0 : ℝ), + (t * t)⁻¹ • (f (x + t • h₁ + t • h₂) - f (x + t • h₁) - f (x + t • h₂) + f x) ∈ W := by + set D₁₂ : E → F := fun y ↦ dMB (dMB f) ((y, h₁), (h₂, 0)) with hD₁₂ + have hf1 : ContDiffMBOn 1 f U := hf.of_le (by omega) + have hdf : ContDiffMBOn 1 (dMB f) (U ×ˢ univ) := hf.2.2 + have hD : ContinuousOn D₁₂ U := by + have h0 : ContinuousOn (dMB (dMB f)) ((U ×ˢ univ) ×ˢ univ) := hdf.2.2 + exact h0.comp + (by fun_prop : Continuous fun y : E ↦ ((y, h₁), (h₂, (0 : E)))).continuousOn + fun y hy ↦ ⟨⟨hy, mem_univ _⟩, mem_univ _⟩ + -- directional derivative of `y ↦ df(y)(h₁)` in the direction `h₂` + have hinner : ∀ y ∈ U, HasDirDerivAt (fun y' ↦ dMB f (y', h₁)) y h₂ (D₁₂ y) := by + intro y hy + refine (hdf.2.1 (y, h₁) ⟨hy, mem_univ _⟩ (h₂, 0)).congr fun t ↦ ?_ + simp + have hev : ∀ᶠ y in 𝓝 x, y ∈ U ∧ D₁₂ y ∈ W := + (hU.eventually_mem hx).and ((hD.continuousAt (hU.mem_nhds hx)).eventually_mem hW) + have htube : ∀ᶠ t in 𝓝 (0 : ℝ), ∀ q ∈ Icc (0 : ℝ) 1 ×ˢ Icc (0 : ℝ) 1, + x + (q.1 * t) • h₁ + (q.2 * t) • h₂ ∈ U ∧ D₁₂ (x + (q.1 * t) • h₁ + (q.2 * t) • h₂) ∈ W := by + refine (isCompact_Icc.prod isCompact_Icc).eventually_forall_of_forall_eventually + fun q _ ↦ ?_ + have hΨ : Continuous fun z : ℝ × (ℝ × ℝ) ↦ x + (z.2.1 * z.1) • h₁ + (z.2.2 * z.1) • h₂ := by + fun_prop + have : Tendsto (fun z : ℝ × (ℝ × ℝ) ↦ x + (z.2.1 * z.1) • h₁ + (z.2.2 * z.1) • h₂) + (𝓝 (0, q)) (𝓝 x) := by + simpa using hΨ.tendsto ((0 : ℝ), q) + exact this.eventually hev + filter_upwards [nhdsWithin_le_nhds htube, self_mem_nhdsWithin] with t ht (ht0 : t ≠ 0) + have hU' : ∀ σ ∈ Icc (0 : ℝ) 1, ∀ τ ∈ Icc (0 : ℝ) 1, + x + (σ * t) • h₁ + (τ * t) • h₂ ∈ U := fun σ hσ τ hτ ↦ (ht (σ, τ) ⟨hσ, hτ⟩).1 + -- inner step: `df(z + t h₂)(h₁) - df(z)(h₁) ∈ t • W` for `z = x + σ t h₁` + have hstep : ∀ σ ∈ Icc (0 : ℝ) 1, + dMB f (x + (σ * t) • h₁ + t • h₂, h₁) - dMB f (x + (σ * t) • h₁, h₁) ∈ t • W := by + intro σ hσ + have hpts : ∀ τ : ℝ, x + (σ * t) • h₁ + τ • (t • h₂) = x + (σ * t) • h₁ + (τ * t) • h₂ := + fun τ ↦ by rw [smul_smul] + have hd : ∀ τ ∈ Icc (0 : ℝ) 1, HasDirDerivAt (fun y' ↦ dMB f (y', h₁)) + (x + (σ * t) • h₁ + τ • (t • h₂)) (t • h₂) + (t • D₁₂ (x + (σ * t) • h₁ + (τ * t) • h₂)) := fun τ hτ ↦ by + rw [hpts τ]; exact (hinner _ (hU' σ hσ τ hτ)).smul_dir t + have hDc : ContinuousOn (fun τ : ℝ ↦ t • D₁₂ (x + (σ * t) • h₁ + (τ * t) • h₂)) (Icc 0 1) := + (continuous_const_smul _).comp_continuousOn (hD.comp + (by fun_prop : Continuous fun τ : ℝ ↦ x + (σ * t) • h₁ + (τ * t) • h₂).continuousOn + fun τ hτ ↦ hU' σ hσ τ hτ) + exact sub_mem_of_hasDirDerivAt hd hDc (hWc.smul t) (hWcl.smul_of_ne_zero ht0) + (fun τ hτ ↦ Set.smul_mem_smul_set (ht (σ, τ) ⟨hσ, hτ⟩).2) + -- outer step, for `G y = f (y + t h₂) - f y` along `x + σ t h₁` + have hpts : ∀ σ : ℝ, x + σ • (t • h₁) = x + (σ * t) • h₁ := fun σ ↦ by rw [smul_smul] + have hU0 : ∀ σ ∈ Icc (0 : ℝ) 1, x + (σ * t) • h₁ ∈ U := fun σ hσ ↦ by + simpa using hU' σ hσ 0 ⟨le_rfl, zero_le_one⟩ + have hU1 : ∀ σ ∈ Icc (0 : ℝ) 1, x + (σ * t) • h₁ + t • h₂ ∈ U := fun σ hσ ↦ by + simpa using hU' σ hσ 1 ⟨zero_le_one, le_rfl⟩ + have hd : ∀ σ ∈ Icc (0 : ℝ) 1, HasDirDerivAt (fun y ↦ f (y + t • h₂) - f y) + (x + σ • (t • h₁)) (t • h₁) + (t • dMB f (x + (σ * t) • h₁ + t • h₂, h₁) - t • dMB f (x + (σ * t) • h₁, h₁)) := by + intro σ hσ + rw [hpts σ] + exact (((hf1.2.1 _ (hU1 σ hσ) h₁).smul_dir t).comp_add_const).sub + ((hf1.2.1 _ (hU0 σ hσ) h₁).smul_dir t) + have hdfc : ContinuousOn (dMB f) (U ×ˢ univ) := hdf.continuousOn + have hDc : ContinuousOn (fun σ : ℝ ↦ + t • dMB f (x + (σ * t) • h₁ + t • h₂, h₁) - t • dMB f (x + (σ * t) • h₁, h₁)) (Icc 0 1) := by + refine ((continuous_const_smul t).comp_continuousOn (hdfc.comp + (by fun_prop : Continuous fun σ : ℝ ↦ (x + (σ * t) • h₁ + t • h₂, h₁)).continuousOn + fun σ hσ ↦ ⟨hU1 σ hσ, mem_univ _⟩)).sub + ((continuous_const_smul t).comp_continuousOn (hdfc.comp + (by fun_prop : Continuous fun σ : ℝ ↦ (x + (σ * t) • h₁, h₁)).continuousOn + fun σ hσ ↦ ⟨hU0 σ hσ, mem_univ _⟩)) + have hmem := sub_mem_of_hasDirDerivAt hd hDc ((hWc.smul t).smul t) + ((hWcl.smul_of_ne_zero ht0).smul_of_ne_zero ht0) + (fun σ hσ ↦ by rw [← smul_sub]; exact Set.smul_mem_smul_set (hstep σ hσ)) + rw [smul_smul] at hmem + refine (Set.mem_smul_set_iff_inv_smul_mem₀ (mul_ne_zero ht0 ht0) W _).mp ?_ + convert hmem using 1 + abel + +omit [LocallyConvexSpace ℝ E] [T2Space E] in +/-- (iv) Symmetry of the second derivative. -/ +theorem ContDiffMBOn.dMB_dMB_symm {f : E → F} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn 2 f U) {x : E} (hx : x ∈ U) (h₁ h₂ : E) : + dMB (dMB f) ((x, h₁), (h₂, 0)) = dMB (dMB f) ((x, h₂), (h₁, 0)) := by + by_contra hne + obtain ⟨N₁, N₂, hN₁, hN₂, hdisj⟩ := t2_separation_nhds hne + obtain ⟨W₁, hW₁, hW₁cl, hW₁c, hW₁N⟩ := exists_closed_convex_nhds_subset hN₁ + obtain ⟨W₂, hW₂, hW₂cl, hW₂c, hW₂N⟩ := exists_closed_convex_nhds_subset hN₂ + have e₁ := hf.second_diff_mem hU hx h₁ h₂ hW₁ hW₁cl hW₁c + have e₂ := hf.second_diff_mem hU hx h₂ h₁ hW₂ hW₂cl hW₂c + obtain ⟨t, ht₁, ht₂⟩ := (e₁.and e₂).exists + rw [add_right_comm x (t • h₂) (t • h₁)] at ht₂ + have : f (x + t • h₁ + t • h₂) - f (x + t • h₂) - f (x + t • h₁) + f x = + f (x + t • h₁ + t • h₂) - f (x + t • h₁) - f (x + t • h₂) + f x := by abel + rw [this] at ht₂ + exact Set.disjoint_left.mp hdisj (hW₁N ht₁) (hW₂N ht₂) + +end LocallyConvex + +end LCAnalysis diff --git a/LeanPool/LCAnalysis/Rules.lean b/LeanPool/LCAnalysis/Rules.lean new file mode 100644 index 0000000000..083d496736 --- /dev/null +++ b/LeanPool/LCAnalysis/Rules.lean @@ -0,0 +1,245 @@ +/- +Copyright (c) 2026 Gabriel Larotonda. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Gabriel Larotonda +-/ +module + +public import Mathlib.Analysis.Calculus.Deriv.Pow +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.IntegrationByParts + +public import LeanPool.LCAnalysis.Higher + +/-! +# Rules of calculus: products and Taylor's formula + +Glöckner–Neeb, *Infinite-Dimensional Lie Groups* (arXiv:2602.12362), §1.3–1.4. + +* Continuous bilinear maps `β : A × B → F` are smooth, with + `dβ((a, b), (h, k)) = β(a, k) + β(h, b)`; hence the product rule + `d(β(f, g))(x)(h) = β(f x, dg(x)(h)) + β(df(x)(h), g x)`. +* Taylor's formula with integral remainder, in weak form (no completeness assumption on `F`): + for `f` of class `C^{k+1}` and every continuous linear functional `ψ`, + `ψ (f (x + h)) = ∑_{j ≤ k} ψ (d^(j) f (x, h, …, h)) / j! + + ∫₀¹ (1 - t)^k / k! · ψ (d^(k+1) f (x + t h, h, …, h)) dt`. +* The second-order chain rule (`dMB_dMB_comp`): + `d²(g ∘ τ)_y(a, b) = d²g_{τ y}(dτ_y a, dτ_y b) + dg_{τ y}(d²τ_y(a, b))`. +-/ + +@[expose] public section + +open Set Filter Function +open scoped Topology Nat + +noncomputable section + +namespace LCAnalysis + +universe u v + +variable {E : Type u} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] + [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + {F : Type v} [AddCommGroup F] [Module ℝ F] [TopologicalSpace F] + [IsTopologicalAddGroup F] [ContinuousSMul ℝ F] [LocallyConvexSpace ℝ F] [T2Space F] + +/-! ### Bilinear maps and the product rule -/ + +section Bilinear + +variable {A B : Type u} [AddCommGroup A] [Module ℝ A] [TopologicalSpace A] + [IsTopologicalAddGroup A] [ContinuousSMul ℝ A] [LocallyConvexSpace ℝ A] [T2Space A] + [AddCommGroup B] [Module ℝ B] [TopologicalSpace B] + [IsTopologicalAddGroup B] [ContinuousSMul ℝ B] [LocallyConvexSpace ℝ B] [T2Space B] + (β : A →ₗ[ℝ] B →ₗ[ℝ] F) (hβ : Continuous fun p : A × B ↦ β p.1 p.2) +include hβ + +omit [LocallyConvexSpace ℝ F] [T2Space F] [TopologicalSpace A] [IsTopologicalAddGroup A] + [ContinuousSMul ℝ A] [LocallyConvexSpace ℝ A] [T2Space A] [TopologicalSpace B] + [IsTopologicalAddGroup B] [ContinuousSMul ℝ B] [LocallyConvexSpace ℝ B] [T2Space B] hβ in +theorem hasDirDerivAt_bilin (p q : A × B) : + HasDirDerivAt (fun p : A × B ↦ β p.1 p.2) p q (β p.1 q.2 + β q.1 p.2) := by + have key : ∀ t : ℝ, t ≠ 0 → t⁻¹ • (β (p + t • q).1 (p + t • q).2 - β p.1 p.2) = + β p.1 q.2 + β q.1 p.2 + t • β q.1 q.2 := by + intro t ht + have : β (p + t • q).1 (p + t • q).2 - β p.1 p.2 = + t • (β p.1 q.2 + β q.1 p.2 + t • β q.1 q.2) := by + simp only [Prod.fst_add, Prod.snd_add, Prod.smul_fst, Prod.smul_snd, map_add, map_smul, + LinearMap.add_apply, LinearMap.smul_apply] + module + rw [this, smul_smul, inv_mul_cancel₀ ht, one_smul] + have hc : Continuous fun t : ℝ ↦ β p.1 q.2 + β q.1 p.2 + t • β q.1 q.2 := by fun_prop + have h0 := (hc.tendsto 0).mono_left (nhdsWithin_le_nhds (s := {0}ᶜ)) + simp only [zero_smul, add_zero] at h0 + refine h0.congr' ?_ + filter_upwards [self_mem_nhdsWithin] with t (ht : t ≠ 0) + exact (key t ht).symm + +/-- Continuous bilinear maps are `C^k` for every `k`. -/ +theorem contDiffMBOn_bilin (k : ℕ) : ContDiffMBOn k (fun p : A × B ↦ β p.1 p.2) univ := by + induction k with + | zero => exact hβ.continuousOn + | succ k ih => + have heq : dMB (fun p : A × B ↦ β p.1 p.2) = + fun r ↦ β r.1.1 r.2.2 + β r.2.1 r.1.2 := + funext fun r ↦ (hasDirDerivAt_bilin β r.1 r.2).dMB_eq + refine ⟨hβ.continuousOn, fun p _ q ↦ ?_, ?_⟩ + · rw [heq]; exact hasDirDerivAt_bilin β p q + · rw [heq, univ_prod_univ] + let L₁ : (A × B) × (A × B) →L[ℝ] A × B := + ((ContinuousLinearMap.fst ℝ A B).comp (ContinuousLinearMap.fst ℝ _ _)).prod + ((ContinuousLinearMap.snd ℝ A B).comp (ContinuousLinearMap.snd ℝ _ _)) + let L₂ : (A × B) × (A × B) →L[ℝ] A × B := + ((ContinuousLinearMap.fst ℝ A B).comp (ContinuousLinearMap.snd ℝ _ _)).prod + ((ContinuousLinearMap.snd ℝ A B).comp (ContinuousLinearMap.fst ℝ _ _)) + have h₁ := ContDiffMBOn.comp_clm L₁ isOpen_univ ih + have h₂ := ContDiffMBOn.comp_clm L₂ isOpen_univ ih + rw [preimage_univ] at h₁ h₂ + exact h₁.add isOpen_univ h₂ + +/-- Product rule: `x ↦ β (f x) (g x)` is `C^k` if `f` and `g` are. -/ +theorem ContDiffMBOn.bilin {k : ℕ} {f : E → A} {g : E → B} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn k f U) (hg : ContDiffMBOn k g U) : + ContDiffMBOn k (fun x ↦ β (f x) (g x)) U := + ContDiffMBOn.comp hU isOpen_univ (contDiffMBOn_bilin β hβ k) (hf.prodMk hU hg) + (mapsTo_univ _ _) + +/-- Product rule: `d(β(f, g))(x)(h) = β(f x, dg(x)(h)) + β(df(x)(h), g x)`. -/ +theorem ContDiffMBOn.dMB_bilin {f : E → A} {g : E → B} {U : Set E} (hU : IsOpen U) + (hf : ContDiffMBOn 1 f U) (hg : ContDiffMBOn 1 g U) {x : E} (hx : x ∈ U) (h : E) : + dMB (fun x ↦ β (f x) (g x)) (x, h) = β (f x) (dMB g (x, h)) + β (dMB f (x, h)) (g x) := by + have hc := ContDiffMBOn.dMB_comp (g := fun p : A × B ↦ β p.1 p.2) isOpen_univ + (contDiffMBOn_bilin β hβ 1) (hf.prodMk hU hg) (mapsTo_univ _ _) hx h + have hp : dMB (fun x ↦ (f x, g x)) (x, h) = (dMB f (x, h), dMB g (x, h)) := + ((hf.2.1 x hx h).prodMk (hg.2.1 x hx h)).dMB_eq + rw [hp, (hasDirDerivAt_bilin β _ _).dMB_eq] at hc + exact hc + +end Bilinear + +/-! ### Taylor's formula -/ + +omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [LocallyConvexSpace ℝ E] [T2Space E] + [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] [T2Space F] [ContinuousSMul ℝ F] in +/-- Along a line, `t ↦ ψ (d^(j) f (x + t h, h, …, h))` has derivative +`ψ (d^(j+1) f (x + t h, h, …, h))`. -/ +theorem ContDiffMBOn.hasDerivAt_iteratedDMB_line {k j : ℕ} {f : E → F} {U : Set E} + (hf : ContDiffMBOn k f U) (hj : j < k) {x h : E} {t : ℝ} (ht : x + t • h ∈ U) + (ψ : F →L[ℝ] ℝ) : + HasDerivAt (fun s : ℝ ↦ ψ (iteratedDMB j f (x + s • h, fun _ ↦ h))) + (ψ (iteratedDMB (j + 1) f (x + t • h, fun _ ↦ h))) t := + (hf.hasContIterDerivOn.1 j hj _ ht (fun _ ↦ h)).hasDerivAt_clm ψ + +omit [LocallyConvexSpace ℝ E] [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] + [T2Space F] [ContinuousSMul ℝ F] in +theorem ContDiffMBOn.continuousOn_iteratedDMB_line {k j : ℕ} {f : E → F} {U : Set E} + (hf : ContDiffMBOn k f U) (hj : j ≤ k) {x h : E} {s : Set ℝ} + (hs : ∀ t ∈ s, x + t • h ∈ U) (ψ : F →L[ℝ] ℝ) : + ContinuousOn (fun t : ℝ ↦ ψ (iteratedDMB j f (x + t • h, fun _ ↦ h))) s := + ψ.continuous.comp_continuousOn ((hf.hasContIterDerivOn.2 j hj).comp (by fun_prop) + fun t ht ↦ ⟨hs t ht, mem_univ _⟩) + +omit [LocallyConvexSpace ℝ E] [T2Space E] [IsTopologicalAddGroup F] [LocallyConvexSpace ℝ F] + [T2Space F] [ContinuousSMul ℝ F] in +/-- Taylor's formula with integral remainder, in weak form. -/ +theorem ContDiffMBOn.taylor {f : E → F} {U : Set E} {x h : E} + (hxh : ∀ t ∈ Icc (0 : ℝ) 1, x + t • h ∈ U) (ψ : F →L[ℝ] ℝ) : ∀ (k : ℕ), + ContDiffMBOn (k + 1) f U → + ψ (f (x + h)) = ∑ j ∈ Finset.range (k + 1), (j ! : ℝ)⁻¹ * ψ (iteratedDMB j f (x, fun _ ↦ h)) + + ∫ t in (0 : ℝ)..1, (1 - t) ^ k / k ! * ψ (iteratedDMB (k + 1) f (x + t • h, fun _ ↦ h)) := by + have hI : uIcc (0 : ℝ) 1 = Icc 0 1 := uIcc_of_le zero_le_one + intro k + induction k with + | zero => + intro hf + have := intervalIntegral.integral_eq_sub_of_hasDerivAt + (f := fun s : ℝ ↦ ψ (iteratedDMB 0 f (x + s • h, fun _ ↦ h))) + (fun t ht ↦ hf.hasDerivAt_iteratedDMB_line (Nat.zero_lt_one) (hxh t (hI ▸ ht)) ψ) + ((hf.continuousOn_iteratedDMB_line le_rfl (hI ▸ hxh) ψ).intervalIntegrable) + simp only [iteratedDMB_zero, one_smul, zero_smul, add_zero] at this + simp only [zero_add, Finset.sum_range_one, Nat.factorial_zero, Nat.cast_one, inv_one, one_mul, + pow_zero, div_one, iteratedDMB_zero] at this ⊢ + rw [this] + abel + | succ k ih => + intro hf + rw [ih hf.of_succ, Finset.sum_range_succ _ (k + 1), add_assoc] + congr 1 + have hk : ((k + 1) ! : ℝ) = (k + 1) * k ! := by push_cast [Nat.factorial_succ]; ring + have hk0 : (k ! : ℝ) ≠ 0 := by positivity + have hu : ∀ t ∈ uIcc (0 : ℝ) 1, HasDerivAt (fun s : ℝ ↦ -((1 - s) ^ (k + 1) / (k + 1) !)) + ((1 - t) ^ k / k !) t := by + intro t _ + have := (((hasDerivAt_id t).const_sub 1).pow (k + 1)).div_const ((k + 1) ! : ℝ) |>.neg + refine this.congr_deriv ?_ + simp only [id, hk] + field_simp + push_cast + ring + have hv : ∀ t ∈ uIcc (0 : ℝ) 1, + HasDerivAt (fun s : ℝ ↦ ψ (iteratedDMB (k + 1) f (x + s • h, fun _ ↦ h))) + (ψ (iteratedDMB (k + 1 + 1) f (x + t • h, fun _ ↦ h))) t := + fun t ht ↦ hf.hasDerivAt_iteratedDMB_line (by omega) (hxh t (hI ▸ ht)) ψ + have hu' : IntervalIntegrable (fun t : ℝ ↦ (1 - t) ^ k / k !) MeasureTheory.volume 0 1 := + (by fun_prop : Continuous fun t : ℝ ↦ (1 - t) ^ k / k !).intervalIntegrable 0 1 + have hv' : IntervalIntegrable + (fun t : ℝ ↦ ψ (iteratedDMB (k + 1 + 1) f (x + t • h, fun _ ↦ h))) + MeasureTheory.volume 0 1 := + (hf.continuousOn_iteratedDMB_line le_rfl (hI ▸ hxh) ψ).intervalIntegrable + have := intervalIntegral.integral_mul_deriv_eq_deriv_mul hu hv hu' hv' + simp only [neg_mul, intervalIntegral.integral_neg, sub_self, + zero_pow (Nat.succ_ne_zero k), zero_div, neg_zero, zero_mul, zero_sub, one_pow, zero_smul, + add_zero, sub_zero, one_pow, one_div, neg_neg] at this + linarith + +/-! ### The second-order chain rule -/ + +section SecondOrder + +variable {E' : Type u} [AddCommGroup E'] [Module ℝ E'] [TopologicalSpace E'] + [IsTopologicalAddGroup E'] [ContinuousSMul ℝ E'] [LocallyConvexSpace ℝ E'] [T2Space E'] + +/-- **Second-order chain rule**: +`d²(g ∘ τ)_y(a, b) = d²g_{τ y}(dτ_y a, dτ_y b) + dg_{τ y}(d²τ_y(a, b))`. -/ +theorem dMB_dMB_comp {g : E' → F} {τ : E → E'} {U : Set E} {V : Set E'} (hU : IsOpen U) + (hV : IsOpen V) (hg : ContDiffMBOn 2 g V) (hτ : ContDiffMBOn 2 τ U) (hUV : MapsTo τ U V) + {y : E} (hy : y ∈ U) (a b : E) : + dMB (dMB (g ∘ τ)) ((y, b), (a, 0)) = + dMB (dMB g) ((τ y, dMB τ (y, b)), (dMB τ (y, a), 0)) + + dMB g (τ y, dMB (dMB τ) ((y, b), (a, 0))) := by + have hU2 : IsOpen (U ×ˢ (univ : Set E)) := hU.prod isOpen_univ + have hV2 : IsOpen (V ×ˢ (univ : Set E')) := hV.prod isOpen_univ + have hτ1 : ContDiffMBOn 1 τ U := hτ.of_le (by norm_num) + have hg1 : ContDiffMBOn 1 g V := hg.of_le (by norm_num) + have hdg : ContDiffMBOn 1 (dMB g) (V ×ˢ univ) := hg.2.2 + have hdτ : ContDiffMBOn 1 (dMB τ) (U ×ˢ univ) := hτ.2.2 + have hfst : ContDiffMBOn 1 (τ ∘ ContinuousLinearMap.fst ℝ E E) (U ×ˢ univ) := + hτ1.comp hU2 hU ((ContinuousLinearMap.fst ℝ E E).contDiffMBOn 1 _) fun p hp ↦ hp.1 + -- `Φ (y', b') = (τ y', dτ_{y'} b')` + set Φ : E × E → E' × E' := fun p ↦ ((τ ∘ ContinuousLinearMap.fst ℝ E E) p, dMB τ p) + have hΦ : ContDiffMBOn 1 Φ (U ×ˢ univ) := ContDiffMBOn.prodMk hU2 hfst hdτ + have hΦmaps : MapsTo Φ (U ×ˢ univ) (V ×ˢ univ) := fun p hp ↦ ⟨hUV hp.1, mem_univ _⟩ + have hp : (y, b) ∈ U ×ˢ (univ : Set E) := ⟨hy, mem_univ b⟩ + -- first-order chain rule, near `(y, b)` + have hev : dMB (g ∘ τ) =ᶠ[𝓝 (y, b)] dMB g ∘ Φ := + Filter.eventuallyEq_of_mem (hU2.mem_nhds hp) fun q hq ↦ + ContDiffMBOn.dMB_comp hV hg1 hτ1 hUV hq.1 q.2 + rw [dMB_congr_of_eventuallyEq hev, ContDiffMBOn.dMB_comp hV2 hdg hΦ hΦmaps hp] + -- the derivative of `Φ` + have hdfst : dMB (τ ∘ ContinuousLinearMap.fst ℝ E E) ((y, b), (a, 0)) = dMB τ (y, a) := by + rw [ContDiffMBOn.dMB_comp hU hτ1 ((ContinuousLinearMap.fst ℝ E E).contDiffMBOn 1 + (U ×ˢ univ)) (fun p (hp : p ∈ U ×ˢ (univ : Set E)) ↦ hp.1) hp, + ((ContinuousLinearMap.fst ℝ E E).hasDirDerivAt _ _).dMB_eq] + rfl + have hdΦ : dMB Φ ((y, b), (a, 0)) = (dMB τ (y, a), dMB (dMB τ) ((y, b), (a, 0))) := by + rw [((hfst.hasDirDerivAt hp (a, 0)).prodMk (hdτ.hasDirDerivAt hp (a, 0))).dMB_eq, hdfst] + have hsplit : (dMB τ (y, a), dMB (dMB τ) ((y, b), (a, 0))) = + (dMB τ (y, a), (0 : E')) + (0, dMB (dMB τ) ((y, b), (a, 0))) := by simp + have hΦy : Φ (y, b) = (τ y, dMB τ (y, b)) := rfl + rw [hdΦ, hsplit, hdg.dMB_add hV2 (hΦmaps hp), hΦy, dMB_slice₂] + obtain ⟨L, hL⟩ := hg1.exists_clm hV (hUV hy) + have hfun : (fun w ↦ dMB g (τ y, w)) = ⇑L := funext fun w ↦ (hL w).symm + rw [hfun, (L.hasDirDerivAt _ _).dMB_eq, hL] + +end SecondOrder + +end LCAnalysis diff --git a/LeanPool/projects/lc-analysis.yaml b/LeanPool/projects/lc-analysis.yaml new file mode 100644 index 0000000000..1232a99c63 --- /dev/null +++ b/LeanPool/projects/lc-analysis.yaml @@ -0,0 +1,77 @@ +slug: lc-analysis +title: Michal–Bastiani Calculus on Locally Convex Spaces +summary: >- + Develops real Michal–Bastiani calculus on Hausdorff locally convex spaces, + with the chain rule, continuous symmetric higher differentials, and Taylor's + formula in weak form. It proves equivalence with smooth Fréchet calculus on + open subsets of normed spaces. Weak integrals exist for continuous curves in + sequentially complete spaces and for continuously differentiable curves in + Mackey complete spaces; Mackey completeness is characterized by weak + integrability of Lipschitz curves. A smooth map from a Banach space to a + normed space with derivative uniformly bounded below reflects finite + differentiability of continuous maps from open locally convex domains. +branch: functional analysis +entry_module: LeanPool.LCAnalysis +authors: +- Gabriel Larotonda +source: + title: Infinite-Dimensional Lie Groups + authors: + - Helge Glöckner + - Karl-Hermann Neeb + arxiv: '2602.12362' + url: https://github.com/glaroton/LCAnalysis + github_repo: glaroton/LCAnalysis + commit: c7c5a228221bba0313e7caee62ca0f9b1e2e5c0f +license: Apache-2.0 +status: verified +provenance: AI +main_declarations: +- LCAnalysis.ContDiffMBOn.comp +- LCAnalysis.ContDiffMBOn.exists_iteratedDMB_multilinear +- LCAnalysis.smoothMBOn_iff_contDiffOn +- LCAnalysis.exists_hasWeakIntegral +- LCAnalysis.mackeyComplete_iff_integratesLipschitzCurves +- LCAnalysis.ContDiffMBOn.of_comp_of_boundedBelow +main_results: +- declaration: LCAnalysis.ContDiffMBOn.comp + informal: >- + Composing two real Michal–Bastiani C^k maps between open subsets of + Hausdorff locally convex spaces preserves C^k regularity, provided the + inner map takes the first domain into the second. +- declaration: LCAnalysis.ContDiffMBOn.exists_iteratedDMB_multilinear + informal: >- + At every point of its open domain, the kth differential of a + Michal–Bastiani C^k map is a continuous symmetric k-linear map. +- declaration: LCAnalysis.smoothMBOn_iff_contDiffOn + informal: >- + On open subsets of real normed spaces, Michal–Bastiani smoothness is + equivalent to Fréchet smoothness. +- declaration: LCAnalysis.exists_hasWeakIntegral + informal: >- + A continuous curve on the closed interval between any two real + endpoints has a weak integral in every sequentially complete + Hausdorff locally convex target space. +- declaration: LCAnalysis.mackeyComplete_iff_integratesLipschitzCurves + informal: >- + In a Hausdorff locally convex real space, convergence of Mackey–Cauchy + sequences is equivalent to existence of weak integrals for all curves + whose difference quotients form a bounded set on every nondegenerate + compact real interval. +- declaration: LCAnalysis.ContDiffMBOn.of_comp_of_boundedBelow + informal: >- + Let j be a smooth map from an open subset U of a real Banach space to + a real normed space, with a fixed m > 0 such that every x in U and + every vector v satisfy norm(dj(x)v) >= m * norm(v). If gamma maps an + open locally convex domain + continuously into U and j composed with gamma is C^k in the sense of + Michal–Bastiani, then gamma is C^k. +tags: +- functional-analysis +- locally-convex-spaces +- calculus +- weak-integrals +msc: +- 46T20 +- 46A03 +- 58B10