Samplinglib
Lean gate not recorded for this source state main · ed709a7f320d
test module

Tests.Shared.QuadraticRegularizationOracle

0 named declarations scanned from Tests/Shared/QuadraticRegularizationOracle.lean.

Imports
Imported by
Placeholder scan
0 declaration(s) flagged
Gate status
Partial

Declarations

This aggregator contains no named declarations.

Complete Lean source

Tests/Shared/QuadraticRegularizationOracle.lean — full module with imports and context
Download module (.lean)
import AutoSamplingTheory.TechnicalLemmas.Analysis.QuadraticRegularizationOracle
import Mathlib.Analysis.Calculus.Deriv.Pow
import Mathlib.Analysis.Calculus.Deriv.Mul

open Set
open AutoSamplingTheory.TechnicalLemmas.Analysis
open QuadraticRegularizationOracle
open scoped NNReal

-- Control inspection is free, including at zero query fuel.
example (n : ℕ) : run (fun s : ℕ => (Sum.inl s : Sum ℕ ℕ))
    (fun _ _ (a : ℕ) => a) id n 7 = ((7, some 7), 0) := by
  cases n <;> rfl
example : run (fun s : ℕ => (Sum.inr s : Sum ℕ ℕ))
    (fun _ _ (a : ℕ) => a) id 0 7 = ((7, none), 0) := rfl

-- A two-query adaptive method: second point depends on the first gradient;
-- termination after the second reply depends on that reply's gradient.
set_option backward.isDefEq.respectTransparency false in
example :
    let f := fun x : ℝ => x^2/2
    let W := fun x : ℝ => f x + (1:ℝ)/2*‖x-1‖^2
    let next := fun s : ℕ × ℝ × ℝ =>
      if s.1 = 0 then Sum.inr (1:ℝ)
      else if s.1 = 1 then Sum.inr (s.2.1-s.2.2/2)
      else if s.2.2 = 0 then Sum.inl s.2.1 else Sum.inr s.2.1
    let update := fun s : ℕ × ℝ × ℝ => fun x : ℝ => fun a : ℝ × ℝ =>
      (s.1+1, x, a.2)
    let corrected := fun s x (a : ℝ × ℝ) =>
      update s x (a.1+(1:ℝ)/2*‖x-1‖^2,a.2+(x-1))
    let oracle := fun x => (f x, gradient f x)
    run next corrected oracle 1 (0,0,0) = (((1,1,1),none),1) ∧
    run next corrected oracle 2 (0,0,0) = (((2,1/2,0),some (1/2)),2) ∧
    run next update (fun x => (W x,gradient W x)) 4 (0,0,0) =
      (((2,1/2,0),some (1/2)),2) := by
  dsimp only
  let f := fun x : ℝ => x^2/2
  have hd : Differentiable ℝ f := by fun_prop
  have hg (x : ℝ) : gradient f x = x := by
    have h : HasDerivAt f x x := by
      simpa [f] using ((hasDerivAt_id x).pow 2).div_const (2:ℝ)
    exact h.hasGradientAt.gradient
  have hc : ConvexOn ℝ univ f := by
    refine ⟨convex_univ, ?_⟩
    intro x _ y _ a b ha hb hab
    simp only [f, smul_eq_mul]
    have hnon : 0 ≤ a*b*(x-y)^2 := mul_nonneg (mul_nonneg ha hb) (sq_nonneg _)
    have he : a*x^2/2+b*y^2/2-(a*x+b*y)^2/2 = a*b*(x-y)^2/2 := by
      have hb' : b = 1-a := by linarith
      rw [hb']; ring
    nlinarith
  have hL : LipschitzWith 1 (gradient f) := by
    rw [show gradient f = id from funext hg]; exact LipschitzWith.id
  let next := fun s : ℕ × ℝ × ℝ =>
    if s.1 = 0 then Sum.inr (1:ℝ)
    else if s.1 = 1 then Sum.inr (s.2.1-s.2.2/2)
    else if s.2.2 = 0 then Sum.inl s.2.1 else Sum.inr s.2.1
  let update := fun s : ℕ × ℝ × ℝ => fun x : ℝ => fun a : ℝ × ℝ =>
    (s.1+1, x, a.2)
  have sim := (simulate_regularized next update hd hc hL (δ := 1) 1 4 (0,0,0)).1
  dsimp only at sim
  norm_num only [NNReal.coe_one, one_smul] at sim
  refine ⟨?_,?_,?_⟩
  · norm_num [run, show (fun x : ℝ => x^2/2) = f from rfl, hg]
  · norm_num [run, show (fun x : ℝ => x^2/2) = f from rfl, hg]
  · rw [← sim]
    norm_num [run, next, update, hg]

-- Zero precision is the identity reply conversion, also for arbitrary programs.
example {S X : Type*} (next : S → Sum X ℝ)
    (update : S → ℝ → (ℝ × ℝ) → S) (n : ℕ) (s : S) :
    run next (fun s x (a : ℝ × ℝ) => update s x (a.1+0/2*‖x-1‖^2,a.2+0*(x-1)))
      (fun x => (x^2/2,x)) n s = run next update (fun x => (x^2/2,x)) n s := by
  simp

#print axioms AutoSamplingTheory.TechnicalLemmas.Analysis.QuadraticRegularizationOracle.simulate_regularized