/- SPDX-License-Identifier: MIT SPDX-FileCopyrightText: 2025 Shangtong Zhang -/ import Mathlib.Analysis.RCLike.Basic import Mathlib.Analysis.InnerProductSpace.PiL2 import Mathlib.Analysis.InnerProductSpace.Basic import Mathlib.Analysis.InnerProductSpace.Defs import Mathlib.Analysis.Calculus.FDeriv.Basic import Mathlib.Data.NNReal.Defs import Mathlib.Order.Filter.Defs import Mathlib.Topology.Defs.Filter import Mathlib.Order.Interval.Finset.Defs import Mathlib.Analysis.Calculus.Gradient.Basic import Mathlib.Tactic.MoveAdd import Mathlib.Analysis.Normed.Lp.MeasurableSpace import Mathlib.Data.Real.Sign import Mathlib.Analysis.Calculus.FDeriv.Pow import Mathlib.Analysis.Calculus.Deriv.Pow import Mathlib.Analysis.Calculus.Deriv.Mul import Mathlib.Analysis.Calculus.Deriv.Add import Mathlib.Analysis.Calculus.Deriv.Comp import Mathlib.Analysis.Asymptotics.Defs import Mathlib.Analysis.Normed.Lp.lpSpace import Mathlib.Analysis.SpecialFunctions.Pow.Deriv import Mathlib.Analysis.Calculus.Deriv.MeanValue import RLTheory.Defs import RLTheory.Analysis.Normed.Group.Basic open ENNReal NNReal Real Finset Filter Asymptotics RLTheory open scoped Topology InnerProductSpace RealInnerProductSpace Gradient lemma abs_eq_sign_mul_nhds {x : ℝ} (hx : x β‰  0) : (fun y => |y|) =αΆ [𝓝 x] fun y => x.sign * y := by have hfx : 0 < |x| := by simp [abs_pos.mpr hx] apply Metric.eventually_nhds_iff.mpr use |x| / 2 constructor linarith intro y hy simp simp [dist] at hy by_cases hx0 : 0 < x case pos => simp [Real.sign_of_pos hx0] simp [abs_of_pos hx0] at hy rw [←abs_neg, neg_sub] at hy have : x - y ≀ |x - y| := by apply le_abs_self linarith case neg => simp at hx0 have : x < 0 := by apply lt_of_le_of_ne hx0 hx simp [Real.sign_of_neg this] simp [abs_of_neg this] at hy have := le_abs_self (y - x) linarith theorem hasDerivAt_abs_pow {x : ℝ} {n : β„•} (hn : 2 ≀ n) : HasDerivAt (fun x => |x| ^ n) (n * |x| ^ (n - 2) * x) x := by by_cases hx : x β‰  0 case pos => have := abs_eq_sign_mul_nhds hx have := EventuallyEq.pow_const this n apply HasDerivAt.congr_of_eventuallyEq (h₁ := this) have := ((hasDerivAt_id' x).const_mul (x.sign)).pow n apply HasDerivAt.congr_deriv this simp by_cases hx0 : 0 < x case pos => simp [Real.sign_of_pos hx0, abs_of_pos hx0] rw [mul_assoc, ←pow_succ] simp apply Or.inl apply congrArg omega case neg => simp at hx0 have : x < 0 := by apply lt_of_le_of_ne hx0 hx simp [Real.sign_of_neg this, abs_of_neg this] conv_rhs => rw [mul_assoc, ←neg_neg x, mul_neg, neg_neg, ←pow_succ, mul_neg] simp apply Or.inl have : n - 2 + 1 = n - 1 := by omega rw [this] case neg => simp at hx simp [hx] apply hasDerivAt_iff_isLittleO.mpr simp apply isLittleO_iff.mpr simp intro c hc apply Metric.eventually_nhds_iff.mpr simp use min c 1 constructor simp exact hc intro y hy rw [zero_pow (by linarith)] simp have : n = (n - 2) + 1 + 1 := by omega rw [this, pow_succ, pow_succ] grw [pow_le_oneβ‚€] rw [one_mul] apply mul_le_mul_of_nonneg_right apply le_of_lt exact hy.trans_le (by apply min_le_left) simp simp apply le_of_lt exact hy.trans_le (by apply min_le_right) theorem hasDeriveAt_hasDerivAt_abs_pow {x : ℝ} {n : β„•} (hn : 2 ≀ n) : HasDerivAt (fun x : ℝ => n * |x| ^ (n - 2) * x) (n * (n - 1) * |x| ^ (n - 2)) x := by by_cases hx : x β‰  0 case pos => have heq := abs_eq_sign_mul_nhds hx -- We want to show: f(y) = n * |y|^(n-2) * y =αΆ [𝓝 x] n * (sign x * y)^(n-2) * y -- = n * sign^(n-2) * y^(n-2) * y = n * sign^(n-2) * y^(n-1) have heq_fn : (fun y => n * |y| ^ (n - 2) * y) =αΆ [𝓝 x] (fun y => n * x.sign ^ (n - 2) * y ^ (n - 1)) := by apply heq.mono intro y hy simp only at hy ⊒ rw [hy, mul_pow] have hsub : n - 2 + 1 = n - 1 := by omega calc n * (x.sign ^ (n - 2) * y ^ (n - 2)) * y = n * x.sign ^ (n - 2) * (y ^ (n - 2) * y) := by ring _ = n * x.sign ^ (n - 2) * y ^ (n - 2 + 1) := by rw [pow_succ] _ = n * x.sign ^ (n - 2) * y ^ (n - 1) := by rw [hsub] rw [heq_fn.hasDerivAt_iff] -- Now prove HasDerivAt for n * sign^(n-2) * y^(n-1) have hderiv := ((hasDerivAt_id' x).pow (n - 1)).const_mul (n * x.sign ^ (n - 2)) apply HasDerivAt.congr_deriv hderiv -- Show derivative values are equal: n * sign^(n-2) * (n-1) * x^(n-2) = n * (n-1) * |x|^(n-2) have hn1_cast : ((n - 1 : β„•) : ℝ) = (n : ℝ) - 1 := by rw [Nat.cast_sub (by omega : 1 ≀ n)] simp by_cases hx0 : 0 < x case pos => simp only [Real.sign_of_pos hx0, one_pow, abs_of_pos hx0] have h1 : n - 1 - 1 = n - 2 := by omega rw [h1, hn1_cast] ring case neg => simp only [not_lt] at hx0 have hxneg : x < 0 := lt_of_le_of_ne hx0 hx simp only [Real.sign_of_neg hxneg, abs_of_neg hxneg] have h1 : n - 1 - 1 = n - 2 := by omega rw [h1, neg_pow, neg_pow, hn1_cast] ring case neg => simp only [not_not] at hx simp only [hx, abs_zero] by_cases hn₁ : n = 2 case pos => subst hn₁ simp only [Nat.sub_self, pow_zero, mul_one, Nat.cast_ofNat] have := (hasDerivAt_id' (0 : ℝ)).const_mul 2 simp only [mul_one] at this apply HasDerivAt.congr_deriv this ring case neg => have hnβ‚‚ : 2 < n := lt_of_le_of_ne hn (fun h => hn₁ h.symm) simp only [zero_pow (by omega : n - 2 β‰  0), mul_zero] apply hasDerivAt_iff_isLittleO.mpr simp only [sub_zero] apply isLittleO_iff.mpr intro c hc apply Metric.eventually_nhds_iff.mpr simp only [dist_zero_right] refine ⟨(c / n) ^ (1 / ((n : ℝ) - 2)), by positivity, ?_⟩ intro y hy simp only [mul_zero, smul_zero, sub_zero, Real.norm_eq_abs] rw [abs_mul, abs_mul, abs_of_nonneg (by positivity : 0 ≀ (n : ℝ)), abs_of_nonneg (pow_nonneg (abs_nonneg _) _)] -- Goal: n * |y|^(n-2) * |y| ≀ c * |y| -- Strategy: use mul_le_mul_of_nonneg_right to reduce to n * |y|^(n-2) ≀ c apply mul_le_mul_of_nonneg_right _ (abs_nonneg y) -- Now need: n * |y|^(n-2) ≀ c -- From hy: |y| < (c/n)^(1/(n-2)) -- So |y|^(n-2) < c/n, hence n * |y|^(n-2) < c have hynorm : |y| < (c / n) ^ (1 / ((n : ℝ) - 2)) := hy have habs_pow : |y| ^ (n - 2) < c / n := by have hne : ((n : ℝ) - 2) β‰  0 := by have : (2 : ℝ) < n := by exact Nat.ofNat_lt_cast.mpr hnβ‚‚ linarith have hpos : 0 < ((n : ℝ) - 2) := by have : (2 : ℝ) < n := by exact Nat.ofNat_lt_cast.mpr hnβ‚‚ linarith have hn2cast : ((n - 2 : β„•) : ℝ) = (n : ℝ) - 2 := by rw [Nat.cast_sub (by omega : 2 ≀ n)] simp have hbase_pos : 0 < c / n := by positivity have hbase_nonneg : 0 ≀ (c / n) ^ (1 / ((n : ℝ) - 2)) := by positivity have h2 : ((c / n) ^ (1 / ((n : ℝ) - 2))) ^ (n - 2) = c / n := by rw [← Real.rpow_natCast ((c / n) ^ (1 / ((n : ℝ) - 2))) (n - 2)] rw [← Real.rpow_mul hbase_pos.le] rw [hn2cast, one_div, inv_mul_cancelβ‚€ hne] simp calc |y| ^ (n - 2) < ((c / n) ^ (1 / ((n : ℝ) - 2))) ^ (n - 2) := pow_lt_pow_leftβ‚€ hynorm (abs_nonneg _) (by omega) _ = c / n := h2 have hfinal : n * |y| ^ (n - 2) < c := by calc n * |y| ^ (n - 2) < n * (c / n) := by apply mul_lt_mul_of_pos_left habs_pow simp; linarith _ = c := by field_simp exact le_of_lt hfinal namespace StochasticApproximation variable {p : β„•} variable {d : β„•} abbrev LpSpace (p : β„•) (d : β„•) := PiLp p fun _ : Fin d => ℝ def toL2 (x : LpSpace p d) : E d := WithLp.toLp 2 x.ofLp noncomputable def half_sq_Lp : LpSpace p d β†’ ℝ := fun x => 1 / 2 * β€–xβ€– ^ 2 noncomputable def half_sq_Lp' : LpSpace p d β†’ LpSpace p d := fun x => WithLp.toLp p fun i => β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i section smooth variable [Fact (1 ≀ (p : ℝβ‰₯0∞))] lemma continuous_half_sq_Lp : Continuous (@half_sq_Lp p d) := by apply Continuous.mul apply continuous_const apply Continuous.pow apply Continuous.norm apply continuous_id noncomputable def path (x y : LpSpace p d) (t : ℝ) : LpSpace p d := x + t β€’ (y - x) lemma continuousOn_path (x y : LpSpace p d) : ContinuousOn (path x y) (Set.Icc 0 1) := by apply ContinuousOn.add apply continuousOn_const apply ContinuousOn.smul apply continuousOn_id apply continuousOn_const noncomputable def Lp_pow_p_path (x y : LpSpace p d) (t : ℝ) : ℝ := β€–path x y tβ€– ^ (p : ℝ) lemma Lp_pow_p_path_ne_zero {x y : LpSpace p d} {t : ℝ} {ht : path x y t β‰  0} : Lp_pow_p_path x y t β‰  0 := by have hp : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by infer_instance have hp := hp.elim simp at hp unfold Lp_pow_p_path apply (rpow_ne_zero ?_ ?_).mpr simp [ht] apply norm_nonneg simp linarith lemma continuousOn_Lp_pow_p_path {x y : LpSpace p d} : ContinuousOn (Lp_pow_p_path x y) (Set.Icc 0 1) := by intro _ unfold Lp_pow_p_path have := (continuousOn_path x y).norm.pow p apply ContinuousOn.congr this intro t ht simp lemma unfold_Lp_pow_p_path (x y : LpSpace p d) : Lp_pow_p_path x y = fun t => (βˆ‘ i, |x i + t * (y i - x i)| ^ (p : ℝ)) := by have hp : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by infer_instance have hp := hp.elim simp at hp ext t simp [Lp_pow_p_path] rw [PiLp.norm_eq_sum] simp rw [←Real.rpow_mul_natCast, inv_mul_cancelβ‚€] simp [path] simp linarith apply sum_nonneg; intro i hi; apply pow_nonneg; apply abs_nonneg simp linarith noncomputable def Lp_pow_p_path' (x y : LpSpace p d) : ℝ β†’ ℝ := fun t => βˆ‘ i, p * |x.ofLp i + t * (y.ofLp i - x.ofLp i)| ^ (p - 2) * (x.ofLp i + t * (y.ofLp i - x.ofLp i)) * (y.ofLp i - x.ofLp i) lemma continuousOn_Lp_pow_p_path' {x y : LpSpace p d} : ContinuousOn (Lp_pow_p_path' x y) (Set.Icc 0 1) := by unfold Lp_pow_p_path' -- Get component-wise continuity from path continuity have hpath := continuousOn_path x y -- For each component i, the function t ↦ (path x y t).ofLp i is continuous have hcomp : βˆ€ i, ContinuousOn (fun t => (path x y t).ofLp i) (Set.Icc 0 1) := by intro i simp only [path, WithLp.ofLp_add, WithLp.ofLp_smul, Pi.add_apply, Pi.smul_apply, smul_eq_mul] apply ContinuousOn.add Β· apply continuousOn_const Β· apply ContinuousOn.mul Β· apply continuousOn_id Β· apply continuousOn_const -- Now prove the sum is continuous apply continuousOn_finset_sum intro i _ -- Each term: p * |path_i(t)|^(p-2) * path_i(t) * (y_i - x_i) -- where path_i(t) = x.ofLp i + t * (y.ofLp i - x.ofLp i) apply ContinuousOn.mul apply ContinuousOn.mul apply ContinuousOn.mul Β· apply continuousOn_const Β· apply ContinuousOn.pow apply ContinuousOn.abs exact hcomp i Β· exact hcomp i Β· apply continuousOn_const lemma hasDerivAt_Lp_pow_p_path (hp : 2 ≀ p) (x y : LpSpace p d) : βˆ€ t : ℝ, HasDerivAt (Lp_pow_p_path x y) (Lp_pow_p_path' x y t) t := by intro t simp [unfold_Lp_pow_p_path] apply HasDerivAt.fun_sum intro i hi set Ξ΄ := y i - x i have h₁ : HasDerivAt (fun t => x i + t * Ξ΄) Ξ΄ t := by apply HasDerivAt.const_add have := (hasDerivAt_id' t).mul_const Ξ΄ simp at this exact this have hβ‚‚ := hasDerivAt_abs_pow (hn := hp) (x := x i + t * Ξ΄) have := HasDerivAt.comp t hβ‚‚ h₁ apply HasDerivAt.congr ?_ this ext z simp noncomputable def Lp_pow_p_path'' (x y : LpSpace p d) : ℝ β†’ ℝ := fun t => βˆ‘ i, p * (p - 1) * |x i + t * (y i - x i)| ^ (p - 2) * (y i - x i) ^ 2 omit [Fact (1 ≀ (p : ℝβ‰₯0∞))] in lemma hasDerivAt_Lp_pow_p_path' (hp : 2 ≀ p) (x y : LpSpace p d) : βˆ€ t : ℝ, HasDerivAt (Lp_pow_p_path' x y) (Lp_pow_p_path'' x y t) t := by intro t unfold Lp_pow_p_path' apply HasDerivAt.fun_sum intro i hi set Ξ΄ := y i - x i let g₁ := fun y : ℝ => p * |y| ^ (p - 2) * y let g₁' := fun y : ℝ => p * (p - 1) * |y| ^ (p - 2) have hg₁ : βˆ€ y, HasDerivAt g₁ (g₁' y) y := by intro y apply hasDeriveAt_hasDerivAt_abs_pow linarith let gβ‚‚ := fun y : ℝ => Ξ΄ have hgβ‚‚ : βˆ€ y, HasDerivAt gβ‚‚ 0 y := by intro y apply hasDerivAt_const let g₃ := fun t => x i + t * Ξ΄ let g₃' := fun t : ℝ => Ξ΄ have hg₃ : βˆ€ t, HasDerivAt g₃ (g₃' t) t := by intro t apply HasDerivAt.const_add have := (hasDerivAt_id' t).mul_const Ξ΄ simp at this exact this apply HasDerivAt.congr (f := (g₁ ∘ g₃) * gβ‚‚) ext z simp [g₁, gβ‚‚, g₃] have := HasDerivAt.comp t (hg₁ (g₃ t)) (hg₃ t) have := HasDerivAt.mul this (hgβ‚‚ t) apply HasDerivAt.congr_deriv this simp [g₁, gβ‚‚, g₃, g₁', g₃'] ring lemma bdd_Lp_pow_path'' (x y : LpSpace p d) (t : ℝ) (hp : 2 < p) : Lp_pow_p_path'' x y t ≀ p * (p - 1) * β€–path x y tβ€– ^ (p - 2) * β€–y - xβ€– ^ 2 := by simp [Lp_pow_p_path''] conv_lhs => congr; rfl; ext i; rw [mul_assoc, mul_assoc] rw [←mul_sum, ←mul_sum, mul_assoc, mul_assoc] grw [Real.inner_le_Lp_mul_Lq (p := p / ↑(p - 2)) (q := p / (2 : β„•))] apply le_of_eq simp apply Or.inl apply Or.inl have h₁ : ↑(p - 2) β‰  (0 : ℝ) := by apply ne_of_gt; simp; linarith have hβ‚‚ : ↑(2 : β„•) β‰  (0 : ℝ) := by simp conv_lhs => congr; congr; congr; rfl; ext i rw [←Real.rpow_natCast_mul, mul_div_cancelβ‚€] rfl exact h₁ apply abs_nonneg rw [div_eq_mul_inv, mul_comm] rfl congr; congr; rfl; ext i rw [←sq_abs, ←Real.rpow_natCast_mul] simp rw [mul_div_cancelβ‚€] rfl exact hβ‚‚ apply abs_nonneg rw [div_eq_mul_inv, mul_comm] rw [Real.rpow_mul, Real.rpow_mul] rw [PiLp.norm_eq_sum, PiLp.norm_eq_sum] simp [path] simp; linarith simp; linarith apply sum_nonneg; intro i hi; apply rpow_nonneg; apply abs_nonneg apply sum_nonneg; intro i hi; apply rpow_nonneg; apply abs_nonneg simp; linarith constructor simp rw [Nat.cast_sub] ring_nf apply mul_inv_cancelβ‚€ simp; linarith; linarith apply div_pos simp; linarith; simp; linarith apply div_pos simp; linarith; simp lemma unfold_half_sq_Lp_path (x y : LpSpace p d) : half_sq_Lp ∘ path x y = (2⁻¹ : ℝ) β€’ (Lp_pow_p_path x y) ^ (2 / (p : ℝ)) := by have hp : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by infer_instance have hp := hp.elim simp at hp ext t simp [half_sq_Lp, Lp_pow_p_path] rw [←Real.rpow_natCast_mul, mul_div_cancelβ‚€] simp simp linarith apply norm_nonneg lemma continuousOn_half_sq_Lp_path {x y : LpSpace p d} : ContinuousOn (half_sq_Lp ∘ path x y) (Set.Icc 0 1) := by rw [unfold_half_sq_Lp_path x y] apply ContinuousOn.mul apply continuousOn_const apply ContinuousOn.rpow_const apply continuousOn_Lp_pow_p_path intro t ht apply Or.inr apply div_nonneg simp simp noncomputable def half_sq_Lp_path' (x y : LpSpace p d) : ℝ β†’ ℝ := (p⁻¹ : ℝ) β€’ Lp_pow_p_path x y ^ (2 / (p : ℝ) - 1) * Lp_pow_p_path' x y lemma continuousOn_half_sq_Lp_path' {x y : LpSpace p d} : (βˆ€ t ∈ Set.Icc (0 : ℝ) 1, path x y t β‰  0) β†’ ContinuousOn (half_sq_Lp_path' x y) (Set.Icc 0 1) := by intro ht apply ContinuousOn.mul apply ContinuousOn.mul apply continuousOn_const apply ContinuousOn.rpow_const apply continuousOn_Lp_pow_p_path intro t ht' apply Or.inl apply Lp_pow_p_path_ne_zero apply ht t ht' apply continuousOn_Lp_pow_p_path' lemma hasDerivAt_half_sq_Lp_path (hp : 2 ≀ p) (x y : LpSpace p d) : βˆ€ t : ℝ, path x y t β‰  0 β†’ HasDerivAt (half_sq_Lp ∘ path x y) (half_sq_Lp_path' x y t) t := by intro t ht rw [unfold_half_sq_Lp_path x y] have := (hasDerivAt_Lp_pow_p_path hp x y t) have := this.rpow_const (p := 2 / (p : ℝ)) ?_ have := this.const_mul (2⁻¹ : ℝ) apply HasDerivAt.congr_congr this ext t simp rw [half_sq_Lp_path'] simp ring apply Or.inl apply Lp_pow_p_path_ne_zero exact ht noncomputable def half_sq_Lp_path'' (x y : LpSpace p d) : ℝ β†’ ℝ := (p⁻¹ : ℝ) β€’ ((2 / (p : ℝ) - 1) β€’ Lp_pow_p_path x y ^ (2 / (p : ℝ) - 2) * Lp_pow_p_path' x y ^ 2 + Lp_pow_p_path x y ^ (2 / (p : ℝ) - 1) * Lp_pow_p_path'' x y) lemma hasDerivAt_half_sq_Lp_path' (hp : 2 ≀ p) (x y : LpSpace p d) : βˆ€ t, path x y t β‰  0 β†’ HasDerivAt (half_sq_Lp_path' x y) (half_sq_Lp_path'' x y t) t := by intro t ht unfold half_sq_Lp_path' apply HasDerivAt.congr_deriv apply HasDerivAt.mul apply HasDerivAt.const_mul apply HasDerivAt.rpow_const apply hasDerivAt_Lp_pow_p_path exact hp apply Or.inl apply Lp_pow_p_path_ne_zero exact ht apply hasDerivAt_Lp_pow_p_path' exact hp rw [half_sq_Lp_path''] simp rw [mul_add] nth_rw 4 [←mul_assoc] simp rw [mul_assoc] simp apply Or.inl ring_nf lemma bdd_half_sq_Lp_path'' (x y : LpSpace p d) (t : ℝ) (hp : 2 < p) : path x y t β‰  0 β†’ half_sq_Lp_path'' x y t ≀ (p - 1) * 2 * half_sq_Lp (x - y) := by intro hxy simp [half_sq_Lp_path''] rw [mul_add, add_comm] apply add_le_of_le_of_nonpos grw [bdd_Lp_pow_path''] apply le_of_eq move_mul [←(p : ℝ)] rw [mul_inv_cancelβ‚€] move_mul [(p : ℝ) - 1] simp apply Or.inl simp [Lp_pow_p_path] rw [←Real.rpow_natCast_mul, mul_sub, mul_div_cancelβ‚€, ←Real.rpow_add_natCast] simp rw [Nat.cast_sub, sub_add_sub_cancel] simp [half_sq_Lp] rw [←neg_sub, norm_neg] linarith simp [hxy] simp; linarith apply norm_nonneg simp; linarith unfold Lp_pow_p_path apply rpow_nonneg apply rpow_nonneg apply norm_nonneg linarith apply le_of_neg_le_neg rw [neg_mul_eq_mul_neg, neg_mul_eq_neg_mul, neg_sub] simp apply mul_nonneg simp apply mul_nonneg rw [sub_div'] apply div_nonneg simp; linarith simp simp; linarith apply mul_nonneg apply rpow_nonneg unfold Lp_pow_p_path apply rpow_nonneg apply norm_nonneg apply sq_nonneg lemma smooth_half_sq_Lp_ne (hp : 2 < p) : βˆ€ (x y : LpSpace p d), (βˆ€ t ∈ Set.Icc (0 : ℝ) 1, path x y t β‰  0) β†’ half_sq_Lp y ≀ half_sq_Lp x + βŸͺtoL2 (half_sq_Lp' x), toL2 (y - x)⟫ + (p - 1) * half_sq_Lp (y - x) := by intro x y hxy have : half_sq_Lp_path' x y 0 = βŸͺtoL2 (half_sq_Lp' x), toL2 (y - x)⟫ := by -- Unfold LHS: half_sq_Lp_path' x y = (p⁻¹ : ℝ) β€’ Lp_pow_p_path x y ^ (2 / p - 1) * Lp_pow_p_path' x y simp only [half_sq_Lp_path', Pi.smul_apply, Pi.mul_apply, smul_eq_mul, Pi.pow_apply] -- At t = 0: path x y 0 = x, Lp_pow_p_path x y 0 = β€–xβ€–^p have hpath0 : path x y 0 = x := by simp [path] have hLp_pow_0 : Lp_pow_p_path x y 0 = β€–xβ€– ^ (p : ℝ) := by simp [Lp_pow_p_path, hpath0] have hLp_pow'_0 : Lp_pow_p_path' x y 0 = βˆ‘ i, p * |x.ofLp i| ^ (p - 2) * x.ofLp i * (y.ofLp i - x.ofLp i) := by simp [Lp_pow_p_path'] rw [hLp_pow_0, hLp_pow'_0] -- Simplify LHS: p⁻¹ * (β€–xβ€–^p)^(2/p - 1) * (βˆ‘ i, p * |x.ofLp i|^(p-2) * x.ofLp i * (y.ofLp i - x.ofLp i)) -- Use Real.rpow_mul to simplify (β€–xβ€– ^ p) ^ (2 / p - 1) = β€–xβ€– ^ (p * (2/p - 1)) = β€–xβ€– ^ (2 - p) have hp_ne : (p : ℝ) β‰  0 := by simp; linarith rw [←Real.rpow_mul (norm_nonneg _)] have hexp : (p : ℝ) * (2 / (p : ℝ) - 1) = 2 - (p : ℝ) := by field_simp rw [hexp] -- Now LHS is: (↑p)⁻¹ * β€–xβ€–^(2 - p) * (βˆ‘ i, ↑p * |x.ofLp i|^(p-2) * x.ofLp i * (y.ofLp i - x.ofLp i)) -- Unfold RHS using inner product rw [toL2, toL2, half_sq_Lp', PiLp.inner_apply] simp only [WithLp.ofLp_sub, Pi.sub_apply, RCLike.inner_apply, conj_trivial] -- Distribute the scalar into the sum rw [mul_sum] apply sum_congr rfl intro i _ -- Both sides have the same terms, just arranged differently -- Need to equate |x.ofLp i|^(p-2 : β„•) with |x.ofLp i|^((p : ℝ) - 2) have hpow_eq : |x.ofLp i| ^ (p - 2) = |x.ofLp i| ^ ((p : ℝ) - 2) := by rw [← Real.rpow_natCast |x.ofLp i| (p - 2)] congr 1 simp [Nat.cast_sub hp.le] simp only [hpow_eq] -- Goal: (↑p)⁻¹ * β€–xβ€–^(2-↑p) * (↑p * ... * (y.ofLp i - x.ofLp i)) = (y.ofLp i - x.ofLp i) * (...) field_simp rw [←this] let I := Set.Ioo (0 : ℝ) 1 have hI : βˆ€ t ∈ I, path x y t β‰  0 := by intro t ht apply hxy t ?_ simp [I] at ht exact ⟨ht.1.le, ht.2.le⟩ let Ο† := half_sq_Lp ∘ path x y let Ο†' := half_sq_Lp_path' x y let Ο†'' := half_sq_Lp_path'' x y let f := fun t => Ο† t - Ο† 0 - Ο†' 0 * t let f' := fun t => Ο†' t - Ο†' 0 have hfDeriv : βˆ€ t ∈ I, HasDerivAt f (f' t) t := by intro t ht apply HasDerivAt.congr_deriv apply HasDerivAt.sub apply HasDerivAt.sub apply hasDerivAt_half_sq_Lp_path linarith apply hI t ht apply hasDerivAt_const apply HasDerivAt.const_mul apply hasDerivAt_id simp [f', Ο†'] let C := Ο† 1 - Ο† 0 - Ο†' 0 let g := fun t => f t - C * t ^2 let g' := fun t => f' t - 2 * C * t have hgDeriv : βˆ€ t ∈ I, HasDerivAt g (g' t) t := by intro t ht apply HasDerivAt.congr_deriv apply HasDerivAt.sub apply hfDeriv t ht apply HasDerivAt.const_mul apply HasDerivAt.pow apply hasDerivAt_id simp [g', f', Ο†'] ring have := exists_hasDerivAt_eq_slope g g' (a := 0) (b := 1) (by simp) ?_ hgDeriv obtain ⟨z₁, hz₁I, hzβ‚βŸ© := this simp at hz₁I simp [g, f, C, g'] at hz₁ let h := fun t => f' t - 2 * C * t let h' := fun t => Ο†'' t - 2 * C have hhDeriv : βˆ€ t ∈ Set.Ioo 0 z₁, HasDerivAt h (h' t) t := by intro t ht apply HasDerivAt.congr_deriv apply HasDerivAt.sub unfold f' apply HasDerivAt.sub apply hasDerivAt_half_sq_Lp_path' linarith apply hxy simp at ht ⊒ constructor linarith linarith apply hasDerivAt_const apply HasDerivAt.const_mul apply hasDerivAt_id simp [h', Ο†''] have := exists_hasDerivAt_eq_slope h h' (a := 0) (b := z₁) hz₁I.1 ?_ hhDeriv obtain ⟨zβ‚‚, hzβ‚‚I, hzβ‚‚βŸ© := this simp at hzβ‚‚I have : h 0 = 0 := by simp [h, f'] rw [this] at hzβ‚‚ have : h z₁ = 0 := by simp [h, C] exact hz₁ rw [this] at hzβ‚‚ simp at hzβ‚‚ simp [h', C] at hzβ‚‚ have := eq_of_sub_eq_zero hzβ‚‚ have : Ο† 1 = Ο† 0 + Ο†' 0 * 1 + 1 / 2 * Ο†'' zβ‚‚ := by rw [this] ring simp [Ο†, Ο†', Ο†'', path] at this rw [this] apply add_le_add_three rfl rfl grw [bdd_half_sq_Lp_path'' x y zβ‚‚] unfold half_sq_Lp apply le_of_eq rw [←norm_neg, neg_sub] ring linarith apply hxy simp; constructor; linarith; linarith simp [h, f', Ο†'] apply ContinuousOn.sub apply ContinuousOn.sub apply ContinuousOn.mono (by apply continuousOn_half_sq_Lp_path' hxy) intro t ht simp at ht ⊒ constructor; linarith; linarith apply continuousOn_const apply ContinuousOn.mul apply continuousOn_const apply continuousOn_id simp [g, f, Ο†, Ο†'] apply ContinuousOn.sub apply ContinuousOn.sub apply ContinuousOn.sub apply continuousOn_half_sq_Lp_path apply continuousOn_const apply ContinuousOn.mul apply continuousOn_const apply continuousOn_id apply ContinuousOn.mul apply continuousOn_const apply ContinuousOn.pow apply continuousOn_id end smooth theorem smooth_half_sq_Lp (hp : 2 ≀ p) : βˆ€ (x y : LpSpace p d), half_sq_Lp y ≀ half_sq_Lp x + βŸͺtoL2 (half_sq_Lp' x), toL2 (y - x)⟫ + (p - 1) * half_sq_Lp (y - x) := by have hFact : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) by_cases hp2 : 2 = p case pos => -- Case p = 2: Use inner product space identity intro x y subst hp2 simp only [half_sq_Lp, toL2, half_sq_Lp'] apply (mul_le_mul_iff_of_pos_left (by norm_num : (0 : ℝ) < 2)).mp simp_rw [mul_add] simp only [Nat.cast_ofNat, sub_self, Real.rpow_zero, one_mul, mul_one] -- Simplify LHS and RHS have hlhs : 2 * (1 / 2 * β€–yβ€– ^ 2) = β€–yβ€– ^ 2 := by ring have hrhs1 : 2 * (1 / 2 * β€–xβ€– ^ 2) = β€–xβ€– ^ 2 := by ring have hrhs3 : 2 * ((2 - 1) * (1 / 2 * β€–y - xβ€– ^ 2)) = β€–y - xβ€– ^ 2 := by ring rw [hlhs, hrhs1, hrhs3] -- Key: y = x + (y - x), and for p=2 we use E d which has inner product structure have heq : y = x + (y - x) := by simp conv_lhs => rw [heq] -- Convert to E d where we have InnerProductSpace let x' : E d := WithLp.toLp 2 x.ofLp let y' : E d := WithLp.toLp 2 y.ofLp let diff' : E d := WithLp.toLp 2 (y - x).ofLp -- Use norm_add_sq_real on E d have hexpand := norm_add_sq_real (F := E d) x' diff' -- Norms are preserved: β€–xβ€– = β€–x'β€–, β€–y-xβ€– = β€–diff'β€–, β€–x+(y-x)β€– = β€–x'+diff'β€– have hnorm_x : β€–xβ€– = β€–x'β€– := by simp only [x', WithLp.toLp_ofLp] have hnorm_diff : β€–y - xβ€– = β€–diff'β€– := by simp only [diff', WithLp.toLp_ofLp] have hnorm_sum : β€–x + (y - x)β€– = β€–x' + diff'β€– := by have heq_args : x + (y - x) = x' + diff' := by ext i simp only [x', diff', WithLp.ofLp_add, Pi.add_apply] rw [heq_args] -- The inner product in the goal uses toL2 have hinner_eq : βŸͺWithLp.toLp 2 (fun i => x.ofLp i), WithLp.toLp 2 (y - x).ofLp⟫ = βŸͺx', diff'⟫_ℝ := by rfl rw [hinner_eq, hnorm_x, hnorm_diff, hnorm_sum] linarith case neg => -- Case p > 2: Defer to smooth_half_sq_Lp_ne and limit argument have hp' : 2 < p := lt_of_le_of_ne hp hp2 intro x y by_cases hxy : βˆ€ t ∈ Set.Icc (0 : ℝ) 1, path x y t β‰  0 case pos => exact smooth_half_sq_Lp_ne hp' x y hxy -- If the path passes through 0, use a limiting argument push_neg at hxy obtain ⟨t, htI, htx⟩ := hxy by_cases hx : x = 0 case pos => simp only [half_sq_Lp, toL2, half_sq_Lp'] rw [hx] simp only [norm_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow, mul_zero, sub_zero, zero_add] have hp2_ne : 2 - (p : ℝ) β‰  0 := by have : (2 : ℝ) < p := Nat.ofNat_lt_cast.mpr hp' linarith have hpp2_ne : (p : ℝ) - 2 β‰  0 := by have : (2 : ℝ) < p := Nat.ofNat_lt_cast.mpr hp' linarith -- Simplify: 0^(2-p) = 0, |0|^(p-2) = 0, etc. All terms in the gradient become 0 have hgrad_zero : (fun i => (0 : ℝ) ^ (2 - (p : ℝ)) * |WithLp.ofLp (0 : LpSpace p d) i| ^ ((p : ℝ) - 2) * WithLp.ofLp (0 : LpSpace p d) i) = fun _ => 0 := by ext i simp only [WithLp.ofLp_zero, Pi.zero_apply, abs_zero, Real.zero_rpow hpp2_ne, mul_zero] -- The gradient at 0 is the zero vector have hgrad_is_zero : (WithLp.toLp 2 fun i => (0 : ℝ) ^ (2 - (p : ℝ)) * |WithLp.ofLp (0 : LpSpace p d) i| ^ ((p : ℝ) - 2) * WithLp.ofLp (0 : LpSpace p d) i) = 0 := by rw [hgrad_zero] rfl rw [hgrad_is_zero] simp only [inner_zero_left, zero_add] apply le_mul_of_one_le_left Β· positivity Β· apply le_sub_iff_add_le.mpr rw [one_add_one_eq_two] have : (2 : ℝ) ≀ p := Nat.ofNat_le_cast.mpr hp linarith -- x β‰  0 case with path through 0 - use perturbation argument have htpos : 0 < t := by by_contra h simp only [not_lt] at h simp only [Set.mem_Icc] at htI have ht0 := eq_of_le_of_ge htI.1 h simp only [path] at htx rw [← ht0] at htx simp only [zero_smul, add_zero] at htx exact hx htx by_cases hd0 : d = 0 case pos => subst hd0 simp only [half_sq_Lp] -- For d = 0, all norms are 0 have hp_real_pos : (0 : ℝ) < p := by simp; omega have hnorm0 : βˆ€ z : LpSpace p 0, β€–zβ€– = 0 := by intro z rw [PiLp.norm_eq_sum (p := p) (by simp; linarith)] simp only [Finset.univ_eq_empty, Finset.sum_empty] have h_toReal : (p : ℝβ‰₯0∞).toReal = (p : ℝ) := by simp rw [h_toReal] have h_ne : 1 / (p : ℝ) β‰  0 := by apply one_div_ne_zero linarith rw [Real.zero_rpow h_ne] rw [hnorm0, hnorm0, hnorm0] simp only [ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow, mul_zero, zero_add] -- The inner product is also 0 for d = 0 have hinner0 : βŸͺtoL2 (half_sq_Lp' x), toL2 (y - x)⟫ = 0 := by simp only [toL2, half_sq_Lp'] -- For d = 0, the inner product on E 0 is trivially 0 rw [PiLp.inner_apply] simp only [Finset.univ_eq_empty, Finset.sum_empty] rw [hinner0] norm_num by_cases hd1 : d ≀ 1 case pos => -- d = 1 case: reduce to 1-dimensional problem have hd' : d = 1 := by omega subst hd' simp only [half_sq_Lp, toL2, half_sq_Lp'] -- For d = 1, the unique index is 0 : Fin 1 have hnorm_eq : βˆ€ z : LpSpace p 1, β€–zβ€– = |z.ofLp 0| := by intro z rw [PiLp.norm_eq_sum (p := p) (by simp; linarith)] simp only [Fin.sum_univ_one, Fin.isValue] have h_toReal : (p : ℝβ‰₯0∞).toReal = (p : ℝ) := by simp rw [h_toReal] have hp_ne : (p : ℝ) β‰  0 := by simp; linarith have hp_pos : (0 : ℝ) < p := by simp; linarith -- (β€–z.ofLp 0β€– ^ ↑p) ^ (1/↑p) = |z.ofLp 0| since β€–Β·β€– = |Β·| for reals have hnorm_abs : β€–z.ofLp 0β€– = |z.ofLp 0| := Real.norm_eq_abs _ rw [hnorm_abs] -- (|z.ofLp 0| ^ ↑p) ^ (1/↑p) = |z.ofLp 0| rw [← Real.rpow_mul (abs_nonneg _)] simp only [mul_one_div_cancel hp_ne, Real.rpow_one] simp_rw [hnorm_eq, WithLp.ofLp_sub, Pi.sub_apply] apply (mul_le_mul_iff_of_pos_left (by norm_num : (0 : ℝ) < 2)).mp simp only [mul_add] have heq : |y.ofLp 0| = |x.ofLp 0 + (y.ofLp 0 - x.ofLp 0)| := by congr 1 ring conv_lhs => rw [heq] -- Now goal is |x.ofLp 0 + (y.ofLp 0 - x.ofLp 0)|Β² ≀ ... with absolute values -- Use the fact that for p > 2, the inequality holds -- Simplify inner product for d=1 have hinner : βŸͺWithLp.toLp 2 fun i => |x.ofLp 0| ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i, WithLp.toLp 2 (y.ofLp - x.ofLp)⟫ = |x.ofLp 0| ^ (2 - (p : ℝ)) * |x.ofLp 0| ^ ((p : ℝ) - 2) * x.ofLp 0 * (y.ofLp 0 - x.ofLp 0) := by rw [PiLp.inner_apply, Fin.sum_univ_one] simp only [Fin.isValue, Pi.sub_apply, RCLike.inner_apply, conj_trivial] ring rw [hinner] -- Simplify |x.ofLp 0|^(2-p) * |x.ofLp 0|^(p-2) = 1 when x.ofLp 0 β‰  0, or = 0 when x.ofLp 0 = 0 by_cases hx0 : x.ofLp 0 = 0 Β· -- x.ofLp 0 = 0 case simp only [hx0, abs_zero, zero_mul, mul_zero, zero_add, sub_zero, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, zero_pow] have hp_minus_1_ge_1 : (1 : ℝ) ≀ (p : ℝ) - 1 := by have : (2 : ℝ) < p := Nat.ofNat_lt_cast.mpr hp' linarith -- Goal: 2 * (1/2 * |y.ofLp 0|Β²) ≀ 2 * ((p-1) * (1/2 * |y.ofLp 0|Β²)) have h_simpl : 2 * (1 / 2 * |y.ofLp 0| ^ 2) = |y.ofLp 0| ^ 2 := by ring have h_simpl' : 2 * (((p : ℝ) - 1) * (1 / 2 * |y.ofLp 0| ^ 2)) = ((p : ℝ) - 1) * |y.ofLp 0| ^ 2 := by ring rw [h_simpl, h_simpl'] apply le_mul_of_one_le_left (sq_nonneg _) hp_minus_1_ge_1 Β· -- x.ofLp 0 β‰  0 case have habs_pos : 0 < |x.ofLp 0| := abs_pos.mpr hx0 have hpow_eq : |x.ofLp 0| ^ (2 - (p : ℝ)) * |x.ofLp 0| ^ ((p : ℝ) - 2) = 1 := by rw [← Real.rpow_add habs_pos] simp simp only [hpow_eq, one_mul] -- Now: |x + (y-x)|Β² ≀ |x|Β² + 2 * x * (y-x) + (p-1) * |y-x|Β² -- LHS = |y|Β², and we use the identity |y|Β² = |x|Β² + 2*x*(y-x) + |y-x|Β² for reals -- Since p > 2, we have (p-1) > 1, so (p-1)|y-x|Β² β‰₯ |y-x|Β² have h1D : |x.ofLp 0 + (y.ofLp 0 - x.ofLp 0)| ^ 2 = |x.ofLp 0| ^ 2 + 2 * (x.ofLp 0 * (y.ofLp 0 - x.ofLp 0)) + |y.ofLp 0 - x.ofLp 0| ^ 2 := by have hy_eq : x.ofLp 0 + (y.ofLp 0 - x.ofLp 0) = y.ofLp 0 := by ring rw [hy_eq] have hx_eq : y.ofLp 0 = x.ofLp 0 + (y.ofLp 0 - x.ofLp 0) := by ring calc |y.ofLp 0| ^ 2 = y.ofLp 0 ^ 2 := sq_abs _ _ = (x.ofLp 0 + (y.ofLp 0 - x.ofLp 0)) ^ 2 := by rw [← hx_eq] _ = x.ofLp 0 ^ 2 + 2 * (x.ofLp 0 * (y.ofLp 0 - x.ofLp 0)) + (y.ofLp 0 - x.ofLp 0) ^ 2 := by ring _ = |x.ofLp 0| ^ 2 + 2 * (x.ofLp 0 * (y.ofLp 0 - x.ofLp 0)) + |y.ofLp 0 - x.ofLp 0| ^ 2 := by rw [sq_abs, sq_abs] rw [h1D] have hp_minus_1_ge_1 : (1 : ℝ) ≀ p - 1 := by have : (2 : ℝ) < p := Nat.ofNat_lt_cast.mpr hp' linarith have h_last : |y.ofLp 0 - x.ofLp 0| ^ 2 ≀ ((p : ℝ) - 1) * (1 / 2 * |y.ofLp 0 - x.ofLp 0| ^ 2) * 2 := by have hrhs : ((p : ℝ) - 1) * (1 / 2 * |y.ofLp 0 - x.ofLp 0| ^ 2) * 2 = ((p : ℝ) - 1) * |y.ofLp 0 - x.ofLp 0| ^ 2 := by ring rw [hrhs] apply le_mul_of_one_le_left (sq_nonneg _) hp_minus_1_ge_1 linarith case neg => -- d β‰₯ 2: Use perturbation and limiting argument -- This case uses the fact that for x β‰  0 with d β‰₯ 2, we can perturb y slightly -- in a direction orthogonal to x's nonzero components, creating paths y' n β†’ y -- where each path x β†’ y' n doesn't pass through 0, allowing us to apply -- smooth_half_sq_Lp_ne and take the limit. have hxne : βˆƒ i, x.ofLp i β‰  0 := by by_contra h push_neg at h have hx' : x = 0 := by ext i simp only [WithLp.ofLp_zero, Pi.zero_apply] exact h i exact hx hx' obtain ⟨i, hi⟩ := hxne have hjne : βˆƒ j, j β‰  i := by by_cases hi0 : (i : β„•) = 0 case pos => have hd2 : 2 ≀ d := by omega let j := Fin.mk (n := d) 1 hd2 use j apply (Fin.ne_iff_vne j i).mpr simp [hi0] case neg => let j := Fin.mk (n := d) 0 (by omega) use j apply (Fin.ne_iff_vne j i).mpr simp by_contra h exact hi0 h.symm obtain ⟨j, hj⟩ := hjne let u : LpSpace p d := WithLp.toLp p (fun k => if j = k then 1 else 0) let y' := fun k : β„• => y + (1 / ((k : ℝ) + 1)) β€’ u have hxy' : βˆ€ k, βˆ€ s ∈ Set.Icc (0 : ℝ) 1, path x (y' k) s β‰  0 := by intro k by_contra h push_neg at h obtain ⟨s', hs'I, hs'⟩ := h have h₁ := congrFun (congrArg WithLp.ofLp hs') i simp only [path, WithLp.ofLp_add, WithLp.ofLp_smul, WithLp.ofLp_sub, Pi.add_apply, Pi.smul_apply, Pi.sub_apply, smul_eq_mul, WithLp.ofLp_zero, Pi.zero_apply] at h₁ simp only [y', WithLp.ofLp_add, WithLp.ofLp_smul, Pi.add_apply, Pi.smul_apply, smul_eq_mul, u] at h₁ rw [if_neg hj] at h₁ simp only [mul_zero, add_zero] at h₁ have hβ‚‚ := congrFun (congrArg WithLp.ofLp htx) i simp only [path, WithLp.ofLp_add, WithLp.ofLp_smul, WithLp.ofLp_sub, Pi.add_apply, Pi.smul_apply, Pi.sub_apply, smul_eq_mul, WithLp.ofLp_zero, Pi.zero_apply] at hβ‚‚ rw [mul_sub, add_sub, add_comm, sub_eq_iff_eq_add, zero_add] at hβ‚‚ have hβ‚‚' := (sub_eq_iff_eq_add.mpr hβ‚‚.symm).symm have hinv := congrArg (fun z => t⁻¹ * z) hβ‚‚' simp only at hinv rw [←mul_assoc, inv_mul_cancelβ‚€ (htpos.ne')] at hinv simp only [one_mul] at hinv rw [hinv] at h₁ -- h₁ : x.ofLp i + s' * (t⁻¹ * (t * x.ofLp i - x.ofLp i) - x.ofLp i) = 0 -- Let a = x.ofLp i. Then hinv says y.ofLp i = t⁻¹ * (t * a - a) = a - t⁻¹ * a -- So h₁ says: a + s' * ((a - t⁻¹ * a) - a) = 0 -- = a + s' * (-t⁻¹ * a) = 0 -- = a - s' * t⁻¹ * a = 0 -- = a * (1 - s' * t⁻¹) = 0 have ht_ne : t β‰  0 := htpos.ne' have h₁' : x.ofLp i * (1 - s' * t⁻¹) = 0 := by have hinv_simp : t⁻¹ * (t * x.ofLp i - x.ofLp i) = x.ofLp i - t⁻¹ * x.ofLp i := by field_simp rw [hinv_simp] at h₁ linarith rw [mul_eq_zero] at h₁' rcases h₁' with hl | hr case inl => exact hi hl case inr => have heq : s' * t⁻¹ = 1 := by linarith have hmul : s' = t := by field_simp at heq; linarith -- hmul : s' = t -- We have: hs' : path x (y' k) s' = 0 and htx : path x y t = 0 -- With s' = t, we get path x (y' k) t = 0 -- Subtracting, t β€’ (y - y' k) = 0, so y = y' k -- But y' k = y + Ξ΅β€’u for Ξ΅ > 0, contradiction rw [hmul] at hs' have hdiff : t β€’ (y - y' k) = 0 := by simp only [path] at htx hs' have h1 : x + t β€’ (y - x) = 0 := htx have h2 : x + t β€’ (y' k - x) = 0 := hs' have hcalc : t β€’ (y - y' k) = (x + t β€’ (y - x)) - (x + t β€’ (y' k - x)) := by simp only [smul_sub] abel rw [hcalc, h1, h2, sub_zero] rw [smul_eq_zero] at hdiff rcases hdiff with htfalse | hy_eq case inl => exact ht_ne htfalse case inr => have hy'_def : y' k = y + (1 / ((k : ℝ) + 1)) β€’ u := rfl rw [hy'_def, sub_add_cancel_left, neg_eq_zero, smul_eq_zero] at hy_eq rcases hy_eq with heps_zero | hu_zero case inl => have hk_pos : 0 < 1 / ((k : ℝ) + 1) := by positivity linarith case inr => have hu_j := congrFun (congrArg WithLp.ofLp hu_zero) j simp only [WithLp.ofLp_zero, Pi.zero_apply, u] at hu_j simp only [if_true] at hu_j exact one_ne_zero hu_j have hy' : Tendsto y' atTop (𝓝 y) := by apply tendsto_iff_norm_sub_tendsto_zero.mpr simp only [y'] have heq : βˆ€ k : β„•, β€–y + (1 / ((k : ℝ) + 1)) β€’ u - yβ€– = 1 / ((k : ℝ) + 1) * β€–uβ€– := by intro k rw [add_sub_cancel_left, norm_smul, norm_eq_abs] have hk_nonneg : 0 ≀ 1 / ((k : ℝ) + 1) := by apply div_nonneg (by norm_num : (0 : ℝ) ≀ 1) linarith [Nat.cast_nonneg (Ξ± := ℝ) k] rw [abs_of_nonneg hk_nonneg] simp_rw [heq] have := tendsto_one_div_add_atTop_nhds_zero_nat.mul_const β€–uβ€– simp only [zero_mul] at this exact this have hlhs := (continuous_half_sq_Lp.tendsto y).comp hy' have hcont_toL2 : Continuous (toL2 (p := p) (d := d)) := by unfold toL2 have h1 := (PiLp.lipschitzWith_ofLp p (fun _ : Fin d => ℝ)).continuous have h2 := (PiLp.lipschitzWith_toLp 2 (fun _ : Fin d => ℝ)).continuous exact h2.comp h1 have hcont : Continuous fun z => half_sq_Lp x + βŸͺtoL2 (half_sq_Lp' x), toL2 (z - x)⟫ + (p - 1) * half_sq_Lp (z - x) := by apply Continuous.add apply Continuous.add apply continuous_const apply Continuous.inner apply continuous_const apply hcont_toL2.comp apply Continuous.sub continuous_id continuous_const apply Continuous.mul apply continuous_const apply continuous_half_sq_Lp.comp apply Continuous.sub continuous_id continuous_const have hrhs := (hcont.tendsto y).comp hy' apply le_of_tendsto_of_tendsto' hlhs hrhs intro k exact smooth_half_sq_Lp_ne hp' x (y' k) (hxy' k) section norm_equivalence lemma Lp_le_L2 {x : LpSpace p d} (hp : 2 ≀ p) : β€–xβ€– ≀ β€–toL2 xβ€– := by have : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) conv_rhs => rw [←one_mul (a := β€–toL2 xβ€–)] by_cases hx : β€–toL2 xβ€– = 0 case pos => simp [toL2] at hx simp [hx] apply (inv_mul_le_iffβ‚€' ?_).mp rw [PiLp.norm_eq_sum (p := p)] simp have : (β€–toL2 x‖⁻¹ ^ p) ^ ((p : ℝ))⁻¹ = β€–toL2 x‖⁻¹ := by rw [←Real.rpow_natCast_mul, mul_inv_cancelβ‚€] simp simp; linarith simp rw [←this] rw [←Real.mul_rpow, mul_sum] apply Real.rpow_le_one apply sum_nonneg; intro i hi; positivity conv_lhs => congr; rfl; ext i; rw [←mul_pow] have : β€–toL2 (β€–toL2 x‖⁻¹ β€’ x)β€– = 1 := by simp [toL2] rw [norm_smul] simp apply inv_mul_cancelβ‚€ simp [toL2] at hx simp [hx] rw [PiLp.norm_eq_sum] at this simp at this nth_rw 2 [←one_div] at this rw [←Real.sqrt_eq_rpow, Real.sqrt_eq_one] at this nth_rw 1 [toL2] at this rw [←this] apply sum_le_sum simp intro i rw [←sq_abs, abs_mul, abs_inv] simp apply pow_le_pow_of_le_one positivity apply (sq_le_one_iffβ‚€ (by positivity)).mp rw [←this] conv_rhs => congr; rfl; ext i; simp rw [←sq_abs, abs_mul, abs_inv] simp apply single_le_sum (f := fun i => (β€–toL2 x‖⁻¹ * |x i|) ^ 2) intro i hi; positivity simp linarith simp positivity positivity positivity simp linarith simp simp at hx exact hx lemma L2_le_Lp (hp : 2 ≀ p) : βˆƒ C : ℝ, 0 ≀ C ∧ βˆ€ x : LpSpace p d, β€–toL2 xβ€– ≀ C * β€–xβ€– := by use ((d : ℝ) ^ (((p : ℝ) - 2) / p)) ^ (2⁻¹ : ℝ) constructor Β· positivity intro x simp only [toL2] by_cases hp2 : 2 = p case pos => subst hp2 simp only [WithLp.toLp_ofLp] -- When p = 2, the constant is (d^((2-2)/2))^(1/2) = (d^0)^(1/2) = 1^(1/2) = 1 have hconst : ((d : ℝ) ^ ((((2 : β„•) : ℝ) - 2) / (2 : β„•))) ^ (2⁻¹ : ℝ) = 1 := by simp only [Nat.cast_ofNat, sub_self, zero_div, Real.rpow_zero, Real.one_rpow] rw [hconst, one_mul] case neg => -- Use PiLp.norm_eq_sum to expand both norms have hp_pos : (0 : ℝ) < p := by simp; omega have h2_pos : (0 : ℝ) < 2 := by norm_num have hp_ne : (p : ℝ) β‰  0 := by linarith have h2_ne : (2 : ℝ) β‰  0 := by norm_num have hp' : 2 < p := lt_of_le_of_ne hp hp2 -- Expand β€–toL2 xβ€– = β€–WithLp.toLp 2 x.ofLpβ€– have htoL2_norm : β€–WithLp.toLp 2 x.ofLpβ€– = (βˆ‘ i, |x.ofLp i| ^ (2 : ℝ)) ^ (1 / 2 : ℝ) := by rw [PiLp.norm_eq_sum (p := 2) (by simp)] simp only [ENNReal.toReal_ofNat, one_div, Real.norm_eq_abs] -- Expand β€–xβ€– have hx_norm : β€–xβ€– = (βˆ‘ i, |x.ofLp i| ^ (p : ℝ)) ^ (1 / (p : ℝ)) := by rw [PiLp.norm_eq_sum (p := p) (by simp; linarith)] simp only [one_div, Real.norm_eq_abs, ENNReal.toReal_natCast] rw [htoL2_norm, hx_norm] -- Apply HΓΆlder's inequality: βˆ‘|x_i|^2 ≀ (βˆ‘|x_i|^p)^(2/p) * d^((p-2)/p) have hHolder := Real.inner_le_Lp_mul_Lq (p := (p : ℝ) / 2) (q := (p : ℝ) / (p - 2)) (f := fun i => |x.ofLp i| ^ 2) (g := fun _ => (1 : ℝ)) Finset.univ ?hpq case hpq => refine ⟨?_, ?_, ?_⟩ Β· -- 2/p + (p-2)/p = p/p = 1 field_simp ring Β· apply div_pos (by linarith) h2_pos Β· have hp_lt : (2 : ℝ) < p := Nat.ofNat_lt_cast.mpr hp' apply div_pos (by linarith) (by linarith) simp only [mul_one, abs_one, Real.one_rpow, Finset.sum_const, Finset.card_univ, Fintype.card_fin, nsmul_eq_mul] at hHolder -- Simplify |abs(x_i)^2| = |x_i|^2 since |x_i|^2 β‰₯ 0 have habs_pow2 : βˆ€ i, |((|x.ofLp i|) ^ 2)| = |x.ofLp i| ^ 2 := by intro i apply abs_of_nonneg apply sq_nonneg simp only [habs_pow2] at hHolder -- Simplify (|x_i|^2)^(p/2) = |x_i|^p have hsimp_pow : βˆ€ i, (|x.ofLp i| ^ 2) ^ ((p : ℝ) / 2) = |x.ofLp i| ^ (p : ℝ) := by intro i rw [← Real.rpow_natCast, ← Real.rpow_mul (abs_nonneg _)] simp only [Nat.cast_ofNat] field_simp simp only [hsimp_pow] at hHolder -- Convert β„• exponent to ℝ exponent in the sum have hnat_to_real_pow : βˆ€ i, |x.ofLp i| ^ (2 : β„•) = |x.ofLp i| ^ (2 : ℝ) := by intro i rw [← Real.rpow_natCast] simp simp only [hnat_to_real_pow] at hHolder -- Now raise both sides to the power 1/2 have hsum_nonneg : 0 ≀ βˆ‘ i, |x.ofLp i| ^ (2 : ℝ) := by apply Finset.sum_nonneg intro i _ apply Real.rpow_nonneg (abs_nonneg _) have hrhs_nonneg : 0 ≀ (βˆ‘ i, |x.ofLp i| ^ (p : ℝ)) ^ (2 / (p : ℝ)) * (d : ℝ) ^ (((p : ℝ) - 2) / (p : ℝ)) := by apply mul_nonneg Β· apply Real.rpow_nonneg apply Finset.sum_nonneg intro i _ apply Real.rpow_nonneg (abs_nonneg _) Β· apply Real.rpow_nonneg simp have hpow_mono := Real.rpow_le_rpow hsum_nonneg hHolder (by norm_num : (0 : ℝ) ≀ 1 / 2) -- Simplify: (βˆ‘|x_i|^2)^(1/2) ≀ ((βˆ‘|x_i|^p)^(1/(p/2)) * d^(1/(p/(p-2))))^(1/2) rw [Real.mul_rpow (Real.rpow_nonneg (Finset.sum_nonneg (fun i _ => Real.rpow_nonneg (abs_nonneg _) _)) _) (Real.rpow_nonneg (by simp) _)] at hpow_mono -- (a^(1/(p/2)))^(1/2) = a^(1/p) have hexp1 : (1 / ((p : ℝ) / 2)) * (1 / 2) = 1 / (p : ℝ) := by field_simp rw [← Real.rpow_mul (Finset.sum_nonneg (fun i _ => Real.rpow_nonneg (abs_nonneg _) _)), hexp1] at hpow_mono -- (d^(1/(p/(p-2))))^(1/2) = (d^((p-2)/p))^(1/2) have hexp2_eq : (1 : ℝ) / ((p : ℝ) / (↑p - 2)) = (↑p - 2) / ↑p := by field_simp rw [hexp2_eq] at hpow_mono have hexp2 : (((p : ℝ) - 2) / (p : ℝ)) * (1 / 2) = ((p : ℝ) - 2) / (p : ℝ) * 2⁻¹ := by ring rw [← Real.rpow_mul (by simp : (0 : ℝ) ≀ d), hexp2, Real.rpow_mul (by simp : (0 : ℝ) ≀ d)] at hpow_mono rw [mul_comm] at hpow_mono exact hpow_mono -- NOTE: This notation converts the underlying function to the L∞ space local notation (priority := 2000) "β€–" x "β€–βˆž" => β€–WithLp.toLp ⊀ (WithLp.ofLp x)β€– lemma nnreal_toReal_sup_eq_sup' {ΞΉ} {s : Finset ΞΉ} (hs : s.Nonempty) {x : ΞΉ β†’ ℝβ‰₯0} : (s.sup x).toReal = s.sup' hs (fun i => (x i).toReal) := by obtain ⟨i, his, hi⟩ := exists_mem_eq_sup' hs x apply le_antisymm simp use i constructor exact his rw [←hi] intro j hj apply (le_sup'_iff hs).mpr use j simp intro j hj apply le_sup_of_le hj rfl lemma infty_norm_eq_norm {Ξ±} [Fintype Ξ±] [Nonempty Ξ±] {f : Ξ± β†’ ℝ} : β€–WithLp.toLp ⊀ fβ€– = β€–fβ€– := PiLp.norm_toLp f lemma Linfty_le_Lp {x : LpSpace p d} (hp : 1 ≀ p) : β€–xβ€–βˆž ≀ β€–xβ€– := by have hfact : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) -- β€–xβ€–βˆž = β€–WithLp.toLp ⊀ (WithLp.ofLp x)β€– = β€–x.ofLpβ€–_Pi -- We need to show β€–x.ofLpβ€–_Pi ≀ β€–xβ€– rw [PiLp.norm_toLp] -- Use pi_norm_le_iff_of_nonneg: β€–fβ€– ≀ r ↔ βˆ€ i, β€–f iβ€– ≀ r (when r β‰₯ 0) rw [pi_norm_le_iff_of_nonneg (norm_nonneg x)] -- Now we need: βˆ€ i, β€–x.ofLp iβ€– ≀ β€–xβ€– intro i exact PiLp.norm_apply_le x i lemma Lp_le_Linfty {x : LpSpace p d} (hp : 1 ≀ p) : β€–xβ€– ≀ (d : ℝ) ^ (1 / (p : ℝ)) * β€–xβ€–βˆž := by have hfact : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) have hp_pos : (0 : ℝ) < p := by have : (1 : β„•) ≀ p := hp have : (1 : ℝ) ≀ (p : ℝ) := Nat.one_le_cast.mpr this linarith have hp_ne : (p : ℝ) β‰  0 := by linarith -- β€–xβ€– = (βˆ‘α΅’ β€–x.ofLp iβ€–^p)^(1/p) have hp_toReal_pos : 0 < (p : ℝβ‰₯0∞).toReal := by simp [hp_pos] rw [PiLp.norm_eq_sum hp_toReal_pos] simp only [ENNReal.toReal_natCast] -- β€–xβ€–βˆž = β€–x.ofLpβ€–_Pi = sup over components rw [PiLp.norm_toLp] -- Each component β€–x.ofLp iβ€– ≀ β€–x.ofLpβ€–_Pi have hcomp_le : βˆ€ i, β€–x.ofLp iβ€– ≀ β€–x.ofLpβ€– := fun i => norm_le_pi_norm (x.ofLp) i -- Sum bound: βˆ‘α΅’ β€–x.ofLp iβ€–^p ≀ βˆ‘α΅’ β€–x.ofLpβ€–^p = d * β€–x.ofLpβ€–^p have hsum_le : βˆ‘ i : Fin d, β€–x.ofLp iβ€– ^ (p : ℝ) ≀ d * β€–x.ofLpβ€– ^ (p : ℝ) := by calc βˆ‘ i : Fin d, β€–x.ofLp iβ€– ^ (p : ℝ) ≀ βˆ‘ i : Fin d, β€–x.ofLpβ€– ^ (p : ℝ) := by apply Finset.sum_le_sum intro i _ apply Real.rpow_le_rpow (norm_nonneg _) (hcomp_le i) (by linarith) _ = d * β€–x.ofLpβ€– ^ (p : ℝ) := by simp [Finset.sum_const] -- Take p-th root of both sides have hsum_nonneg : 0 ≀ βˆ‘ i : Fin d, β€–x.ofLp iβ€– ^ (p : ℝ) := by apply Finset.sum_nonneg intro i _ apply Real.rpow_nonneg (norm_nonneg _) have hrhs_nonneg : 0 ≀ d * β€–x.ofLpβ€– ^ (p : ℝ) := by apply mul_nonneg (by simp) (Real.rpow_nonneg (norm_nonneg _) _) have hroot := Real.rpow_le_rpow hsum_nonneg hsum_le (by positivity : 0 ≀ 1 / (p : ℝ)) -- Simplify RHS: (d * β€–x.ofLpβ€–^p)^(1/p) = d^(1/p) * β€–x.ofLpβ€– rw [Real.mul_rpow (by simp : (0 : ℝ) ≀ d) (Real.rpow_nonneg (norm_nonneg _) _)] at hroot rw [← Real.rpow_mul (norm_nonneg _), mul_one_div_cancel hp_ne, Real.rpow_one] at hroot exact hroot end norm_equivalence section inner lemma inner_gradient_half_sq_Lp_self (hp : 1 ≀ p) (x : LpSpace p d) : βŸͺtoL2 (half_sq_Lp' x), toL2 x⟫ = β€–xβ€– ^ 2 := by have hfact : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) have hp_pos : (0 : ℝ) < p := by have : (1 : β„•) ≀ p := hp have : (1 : ℝ) ≀ (p : ℝ) := Nat.one_le_cast.mpr this linarith have hp_ne : (p : ℝ) β‰  0 := by linarith -- Expand the inner product using PiLp.inner_apply simp only [toL2, half_sq_Lp'] rw [PiLp.inner_apply] simp only [RCLike.inner_apply, conj_trivial] -- The sum is: βˆ‘ i, (β€–xβ€–^(2-p) * |x.ofLp i|^(p-2) * x.ofLp i) * x.ofLp i -- = βˆ‘ i, β€–xβ€–^(2-p) * |x.ofLp i|^(p-2) * (x.ofLp i)^2 -- = β€–xβ€–^(2-p) * βˆ‘ i, |x.ofLp i|^(p-2) * |x.ofLp i|^2 (since (x.ofLp i)^2 = |x.ofLp i|^2) -- = β€–xβ€–^(2-p) * βˆ‘ i, |x.ofLp i|^p -- = β€–xβ€–^(2-p) * β€–xβ€–^p (by definition of Lp norm) -- = β€–xβ€–^2 have h1 : (p : ℝ) - 2 + 2 = p := by ring -- Simplify each term in the sum have hterm : βˆ€ i, β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i * x.ofLp i = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ (p : ℝ) := by intro i -- x.ofLp i * x.ofLp i = |x.ofLp i|^2 have hsq : x.ofLp i * x.ofLp i = |x.ofLp i| ^ (2 : ℝ) := by have h1 : x.ofLp i * x.ofLp i = (x.ofLp i) ^ 2 := by ring have h2 : |x.ofLp i| ^ 2 = (x.ofLp i) ^ 2 := sq_abs _ rw [h1, ← h2, ← Real.rpow_natCast] simp only [Nat.cast_ofNat] -- |x.ofLp i|^(p-2) * |x.ofLp i|^2 = |x.ofLp i|^p have hp_sum_ne : ((p : ℝ) - 2) + 2 β‰  0 := by linarith calc β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i * x.ofLp i = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * (x.ofLp i * x.ofLp i) := by ring _ = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * |x.ofLp i| ^ (2 : ℝ) := by rw [hsq] _ = β€–xβ€– ^ (2 - (p : ℝ)) * (|x.ofLp i| ^ ((p : ℝ) - 2) * |x.ofLp i| ^ (2 : ℝ)) := by ring _ = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2 + 2) := by rw [← Real.rpow_add' (abs_nonneg _) hp_sum_ne] _ = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ (p : ℝ) := by ring_nf -- The goal sum has form: βˆ‘ i, x.ofLp i * (β€–xβ€– ^ (2 - p) * |x.ofLp i| ^ (p - 2) * x.ofLp i) -- which equals βˆ‘ i, β€–xβ€– ^ (2 - p) * |x.ofLp i| ^ p by ring + hterm have hterm' : βˆ€ i, x.ofLp i * (β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i) = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ (p : ℝ) := by intro i calc x.ofLp i * (β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i) = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i * x.ofLp i := by ring _ = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ (p : ℝ) := hterm i simp_rw [hterm'] -- Factor out β€–xβ€–^(2-p) rw [← Finset.mul_sum] -- The sum βˆ‘ i, |x.ofLp i|^p = β€–xβ€–^p have hp_toReal_pos : 0 < (p : ℝβ‰₯0∞).toReal := by simp [hp_pos] have hnorm_sum : βˆ‘ i : Fin d, |x.ofLp i| ^ (p : ℝ) = β€–xβ€– ^ (p : ℝ) := by have hnorm_eq := PiLp.norm_eq_sum hp_toReal_pos x simp only [ENNReal.toReal_natCast] at hnorm_eq -- β€–xβ€– = (βˆ‘ i, β€–x.ofLp iβ€–^p)^(1/p) -- So β€–xβ€–^p = βˆ‘ i, β€–x.ofLp iβ€–^p = βˆ‘ i, |x.ofLp i|^p have : β€–xβ€– ^ (p : ℝ) = (βˆ‘ i : Fin d, β€–x.ofLp iβ€– ^ (p : ℝ)) ^ ((1 / (p : ℝ)) * (p : ℝ)) := by rw [hnorm_eq] rw [← Real.rpow_mul (Finset.sum_nonneg (fun i _ => Real.rpow_nonneg (norm_nonneg _) _))] rw [one_div_mul_cancel hp_ne, Real.rpow_one] at this rw [this] simp only [Real.norm_eq_abs] rw [hnorm_sum] -- β€–xβ€–^(2-p) * β€–xβ€–^p = β€–xβ€–^2 have h2_ne : (2 - (p : ℝ)) + p β‰  0 := by norm_num rw [← Real.rpow_add' (norm_nonneg _) h2_ne] norm_num lemma inner_abs_gradient_half_sq_Lp_le (hp : 2 ≀ p) (x y: LpSpace p d) : βˆ‘ i, |(half_sq_Lp' x).ofLp i| * |y.ofLp i| ≀ β€–xβ€– * β€–yβ€– := by have hfact : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) have hp_pos : (0 : ℝ) < p := by have : (2 : β„•) ≀ p := hp have : (2 : ℝ) ≀ (p : ℝ) := Nat.ofNat_le_cast.mpr this linarith have hp_ne : (p : ℝ) β‰  0 := ne_of_gt hp_pos have hp1_pos : (0 : ℝ) < p - 1 := by have : (2 : β„•) ≀ p := hp have : (2 : ℝ) ≀ (p : ℝ) := Nat.ofNat_le_cast.mpr this linarith have hp1_ne : (p : ℝ) - 1 β‰  0 := ne_of_gt hp1_pos have hp2_add : (p : ℝ) - 2 + 1 = p - 1 := by ring have hpm1_ne : ((p : ℝ) - 2 + 1) β‰  0 := by rw [hp2_add]; exact hp1_ne -- Expand (half_sq_Lp' x).ofLp i = β€–xβ€–^(2-p) * |x.ofLp i|^(p-2) * x.ofLp i have hgrad : βˆ€ i, (half_sq_Lp' x).ofLp i = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 2) * x.ofLp i := by intro i simp only [half_sq_Lp', WithLp.ofLp_toLp] -- Simplify |grad_i| = β€–xβ€–^(2-p) * |x_i|^(p-1) have habs_grad : βˆ€ i, |(half_sq_Lp' x).ofLp i| = β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 1) := by intro i rw [hgrad] rw [abs_mul, abs_mul] rw [abs_of_nonneg (Real.rpow_nonneg (norm_nonneg _) _)] rw [abs_of_nonneg (Real.rpow_nonneg (abs_nonneg _) _)] -- Goal: β€–xβ€–^(2-p) * |x_i|^(p-2) * |x_i| = β€–xβ€–^(2-p) * |x_i|^(p-1) rw [mul_assoc] congr 1 rw [← Real.rpow_add_one' (abs_nonneg _) hpm1_ne, hp2_add] -- Rewrite the sum using habs_grad have hsum_eq : βˆ‘ i, |(half_sq_Lp' x).ofLp i| * |y.ofLp i| = βˆ‘ i, β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 1) * |y.ofLp i| := by congr 1 funext i rw [habs_grad] rw [hsum_eq] -- Factor out β€–xβ€–^(2-p) have hfactor : βˆ‘ i, β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 1) * |y.ofLp i| = β€–xβ€– ^ (2 - (p : ℝ)) * βˆ‘ i, |x.ofLp i| ^ ((p : ℝ) - 1) * |y.ofLp i| := by conv_lhs => arg 2 ext i rw [show β€–xβ€– ^ (2 - (p : ℝ)) * |x.ofLp i| ^ ((p : ℝ) - 1) * |y.ofLp i| = β€–xβ€– ^ (2 - (p : ℝ)) * (|x.ofLp i| ^ ((p : ℝ) - 1) * |y.ofLp i|) by ring] rw [← Finset.mul_sum] rw [hfactor] -- Apply HΓΆlder's inequality with p' = p/(p-1) and q = p -- Note: 1/p' + 1/q = (p-1)/p + 1/p = 1 have hHolder := Real.inner_le_Lp_mul_Lq (p := (p : ℝ) / ((p : ℝ) - 1)) (q := p) (f := fun i => |x.ofLp i| ^ ((p : ℝ) - 1)) (g := fun i => |y.ofLp i|) Finset.univ ?hpq case hpq => refine ⟨?_, ?_, ?_⟩ Β· -- (p-1)/p + 1/p = 1 field_simp ring Β· apply div_pos hp_pos hp1_pos Β· exact hp_pos -- Simplify the absolute values in HΓΆlder (they're already non-negative) have habs_f : βˆ€ i, |(|x.ofLp i| ^ ((p : ℝ) - 1))| = |x.ofLp i| ^ ((p : ℝ) - 1) := by intro i apply abs_of_nonneg apply Real.rpow_nonneg (abs_nonneg _) have habs_g : βˆ€ i, |(|y.ofLp i|)| = |y.ofLp i| := by intro i apply abs_abs simp only [habs_f, habs_g] at hHolder -- Simplify (|x_i|^(p-1))^(p/(p-1)) = |x_i|^p have hpow_f : βˆ€ i, (|x.ofLp i| ^ ((p : ℝ) - 1)) ^ ((p : ℝ) / ((p : ℝ) - 1)) = |x.ofLp i| ^ (p : ℝ) := by intro i rw [← Real.rpow_mul (abs_nonneg _)] congr 1 field_simp simp only [hpow_f] at hHolder -- Simplify 1/(p/(p-1)) = (p-1)/p in hHolder have hexp_simp : 1 / ((p : ℝ) / ((p : ℝ) - 1)) = ((p : ℝ) - 1) / (p : ℝ) := by field_simp simp only [hexp_simp] at hHolder -- Now hHolder says: βˆ‘|x_i|^(p-1)*|y_i| ≀ (βˆ‘|x_i|^p)^((p-1)/p) * (βˆ‘|y_i|^p)^(1/p) -- The LHS multiplied by β€–xβ€–^(2-p) should be ≀ β€–xβ€– * β€–yβ€– apply le_trans (mul_le_mul_of_nonneg_left hHolder (Real.rpow_nonneg (norm_nonneg _) _)) -- Need to show: β€–xβ€–^(2-p) * (βˆ‘|x_i|^p)^((p-1)/p) * (βˆ‘|y_i|^p)^(1/p) ≀ β€–xβ€– * β€–yβ€– -- Note: (βˆ‘|x_i|^p)^(1/p) = β€–xβ€– and (βˆ‘|y_i|^p)^(1/p) = β€–yβ€– have hp_toReal_pos : 0 < (p : ℝβ‰₯0∞).toReal := by simp [hp_pos] have hx_norm : β€–xβ€– = (βˆ‘ i, |x.ofLp i| ^ (p : ℝ)) ^ (1 / (p : ℝ)) := by rw [PiLp.norm_eq_sum hp_toReal_pos] simp only [one_div, Real.norm_eq_abs, ENNReal.toReal_natCast] have hy_norm : β€–yβ€– = (βˆ‘ i, |y.ofLp i| ^ (p : ℝ)) ^ (1 / (p : ℝ)) := by rw [PiLp.norm_eq_sum hp_toReal_pos] simp only [one_div, Real.norm_eq_abs, ENNReal.toReal_natCast] -- (βˆ‘|x_i|^p)^((p-1)/p) = β€–xβ€–^(p-1) have hsum_x_pow : (βˆ‘ i, |x.ofLp i| ^ (p : ℝ)) ^ (((p : ℝ) - 1) / (p : ℝ)) = β€–xβ€– ^ ((p : ℝ) - 1) := by rw [hx_norm] rw [← Real.rpow_mul (by apply Finset.sum_nonneg; intro i _; apply Real.rpow_nonneg (abs_nonneg _))] congr 1 field_simp rw [hsum_x_pow, hy_norm] -- Now need: β€–xβ€–^(2-p) * (β€–xβ€–^(p-1) * β€–yβ€–) ≀ β€–xβ€– * β€–yβ€– -- i.e., β€–xβ€–^(2-p+p-1) * β€–yβ€– ≀ β€–xβ€– * β€–yβ€– -- i.e., β€–xβ€–^1 * β€–yβ€– ≀ β€–xβ€– * β€–yβ€– βœ“ have hexp_sum : (2 - (p : ℝ)) + ((p : ℝ) - 1) = 1 := by ring have hexp_ne : (2 - (p : ℝ)) + ((p : ℝ) - 1) β‰  0 := by rw [hexp_sum]; norm_num -- Rewrite a * (b * c) to (a * b) * c rw [← mul_assoc (β€–xβ€– ^ (2 - (p : ℝ))) (β€–xβ€– ^ ((p : ℝ) - 1))] rw [← Real.rpow_add' (norm_nonneg _) hexp_ne] rw [hexp_sum, Real.rpow_one] end inner section measurable instance measurable_of_half_sq_Lp (hp : 1 ≀ p) : Measurable (half_sq_Lp : LpSpace p d β†’ ℝ) := by have : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) apply Continuous.measurable apply Continuous.mul apply continuous_const apply Continuous.pow apply Continuous.norm apply continuous_id instance measurable_of_gradient_half_sq_Lp (hp : 2 ≀ p) : Measurable (half_sq_Lp' : LpSpace p d β†’ LpSpace p d) := by have hfact : Fact (1 ≀ (p : ℝβ‰₯0∞)) := by apply Fact.mk (by simp; linarith) have hp_pos : (0 : ℝ) < p := by have : (2 : β„•) ≀ p := hp have : (2 : ℝ) ≀ (p : ℝ) := Nat.ofNat_le_cast.mpr this linarith have hp2_nonneg : (0 : ℝ) ≀ (p : ℝ) - 2 := by have : (2 : β„•) ≀ p := hp have : (2 : ℝ) ≀ (p : ℝ) := Nat.ofNat_le_cast.mpr this linarith -- half_sq_Lp' x = WithLp.toLp p (fun i => β€–xβ€–^(2-p) * |x.ofLp i|^(p-2) * x.ofLp i) -- Use the measurable equivalence between (Fin d β†’ ℝ) and LpSpace p d -- half_sq_Lp' = (MeasurableEquiv.toLp p (Fin d β†’ ℝ)) ∘ f ∘ (MeasurableEquiv.toLp p (Fin d β†’ ℝ)).symm -- where f : (Fin d β†’ ℝ) β†’ (Fin d β†’ ℝ) is measurable have heq : half_sq_Lp' = (MeasurableEquiv.toLp (p : ℝβ‰₯0∞) (Fin d β†’ ℝ)) ∘ (fun v : Fin d β†’ ℝ => fun i => β€–WithLp.toLp p vβ€– ^ (2 - (p : ℝ)) * |v i| ^ ((p : ℝ) - 2) * v i) ∘ (MeasurableEquiv.toLp (p : ℝβ‰₯0∞) (Fin d β†’ ℝ)).symm := by ext x simp only [Function.comp_apply, MeasurableEquiv.toLp_apply, MeasurableEquiv.toLp_symm_apply, half_sq_Lp', WithLp.ofLp_toLp] rw [heq] apply Measurable.comp Β· exact (MeasurableEquiv.toLp (p : ℝβ‰₯0∞) (Fin d β†’ ℝ)).measurable apply Measurable.comp Β· -- Show the middle function is measurable apply measurable_pi_iff.mpr intro i apply Measurable.mul apply Measurable.mul -- β€–WithLp.toLp p vβ€–^(2-p) is measurable -- Rewrite 2-p = (-1) * (p-2) to use Measurable.pow_const for integer powers Β· have h2p : 2 - (p : ℝ) = (-1 : β„€) * ((p : ℝ) - 2) := by ring rw [h2p] apply Measurable.pow_const apply Measurable.norm exact (PiLp.continuous_toLp p (fun _ : Fin d => ℝ)).measurable -- |v i|^(p-2) is measurable (use continuity since |v i| β‰₯ 0 and p-2 β‰₯ 0) Β· apply Continuous.measurable apply Continuous.rpow_const Β· apply Continuous.abs apply continuous_apply Β· intro v apply Or.inr exact hp2_nonneg -- v i is measurable Β· apply measurable_pi_apply Β· exact (MeasurableEquiv.toLp (p : ℝβ‰₯0∞) (Fin d β†’ ℝ)).symm.measurable end measurable end StochasticApproximation