From dea58155136a3803cbb2a3a9f402116ad5a814c3 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 11 May 2026 15:38:42 +0200 Subject: [PATCH 01/40] refactor(Analysis/Calculus/Gradient): ungate inner_gradient lemmas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The four `inner_gradient[Within]_[left|right]` lemmas in `Mathlib/Analysis/Calculus/Gradient/Basic.lean` required differentiability hypotheses (`DifferentiableAt`, `DifferentiableWithinAt`, plus `UniqueDiffWithinAt` for the `Within` versions). These were never necessary: `gradient` is *defined* via the Riesz isomorphism from `fderiv`, so the identification `βŸͺβˆ‡ f x, y⟫ = fderiv π•œ f x y` holds unconditionally β€” both sides are zero when `f` is not differentiable. Removes the hypotheses and rewrites the proofs to go through `toDual_apply_apply` and `LinearIsometryEquiv.apply_symm_apply` directly. No call-site updates needed (no current mathlib callers pass the now-redundant arguments). --- Mathlib/Analysis/Calculus/Gradient/Basic.lean | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Gradient/Basic.lean b/Mathlib/Analysis/Calculus/Gradient/Basic.lean index f985036e0f938e..1496918325d32a 100644 --- a/Mathlib/Analysis/Calculus/Gradient/Basic.lean +++ b/Mathlib/Analysis/Calculus/Gradient/Basic.lean @@ -262,21 +262,21 @@ lemma HasGradientWithinAt.fderivWithin_apply lemma HasGradientAt.fderiv_apply (h : HasGradientAt f f' x) : fderiv π•œ f x y = βŸͺf', y⟫ := by rw [h.hasFDerivAt.fderiv, toDual_apply_apply] -lemma inner_gradientWithin_left - (h : DifferentiableWithinAt π•œ f s x) (hs : UniqueDiffWithinAt π•œ s x) : +lemma inner_gradientWithin_left : βŸͺgradientWithin f s x, y⟫ = fderivWithin π•œ f s x y := by - rw [h.hasGradientWithinAt.fderivWithin_apply hs] + rw [gradientWithin, ← toDual_apply_apply (π•œ := π•œ) (E := F), + LinearIsometryEquiv.apply_symm_apply] -lemma inner_gradient_left (h : DifferentiableAt π•œ f x) : βŸͺβˆ‡ f x, y⟫ = fderiv π•œ f x y := by - rw [h.hasGradientAt.fderiv_apply] +lemma inner_gradient_left : βŸͺβˆ‡ f x, y⟫ = fderiv π•œ f x y := by + rw [gradient, ← toDual_apply_apply (π•œ := π•œ) (E := F), + LinearIsometryEquiv.apply_symm_apply] -lemma inner_gradientWithin_right - (h : DifferentiableWithinAt π•œ f s y) (hs : UniqueDiffWithinAt π•œ s y) : +lemma inner_gradientWithin_right : βŸͺx, gradientWithin f s y⟫ = conj (fderivWithin π•œ f s y x) := by - rw [← inner_conj_symm, inner_gradientWithin_left h hs] + rw [← inner_conj_symm, inner_gradientWithin_left] -lemma inner_gradient_right (h : DifferentiableAt π•œ f y) : βŸͺx, βˆ‡ f y⟫ = conj (fderiv π•œ f y x) := by - rw [← inner_conj_symm, h.hasGradientAt.fderiv_apply] +lemma inner_gradient_right : βŸͺx, βˆ‡ f y⟫ = conj (fderiv π•œ f y x) := by + rw [← inner_conj_symm, inner_gradient_left] end Inner From 88dce581032439ed92d5a51555f632837f3a9024 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 11 May 2026 15:19:57 +0200 Subject: [PATCH 02/40] feat(Analysis/Calculus/AddTorsor/AffineMap): smoothness of AffineMap.lineMap Add `AffineMap.lineMap_contDiff_uncurry` (joint smoothness in all three arguments), `AffineMap.lineMap_contDiff` (smoothness in the parameter with fixed endpoints), and the composition family `ContDiff.lineMap`, `ContDiffOn.lineMap`, `ContDiffAt.lineMap`, `ContDiffWithinAt.lineMap`, mirroring the corresponding `Continuous` family in `Mathlib.Topology.Algebra.Affine`. The uncurried and `ContDiffWithinAt` forms are tagged `@[fun_prop]`. Closes the long-standing TODO at `MeasureTheory.Integral.CurveIntegral.Poincare:333` (`-- TODO: add ContDiff.lineMap etc`), where the absence of this API forced a manual `simp only [AffineMap.lineMap_apply_module]` unfold before `fun_prop` could close the goal. The Poincare proof now closes with just `fun_prop` once the new file is imported. --- .../Calculus/AddTorsor/AffineMap.lean | 57 ++++++++++++++++++- .../Integral/CurveIntegral/Poincare.lean | 3 +- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean b/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean index 28e8e0571eb140..67f99929fed34c 100644 --- a/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean +++ b/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean @@ -14,9 +14,12 @@ public import Mathlib.Analysis.Normed.Group.AddTorsor This file contains results about smoothness of affine maps. -## Main definitions: +## Main results -* `ContinuousAffineMap.contDiff`: a continuous affine map is smooth +* `ContinuousAffineMap.contDiff`: a continuous affine map is smooth. +* `AffineMap.lineMap_contDiff_uncurry`, `AffineMap.lineMap_contDiff`, + `ContDiff.lineMap` and variants: `AffineMap.lineMap` is smooth in its three + arguments, jointly and pointwise. -/ @@ -34,3 +37,53 @@ theorem contDiff {n : WithTop β„•βˆž} (f : V →ᴬ[π•œ] W) : ContDiff π•œ n f exact contDiff_const end ContinuousAffineMap + +namespace AffineMap + +variable {π•œ V : Type*} [NontriviallyNormedField π•œ] +variable [NormedAddCommGroup V] [NormedSpace π•œ V] + +/-- `AffineMap.lineMap` is smooth in all three arguments. -/ +@[fun_prop] +theorem lineMap_contDiff_uncurry {n : WithTop β„•βˆž} : + ContDiff π•œ n (fun pqc : V Γ— V Γ— π•œ ↦ AffineMap.lineMap pqc.1 pqc.2.1 pqc.2.2) := by + simp only [AffineMap.lineMap_apply_module] + fun_prop + +/-- `AffineMap.lineMap` is smooth as a function `π•œ β†’ V`. -/ +theorem lineMap_contDiff (pβ‚€ p₁ : V) {n : WithTop β„•βˆž} : + ContDiff π•œ n (AffineMap.lineMap pβ‚€ p₁ : π•œ β†’ V) := by + fun_prop + +end AffineMap + +section LineMapComp + +variable {π•œ V E : Type*} [NontriviallyNormedField π•œ] +variable [NormedAddCommGroup V] [NormedSpace π•œ V] +variable [NormedAddCommGroup E] [NormedSpace π•œ E] +variable {f₁ fβ‚‚ : E β†’ V} {g : E β†’ π•œ} {s : Set E} {x : E} {n : WithTop β„•βˆž} + +@[fun_prop] +theorem ContDiffWithinAt.lineMap (h₁ : ContDiffWithinAt π•œ n f₁ s x) + (hβ‚‚ : ContDiffWithinAt π•œ n fβ‚‚ s x) (hg : ContDiffWithinAt π•œ n g s x) : + ContDiffWithinAt π•œ n (fun x ↦ AffineMap.lineMap (f₁ x) (fβ‚‚ x) (g x)) s x := by + simp only [AffineMap.lineMap_apply_module] + fun_prop + +theorem ContDiffAt.lineMap (h₁ : ContDiffAt π•œ n f₁ x) + (hβ‚‚ : ContDiffAt π•œ n fβ‚‚ x) (hg : ContDiffAt π•œ n g x) : + ContDiffAt π•œ n (fun x ↦ AffineMap.lineMap (f₁ x) (fβ‚‚ x) (g x)) x := by + fun_prop + +theorem ContDiffOn.lineMap (h₁ : ContDiffOn π•œ n f₁ s) + (hβ‚‚ : ContDiffOn π•œ n fβ‚‚ s) (hg : ContDiffOn π•œ n g s) : + ContDiffOn π•œ n (fun x ↦ AffineMap.lineMap (f₁ x) (fβ‚‚ x) (g x)) s := by + fun_prop + +theorem ContDiff.lineMap (h₁ : ContDiff π•œ n f₁) + (hβ‚‚ : ContDiff π•œ n fβ‚‚) (hg : ContDiff π•œ n g) : + ContDiff π•œ n (fun x ↦ AffineMap.lineMap (f₁ x) (fβ‚‚ x) (g x)) := by + fun_prop + +end LineMapComp diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean index 405444b82178c8..b2b2829f3c7f1d 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean @@ -5,6 +5,7 @@ Authors: Yury Kudryashov -/ module +public import Mathlib.Analysis.Calculus.AddTorsor.AffineMap public import Mathlib.Analysis.Calculus.Deriv.Prod public import Mathlib.Analysis.Calculus.DiffContOnCl public import Mathlib.Analysis.Calculus.FDeriv.Symmetric @@ -330,8 +331,6 @@ theorem curveIntegral_segment_add_eq_of_hasFDerivWithinAt_symmetric (hs : Convex lift y to I using hy simp [Ο†] refine .congr ?_ this - -- TODO: add `ContDiff.lineMap` etc - simp only [AffineMap.lineMap_apply_module] fun_prop variable [CompleteSpace F] From 5e40b133f011d166611a1b5674aab66a91de8bea Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Sun, 17 May 2026 19:08:22 +0200 Subject: [PATCH 03/40] added simp attribute and additional lemma by Komyyy's suggestion --- Mathlib/Analysis/Calculus/Gradient/Basic.lean | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Calculus/Gradient/Basic.lean b/Mathlib/Analysis/Calculus/Gradient/Basic.lean index 1496918325d32a..3722367d7b138f 100644 --- a/Mathlib/Analysis/Calculus/Gradient/Basic.lean +++ b/Mathlib/Analysis/Calculus/Gradient/Basic.lean @@ -147,6 +147,10 @@ theorem hasGradientWithinAt_univ : HasGradientWithinAt f f' univ x ↔ HasGradie rw [hasGradientWithinAt_iff_hasFDerivWithinAt, hasGradientAt_iff_hasFDerivAt] exact hasFDerivWithinAt_univ +@[simp] +lemma gradientWithin_univ : gradientWithin f univ = gradient f := by + ext; simp [gradientWithin, gradient] + theorem DifferentiableOn.hasGradientAt (h : DifferentiableOn π•œ f s) (hs : s ∈ 𝓝 x) : HasGradientAt f (βˆ‡ f x) x := (h.hasFDerivAt hs).hasGradientAt @@ -262,19 +266,22 @@ lemma HasGradientWithinAt.fderivWithin_apply lemma HasGradientAt.fderiv_apply (h : HasGradientAt f f' x) : fderiv π•œ f x y = βŸͺf', y⟫ := by rw [h.hasFDerivAt.fderiv, toDual_apply_apply] +@[simp] lemma inner_gradientWithin_left : βŸͺgradientWithin f s x, y⟫ = fderivWithin π•œ f s x y := by rw [gradientWithin, ← toDual_apply_apply (π•œ := π•œ) (E := F), LinearIsometryEquiv.apply_symm_apply] +@[simp] lemma inner_gradient_left : βŸͺβˆ‡ f x, y⟫ = fderiv π•œ f x y := by - rw [gradient, ← toDual_apply_apply (π•œ := π•œ) (E := F), - LinearIsometryEquiv.apply_symm_apply] + simp [← gradientWithin_univ] +@[simp] lemma inner_gradientWithin_right : βŸͺx, gradientWithin f s y⟫ = conj (fderivWithin π•œ f s y x) := by rw [← inner_conj_symm, inner_gradientWithin_left] +@[simp] lemma inner_gradient_right : βŸͺx, βˆ‡ f y⟫ = conj (fderiv π•œ f y x) := by rw [← inner_conj_symm, inner_gradient_left] From 0485defd319197dbab2952f199d52f25cf249de0 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 13:07:38 +0200 Subject: [PATCH 04/40] feat(Analysis/Calculus/LipschitzSmooth): add LipschitzSmoothWith predicate Introduces LipschitzSmoothWith K f for a real-valued function f on a normed real vector space: the quadratic descent inequality f y le f x + lineDeriv R f x (y - x) + (K / 2) (dist x y)^2 stated in line-derivative form so that it does not presuppose Frechet differentiability. The K / 2 convention makes the descent lemma constant-preserving (a K-Lipschitz Frechet derivative gives K-smoothness). Two basic consequences fall directly out of the definition: * LipschitzSmoothWith.lineDeriv_apply_sub_le - the quadratic variation bound on the line-derivative. * LipschitzSmoothWith.lineDeriv_sub_apply_le - function-subtraction form. Frechet- and gradient-form restatements (the actual descent lemma) and the Baillon-Haddad equivalence with cocoercivity under convexity are deferred to follow-up files. --- Mathlib.lean | 1 + .../Calculus/LipschitzSmooth/Basic.lean | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 35e81d18f11eb2..d8e34a889790ad 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1774,6 +1774,7 @@ public import Mathlib.Analysis.Calculus.LineDeriv.Basic public import Mathlib.Analysis.Calculus.LineDeriv.IntegrationByParts public import Mathlib.Analysis.Calculus.LineDeriv.Measurable public import Mathlib.Analysis.Calculus.LineDeriv.QuadraticMap +public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic public import Mathlib.Analysis.Calculus.LocalExtr.Basic public import Mathlib.Analysis.Calculus.LocalExtr.LineDeriv public import Mathlib.Analysis.Calculus.LocalExtr.Polynomial diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean new file mode 100644 index 00000000000000..f0272138ec268c --- /dev/null +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -0,0 +1,71 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Calculus.LineDeriv.Basic + +/-! +# Lipschitz smoothness + +A real-valued function `f` on a normed real vector space is **`K`-smooth** if +it satisfies the quadratic descent inequality + +`f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β²` + +for all `x, y`. This is the standard quadratic upper bound used to control +descent steps in first-order convex optimisation. The `K / 2` convention +makes the descent lemma constant-preserving: a `K`-Lipschitz FrΓ©chet +derivative implies `K`-smoothness. + +The predicate is stated using `lineDeriv` so it does not presuppose FrΓ©chet +differentiability; for differentiable `f`, `lineDeriv` and `fderiv` agree +pointwise. FrΓ©chet-derivative restatements and the descent lemma β€” whose +hypothesis `LipschitzWith K (fderiv ℝ f)` lives in the fderiv world β€” are in +`Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv`. Inner-product-space restatements +via the gradient `βˆ‡` and `βŸͺΒ·, ·⟫` are in +`Mathlib.Analysis.Calculus.LipschitzSmooth.Gradient`. + +## Main definitions + +* `LipschitzSmoothWith K f` β€” the predicate above. + +## Main results + +* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” a `K`-smooth `f` satisfies + the quadratic upper bound `lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) + ≀ K Β· (dist x y)Β²` on the variation of its line-derivative, with no + additional hypotheses. +* `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” the same bound stated with + function-level subtraction, `(lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x)`. +-/ + +public section + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] + +/-- A real-valued function `f` on a normed real vector space `F` is `K`-smooth +if it satisfies the quadratic descent inequality +`f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β²` for all `x, y`. -/ +@[expose] def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) : Prop := + βˆ€ (x y : F), f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 + +namespace LipschitzSmoothWith + +variable {K : NNReal} {f : F β†’ ℝ} + +/-- A `K`-smooth `f` satisfies a quadratic upper bound on the variation of its line-derivative: +`lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -/ +theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : + lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by + linarith [h x y, lineDeriv_neg (π•œ := ℝ) (f := f) β–Έ neg_sub y _ β–Έ dist_comm y _ β–Έ h y x] + +/-- Function-subtraction restatement of `lineDeriv_apply_sub_le`: +`(lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. -/ +theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : + (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := + Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y + +end LipschitzSmoothWith From db5713e1a21e76db604667cd358528e3d4ceb984 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 14:37:30 +0200 Subject: [PATCH 05/40] refactor(Analysis/Calculus/LipschitzSmooth): opaque predicate + add FDeriv layer Adopt the opaque-with-iff pattern for LipschitzSmoothWith: drop the @[expose] annotation so that lineDeriv is treated as an internal implementation detail of the predicate, and provide explicit characterisations and extractors via named API lemmas. Users in any derivative framework reach the predicate through their preferred form via the appropriate iff. Basic.lean changes: * Add lipschitzSmoothWith_iff_lineDeriv (iff characterisation in lineDeriv form, Iff.rfl since the file owns the definition). * Add LipschitzSmoothWith.lineDeriv_descent_le as the named extractor. * Drop @[expose] from the def. FDeriv.lean (new file): * lipschitzSmoothWith_iff_fderiv: iff characterisation in fderiv form under Differentiable. * LipschitzSmoothWith.fderiv_descent_le: descent inequality extractor in fderiv form. * LipschitzSmoothWith.fderiv_apply_sub_le and fderiv_sub_apply_le: variance bound on the Frechet derivative in applied and function-subtraction forms. The Frechet-form descent lemma proper (converse direction, requires segment-level FTC machinery) is deferred to a follow-up. --- Mathlib.lean | 1 + .../Calculus/LipschitzSmooth/Basic.lean | 36 +++++++--- .../Calculus/LipschitzSmooth/FDeriv.lean | 71 +++++++++++++++++++ 3 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean diff --git a/Mathlib.lean b/Mathlib.lean index d8e34a889790ad..2975b58141ac91 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1775,6 +1775,7 @@ public import Mathlib.Analysis.Calculus.LineDeriv.IntegrationByParts public import Mathlib.Analysis.Calculus.LineDeriv.Measurable public import Mathlib.Analysis.Calculus.LineDeriv.QuadraticMap public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic +public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv public import Mathlib.Analysis.Calculus.LocalExtr.Basic public import Mathlib.Analysis.Calculus.LocalExtr.LineDeriv public import Mathlib.Analysis.Calculus.LocalExtr.Polynomial diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index f0272138ec268c..9b3f53ba544ece 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -34,12 +34,13 @@ via the gradient `βˆ‡` and `βŸͺΒ·, ·⟫` are in ## Main results -* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” a `K`-smooth `f` satisfies - the quadratic upper bound `lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) - ≀ K Β· (dist x y)Β²` on the variation of its line-derivative, with no - additional hypotheses. -* `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” the same bound stated with - function-level subtraction, `(lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x)`. +* `lipschitzSmoothWith_iff_lineDeriv` β€” characterisation in line-derivative form. +* `LipschitzSmoothWith.lineDeriv_descent_le` β€” the defining descent inequality + extracted as a forward implication. +* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” a `K`-smooth `f` satisfies the + quadratic upper bound `lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K Β· (dist x y)Β²` + on the variation of its line-derivative, with no additional hypotheses. +* `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” function-subtraction restatement. -/ public section @@ -48,19 +49,36 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] /-- A real-valued function `f` on a normed real vector space `F` is `K`-smooth if it satisfies the quadratic descent inequality -`f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β²` for all `x, y`. -/ -@[expose] def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) : Prop := +`f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β²` for all `x, y`. + +The choice of `lineDeriv` here is an implementation detail: it is the weakest form +that makes the predicate well-defined for non-differentiable functions. Equivalent +characterisations in `fderiv`, `gradient`, and `deriv` form are provided in the +sibling files, predicated on the appropriate differentiability hypothesis. -/ +def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) : Prop := βˆ€ (x y : F), f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 +/-- Characterisation of `LipschitzSmoothWith` in line-derivative form. -/ +theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : F β†’ ℝ} : + LipschitzSmoothWith K f ↔ + βˆ€ x y : F, f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := + Iff.rfl + namespace LipschitzSmoothWith variable {K : NNReal} {f : F β†’ ℝ} +/-- The defining descent inequality of a `K`-smooth function in line-derivative form. -/ +theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : + f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := + h x y + /-- A `K`-smooth `f` satisfies a quadratic upper bound on the variation of its line-derivative: `lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -/ theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by - linarith [h x y, lineDeriv_neg (π•œ := ℝ) (f := f) β–Έ neg_sub y _ β–Έ dist_comm y _ β–Έ h y x] + linarith [h.lineDeriv_descent_le x y, + lineDeriv_neg (π•œ := ℝ) (f := f) β–Έ neg_sub y _ β–Έ dist_comm y _ β–Έ h.lineDeriv_descent_le y x] /-- Function-subtraction restatement of `lineDeriv_apply_sub_le`: `(lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. -/ diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean new file mode 100644 index 00000000000000..a26b3c8076e9b9 --- /dev/null +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -0,0 +1,71 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Calculus.FDeriv.Basic +public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic + +/-! +# Lipschitz smoothness via the FrΓ©chet derivative + +FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate from +`Mathlib.Analysis.Calculus.LipschitzSmooth.Basic`. For differentiable `f`, +`lineDeriv ℝ f x v = fderiv ℝ f x v` pointwise, and the predicate is equivalent +to the corresponding descent inequality stated in `fderiv` form. + +This file provides only the equivalence and the elementary variance-bound consequences; +the full descent lemma β€” i.e. the converse direction +`LipschitzWith K (fderiv ℝ f) β†’ LipschitzSmoothWith K f` β€” is deferred to a follow-up. + +## Main results + +* `lipschitzSmoothWith_iff_fderiv` β€” characterisation of `K`-smoothness in FrΓ©chet form + under `Differentiable`. +* `LipschitzSmoothWith.fderiv_descent_le` β€” the descent inequality in FrΓ©chet form. +* `LipschitzSmoothWith.fderiv_apply_sub_le` β€” variance bound on the FrΓ©chet derivative, + `fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. +* `LipschitzSmoothWith.fderiv_sub_apply_le` β€” function-subtraction restatement, + `(fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. +-/ + +public section + +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] +variable {K : NNReal} {f : F β†’ ℝ} + +/-- Characterisation of `LipschitzSmoothWith` in FrΓ©chet-derivative form, under +`Differentiable`. -/ +theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : + LipschitzSmoothWith K f ↔ + βˆ€ x y : F, f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by + rw [lipschitzSmoothWith_iff_lineDeriv] + refine forall_congr' fun x => forall_congr' fun y => ?_ + rw [(hf x).lineDeriv_eq_fderiv] + +namespace LipschitzSmoothWith + +/-- The descent inequality of a `K`-smooth `f` in FrΓ©chet-derivative form, under +`Differentiable`. -/ +theorem fderiv_descent_le (h : LipschitzSmoothWith K f) + (hf : Differentiable ℝ f) (x y : F) : + f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := + (lipschitzSmoothWith_iff_fderiv hf).mp h x y + +/-- For a differentiable `K`-smooth `f`, the variation of the FrΓ©chet derivative satisfies +`fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -/ +theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : F) : + fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by + rw [← (hf y).lineDeriv_eq_fderiv, ← (hf x).lineDeriv_eq_fderiv] + exact h.lineDeriv_apply_sub_le x y + +/-- Function-subtraction restatement of `fderiv_apply_sub_le`: +`(fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. -/ +theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : F) : + (fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := by + rw [ContinuousLinearMap.sub_apply] + exact h.fderiv_apply_sub_le hf x y + +end LipschitzSmoothWith From 0d3752ee9a6033d25012b057f710036d226af7f7 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 14:52:38 +0200 Subject: [PATCH 06/40] feat(Analysis/Calculus/LipschitzSmooth): add Deriv and Gradient layers Mirrors the FDeriv-layer pattern (iff characterisation + extractor + variance bound) for the 1D-deriv and Hilbert-gradient flavours of the LipschitzSmoothWith predicate, completing the four derivative-form characterisations symmetrically. Deriv.lean: * lipschitzSmoothWith_iff_deriv: characterisation for f : R -> R in deriv form under Differentiable, with the (y - x)^2 1D shape rather than (dist x y)^2. * LipschitzSmoothWith.deriv_descent_le: descent inequality extractor. * LipschitzSmoothWith.deriv_sub_mul_le: variance bound on deriv. Gradient.lean: * lipschitzSmoothWith_iff_inner_gradient: characterisation on a Hilbert space in gradient form under Differentiable. * LipschitzSmoothWith.inner_gradient_descent_le: descent inequality extractor. * LipschitzSmoothWith.inner_gradient_sub_le: variance bound on the gradient. The descent lemma (converse direction), the LipschitzWith K (fderiv) <-> LipschitzWith K (gradient) Riesz isomorphism, and the Baillon-Haddad equivalence with cocoercivity under convexity remain deferred to follow-ups. --- Mathlib.lean | 2 + .../Calculus/LipschitzSmooth/Deriv.lean | 61 +++++++++++++++++ .../Calculus/LipschitzSmooth/Gradient.lean | 66 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean create mode 100644 Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2975b58141ac91..2a3540cbc4140a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1775,7 +1775,9 @@ public import Mathlib.Analysis.Calculus.LineDeriv.IntegrationByParts public import Mathlib.Analysis.Calculus.LineDeriv.Measurable public import Mathlib.Analysis.Calculus.LineDeriv.QuadraticMap public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic +public import Mathlib.Analysis.Calculus.LipschitzSmooth.Deriv public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv +public import Mathlib.Analysis.Calculus.LipschitzSmooth.Gradient public import Mathlib.Analysis.Calculus.LocalExtr.Basic public import Mathlib.Analysis.Calculus.LocalExtr.LineDeriv public import Mathlib.Analysis.Calculus.LocalExtr.Polynomial diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean new file mode 100644 index 00000000000000..b2c23e4b6b6caa --- /dev/null +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -0,0 +1,61 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Calculus.Deriv.Basic +public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv + +/-! +# Lipschitz smoothness in 1D via the derivative + +For a `K`-smooth function `f : ℝ β†’ ℝ`, the descent inequality and the variation bound +on the derivative take their classical 1D forms + +`f y ≀ f x + deriv f x * (y - x) + K/2 * (y - x)^2`, +`(deriv f y - deriv f x) * (y - x) ≀ K * (y - x)^2`. + +These are the 1D restatements of the FrΓ©chet-derivative forms in +`Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv`, lifted via `fderiv_eq_deriv_mul` +(the identity `(fderiv ℝ f x : ℝ β†’ ℝ) y = deriv f x * y`). + +## Main results + +* `lipschitzSmoothWith_iff_deriv` β€” characterisation of `K`-smoothness in 1D + `deriv` form, under `Differentiable`. +* `LipschitzSmoothWith.deriv_descent_le` β€” the descent inequality in 1D `deriv` form. +* `LipschitzSmoothWith.deriv_sub_mul_le` β€” the variation bound in 1D `deriv` form. +-/ + +public section + +variable {K : NNReal} {f : ℝ β†’ ℝ} + +/-- Characterisation of `LipschitzSmoothWith` for `f : ℝ β†’ ℝ` in `deriv` form under +`Differentiable`. -/ +theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : + LipschitzSmoothWith K f ↔ + βˆ€ x y : ℝ, f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by + rw [lipschitzSmoothWith_iff_fderiv hf] + refine forall_congr' fun x => forall_congr' fun y => ?_ + rw [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] + +namespace LipschitzSmoothWith + +/-- For a differentiable `K`-smooth `f : ℝ β†’ ℝ`, the descent inequality in 1D form: +`f y ≀ f x + deriv f x * (y - x) + K/2 * (y - x)^2`. -/ +theorem deriv_descent_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : ℝ) : + f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := + (lipschitzSmoothWith_iff_deriv hf).mp h x y + +/-- For a differentiable `K`-smooth `f : ℝ β†’ ℝ`, the variation bound in 1D form: +`(deriv f y - deriv f x) * (y - x) ≀ K * (y - x)^2`. -/ +theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : ℝ) : + (deriv f y - deriv f x) * (y - x) ≀ ↑K * (y - x) ^ 2 := by + have hbase := h.fderiv_sub_apply_le hf x y + rwa [ContinuousLinearMap.sub_apply, fderiv_eq_deriv_mul, fderiv_eq_deriv_mul, ← sub_mul, + dist_comm, Real.dist_eq, sq_abs] at hbase + +end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean new file mode 100644 index 00000000000000..0da988c712adbf --- /dev/null +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -0,0 +1,66 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Calculus.Gradient.Basic +public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv + +/-! +# Lipschitz smoothness on a Hilbert space via the gradient + +On a Hilbert space `F`, the `LipschitzSmoothWith` predicate from +`Mathlib.Analysis.Calculus.LipschitzSmooth.Basic` admits a gradient-form +characterisation. For differentiable `f`, `fderiv ℝ f x (y - x) = βŸͺβˆ‡ f x, y - x⟫` +via Riesz representation (`inner_gradient_left`), and the descent inequality +becomes `f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K/2 Β· β€–y - xβ€–Β²`. + +This file provides only the characterisation and the elementary variance-bound +consequences; the descent lemma (converse direction) and the Baillon-Haddad +equivalence with cocoercivity are deferred to follow-ups. + +## Main results + +* `lipschitzSmoothWith_iff_inner_gradient` β€” characterisation of `K`-smoothness + in gradient form under `Differentiable`. +* `LipschitzSmoothWith.inner_gradient_descent_le` β€” the descent inequality in + gradient form. +* `LipschitzSmoothWith.inner_gradient_sub_le` β€” the gradient-variation bound + `βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ K Β· β€–y - xβ€–Β²`. +-/ + +public section + +variable {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] [CompleteSpace F] +variable {K : NNReal} {f : F β†’ ℝ} + +open InnerProductSpace +open scoped Gradient RealInnerProductSpace + +/-- Characterisation of `LipschitzSmoothWith` on a Hilbert space in gradient form under +`Differentiable`. -/ +theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : + LipschitzSmoothWith K f ↔ + βˆ€ x y : F, f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by + rw [lipschitzSmoothWith_iff_fderiv hf] + refine forall_congr' fun x => forall_congr' fun y => ?_ + rw [inner_gradient_left, dist_eq_norm'] + +namespace LipschitzSmoothWith + +/-- For a differentiable `K`-smooth `f` on a Hilbert space, the descent inequality in +gradient form: `f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K / 2 Β· β€–y - xβ€–Β²`. -/ +theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) + (x y : F) : f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := + (lipschitzSmoothWith_iff_inner_gradient hf).mp h x y + +/-- For a differentiable `K`-smooth `f` on a Hilbert space, the gradient-variation bound: +`βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ K * β€–y - xβ€–Β²`. -/ +theorem inner_gradient_sub_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) + (x y : F) : βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ ↑K * β€–y - xβ€– ^ 2 := by + simp only [← dist_eq_norm', inner_sub_left, inner_gradient_left, ← ContinuousLinearMap.sub_apply] + exact h.fderiv_sub_apply_le hf x y + +end LipschitzSmoothWith From 9b4c90bd630fc079b40c9965e68a3059d4987c44 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 15:03:11 +0200 Subject: [PATCH 07/40] refactor(LipschitzSmooth): weaken extractor hypotheses to DifferentiableAt The descent and variance-bound extractors at the FDeriv, Deriv, and Gradient layers previously required global Differentiable R f. Weaken to pointwise DifferentiableAt at the relevant point(s): * fderiv_descent_le, deriv_descent_le, inner_gradient_descent_le now take DifferentiableAt at x. * fderiv_apply_sub_le, fderiv_sub_apply_le, deriv_sub_mul_le, and inner_gradient_sub_le now take DifferentiableAt at both x and y. The iff lemmas (lipschitzSmoothWith_iff_fderiv, _deriv, _inner_gradient) keep Differentiable since they are global characterisations and genuinely require it. --- .../Calculus/LipschitzSmooth/Deriv.lean | 17 +++++++------ .../Calculus/LipschitzSmooth/FDeriv.lean | 25 +++++++++++-------- .../Calculus/LipschitzSmooth/Gradient.lean | 21 +++++++++------- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index b2c23e4b6b6caa..a66ede46c554b1 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -44,17 +44,20 @@ theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : namespace LipschitzSmoothWith -/-- For a differentiable `K`-smooth `f : ℝ β†’ ℝ`, the descent inequality in 1D form: +/-- For a `K`-smooth `f : ℝ β†’ ℝ` differentiable at `x`, the descent inequality in 1D form: `f y ≀ f x + deriv f x * (y - x) + K/2 * (y - x)^2`. -/ -theorem deriv_descent_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : ℝ) : - f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := - (lipschitzSmoothWith_iff_deriv hf).mp h x y +theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) + (hf : DifferentiableAt ℝ f x) : + f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by + have hbase := h.fderiv_descent_le x y hf + rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at hbase -/-- For a differentiable `K`-smooth `f : ℝ β†’ ℝ`, the variation bound in 1D form: +/-- For a `K`-smooth `f : ℝ β†’ ℝ` differentiable at `x` and `y`, the variation bound in 1D form: `(deriv f y - deriv f x) * (y - x) ≀ K * (y - x)^2`. -/ -theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : ℝ) : +theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (deriv f y - deriv f x) * (y - x) ≀ ↑K * (y - x) ^ 2 := by - have hbase := h.fderiv_sub_apply_le hf x y + have hbase := h.fderiv_sub_apply_le x y hfx hfy rwa [ContinuousLinearMap.sub_apply, fderiv_eq_deriv_mul, fderiv_eq_deriv_mul, ← sub_mul, dist_comm, Real.dist_eq, sq_abs] at hbase diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index a26b3c8076e9b9..ea73f6633999f3 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -48,24 +48,27 @@ theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : namespace LipschitzSmoothWith /-- The descent inequality of a `K`-smooth `f` in FrΓ©chet-derivative form, under -`Differentiable`. -/ -theorem fderiv_descent_le (h : LipschitzSmoothWith K f) - (hf : Differentiable ℝ f) (x y : F) : - f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := - (lipschitzSmoothWith_iff_fderiv hf).mp h x y +`DifferentiableAt` at `x`. -/ +theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : F) + (hf : DifferentiableAt ℝ f x) : + f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by + rw [← hf.lineDeriv_eq_fderiv] + exact h.lineDeriv_descent_le x y -/-- For a differentiable `K`-smooth `f`, the variation of the FrΓ©chet derivative satisfies -`fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -/ -theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : F) : +/-- For a `K`-smooth `f` differentiable at `x` and `y`, the variation of the FrΓ©chet derivative +satisfies `fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -/ +theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by - rw [← (hf y).lineDeriv_eq_fderiv, ← (hf x).lineDeriv_eq_fderiv] + rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] exact h.lineDeriv_apply_sub_le x y /-- Function-subtraction restatement of `fderiv_apply_sub_le`: `(fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. -/ -theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) (x y : F) : +theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := by rw [ContinuousLinearMap.sub_apply] - exact h.fderiv_apply_sub_le hf x y + exact h.fderiv_apply_sub_le x y hfx hfy end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 0da988c712adbf..2459406fd9f45a 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -50,17 +50,20 @@ theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : namespace LipschitzSmoothWith -/-- For a differentiable `K`-smooth `f` on a Hilbert space, the descent inequality in +/-- For a `K`-smooth `f` differentiable at `x` on a Hilbert space, the descent inequality in gradient form: `f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K / 2 Β· β€–y - xβ€–Β²`. -/ -theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) - (x y : F) : f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := - (lipschitzSmoothWith_iff_inner_gradient hf).mp h x y +theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (x y : F) + (hf : DifferentiableAt ℝ f x) : + f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by + rw [inner_gradient_left, ← dist_eq_norm'] + exact h.fderiv_descent_le x y hf -/-- For a differentiable `K`-smooth `f` on a Hilbert space, the gradient-variation bound: -`βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ K * β€–y - xβ€–Β²`. -/ -theorem inner_gradient_sub_le (h : LipschitzSmoothWith K f) (hf : Differentiable ℝ f) - (x y : F) : βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ ↑K * β€–y - xβ€– ^ 2 := by +/-- For a `K`-smooth `f` differentiable at `x` and `y` on a Hilbert space, the gradient-variation +bound: `βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ K * β€–y - xβ€–Β²`. -/ +theorem inner_gradient_sub_le (h : LipschitzSmoothWith K f) (x y : F) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : + βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ ↑K * β€–y - xβ€– ^ 2 := by simp only [← dist_eq_norm', inner_sub_left, inner_gradient_left, ← ContinuousLinearMap.sub_apply] - exact h.fderiv_sub_apply_le hf x y + exact h.fderiv_sub_apply_le x y hfx hfy end LipschitzSmoothWith From 5e90e5776f661a737120510d007bb1ecc64c24a1 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 15:08:11 +0200 Subject: [PATCH 08/40] chore(LipschitzSmooth): drop redundant per-theorem docstrings Each theorem's docstring just restated the signature in English. The module-level 'Main results' lists already give a brief one-line description per declaration, which is sufficient. Per mathlib-design conventions, docstrings on theorems are encouraged only where they add information beyond the type signature. The def-level docstring on LipschitzSmoothWith itself is preserved. --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 6 ------ Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean | 6 ------ Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean | 8 -------- Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean | 6 ------ 4 files changed, 26 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 9b3f53ba544ece..e0b781475d0399 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -58,7 +58,6 @@ sibling files, predicated on the appropriate differentiability hypothesis. -/ def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) : Prop := βˆ€ (x y : F), f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 -/-- Characterisation of `LipschitzSmoothWith` in line-derivative form. -/ theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : F β†’ ℝ} : LipschitzSmoothWith K f ↔ βˆ€ x y : F, f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := @@ -68,20 +67,15 @@ namespace LipschitzSmoothWith variable {K : NNReal} {f : F β†’ ℝ} -/-- The defining descent inequality of a `K`-smooth function in line-derivative form. -/ theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := h x y -/-- A `K`-smooth `f` satisfies a quadratic upper bound on the variation of its line-derivative: -`lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -/ theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by linarith [h.lineDeriv_descent_le x y, lineDeriv_neg (π•œ := ℝ) (f := f) β–Έ neg_sub y _ β–Έ dist_comm y _ β–Έ h.lineDeriv_descent_le y x] -/-- Function-subtraction restatement of `lineDeriv_apply_sub_le`: -`(lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. -/ theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index a66ede46c554b1..63d14f54022be7 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -33,8 +33,6 @@ public section variable {K : NNReal} {f : ℝ β†’ ℝ} -/-- Characterisation of `LipschitzSmoothWith` for `f : ℝ β†’ ℝ` in `deriv` form under -`Differentiable`. -/ theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ βˆ€ x y : ℝ, f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by @@ -44,16 +42,12 @@ theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : namespace LipschitzSmoothWith -/-- For a `K`-smooth `f : ℝ β†’ ℝ` differentiable at `x`, the descent inequality in 1D form: -`f y ≀ f x + deriv f x * (y - x) + K/2 * (y - x)^2`. -/ theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by have hbase := h.fderiv_descent_le x y hf rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at hbase -/-- For a `K`-smooth `f : ℝ β†’ ℝ` differentiable at `x` and `y`, the variation bound in 1D form: -`(deriv f y - deriv f x) * (y - x) ≀ K * (y - x)^2`. -/ theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (deriv f y - deriv f x) * (y - x) ≀ ↑K * (y - x) ^ 2 := by diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index ea73f6633999f3..92fbf9fb16f812 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -36,8 +36,6 @@ public section variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] variable {K : NNReal} {f : F β†’ ℝ} -/-- Characterisation of `LipschitzSmoothWith` in FrΓ©chet-derivative form, under -`Differentiable`. -/ theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ βˆ€ x y : F, f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by @@ -47,24 +45,18 @@ theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : namespace LipschitzSmoothWith -/-- The descent inequality of a `K`-smooth `f` in FrΓ©chet-derivative form, under -`DifferentiableAt` at `x`. -/ theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_descent_le x y -/-- For a `K`-smooth `f` differentiable at `x` and `y`, the variation of the FrΓ©chet derivative -satisfies `fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -/ theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] exact h.lineDeriv_apply_sub_le x y -/-- Function-subtraction restatement of `fderiv_apply_sub_le`: -`(fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. -/ theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := by diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 2459406fd9f45a..29730a739fbee3 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -39,8 +39,6 @@ variable {K : NNReal} {f : F β†’ ℝ} open InnerProductSpace open scoped Gradient RealInnerProductSpace -/-- Characterisation of `LipschitzSmoothWith` on a Hilbert space in gradient form under -`Differentiable`. -/ theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ βˆ€ x y : F, f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by @@ -50,16 +48,12 @@ theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : namespace LipschitzSmoothWith -/-- For a `K`-smooth `f` differentiable at `x` on a Hilbert space, the descent inequality in -gradient form: `f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K / 2 Β· β€–y - xβ€–Β²`. -/ theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by rw [inner_gradient_left, ← dist_eq_norm'] exact h.fderiv_descent_le x y hf -/-- For a `K`-smooth `f` differentiable at `x` and `y` on a Hilbert space, the gradient-variation -bound: `βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ K * β€–y - xβ€–Β²`. -/ theorem inner_gradient_sub_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ ↑K * β€–y - xβ€– ^ 2 := by From 86e28e37f80c462248424694e7cec1ba6ba653f8 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 15:18:18 +0200 Subject: [PATCH 09/40] chore(LipschitzSmooth): audit-pass on docstrings and imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Basic.lean: add Deriv.lean to the sibling-file references in the file docstring. * Harmonise Main-results bullets across the four files: one-line descriptions with no embedded statement repetitions. * Gradient.lean: drop unused `open InnerProductSpace` β€” the file uses only inner-product-scoped notation (`open scoped RealInnerProductSpace`) and root-namespace lemmas like `inner_gradient_left`. --- .../Calculus/LipschitzSmooth/Basic.lean | 19 +++++++++---------- .../Calculus/LipschitzSmooth/Deriv.lean | 5 ++--- .../Calculus/LipschitzSmooth/FDeriv.lean | 9 +++------ .../Calculus/LipschitzSmooth/Gradient.lean | 11 ++++------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index e0b781475d0399..0032e10012aa7c 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -22,11 +22,11 @@ derivative implies `K`-smoothness. The predicate is stated using `lineDeriv` so it does not presuppose FrΓ©chet differentiability; for differentiable `f`, `lineDeriv` and `fderiv` agree -pointwise. FrΓ©chet-derivative restatements and the descent lemma β€” whose -hypothesis `LipschitzWith K (fderiv ℝ f)` lives in the fderiv world β€” are in -`Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv`. Inner-product-space restatements -via the gradient `βˆ‡` and `βŸͺΒ·, ·⟫` are in -`Mathlib.Analysis.Calculus.LipschitzSmooth.Gradient`. +pointwise. Restatements in other derivative-flavoured forms live in the sibling +files: `Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv` for `fderiv`, +`Mathlib.Analysis.Calculus.LipschitzSmooth.Deriv` for the 1D `deriv` form, +and `Mathlib.Analysis.Calculus.LipschitzSmooth.Gradient` for the Hilbert-space +gradient form. ## Main definitions @@ -35,11 +35,10 @@ via the gradient `βˆ‡` and `βŸͺΒ·, ·⟫` are in ## Main results * `lipschitzSmoothWith_iff_lineDeriv` β€” characterisation in line-derivative form. -* `LipschitzSmoothWith.lineDeriv_descent_le` β€” the defining descent inequality - extracted as a forward implication. -* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” a `K`-smooth `f` satisfies the - quadratic upper bound `lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K Β· (dist x y)Β²` - on the variation of its line-derivative, with no additional hypotheses. +* `LipschitzSmoothWith.lineDeriv_descent_le` β€” the descent inequality extracted as + a forward implication. +* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” variance bound on the line-derivative, + with no additional hypotheses. * `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” function-subtraction restatement. -/ diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index 63d14f54022be7..68fc2529f4447c 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -23,10 +23,9 @@ These are the 1D restatements of the FrΓ©chet-derivative forms in ## Main results -* `lipschitzSmoothWith_iff_deriv` β€” characterisation of `K`-smoothness in 1D - `deriv` form, under `Differentiable`. +* `lipschitzSmoothWith_iff_deriv` β€” characterisation in 1D `deriv` form under `Differentiable`. * `LipschitzSmoothWith.deriv_descent_le` β€” the descent inequality in 1D `deriv` form. -* `LipschitzSmoothWith.deriv_sub_mul_le` β€” the variation bound in 1D `deriv` form. +* `LipschitzSmoothWith.deriv_sub_mul_le` β€” variance bound on the 1D `deriv`. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index 92fbf9fb16f812..be67c228bd877d 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -22,13 +22,10 @@ the full descent lemma β€” i.e. the converse direction ## Main results -* `lipschitzSmoothWith_iff_fderiv` β€” characterisation of `K`-smoothness in FrΓ©chet form - under `Differentiable`. +* `lipschitzSmoothWith_iff_fderiv` β€” characterisation in FrΓ©chet form under `Differentiable`. * `LipschitzSmoothWith.fderiv_descent_le` β€” the descent inequality in FrΓ©chet form. -* `LipschitzSmoothWith.fderiv_apply_sub_le` β€” variance bound on the FrΓ©chet derivative, - `fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K Β· (dist x y)Β²`. -* `LipschitzSmoothWith.fderiv_sub_apply_le` β€” function-subtraction restatement, - `(fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ K Β· (dist x y)Β²`. +* `LipschitzSmoothWith.fderiv_apply_sub_le` β€” variance bound on the FrΓ©chet derivative. +* `LipschitzSmoothWith.fderiv_sub_apply_le` β€” function-subtraction restatement. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 29730a739fbee3..6e29aff9a39ec6 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -23,12 +23,10 @@ equivalence with cocoercivity are deferred to follow-ups. ## Main results -* `lipschitzSmoothWith_iff_inner_gradient` β€” characterisation of `K`-smoothness - in gradient form under `Differentiable`. -* `LipschitzSmoothWith.inner_gradient_descent_le` β€” the descent inequality in - gradient form. -* `LipschitzSmoothWith.inner_gradient_sub_le` β€” the gradient-variation bound - `βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ K Β· β€–y - xβ€–Β²`. +* `lipschitzSmoothWith_iff_inner_gradient` β€” characterisation in gradient form + under `Differentiable`. +* `LipschitzSmoothWith.inner_gradient_descent_le` β€” the descent inequality in gradient form. +* `LipschitzSmoothWith.inner_gradient_sub_le` β€” variance bound on the gradient. -/ public section @@ -36,7 +34,6 @@ public section variable {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] [CompleteSpace F] variable {K : NNReal} {f : F β†’ ℝ} -open InnerProductSpace open scoped Gradient RealInnerProductSpace theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : From 49820aeaa36f6f5f3cc9fc6386cc23ccc6400e44 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 16:09:24 +0200 Subject: [PATCH 10/40] chore(LipschitzSmooth/Basic): refactor lineDeriv_apply_sub_le, trim docstring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replace the β–Έ chain (lineDeriv_neg β–Έ neg_sub β–Έ dist_comm β–Έ) in the proof of lineDeriv_apply_sub_le with explicit `have` + `rw` + `linarith`. * Trim the module docstring from ~33 to ~22 lines: drop the per-sibling-file enumeration (the directory listing is self-evident) and remove repetition of the implementation-detail rationale. --- .../Calculus/LipschitzSmooth/Basic.lean | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 0032e10012aa7c..c54ce7ae268d5b 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -10,23 +10,14 @@ public import Mathlib.Analysis.Calculus.LineDeriv.Basic /-! # Lipschitz smoothness -A real-valued function `f` on a normed real vector space is **`K`-smooth** if -it satisfies the quadratic descent inequality +A real-valued function `f` on a normed real vector space is **`K`-smooth** if it satisfies +the quadratic descent inequality `f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β²` -for all `x, y`. This is the standard quadratic upper bound used to control -descent steps in first-order convex optimisation. The `K / 2` convention -makes the descent lemma constant-preserving: a `K`-Lipschitz FrΓ©chet -derivative implies `K`-smoothness. - -The predicate is stated using `lineDeriv` so it does not presuppose FrΓ©chet -differentiability; for differentiable `f`, `lineDeriv` and `fderiv` agree -pointwise. Restatements in other derivative-flavoured forms live in the sibling -files: `Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv` for `fderiv`, -`Mathlib.Analysis.Calculus.LipschitzSmooth.Deriv` for the 1D `deriv` form, -and `Mathlib.Analysis.Calculus.LipschitzSmooth.Gradient` for the Hilbert-space -gradient form. +for all `x, y`. The predicate uses `lineDeriv` so as not to presuppose FrΓ©chet +differentiability; restatements in `fderiv`, 1D `deriv`, and Hilbert-space gradient +form live in the sibling files in this directory. ## Main definitions @@ -35,10 +26,8 @@ gradient form. ## Main results * `lipschitzSmoothWith_iff_lineDeriv` β€” characterisation in line-derivative form. -* `LipschitzSmoothWith.lineDeriv_descent_le` β€” the descent inequality extracted as - a forward implication. -* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” variance bound on the line-derivative, - with no additional hypotheses. +* `LipschitzSmoothWith.lineDeriv_descent_le` β€” the descent inequality as a forward implication. +* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” variance bound on the line-derivative. * `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” function-subtraction restatement. -/ @@ -72,8 +61,9 @@ theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by - linarith [h.lineDeriv_descent_le x y, - lineDeriv_neg (π•œ := ℝ) (f := f) β–Έ neg_sub y _ β–Έ dist_comm y _ β–Έ h.lineDeriv_descent_le y x] + have hyx := h.lineDeriv_descent_le y x + rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx + linarith [h.lineDeriv_descent_le x y, hyx] theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := From ea0191c901bd2735242617df3e31d9e8bf3fa319 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 16:23:59 +0200 Subject: [PATCH 11/40] chore(LipschitzSmooth): consolidate Main results bullets Each file's ## Main results section listed the descent extractor and the two variance-bound packaging forms as separate bullets, which inflated the section without adding information. Consolidate to one bullet per file covering descent + variance-bound together, while keeping the iff lemma as a separate top-level entry. --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 8 ++++---- Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean | 4 ++-- Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean | 5 ++--- Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean | 8 ++++---- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index c54ce7ae268d5b..5bfc61b717339d 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -25,10 +25,10 @@ form live in the sibling files in this directory. ## Main results -* `lipschitzSmoothWith_iff_lineDeriv` β€” characterisation in line-derivative form. -* `LipschitzSmoothWith.lineDeriv_descent_le` β€” the descent inequality as a forward implication. -* `LipschitzSmoothWith.lineDeriv_apply_sub_le` β€” variance bound on the line-derivative. -* `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” function-subtraction restatement. +* `lipschitzSmoothWith_iff_lineDeriv` β€” characterisation as the underlying inequality. +* `LipschitzSmoothWith.{lineDeriv_descent_le, lineDeriv_apply_sub_le, lineDeriv_sub_apply_le}` β€” + the descent inequality as a forward implication and the resulting variance bound on the + line-derivative. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index 68fc2529f4447c..e30595621fba1f 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -24,8 +24,8 @@ These are the 1D restatements of the FrΓ©chet-derivative forms in ## Main results * `lipschitzSmoothWith_iff_deriv` β€” characterisation in 1D `deriv` form under `Differentiable`. -* `LipschitzSmoothWith.deriv_descent_le` β€” the descent inequality in 1D `deriv` form. -* `LipschitzSmoothWith.deriv_sub_mul_le` β€” variance bound on the 1D `deriv`. +* `LipschitzSmoothWith.{deriv_descent_le, deriv_sub_mul_le}` β€” the descent inequality and the + variance bound on the 1D `deriv`. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index be67c228bd877d..e4e087aead41f4 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -23,9 +23,8 @@ the full descent lemma β€” i.e. the converse direction ## Main results * `lipschitzSmoothWith_iff_fderiv` β€” characterisation in FrΓ©chet form under `Differentiable`. -* `LipschitzSmoothWith.fderiv_descent_le` β€” the descent inequality in FrΓ©chet form. -* `LipschitzSmoothWith.fderiv_apply_sub_le` β€” variance bound on the FrΓ©chet derivative. -* `LipschitzSmoothWith.fderiv_sub_apply_le` β€” function-subtraction restatement. +* `LipschitzSmoothWith.{fderiv_descent_le, fderiv_apply_sub_le, fderiv_sub_apply_le}` β€” + the descent inequality and the variance bound on the FrΓ©chet derivative. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 6e29aff9a39ec6..987490b32c086f 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -23,10 +23,10 @@ equivalence with cocoercivity are deferred to follow-ups. ## Main results -* `lipschitzSmoothWith_iff_inner_gradient` β€” characterisation in gradient form - under `Differentiable`. -* `LipschitzSmoothWith.inner_gradient_descent_le` β€” the descent inequality in gradient form. -* `LipschitzSmoothWith.inner_gradient_sub_le` β€” variance bound on the gradient. +* `lipschitzSmoothWith_iff_inner_gradient` β€” characterisation in gradient form under + `Differentiable`. +* `LipschitzSmoothWith.{inner_gradient_descent_le, inner_gradient_sub_le}` β€” the descent + inequality and the variance bound on the gradient. -/ public section From 7d686b17ba4e25172bc7955fab6b3a143c5760f2 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 16:26:17 +0200 Subject: [PATCH 12/40] chore(LipschitzSmooth): use comma-separated names in Main results Foo.{bar, baz} is Lean syntax for universe parameters and could confuse a reader. Switch to mathlib-standard comma-separated qualified names. --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 6 +++--- Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean | 4 ++-- Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean | 5 +++-- Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 5bfc61b717339d..ac84512d11f4f9 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -26,9 +26,9 @@ form live in the sibling files in this directory. ## Main results * `lipschitzSmoothWith_iff_lineDeriv` β€” characterisation as the underlying inequality. -* `LipschitzSmoothWith.{lineDeriv_descent_le, lineDeriv_apply_sub_le, lineDeriv_sub_apply_le}` β€” - the descent inequality as a forward implication and the resulting variance bound on the - line-derivative. +* `LipschitzSmoothWith.lineDeriv_descent_le`, `LipschitzSmoothWith.lineDeriv_apply_sub_le`, + `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” the descent inequality as a forward + implication and the resulting variance bound on the line-derivative. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index e30595621fba1f..0cfffb4f6c948b 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -24,8 +24,8 @@ These are the 1D restatements of the FrΓ©chet-derivative forms in ## Main results * `lipschitzSmoothWith_iff_deriv` β€” characterisation in 1D `deriv` form under `Differentiable`. -* `LipschitzSmoothWith.{deriv_descent_le, deriv_sub_mul_le}` β€” the descent inequality and the - variance bound on the 1D `deriv`. +* `LipschitzSmoothWith.deriv_descent_le`, `LipschitzSmoothWith.deriv_sub_mul_le` β€” + the descent inequality and the variance bound on the 1D `deriv`. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index e4e087aead41f4..989540d03fb07a 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -23,8 +23,9 @@ the full descent lemma β€” i.e. the converse direction ## Main results * `lipschitzSmoothWith_iff_fderiv` β€” characterisation in FrΓ©chet form under `Differentiable`. -* `LipschitzSmoothWith.{fderiv_descent_le, fderiv_apply_sub_le, fderiv_sub_apply_le}` β€” - the descent inequality and the variance bound on the FrΓ©chet derivative. +* `LipschitzSmoothWith.fderiv_descent_le`, `LipschitzSmoothWith.fderiv_apply_sub_le`, + `LipschitzSmoothWith.fderiv_sub_apply_le` β€” the descent inequality and the variance + bound on the FrΓ©chet derivative. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 987490b32c086f..04740f4394a1e2 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -25,8 +25,8 @@ equivalence with cocoercivity are deferred to follow-ups. * `lipschitzSmoothWith_iff_inner_gradient` β€” characterisation in gradient form under `Differentiable`. -* `LipschitzSmoothWith.{inner_gradient_descent_le, inner_gradient_sub_le}` β€” the descent - inequality and the variance bound on the gradient. +* `LipschitzSmoothWith.inner_gradient_descent_le`, `LipschitzSmoothWith.inner_gradient_sub_le` β€” + the descent inequality and the variance bound on the gradient. -/ public section From cf64bce52e31d22a011d4bf1f77080fe783e5fb8 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Tue, 19 May 2026 11:12:04 +0200 Subject: [PATCH 13/40] chore(LipschitzSmooth): minor style/formatting tweaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Drop `: Prop` annotation on `def LipschitzSmoothWith` (matches the `LipschitzWith` precedent in `Topology/EMetricSpace/Lipschitz.lean`). * Compact iff lemma signatures: put `LipschitzSmoothWith K f ↔` on the same line as the `theorem` keyword across all four files. * Inline single-line returns where the body is short (`lineDeriv_descent_le`, `fderiv_descent_le`, `deriv_descent_le`). * Rename `have hbase := ...` to `have := ...` (anonymous `this` binding) in `Deriv.lean` proofs. --- .../Analysis/Calculus/LipschitzSmooth/Basic.lean | 11 ++++------- .../Analysis/Calculus/LipschitzSmooth/Deriv.lean | 16 +++++++--------- .../Calculus/LipschitzSmooth/FDeriv.lean | 8 +++----- .../Calculus/LipschitzSmooth/Gradient.lean | 3 +-- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index ac84512d11f4f9..bedf38dfaefc35 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -43,21 +43,18 @@ The choice of `lineDeriv` here is an implementation detail: it is the weakest fo that makes the predicate well-defined for non-differentiable functions. Equivalent characterisations in `fderiv`, `gradient`, and `deriv` form are provided in the sibling files, predicated on the appropriate differentiability hypothesis. -/ -def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) : Prop := +def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) := βˆ€ (x y : F), f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 -theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : F β†’ ℝ} : - LipschitzSmoothWith K f ↔ - βˆ€ x y : F, f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := - Iff.rfl +theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : F β†’ ℝ} : LipschitzSmoothWith K f ↔ + βˆ€ x y : F, f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := Iff.rfl namespace LipschitzSmoothWith variable {K : NNReal} {f : F β†’ ℝ} theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : - f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := - h x y + f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := h x y theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index 0cfffb4f6c948b..820946890e827f 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -32,26 +32,24 @@ public section variable {K : NNReal} {f : ℝ β†’ ℝ} -theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : - LipschitzSmoothWith K f ↔ - βˆ€ x y : ℝ, f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by +theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ + βˆ€ x y : ℝ, f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] namespace LipschitzSmoothWith -theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) - (hf : DifferentiableAt ℝ f x) : +theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by - have hbase := h.fderiv_descent_le x y hf - rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at hbase + have := h.fderiv_descent_le x y hf + rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (deriv f y - deriv f x) * (y - x) ≀ ↑K * (y - x) ^ 2 := by - have hbase := h.fderiv_sub_apply_le x y hfx hfy + have := h.fderiv_sub_apply_le x y hfx hfy rwa [ContinuousLinearMap.sub_apply, fderiv_eq_deriv_mul, fderiv_eq_deriv_mul, ← sub_mul, - dist_comm, Real.dist_eq, sq_abs] at hbase + dist_comm, Real.dist_eq, sq_abs] at this end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index 989540d03fb07a..ecf1269a2b8e50 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -33,17 +33,15 @@ public section variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] variable {K : NNReal} {f : F β†’ ℝ} -theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : - LipschitzSmoothWith K f ↔ - βˆ€ x y : F, f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by +theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ + βˆ€ x y : F, f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by rw [lipschitzSmoothWith_iff_lineDeriv] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [(hf x).lineDeriv_eq_fderiv] namespace LipschitzSmoothWith -theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : F) - (hf : DifferentiableAt ℝ f x) : +theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_descent_le x y diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 04740f4394a1e2..9f6615b5461780 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -37,8 +37,7 @@ variable {K : NNReal} {f : F β†’ ℝ} open scoped Gradient RealInnerProductSpace theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : - LipschitzSmoothWith K f ↔ - βˆ€ x y : F, f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by + LipschitzSmoothWith K f ↔ βˆ€ x y : F, f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [inner_gradient_left, dist_eq_norm'] From 3365004bc194ec6dd1f922a882df89307f088902 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Tue, 19 May 2026 11:21:08 +0200 Subject: [PATCH 14/40] chore(LipschitzSmooth): trim verbose file-level docstrings Drop the per-file "Main results" / "Main definitions" enumerations from the four module docstrings; keep just the intro paragraph. The declarations bot already lists new declarations, and the file contents are short enough that the enumeration was pure duplication. --- .../Calculus/LipschitzSmooth/Basic.lean | 11 ---------- .../Calculus/LipschitzSmooth/Deriv.lean | 17 +++++----------- .../Calculus/LipschitzSmooth/FDeriv.lean | 20 +++++-------------- .../Calculus/LipschitzSmooth/Gradient.lean | 19 ++++-------------- 4 files changed, 14 insertions(+), 53 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index bedf38dfaefc35..e681029936231c 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -18,17 +18,6 @@ the quadratic descent inequality for all `x, y`. The predicate uses `lineDeriv` so as not to presuppose FrΓ©chet differentiability; restatements in `fderiv`, 1D `deriv`, and Hilbert-space gradient form live in the sibling files in this directory. - -## Main definitions - -* `LipschitzSmoothWith K f` β€” the predicate above. - -## Main results - -* `lipschitzSmoothWith_iff_lineDeriv` β€” characterisation as the underlying inequality. -* `LipschitzSmoothWith.lineDeriv_descent_le`, `LipschitzSmoothWith.lineDeriv_apply_sub_le`, - `LipschitzSmoothWith.lineDeriv_sub_apply_le` β€” the descent inequality as a forward - implication and the resulting variance bound on the line-derivative. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index 820946890e827f..c878a8bb76ae8c 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -12,20 +12,13 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv # Lipschitz smoothness in 1D via the derivative For a `K`-smooth function `f : ℝ β†’ ℝ`, the descent inequality and the variation bound -on the derivative take their classical 1D forms +take their classical 1D forms -`f y ≀ f x + deriv f x * (y - x) + K/2 * (y - x)^2`, -`(deriv f y - deriv f x) * (y - x) ≀ K * (y - x)^2`. +`f y ≀ f x + deriv f x * (y - x) + K/2 * (y - x)Β²`, +`(deriv f y - deriv f x) * (y - x) ≀ K * (y - x)Β²`. -These are the 1D restatements of the FrΓ©chet-derivative forms in -`Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv`, lifted via `fderiv_eq_deriv_mul` -(the identity `(fderiv ℝ f x : ℝ β†’ ℝ) y = deriv f x * y`). - -## Main results - -* `lipschitzSmoothWith_iff_deriv` β€” characterisation in 1D `deriv` form under `Differentiable`. -* `LipschitzSmoothWith.deriv_descent_le`, `LipschitzSmoothWith.deriv_sub_mul_le` β€” - the descent inequality and the variance bound on the 1D `deriv`. +These are 1D restatements of the FrΓ©chet-derivative forms in +`Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv`, lifted via `fderiv_eq_deriv_mul`. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index ecf1269a2b8e50..0b3767c864e668 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -11,21 +11,11 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic /-! # Lipschitz smoothness via the FrΓ©chet derivative -FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate from -`Mathlib.Analysis.Calculus.LipschitzSmooth.Basic`. For differentiable `f`, -`lineDeriv ℝ f x v = fderiv ℝ f x v` pointwise, and the predicate is equivalent -to the corresponding descent inequality stated in `fderiv` form. - -This file provides only the equivalence and the elementary variance-bound consequences; -the full descent lemma β€” i.e. the converse direction -`LipschitzWith K (fderiv ℝ f) β†’ LipschitzSmoothWith K f` β€” is deferred to a follow-up. - -## Main results - -* `lipschitzSmoothWith_iff_fderiv` β€” characterisation in FrΓ©chet form under `Differentiable`. -* `LipschitzSmoothWith.fderiv_descent_le`, `LipschitzSmoothWith.fderiv_apply_sub_le`, - `LipschitzSmoothWith.fderiv_sub_apply_le` β€” the descent inequality and the variance - bound on the FrΓ©chet derivative. +FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate. For differentiable +`f`, `lineDeriv ℝ f x v = fderiv ℝ f x v` pointwise, and the predicate is equivalent to +the corresponding descent inequality stated in `fderiv` form. The full descent lemma β€” +the converse direction `LipschitzWith K (fderiv ℝ f) β†’ LipschitzSmoothWith K f` β€” is +deferred to a follow-up. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 9f6615b5461780..f91cb9ce3d39ab 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -11,22 +11,11 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv /-! # Lipschitz smoothness on a Hilbert space via the gradient -On a Hilbert space `F`, the `LipschitzSmoothWith` predicate from -`Mathlib.Analysis.Calculus.LipschitzSmooth.Basic` admits a gradient-form +On a Hilbert space `F`, the `LipschitzSmoothWith` predicate admits a gradient-form characterisation. For differentiable `f`, `fderiv ℝ f x (y - x) = βŸͺβˆ‡ f x, y - x⟫` -via Riesz representation (`inner_gradient_left`), and the descent inequality -becomes `f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K/2 Β· β€–y - xβ€–Β²`. - -This file provides only the characterisation and the elementary variance-bound -consequences; the descent lemma (converse direction) and the Baillon-Haddad -equivalence with cocoercivity are deferred to follow-ups. - -## Main results - -* `lipschitzSmoothWith_iff_inner_gradient` β€” characterisation in gradient form under - `Differentiable`. -* `LipschitzSmoothWith.inner_gradient_descent_le`, `LipschitzSmoothWith.inner_gradient_sub_le` β€” - the descent inequality and the variance bound on the gradient. +via Riesz representation (`inner_gradient_left`), and the descent inequality becomes +`f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K/2 Β· β€–y - xβ€–Β²`. The descent lemma (converse direction) +and the Baillon-Haddad equivalence with cocoercivity are deferred to follow-ups. -/ public section From 1c3478cc316fa5a78a89f2ad8a2c65a30d4d7211 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Tue, 19 May 2026 11:55:05 +0200 Subject: [PATCH 15/40] feat(Analysis/Calculus/LipschitzSmooth): add CocoerciveWith MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce the `CocoerciveWith K f` predicate on a Hilbert space and the elementary direction `K`-cocoercive ⟹ `K`-Lipschitz gradient (Cauchy-Schwarz). The converse direction `K`-smooth + convex ⟹ `K`-cocoercive (Baillon-Haddad) is provided in a follow-up. --- .../Calculus/LipschitzSmooth/Cocoercive.lean | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean new file mode 100644 index 00000000000000..48c3d38ab16978 --- /dev/null +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean @@ -0,0 +1,41 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Calculus.Gradient.Basic + +/-! +# Cocoercivity + +A function `f : F β†’ ℝ` on a Hilbert space is **`K`-cocoercive** if its gradient satisfies +`β€–βˆ‡ f y - βˆ‡ f xβ€–Β² ≀ K Β· βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫` for all `x, y`. This is the conclusion of +the Baillon-Haddad theorem (`K`-smooth + convex ⟹ `K`-cocoercive); this file packages +only the predicate and the elementary direction `K`-cocoercive ⟹ `K`-Lipschitz gradient, +which is a pure Cauchy-Schwarz consequence and needs no convexity or smoothness input. +-/ + +public section + +variable {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] [CompleteSpace F] + +open scoped Gradient RealInnerProductSpace + +/-- A function `f : F β†’ ℝ` on a Hilbert space is **`K`-cocoercive** if its gradient satisfies +`β€–βˆ‡ f y - βˆ‡ f xβ€–Β² ≀ K Β· βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫` for all `x, y`. Equivalent to the standard +`(1/K)Β·β€–Β·β€–Β² ≀ βŸͺΒ·,·⟫` form when `0 < K`, but well-defined and meaningful even at `K = 0` +(then forces `βˆ‡ f` constant). The conclusion of the Baillon-Haddad theorem. -/ +abbrev CocoerciveWith (K : NNReal) (f : F β†’ ℝ) : Prop := + βˆ€ x y : F, β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 ≀ ↑K * βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ + +/-- A `K`-cocoercive gradient is `K`-Lipschitz. (One direction of the Baillon-Haddad +characterisation; the reverse requires convexity.) -/ +theorem CocoerciveWith.lipschitzWith_gradient {K : NNReal} {f : F β†’ ℝ} + (h : CocoerciveWith K f) : LipschitzWith K (βˆ‡ f) := + lipschitzWith_iff_dist_le_mul.mpr fun x y => by + simp only [dist_eq_norm'] + have hcs : βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ β€–βˆ‡ f y - βˆ‡ f xβ€– * β€–y - xβ€– := real_inner_le_norm _ _ + nlinarith [h x y, mul_nonneg K.coe_nonneg (norm_nonneg (y - x)), + mul_le_mul_of_nonneg_left hcs K.coe_nonneg] From c5147c215a18212e2ae160409cf58bba1ba7567b Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Tue, 19 May 2026 12:58:18 +0200 Subject: [PATCH 16/40] chore(LipschitzSmooth/Cocoercive): inline single-use hcs hypothesis --- Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean index 48c3d38ab16978..42428b753d10f3 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean @@ -36,6 +36,5 @@ theorem CocoerciveWith.lipschitzWith_gradient {K : NNReal} {f : F β†’ ℝ} (h : CocoerciveWith K f) : LipschitzWith K (βˆ‡ f) := lipschitzWith_iff_dist_le_mul.mpr fun x y => by simp only [dist_eq_norm'] - have hcs : βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ β€–βˆ‡ f y - βˆ‡ f xβ€– * β€–y - xβ€– := real_inner_le_norm _ _ nlinarith [h x y, mul_nonneg K.coe_nonneg (norm_nonneg (y - x)), - mul_le_mul_of_nonneg_left hcs K.coe_nonneg] + mul_le_mul_of_nonneg_left (real_inner_le_norm (βˆ‡ f y - βˆ‡ f x) (y - x)) K.coe_nonneg] From 6eecf03fc5fa30a347bf25ca8ee6f7b77e853f49 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Tue, 19 May 2026 13:32:59 +0200 Subject: [PATCH 17/40] refactor(LipschitzSmooth): fold Cocoercive.lean into Gradient.lean MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `CocoerciveWith` shares the Hilbert-space context with the gradient-form characterisations of `LipschitzSmoothWith` and was always going to be a small, focused file. Folding it eliminates one module with no import overhead β€” `Gradient.lean` already imports `Gradient.Basic`. --- .../Calculus/LipschitzSmooth/Cocoercive.lean | 40 ------------------- .../Calculus/LipschitzSmooth/Gradient.lean | 21 ++++++++++ 2 files changed, 21 insertions(+), 40 deletions(-) delete mode 100644 Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean deleted file mode 100644 index 42428b753d10f3..00000000000000 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Cocoercive.lean +++ /dev/null @@ -1,40 +0,0 @@ -/- -Copyright (c) 2026 Christoph Spiegel. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Christoph Spiegel --/ -module - -public import Mathlib.Analysis.Calculus.Gradient.Basic - -/-! -# Cocoercivity - -A function `f : F β†’ ℝ` on a Hilbert space is **`K`-cocoercive** if its gradient satisfies -`β€–βˆ‡ f y - βˆ‡ f xβ€–Β² ≀ K Β· βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫` for all `x, y`. This is the conclusion of -the Baillon-Haddad theorem (`K`-smooth + convex ⟹ `K`-cocoercive); this file packages -only the predicate and the elementary direction `K`-cocoercive ⟹ `K`-Lipschitz gradient, -which is a pure Cauchy-Schwarz consequence and needs no convexity or smoothness input. --/ - -public section - -variable {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] [CompleteSpace F] - -open scoped Gradient RealInnerProductSpace - -/-- A function `f : F β†’ ℝ` on a Hilbert space is **`K`-cocoercive** if its gradient satisfies -`β€–βˆ‡ f y - βˆ‡ f xβ€–Β² ≀ K Β· βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫` for all `x, y`. Equivalent to the standard -`(1/K)Β·β€–Β·β€–Β² ≀ βŸͺΒ·,·⟫` form when `0 < K`, but well-defined and meaningful even at `K = 0` -(then forces `βˆ‡ f` constant). The conclusion of the Baillon-Haddad theorem. -/ -abbrev CocoerciveWith (K : NNReal) (f : F β†’ ℝ) : Prop := - βˆ€ x y : F, β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 ≀ ↑K * βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ - -/-- A `K`-cocoercive gradient is `K`-Lipschitz. (One direction of the Baillon-Haddad -characterisation; the reverse requires convexity.) -/ -theorem CocoerciveWith.lipschitzWith_gradient {K : NNReal} {f : F β†’ ℝ} - (h : CocoerciveWith K f) : LipschitzWith K (βˆ‡ f) := - lipschitzWith_iff_dist_le_mul.mpr fun x y => by - simp only [dist_eq_norm'] - nlinarith [h x y, mul_nonneg K.coe_nonneg (norm_nonneg (y - x)), - mul_le_mul_of_nonneg_left (real_inner_le_norm (βˆ‡ f y - βˆ‡ f x) (y - x)) K.coe_nonneg] diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index f91cb9ce3d39ab..9f177feed84fba 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -16,6 +16,10 @@ characterisation. For differentiable `f`, `fderiv ℝ f x (y - x) = βŸͺβˆ‡ f x, via Riesz representation (`inner_gradient_left`), and the descent inequality becomes `f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K/2 Β· β€–y - xβ€–Β²`. The descent lemma (converse direction) and the Baillon-Haddad equivalence with cocoercivity are deferred to follow-ups. + +This file also defines the **`CocoerciveWith K f`** predicate (the conclusion of the +Baillon-Haddad theorem) and the elementary direction `K`-cocoercive ⟹ `K`-Lipschitz +gradient. -/ public section @@ -46,3 +50,20 @@ theorem inner_gradient_sub_le (h : LipschitzSmoothWith K f) (x y : F) exact h.fderiv_sub_apply_le x y hfx hfy end LipschitzSmoothWith + +/-! ### Cocoercivity -/ + +/-- A function `f : F β†’ ℝ` on a Hilbert space is **`K`-cocoercive** if its gradient satisfies +`β€–βˆ‡ f y - βˆ‡ f xβ€–Β² ≀ K Β· βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫` for all `x, y`. Equivalent to the standard +`(1/K)Β·β€–Β·β€–Β² ≀ βŸͺΒ·,·⟫` form when `0 < K`, but well-defined and meaningful even at `K = 0` +(then forces `βˆ‡ f` constant). The conclusion of the Baillon-Haddad theorem. -/ +abbrev CocoerciveWith (K : NNReal) (f : F β†’ ℝ) : Prop := + βˆ€ x y : F, β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 ≀ ↑K * βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ + +/-- A `K`-cocoercive gradient is `K`-Lipschitz. (One direction of the Baillon-Haddad +characterisation; the reverse requires convexity.) -/ +theorem CocoerciveWith.lipschitzWith_gradient (h : CocoerciveWith K f) : LipschitzWith K (βˆ‡ f) := + lipschitzWith_iff_dist_le_mul.mpr fun x y => by + simp only [dist_eq_norm'] + nlinarith [h x y, mul_nonneg K.coe_nonneg (norm_nonneg (y - x)), + mul_le_mul_of_nonneg_left (real_inner_le_norm (βˆ‡ f y - βˆ‡ f x) (y - x)) K.coe_nonneg] From 49f4741e0421bd781b48544ff6543d368de88936 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Tue, 19 May 2026 14:15:21 +0200 Subject: [PATCH 18/40] chore(LipschitzSmooth): drop 'deferred to follow-up' from module docstrings --- Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean | 4 +--- Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index 0b3767c864e668..0e4dfecb12a736 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -13,9 +13,7 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate. For differentiable `f`, `lineDeriv ℝ f x v = fderiv ℝ f x v` pointwise, and the predicate is equivalent to -the corresponding descent inequality stated in `fderiv` form. The full descent lemma β€” -the converse direction `LipschitzWith K (fderiv ℝ f) β†’ LipschitzSmoothWith K f` β€” is -deferred to a follow-up. +the corresponding descent inequality stated in `fderiv` form. -/ public section diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 9f177feed84fba..d0ec87cc42d2e5 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -14,8 +14,7 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv On a Hilbert space `F`, the `LipschitzSmoothWith` predicate admits a gradient-form characterisation. For differentiable `f`, `fderiv ℝ f x (y - x) = βŸͺβˆ‡ f x, y - x⟫` via Riesz representation (`inner_gradient_left`), and the descent inequality becomes -`f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K/2 Β· β€–y - xβ€–Β²`. The descent lemma (converse direction) -and the Baillon-Haddad equivalence with cocoercivity are deferred to follow-ups. +`f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K/2 Β· β€–y - xβ€–Β²`. This file also defines the **`CocoerciveWith K f`** predicate (the conclusion of the Baillon-Haddad theorem) and the elementary direction `K`-cocoercive ⟹ `K`-Lipschitz From 3ff23930623599ce9eefce019094f77ea8c083ca Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 20 May 2026 00:11:42 +0200 Subject: [PATCH 19/40] refactor(LipschitzSmooth): switch to two-sided absolute-value predicate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change `LipschitzSmoothWith K f` from the one-sided descent inequality f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β² to the two-sided absolute-value form |f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) (dist x y)Β² matching the textbook definition of L-smoothness (Lipschitz gradient, class C^{1,1}) β€” orientation-agnostic, closed under f ↦ -f, and used in Nesterov (Lemma 1.2.3), Beck (Ch. 5), Bauschke-Combettes (Lemma 2.64), etc. The one-sided form admitted pathological cases like `-|x|` being 0-smooth, which the two-sided form excludes. API changes: - New primary extractor `lineDeriv_abs_le` (matching the def body). - New lower-bound `lineDeriv_descent_ge` and two-sided variance `lineDeriv_apply_sub_abs_le` extractors. - `LipschitzSmoothWith.hasLineDerivAt` and `lineDifferentiableAt`: the two-sided form unlocks line-differentiability everywhere, provable from the predicate's bound `|f(x + tv) - f x - tΒ·L| ≀ K/2 tΒ²β€–vβ€–Β² = o(t)`. - Existing extractors `lineDeriv_descent_le`, `lineDeriv_apply_sub_le`, `lineDeriv_sub_apply_le` retained (one-sided, derived from the abs). - Parallel additions in `FDeriv.lean`, `Deriv.lean`, `Gradient.lean`. - `CocoerciveWith` and `CocoerciveWith.lipschitzWith_gradient` unchanged. --- .../Calculus/LipschitzSmooth/Basic.lean | 73 +++++++++++++++---- .../Calculus/LipschitzSmooth/Deriv.lean | 20 +++-- .../Calculus/LipschitzSmooth/FDeriv.lean | 20 ++++- .../Calculus/LipschitzSmooth/Gradient.lean | 19 ++++- 4 files changed, 108 insertions(+), 24 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index e681029936231c..e9e684aba50b64 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -10,14 +10,18 @@ public import Mathlib.Analysis.Calculus.LineDeriv.Basic /-! # Lipschitz smoothness -A real-valued function `f` on a normed real vector space is **`K`-smooth** if it satisfies -the quadratic descent inequality +A real-valued function `f` on a normed real vector space is **`K`-smooth** if the +first-order Taylor remainder is bounded quadratically: -`f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β²` +`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) (dist x y)Β²` for all `x, y`. The predicate uses `lineDeriv` so as not to presuppose FrΓ©chet -differentiability; restatements in `fderiv`, 1D `deriv`, and Hilbert-space gradient -form live in the sibling files in this directory. +differentiability; equivalent characterisations in `fderiv`, 1D `deriv`, and +Hilbert-space gradient form live in the sibling files in this directory. + +This two-sided (absolute-value) form is orientation-agnostic (closed under +`f ↦ -f`) β€” matching the textbook notion of L-smoothness (Lipschitz gradient, +the class `C^{1,1}`) used in Nesterov, Beck, Bauschke-Combettes, etc. -/ public section @@ -25,34 +29,75 @@ public section variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] /-- A real-valued function `f` on a normed real vector space `F` is `K`-smooth -if it satisfies the quadratic descent inequality -`f y ≀ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)Β²` for all `x, y`. +if the first-order Taylor remainder is bounded quadratically: +`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) (dist x y)Β²` for all `x, y`. + +The predicate is two-sided (absolute value), so closed under `f ↦ -f` and +matching the textbook L-smoothness / `C^{1,1}` class. The `lineDeriv` form is +the weakest possible underlying derivative form β€” the predicate implies +line-differentiability everywhere (`LipschitzSmoothWith.hasLineDerivAt`), so +the `lineDeriv` value is always the actual line derivative. -The choice of `lineDeriv` here is an implementation detail: it is the weakest form -that makes the predicate well-defined for non-differentiable functions. Equivalent -characterisations in `fderiv`, `gradient`, and `deriv` form are provided in the -sibling files, predicated on the appropriate differentiability hypothesis. -/ +Equivalent characterisations in `fderiv`, `gradient`, and `deriv` form are +provided in the sibling files, predicated on `Differentiable` where useful. -/ def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) := - βˆ€ (x y : F), f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 + βˆ€ (x y : F), |f y - f x - lineDeriv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : F β†’ ℝ} : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := Iff.rfl + βˆ€ x y : F, |f y - f x - lineDeriv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := Iff.rfl namespace LipschitzSmoothWith variable {K : NNReal} {f : F β†’ ℝ} +/-- Primary extractor: the Taylor remainder is bounded in absolute value. -/ +theorem lineDeriv_abs_le (h : LipschitzSmoothWith K f) (x y : F) : + |f y - f x - lineDeriv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := h x y + +/-- Descent inequality (upper-bound extractor). -/ theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : - f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := h x y + f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by + have := (abs_le.mp (h.lineDeriv_abs_le x y)).2 + linarith + +/-- Ascent inequality (lower-bound extractor). -/ +theorem lineDeriv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) : + f x + lineDeriv ℝ f x (y - x) - ↑K / 2 * (dist x y) ^ 2 ≀ f y := by + have := (abs_le.mp (h.lineDeriv_abs_le x y)).1 + linarith +/-- One-sided variance bound on the line derivative. -/ theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by have hyx := h.lineDeriv_descent_le y x rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx linarith [h.lineDeriv_descent_le x y, hyx] +/-- Two-sided variance bound on the line derivative. -/ +theorem lineDeriv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) : + |lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)| ≀ ↑K * (dist x y) ^ 2 := by + rw [abs_le] + refine ⟨?_, h.lineDeriv_apply_sub_le x y⟩ + have hyx := h.lineDeriv_descent_ge y x + rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx + linarith [h.lineDeriv_descent_ge x y] + +/-- Functional-form variance bound. -/ theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y +/-- `K`-smoothness implies line-differentiability: the actual line derivative +exists at every `x, v` and equals `lineDeriv ℝ f x v`. Proof: the predicate +bound `|f(x + tv) - f x - t Β· L| ≀ K/2 Β· tΒ² β€–vβ€–Β²` (via `lineDeriv_smul` to +factor `t`) is `o(t)`. -/ +theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : F) : + HasLineDerivAt ℝ f (lineDeriv ℝ f x v) x v := + sorry + +/-- A `K`-smooth function is line-differentiable everywhere. -/ +theorem lineDifferentiableAt (h : LipschitzSmoothWith K f) (x v : F) : + LineDifferentiableAt ℝ f x v := + (h.hasLineDerivAt x v).lineDifferentiableAt + end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index c878a8bb76ae8c..13b1af70b2a0d5 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -11,11 +11,11 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv /-! # Lipschitz smoothness in 1D via the derivative -For a `K`-smooth function `f : ℝ β†’ ℝ`, the descent inequality and the variation bound -take their classical 1D forms +For a `K`-smooth function `f : ℝ β†’ ℝ`, the Taylor bound and the variation bound take +their classical 1D forms: -`f y ≀ f x + deriv f x * (y - x) + K/2 * (y - x)Β²`, -`(deriv f y - deriv f x) * (y - x) ≀ K * (y - x)Β²`. +`|f y - f x - deriv f x Β· (y - x)| ≀ K/2 Β· (y - x)Β²`, +`(deriv f y - deriv f x) Β· (y - x) ≀ K Β· (y - x)Β²`. These are 1D restatements of the FrΓ©chet-derivative forms in `Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv`, lifted via `fderiv_eq_deriv_mul`. @@ -26,18 +26,28 @@ public section variable {K : NNReal} {f : ℝ β†’ ℝ} theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : ℝ, f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by + βˆ€ x y : ℝ, |f y - f x - deriv f x * (y - x)| ≀ ↑K / 2 * (y - x) ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] namespace LipschitzSmoothWith +theorem deriv_abs_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : + |f y - f x - deriv f x * (y - x)| ≀ ↑K / 2 * (y - x) ^ 2 := by + have := h.fderiv_abs_le x y hf + rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this + theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by have := h.fderiv_descent_le x y hf rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this +theorem deriv_descent_ge (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : + f x + deriv f x * (y - x) - ↑K / 2 * (y - x) ^ 2 ≀ f y := by + have := h.fderiv_descent_ge x y hf + rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this + theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (deriv f y - deriv f x) * (y - x) ≀ ↑K * (y - x) ^ 2 := by diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index 0e4dfecb12a736..6d62ed8eef6282 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -13,7 +13,7 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate. For differentiable `f`, `lineDeriv ℝ f x v = fderiv ℝ f x v` pointwise, and the predicate is equivalent to -the corresponding descent inequality stated in `fderiv` form. +the two-sided Taylor bound stated in `fderiv` form. -/ public section @@ -22,24 +22,40 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] variable {K : NNReal} {f : F β†’ ℝ} theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by + βˆ€ x y : F, |f y - f x - fderiv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := by rw [lipschitzSmoothWith_iff_lineDeriv] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [(hf x).lineDeriv_eq_fderiv] namespace LipschitzSmoothWith +theorem fderiv_abs_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : + |f y - f x - fderiv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := by + rw [← hf.lineDeriv_eq_fderiv] + exact h.lineDeriv_abs_le x y + theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_descent_le x y +theorem fderiv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : + f x + fderiv ℝ f x (y - x) - ↑K / 2 * (dist x y) ^ 2 ≀ f y := by + rw [← hf.lineDeriv_eq_fderiv] + exact h.lineDeriv_descent_ge x y + theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] exact h.lineDeriv_apply_sub_le x y +theorem fderiv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : + |fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x)| ≀ ↑K * (dist x y) ^ 2 := by + rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] + exact h.lineDeriv_apply_sub_abs_le x y + theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := by diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index d0ec87cc42d2e5..4498bcf58bbcca 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -13,8 +13,8 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv On a Hilbert space `F`, the `LipschitzSmoothWith` predicate admits a gradient-form characterisation. For differentiable `f`, `fderiv ℝ f x (y - x) = βŸͺβˆ‡ f x, y - x⟫` -via Riesz representation (`inner_gradient_left`), and the descent inequality becomes -`f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K/2 Β· β€–y - xβ€–Β²`. +via Riesz representation (`inner_gradient_left`), and the two-sided Taylor bound becomes +`|f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ K/2 Β· β€–y - xβ€–Β²`. This file also defines the **`CocoerciveWith K f`** predicate (the conclusion of the Baillon-Haddad theorem) and the elementary direction `K`-cocoercive ⟹ `K`-Lipschitz @@ -29,19 +29,32 @@ variable {K : NNReal} {f : F β†’ ℝ} open scoped Gradient RealInnerProductSpace theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : - LipschitzSmoothWith K f ↔ βˆ€ x y : F, f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by + LipschitzSmoothWith K f ↔ + βˆ€ x y : F, |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ ↑K / 2 * β€–y - xβ€– ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [inner_gradient_left, dist_eq_norm'] namespace LipschitzSmoothWith +theorem inner_gradient_abs_le (h : LipschitzSmoothWith K f) (x y : F) + (hf : DifferentiableAt ℝ f x) : + |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ ↑K / 2 * β€–y - xβ€– ^ 2 := by + rw [inner_gradient_left, ← dist_eq_norm'] + exact h.fderiv_abs_le x y hf + theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by rw [inner_gradient_left, ← dist_eq_norm'] exact h.fderiv_descent_le x y hf +theorem inner_gradient_descent_ge (h : LipschitzSmoothWith K f) (x y : F) + (hf : DifferentiableAt ℝ f x) : + f x + βŸͺβˆ‡ f x, y - x⟫ - ↑K / 2 * β€–y - xβ€– ^ 2 ≀ f y := by + rw [inner_gradient_left, ← dist_eq_norm'] + exact h.fderiv_descent_ge x y hf + theorem inner_gradient_sub_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ ↑K * β€–y - xβ€– ^ 2 := by From 6b44bc942b800d194bcf8749d62a58c22cf9e040 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 20 May 2026 00:34:37 +0200 Subject: [PATCH 20/40] feat(LipschitzSmooth): prove hasLineDerivAt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fill in `LipschitzSmoothWith.hasLineDerivAt`: a `K`-smooth function is line-differentiable everywhere, and the `lineDeriv` value at every direction is the actual line derivative. The predicate bound |f(x + tΒ·v) - f x - t Β· lineDeriv f x v| ≀ K/2 Β· tΒ² Β· β€–vβ€–Β² (obtained by applying the abs-bound at `(x, x + t β€’ v)` and factoring `t` via `lineDeriv_smul`) is `o(t)`, which is the `IsLittleO` form of `HasDerivAt` at `0` for the 1D restriction. The `continuous` field remains `sorry` pending a separate argument. --- .../Calculus/LipschitzSmooth/Basic.lean | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index e9e684aba50b64..0505540d93c878 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -88,12 +88,28 @@ theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y /-- `K`-smoothness implies line-differentiability: the actual line derivative -exists at every `x, v` and equals `lineDeriv ℝ f x v`. Proof: the predicate -bound `|f(x + tv) - f x - t Β· L| ≀ K/2 Β· tΒ² β€–vβ€–Β²` (via `lineDeriv_smul` to -factor `t`) is `o(t)`. -/ +exists at every `x, v` and equals `lineDeriv ℝ f x v`. The predicate bound +`|f(x + tv) - f x - t Β· L| ≀ K/2 Β· tΒ² β€–vβ€–Β²` (via `lineDeriv_smul` to factor `t`) +is `o(t)`. -/ theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : F) : - HasLineDerivAt ℝ f (lineDeriv ℝ f x v) x v := - sorry + HasLineDerivAt ℝ f (lineDeriv ℝ f x v) x v := by + set L := lineDeriv ℝ f x v + change HasDerivAt (fun t : ℝ => f (x + t β€’ v)) L 0 + rw [hasDerivAt_iff_isLittleO_nhds_zero, Asymptotics.isLittleO_iff] + intro Ξ΅ hΞ΅ + have hsum_pos : (0:ℝ) < ↑K * β€–vβ€–^2 / 2 + 1 := by positivity + filter_upwards [Metric.ball_mem_nhds (0 : ℝ) (div_pos hΞ΅ hsum_pos)] with t ht + simp only [Metric.mem_ball, Real.dist_eq, sub_zero] at ht + simp only [zero_add, zero_smul, add_zero, smul_eq_mul, Real.norm_eq_abs] + have hpred := h x (x + t β€’ v) + rw [show (x + t β€’ v) - x = t β€’ v from by abel, lineDeriv_smul, smul_eq_mul, + dist_self_add_right, norm_smul, Real.norm_eq_abs, mul_pow, sq_abs] at hpred + refine hpred.trans ?_ + have ht' : |t| * (↑K * β€–vβ€–^2 / 2 + 1) < Ξ΅ := (lt_div_iffβ‚€ hsum_pos).mp ht + have ht'' : ↑K * β€–vβ€–^2 / 2 * |t| ≀ Ξ΅ := by nlinarith [abs_nonneg t] + calc ↑K / 2 * (t ^ 2 * β€–vβ€– ^ 2) + = ↑K * β€–vβ€–^2 / 2 * |t| * |t| := by rw [← sq_abs t]; ring + _ ≀ Ξ΅ * |t| := mul_le_mul_of_nonneg_right ht'' (abs_nonneg t) /-- A `K`-smooth function is line-differentiable everywhere. -/ theorem lineDifferentiableAt (h : LipschitzSmoothWith K f) (x v : F) : From b594c2c98295ff2681c841461dfab955072f2705 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 25 May 2026 09:04:42 +0200 Subject: [PATCH 21/40] review: address EtienneC30 feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rename lineMap_contDiff{,_uncurry} β†’ contDiff_lineMap{,_uncurry} - trim module docstring to first declaration - demote new Poincare import to non-public - inline `refine .congr ?_ this; fun_prop` as `exact .congr (by fun_prop) this` --- Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean | 9 ++++----- .../MeasureTheory/Integral/CurveIntegral/Poincare.lean | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean b/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean index 67f99929fed34c..de7602ee46e29c 100644 --- a/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean +++ b/Mathlib/Analysis/Calculus/AddTorsor/AffineMap.lean @@ -17,9 +17,8 @@ This file contains results about smoothness of affine maps. ## Main results * `ContinuousAffineMap.contDiff`: a continuous affine map is smooth. -* `AffineMap.lineMap_contDiff_uncurry`, `AffineMap.lineMap_contDiff`, - `ContDiff.lineMap` and variants: `AffineMap.lineMap` is smooth in its three - arguments, jointly and pointwise. +* `AffineMap.contDiff_lineMap_uncurry`: `AffineMap.lineMap` is smooth in its three arguments, + jointly and pointwise. -/ @@ -45,13 +44,13 @@ variable [NormedAddCommGroup V] [NormedSpace π•œ V] /-- `AffineMap.lineMap` is smooth in all three arguments. -/ @[fun_prop] -theorem lineMap_contDiff_uncurry {n : WithTop β„•βˆž} : +theorem contDiff_lineMap_uncurry {n : WithTop β„•βˆž} : ContDiff π•œ n (fun pqc : V Γ— V Γ— π•œ ↦ AffineMap.lineMap pqc.1 pqc.2.1 pqc.2.2) := by simp only [AffineMap.lineMap_apply_module] fun_prop /-- `AffineMap.lineMap` is smooth as a function `π•œ β†’ V`. -/ -theorem lineMap_contDiff (pβ‚€ p₁ : V) {n : WithTop β„•βˆž} : +theorem contDiff_lineMap (pβ‚€ p₁ : V) {n : WithTop β„•βˆž} : ContDiff π•œ n (AffineMap.lineMap pβ‚€ p₁ : π•œ β†’ V) := by fun_prop diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean index b2b2829f3c7f1d..805d18dd5acade 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Poincare.lean @@ -5,7 +5,6 @@ Authors: Yury Kudryashov -/ module -public import Mathlib.Analysis.Calculus.AddTorsor.AffineMap public import Mathlib.Analysis.Calculus.Deriv.Prod public import Mathlib.Analysis.Calculus.DiffContOnCl public import Mathlib.Analysis.Calculus.FDeriv.Symmetric @@ -14,6 +13,8 @@ public import Mathlib.MeasureTheory.Integral.CurveIntegral.Basic public import Mathlib.MeasureTheory.Integral.DivergenceTheorem public import Mathlib.Topology.Homotopy.Affine +import Mathlib.Analysis.Calculus.AddTorsor.AffineMap + /-! # PoincarΓ© lemma for 1-forms @@ -330,8 +331,7 @@ theorem curveIntegral_segment_add_eq_of_hasFDerivWithinAt_symmetric (hs : Convex lift x to I using hx lift y to I using hy simp [Ο†] - refine .congr ?_ this - fun_prop + exact .congr (by fun_prop) this variable [CompleteSpace F] From ac72ebbc0966efbbf93291aad57782fd405ec008 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 11 May 2026 15:20:35 +0200 Subject: [PATCH 22/40] feat(CurveIntegral): segment-level lemmas and FTC along a line segment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Splits the existing `PathOperations` section into a dedicated `Segment` section with `[NormedSpace ℝ E]` hoisted to the variable block, and adds: - `curveIntegrable_segment_const` - `ContinuousOn.curveIntegrable_of_contDiffOn` - `Path.segment_contDiffOn` - `ContinuousOn.curveIntegrable_segment`, `Continuous.curveIntegrable_segment` - `curveIntegral_fderiv_segment` β€” FTC along a line segment `curveIntegrable_segment` is renamed to `curveIntegrable_segment_iff` (deprecated alias retained). --- .../Integral/CurveIntegral/Basic.lean | 84 ++++++++++++++----- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index 75b8d7e351cd73..2315488e3368e8 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -6,11 +6,12 @@ Authors: Yury Kudryashov module public import Mathlib.Algebra.Order.Field.Pointwise +public import Mathlib.Analysis.Calculus.AddTorsor.AffineMap public import Mathlib.Analysis.Calculus.ContDiff.Deriv public import Mathlib.Analysis.Calculus.Deriv.AffineMap public import Mathlib.Analysis.Calculus.Deriv.Shift public import Mathlib.Analysis.Normed.Module.Convex -public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.FundThmCalculus /-! # Integral of a 1-form along a path @@ -287,20 +288,59 @@ theorem curveIntegral_trans (h₁ : CurveIntegrable Ο‰ Ξ³ab) (hβ‚‚ : CurveIntegr simp only [curveIntegral_def] norm_num -theorem curveIntegralFun_segment [NormedSpace ℝ E] (Ο‰ : E β†’ E β†’L[π•œ] F) (a b : E) - {t : ℝ} (ht : t ∈ I) : curveIntegralFun Ο‰ (.segment a b) t = Ο‰ (lineMap a b t) (b - a) := by +end PathOperations + +section Segment + +variable {π•œ E F : Type*} [RCLike π•œ] [NormedAddCommGroup E] [NormedSpace π•œ E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace π•œ F] {a b c d : E} {Ο‰ : E β†’ E β†’L[π•œ] F} + {Ξ³ Ξ³ab : Path a b} {Ξ³bc : Path b c} {t : ℝ} + +theorem curveIntegralFun_segment (Ο‰ : E β†’ E β†’L[π•œ] F) (a b : E) {t : ℝ} (ht : t ∈ I) : + curveIntegralFun Ο‰ (.segment a b) t = Ο‰ (lineMap a b t) (b - a) := by have := Path.eqOn_extend_segment a b simp only [curveIntegralFun_def, this ht, derivWithin_congr this (this ht), (hasDerivWithinAt_lineMap ..).derivWithin (uniqueDiffOn_Icc_zero_one t ht)] -theorem curveIntegrable_segment [NormedSpace ℝ E] : - CurveIntegrable Ο‰ (.segment a b) ↔ +theorem curveIntegrable_segment_iff : CurveIntegrable Ο‰ (.segment a b) ↔ IntervalIntegrable (fun t ↦ Ο‰ (lineMap a b t) (b - a)) volume 0 1 := by rw [CurveIntegrable, intervalIntegrable_congr] rw [uIoc_of_le zero_le_one] exact .mono Ioc_subset_Icc_self fun _t ↦ curveIntegralFun_segment Ο‰ a b -theorem curveIntegral_segment [NormedSpace ℝ E] [NormedSpace ℝ F] (Ο‰ : E β†’ E β†’L[π•œ] F) (a b : E) : +@[deprecated (since := "2026-05-11")] alias curveIntegrable_segment := curveIntegrable_segment_iff + +@[simp] theorem curveIntegrable_segment_const (Ο‰ : E β†’L[π•œ] F) (a b : E) : + CurveIntegrable (fun _ : E => Ο‰) (.segment a b) := + curveIntegrable_segment_iff.mpr intervalIntegrable_const + +/-- If a 1-form `Ο‰` is continuous on a set `s`, +then it is curve integrable along any $C^1$ path in this set. -/ +theorem ContinuousOn.curveIntegrable_of_contDiffOn {s : Set E} (hΟ‰ : ContinuousOn Ο‰ s) + (hΞ³ : ContDiffOn ℝ 1 Ξ³.extend I) (hΞ³s : βˆ€ t, Ξ³ t ∈ s) : CurveIntegrable Ο‰ Ξ³ := by + apply ContinuousOn.intervalIntegrable_of_Icc zero_le_one + simp only [funext (curveIntegralFun_def Ο‰ Ξ³)] + apply ContinuousOn.clm_apply + Β· exact hΟ‰.comp (by fun_prop) fun _ _ ↦ hΞ³s _ + Β· exact hΞ³.continuousOn_derivWithin uniqueDiffOn_Icc_zero_one le_rfl + +/-- The straight-line path `Path.segment a b` is `CΒΉ` (in fact smooth) on the unit interval. -/ +theorem Path.segment_contDiffOn (a b : E) : + ContDiffOn ℝ 1 (Path.segment a b).extend I := + (AffineMap.lineMap_contDiff a b).contDiffOn.congr (Path.eqOn_extend_segment a b) + +/-- If a 1-form `Ο‰` is continuous on the segment `[a -[ℝ] b]`, +then it is curve integrable along the segment from `a` to `b`. -/ +theorem ContinuousOn.curveIntegrable_segment (hΟ‰ : ContinuousOn Ο‰ [a -[ℝ] b]) : + CurveIntegrable Ο‰ (.segment a b) := + hΟ‰.curveIntegrable_of_contDiffOn (Path.segment_contDiffOn a b) + fun t => Path.range_segment a b β–Έ Set.mem_range_self t + +/-- If a 1-form `Ο‰` is continuous, then it is curve integrable along any segment. -/ +theorem Continuous.curveIntegrable_segment (hΟ‰ : Continuous Ο‰) (a b : E) : + CurveIntegrable Ο‰ (.segment a b) := hΟ‰.continuousOn.curveIntegrable_segment + +theorem curveIntegral_segment [NormedSpace ℝ F] (Ο‰ : E β†’ E β†’L[π•œ] F) (a b : E) : ∫ᢜ x in .segment a b, Ο‰ x = ∫ t in 0..1, Ο‰ (lineMap a b t) (b - a) := by rw [curveIntegral_def] refine intervalIntegral.integral_congr fun t ht ↦ ?_ @@ -308,14 +348,14 @@ theorem curveIntegral_segment [NormedSpace ℝ E] [NormedSpace ℝ F] (Ο‰ : E exact curveIntegralFun_segment Ο‰ a b ht @[simp] -theorem curveIntegral_segment_const [NormedSpace ℝ E] [CompleteSpace F] (Ο‰ : E β†’L[π•œ] F) (a b : E) : +theorem curveIntegral_segment_const [CompleteSpace F] (Ο‰ : E β†’L[π•œ] F) (a b : E) : ∫ᢜ _ in .segment a b, Ο‰ = Ο‰ (b - a) := by letI : NormedSpace ℝ F := .restrictScalars ℝ π•œ F simp [curveIntegral_segment] /-- If `β€–Ο‰ zβ€– ≀ C` at all points of the segment `[a -[ℝ] b]`, then the curve integral `∫ᢜ x in .segment a b, Ο‰ x` has norm at most `C * β€–b - aβ€–`. -/ -theorem norm_curveIntegral_segment_le [NormedSpace ℝ E] {C : ℝ} (h : βˆ€ z ∈ [a -[ℝ] b], β€–Ο‰ zβ€– ≀ C) : +theorem norm_curveIntegral_segment_le {C : ℝ} (h : βˆ€ z ∈ [a -[ℝ] b], β€–Ο‰ zβ€– ≀ C) : β€–βˆ«αΆœ x in .segment a b, Ο‰ xβ€– ≀ C * β€–b - aβ€– := calc β€–βˆ«αΆœ x in .segment a b, Ο‰ xβ€– ≀ C * β€–b - aβ€– * |1 - 0| := by letI : NormedSpace ℝ F := .restrictScalars ℝ π•œ F @@ -326,18 +366,7 @@ theorem norm_curveIntegral_segment_le [NormedSpace ℝ E] {C : ℝ} (h : βˆ€ z apply_rules [(Ο‰ _).le_of_opNorm_le, mem_image_of_mem, Ioc_subset_Icc_self] _ = C * β€–b - aβ€– := by simp -/-- If a 1-form `Ο‰` is continuous on a set `s`, -then it is curve integrable along any $C^1$ path in this set. -/ -theorem ContinuousOn.curveIntegrable_of_contDiffOn [NormedSpace ℝ E] {s : Set E} - (hΟ‰ : ContinuousOn Ο‰ s) (hΞ³ : ContDiffOn ℝ 1 Ξ³.extend I) (hΞ³s : βˆ€ t, Ξ³ t ∈ s) : - CurveIntegrable Ο‰ Ξ³ := by - apply ContinuousOn.intervalIntegrable_of_Icc zero_le_one - simp only [funext (curveIntegralFun_def Ο‰ Ξ³)] - apply ContinuousOn.clm_apply - Β· exact hΟ‰.comp (by fun_prop) fun _ _ ↦ hΞ³s _ - Β· exact hΞ³.continuousOn_derivWithin uniqueDiffOn_Icc_zero_one le_rfl - -end PathOperations +end Segment /-! ### Algebraic operations on the 1-form @@ -529,13 +558,13 @@ theorem HasFDerivWithinAt.curveIntegral_segment_source' (hs : Convex ℝ s) rw [← curveIntegral_segment_const, ← curveIntegral_fun_sub] Β· refine norm_curveIntegral_segment_le fun z hz ↦ ?_ simpa [dist_eq_norm] using (hΞ΄ (hsub hz)).2 - Β· rw [curveIntegrable_segment] + Β· rw [curveIntegrable_segment_iff] refine ContinuousOn.intervalIntegrable_of_Icc zero_le_one fun t ht ↦ ?_ refine ((hΞ΄ ?_).1.eval_const _).comp AffineMap.lineMap_continuous.continuousWithinAt ?_ Β· refine hsub <| segment_eq_image_lineMap ℝ a b β–Έ mem_image_of_mem _ ht Β· rw [mapsTo_iff_image_subset, ← segment_eq_image_lineMap] exact hs.segment_subset ha hbs - Β· rw [curveIntegrable_segment] + Β· rw [curveIntegrable_segment_iff] exact intervalIntegrable_const /-- The integral of `Ο‰` along `[a -[ℝ] b]`, as a function of `b`, has derivative `Ο‰ a` at `b = a`. @@ -557,4 +586,15 @@ theorem HasFDerivAt.curveIntegral_segment_source (hΟ‰ : Continuous Ο‰) : HasFDerivAt (∫ᢜ x in .segment a Β·, Ο‰ x) (Ο‰ a) a := .curveIntegral_segment_source' <| .of_forall fun _ ↦ hΟ‰.continuousAt +/-- **Fundamental theorem of calculus along a line segment.** If `f : E β†’ F` is differentiable +with continuous derivative `fderiv ℝ f` on the segment `[a -[ℝ] b]`, then the curve integral of +`fderiv ℝ f` along the segment equals `f b - f a`. -/ +theorem curveIntegral_fderiv_segment [NormedSpace ℝ F] {f : E β†’ F} + (hf : Differentiable ℝ f) (hcont : Continuous (fderiv ℝ f)) (a b : E) : + ∫ᢜ z in .segment a b, fderiv ℝ f z = f b - f a := by + rw [curveIntegral_segment] + simpa using intervalIntegral.integral_eq_sub_of_hasDerivAt + (fun t _ => (hf _).hasFDerivAt.comp_hasDerivAt t AffineMap.hasDerivAt_lineMap) + (((hcont.comp (by fun_prop)).clm_apply continuous_const).intervalIntegrable 0 1) + end FDeriv From 613b043633c56dfbaea619f84e53097bb2209c31 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 09:17:17 +0200 Subject: [PATCH 23/40] refactor(CurveIntegral): apply review feedback - Drop rename of `curveIntegrable_segment`: `curveIntegrable_segment_const` takes a different name slot, so deprecation is unnecessary - Restrict `curveIntegral_fderiv_segment` hypotheses to the segment (`DifferentiableAt` on the segment + `ContinuousOn` of the derivative) - Move `curveIntegral_fderiv_segment` from FDeriv section into Segment section, where the headline segment-FTC result belongs thematically - Make `a b` implicit in `Continuous.curveIntegrable_segment` for parity with the `ContinuousOn` variant - Keep `ContinuousOn.curveIntegrable_of_contDiffOn` at end of Segment section to reduce diff churn (it pre-existed in that position) - Drop docstrings that restate the type signature in English - Tag `Path.segment_contDiffOn` with `@[fun_prop]` --- .../Integral/CurveIntegral/Basic.lean | 84 +++++++++---------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index 2315488e3368e8..c71bc1545b6934 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -302,43 +302,15 @@ theorem curveIntegralFun_segment (Ο‰ : E β†’ E β†’L[π•œ] F) (a b : E) {t : ℝ} simp only [curveIntegralFun_def, this ht, derivWithin_congr this (this ht), (hasDerivWithinAt_lineMap ..).derivWithin (uniqueDiffOn_Icc_zero_one t ht)] -theorem curveIntegrable_segment_iff : CurveIntegrable Ο‰ (.segment a b) ↔ +theorem curveIntegrable_segment : CurveIntegrable Ο‰ (.segment a b) ↔ IntervalIntegrable (fun t ↦ Ο‰ (lineMap a b t) (b - a)) volume 0 1 := by rw [CurveIntegrable, intervalIntegrable_congr] rw [uIoc_of_le zero_le_one] exact .mono Ioc_subset_Icc_self fun _t ↦ curveIntegralFun_segment Ο‰ a b -@[deprecated (since := "2026-05-11")] alias curveIntegrable_segment := curveIntegrable_segment_iff - @[simp] theorem curveIntegrable_segment_const (Ο‰ : E β†’L[π•œ] F) (a b : E) : - CurveIntegrable (fun _ : E => Ο‰) (.segment a b) := - curveIntegrable_segment_iff.mpr intervalIntegrable_const - -/-- If a 1-form `Ο‰` is continuous on a set `s`, -then it is curve integrable along any $C^1$ path in this set. -/ -theorem ContinuousOn.curveIntegrable_of_contDiffOn {s : Set E} (hΟ‰ : ContinuousOn Ο‰ s) - (hΞ³ : ContDiffOn ℝ 1 Ξ³.extend I) (hΞ³s : βˆ€ t, Ξ³ t ∈ s) : CurveIntegrable Ο‰ Ξ³ := by - apply ContinuousOn.intervalIntegrable_of_Icc zero_le_one - simp only [funext (curveIntegralFun_def Ο‰ Ξ³)] - apply ContinuousOn.clm_apply - Β· exact hΟ‰.comp (by fun_prop) fun _ _ ↦ hΞ³s _ - Β· exact hΞ³.continuousOn_derivWithin uniqueDiffOn_Icc_zero_one le_rfl - -/-- The straight-line path `Path.segment a b` is `CΒΉ` (in fact smooth) on the unit interval. -/ -theorem Path.segment_contDiffOn (a b : E) : - ContDiffOn ℝ 1 (Path.segment a b).extend I := - (AffineMap.lineMap_contDiff a b).contDiffOn.congr (Path.eqOn_extend_segment a b) - -/-- If a 1-form `Ο‰` is continuous on the segment `[a -[ℝ] b]`, -then it is curve integrable along the segment from `a` to `b`. -/ -theorem ContinuousOn.curveIntegrable_segment (hΟ‰ : ContinuousOn Ο‰ [a -[ℝ] b]) : - CurveIntegrable Ο‰ (.segment a b) := - hΟ‰.curveIntegrable_of_contDiffOn (Path.segment_contDiffOn a b) - fun t => Path.range_segment a b β–Έ Set.mem_range_self t - -/-- If a 1-form `Ο‰` is continuous, then it is curve integrable along any segment. -/ -theorem Continuous.curveIntegrable_segment (hΟ‰ : Continuous Ο‰) (a b : E) : - CurveIntegrable Ο‰ (.segment a b) := hΟ‰.continuousOn.curveIntegrable_segment + CurveIntegrable (fun _ : E ↦ Ο‰) (.segment a b) := + curveIntegrable_segment.mpr intervalIntegrable_const theorem curveIntegral_segment [NormedSpace ℝ F] (Ο‰ : E β†’ E β†’L[π•œ] F) (a b : E) : ∫ᢜ x in .segment a b, Ο‰ x = ∫ t in 0..1, Ο‰ (lineMap a b t) (b - a) := by @@ -366,6 +338,41 @@ theorem norm_curveIntegral_segment_le {C : ℝ} (h : βˆ€ z ∈ [a -[ℝ] b], β€– apply_rules [(Ο‰ _).le_of_opNorm_le, mem_image_of_mem, Ioc_subset_Icc_self] _ = C * β€–b - aβ€– := by simp +theorem ContinuousOn.curveIntegrable_of_contDiffOn {s : Set E} (hΟ‰ : ContinuousOn Ο‰ s) + (hΞ³ : ContDiffOn ℝ 1 Ξ³.extend I) (hΞ³s : βˆ€ t, Ξ³ t ∈ s) : CurveIntegrable Ο‰ Ξ³ := by + apply ContinuousOn.intervalIntegrable_of_Icc zero_le_one + simp only [funext (curveIntegralFun_def Ο‰ Ξ³)] + apply ContinuousOn.clm_apply + Β· exact hΟ‰.comp (by fun_prop) fun _ _ ↦ hΞ³s _ + Β· exact hΞ³.continuousOn_derivWithin uniqueDiffOn_Icc_zero_one le_rfl + +@[fun_prop] +theorem Path.segment_contDiffOn (a b : E) : + ContDiffOn ℝ 1 (Path.segment a b).extend I := + (AffineMap.lineMap_contDiff a b).contDiffOn.congr (Path.eqOn_extend_segment a b) + +theorem ContinuousOn.curveIntegrable_segment (hΟ‰ : ContinuousOn Ο‰ [a -[ℝ] b]) : + CurveIntegrable Ο‰ (.segment a b) := + hΟ‰.curveIntegrable_of_contDiffOn (Path.segment_contDiffOn a b) + fun t ↦ Path.range_segment a b β–Έ Set.mem_range_self t + +theorem Continuous.curveIntegrable_segment (hΟ‰ : Continuous Ο‰) : + CurveIntegrable Ο‰ (.segment a b) := hΟ‰.continuousOn.curveIntegrable_segment + +/-- **Fundamental theorem of calculus along a line segment.** If `f : E β†’ F` is differentiable +on `[a -[ℝ] b]` and its derivative is continuous on the segment, then the curve integral of +`fderiv ℝ f` along the segment equals `f b - f a`. -/ +theorem curveIntegral_fderiv_segment [NormedSpace ℝ F] [CompleteSpace F] {f : E β†’ F} + (hf : βˆ€ z ∈ [a -[ℝ] b], DifferentiableAt ℝ f z) + (hcont : ContinuousOn (fderiv ℝ f) [a -[ℝ] b]) : + ∫ᢜ z in .segment a b, fderiv ℝ f z = f b - f a := by + rw [curveIntegral_segment] + simpa using intervalIntegral.integral_eq_sub_of_hasDerivAt + (fun t ht ↦ (hf _ (segment_eq_image_lineMap ℝ a b β–Έ mem_image_of_mem _ + (uIcc_of_le (zero_le_one : (0 : ℝ) ≀ 1) β–Έ ht))).hasFDerivAt + |>.comp_hasDerivAt t AffineMap.hasDerivAt_lineMap) + (curveIntegrable_segment.mp hcont.curveIntegrable_segment) + end Segment /-! @@ -558,13 +565,13 @@ theorem HasFDerivWithinAt.curveIntegral_segment_source' (hs : Convex ℝ s) rw [← curveIntegral_segment_const, ← curveIntegral_fun_sub] Β· refine norm_curveIntegral_segment_le fun z hz ↦ ?_ simpa [dist_eq_norm] using (hΞ΄ (hsub hz)).2 - Β· rw [curveIntegrable_segment_iff] + Β· rw [curveIntegrable_segment] refine ContinuousOn.intervalIntegrable_of_Icc zero_le_one fun t ht ↦ ?_ refine ((hΞ΄ ?_).1.eval_const _).comp AffineMap.lineMap_continuous.continuousWithinAt ?_ Β· refine hsub <| segment_eq_image_lineMap ℝ a b β–Έ mem_image_of_mem _ ht Β· rw [mapsTo_iff_image_subset, ← segment_eq_image_lineMap] exact hs.segment_subset ha hbs - Β· rw [curveIntegrable_segment_iff] + Β· rw [curveIntegrable_segment] exact intervalIntegrable_const /-- The integral of `Ο‰` along `[a -[ℝ] b]`, as a function of `b`, has derivative `Ο‰ a` at `b = a`. @@ -586,15 +593,4 @@ theorem HasFDerivAt.curveIntegral_segment_source (hΟ‰ : Continuous Ο‰) : HasFDerivAt (∫ᢜ x in .segment a Β·, Ο‰ x) (Ο‰ a) a := .curveIntegral_segment_source' <| .of_forall fun _ ↦ hΟ‰.continuousAt -/-- **Fundamental theorem of calculus along a line segment.** If `f : E β†’ F` is differentiable -with continuous derivative `fderiv ℝ f` on the segment `[a -[ℝ] b]`, then the curve integral of -`fderiv ℝ f` along the segment equals `f b - f a`. -/ -theorem curveIntegral_fderiv_segment [NormedSpace ℝ F] {f : E β†’ F} - (hf : Differentiable ℝ f) (hcont : Continuous (fderiv ℝ f)) (a b : E) : - ∫ᢜ z in .segment a b, fderiv ℝ f z = f b - f a := by - rw [curveIntegral_segment] - simpa using intervalIntegral.integral_eq_sub_of_hasDerivAt - (fun t _ => (hf _).hasFDerivAt.comp_hasDerivAt t AffineMap.hasDerivAt_lineMap) - (((hcont.comp (by fun_prop)).clm_apply continuous_const).intervalIntegrable 0 1) - end FDeriv From 4615cf7e25e41bf3d3cd55a4e1acb5ff7339d1a1 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 25 May 2026 09:07:33 +0200 Subject: [PATCH 24/40] review: rename to AffineMap.contDiff_lineMap --- Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index c71bc1545b6934..a2e53d2edc7c4a 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -349,7 +349,7 @@ theorem ContinuousOn.curveIntegrable_of_contDiffOn {s : Set E} (hΟ‰ : Continuous @[fun_prop] theorem Path.segment_contDiffOn (a b : E) : ContDiffOn ℝ 1 (Path.segment a b).extend I := - (AffineMap.lineMap_contDiff a b).contDiffOn.congr (Path.eqOn_extend_segment a b) + (AffineMap.contDiff_lineMap a b).contDiffOn.congr (Path.eqOn_extend_segment a b) theorem ContinuousOn.curveIntegrable_segment (hΟ‰ : ContinuousOn Ο‰ [a -[ℝ] b]) : CurveIntegrable Ο‰ (.segment a b) := From 77c92d40ee29df0cdb811bbf33c6754f52bb01e6 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 25 May 2026 09:37:59 +0200 Subject: [PATCH 25/40] review: extend review feedback to this PR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - demote AddTorsor.AffineMap and IntervalIntegral.FundThmCalculus to non-public imports (used only in proof bodies); restore IntervalIntegral.Basic as public since it provides IntervalIntegrable - rename Path.segment_contDiffOn β†’ Path.contDiffOn_segment_extend per mathlib predicate-first naming convention (parallels the lineMap_contDiff β†’ contDiff_lineMap rename in #39206) --- .../MeasureTheory/Integral/CurveIntegral/Basic.lean | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean index a2e53d2edc7c4a..b405456ff145bb 100644 --- a/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean +++ b/Mathlib/MeasureTheory/Integral/CurveIntegral/Basic.lean @@ -6,12 +6,14 @@ Authors: Yury Kudryashov module public import Mathlib.Algebra.Order.Field.Pointwise -public import Mathlib.Analysis.Calculus.AddTorsor.AffineMap public import Mathlib.Analysis.Calculus.ContDiff.Deriv public import Mathlib.Analysis.Calculus.Deriv.AffineMap public import Mathlib.Analysis.Calculus.Deriv.Shift public import Mathlib.Analysis.Normed.Module.Convex -public import Mathlib.MeasureTheory.Integral.IntervalIntegral.FundThmCalculus +public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic + +import Mathlib.Analysis.Calculus.AddTorsor.AffineMap +import Mathlib.MeasureTheory.Integral.IntervalIntegral.FundThmCalculus /-! # Integral of a 1-form along a path @@ -347,13 +349,13 @@ theorem ContinuousOn.curveIntegrable_of_contDiffOn {s : Set E} (hΟ‰ : Continuous Β· exact hΞ³.continuousOn_derivWithin uniqueDiffOn_Icc_zero_one le_rfl @[fun_prop] -theorem Path.segment_contDiffOn (a b : E) : +theorem Path.contDiffOn_segment_extend (a b : E) : ContDiffOn ℝ 1 (Path.segment a b).extend I := (AffineMap.contDiff_lineMap a b).contDiffOn.congr (Path.eqOn_extend_segment a b) theorem ContinuousOn.curveIntegrable_segment (hΟ‰ : ContinuousOn Ο‰ [a -[ℝ] b]) : CurveIntegrable Ο‰ (.segment a b) := - hΟ‰.curveIntegrable_of_contDiffOn (Path.segment_contDiffOn a b) + hΟ‰.curveIntegrable_of_contDiffOn (Path.contDiffOn_segment_extend a b) fun t ↦ Path.range_segment a b β–Έ Set.mem_range_self t theorem Continuous.curveIntegrable_segment (hΟ‰ : Continuous Ο‰) : From 56342d2be8d99fdf8a7a203ff0403213abb5b6b4 Mon Sep 17 00:00:00 2001 From: FordUniver <61389961+FordUniver@users.noreply.github.com> Date: Wed, 8 Jul 2026 17:50:30 +0900 Subject: [PATCH 26/40] Update Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean Co-authored-by: Jireh Loreaux --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 0505540d93c878..719435e477335e 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -13,7 +13,7 @@ public import Mathlib.Analysis.Calculus.LineDeriv.Basic A real-valued function `f` on a normed real vector space is **`K`-smooth** if the first-order Taylor remainder is bounded quadratically: -`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) (dist x y)Β²` +`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) * (dist x y) ^ 2` for all `x, y`. The predicate uses `lineDeriv` so as not to presuppose FrΓ©chet differentiability; equivalent characterisations in `fderiv`, 1D `deriv`, and From 0584ae9e593e8fcb4b5a4bd08270ad1a601956b4 Mon Sep 17 00:00:00 2001 From: FordUniver <61389961+FordUniver@users.noreply.github.com> Date: Wed, 8 Jul 2026 17:50:43 +0900 Subject: [PATCH 27/40] Update Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean Co-authored-by: Jireh Loreaux --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 719435e477335e..a78bbc3a579679 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -30,7 +30,7 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] /-- A real-valued function `f` on a normed real vector space `F` is `K`-smooth if the first-order Taylor remainder is bounded quadratically: -`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) (dist x y)Β²` for all `x, y`. +`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) * (dist x y) ^ 2` for all `x, y`. The predicate is two-sided (absolute value), so closed under `f ↦ -f` and matching the textbook L-smoothness / `C^{1,1}` class. The `lineDeriv` form is From 330212546a2f8d8e5819746a6c8d66774a0763fc Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 12:04:29 +0200 Subject: [PATCH 28/40] chore: drop redundant coercion arrows on K, fix sub_apply deprecation The binrel elaborator inserts the NNReal-to-Real coercion at the leaf either way (verified: both spellings elaborate to the same term), so the explicit arrows were noise. Requested in review. --- .../Calculus/LipschitzSmooth/Basic.lean | 26 +++++++++---------- .../Calculus/LipschitzSmooth/Deriv.lean | 12 ++++----- .../Calculus/LipschitzSmooth/FDeriv.lean | 16 ++++++------ .../Calculus/LipschitzSmooth/Gradient.lean | 14 +++++----- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index a78bbc3a579679..55e70bf9cb02de 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -41,10 +41,10 @@ the `lineDeriv` value is always the actual line derivative. Equivalent characterisations in `fderiv`, `gradient`, and `deriv` form are provided in the sibling files, predicated on `Differentiable` where useful. -/ def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) := - βˆ€ (x y : F), |f y - f x - lineDeriv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 + βˆ€ (x y : F), |f y - f x - lineDeriv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : F β†’ ℝ} : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, |f y - f x - lineDeriv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := Iff.rfl + βˆ€ x y : F, |f y - f x - lineDeriv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := Iff.rfl namespace LipschitzSmoothWith @@ -52,30 +52,30 @@ variable {K : NNReal} {f : F β†’ ℝ} /-- Primary extractor: the Taylor remainder is bounded in absolute value. -/ theorem lineDeriv_abs_le (h : LipschitzSmoothWith K f) (x y : F) : - |f y - f x - lineDeriv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := h x y + |f y - f x - lineDeriv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := h x y /-- Descent inequality (upper-bound extractor). -/ theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : - f y ≀ f x + lineDeriv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by + f y ≀ f x + lineDeriv ℝ f x (y - x) + K / 2 * (dist x y) ^ 2 := by have := (abs_le.mp (h.lineDeriv_abs_le x y)).2 linarith /-- Ascent inequality (lower-bound extractor). -/ theorem lineDeriv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) : - f x + lineDeriv ℝ f x (y - x) - ↑K / 2 * (dist x y) ^ 2 ≀ f y := by + f x + lineDeriv ℝ f x (y - x) - K / 2 * (dist x y) ^ 2 ≀ f y := by have := (abs_le.mp (h.lineDeriv_abs_le x y)).1 linarith /-- One-sided variance bound on the line derivative. -/ theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : - lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by + lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := by have hyx := h.lineDeriv_descent_le y x rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx linarith [h.lineDeriv_descent_le x y, hyx] /-- Two-sided variance bound on the line derivative. -/ theorem lineDeriv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) : - |lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)| ≀ ↑K * (dist x y) ^ 2 := by + |lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)| ≀ K * (dist x y) ^ 2 := by rw [abs_le] refine ⟨?_, h.lineDeriv_apply_sub_le x y⟩ have hyx := h.lineDeriv_descent_ge y x @@ -84,7 +84,7 @@ theorem lineDeriv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) : /-- Functional-form variance bound. -/ theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : - (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := + (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ K * (dist x y) ^ 2 := Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y /-- `K`-smoothness implies line-differentiability: the actual line derivative @@ -97,7 +97,7 @@ theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : F) : change HasDerivAt (fun t : ℝ => f (x + t β€’ v)) L 0 rw [hasDerivAt_iff_isLittleO_nhds_zero, Asymptotics.isLittleO_iff] intro Ξ΅ hΞ΅ - have hsum_pos : (0:ℝ) < ↑K * β€–vβ€–^2 / 2 + 1 := by positivity + have hsum_pos : (0:ℝ) < K * β€–vβ€–^2 / 2 + 1 := by positivity filter_upwards [Metric.ball_mem_nhds (0 : ℝ) (div_pos hΞ΅ hsum_pos)] with t ht simp only [Metric.mem_ball, Real.dist_eq, sub_zero] at ht simp only [zero_add, zero_smul, add_zero, smul_eq_mul, Real.norm_eq_abs] @@ -105,10 +105,10 @@ theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : F) : rw [show (x + t β€’ v) - x = t β€’ v from by abel, lineDeriv_smul, smul_eq_mul, dist_self_add_right, norm_smul, Real.norm_eq_abs, mul_pow, sq_abs] at hpred refine hpred.trans ?_ - have ht' : |t| * (↑K * β€–vβ€–^2 / 2 + 1) < Ξ΅ := (lt_div_iffβ‚€ hsum_pos).mp ht - have ht'' : ↑K * β€–vβ€–^2 / 2 * |t| ≀ Ξ΅ := by nlinarith [abs_nonneg t] - calc ↑K / 2 * (t ^ 2 * β€–vβ€– ^ 2) - = ↑K * β€–vβ€–^2 / 2 * |t| * |t| := by rw [← sq_abs t]; ring + have ht' : |t| * (K * β€–vβ€–^2 / 2 + 1) < Ξ΅ := (lt_div_iffβ‚€ hsum_pos).mp ht + have ht'' : K * β€–vβ€–^2 / 2 * |t| ≀ Ξ΅ := by nlinarith [abs_nonneg t] + calc K / 2 * (t ^ 2 * β€–vβ€– ^ 2) + = K * β€–vβ€–^2 / 2 * |t| * |t| := by rw [← sq_abs t]; ring _ ≀ Ξ΅ * |t| := mul_le_mul_of_nonneg_right ht'' (abs_nonneg t) /-- A `K`-smooth function is line-differentiable everywhere. -/ diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index 13b1af70b2a0d5..f1bc11432c8313 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -26,7 +26,7 @@ public section variable {K : NNReal} {f : ℝ β†’ ℝ} theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : ℝ, |f y - f x - deriv f x * (y - x)| ≀ ↑K / 2 * (y - x) ^ 2 := by + βˆ€ x y : ℝ, |f y - f x - deriv f x * (y - x)| ≀ K / 2 * (y - x) ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] @@ -34,25 +34,25 @@ theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : LipschitzSmo namespace LipschitzSmoothWith theorem deriv_abs_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : - |f y - f x - deriv f x * (y - x)| ≀ ↑K / 2 * (y - x) ^ 2 := by + |f y - f x - deriv f x * (y - x)| ≀ K / 2 * (y - x) ^ 2 := by have := h.fderiv_abs_le x y hf rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : - f y ≀ f x + deriv f x * (y - x) + ↑K / 2 * (y - x) ^ 2 := by + f y ≀ f x + deriv f x * (y - x) + K / 2 * (y - x) ^ 2 := by have := h.fderiv_descent_le x y hf rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this theorem deriv_descent_ge (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : - f x + deriv f x * (y - x) - ↑K / 2 * (y - x) ^ 2 ≀ f y := by + f x + deriv f x * (y - x) - K / 2 * (y - x) ^ 2 ≀ f y := by have := h.fderiv_descent_ge x y hf rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : - (deriv f y - deriv f x) * (y - x) ≀ ↑K * (y - x) ^ 2 := by + (deriv f y - deriv f x) * (y - x) ≀ K * (y - x) ^ 2 := by have := h.fderiv_sub_apply_le x y hfx hfy - rwa [ContinuousLinearMap.sub_apply, fderiv_eq_deriv_mul, fderiv_eq_deriv_mul, ← sub_mul, + rwa [sub_apply, fderiv_eq_deriv_mul, fderiv_eq_deriv_mul, ← sub_mul, dist_comm, Real.dist_eq, sq_abs] at this end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index 6d62ed8eef6282..91c1265a11ee5f 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -22,7 +22,7 @@ variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] variable {K : NNReal} {f : F β†’ ℝ} theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, |f y - f x - fderiv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := by + βˆ€ x y : F, |f y - f x - fderiv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := by rw [lipschitzSmoothWith_iff_lineDeriv] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [(hf x).lineDeriv_eq_fderiv] @@ -30,36 +30,36 @@ theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : LipschitzSm namespace LipschitzSmoothWith theorem fderiv_abs_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - |f y - f x - fderiv ℝ f x (y - x)| ≀ ↑K / 2 * (dist x y) ^ 2 := by + |f y - f x - fderiv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_abs_le x y theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - f y ≀ f x + fderiv ℝ f x (y - x) + ↑K / 2 * (dist x y) ^ 2 := by + f y ≀ f x + fderiv ℝ f x (y - x) + K / 2 * (dist x y) ^ 2 := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_descent_le x y theorem fderiv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - f x + fderiv ℝ f x (y - x) - ↑K / 2 * (dist x y) ^ 2 ≀ f y := by + f x + fderiv ℝ f x (y - x) - K / 2 * (dist x y) ^ 2 ≀ f y := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_descent_ge x y theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : - fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ ↑K * (dist x y) ^ 2 := by + fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := by rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] exact h.lineDeriv_apply_sub_le x y theorem fderiv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : - |fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x)| ≀ ↑K * (dist x y) ^ 2 := by + |fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x)| ≀ K * (dist x y) ^ 2 := by rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] exact h.lineDeriv_apply_sub_abs_le x y theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : - (fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ ↑K * (dist x y) ^ 2 := by - rw [ContinuousLinearMap.sub_apply] + (fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ K * (dist x y) ^ 2 := by + rw [sub_apply] exact h.fderiv_apply_sub_le x y hfx hfy end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 4498bcf58bbcca..9f82f92939374e 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -30,7 +30,7 @@ open scoped Gradient RealInnerProductSpace theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ ↑K / 2 * β€–y - xβ€– ^ 2 := by + βˆ€ x y : F, |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ K / 2 * β€–y - xβ€– ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [inner_gradient_left, dist_eq_norm'] @@ -39,26 +39,26 @@ namespace LipschitzSmoothWith theorem inner_gradient_abs_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ ↑K / 2 * β€–y - xβ€– ^ 2 := by + |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ K / 2 * β€–y - xβ€– ^ 2 := by rw [inner_gradient_left, ← dist_eq_norm'] exact h.fderiv_abs_le x y hf theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + ↑K / 2 * β€–y - xβ€– ^ 2 := by + f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ + K / 2 * β€–y - xβ€– ^ 2 := by rw [inner_gradient_left, ← dist_eq_norm'] exact h.fderiv_descent_le x y hf theorem inner_gradient_descent_ge (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - f x + βŸͺβˆ‡ f x, y - x⟫ - ↑K / 2 * β€–y - xβ€– ^ 2 ≀ f y := by + f x + βŸͺβˆ‡ f x, y - x⟫ - K / 2 * β€–y - xβ€– ^ 2 ≀ f y := by rw [inner_gradient_left, ← dist_eq_norm'] exact h.fderiv_descent_ge x y hf theorem inner_gradient_sub_le (h : LipschitzSmoothWith K f) (x y : F) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : - βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ ↑K * β€–y - xβ€– ^ 2 := by - simp only [← dist_eq_norm', inner_sub_left, inner_gradient_left, ← ContinuousLinearMap.sub_apply] + βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ ≀ K * β€–y - xβ€– ^ 2 := by + simp only [← dist_eq_norm', inner_sub_left, inner_gradient_left, ← sub_apply] exact h.fderiv_sub_apply_le x y hfx hfy end LipschitzSmoothWith @@ -70,7 +70,7 @@ end LipschitzSmoothWith `(1/K)Β·β€–Β·β€–Β² ≀ βŸͺΒ·,·⟫` form when `0 < K`, but well-defined and meaningful even at `K = 0` (then forces `βˆ‡ f` constant). The conclusion of the Baillon-Haddad theorem. -/ abbrev CocoerciveWith (K : NNReal) (f : F β†’ ℝ) : Prop := - βˆ€ x y : F, β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 ≀ ↑K * βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ + βˆ€ x y : F, β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 ≀ K * βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ /-- A `K`-cocoercive gradient is `K`-Lipschitz. (One direction of the Baillon-Haddad characterisation; the reverse requires convexity.) -/ From f0803956d969783ab7cf4b494ea32fa85d288d0b Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 12:18:10 +0200 Subject: [PATCH 29/40] chore: replace "extractor" jargon with plain descriptions in docstrings "extractor" is homemade terminology (review feedback); the upper/lower quadratic bounds are the standard descent lemma. Plain descriptive docstrings, no inline citations (not the mathlib per-theorem style). --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 55e70bf9cb02de..17860d191e94cb 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -50,17 +50,18 @@ namespace LipschitzSmoothWith variable {K : NNReal} {f : F β†’ ℝ} -/-- Primary extractor: the Taylor remainder is bounded in absolute value. -/ +/-- The two-sided quadratic bound on the first-order Taylor remainder, restated +from the definition for dot notation. -/ theorem lineDeriv_abs_le (h : LipschitzSmoothWith K f) (x y : F) : |f y - f x - lineDeriv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := h x y -/-- Descent inequality (upper-bound extractor). -/ +/-- The quadratic upper bound on `f y`, traditionally called the *descent lemma*. -/ theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : f y ≀ f x + lineDeriv ℝ f x (y - x) + K / 2 * (dist x y) ^ 2 := by have := (abs_le.mp (h.lineDeriv_abs_le x y)).2 linarith -/-- Ascent inequality (lower-bound extractor). -/ +/-- The quadratic lower bound on `f y`: the descent lemma applied to `-f`. -/ theorem lineDeriv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) : f x + lineDeriv ℝ f x (y - x) - K / 2 * (dist x y) ^ 2 ≀ f y := by have := (abs_le.mp (h.lineDeriv_abs_le x y)).1 From b00b1e95398b439e21b137eba8674ce1ebf6155d Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 12:27:31 +0200 Subject: [PATCH 30/40] chore: drop bare author name-drop from module docstring Surnames without bib entries gesture at authority without giving the reader anything to look up; the 'L-smoothness / C^{1,1}' framing already signals it is the standard notion. --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 17860d191e94cb..5f5956e480f0e6 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -21,7 +21,7 @@ Hilbert-space gradient form live in the sibling files in this directory. This two-sided (absolute-value) form is orientation-agnostic (closed under `f ↦ -f`) β€” matching the textbook notion of L-smoothness (Lipschitz gradient, -the class `C^{1,1}`) used in Nesterov, Beck, Bauschke-Combettes, etc. +the class `C^{1,1}`). -/ public section From fcff1bae3077575b62047d8133f7593f306f398b Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 12:32:04 +0200 Subject: [PATCH 31/40] chore: "variance" -> "variation" in line-derivative bound docstrings "variance" is a statistics term; these lemmas bound how much the line derivative changes (its variation) along y - x. Homemade wording, same category as the "extractor" fix. --- Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 5f5956e480f0e6..fc58a4ae526cb0 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -67,14 +67,14 @@ theorem lineDeriv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) : have := (abs_le.mp (h.lineDeriv_abs_le x y)).1 linarith -/-- One-sided variance bound on the line derivative. -/ +/-- One-sided bound on the variation of the line derivative along `y - x`. -/ theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := by have hyx := h.lineDeriv_descent_le y x rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx linarith [h.lineDeriv_descent_le x y, hyx] -/-- Two-sided variance bound on the line derivative. -/ +/-- Two-sided bound on the variation of the line derivative along `y - x`. -/ theorem lineDeriv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) : |lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)| ≀ K * (dist x y) ^ 2 := by rw [abs_le] @@ -83,7 +83,8 @@ theorem lineDeriv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) : rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx linarith [h.lineDeriv_descent_ge x y] -/-- Functional-form variance bound. -/ +/-- The one-sided variation bound in functional form: the difference of +line-derivative maps applied to `y - x`. -/ theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ K * (dist x y) ^ 2 := Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y From ecebcc07cda6e81e1f0b77447f4a1b8ceb98cafc Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 13:33:05 +0200 Subject: [PATCH 32/40] feat: generalize LipschitzSmoothWith codomain to normed spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per review by j-loreaux on #39574, the predicate should not hard-code the codomain ℝ. `LipschitzSmoothWith K f` now takes `f : E β†’ F` for any real normed space `F`, with the first-order Taylor remainder bound stated in norms: β€–f y - f x - lineDeriv ℝ f x (y - x)β€– ≀ K / 2 * (dist x y) ^ 2 All two-sided bounds generalize: the defining bound, the variation bound on the line derivative (now proved directly via the triangle inequality), `hasLineDerivAt`, and their fderiv forms; the 1D deriv form becomes `f : ℝ β†’ F` via `fderiv_eq_smul_deriv`. The one-sided descent and variation bounds require an order on the codomain and stay specialized to real-valued `f` in dedicated `Real` sections; the Hilbert-space gradient file is unchanged apart from stating its two-sided bounds with β€–Β·β€– in place of |Β·|. Renames follow the naming convention (`abs` for |Β·|, `norm` for β€–Β·β€–): `*_abs_le` β†’ `*_norm_le`, `*_apply_sub_abs_le` β†’ `*_apply_sub_norm_le`; no ℝ-specialized `abs` duplicates are kept (`Real.norm_eq_abs` is a simp lemma and rfl). --- .../Calculus/LipschitzSmooth/Basic.lean | 136 ++++++++++-------- .../Calculus/LipschitzSmooth/Deriv.lean | 39 +++-- .../Calculus/LipschitzSmooth/FDeriv.lean | 47 +++--- .../Calculus/LipschitzSmooth/Gradient.lean | 13 +- 4 files changed, 142 insertions(+), 93 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index fc58a4ae526cb0..0648d94b062863 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -10,90 +10,75 @@ public import Mathlib.Analysis.Calculus.LineDeriv.Basic /-! # Lipschitz smoothness -A real-valued function `f` on a normed real vector space is **`K`-smooth** if the +A function `f : E β†’ F` between real normed vector spaces is **`K`-smooth** if the first-order Taylor remainder is bounded quadratically: -`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) * (dist x y) ^ 2` +`β€–f y - f x - lineDeriv ℝ f x (y - x)β€– ≀ (K / 2) * (dist x y) ^ 2` for all `x, y`. The predicate uses `lineDeriv` so as not to presuppose FrΓ©chet differentiability; equivalent characterisations in `fderiv`, 1D `deriv`, and Hilbert-space gradient form live in the sibling files in this directory. -This two-sided (absolute-value) form is orientation-agnostic (closed under -`f ↦ -f`) β€” matching the textbook notion of L-smoothness (Lipschitz gradient, -the class `C^{1,1}`). +This two-sided (norm) form is orientation-agnostic (closed under `f ↦ -f`) β€” +matching, for real-valued `f`, the textbook notion of L-smoothness (Lipschitz +gradient, the class `C^{1,1}`). The one-sided descent bounds require an order +on the codomain and are stated for real-valued `f` in a dedicated section. -/ public section -variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] +variable {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] + [NormedAddCommGroup F] [NormedSpace ℝ F] -/-- A real-valued function `f` on a normed real vector space `F` is `K`-smooth +/-- A function `f : E β†’ F` between real normed vector spaces is `K`-smooth if the first-order Taylor remainder is bounded quadratically: -`|f y - f x - lineDeriv ℝ f x (y - x)| ≀ (K / 2) * (dist x y) ^ 2` for all `x, y`. +`β€–f y - f x - lineDeriv ℝ f x (y - x)β€– ≀ (K / 2) * (dist x y) ^ 2` for all `x, y`. -The predicate is two-sided (absolute value), so closed under `f ↦ -f` and -matching the textbook L-smoothness / `C^{1,1}` class. The `lineDeriv` form is -the weakest possible underlying derivative form β€” the predicate implies +The predicate is two-sided (norm), so closed under `f ↦ -f` and matching, for +real-valued `f`, the textbook L-smoothness / `C^{1,1}` class. The `lineDeriv` +form is the weakest possible underlying derivative form β€” the predicate implies line-differentiability everywhere (`LipschitzSmoothWith.hasLineDerivAt`), so the `lineDeriv` value is always the actual line derivative. Equivalent characterisations in `fderiv`, `gradient`, and `deriv` form are -provided in the sibling files, predicated on `Differentiable` where useful. -/ -def LipschitzSmoothWith (K : NNReal) (f : F β†’ ℝ) := - βˆ€ (x y : F), |f y - f x - lineDeriv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 +provided in the sibling files, predicated on `Differentiable` where useful. +The one-sided descent bounds, which require an order on the codomain, are +stated for real-valued `f`. -/ +def LipschitzSmoothWith (K : NNReal) (f : E β†’ F) := + βˆ€ (x y : E), β€–f y - f x - lineDeriv ℝ f x (y - x)β€– ≀ K / 2 * (dist x y) ^ 2 -theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : F β†’ ℝ} : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, |f y - f x - lineDeriv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := Iff.rfl +theorem lipschitzSmoothWith_iff_lineDeriv {K : NNReal} {f : E β†’ F} : LipschitzSmoothWith K f ↔ + βˆ€ x y : E, β€–f y - f x - lineDeriv ℝ f x (y - x)β€– ≀ K / 2 * (dist x y) ^ 2 := Iff.rfl namespace LipschitzSmoothWith -variable {K : NNReal} {f : F β†’ ℝ} +variable {K : NNReal} {f : E β†’ F} /-- The two-sided quadratic bound on the first-order Taylor remainder, restated from the definition for dot notation. -/ -theorem lineDeriv_abs_le (h : LipschitzSmoothWith K f) (x y : F) : - |f y - f x - lineDeriv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := h x y - -/-- The quadratic upper bound on `f y`, traditionally called the *descent lemma*. -/ -theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : F) : - f y ≀ f x + lineDeriv ℝ f x (y - x) + K / 2 * (dist x y) ^ 2 := by - have := (abs_le.mp (h.lineDeriv_abs_le x y)).2 - linarith - -/-- The quadratic lower bound on `f y`: the descent lemma applied to `-f`. -/ -theorem lineDeriv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) : - f x + lineDeriv ℝ f x (y - x) - K / 2 * (dist x y) ^ 2 ≀ f y := by - have := (abs_le.mp (h.lineDeriv_abs_le x y)).1 - linarith - -/-- One-sided bound on the variation of the line derivative along `y - x`. -/ -theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) : - lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := by - have hyx := h.lineDeriv_descent_le y x - rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx - linarith [h.lineDeriv_descent_le x y, hyx] +theorem lineDeriv_norm_le (h : LipschitzSmoothWith K f) (x y : E) : + β€–f y - f x - lineDeriv ℝ f x (y - x)β€– ≀ K / 2 * (dist x y) ^ 2 := h x y /-- Two-sided bound on the variation of the line derivative along `y - x`. -/ -theorem lineDeriv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) : - |lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)| ≀ K * (dist x y) ^ 2 := by - rw [abs_le] - refine ⟨?_, h.lineDeriv_apply_sub_le x y⟩ - have hyx := h.lineDeriv_descent_ge y x - rw [← neg_sub y x, lineDeriv_neg, dist_comm] at hyx - linarith [h.lineDeriv_descent_ge x y] - -/-- The one-sided variation bound in functional form: the difference of -line-derivative maps applied to `y - x`. -/ -theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) : - (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ K * (dist x y) ^ 2 := - Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y +theorem lineDeriv_apply_sub_norm_le (h : LipschitzSmoothWith K f) (x y : E) : + β€–lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)β€– ≀ K * (dist x y) ^ 2 := by + have hyx := h.lineDeriv_norm_le y x + rw [← neg_sub y x, lineDeriv_neg, sub_neg_eq_add, dist_comm] at hyx + calc β€–lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)β€– + = β€–(f y - f x - lineDeriv ℝ f x (y - x)) + (f x - f y + lineDeriv ℝ f y (y - x))β€– := by + congr 1 + abel + _ ≀ β€–f y - f x - lineDeriv ℝ f x (y - x)β€– + β€–f x - f y + lineDeriv ℝ f y (y - x)β€– := + norm_add_le _ _ + _ ≀ K / 2 * (dist x y) ^ 2 + K / 2 * (dist x y) ^ 2 := + add_le_add (h.lineDeriv_norm_le x y) hyx + _ = K * (dist x y) ^ 2 := by ring /-- `K`-smoothness implies line-differentiability: the actual line derivative exists at every `x, v` and equals `lineDeriv ℝ f x v`. The predicate bound -`|f(x + tv) - f x - t Β· L| ≀ K/2 Β· tΒ² β€–vβ€–Β²` (via `lineDeriv_smul` to factor `t`) +`β€–f (x + tv) - f x - t β€’ Lβ€– ≀ K/2 Β· tΒ² β€–vβ€–Β²` (via `lineDeriv_smul` to factor `t`) is `o(t)`. -/ -theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : F) : +theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : E) : HasLineDerivAt ℝ f (lineDeriv ℝ f x v) x v := by set L := lineDeriv ℝ f x v change HasDerivAt (fun t : ℝ => f (x + t β€’ v)) L 0 @@ -102,9 +87,9 @@ theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : F) : have hsum_pos : (0:ℝ) < K * β€–vβ€–^2 / 2 + 1 := by positivity filter_upwards [Metric.ball_mem_nhds (0 : ℝ) (div_pos hΞ΅ hsum_pos)] with t ht simp only [Metric.mem_ball, Real.dist_eq, sub_zero] at ht - simp only [zero_add, zero_smul, add_zero, smul_eq_mul, Real.norm_eq_abs] + simp only [zero_add, zero_smul, add_zero, Real.norm_eq_abs] have hpred := h x (x + t β€’ v) - rw [show (x + t β€’ v) - x = t β€’ v from by abel, lineDeriv_smul, smul_eq_mul, + rw [show (x + t β€’ v) - x = t β€’ v from by abel, lineDeriv_smul, dist_self_add_right, norm_smul, Real.norm_eq_abs, mul_pow, sq_abs] at hpred refine hpred.trans ?_ have ht' : |t| * (K * β€–vβ€–^2 / 2 + 1) < Ξ΅ := (lt_div_iffβ‚€ hsum_pos).mp ht @@ -114,8 +99,47 @@ theorem hasLineDerivAt (h : LipschitzSmoothWith K f) (x v : F) : _ ≀ Ξ΅ * |t| := mul_le_mul_of_nonneg_right ht'' (abs_nonneg t) /-- A `K`-smooth function is line-differentiable everywhere. -/ -theorem lineDifferentiableAt (h : LipschitzSmoothWith K f) (x v : F) : +theorem lineDifferentiableAt (h : LipschitzSmoothWith K f) (x v : E) : LineDifferentiableAt ℝ f x v := (h.hasLineDerivAt x v).lineDifferentiableAt +/-! ### Real-valued functions + +The one-sided (order-based) bounds require an order on the codomain, so they are +stated for real-valued `f`. The norm and the absolute value agree on `ℝ` +(`Real.norm_eq_abs`), so the two-sided bounds above apply verbatim. -/ + +section Real + +variable {f : E β†’ ℝ} + +/-- The quadratic upper bound on `f y`, traditionally called the *descent lemma*. -/ +theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : E) : + f y ≀ f x + lineDeriv ℝ f x (y - x) + K / 2 * (dist x y) ^ 2 := by + have h₁ := h.lineDeriv_norm_le x y + rw [Real.norm_eq_abs, abs_le] at h₁ + linarith [h₁.2] + +/-- The quadratic lower bound on `f y`: the descent lemma applied to `-f`. -/ +theorem lineDeriv_descent_ge (h : LipschitzSmoothWith K f) (x y : E) : + f x + lineDeriv ℝ f x (y - x) - K / 2 * (dist x y) ^ 2 ≀ f y := by + have h₁ := h.lineDeriv_norm_le x y + rw [Real.norm_eq_abs, abs_le] at h₁ + linarith [h₁.1] + +/-- One-sided bound on the variation of the line derivative along `y - x`. -/ +theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : E) : + lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := by + have h₁ := h.lineDeriv_apply_sub_norm_le x y + rw [Real.norm_eq_abs] at h₁ + exact le_of_abs_le h₁ + +/-- The one-sided variation bound in functional form: the difference of +line-derivative maps applied to `y - x`. -/ +theorem lineDeriv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : E) : + (lineDeriv ℝ f y - lineDeriv ℝ f x) (y - x) ≀ K * (dist x y) ^ 2 := + Pi.sub_apply (lineDeriv ℝ f _) _ _ β–Έ h.lineDeriv_apply_sub_le x y + +end Real + end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index f1bc11432c8313..992054b7a457f6 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -11,32 +11,43 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv /-! # Lipschitz smoothness in 1D via the derivative -For a `K`-smooth function `f : ℝ β†’ ℝ`, the Taylor bound and the variation bound take -their classical 1D forms: +For a `K`-smooth function `f : ℝ β†’ F`, the Taylor bound takes its 1D form -`|f y - f x - deriv f x Β· (y - x)| ≀ K/2 Β· (y - x)Β²`, -`(deriv f y - deriv f x) Β· (y - x) ≀ K Β· (y - x)Β²`. +`β€–f y - f x - (y - x) β€’ deriv f xβ€– ≀ K/2 Β· (y - x)Β²`, -These are 1D restatements of the FrΓ©chet-derivative forms in -`Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv`, lifted via `fderiv_eq_deriv_mul`. +lifted from the FrΓ©chet-derivative form in +`Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv` via `fderiv_eq_smul_deriv`. +For real-valued `f` the one-sided bounds take their classical forms + +`f y ≀ f x + deriv f x * (y - x) + K/2 Β· (y - x)Β²`, +`(deriv f y - deriv f x) * (y - x) ≀ K Β· (y - x)Β²`, + +with the scalar action spelled as multiplication (`smul_eq_mul` bridges the two). -/ public section -variable {K : NNReal} {f : ℝ β†’ ℝ} +variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] +variable {K : NNReal} {f : ℝ β†’ F} theorem lipschitzSmoothWith_iff_deriv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : ℝ, |f y - f x - deriv f x * (y - x)| ≀ K / 2 * (y - x) ^ 2 := by + βˆ€ x y : ℝ, β€–f y - f x - (y - x) β€’ deriv f xβ€– ≀ K / 2 * (y - x) ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ - rw [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] + rw [fderiv_eq_smul_deriv, dist_comm, Real.dist_eq, sq_abs] namespace LipschitzSmoothWith -theorem deriv_abs_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : - |f y - f x - deriv f x * (y - x)| ≀ K / 2 * (y - x) ^ 2 := by - have := h.fderiv_abs_le x y hf - rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this +theorem deriv_norm_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : + β€–f y - f x - (y - x) β€’ deriv f xβ€– ≀ K / 2 * (y - x) ^ 2 := by + have := h.fderiv_norm_le x y hf + rwa [fderiv_eq_smul_deriv, dist_comm, Real.dist_eq, sq_abs] at this + +/-! ### Real-valued functions -/ + +section Real + +variable {f : ℝ β†’ ℝ} theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + deriv f x * (y - x) + K / 2 * (y - x) ^ 2 := by @@ -55,4 +66,6 @@ theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) rwa [sub_apply, fderiv_eq_deriv_mul, fderiv_eq_deriv_mul, ← sub_mul, dist_comm, Real.dist_eq, sq_abs] at this +end Real + end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index 91c1265a11ee5f..556bb1108b636f 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -11,55 +11,66 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic /-! # Lipschitz smoothness via the FrΓ©chet derivative -FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate. For differentiable -`f`, `lineDeriv ℝ f x v = fderiv ℝ f x v` pointwise, and the predicate is equivalent to -the two-sided Taylor bound stated in `fderiv` form. +FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate for +`f : E β†’ F`. For differentiable `f`, `lineDeriv ℝ f x v = fderiv ℝ f x v` +pointwise, and the predicate is equivalent to the two-sided Taylor bound stated +in `fderiv` form. The one-sided descent bounds require an order on the codomain +and are stated for real-valued `f` in a dedicated section. -/ public section +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ℝ F] -variable {K : NNReal} {f : F β†’ ℝ} +variable {K : NNReal} {f : E β†’ F} theorem lipschitzSmoothWith_iff_fderiv (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, |f y - f x - fderiv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := by + βˆ€ x y : E, β€–f y - f x - fderiv ℝ f x (y - x)β€– ≀ K / 2 * (dist x y) ^ 2 := by rw [lipschitzSmoothWith_iff_lineDeriv] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [(hf x).lineDeriv_eq_fderiv] namespace LipschitzSmoothWith -theorem fderiv_abs_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - |f y - f x - fderiv ℝ f x (y - x)| ≀ K / 2 * (dist x y) ^ 2 := by +theorem fderiv_norm_le (h : LipschitzSmoothWith K f) (x y : E) (hf : DifferentiableAt ℝ f x) : + β€–f y - f x - fderiv ℝ f x (y - x)β€– ≀ K / 2 * (dist x y) ^ 2 := by rw [← hf.lineDeriv_eq_fderiv] - exact h.lineDeriv_abs_le x y + exact h.lineDeriv_norm_le x y -theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : +theorem fderiv_apply_sub_norm_le (h : LipschitzSmoothWith K f) (x y : E) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : + β€–fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x)β€– ≀ K * (dist x y) ^ 2 := by + rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] + exact h.lineDeriv_apply_sub_norm_le x y + +/-! ### Real-valued functions -/ + +section Real + +variable {f : E β†’ ℝ} + +theorem fderiv_descent_le (h : LipschitzSmoothWith K f) (x y : E) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + fderiv ℝ f x (y - x) + K / 2 * (dist x y) ^ 2 := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_descent_le x y -theorem fderiv_descent_ge (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : +theorem fderiv_descent_ge (h : LipschitzSmoothWith K f) (x y : E) (hf : DifferentiableAt ℝ f x) : f x + fderiv ℝ f x (y - x) - K / 2 * (dist x y) ^ 2 ≀ f y := by rw [← hf.lineDeriv_eq_fderiv] exact h.lineDeriv_descent_ge x y -theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : F) +theorem fderiv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : E) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := by rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] exact h.lineDeriv_apply_sub_le x y -theorem fderiv_apply_sub_abs_le (h : LipschitzSmoothWith K f) (x y : F) - (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : - |fderiv ℝ f y (y - x) - fderiv ℝ f x (y - x)| ≀ K * (dist x y) ^ 2 := by - rw [← hfy.lineDeriv_eq_fderiv, ← hfx.lineDeriv_eq_fderiv] - exact h.lineDeriv_apply_sub_abs_le x y - -theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : F) +theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : E) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (fderiv ℝ f y - fderiv ℝ f x) (y - x) ≀ K * (dist x y) ^ 2 := by rw [sub_apply] exact h.fderiv_apply_sub_le x y hfx hfy +end Real + end LipschitzSmoothWith diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 9f82f92939374e..86a31d07d0cb9c 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -14,7 +14,7 @@ public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv On a Hilbert space `F`, the `LipschitzSmoothWith` predicate admits a gradient-form characterisation. For differentiable `f`, `fderiv ℝ f x (y - x) = βŸͺβˆ‡ f x, y - x⟫` via Riesz representation (`inner_gradient_left`), and the two-sided Taylor bound becomes -`|f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ K/2 Β· β€–y - xβ€–Β²`. +`β€–f y - f x - βŸͺβˆ‡ f x, y - xβŸ«β€– ≀ K/2 Β· β€–y - xβ€–Β²`. This file also defines the **`CocoerciveWith K f`** predicate (the conclusion of the Baillon-Haddad theorem) and the elementary direction `K`-cocoercive ⟹ `K`-Lipschitz @@ -30,18 +30,19 @@ open scoped Gradient RealInnerProductSpace theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : LipschitzSmoothWith K f ↔ - βˆ€ x y : F, |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ K / 2 * β€–y - xβ€– ^ 2 := by + βˆ€ x y : F, β€–f y - f x - βŸͺβˆ‡ f x, y - xβŸ«β€– ≀ K / 2 * β€–y - xβ€– ^ 2 := by rw [lipschitzSmoothWith_iff_fderiv hf] refine forall_congr' fun x => forall_congr' fun y => ?_ rw [inner_gradient_left, dist_eq_norm'] namespace LipschitzSmoothWith -theorem inner_gradient_abs_le (h : LipschitzSmoothWith K f) (x y : F) +theorem inner_gradient_norm_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : - |f y - f x - βŸͺβˆ‡ f x, y - x⟫| ≀ K / 2 * β€–y - xβ€– ^ 2 := by - rw [inner_gradient_left, ← dist_eq_norm'] - exact h.fderiv_abs_le x y hf + β€–f y - f x - βŸͺβˆ‡ f x, y - xβŸ«β€– ≀ K / 2 * β€–y - xβ€– ^ 2 := by + rw [inner_gradient_left] + have := h.fderiv_norm_le x y hf + rwa [dist_eq_norm'] at this theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : From de50c2f97664e37e10ee3632fe7be350f91bf09e Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 13:44:50 +0200 Subject: [PATCH 33/40] style: tighten proofs after codomain generalization - replace have/rwa-at chains with simpa only ... using (Deriv, Gradient) - scalar section consumes the norm bounds directly by defeq (Real.norm_eq_abs is rfl): descent lemmas are one-line linarith, lineDeriv_apply_sub_le is term-mode le_of_abs_le - lineDeriv_apply_sub_norm_le: drop the calc block for norm_add_le + one abel rewrite + linarith --- .../Calculus/LipschitzSmooth/Basic.lean | 27 ++++++------------- .../Calculus/LipschitzSmooth/Deriv.lean | 17 ++++++------ .../Calculus/LipschitzSmooth/Gradient.lean | 4 +-- 3 files changed, 17 insertions(+), 31 deletions(-) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean index 0648d94b062863..5bdcc496600923 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Basic.lean @@ -64,15 +64,10 @@ theorem lineDeriv_apply_sub_norm_le (h : LipschitzSmoothWith K f) (x y : E) : β€–lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)β€– ≀ K * (dist x y) ^ 2 := by have hyx := h.lineDeriv_norm_le y x rw [← neg_sub y x, lineDeriv_neg, sub_neg_eq_add, dist_comm] at hyx - calc β€–lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)β€– - = β€–(f y - f x - lineDeriv ℝ f x (y - x)) + (f x - f y + lineDeriv ℝ f y (y - x))β€– := by - congr 1 - abel - _ ≀ β€–f y - f x - lineDeriv ℝ f x (y - x)β€– + β€–f x - f y + lineDeriv ℝ f y (y - x)β€– := - norm_add_le _ _ - _ ≀ K / 2 * (dist x y) ^ 2 + K / 2 * (dist x y) ^ 2 := - add_le_add (h.lineDeriv_norm_le x y) hyx - _ = K * (dist x y) ^ 2 := by ring + have key := (norm_add_le _ _).trans (add_le_add hyx (h.lineDeriv_norm_le x y)) + rw [show f x - f y + lineDeriv ℝ f y (y - x) + (f y - f x - lineDeriv ℝ f x (y - x)) + = lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) from by abel] at key + linarith /-- `K`-smoothness implies line-differentiability: the actual line derivative exists at every `x, v` and equals `lineDeriv ℝ f x v`. The predicate bound @@ -116,23 +111,17 @@ variable {f : E β†’ ℝ} /-- The quadratic upper bound on `f y`, traditionally called the *descent lemma*. -/ theorem lineDeriv_descent_le (h : LipschitzSmoothWith K f) (x y : E) : f y ≀ f x + lineDeriv ℝ f x (y - x) + K / 2 * (dist x y) ^ 2 := by - have h₁ := h.lineDeriv_norm_le x y - rw [Real.norm_eq_abs, abs_le] at h₁ - linarith [h₁.2] + linarith [(abs_le.mp (h.lineDeriv_norm_le x y)).2] /-- The quadratic lower bound on `f y`: the descent lemma applied to `-f`. -/ theorem lineDeriv_descent_ge (h : LipschitzSmoothWith K f) (x y : E) : f x + lineDeriv ℝ f x (y - x) - K / 2 * (dist x y) ^ 2 ≀ f y := by - have h₁ := h.lineDeriv_norm_le x y - rw [Real.norm_eq_abs, abs_le] at h₁ - linarith [h₁.1] + linarith [(abs_le.mp (h.lineDeriv_norm_le x y)).1] /-- One-sided bound on the variation of the line derivative along `y - x`. -/ theorem lineDeriv_apply_sub_le (h : LipschitzSmoothWith K f) (x y : E) : - lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := by - have h₁ := h.lineDeriv_apply_sub_norm_le x y - rw [Real.norm_eq_abs] at h₁ - exact le_of_abs_le h₁ + lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) ≀ K * (dist x y) ^ 2 := + le_of_abs_le (h.lineDeriv_apply_sub_norm_le x y) /-- The one-sided variation bound in functional form: the difference of line-derivative maps applied to `y - x`. -/ diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index 992054b7a457f6..a1b104cca702d5 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -40,8 +40,8 @@ namespace LipschitzSmoothWith theorem deriv_norm_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : β€–f y - f x - (y - x) β€’ deriv f xβ€– ≀ K / 2 * (y - x) ^ 2 := by - have := h.fderiv_norm_le x y hf - rwa [fderiv_eq_smul_deriv, dist_comm, Real.dist_eq, sq_abs] at this + simpa only [fderiv_eq_smul_deriv, dist_comm x y, Real.dist_eq, sq_abs] + using h.fderiv_norm_le x y hf /-! ### Real-valued functions -/ @@ -51,20 +51,19 @@ variable {f : ℝ β†’ ℝ} theorem deriv_descent_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + deriv f x * (y - x) + K / 2 * (y - x) ^ 2 := by - have := h.fderiv_descent_le x y hf - rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this + simpa only [fderiv_eq_deriv_mul, dist_comm x y, Real.dist_eq, sq_abs] + using h.fderiv_descent_le x y hf theorem deriv_descent_ge (h : LipschitzSmoothWith K f) (x y : ℝ) (hf : DifferentiableAt ℝ f x) : f x + deriv f x * (y - x) - K / 2 * (y - x) ^ 2 ≀ f y := by - have := h.fderiv_descent_ge x y hf - rwa [fderiv_eq_deriv_mul, dist_comm, Real.dist_eq, sq_abs] at this + simpa only [fderiv_eq_deriv_mul, dist_comm x y, Real.dist_eq, sq_abs] + using h.fderiv_descent_ge x y hf theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : (deriv f y - deriv f x) * (y - x) ≀ K * (y - x) ^ 2 := by - have := h.fderiv_sub_apply_le x y hfx hfy - rwa [sub_apply, fderiv_eq_deriv_mul, fderiv_eq_deriv_mul, ← sub_mul, - dist_comm, Real.dist_eq, sq_abs] at this + simpa only [sub_apply, fderiv_eq_deriv_mul, ← sub_mul, dist_comm x y, Real.dist_eq, sq_abs] + using h.fderiv_sub_apply_le x y hfx hfy end Real diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index 86a31d07d0cb9c..a78e28cd88dead 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -40,9 +40,7 @@ namespace LipschitzSmoothWith theorem inner_gradient_norm_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : β€–f y - f x - βŸͺβˆ‡ f x, y - xβŸ«β€– ≀ K / 2 * β€–y - xβ€– ^ 2 := by - rw [inner_gradient_left] - have := h.fderiv_norm_le x y hf - rwa [dist_eq_norm'] at this + simpa only [inner_gradient_left, dist_eq_norm'] using h.fderiv_norm_le x y hf theorem inner_gradient_descent_le (h : LipschitzSmoothWith K f) (x y : F) (hf : DifferentiableAt ℝ f x) : From d7b45d96071f09fa6a42b1d187b0ba1317d13a14 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 11:08:18 +0200 Subject: [PATCH 34/40] feat(Analysis/Convex): first-order convexity inequalities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds first-order characterizations of convexity for differentiable functions: `f` is convex on `s` iff `f y β‰₯ f x + lineDeriv f x (y - x)` (and FrΓ©chet / gradient analogues), plus the strict variant, the iff converse, and a few corollaries. * `Mathlib/Analysis/Convex/LineDeriv.lean` (new): the proof-content layer. `ConvexOn.lineRestriction`, `ConvexOn.add_lineDeriv_le`, `ConvexOn.lineDeriv_sub_apply_nonneg`, `ConcaveOn.le_add_lineDeriv`, `StrictConvexOn.add_lineDeriv_lt`, `convexOn_iff_add_lineDeriv_le`. * `Mathlib/Analysis/Convex/FDeriv.lean` (new): FrΓ©chet-form lifts via `lineDeriv_eq_fderiv`. `ConvexOn.add_fderiv_le`, `ConvexOn.fderiv_sub_apply_nonneg`, `ConcaveOn.le_add_fderiv`, `StrictConvexOn.add_fderiv_lt`, `convexOn_iff_add_fderiv_le`. * `Mathlib/Analysis/Convex/Gradient.lean` (new): gradient-form lifts via Riesz (`inner_gradient_left`). `ConvexOn.add_inner_gradient_le`, `ConvexOn.inner_gradient_sub_nonneg`, `ConvexOn.isMinOn_of_gradient_eq_zero`, `ConcaveOn.le_add_inner_gradient`, `StrictConvexOn.add_inner_gradient_lt`, `convexOn_iff_add_inner_gradient_le`. * `Mathlib/Analysis/Convex/Deriv.lean` (additions): 1D additive form + line-restriction helper. --- Mathlib.lean | 3 + Mathlib/Analysis/Convex/Deriv.lean | 32 ++++++ Mathlib/Analysis/Convex/FDeriv.lean | 86 +++++++++++++++ Mathlib/Analysis/Convex/Gradient.lean | 100 +++++++++++++++++ Mathlib/Analysis/Convex/LineDeriv.lean | 146 +++++++++++++++++++++++++ 5 files changed, 367 insertions(+) create mode 100644 Mathlib/Analysis/Convex/FDeriv.lean create mode 100644 Mathlib/Analysis/Convex/Gradient.lean create mode 100644 Mathlib/Analysis/Convex/LineDeriv.lean diff --git a/Mathlib.lean b/Mathlib.lean index 25322c6b37cb10..4c02e90fdc611e 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1951,10 +1951,12 @@ public import Mathlib.Analysis.Convex.EGauge public import Mathlib.Analysis.Convex.Exposed public import Mathlib.Analysis.Convex.Extrema public import Mathlib.Analysis.Convex.Extreme +public import Mathlib.Analysis.Convex.FDeriv public import Mathlib.Analysis.Convex.Function public import Mathlib.Analysis.Convex.FunctionTopology public import Mathlib.Analysis.Convex.Gauge public import Mathlib.Analysis.Convex.GaugeRescale +public import Mathlib.Analysis.Convex.Gradient public import Mathlib.Analysis.Convex.Hull public import Mathlib.Analysis.Convex.Independent public import Mathlib.Analysis.Convex.Integral @@ -1962,6 +1964,7 @@ public import Mathlib.Analysis.Convex.Intrinsic public import Mathlib.Analysis.Convex.Jensen public import Mathlib.Analysis.Convex.Join public import Mathlib.Analysis.Convex.KreinMilman +public import Mathlib.Analysis.Convex.LineDeriv public import Mathlib.Analysis.Convex.LinearIsometry public import Mathlib.Analysis.Convex.Measure public import Mathlib.Analysis.Convex.MetricSpace diff --git a/Mathlib/Analysis/Convex/Deriv.lean b/Mathlib/Analysis/Convex/Deriv.lean index 0e4fae608c2e01..a3e70d69ee05a4 100644 --- a/Mathlib/Analysis/Convex/Deriv.lean +++ b/Mathlib/Analysis/Convex/Deriv.lean @@ -603,6 +603,22 @@ lemma deriv_le_slope (hfc : ConvexOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy deriv f x ≀ slope f x y := le_slope_of_hasDerivAt hfc hx hy hxy hfd.hasDerivAt +/-- Additive form of the 1D first-order convexity inequality: for `f : ℝ β†’ ℝ` convex on `S`, +`x, y ∈ S` with `x < y`, and `f` differentiable at `x`, we have +`f x + f' * (y - x) ≀ f y` where `f' = deriv f x`. -/ +lemma add_hasDerivAt_mul_le (hfc : ConvexOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (ha : HasDerivAt f f' x) : + f x + f' * (y - x) ≀ f y := by + have h := hfc.le_slope_of_hasDerivAt hx hy hxy ha + rw [slope_def_field, le_div_iffβ‚€ (sub_pos.mpr hxy)] at h + linarith + +/-- Reformulation of `ConvexOn.add_hasDerivAt_mul_le` using `deriv`. -/ +lemma add_deriv_mul_le (hfc : ConvexOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (hfd : DifferentiableAt ℝ f x) : + f x + deriv f x * (y - x) ≀ f y := + hfc.add_hasDerivAt_mul_le hx hy hxy hfd.hasDerivAt + end left section right @@ -892,6 +908,22 @@ lemma slope_le_deriv (hfc : ConcaveOn ℝ S f) slope f x y ≀ deriv f x := hfc.slope_le_of_hasDerivAt hx hy hxy hfd.hasDerivAt +/-- Additive form of the 1D first-order concavity inequality: for `f : ℝ β†’ ℝ` concave on `S`, +`x, y ∈ S` with `x < y`, and `f` differentiable at `x`, we have +`f y ≀ f x + f' * (y - x)` where `f' = deriv f x`. -/ +lemma le_add_hasDerivAt_mul (hfc : ConcaveOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (ha : HasDerivAt f f' x) : + f y ≀ f x + f' * (y - x) := by + have h := hfc.slope_le_of_hasDerivAt hx hy hxy ha + rw [slope_def_field, div_le_iffβ‚€ (sub_pos.mpr hxy)] at h + linarith + +/-- Reformulation of `ConcaveOn.le_add_hasDerivAt_mul` using `deriv`. -/ +lemma le_add_deriv_mul (hfc : ConcaveOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (hfd : DifferentiableAt ℝ f x) : + f y ≀ f x + deriv f x * (y - x) := + hfc.le_add_hasDerivAt_mul hx hy hxy hfd.hasDerivAt + end left section right diff --git a/Mathlib/Analysis/Convex/FDeriv.lean b/Mathlib/Analysis/Convex/FDeriv.lean new file mode 100644 index 00000000000000..63d36de0e912ae --- /dev/null +++ b/Mathlib/Analysis/Convex/FDeriv.lean @@ -0,0 +1,86 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Convex.LineDeriv +public import Mathlib.Analysis.Calculus.FDeriv.Basic + +/-! +# First-order convexity inequality via the FrΓ©chet derivative + +For `f : E β†’ ℝ` convex on `s βŠ† E` and FrΓ©chet-differentiable at `x ∈ s`, the first-order +convexity inequality + +`f x + (fderiv ℝ f x) (y - x) ≀ f y` + +holds for `y ∈ s`. This is the FrΓ©chet-derivative restatement of the line-derivative form +in `Mathlib.Analysis.Convex.LineDeriv`, lifted via `DifferentiableAt.lineDeriv_eq_fderiv`. + +## Main results + +* `ConvexOn.add_fderiv_le` β€” the first-order convexity inequality (FrΓ©chet form). +* `ConcaveOn.le_add_fderiv` β€” the concave dual. +* `ConvexOn.fderiv_sub_apply_nonneg` β€” monotonicity: `0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x)`. +* `StrictConvexOn.add_fderiv_lt` β€” strict variant. +* `convexOn_iff_add_fderiv_le` β€” iff converse: differentiability plus the first-order + inequality everywhere implies `ConvexOn`. +-/ + +public section + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] +variable {f : E β†’ ℝ} {s : Set E} {x y : E} + +namespace ConvexOn + +/-- For a convex function `f` FrΓ©chet-differentiable at `x`, the first-order inequality +`f x + (fderiv ℝ f x) (y - x) ≀ f y` holds. -/ +theorem add_fderiv_le (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hf : DifferentiableAt ℝ f x) : + f x + fderiv ℝ f x (y - x) ≀ f y := + hf.lineDeriv_eq_fderiv β–Έ hc.add_lineDeriv_le hx hy hf.lineDifferentiableAt + +/-- Monotonicity of the FrΓ©chet derivative along the chord: for convex `f` differentiable +at `x` and `y`, `0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x)`. -/ +theorem fderiv_sub_apply_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : + 0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x) := by + rw [ContinuousLinearMap.sub_apply, ← hfx.lineDeriv_eq_fderiv, ← hfy.lineDeriv_eq_fderiv] + exact hc.lineDeriv_sub_apply_nonneg hx hy hfx.lineDifferentiableAt hfy.lineDifferentiableAt + +end ConvexOn + +namespace ConcaveOn + +/-- For a concave function `f` FrΓ©chet-differentiable at `x`, the reverse first-order +inequality `f y ≀ f x + (fderiv ℝ f x) (y - x)` holds. -/ +theorem le_add_fderiv (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hf : DifferentiableAt ℝ f x) : + f y ≀ f x + fderiv ℝ f x (y - x) := + hf.lineDeriv_eq_fderiv β–Έ hc.le_add_lineDeriv hx hy hf.lineDifferentiableAt + +end ConcaveOn + +namespace StrictConvexOn + +/-- Strict variant of the first-order inequality for strictly convex `f`: +when `x β‰  y`, the inequality is strict. -/ +theorem add_fderiv_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + (hf : DifferentiableAt ℝ f x) : + f x + fderiv ℝ f x (y - x) < f y := + hf.lineDeriv_eq_fderiv β–Έ hc.add_lineDeriv_lt hx hy hxy hf.lineDifferentiableAt + +end StrictConvexOn + +/-- A differentiable function is convex iff it satisfies the first-order inequality +at every pair of points in `s`. -/ +theorem convexOn_iff_add_fderiv_le (hs : Convex ℝ s) (hf : βˆ€ x ∈ s, DifferentiableAt ℝ f x) : + ConvexOn ℝ s f ↔ + βˆ€ x ∈ s, βˆ€ y ∈ s, f x + fderiv ℝ f x (y - x) ≀ f y := by + rw [convexOn_iff_add_lineDeriv_le hs fun x hx _ _ => (hf x hx).lineDifferentiableAt] + refine forall_congr' fun x => imp_congr_right fun hx => forall_congr' fun _ => + imp_congr_right fun _ => ?_ + rw [(hf x hx).lineDeriv_eq_fderiv] diff --git a/Mathlib/Analysis/Convex/Gradient.lean b/Mathlib/Analysis/Convex/Gradient.lean new file mode 100644 index 00000000000000..f1621b418411c8 --- /dev/null +++ b/Mathlib/Analysis/Convex/Gradient.lean @@ -0,0 +1,100 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Convex.FDeriv +public import Mathlib.Analysis.Calculus.Gradient.Basic + +/-! +# First-order convexity inequality via the gradient + +For `f : F β†’ ℝ` convex on `s βŠ† F` on a Hilbert space and differentiable at `x ∈ s`, +the first-order convexity inequality + +`f x + βŸͺβˆ‡ f x, y - x⟫ ≀ f y` + +holds for `y ∈ s`. This is the gradient/inner-product restatement of the FrΓ©chet form +in `Mathlib.Analysis.Convex.FDeriv`, lifted via `inner_gradient_left`. + +## Main results + +* `ConvexOn.add_inner_gradient_le` β€” the first-order convexity inequality (gradient form). +* `ConcaveOn.le_add_inner_gradient` β€” the concave dual. +* `ConvexOn.inner_gradient_sub_nonneg` β€” monotonicity: `0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫`. +* `ConvexOn.isMinOn_of_gradient_eq_zero` β€” convex + zero gradient at `x` ⟹ `x` minimizes `f`. +* `StrictConvexOn.add_inner_gradient_lt` β€” strict variant. +* `convexOn_iff_add_inner_gradient_le` β€” iff converse. +-/ + +public section + +variable {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] [CompleteSpace F] +variable {f : F β†’ ℝ} {s : Set F} {x y : F} + +open InnerProductSpace +open scoped Gradient RealInnerProductSpace + +namespace ConvexOn + +/-- For a convex function `f` differentiable at `x` on a Hilbert space, the first-order +inequality `f x + βŸͺβˆ‡ f x, y - x⟫ ≀ f y` holds. -/ +theorem add_inner_gradient_le (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hf : DifferentiableAt ℝ f x) : + f x + βŸͺβˆ‡ f x, y - x⟫ ≀ f y := by + rw [inner_gradient_left] + exact hc.add_fderiv_le hx hy hf + +/-- Monotonicity of the gradient along the chord: for convex `f` differentiable at `x` +and `y`, `0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫`. -/ +theorem inner_gradient_sub_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : + 0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ := by + rw [inner_sub_left, inner_gradient_left, inner_gradient_left, + ← ContinuousLinearMap.sub_apply] + exact hc.fderiv_sub_apply_nonneg hx hy hfx hfy + +/-- A convex function attains its minimum on `s` at any critical point: if `f` is convex on +`s`, FrΓ©chet-differentiable at `x ∈ s`, and `βˆ‡ f x = 0`, then `x` minimizes `f` on `s`. +Multi-dimensional gradient analogue of `ConvexOn.isMinOn_of_rightDeriv_eq_zero`. -/ +theorem isMinOn_of_gradient_eq_zero (hc : ConvexOn ℝ s f) (hx : x ∈ s) + (hf : DifferentiableAt ℝ f x) (hg : βˆ‡ f x = 0) : + IsMinOn f s x := fun _ hy => by + simpa [hg] using hc.add_inner_gradient_le hx hy hf + +end ConvexOn + +namespace ConcaveOn + +/-- For a concave function `f` differentiable at `x` on a Hilbert space, the reverse +first-order inequality `f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫` holds. -/ +theorem le_add_inner_gradient (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hf : DifferentiableAt ℝ f x) : + f y ≀ f x + βŸͺβˆ‡ f x, y - x⟫ := by + rw [inner_gradient_left] + exact hc.le_add_fderiv hx hy hf + +end ConcaveOn + +namespace StrictConvexOn + +/-- Strict variant of the first-order gradient inequality for strictly convex `f`. -/ +theorem add_inner_gradient_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hxy : x β‰  y) (hf : DifferentiableAt ℝ f x) : + f x + βŸͺβˆ‡ f x, y - x⟫ < f y := by + rw [inner_gradient_left] + exact hc.add_fderiv_lt hx hy hxy hf + +end StrictConvexOn + +/-- A differentiable function on a Hilbert space is convex iff it satisfies the first-order +gradient inequality at every pair of points in `s`. -/ +theorem convexOn_iff_add_inner_gradient_le (hs : Convex ℝ s) + (hf : βˆ€ x ∈ s, DifferentiableAt ℝ f x) : + ConvexOn ℝ s f ↔ βˆ€ x ∈ s, βˆ€ y ∈ s, f x + βŸͺβˆ‡ f x, y - x⟫ ≀ f y := by + rw [convexOn_iff_add_fderiv_le hs hf] + refine forall_congr' fun _ => imp_congr_right fun _ => forall_congr' fun _ => + imp_congr_right fun _ => ?_ + rw [inner_gradient_left] diff --git a/Mathlib/Analysis/Convex/LineDeriv.lean b/Mathlib/Analysis/Convex/LineDeriv.lean new file mode 100644 index 00000000000000..65e02925a5a67e --- /dev/null +++ b/Mathlib/Analysis/Convex/LineDeriv.lean @@ -0,0 +1,146 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Convex.Deriv +public import Mathlib.Analysis.Calculus.LineDeriv.Basic + +/-! +# First-order convexity inequality via the directional derivative + +For `f : E β†’ ℝ` convex on `s βŠ† E` and line-differentiable at `x ∈ s` in the direction +`y - x`, the first-order convexity inequality + +`f x + lineDeriv ℝ f x (y - x) ≀ f y` + +holds for `y ∈ s`. This is the directional-derivative form of the convex subgradient +inequality, lifted from the 1D case in `Mathlib.Analysis.Convex.Deriv` by restricting +to the line segment between `x` and `y`. + +## Main results + +* `ConvexOn.add_lineDeriv_le` β€” the first-order convexity inequality (line-derivative + form). +* `ConcaveOn.le_add_lineDeriv` β€” the concave dual. +* `ConvexOn.lineDeriv_sub_apply_nonneg` β€” monotonicity of the directional derivative: + `0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)`. +* `StrictConvexOn.add_lineDeriv_lt` β€” strict variant under `StrictConvexOn`. +* `convexOn_iff_add_lineDeriv_le` β€” iff converse: line-differentiability everywhere plus + the first-order inequality implies `ConvexOn`. +-/ + +public section + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] +variable {f : E β†’ ℝ} {s : Set E} {x y : E} + +/-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function convex on `s`, where `x, y ∈ s`, +is convex on `Icc 0 1` (the segment from `x` to `y` lies in `s` by convexity of `s`). -/ +theorem ConvexOn.lineRestriction (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) : + ConvexOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by + rw [show (fun t : ℝ => f (x + t β€’ (y - x))) = f ∘ AffineMap.lineMap x y from + funext fun t => by rw [Function.comp_apply, AffineMap.lineMap_apply_module', add_comm]] + exact (hc.comp_affineMap (AffineMap.lineMap x y)).subset + (fun t ht => hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht)) + (convex_Icc _ _) + +/-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function concave on `s`, where `x, y ∈ s`, +is concave on `Icc 0 1`. -/ +theorem ConcaveOn.lineRestriction (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) : + ConcaveOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by + rw [show (fun t : ℝ => f (x + t β€’ (y - x))) = f ∘ AffineMap.lineMap x y from + funext fun t => by rw [Function.comp_apply, AffineMap.lineMap_apply_module', add_comm]] + exact (hc.comp_affineMap (AffineMap.lineMap x y)).subset + (fun t ht => hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht)) + (convex_Icc _ _) + +namespace ConvexOn + +/-- For a convex function `f` line-differentiable at `x` in direction `y - x`, +the first-order inequality `f x + lineDeriv ℝ f x (y - x) ≀ f y` holds. -/ +theorem add_lineDeriv_le (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hf : LineDifferentiableAt ℝ f x (y - x)) : + f x + lineDeriv ℝ f x (y - x) ≀ f y := by + simpa using (hc.lineRestriction hx hy).add_hasDerivAt_mul_le + (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) + zero_lt_one hf.hasDerivAt + +/-- Monotonicity of the directional derivative along the chord: for convex `f` +line-differentiable at both endpoints in direction `y - x`, +`0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)`. -/ +theorem lineDeriv_sub_apply_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hfx : LineDifferentiableAt ℝ f x (y - x)) + (hfy : LineDifferentiableAt ℝ f y (y - x)) : + 0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) := by + have h2 := hc.add_lineDeriv_le hy hx (neg_sub y _ β–Έ neg_one_smul ℝ (y - x) β–Έ hfy.smul _) + rw [(neg_sub _ _).symm, lineDeriv_neg] at h2 + linarith [hc.add_lineDeriv_le hx hy hfx] + +end ConvexOn + +namespace ConcaveOn + +/-- For a concave function `f` line-differentiable at `x` in direction `y - x`, +the reverse first-order inequality `f y ≀ f x + lineDeriv ℝ f x (y - x)` holds. -/ +theorem le_add_lineDeriv (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hf : LineDifferentiableAt ℝ f x (y - x)) : + f y ≀ f x + lineDeriv ℝ f x (y - x) := by + simpa using (hc.lineRestriction hx hy).le_add_hasDerivAt_mul + (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) + zero_lt_one hf.hasDerivAt + +end ConcaveOn + +namespace StrictConvexOn + +/-- Strict variant of the first-order inequality for strictly convex `f`: +when `x β‰  y`, the inequality is strict. -/ +theorem add_lineDeriv_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + (hf : LineDifferentiableAt ℝ f x (y - x)) : + f x + lineDeriv ℝ f x (y - x) < f y := by + have hβ‚‚ : (0 : ℝ) < 1 / 2 := by norm_num + calc f x + lineDeriv ℝ f x (y - x) + = 2 * (f x + (1 / 2) * lineDeriv ℝ f x (y - x)) - f x := by ring + _ ≀ 2 * f (((1 : ℝ) / 2) β€’ x + ((1 : ℝ) / 2) β€’ y) - f x := by + have hm_eq : ((1 : ℝ) / 2) β€’ x + ((1 : ℝ) / 2) β€’ y - x = ((1 : ℝ) / 2) β€’ (y - x) := by + module + have h := hc.convexOn.add_lineDeriv_le hx (hc.1 hx hy hβ‚‚.le hβ‚‚.le (by norm_num)) + (hm_eq.symm β–Έ hf.smul _) + simp only [hm_eq, lineDeriv_smul, smul_eq_mul] at h + linarith + _ < 2 * ((1 / 2) * f x + (1 / 2) * f y) - f x := by + have h := hc.2 hx hy hxy hβ‚‚ hβ‚‚ (by norm_num) + simp at h + linarith + _ = f y := by ring + +end StrictConvexOn + +/-- A line-differentiable function is convex iff it satisfies the first-order inequality +at every pair of points in `s`. -/ +theorem convexOn_iff_add_lineDeriv_le (hs : Convex ℝ s) + (hf : βˆ€ x ∈ s, βˆ€ y ∈ s, LineDifferentiableAt ℝ f x (y - x)) : + ConvexOn ℝ s f ↔ + βˆ€ x ∈ s, βˆ€ y ∈ s, f x + lineDeriv ℝ f x (y - x) ≀ f y := by + refine ⟨fun hc x hx y hy => hc.add_lineDeriv_le hx hy (hf x hx y hy), fun H => ⟨hs, ?_⟩⟩ + intro x hx y hy a b ha hb hab + set z := a β€’ x + b β€’ y with hz + set L := lineDeriv ℝ f z (x - y) + change f z ≀ a β€’ f x + b β€’ f y + simp only [smul_eq_mul] + calc f z + = a * (f z + b * L) + b * (f z - a * L) := by linear_combination (f z) * hab.symm + _ ≀ a * f x + b * f y := by + have hb_eq : b = 1 - a := by linarith + have hzs : z ∈ s := hs hx hy ha hb hab + have hzx : f z + b * L ≀ f x := by + have hxz : x - z = b β€’ (x - y) := by rw [hz, hb_eq]; module + simpa only [hxz, lineDeriv_smul, smul_eq_mul] using H z hzs x hx + have hzy : f z - a * L ≀ f y := by + have hyz : y - z = -(a β€’ (x - y)) := by rw [hz, hb_eq]; module + simpa only [hyz, lineDeriv_neg, lineDeriv_smul, smul_eq_mul, ← sub_eq_add_neg] + using H z hzs y hy + exact add_le_add (mul_le_mul_of_nonneg_left hzx ha) (mul_le_mul_of_nonneg_left hzy hb) From d599d2a12ae7c659ce8a44990e2bac9caa763955 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 11:40:06 +0200 Subject: [PATCH 35/40] refactor(Analysis/Convex): apply review feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Must-fixes (1)–(3): - Add strict 1D additive forms `StrictConvexOn.add_hasDerivAt_mul_lt` and `StrictConcaveOn.lt_add_hasDerivAt_mul` (plus `deriv`-form variants) to `Convex/Deriv.lean`. - Refactor `StrictConvexOn.add_lineDeriv_lt` to use the new strict 1D additive form via `StrictConvexOn.lineRestriction` (drops the brittle midpoint `calc`). - Add `StrictConcaveOn.lt_add_lineDeriv`, `.lt_add_fderiv`, `.lt_add_inner_gradient` (missing concave strict duals across all three layers). - Add `ConvexOn.isMinOn_of_fderiv_eq_zero` (FDeriv-form sibling of the gradient one; needs only `NormedSpace ℝ E`, not Hilbert). - Add `HasLineDerivAt`- and `HasFDerivAt`-flavoured primitive forms for all inequality lemmas; the `lineDeriv` / `fderiv` versions become one-line corollaries via `LineDifferentiableAt.hasLineDerivAt` / `DifferentiableAt.hasFDerivAt`. Should-fixes (4)–(7): - Rename `_sub_apply_nonneg` β†’ `_sub_nonneg` in both LineDeriv and FDeriv; `_apply` was vestigial for the scalar `lineDeriv` and added noise for `fderiv` where the application is visible in the statement. - Drop the LineDeriv-layer iff converse (`convexOn_iff_add_lineDeriv_le`); the FDeriv-layer iff is the canonical statement users want, and its premise `βˆ€ x ∈ s, DifferentiableAt ℝ f x` is easier to instantiate than the pair-quantified line-differentiability of the dropped version. - Reprove `convexOn_iff_add_fderiv_le` directly using `fderiv`-arithmetic (no longer delegating through the dropped LineDeriv iff). - Rewrite Gradient module docstring to lead with "Hilbert space" framing. - Refactor the `β–Έ` chain in `ConvexOn.lineDeriv_sub_nonneg` to a `have` + `rw` block. Bonus: factor out `private lineMap_eq_add_smul_sub` helper. --- Mathlib/Analysis/Convex/Deriv.lean | 32 +++++ Mathlib/Analysis/Convex/FDeriv.lean | 99 ++++++++++++-- Mathlib/Analysis/Convex/Gradient.lean | 24 +++- Mathlib/Analysis/Convex/LineDeriv.lean | 178 ++++++++++++++++--------- 4 files changed, 250 insertions(+), 83 deletions(-) diff --git a/Mathlib/Analysis/Convex/Deriv.lean b/Mathlib/Analysis/Convex/Deriv.lean index a3e70d69ee05a4..f42a1ae91b387c 100644 --- a/Mathlib/Analysis/Convex/Deriv.lean +++ b/Mathlib/Analysis/Convex/Deriv.lean @@ -790,6 +790,22 @@ lemma deriv_lt_slope (hfc : StrictConvexOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S deriv f x < slope f x y := hfc.lt_slope_of_hasDerivAt hx hy hxy hfd.hasDerivAt +/-- Strict additive form of the 1D first-order convexity inequality: for `f : ℝ β†’ ℝ` strictly +convex on `S`, `x, y ∈ S` with `x < y`, and `f` differentiable at `x`, we have +`f x + f' * (y - x) < f y` where `f' = deriv f x`. -/ +lemma add_hasDerivAt_mul_lt (hfc : StrictConvexOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (ha : HasDerivAt f f' x) : + f x + f' * (y - x) < f y := by + have h := hfc.lt_slope_of_hasDerivAt hx hy hxy ha + rw [slope_def_field, lt_div_iffβ‚€ (sub_pos.mpr hxy)] at h + linarith + +/-- Reformulation of `StrictConvexOn.add_hasDerivAt_mul_lt` using `deriv`. -/ +lemma add_deriv_mul_lt (hfc : StrictConvexOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (hfd : DifferentiableAt ℝ f x) : + f x + deriv f x * (y - x) < f y := + hfc.add_hasDerivAt_mul_lt hx hy hxy hfd.hasDerivAt + end left section right @@ -1024,6 +1040,22 @@ lemma slope_lt_deriv (hfc : StrictConcaveOn ℝ S f) (hx : x ∈ S) (hy : y ∈ slope f x y < deriv f x := hfc.slope_lt_of_hasDerivAt hx hy hxy hfd.hasDerivAt +/-- Strict additive form of the 1D first-order concavity inequality: for `f : ℝ β†’ ℝ` strictly +concave on `S`, `x, y ∈ S` with `x < y`, and `f` differentiable at `x`, we have +`f y < f x + f' * (y - x)` where `f' = deriv f x`. -/ +lemma lt_add_hasDerivAt_mul (hfc : StrictConcaveOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (ha : HasDerivAt f f' x) : + f y < f x + f' * (y - x) := by + have h := hfc.slope_lt_of_hasDerivAt hx hy hxy ha + rw [slope_def_field, div_lt_iffβ‚€ (sub_pos.mpr hxy)] at h + linarith + +/-- Reformulation of `StrictConcaveOn.lt_add_hasDerivAt_mul` using `deriv`. -/ +lemma lt_add_deriv_mul (hfc : StrictConcaveOn ℝ S f) (hx : x ∈ S) (hy : y ∈ S) (hxy : x < y) + (hfd : DifferentiableAt ℝ f x) : + f y < f x + deriv f x * (y - x) := + hfc.lt_add_hasDerivAt_mul hx hy hxy hfd.hasDerivAt + end left section right diff --git a/Mathlib/Analysis/Convex/FDeriv.lean b/Mathlib/Analysis/Convex/FDeriv.lean index 63d36de0e912ae..ed6d614f6107db 100644 --- a/Mathlib/Analysis/Convex/FDeriv.lean +++ b/Mathlib/Analysis/Convex/FDeriv.lean @@ -17,14 +17,22 @@ convexity inequality `f x + (fderiv ℝ f x) (y - x) ≀ f y` holds for `y ∈ s`. This is the FrΓ©chet-derivative restatement of the line-derivative form -in `Mathlib.Analysis.Convex.LineDeriv`, lifted via `DifferentiableAt.lineDeriv_eq_fderiv`. +in `Mathlib.Analysis.Convex.LineDeriv`, lifted via `HasFDerivAt.hasLineDerivAt`. + +The `HasFDerivAt`-flavoured statements are the primitives; the `fderiv`-flavoured ones are +corollaries under `DifferentiableAt`. ## Main results -* `ConvexOn.add_fderiv_le` β€” the first-order convexity inequality (FrΓ©chet form). -* `ConcaveOn.le_add_fderiv` β€” the concave dual. -* `ConvexOn.fderiv_sub_apply_nonneg` β€” monotonicity: `0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x)`. -* `StrictConvexOn.add_fderiv_lt` β€” strict variant. +* `ConvexOn.add_hasFDerivAt_le` / `ConvexOn.add_fderiv_le` β€” the first-order convexity + inequality (FrΓ©chet form). +* `ConcaveOn.le_add_hasFDerivAt` / `ConcaveOn.le_add_fderiv` β€” the concave dual. +* `ConvexOn.fderiv_sub_nonneg` β€” monotonicity along the chord: + `0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x)`. +* `StrictConvexOn.add_hasFDerivAt_lt` / `StrictConvexOn.add_fderiv_lt` β€” strict variant. +* `StrictConcaveOn.lt_add_hasFDerivAt` / `StrictConcaveOn.lt_add_fderiv` β€” strict concave dual. +* `ConvexOn.isMinOn_of_fderiv_eq_zero` β€” convex + zero FrΓ©chet derivative at `x` ⟹ `x` + minimises `f`. * `convexOn_iff_add_fderiv_le` β€” iff converse: differentiability plus the first-order inequality everywhere implies `ConvexOn`. -/ @@ -36,51 +44,114 @@ variable {f : E β†’ ℝ} {s : Set E} {x y : E} namespace ConvexOn +/-- For a convex function `f` with FrΓ©chet derivative `f'` at `x`, the first-order inequality +`f x + f' (y - x) ≀ f y` holds. -/ +theorem add_hasFDerivAt_le (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + {f' : E β†’L[ℝ] ℝ} (hf : HasFDerivAt f f' x) : + f x + f' (y - x) ≀ f y := + hc.add_hasLineDerivAt_le hx hy (hf.hasLineDerivAt _) + /-- For a convex function `f` FrΓ©chet-differentiable at `x`, the first-order inequality `f x + (fderiv ℝ f x) (y - x) ≀ f y` holds. -/ theorem add_fderiv_le (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hf : DifferentiableAt ℝ f x) : f x + fderiv ℝ f x (y - x) ≀ f y := - hf.lineDeriv_eq_fderiv β–Έ hc.add_lineDeriv_le hx hy hf.lineDifferentiableAt + hc.add_hasFDerivAt_le hx hy hf.hasFDerivAt /-- Monotonicity of the FrΓ©chet derivative along the chord: for convex `f` differentiable at `x` and `y`, `0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x)`. -/ -theorem fderiv_sub_apply_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) +theorem fderiv_sub_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : 0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x) := by rw [ContinuousLinearMap.sub_apply, ← hfx.lineDeriv_eq_fderiv, ← hfy.lineDeriv_eq_fderiv] - exact hc.lineDeriv_sub_apply_nonneg hx hy hfx.lineDifferentiableAt hfy.lineDifferentiableAt + exact hc.lineDeriv_sub_nonneg hx hy hfx.lineDifferentiableAt hfy.lineDifferentiableAt + +/-- A convex function with a vanishing FrΓ©chet derivative at an interior point of differentiability +attains its minimum there. -/ +theorem isMinOn_of_fderiv_eq_zero (hc : ConvexOn ℝ s f) (hx : x ∈ s) + (hf : DifferentiableAt ℝ f x) (hgrad : fderiv ℝ f x = 0) : + IsMinOn f s x := + fun y hy => by simpa [hgrad] using hc.add_fderiv_le hx hy hf end ConvexOn namespace ConcaveOn +/-- For a concave function `f` with FrΓ©chet derivative `f'` at `x`, the reverse first-order +inequality `f y ≀ f x + f' (y - x)` holds. -/ +theorem le_add_hasFDerivAt (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + {f' : E β†’L[ℝ] ℝ} (hf : HasFDerivAt f f' x) : + f y ≀ f x + f' (y - x) := + hc.le_add_hasLineDerivAt hx hy (hf.hasLineDerivAt _) + /-- For a concave function `f` FrΓ©chet-differentiable at `x`, the reverse first-order inequality `f y ≀ f x + (fderiv ℝ f x) (y - x)` holds. -/ theorem le_add_fderiv (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hf : DifferentiableAt ℝ f x) : f y ≀ f x + fderiv ℝ f x (y - x) := - hf.lineDeriv_eq_fderiv β–Έ hc.le_add_lineDeriv hx hy hf.lineDifferentiableAt + hc.le_add_hasFDerivAt hx hy hf.hasFDerivAt end ConcaveOn namespace StrictConvexOn +/-- Strict variant of the first-order inequality for strictly convex `f` with FrΓ©chet derivative +`f'` at `x`, assuming `x β‰  y`: `f x + f' (y - x) < f y`. -/ +theorem add_hasFDerivAt_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + {f' : E β†’L[ℝ] ℝ} (hf : HasFDerivAt f f' x) : + f x + f' (y - x) < f y := + hc.add_hasLineDerivAt_lt hx hy hxy (hf.hasLineDerivAt _) + /-- Strict variant of the first-order inequality for strictly convex `f`: when `x β‰  y`, the inequality is strict. -/ theorem add_fderiv_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) (hf : DifferentiableAt ℝ f x) : f x + fderiv ℝ f x (y - x) < f y := - hf.lineDeriv_eq_fderiv β–Έ hc.add_lineDeriv_lt hx hy hxy hf.lineDifferentiableAt + hc.add_hasFDerivAt_lt hx hy hxy hf.hasFDerivAt end StrictConvexOn +namespace StrictConcaveOn + +/-- Strict variant of the reverse first-order inequality for strictly concave `f` with FrΓ©chet +derivative `f'` at `x`, assuming `x β‰  y`: `f y < f x + f' (y - x)`. -/ +theorem lt_add_hasFDerivAt (hc : StrictConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + {f' : E β†’L[ℝ] ℝ} (hf : HasFDerivAt f f' x) : + f y < f x + f' (y - x) := + hc.lt_add_hasLineDerivAt hx hy hxy (hf.hasLineDerivAt _) + +/-- Strict variant of the reverse first-order inequality for strictly concave `f`: when `x β‰  y`, +the inequality is strict. -/ +theorem lt_add_fderiv (hc : StrictConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + (hf : DifferentiableAt ℝ f x) : + f y < f x + fderiv ℝ f x (y - x) := + hc.lt_add_hasFDerivAt hx hy hxy hf.hasFDerivAt + +end StrictConcaveOn + /-- A differentiable function is convex iff it satisfies the first-order inequality at every pair of points in `s`. -/ theorem convexOn_iff_add_fderiv_le (hs : Convex ℝ s) (hf : βˆ€ x ∈ s, DifferentiableAt ℝ f x) : ConvexOn ℝ s f ↔ βˆ€ x ∈ s, βˆ€ y ∈ s, f x + fderiv ℝ f x (y - x) ≀ f y := by - rw [convexOn_iff_add_lineDeriv_le hs fun x hx _ _ => (hf x hx).lineDifferentiableAt] - refine forall_congr' fun x => imp_congr_right fun hx => forall_congr' fun _ => - imp_congr_right fun _ => ?_ - rw [(hf x hx).lineDeriv_eq_fderiv] + refine ⟨fun hc x hx y hy => hc.add_fderiv_le hx hy (hf x hx), fun H => ⟨hs, ?_⟩⟩ + intro x hx y hy a b ha hb hab + set z := a β€’ x + b β€’ y with hz + set L := fderiv ℝ f z (x - y) with hL + change f z ≀ a β€’ f x + b β€’ f y + simp only [smul_eq_mul] + have hzs : z ∈ s := hs hx hy ha hb hab + have hb_eq : b = 1 - a := by linarith + have hxz : x - z = b β€’ (x - y) := by rw [hz, hb_eq]; module + have hyz : y - z = -(a β€’ (x - y)) := by rw [hz, hb_eq]; module + have hzx : f z + b * L ≀ f x := by + have h := H z hzs x hx + rwa [hxz, (fderiv ℝ f z).map_smul, smul_eq_mul] at h + have hzy : f z - a * L ≀ f y := by + have h := H z hzs y hy + rw [hyz, map_neg, (fderiv ℝ f z).map_smul, smul_eq_mul] at h + linarith + calc f z + = a * (f z + b * L) + b * (f z - a * L) := by linear_combination (f z) * hab.symm + _ ≀ a * f x + b * f y := + add_le_add (mul_le_mul_of_nonneg_left hzx ha) (mul_le_mul_of_nonneg_left hzy hb) diff --git a/Mathlib/Analysis/Convex/Gradient.lean b/Mathlib/Analysis/Convex/Gradient.lean index f1621b418411c8..c7c125f4f8c1b9 100644 --- a/Mathlib/Analysis/Convex/Gradient.lean +++ b/Mathlib/Analysis/Convex/Gradient.lean @@ -11,21 +11,24 @@ public import Mathlib.Analysis.Calculus.Gradient.Basic /-! # First-order convexity inequality via the gradient -For `f : F β†’ ℝ` convex on `s βŠ† F` on a Hilbert space and differentiable at `x ∈ s`, +On a Hilbert space `F`, for `f : F β†’ ℝ` convex on `s βŠ† F` and differentiable at `x ∈ s`, the first-order convexity inequality `f x + βŸͺβˆ‡ f x, y - x⟫ ≀ f y` holds for `y ∈ s`. This is the gradient/inner-product restatement of the FrΓ©chet form -in `Mathlib.Analysis.Convex.FDeriv`, lifted via `inner_gradient_left`. +in `Mathlib.Analysis.Convex.FDeriv`, lifted via Riesz representation +(`inner_gradient_left`). ## Main results * `ConvexOn.add_inner_gradient_le` β€” the first-order convexity inequality (gradient form). * `ConcaveOn.le_add_inner_gradient` β€” the concave dual. -* `ConvexOn.inner_gradient_sub_nonneg` β€” monotonicity: `0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫`. -* `ConvexOn.isMinOn_of_gradient_eq_zero` β€” convex + zero gradient at `x` ⟹ `x` minimizes `f`. +* `ConvexOn.inner_gradient_sub_nonneg` β€” monotonicity along the chord: + `0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫`. +* `ConvexOn.isMinOn_of_gradient_eq_zero` β€” convex + zero gradient at `x` ⟹ `x` minimises `f`. * `StrictConvexOn.add_inner_gradient_lt` β€” strict variant. +* `StrictConcaveOn.lt_add_inner_gradient` β€” strict concave dual. * `convexOn_iff_add_inner_gradient_le` β€” iff converse. -/ @@ -54,7 +57,7 @@ theorem inner_gradient_sub_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y 0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ := by rw [inner_sub_left, inner_gradient_left, inner_gradient_left, ← ContinuousLinearMap.sub_apply] - exact hc.fderiv_sub_apply_nonneg hx hy hfx hfy + exact hc.fderiv_sub_nonneg hx hy hfx hfy /-- A convex function attains its minimum on `s` at any critical point: if `f` is convex on `s`, FrΓ©chet-differentiable at `x ∈ s`, and `βˆ‡ f x = 0`, then `x` minimizes `f` on `s`. @@ -89,6 +92,17 @@ theorem add_inner_gradient_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : end StrictConvexOn +namespace StrictConcaveOn + +/-- Strict variant of the reverse first-order gradient inequality for strictly concave `f`. -/ +theorem lt_add_inner_gradient (hc : StrictConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hxy : x β‰  y) (hf : DifferentiableAt ℝ f x) : + f y < f x + βŸͺβˆ‡ f x, y - x⟫ := by + rw [inner_gradient_left] + exact hc.lt_add_fderiv hx hy hxy hf + +end StrictConcaveOn + /-- A differentiable function on a Hilbert space is convex iff it satisfies the first-order gradient inequality at every pair of points in `s`. -/ theorem convexOn_iff_add_inner_gradient_le (hs : Convex ℝ s) diff --git a/Mathlib/Analysis/Convex/LineDeriv.lean b/Mathlib/Analysis/Convex/LineDeriv.lean index 65e02925a5a67e..bfb3b38fe6ed7e 100644 --- a/Mathlib/Analysis/Convex/LineDeriv.lean +++ b/Mathlib/Analysis/Convex/LineDeriv.lean @@ -20,16 +20,24 @@ holds for `y ∈ s`. This is the directional-derivative form of the convex subgr inequality, lifted from the 1D case in `Mathlib.Analysis.Convex.Deriv` by restricting to the line segment between `x` and `y`. +The `HasLineDerivAt`-flavoured statements are the primitives; the `lineDeriv`-flavoured +ones are corollaries under `LineDifferentiableAt`. + ## Main results -* `ConvexOn.add_lineDeriv_le` β€” the first-order convexity inequality (line-derivative - form). -* `ConcaveOn.le_add_lineDeriv` β€” the concave dual. -* `ConvexOn.lineDeriv_sub_apply_nonneg` β€” monotonicity of the directional derivative: - `0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)`. -* `StrictConvexOn.add_lineDeriv_lt` β€” strict variant under `StrictConvexOn`. -* `convexOn_iff_add_lineDeriv_le` β€” iff converse: line-differentiability everywhere plus - the first-order inequality implies `ConvexOn`. +* `ConvexOn.add_hasLineDerivAt_le` / `ConvexOn.add_lineDeriv_le` β€” the first-order + convexity inequality (line-derivative form). +* `ConcaveOn.le_add_hasLineDerivAt` / `ConcaveOn.le_add_lineDeriv` β€” the concave dual. +* `ConvexOn.lineDeriv_sub_nonneg` β€” monotonicity of the directional derivative along the + chord: `0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)`. +* `StrictConvexOn.add_hasLineDerivAt_lt` / `StrictConvexOn.add_lineDeriv_lt` β€” strict + variant under `StrictConvexOn`. +* `StrictConcaveOn.lt_add_hasLineDerivAt` / `StrictConcaveOn.lt_add_lineDeriv` β€” strict + concave dual. + +The iff converse to the first-order inequality lives at the FrΓ©chet layer +(`convexOn_iff_add_fderiv_le` in `Mathlib.Analysis.Convex.FDeriv`); the LineDeriv layer +contains only forward implications. -/ public section @@ -37,12 +45,16 @@ public section variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] variable {f : E β†’ ℝ} {s : Set E} {x y : E} +private theorem lineMap_eq_add_smul_sub (x y : E) (t : ℝ) : + AffineMap.lineMap x y t = x + t β€’ (y - x) := by + rw [AffineMap.lineMap_apply_module']; abel + /-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function convex on `s`, where `x, y ∈ s`, is convex on `Icc 0 1` (the segment from `x` to `y` lies in `s` by convexity of `s`). -/ theorem ConvexOn.lineRestriction (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) : ConvexOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by rw [show (fun t : ℝ => f (x + t β€’ (y - x))) = f ∘ AffineMap.lineMap x y from - funext fun t => by rw [Function.comp_apply, AffineMap.lineMap_apply_module', add_comm]] + funext fun t => by rw [Function.comp_apply, lineMap_eq_add_smul_sub]] exact (hc.comp_affineMap (AffineMap.lineMap x y)).subset (fun t ht => hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht)) (convex_Icc _ _) @@ -52,95 +64,133 @@ is concave on `Icc 0 1`. -/ theorem ConcaveOn.lineRestriction (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) : ConcaveOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by rw [show (fun t : ℝ => f (x + t β€’ (y - x))) = f ∘ AffineMap.lineMap x y from - funext fun t => by rw [Function.comp_apply, AffineMap.lineMap_apply_module', add_comm]] + funext fun t => by rw [Function.comp_apply, lineMap_eq_add_smul_sub]] exact (hc.comp_affineMap (AffineMap.lineMap x y)).subset (fun t ht => hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht)) (convex_Icc _ _) +/-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function strictly convex on `s`, with +`x β‰  y` both in `s`, is strictly convex on `Icc 0 1`. -/ +theorem StrictConvexOn.lineRestriction (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hxy : x β‰  y) : + StrictConvexOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by + refine ⟨convex_Icc _ _, fun t₁ ht₁ tβ‚‚ htβ‚‚ ht_ne a b ha hb hab => ?_⟩ + have hsub : (y - x : E) β‰  0 := sub_ne_zero.mpr hxy.symm + have hp_ne : x + t₁ β€’ (y - x) β‰  x + tβ‚‚ β€’ (y - x) := fun h => + ht_ne (smul_left_injective ℝ hsub (add_left_cancel h)) + have hp₁ : x + t₁ β€’ (y - x) ∈ s := by + rw [← lineMap_eq_add_smul_sub] + exact hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht₁) + have hpβ‚‚ : x + tβ‚‚ β€’ (y - x) ∈ s := by + rw [← lineMap_eq_add_smul_sub] + exact hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y htβ‚‚) + have hb_eq : b = 1 - a := by linarith + have hcomb : a β€’ (x + t₁ β€’ (y - x)) + b β€’ (x + tβ‚‚ β€’ (y - x)) + = x + (a β€’ t₁ + b β€’ tβ‚‚) β€’ (y - x) := by + rw [hb_eq]; module + have key := hc.2 hp₁ hpβ‚‚ hp_ne ha hb hab + rw [hcomb] at key + exact key + +/-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function strictly concave on `s`, with +`x β‰  y` both in `s`, is strictly concave on `Icc 0 1`. -/ +theorem StrictConcaveOn.lineRestriction (hc : StrictConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + (hxy : x β‰  y) : + StrictConcaveOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by + have hneg : StrictConvexOn ℝ (Set.Icc 0 1) (fun t : ℝ => -f (x + t β€’ (y - x))) := by + simpa using hc.neg.lineRestriction hx hy hxy + simpa [Pi.neg_def] using hneg.neg + namespace ConvexOn +/-- For a convex function `f` with line derivative `f'` at `x` in direction `y - x`, +the first-order inequality `f x + f' ≀ f y` holds. -/ +theorem add_hasLineDerivAt_le (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + {f' : ℝ} (hf : HasLineDerivAt ℝ f f' x (y - x)) : + f x + f' ≀ f y := by + simpa using (hc.lineRestriction hx hy).add_hasDerivAt_mul_le + (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) + zero_lt_one hf + /-- For a convex function `f` line-differentiable at `x` in direction `y - x`, the first-order inequality `f x + lineDeriv ℝ f x (y - x) ≀ f y` holds. -/ theorem add_lineDeriv_le (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hf : LineDifferentiableAt ℝ f x (y - x)) : - f x + lineDeriv ℝ f x (y - x) ≀ f y := by - simpa using (hc.lineRestriction hx hy).add_hasDerivAt_mul_le - (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) - zero_lt_one hf.hasDerivAt + f x + lineDeriv ℝ f x (y - x) ≀ f y := + hc.add_hasLineDerivAt_le hx hy hf.hasLineDerivAt /-- Monotonicity of the directional derivative along the chord: for convex `f` line-differentiable at both endpoints in direction `y - x`, `0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)`. -/ -theorem lineDeriv_sub_apply_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) +theorem lineDeriv_sub_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hfx : LineDifferentiableAt ℝ f x (y - x)) (hfy : LineDifferentiableAt ℝ f y (y - x)) : 0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) := by - have h2 := hc.add_lineDeriv_le hy hx (neg_sub y _ β–Έ neg_one_smul ℝ (y - x) β–Έ hfy.smul _) - rw [(neg_sub _ _).symm, lineDeriv_neg] at h2 + have hfy' : LineDifferentiableAt ℝ f y (x - y) := by + have := hfy.smul (-1 : ℝ) + rwa [neg_one_smul, neg_sub] at this + have hβ‚‚ := hc.add_lineDeriv_le hy hx hfy' + rw [← neg_sub y x, lineDeriv_neg] at hβ‚‚ linarith [hc.add_lineDeriv_le hx hy hfx] end ConvexOn namespace ConcaveOn +/-- For a concave function `f` with line derivative `f'` at `x` in direction `y - x`, +the reverse first-order inequality `f y ≀ f x + f'` holds. -/ +theorem le_add_hasLineDerivAt (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) + {f' : ℝ} (hf : HasLineDerivAt ℝ f f' x (y - x)) : + f y ≀ f x + f' := by + simpa using (hc.lineRestriction hx hy).le_add_hasDerivAt_mul + (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) + zero_lt_one hf + /-- For a concave function `f` line-differentiable at `x` in direction `y - x`, the reverse first-order inequality `f y ≀ f x + lineDeriv ℝ f x (y - x)` holds. -/ theorem le_add_lineDeriv (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hf : LineDifferentiableAt ℝ f x (y - x)) : - f y ≀ f x + lineDeriv ℝ f x (y - x) := by - simpa using (hc.lineRestriction hx hy).le_add_hasDerivAt_mul - (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) - zero_lt_one hf.hasDerivAt + f y ≀ f x + lineDeriv ℝ f x (y - x) := + hc.le_add_hasLineDerivAt hx hy hf.hasLineDerivAt end ConcaveOn namespace StrictConvexOn -/-- Strict variant of the first-order inequality for strictly convex `f`: -when `x β‰  y`, the inequality is strict. -/ +/-- Strict variant of the first-order inequality for strictly convex `f` with line derivative +`f'` at `x` in direction `y - x`, assuming `x β‰  y`: `f x + f' < f y`. -/ +theorem add_hasLineDerivAt_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + {f' : ℝ} (hf : HasLineDerivAt ℝ f f' x (y - x)) : + f x + f' < f y := by + simpa using (hc.lineRestriction hx hy hxy).add_hasDerivAt_mul_lt + (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) + zero_lt_one hf + +/-- Strict variant of the first-order inequality for strictly convex `f`: when `x β‰  y` and `f` +is line-differentiable at `x` in direction `y - x`, the inequality is strict. -/ theorem add_lineDeriv_lt (hc : StrictConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) (hf : LineDifferentiableAt ℝ f x (y - x)) : - f x + lineDeriv ℝ f x (y - x) < f y := by - have hβ‚‚ : (0 : ℝ) < 1 / 2 := by norm_num - calc f x + lineDeriv ℝ f x (y - x) - = 2 * (f x + (1 / 2) * lineDeriv ℝ f x (y - x)) - f x := by ring - _ ≀ 2 * f (((1 : ℝ) / 2) β€’ x + ((1 : ℝ) / 2) β€’ y) - f x := by - have hm_eq : ((1 : ℝ) / 2) β€’ x + ((1 : ℝ) / 2) β€’ y - x = ((1 : ℝ) / 2) β€’ (y - x) := by - module - have h := hc.convexOn.add_lineDeriv_le hx (hc.1 hx hy hβ‚‚.le hβ‚‚.le (by norm_num)) - (hm_eq.symm β–Έ hf.smul _) - simp only [hm_eq, lineDeriv_smul, smul_eq_mul] at h - linarith - _ < 2 * ((1 / 2) * f x + (1 / 2) * f y) - f x := by - have h := hc.2 hx hy hxy hβ‚‚ hβ‚‚ (by norm_num) - simp at h - linarith - _ = f y := by ring + f x + lineDeriv ℝ f x (y - x) < f y := + hc.add_hasLineDerivAt_lt hx hy hxy hf.hasLineDerivAt end StrictConvexOn -/-- A line-differentiable function is convex iff it satisfies the first-order inequality -at every pair of points in `s`. -/ -theorem convexOn_iff_add_lineDeriv_le (hs : Convex ℝ s) - (hf : βˆ€ x ∈ s, βˆ€ y ∈ s, LineDifferentiableAt ℝ f x (y - x)) : - ConvexOn ℝ s f ↔ - βˆ€ x ∈ s, βˆ€ y ∈ s, f x + lineDeriv ℝ f x (y - x) ≀ f y := by - refine ⟨fun hc x hx y hy => hc.add_lineDeriv_le hx hy (hf x hx y hy), fun H => ⟨hs, ?_⟩⟩ - intro x hx y hy a b ha hb hab - set z := a β€’ x + b β€’ y with hz - set L := lineDeriv ℝ f z (x - y) - change f z ≀ a β€’ f x + b β€’ f y - simp only [smul_eq_mul] - calc f z - = a * (f z + b * L) + b * (f z - a * L) := by linear_combination (f z) * hab.symm - _ ≀ a * f x + b * f y := by - have hb_eq : b = 1 - a := by linarith - have hzs : z ∈ s := hs hx hy ha hb hab - have hzx : f z + b * L ≀ f x := by - have hxz : x - z = b β€’ (x - y) := by rw [hz, hb_eq]; module - simpa only [hxz, lineDeriv_smul, smul_eq_mul] using H z hzs x hx - have hzy : f z - a * L ≀ f y := by - have hyz : y - z = -(a β€’ (x - y)) := by rw [hz, hb_eq]; module - simpa only [hyz, lineDeriv_neg, lineDeriv_smul, smul_eq_mul, ← sub_eq_add_neg] - using H z hzs y hy - exact add_le_add (mul_le_mul_of_nonneg_left hzx ha) (mul_le_mul_of_nonneg_left hzy hb) +namespace StrictConcaveOn + +/-- Strict variant of the reverse first-order inequality for strictly concave `f` with line +derivative `f'` at `x` in direction `y - x`, assuming `x β‰  y`: `f y < f x + f'`. -/ +theorem lt_add_hasLineDerivAt (hc : StrictConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + {f' : ℝ} (hf : HasLineDerivAt ℝ f f' x (y - x)) : + f y < f x + f' := by + simpa using (hc.lineRestriction hx hy hxy).lt_add_hasDerivAt_mul + (Set.left_mem_Icc.mpr zero_le_one) (Set.right_mem_Icc.mpr zero_le_one) + zero_lt_one hf + +/-- Strict variant of the reverse first-order inequality for strictly concave `f`: when `x β‰  y` +and `f` is line-differentiable at `x` in direction `y - x`, the inequality is strict. -/ +theorem lt_add_lineDeriv (hc : StrictConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hxy : x β‰  y) + (hf : LineDifferentiableAt ℝ f x (y - x)) : + f y < f x + lineDeriv ℝ f x (y - x) := + hc.lt_add_hasLineDerivAt hx hy hxy hf.hasLineDerivAt + +end StrictConcaveOn From 53d5f074cbdbdde3968e7c0a80effca6148c10ba Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 15:28:24 +0200 Subject: [PATCH 36/40] chore(Analysis/Convex): trim main-results lists to the main statements Concave duals and strict variants are systematic companions, not main results; fold them into one prose line per module docstring. --- Mathlib/Analysis/Convex/FDeriv.lean | 14 +++++--------- Mathlib/Analysis/Convex/Gradient.lean | 10 ++++------ Mathlib/Analysis/Convex/LineDeriv.lean | 13 +++++-------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/Mathlib/Analysis/Convex/FDeriv.lean b/Mathlib/Analysis/Convex/FDeriv.lean index ed6d614f6107db..1a5d30d1ca46c2 100644 --- a/Mathlib/Analysis/Convex/FDeriv.lean +++ b/Mathlib/Analysis/Convex/FDeriv.lean @@ -24,17 +24,13 @@ corollaries under `DifferentiableAt`. ## Main results -* `ConvexOn.add_hasFDerivAt_le` / `ConvexOn.add_fderiv_le` β€” the first-order convexity - inequality (FrΓ©chet form). -* `ConcaveOn.le_add_hasFDerivAt` / `ConcaveOn.le_add_fderiv` β€” the concave dual. -* `ConvexOn.fderiv_sub_nonneg` β€” monotonicity along the chord: - `0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x)`. -* `StrictConvexOn.add_hasFDerivAt_lt` / `StrictConvexOn.add_fderiv_lt` β€” strict variant. -* `StrictConcaveOn.lt_add_hasFDerivAt` / `StrictConcaveOn.lt_add_fderiv` β€” strict concave dual. -* `ConvexOn.isMinOn_of_fderiv_eq_zero` β€” convex + zero FrΓ©chet derivative at `x` ⟹ `x` - minimises `f`. +* `ConvexOn.add_fderiv_le` β€” the first-order convexity inequality (FrΓ©chet form). +* `ConvexOn.fderiv_sub_nonneg` β€” monotonicity along the chord. +* `ConvexOn.isMinOn_of_fderiv_eq_zero` β€” the first-order optimality condition. * `convexOn_iff_add_fderiv_le` β€” iff converse: differentiability plus the first-order inequality everywhere implies `ConvexOn`. + +Concave duals and strict variants are provided alongside. -/ public section diff --git a/Mathlib/Analysis/Convex/Gradient.lean b/Mathlib/Analysis/Convex/Gradient.lean index c7c125f4f8c1b9..0440d70c80b923 100644 --- a/Mathlib/Analysis/Convex/Gradient.lean +++ b/Mathlib/Analysis/Convex/Gradient.lean @@ -23,13 +23,11 @@ in `Mathlib.Analysis.Convex.FDeriv`, lifted via Riesz representation ## Main results * `ConvexOn.add_inner_gradient_le` β€” the first-order convexity inequality (gradient form). -* `ConcaveOn.le_add_inner_gradient` β€” the concave dual. -* `ConvexOn.inner_gradient_sub_nonneg` β€” monotonicity along the chord: - `0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫`. -* `ConvexOn.isMinOn_of_gradient_eq_zero` β€” convex + zero gradient at `x` ⟹ `x` minimises `f`. -* `StrictConvexOn.add_inner_gradient_lt` β€” strict variant. -* `StrictConcaveOn.lt_add_inner_gradient` β€” strict concave dual. +* `ConvexOn.inner_gradient_sub_nonneg` β€” gradient monotonicity along the chord. +* `ConvexOn.isMinOn_of_gradient_eq_zero` β€” the first-order optimality condition. * `convexOn_iff_add_inner_gradient_le` β€” iff converse. + +Concave duals and strict variants are provided alongside. -/ public section diff --git a/Mathlib/Analysis/Convex/LineDeriv.lean b/Mathlib/Analysis/Convex/LineDeriv.lean index bfb3b38fe6ed7e..7db828a2f6e780 100644 --- a/Mathlib/Analysis/Convex/LineDeriv.lean +++ b/Mathlib/Analysis/Convex/LineDeriv.lean @@ -25,15 +25,12 @@ ones are corollaries under `LineDifferentiableAt`. ## Main results -* `ConvexOn.add_hasLineDerivAt_le` / `ConvexOn.add_lineDeriv_le` β€” the first-order - convexity inequality (line-derivative form). -* `ConcaveOn.le_add_hasLineDerivAt` / `ConcaveOn.le_add_lineDeriv` β€” the concave dual. +* `ConvexOn.add_lineDeriv_le` β€” the first-order convexity inequality + (line-derivative form). * `ConvexOn.lineDeriv_sub_nonneg` β€” monotonicity of the directional derivative along the - chord: `0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x)`. -* `StrictConvexOn.add_hasLineDerivAt_lt` / `StrictConvexOn.add_lineDeriv_lt` β€” strict - variant under `StrictConvexOn`. -* `StrictConcaveOn.lt_add_hasLineDerivAt` / `StrictConcaveOn.lt_add_lineDeriv` β€” strict - concave dual. + chord. + +Concave duals and strict variants are provided alongside. The iff converse to the first-order inequality lives at the FrΓ©chet layer (`convexOn_iff_add_fderiv_le` in `Mathlib.Analysis.Convex.FDeriv`); the LineDeriv layer From 0c21f15a88c67c69bd7c5cd4f75524c15d3e9298 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 15:46:30 +0200 Subject: [PATCH 37/40] refactor(Analysis/Convex): tighten proofs - replace have/rwa-at chains with simpa only ... using - drop a no-op change + simp only [smul_eq_mul] pair in convexOn_iff_add_fderiv_le (the calc closes the smul goal by defeq) - derive ConcaveOn.lineRestriction by neg-duality, matching the StrictConcaveOn version; factor the duplicated membership argument in StrictConvexOn.lineRestriction - simp_rw [inner_gradient_left] instead of a forall_congr'/imp_congr_right chain in convexOn_iff_add_inner_gradient_le --- Mathlib/Analysis/Convex/FDeriv.lean | 15 +++------ Mathlib/Analysis/Convex/Gradient.lean | 4 +-- Mathlib/Analysis/Convex/LineDeriv.lean | 43 +++++++++----------------- 3 files changed, 20 insertions(+), 42 deletions(-) diff --git a/Mathlib/Analysis/Convex/FDeriv.lean b/Mathlib/Analysis/Convex/FDeriv.lean index 1a5d30d1ca46c2..87fbf8d291bf07 100644 --- a/Mathlib/Analysis/Convex/FDeriv.lean +++ b/Mathlib/Analysis/Convex/FDeriv.lean @@ -133,20 +133,15 @@ theorem convexOn_iff_add_fderiv_le (hs : Convex ℝ s) (hf : βˆ€ x ∈ s, Differ refine ⟨fun hc x hx y hy => hc.add_fderiv_le hx hy (hf x hx), fun H => ⟨hs, ?_⟩⟩ intro x hx y hy a b ha hb hab set z := a β€’ x + b β€’ y with hz - set L := fderiv ℝ f z (x - y) with hL - change f z ≀ a β€’ f x + b β€’ f y - simp only [smul_eq_mul] + set L := fderiv ℝ f z (x - y) have hzs : z ∈ s := hs hx hy ha hb hab have hb_eq : b = 1 - a := by linarith - have hxz : x - z = b β€’ (x - y) := by rw [hz, hb_eq]; module - have hyz : y - z = -(a β€’ (x - y)) := by rw [hz, hb_eq]; module have hzx : f z + b * L ≀ f x := by - have h := H z hzs x hx - rwa [hxz, (fderiv ℝ f z).map_smul, smul_eq_mul] at h + simpa only [show x - z = b β€’ (x - y) by rw [hz, hb_eq]; module, map_smul, smul_eq_mul] + using H z hzs x hx have hzy : f z - a * L ≀ f y := by - have h := H z hzs y hy - rw [hyz, map_neg, (fderiv ℝ f z).map_smul, smul_eq_mul] at h - linarith + simpa only [show y - z = -(a β€’ (x - y)) by rw [hz, hb_eq]; module, map_neg, map_smul, + smul_eq_mul, ← sub_eq_add_neg] using H z hzs y hy calc f z = a * (f z + b * L) + b * (f z - a * L) := by linear_combination (f z) * hab.symm _ ≀ a * f x + b * f y := diff --git a/Mathlib/Analysis/Convex/Gradient.lean b/Mathlib/Analysis/Convex/Gradient.lean index 0440d70c80b923..de10b519d6594f 100644 --- a/Mathlib/Analysis/Convex/Gradient.lean +++ b/Mathlib/Analysis/Convex/Gradient.lean @@ -107,6 +107,4 @@ theorem convexOn_iff_add_inner_gradient_le (hs : Convex ℝ s) (hf : βˆ€ x ∈ s, DifferentiableAt ℝ f x) : ConvexOn ℝ s f ↔ βˆ€ x ∈ s, βˆ€ y ∈ s, f x + βŸͺβˆ‡ f x, y - x⟫ ≀ f y := by rw [convexOn_iff_add_fderiv_le hs hf] - refine forall_congr' fun _ => imp_congr_right fun _ => forall_congr' fun _ => - imp_congr_right fun _ => ?_ - rw [inner_gradient_left] + simp_rw [inner_gradient_left] diff --git a/Mathlib/Analysis/Convex/LineDeriv.lean b/Mathlib/Analysis/Convex/LineDeriv.lean index 7db828a2f6e780..bf5b50cc44f9f3 100644 --- a/Mathlib/Analysis/Convex/LineDeriv.lean +++ b/Mathlib/Analysis/Convex/LineDeriv.lean @@ -50,21 +50,15 @@ private theorem lineMap_eq_add_smul_sub (x y : E) (t : ℝ) : is convex on `Icc 0 1` (the segment from `x` to `y` lies in `s` by convexity of `s`). -/ theorem ConvexOn.lineRestriction (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) : ConvexOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by - rw [show (fun t : ℝ => f (x + t β€’ (y - x))) = f ∘ AffineMap.lineMap x y from - funext fun t => by rw [Function.comp_apply, lineMap_eq_add_smul_sub]] - exact (hc.comp_affineMap (AffineMap.lineMap x y)).subset - (fun t ht => hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht)) - (convex_Icc _ _) + simpa only [Function.comp_def, lineMap_eq_add_smul_sub] using + (hc.comp_affineMap (AffineMap.lineMap x y)).subset + (fun t ht => hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht)) (convex_Icc _ _) /-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function concave on `s`, where `x, y ∈ s`, is concave on `Icc 0 1`. -/ theorem ConcaveOn.lineRestriction (hc : ConcaveOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) : ConcaveOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by - rw [show (fun t : ℝ => f (x + t β€’ (y - x))) = f ∘ AffineMap.lineMap x y from - funext fun t => by rw [Function.comp_apply, lineMap_eq_add_smul_sub]] - exact (hc.comp_affineMap (AffineMap.lineMap x y)).subset - (fun t ht => hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht)) - (convex_Icc _ _) + simpa [Pi.neg_def] using (hc.neg.lineRestriction hx hy).neg /-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function strictly convex on `s`, with `x β‰  y` both in `s`, is strictly convex on `Icc 0 1`. -/ @@ -72,22 +66,13 @@ theorem StrictConvexOn.lineRestriction (hc : StrictConvexOn ℝ s f) (hx : x ∈ (hxy : x β‰  y) : StrictConvexOn ℝ (Set.Icc 0 1) (fun t : ℝ => f (x + t β€’ (y - x))) := by refine ⟨convex_Icc _ _, fun t₁ ht₁ tβ‚‚ htβ‚‚ ht_ne a b ha hb hab => ?_⟩ - have hsub : (y - x : E) β‰  0 := sub_ne_zero.mpr hxy.symm + have hmem : βˆ€ t ∈ Set.Icc (0 : ℝ) 1, x + t β€’ (y - x) ∈ s := fun t ht => + lineMap_eq_add_smul_sub x y t β–Έ hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht) have hp_ne : x + t₁ β€’ (y - x) β‰  x + tβ‚‚ β€’ (y - x) := fun h => - ht_ne (smul_left_injective ℝ hsub (add_left_cancel h)) - have hp₁ : x + t₁ β€’ (y - x) ∈ s := by - rw [← lineMap_eq_add_smul_sub] - exact hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y ht₁) - have hpβ‚‚ : x + tβ‚‚ β€’ (y - x) ∈ s := by - rw [← lineMap_eq_add_smul_sub] - exact hc.1.segment_subset hx hy (lineMap_mem_segment ℝ x y htβ‚‚) - have hb_eq : b = 1 - a := by linarith - have hcomb : a β€’ (x + t₁ β€’ (y - x)) + b β€’ (x + tβ‚‚ β€’ (y - x)) - = x + (a β€’ t₁ + b β€’ tβ‚‚) β€’ (y - x) := by - rw [hb_eq]; module - have key := hc.2 hp₁ hpβ‚‚ hp_ne ha hb hab - rw [hcomb] at key - exact key + ht_ne (smul_left_injective ℝ (sub_ne_zero.mpr hxy.symm) (add_left_cancel h)) + simpa only [show a β€’ (x + t₁ β€’ (y - x)) + b β€’ (x + tβ‚‚ β€’ (y - x)) + = x + (a β€’ t₁ + b β€’ tβ‚‚) β€’ (y - x) by rw [show b = 1 - a by linarith]; module] + using hc.2 (hmem t₁ ht₁) (hmem tβ‚‚ htβ‚‚) hp_ne ha hb hab /-- The 1D restriction `t ↦ f (x + t β€’ (y - x))` of a function strictly concave on `s`, with `x β‰  y` both in `s`, is strictly concave on `Icc 0 1`. -/ @@ -124,10 +109,10 @@ theorem lineDeriv_sub_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ (hfy : LineDifferentiableAt ℝ f y (y - x)) : 0 ≀ lineDeriv ℝ f y (y - x) - lineDeriv ℝ f x (y - x) := by have hfy' : LineDifferentiableAt ℝ f y (x - y) := by - have := hfy.smul (-1 : ℝ) - rwa [neg_one_smul, neg_sub] at this - have hβ‚‚ := hc.add_lineDeriv_le hy hx hfy' - rw [← neg_sub y x, lineDeriv_neg] at hβ‚‚ + simpa only [neg_one_smul, neg_sub] using hfy.smul (-1 : ℝ) + have hβ‚‚ : f y - lineDeriv ℝ f y (y - x) ≀ f x := by + simpa only [← neg_sub y x, lineDeriv_neg, ← sub_eq_add_neg] + using hc.add_lineDeriv_le hy hx hfy' linarith [hc.add_lineDeriv_le hx hy hfx] end ConvexOn From a9a383ff18f119cb14a2231a72deeb6655e7df83 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Wed, 8 Jul 2026 15:50:27 +0200 Subject: [PATCH 38/40] chore(Analysis/Convex): ContinuousLinearMap.sub_apply -> sub_apply (deprecation) --- Mathlib/Analysis/Convex/FDeriv.lean | 2 +- Mathlib/Analysis/Convex/Gradient.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/Convex/FDeriv.lean b/Mathlib/Analysis/Convex/FDeriv.lean index 87fbf8d291bf07..41b093638809c2 100644 --- a/Mathlib/Analysis/Convex/FDeriv.lean +++ b/Mathlib/Analysis/Convex/FDeriv.lean @@ -59,7 +59,7 @@ at `x` and `y`, `0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x)`. -/ theorem fderiv_sub_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y ∈ s) (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : 0 ≀ (fderiv ℝ f y - fderiv ℝ f x) (y - x) := by - rw [ContinuousLinearMap.sub_apply, ← hfx.lineDeriv_eq_fderiv, ← hfy.lineDeriv_eq_fderiv] + rw [sub_apply, ← hfx.lineDeriv_eq_fderiv, ← hfy.lineDeriv_eq_fderiv] exact hc.lineDeriv_sub_nonneg hx hy hfx.lineDifferentiableAt hfy.lineDifferentiableAt /-- A convex function with a vanishing FrΓ©chet derivative at an interior point of differentiability diff --git a/Mathlib/Analysis/Convex/Gradient.lean b/Mathlib/Analysis/Convex/Gradient.lean index de10b519d6594f..babbd33775e109 100644 --- a/Mathlib/Analysis/Convex/Gradient.lean +++ b/Mathlib/Analysis/Convex/Gradient.lean @@ -54,7 +54,7 @@ theorem inner_gradient_sub_nonneg (hc : ConvexOn ℝ s f) (hx : x ∈ s) (hy : y (hfx : DifferentiableAt ℝ f x) (hfy : DifferentiableAt ℝ f y) : 0 ≀ βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫ := by rw [inner_sub_left, inner_gradient_left, inner_gradient_left, - ← ContinuousLinearMap.sub_apply] + ← sub_apply] exact hc.fderiv_sub_nonneg hx hy hfx hfy /-- A convex function attains its minimum on `s` at any critical point: if `f` is convex on From 608f5bb0055b84ea7276d3aff0ab6540d8674fea Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Tue, 19 May 2026 13:36:24 +0200 Subject: [PATCH 39/40] feat(Analysis/Calculus/LipschitzSmooth): add descent lemma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the descent lemma in FrΓ©chet / 1D `deriv` / Hilbert gradient form on top of the foundational `LipschitzSmoothWith` API: a differentiable function whose derivative (in any form) is `K`-Lipschitz is `K`-smooth. The proof routes through a segment-pointwise predicate `LipschitzSmoothOnSegmentWith` and the fundamental theorem of calculus along a line segment. Includes the Riesz isomorphism between FrΓ©chet and gradient forms for Lipschitz constants and its 1D analogue. --- .../Calculus/LipschitzSmooth/Deriv.lean | 23 ++++++ .../Calculus/LipschitzSmooth/FDeriv.lean | 78 +++++++++++++++++++ .../Calculus/LipschitzSmooth/Gradient.lean | 18 +++++ 3 files changed, 119 insertions(+) diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean index a1b104cca702d5..066fe7718597b8 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Deriv.lean @@ -68,3 +68,26 @@ theorem deriv_sub_mul_le (h : LipschitzSmoothWith K f) (x y : ℝ) end Real end LipschitzSmoothWith + +/-! ### Lipschitz constants of `fderiv` versus `deriv` -/ + +section Real + +variable {f : ℝ β†’ ℝ} + +/-- For `f : ℝ β†’ ℝ`, the Lipschitz constants of `fderiv ℝ f` and `deriv f` coincide: +`deriv f` is the composition of `fderiv ℝ f` with the isometry +`(ContinuousLinearMap.toSpanSingletonLIE ℝ ℝ).symm` (evaluation at `1`). -/ +theorem lipschitzWith_fderiv_iff_lipschitzWith_deriv : + LipschitzWith K (fderiv ℝ f) ↔ LipschitzWith K (deriv f) := + ((ContinuousLinearMap.toSpanSingletonLIE ℝ ℝ).symm.isometry.lipschitzWith_iff K).symm + +/-! ### Descent lemma (1D) -/ + +/-- **Descent lemma (1D).** If `f : ℝ β†’ ℝ` is differentiable and its derivative is +`K`-Lipschitz, then `f` is `K`-smooth. -/ +theorem Differentiable.lipschitzSmoothWith_of_lipschitzWith_deriv + (hf : Differentiable ℝ f) (hL : LipschitzWith K (deriv f)) : LipschitzSmoothWith K f := + hf.lipschitzSmoothWith_of_lipschitzWith (lipschitzWith_fderiv_iff_lipschitzWith_deriv.mpr hL) + +end Real diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean index 556bb1108b636f..a00bd0fa63fea1 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/FDeriv.lean @@ -7,6 +7,9 @@ module public import Mathlib.Analysis.Calculus.FDeriv.Basic public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic +public import Mathlib.Analysis.Normed.Affine.AddTorsor +public import Mathlib.Analysis.SpecialFunctions.Integrals.Basic +public import Mathlib.MeasureTheory.Integral.CurveIntegral.Basic /-! # Lipschitz smoothness via the FrΓ©chet derivative @@ -16,6 +19,11 @@ FrΓ©chet-derivative restatements of the `LipschitzSmoothWith` predicate for pointwise, and the predicate is equivalent to the two-sided Taylor bound stated in `fderiv` form. The one-sided descent bounds require an order on the codomain and are stated for real-valued `f` in a dedicated section. + +This file also defines the segment-pointwise predicate `LipschitzSmoothOnSegmentWith` and +proves the **descent lemma**: a differentiable function with `K`-Lipschitz FrΓ©chet derivative +is `K`-smooth. The proof integrates the segment-pointwise norm-bound along the segment from +`x` to `y` using the fundamental theorem of calculus. -/ public section @@ -74,3 +82,73 @@ theorem fderiv_sub_apply_le (h : LipschitzSmoothWith K f) (x y : E) end Real end LipschitzSmoothWith + +/-! ### Descent lemma -/ + +open AffineMap MeasureTheory + +/-- The pointwise two-sided Lipschitz-smoothness bound on the FrΓ©chet derivative along the +segment from `x` to `y`: `β€–(fderiv ℝ f z - fderiv ℝ f x) (y - x)β€– ≀ K Β· dist x z Β· dist x y` +for all `z ∈ [x -[ℝ] y]`. This is the segment-pointwise form that integrates to the descent +inequality. -/ +abbrev LipschitzSmoothOnSegmentWith (K : NNReal) (f : E β†’ F) : Prop := + βˆ€ x y : E, βˆ€ z ∈ segment ℝ x y, + β€–(fderiv ℝ f z - fderiv ℝ f x) (y - x)β€– ≀ K * dist x z * dist x y + +/-- A `K`-Lipschitz FrΓ©chet derivative implies the segment-pointwise smoothness bound. +Direct from the operator-norm bound (`ContinuousLinearMap.le_opNorm`) plus the Lipschitz bound +at the pair `(z, x)`. -/ +theorem LipschitzSmoothOnSegmentWith.of_lipschitzWith_fderiv + (hL : LipschitzWith K (fderiv ℝ f)) : LipschitzSmoothOnSegmentWith K f := fun x y z _ => + calc β€–(fderiv ℝ f z - fderiv ℝ f x) (y - x)β€– + ≀ β€–fderiv ℝ f z - fderiv ℝ f xβ€– * β€–y - xβ€– := ContinuousLinearMap.le_opNorm _ _ + _ = dist (fderiv ℝ f x) (fderiv ℝ f z) * dist x y := by simp only [← dist_eq_norm'] + _ ≀ K * dist x z * dist x y := mul_le_mul_of_nonneg_right (hL.dist_le_mul _ _) dist_nonneg + +/-- For a segment-pointwise Lipschitz-smooth function with continuous FrΓ©chet derivative, the +norm of the curve integral of `fderiv ℝ f z - fderiv ℝ f x` along the segment is +bounded by `K/2 Β· (dist x y)Β²`. The quantitative FTC step of the descent lemma. -/ +theorem LipschitzSmoothOnSegmentWith.curveIntegral_norm_le + (h : LipschitzSmoothOnSegmentWith K f) (hcont : Continuous (fderiv ℝ f)) (x y : E) : + β€–βˆ«αΆœ z in .segment x y, (fderiv ℝ f z - fderiv ℝ f x)β€– ≀ K / 2 * (dist x y) ^ 2 := by + have h_integrable : IntervalIntegrable + (fun t => (fderiv ℝ f (lineMap x y t) - fderiv ℝ f x) (y - x)) volume 0 1 := + curveIntegrable_segment.mp <| + (hcont.curveIntegrable_segment).sub (curveIntegrable_segment_const _ x y) + calc β€–βˆ«αΆœ z in .segment x y, (fderiv ℝ f z - fderiv ℝ f x)β€– + _ = β€–βˆ« t in (0:ℝ)..1, (fderiv ℝ f (lineMap x y t) - fderiv ℝ f x) (y - x)β€– := by + rw [curveIntegral_segment] + _ ≀ ∫ t in (0:ℝ)..1, β€–(fderiv ℝ f (lineMap x y t) - fderiv ℝ f x) (y - x)β€– := + intervalIntegral.norm_integral_le_integral_norm zero_le_one + _ ≀ ∫ t in (0:ℝ)..1, K * (dist x y) ^ 2 * t := + intervalIntegral.integral_mono_on zero_le_one h_integrable.norm + (Continuous.intervalIntegrable (by fun_prop) _ _) (fun t ht => + (h _ _ _ (segment_eq_image_lineMap ℝ x y β–Έ Set.mem_image_of_mem _ ht)).trans_eq <| by + rw [dist_left_lineMap, Real.norm_of_nonneg ht.1]; ring) + _ = K * (dist x y) ^ 2 * ∫ t in (0:ℝ)..1, t := intervalIntegral.integral_const_mul _ _ + _ = K / 2 * (dist x y) ^ 2 := by rw [integral_id]; ring + +/-- The segment-pointwise smoothness bound, together with differentiability and continuity of +the FrΓ©chet derivative, implies `K`-smoothness. The proof integrates the pointwise norm bound +along the segment from `x` to `y` using FTC. -/ +theorem LipschitzSmoothOnSegmentWith.lipschitzSmoothWith [CompleteSpace F] + (hptwise : LipschitzSmoothOnSegmentWith K f) (hf : Differentiable ℝ f) + (hcont : Continuous (fderiv ℝ f)) : LipschitzSmoothWith K f := by + refine lipschitzSmoothWith_iff_lineDeriv.mpr fun x y => ?_ + have heq : f y - f x - lineDeriv ℝ f x (y - x) = + ∫ᢜ z in .segment x y, (fderiv ℝ f z - fderiv ℝ f x) := calc + _ = f y - f x - (fderiv ℝ f x) (y - x) := by rw [(hf x).lineDeriv_eq_fderiv] + _ = (∫ᢜ z in .segment x y, fderiv ℝ f z) - ∫ᢜ _ in .segment x y, fderiv ℝ f x := by + rw [← curveIntegral_fderiv_segment (fun z _ => hf z) hcont.continuousOn, + ← curveIntegral_segment_const] + _ = ∫ᢜ z in .segment x y, (fderiv ℝ f z - fderiv ℝ f x) := + (curveIntegral_fun_sub (hcont.curveIntegrable_segment) + (curveIntegrable_segment_const _ x y)).symm + rw [heq] + exact hptwise.curveIntegral_norm_le hcont x y + +/-- **Descent lemma.** If `f` is differentiable and its FrΓ©chet derivative is +`K`-Lipschitz, then `f` is `K`-smooth (without convexity assumption). -/ +theorem Differentiable.lipschitzSmoothWith_of_lipschitzWith [CompleteSpace F] + (hf : Differentiable ℝ f) (hL : LipschitzWith K (fderiv ℝ f)) : LipschitzSmoothWith K f := + (LipschitzSmoothOnSegmentWith.of_lipschitzWith_fderiv hL).lipschitzSmoothWith hf hL.continuous diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean index a78e28cd88dead..0227a5b5de611e 100644 --- a/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Gradient.lean @@ -26,6 +26,7 @@ public section variable {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] [CompleteSpace F] variable {K : NNReal} {f : F β†’ ℝ} +open InnerProductSpace open scoped Gradient RealInnerProductSpace theorem lipschitzSmoothWith_iff_inner_gradient (hf : Differentiable ℝ f) : @@ -78,3 +79,20 @@ theorem CocoerciveWith.lipschitzWith_gradient (h : CocoerciveWith K f) : Lipschi simp only [dist_eq_norm'] nlinarith [h x y, mul_nonneg K.coe_nonneg (norm_nonneg (y - x)), mul_le_mul_of_nonneg_left (real_inner_le_norm (βˆ‡ f y - βˆ‡ f x) (y - x)) K.coe_nonneg] + +/-! ### Riesz isomorphism for Lipschitz constants -/ + +/-- The Riesz isomorphism identifies the Lipschitz constant of the FrΓ©chet derivative with +that of the gradient: `LipschitzWith K (fderiv ℝ f) ↔ LipschitzWith K (βˆ‡ f)`. Unconditional β€” +the gradient is *defined* via Riesz from the fderiv, and Riesz is an isometry. -/ +theorem lipschitzWith_fderiv_iff_lipschitzWith_gradient : + LipschitzWith K (fderiv ℝ f) ↔ LipschitzWith K (βˆ‡ f) := + toDual_comp_gradient (π•œ := ℝ) (f := f) β–Έ (toDual ℝ F).isometry.lipschitzWith_iff K + +/-! ### Descent lemma (Hilbert form) -/ + +/-- **Descent lemma (Hilbert form).** If `f : F β†’ ℝ` is differentiable on a Hilbert space +and its gradient `βˆ‡ f` is `K`-Lipschitz, then `f` is `K`-smooth. -/ +theorem Differentiable.lipschitzSmoothWith_of_lipschitzWith_gradient + (hf : Differentiable ℝ f) (hL : LipschitzWith K (βˆ‡ f)) : LipschitzSmoothWith K f := + hf.lipschitzSmoothWith_of_lipschitzWith (lipschitzWith_fderiv_iff_lipschitzWith_gradient.mpr hL) From 5ef236983d1b9f888451a013cd7ccefdee680885 Mon Sep 17 00:00:00 2001 From: Christoph Spiegel Date: Mon, 18 May 2026 17:31:31 +0200 Subject: [PATCH 40/40] feat(LipschitzSmooth/Convex): Baillon-Haddad theorem and convex equivalences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For a differentiable convex function on a Hilbert space, `K`-smoothness implies `K`-cocoercivity of the gradient (`ConvexOn.cocoerciveWith_of_lipschitzSmoothWith`). Combined with the descent lemma and the elementary cocoercive ⟹ Lipschitz-gradient direction, this yields the four pairwise iff equivalences between `LipschitzSmoothWith`, `LipschitzWith (fderiv ℝ f)`, `LipschitzWith (βˆ‡ f)`, and `CocoerciveWith` under `ConvexOn ℝ Set.univ f` and `Differentiable ℝ f`. --- Mathlib.lean | 1 + .../Calculus/LipschitzSmooth/Convex.lean | 135 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 Mathlib/Analysis/Calculus/LipschitzSmooth/Convex.lean diff --git a/Mathlib.lean b/Mathlib.lean index fec96c4e71c0ff..e1d8e4209686b3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1832,6 +1832,7 @@ public import Mathlib.Analysis.Calculus.LineDeriv.IntegrationByParts public import Mathlib.Analysis.Calculus.LineDeriv.Measurable public import Mathlib.Analysis.Calculus.LineDeriv.QuadraticMap public import Mathlib.Analysis.Calculus.LipschitzSmooth.Basic +public import Mathlib.Analysis.Calculus.LipschitzSmooth.Convex public import Mathlib.Analysis.Calculus.LipschitzSmooth.Deriv public import Mathlib.Analysis.Calculus.LipschitzSmooth.FDeriv public import Mathlib.Analysis.Calculus.LipschitzSmooth.Gradient diff --git a/Mathlib/Analysis/Calculus/LipschitzSmooth/Convex.lean b/Mathlib/Analysis/Calculus/LipschitzSmooth/Convex.lean new file mode 100644 index 00000000000000..9048f968e040c7 --- /dev/null +++ b/Mathlib/Analysis/Calculus/LipschitzSmooth/Convex.lean @@ -0,0 +1,135 @@ +/- +Copyright (c) 2026 Christoph Spiegel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christoph Spiegel +-/ +module + +public import Mathlib.Analysis.Calculus.LipschitzSmooth.Gradient +public import Mathlib.Analysis.Convex.Gradient + +/-! +# Baillon-Haddad theorem + +For a differentiable convex function on a Hilbert space, `K`-smoothness implies +`K`-cocoercivity of the gradient (the Baillon-Haddad theorem). Combined with the +descent lemma, this yields the pairwise iff equivalences between +`LipschitzSmoothWith`, `LipschitzWith (fderiv ℝ f)`, `LipschitzWith (βˆ‡ f)`, and +`CocoerciveWith`. +-/ + +public section + +namespace ConvexOn + +variable {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] [CompleteSpace F] +variable {K : NNReal} {f : F β†’ ℝ} + +open InnerProductSpace +open scoped Gradient RealInnerProductSpace + +/-- Core Baillon-Haddad estimate (`K > 0` case): for convex differentiable `K`-smooth `f`, +`β€–βˆ‡f y - βˆ‡f xβ€–Β² ≀ 2K Β· (f y - f x - βŸͺβˆ‡f x, y - x⟫)`. Direct proof via the descent inequality +applied at the auxiliary point `u := y - (1/K) Β· (βˆ‡f y - βˆ‡f x)` combined with the +first-order convexity inequality at `(x, u)`. -/ +private theorem norm_gradient_sub_sq_le_aux (hc : ConvexOn ℝ Set.univ f) + (hf : Differentiable ℝ f) (hs : LipschitzSmoothWith K f) (hKp : 0 < (K : ℝ)) (x y : F) : + β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 ≀ 2 * K * (f y - f x - βŸͺβˆ‡ f x, y - x⟫) := by + set g := βˆ‡ f y - βˆ‡ f x with hg + -- Combining convex FOC at `(x, u)` with K-smooth descent at `(y, u)` for the step + -- `u := y - (1/K) β€’ g`, then substituting the shape of `u - x`, `u - y`, `β€–u - yβ€–Β²`. + have h_chain : f x + βŸͺβˆ‡ f x, y - x⟫_ℝ - 1 / K * βŸͺβˆ‡ f x, g⟫_ℝ ≀ + f y - 1 / K * βŸͺβˆ‡ f y, g⟫_ℝ + β€–gβ€– ^ 2 / (2 * K) := by + set u := y - (1 / (K : ℝ)) β€’ g with hu + calc f x + βŸͺβˆ‡ f x, y - x⟫_ℝ - 1 / K * βŸͺβˆ‡ f x, g⟫_ℝ + = f x + βŸͺβˆ‡ f x, u - x⟫_ℝ := by + simp only [hu, inner_sub_right, inner_smul_right]; ring + _ ≀ f u := hc.add_inner_gradient_le (Set.mem_univ x) (Set.mem_univ u) (hf x) + _ ≀ f y + βŸͺβˆ‡ f y, u - y⟫_ℝ + K / 2 * β€–u - yβ€– ^ 2 := + hs.inner_gradient_descent_le y u (hf y) + _ = f y - 1 / K * βŸͺβˆ‡ f y, g⟫_ℝ + β€–gβ€– ^ 2 / (2 * K) := by + simp only [hu, sub_sub_cancel_left, inner_neg_right, inner_smul_right, norm_neg, + norm_smul, mul_pow, Real.norm_eq_abs, sq_abs] + field_simp; ring + -- Inner-product self identity: `(1/K) Β· (βŸͺβˆ‡f y, g⟫ - βŸͺβˆ‡f x, g⟫) = β€–gβ€–Β²/K = 2 Β· β€–gβ€–Β²/(2K)`. + have h_inner : 1 / K * βŸͺβˆ‡ f y, g⟫_ℝ - 1 / K * βŸͺβˆ‡ f x, g⟫_ℝ + = 2 * (β€–gβ€– ^ 2 / (2 * K)) := by + rw [← mul_sub, ← inner_sub_left, ← hg, real_inner_self_eq_norm_sq]; field_simp + calc β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 + = 2 * K * (β€–gβ€– ^ 2 / (2 * K)) := by rw [hg]; field_simp + _ ≀ 2 * K * (f y - f x - βŸͺβˆ‡ f x, y - x⟫_ℝ) := + mul_le_mul_of_nonneg_left (by linarith [h_chain, h_inner]) (by positivity) + +/-- **Baillon-Haddad theorem.** A differentiable convex `K`-smooth function on a Hilbert +space is `K`-cocoercive. + +The standard proof, here inlined without introducing `Ο†β‚“` explicitly: define +`Ο†β‚“(z) := f(z) - βŸ¨βˆ‡f(x), z⟩`, which is convex and `K`-smooth with minimum at `x` +(since `βˆ‡Ο†β‚“(x) = 0`). Apply the descent inequality of `Ο†β‚“` at `y` +stepping by `-βˆ‡Ο†β‚“(y) / K`; using `Ο†β‚“(x) = min Ο†β‚“` yields +`β€–βˆ‡f(y) - βˆ‡f(x)β€–Β² ≀ 2K (f(y) - f(x) - βŸ¨βˆ‡f(x), y - x⟩)`. Sum with the symmetric bound from +`Ο†α΅§`, and the linear terms in `f` cancel to give the cocoercive inequality. -/ +theorem cocoerciveWith_of_lipschitzSmoothWith + (hc : ConvexOn ℝ Set.univ f) (hf : Differentiable ℝ f) + (hs : LipschitzSmoothWith K f) : CocoerciveWith K f := by + intro x y + by_cases hK : (K : ℝ) = 0 + Β· -- K = 0: descent + FOC pinch `f b = f a + βŸͺβˆ‡f a, b - a⟫` to equality everywhere, + -- forcing `f` affine and `βˆ‡f` constant. Both sides of the cocoercive bound are then 0. + have h_eq : βˆ€ a b : F, f b = f a + βŸͺβˆ‡ f a, b - a⟫_ℝ := fun a b => + le_antisymm (by simpa [hK] using hs.inner_gradient_descent_le a b (hf a)) + (hc.add_inner_gradient_le (Set.mem_univ a) (Set.mem_univ b) (hf a)) + have h_grad_eq : βˆ€ v : F, βŸͺβˆ‡ f y, v⟫_ℝ = βŸͺβˆ‡ f x, v⟫_ℝ := fun v => by + have e1 := h_eq x (y + v) + have e2 := h_eq y (y + v) + have e3 := h_eq x y + rw [show (y + v) - y = v from by abel] at e2 + rw [show (y + v) - x = (y - x) + v from by abel, inner_add_right] at e1 + linarith + simp [ext_inner_right ℝ h_grad_eq] + Β· have hKp : 0 < (K : ℝ) := lt_of_le_of_ne K.coe_nonneg (Ne.symm hK) + -- Apply the core bound at `(x, y)` and `(y, x)`; sum cancels the linear-in-f terms. + have h_sym : β€–βˆ‡ f x - βˆ‡ f yβ€– ^ 2 = β€–βˆ‡ f y - βˆ‡ f xβ€– ^ 2 := by rw [norm_sub_rev] + have h_inner : βŸͺβˆ‡ f x, y - x⟫_ℝ + βŸͺβˆ‡ f y, x - y⟫_ℝ + = -βŸͺβˆ‡ f y - βˆ‡ f x, y - x⟫_ℝ := by + rw [show (x - y : F) = -(y - x) from (neg_sub y x).symm, inner_neg_right, + inner_sub_left] + ring + nlinarith [norm_gradient_sub_sq_le_aux hc hf hs hKp x y, + norm_gradient_sub_sq_le_aux hc hf hs hKp y x, h_sym, h_inner, K.coe_nonneg] + +/-- For a differentiable convex function on a Hilbert space, `K`-smoothness is equivalent +to `K`-cocoercivity. The forward direction is the Baillon-Haddad theorem; the backward +direction goes via `K`-Lipschitz gradient and the descent lemma, no convexity needed. -/ +theorem lipschitzSmoothWith_iff_cocoerciveWith + (hc : ConvexOn ℝ Set.univ f) (hf : Differentiable ℝ f) : + LipschitzSmoothWith K f ↔ CocoerciveWith K f := + ⟨hc.cocoerciveWith_of_lipschitzSmoothWith hf, + fun h => hf.lipschitzSmoothWith_of_lipschitzWith_gradient h.lipschitzWith_gradient⟩ + +/-- For a differentiable convex function on a Hilbert space, `K`-smoothness is equivalent +to `K`-Lipschitz gradient. Forward: K-smooth β†’ cocoercive (Baillon-Haddad) β†’ Lipschitz +gradient. Backward: the descent lemma in Hilbert form. -/ +theorem lipschitzSmoothWith_iff_lipschitzWith_gradient + (hc : ConvexOn ℝ Set.univ f) (hf : Differentiable ℝ f) : + LipschitzSmoothWith K f ↔ LipschitzWith K (βˆ‡ f) := + ⟨fun hs => (hc.cocoerciveWith_of_lipschitzSmoothWith hf hs).lipschitzWith_gradient, + hf.lipschitzSmoothWith_of_lipschitzWith_gradient⟩ + +/-- For a differentiable convex function on a Hilbert space, `K`-smoothness is equivalent +to a `K`-Lipschitz FrΓ©chet derivative. -/ +theorem lipschitzSmoothWith_iff_lipschitzWith_fderiv + (hc : ConvexOn ℝ Set.univ f) (hf : Differentiable ℝ f) : + LipschitzSmoothWith K f ↔ LipschitzWith K (fderiv ℝ f) := + (hc.lipschitzSmoothWith_iff_lipschitzWith_gradient hf).trans + lipschitzWith_fderiv_iff_lipschitzWith_gradient.symm + +/-- **Baillon-Haddad theorem** (`iff` form): for a differentiable convex function on a Hilbert +space, `K`-Lipschitz gradient is equivalent to `K`-cocoercivity. -/ +theorem cocoerciveWith_iff_lipschitzWith_gradient + (hc : ConvexOn ℝ Set.univ f) (hf : Differentiable ℝ f) : + CocoerciveWith K f ↔ LipschitzWith K (βˆ‡ f) := + (hc.lipschitzSmoothWith_iff_cocoerciveWith hf).symm.trans + (hc.lipschitzSmoothWith_iff_lipschitzWith_gradient hf) + +end ConvexOn