CubicPathwidth.T2.Slepian
Source file CubicPathwidth/T2/Slepian.lean of the Lean project (how it is built).
import CubicPathwidth.T2.SlepianSmooth
import Mathlib.Analysis.SpecialFunctions.SmoothTransition
/-!
# Slepian's inequality for Gaussian upper orthants (O3)
`slepian : SlepianClaim`.
Route: Gaussian interpolation with smooth product test functions
(`CubicPathwidth.T2.SlepianSmooth`), followed by
* approximation of the indicator of `(0, ∞)` by `s ↦ smoothTransition ((n + 1) s)`, which is
eventually constant at every point, so dominated convergence applies;
* reduction of the inner-product model on `Sample m` to the coordinate model on
`Fin (m + m) → ℝ`, with the `a`-vectors on the first block and the `b`-vectors on the second
block, so that the two families are orthogonal.
-/
noncomputable section
open scoped Real RealInnerProductSpace ContDiff
open MeasureTheory ProbabilityTheory Set Filter Topology Finset
namespace CubicPathwidth
namespace T2
namespace Slepian
/-! ## The smooth step and its derivatives -/
local notation "ST" => Real.smoothTransition
theorem st_smooth : Differentiable ℝ ST ∧ Differentiable ℝ (deriv ST) ∧
Continuous (deriv (deriv ST)) := by
have h0 : ContDiff ℝ ∞ ST := Real.smoothTransition.contDiff (n := ⊤)
have h1 := contDiff_infty_iff_deriv.1 h0
have h2 := contDiff_infty_iff_deriv.1 h1.2
exact ⟨h1.1, h2.1, h2.2.continuous⟩
theorem st1_zero : ∀ x : ℝ, x < 0 ∨ 1 < x → deriv ST x = 0 := by
rintro x (hx | hx)
· have : ST =ᶠ[𝓝 x] fun _ => 0 := by
filter_upwards [Iio_mem_nhds hx] with y hy
exact Real.smoothTransition.zero_of_nonpos hy.le
rw [this.deriv_eq]; simp
· have : ST =ᶠ[𝓝 x] fun _ => 1 := by
filter_upwards [Ioi_mem_nhds hx] with y hy
exact Real.smoothTransition.one_of_one_le hy.le
rw [this.deriv_eq]; simp
theorem st2_zero : ∀ x : ℝ, x < 0 ∨ 1 < x → deriv (deriv ST) x = 0 := by
rintro x (hx | hx)
· have : deriv ST =ᶠ[𝓝 x] fun _ => 0 := by
filter_upwards [Iio_mem_nhds hx] with y hy
exact st1_zero y (Or.inl hy)
rw [this.deriv_eq]; simp
· have : deriv ST =ᶠ[𝓝 x] fun _ => 0 := by
filter_upwards [Ioi_mem_nhds hx] with y hy
exact st1_zero y (Or.inr hy)
rw [this.deriv_eq]; simp
theorem bdd_of_vanish {h : ℝ → ℝ} (hc : Continuous h) (hz : ∀ x, x < 0 ∨ 1 < x → h x = 0) :
∃ C, ∀ x, |h x| ≤ C := by
obtain ⟨C, hC⟩ := (isCompact_Icc (a := (0 : ℝ)) (b := 1)).exists_bound_of_continuousOn
hc.continuousOn
refine ⟨max C 0, fun x => ?_⟩
by_cases hx : x ∈ Icc (0 : ℝ) 1
· exact (by simpa [Real.norm_eq_abs] using hC x hx : |h x| ≤ C).trans (le_max_left _ _)
· have : x < 0 ∨ 1 < x := by
simp only [Set.mem_Icc, not_and_or, not_le] at hx; exact hx
rw [hz x this]; simp
/-- Scaled smooth step. -/
def gs (c s : ℝ) : ℝ := ST (c * s)
/-- Its derivative. -/
def gs1 (c s : ℝ) : ℝ := c * deriv ST (c * s)
/-- Its second derivative. -/
def gs2 (c s : ℝ) : ℝ := c * (c * deriv (deriv ST) (c * s))
theorem hasDerivAt_gs (c s : ℝ) : HasDerivAt (gs c) (gs1 c s) s := by
have := (st_smooth.1 (c * s)).hasDerivAt.comp s ((hasDerivAt_id s).const_mul c)
unfold gs gs1
convert this using 1 <;> first | rfl | ring
theorem hasDerivAt_gs1 (c s : ℝ) : HasDerivAt (gs1 c) (gs2 c s) s := by
have := ((st_smooth.2.1 (c * s)).hasDerivAt.comp s ((hasDerivAt_id s).const_mul c)).const_mul c
unfold gs1 gs2
convert this using 1 <;> first | rfl | ring
theorem continuous_gs2 (c : ℝ) : Continuous (gs2 c) := by
unfold gs2
exact continuous_const.mul (continuous_const.mul
(st_smooth.2.2.comp (continuous_const.mul continuous_id)))
/-! ## The coordinate model -/
theorem measurableSet_orthant {N k : ℕ} (A : Fin k → Fin N → ℝ) (t : Fin k → ℝ) :
MeasurableSet {x | ∀ i, t i < ip (A i) x} := by
simp only [Set.ofPred_forall]
exact MeasurableSet.iInter fun i =>
measurableSet_lt measurable_const (continuous_ip _).measurable
theorem tendsto_smooth_orthant {N k : ℕ} (A : Fin k → Fin N → ℝ) (t : Fin k → ℝ) :
Tendsto (fun n : ℕ => ∫ x, ∏ i, gs ((n : ℝ) + 1) (ip (A i) x - t i) ∂gpi N) atTop
(𝓝 ((gpi N).real {x | ∀ i, t i < ip (A i) x})) := by
rw [← integral_indicator_one (measurableSet_orthant A t)]
refine tendsto_integral_of_dominated_convergence (fun _ => 1) (fun n => ?_)
(integrable_const 1) (fun n => ae_of_all _ fun x => ?_) (ae_of_all _ fun x => ?_)
· unfold gs
exact (continuous_finsetProd _ fun i _ => Real.smoothTransition.continuous.comp
(continuous_const.mul ((continuous_ip _).sub continuous_const))).aestronglyMeasurable
· simp only [gs]
rw [Real.norm_eq_abs, abs_of_nonneg (Finset.prod_nonneg fun i _ =>
Real.smoothTransition.nonneg _)]
exact Finset.prod_le_one₀ (fun i _ => Real.smoothTransition.nonneg _)
fun i _ => Real.smoothTransition.le_one _
· have hev : ∀ i, ∀ᶠ n : ℕ in atTop,
gs ((n : ℝ) + 1) (ip (A i) x - t i) = if t i < ip (A i) x then 1 else 0 := by
intro i
split_ifs with h
· have hp : 0 < ip (A i) x - t i := sub_pos.2 h
obtain ⟨n0, hn0⟩ := exists_nat_ge (1 / (ip (A i) x - t i))
filter_upwards [eventually_ge_atTop n0] with n hn
apply Real.smoothTransition.one_of_one_le
have h1 : (1 / (ip (A i) x - t i)) ≤ (n : ℝ) + 1 := by
have : (n0 : ℝ) ≤ n := by exact_mod_cast hn
linarith
rw [div_le_iff₀ hp] at h1
exact h1
· refine Eventually.of_forall fun n => Real.smoothTransition.zero_of_nonpos ?_
exact mul_nonpos_of_nonneg_of_nonpos (by positivity) (by linarith [not_lt.1 h])
refine tendsto_const_nhds.congr' ?_
filter_upwards [eventually_all.2 hev] with n hn
rw [Finset.prod_congr rfl fun i _ => hn i, Fintype.prod_boole]
simp only [Set.indicator_apply, Set.mem_ofPred_eq, Pi.one_apply]
convert rfl
/-- Slepian's inequality in the coordinate model, with `A` orthogonal to `B`. -/
theorem pi_slepian {N k : ℕ} (A B : Fin k → Fin N → ℝ) (horth : ∀ i l, ip (A i) (B l) = 0)
(hnorm : ∀ i, ip (A i) (A i) = ip (B i) (B i))
(hoff : ∀ i l, i ≠ l → ip (A i) (A l) ≤ ip (B i) (B l)) (t : Fin k → ℝ) :
(gpi N).real {x | ∀ i, t i < ip (A i) x} ≤ (gpi N).real {x | ∀ i, t i < ip (B i) x} := by
obtain ⟨C1, hC1⟩ := bdd_of_vanish (st_smooth.2.1.continuous) st1_zero
obtain ⟨C2, hC2⟩ := bdd_of_vanish st_smooth.2.2 st2_zero
refine le_of_tendsto_of_tendsto' (tendsto_smooth_orthant A t) (tendsto_smooth_orthant B t)
fun n => ?_
set c : ℝ := (n : ℝ) + 1
have hc : 0 ≤ c := by positivity
refine smooth_slepian A B horth hnorm hoff (hasDerivAt_gs c) (hasDerivAt_gs1 c)
(continuous_gs2 c) (fun s => Real.smoothTransition.nonneg _)
(fun s => Real.smoothTransition.le_one _)
(fun s => mul_nonneg hc (Real.smoothTransition.monotone.deriv_nonneg))
(C1 := c * C1) (C2 := c * (c * C2)) (fun s => ?_) (fun s => ?_) t
· exact mul_le_mul_of_nonneg_left ((le_abs_self _).trans (hC1 _)) hc
· unfold gs2
rw [abs_mul, abs_mul, abs_of_nonneg hc]
exact mul_le_mul_of_nonneg_left (mul_le_mul_of_nonneg_left (hC2 _) hc) hc
/-! ## Reduction from the inner-product model -/
theorem map_castAdd (m m' : ℕ) :
(gpi (m + m')).map (fun x (j : Fin m) => x (Fin.castAdd m' j)) = gpi m := by
refine (Measure.pi_eq fun s hs => ?_).symm
rw [Measure.map_apply (by fun_prop) (MeasurableSet.univ_pi hs)]
have : (fun x (j : Fin m) => x (Fin.castAdd m' j)) ⁻¹' Set.pi univ s =
Set.pi univ (Fin.append s fun _ => univ) := by
ext x
simp [Fin.forall_fin_add]
rw [this, Measure.pi_pi, Fin.prod_univ_add]
simp
theorem map_natAdd (m m' : ℕ) :
(gpi (m + m')).map (fun x (j : Fin m') => x (Fin.natAdd m j)) = gpi m' := by
refine (Measure.pi_eq fun s hs => ?_).symm
rw [Measure.map_apply (by fun_prop) (MeasurableSet.univ_pi hs)]
have : (fun x (j : Fin m') => x (Fin.natAdd m j)) ⁻¹' Set.pi univ s =
Set.pi univ (Fin.append (fun _ => univ) s) := by
ext x
simp [Fin.forall_fin_add]
rw [this, Measure.pi_pi, Fin.prod_univ_add]
simp
theorem inner_eq_ip {m : ℕ} (u v : GaussianField.Sample m) :
⟪u, v⟫ = ip (fun j => u j) (fun j => v j) := by
simp [PiLp.inner_apply, ip, mul_comm]
/-- Transfer of an orthant probability along a block embedding. -/
theorem orthant_transfer {m M k : ℕ} (a : Fin k → GaussianField.Sample m)
(e : (Fin M → ℝ) → (Fin m → ℝ)) (he : Measurable e) (hmap : (gpi M).map e = gpi m)
(A : Fin k → Fin M → ℝ) (hA : ∀ i x, ip (A i) x = ip (fun j => a i j) (e x))
(t : Fin k → ℝ) :
(stdGaussian (GaussianField.Sample m)).real {x | ∀ i, t i < ⟪a i, x⟫} =
(gpi M).real {x | ∀ i, t i < ip (A i) x} := by
have hS : MeasurableSet {x : GaussianField.Sample m | ∀ i, t i < ⟪a i, x⟫} := by
simp only [Set.ofPred_forall]
exact MeasurableSet.iInter fun i =>
measurableSet_lt measurable_const (continuous_const.inner continuous_id).measurable
have hmeas : Measurable fun x => WithLp.toLp 2 (e x) := by fun_prop
have hstd : (gpi M).map (fun x => WithLp.toLp 2 (e x)) =
stdGaussian (GaussianField.Sample m) := by
rw [← map_pi_eq_stdGaussian]
change _ = Measure.map (WithLp.toLp 2) (gpi m)
rw [← hmap, Measure.map_map (by fun_prop) he]
rfl
rw [← hstd, map_measureReal_apply hmeas hS]
congr 1
ext x
simp only [Set.mem_preimage, Set.mem_ofPred_eq, inner_eq_ip, hA]
theorem ip_append {m m' : ℕ} (u v : Fin m → ℝ) (u' v' : Fin m' → ℝ) :
ip (Fin.append u u') (Fin.append v v') = ip u v + ip u' v' := by
simp [ip, Fin.sum_univ_add]
end Slepian
open Slepian in
/-- **Slepian's inequality** for Gaussian upper orthants (O3). -/
theorem slepian : SlepianClaim := by
intro m k a b hn ho t
set A : Fin k → Fin (m + m) → ℝ := fun i => Fin.append (fun j => a i j) (0 : Fin m → ℝ)
with hAdef
set B : Fin k → Fin (m + m) → ℝ := fun i => Fin.append (0 : Fin m → ℝ) (fun j => b i j)
with hBdef
have split : ∀ x : Fin (m + m) → ℝ,
x = Fin.append (fun j => x (Fin.castAdd m j)) (fun j => x (Fin.natAdd m j)) := by
intro x; ext j
refine Fin.addCases (fun j => ?_) (fun j => ?_) j
· rw [Fin.append_left]
· rw [Fin.append_right]
have hA : ∀ i x, ip (A i) x = ip (fun j => a i j) (fun j => x (Fin.castAdd m j)) := by
intro i x
conv_lhs => rw [split x]
rw [hAdef, ip_append]; simp [ip]
have hB : ∀ i x, ip (B i) x = ip (fun j => b i j) (fun j => x (Fin.natAdd m j)) := by
intro i x
conv_lhs => rw [split x]
rw [hBdef, ip_append]; simp [ip]
rw [orthant_transfer a _ (by fun_prop) (map_castAdd m m) A hA t,
orthant_transfer b _ (by fun_prop) (map_natAdd m m) B hB t]
refine pi_slepian A B (fun i l => ?_) (fun i => ?_) (fun i l hil => ?_) t
· rw [hAdef, hBdef, ip_append]; simp [ip]
· rw [hAdef, hBdef, ip_append, ip_append, ← inner_eq_ip, ← inner_eq_ip,
real_inner_self_eq_norm_sq, real_inner_self_eq_norm_sq, hn i]
simp [ip]
· rw [hAdef, hBdef, ip_append, ip_append, ← inner_eq_ip, ← inner_eq_ip]
simpa [ip] using ho i l hil
end T2
end CubicPathwidth
#print axioms CubicPathwidth.T2.slepian
Back to top