Mathlib.Probability.Birthday

Draw labels independently and uniformly from an alphabet of size m, where the number of draws is Binomial(T, η).

Basic 6 core · 0 supporting This module defines the collision probability for independent uniform labels, its binomial average, and the mean and pair scales used by the limit theorem.

Binomially averaged birthday collisions

This module defines the collision probability for independent uniform labels, its binomial average, and the mean and pair scales used by the limit theorem. The falling factorial is zero when the number of draws exceeds the alphabet.

def noRepeat reviewed
Causalean.Mathlib.Probability.Birthday

For an alphabet size and draw count, the no-repeat kernel is given by the falling factorial divided by the number of all label sequences.

Definition (Lean source)
m r :
ℕ
noRepeat m r :
ℝ
(m.descFactorial r : ℝ) / (m : ℝ) ^ r
Causalean.Mathlib.Probability.Birthday.noRepeat · Causalean/Mathlib/Probability/Birthday/Basic.lean:19
def repeatKernel reviewed
Causalean.Mathlib.Probability.Birthday

For an alphabet size and draw count, the repeat kernel is given by the complement of the no-repeat kernel.

Definition (Lean source)
m r :
ℕ
repeatKernel m r :
ℝ
1 - noRepeat m r
Causalean.Mathlib.Probability.Birthday.repeatKernel · Causalean/Mathlib/Probability/Birthday/Basic.lean:25
def binomialAverage reviewed
Causalean.Mathlib.Probability.Birthday

For a trial count, success probability, and count function, the binomial average is given by weighting each possible success count by its binomial probability.

Definition (Lean source)
T :
ℕ
eta :
ℝ
f :
ℕ → ℝ
binomialAverage T eta f :
ℝ
∑ r ∈ range (T + 1), binomialWeight T eta r * f r
Causalean.Mathlib.Probability.Birthday.binomialAverage · Causalean/Mathlib/Probability/Birthday/Basic.lean:30
def birthdayRepeat reviewed
Causalean.Mathlib.Probability.Birthday

For a trial count, alphabet size, and success probability, the averaged repeat probability is the binomial average of the finite uniform birthday collision kernel.

Definition (Lean source)
T m :
ℕ
eta :
ℝ
birthdayRepeat T m eta :
ℝ
Causalean.Mathlib.Probability.Birthday.birthdayRepeat · Causalean/Mathlib/Probability/Birthday/Basic.lean:37
def mean reviewed
Causalean.Mathlib.Probability.Birthday

The mean number of successes in T trials with success probability η is the product T·η.

Definition (Lean source)
T :
ℕ
eta :
ℝ
mean T eta :
ℝ
(T : ℝ) * eta
Causalean.Mathlib.Probability.Birthday.mean · Causalean/Mathlib/Probability/Birthday/Basic.lean:44
def pairScale reviewed
Causalean.Mathlib.Probability.Birthday

For a trial count and success probability, the expected number of unordered pairs is given by the binomial pair count times the squared success probability.

Definition (Lean source)
T :
ℕ
eta :
ℝ
pairScale T eta :
ℝ
(T.choose 2 : ℝ) * eta ^ 2
Causalean.Mathlib.Probability.Birthday.pairScale · Causalean/Mathlib/Probability/Birthday/Basic.lean:48
Rounding 3 core · 3 supporting Ceiling and floor choices with a positive minimum allow an arbitrary diverging real scale to be instantiated as positive alphabet sizes. ★ positiveCeil_mul_div_tendsto

Positive integer rounding of real scales

Ceiling and floor choices with a positive minimum allow an arbitrary diverging real scale to be instantiated as positive alphabet sizes.

def positiveCeil reviewed
Causalean.Mathlib.Probability.Birthday

For a real scale, the positive ceiling is given by the larger of one and its natural-number ceiling.

Definition (Lean source)
x :
ℝ
positiveCeil x :
ℕ
max 1 (ceil x)
Causalean.Mathlib.Probability.Birthday.positiveCeil · Causalean/Mathlib/Probability/Birthday/Rounding.lean:17
def positiveFloor reviewed
Causalean.Mathlib.Probability.Birthday

For a real scale, the positive floor is given by the larger of one and its natural-number floor.

Definition (Lean source)
x :
ℝ
positiveFloor x :
ℕ
max 1 (Nat.floor x)
Causalean.Mathlib.Probability.Birthday.positiveFloor · Causalean/Mathlib/Probability/Birthday/Rounding.lean:21
theorem positiveCeil_mul_div_tendsto reviewed
Causalean.Mathlib.Probability.Birthday

For a diverging positive scale and positive multiplier, the positive ceiling divided by the original scale converges to the multiplier.

Formal statement
a :
ℕ → ℝ
c :
ℝ
hc :
0 < c
Tendsto (fun j => (positiveCeil (c * a j) : ℝ) / a j) atTop (nhds c)
Proof (Lean source)
theorem positiveCeil_mul_div_tendsto (a : ℕ → ℝ) {c : ℝ} (ha : Tendsto a atTop atTop) (hc : 0 < c) : Tendsto (fun j => (positiveCeil (c * a j) : ℝ) / a j) atTop (nhds c) := by have hlarge : ∀ᶠ j in atTop, (1 : ℝ) ≤ c * a j := (ha.const_mul_atTop hc).eventually_ge_atTop 1 apply (tendsto_nat_ceil_mul_div_atTop hc.le).comp ha |>.congr' filter_upwards [hlarge] with j hj simp [positiveCeil, (Nat.one_le_ceil_iff).mpr (lt_of_lt_of_le zero_lt_one hj)]
Causalean.Mathlib.Probability.Birthday.positiveCeil_mul_div_tendsto · Causalean/Mathlib/Probability/Birthday/Rounding.lean:33 · uses positiveCeil
3 supporting declarations (lemmas, instances)
Threshold­Finite 2 core · 2 supporting The averaged collision probability eventually falls below every positive tolerance as the alphabet grows. ★ repeat_le_iff_mStar_le

The least positive birthday threshold at finite parameters

The averaged collision probability eventually falls below every positive tolerance as the alphabet grows. This gives a least positive threshold and its monotone characterization.

def mStar reviewed
Causalean.Mathlib.Probability.Birthday

For a trial count, success probability, and collision tolerance, the least positive threshold is given by the infimum of positive alphabet sizes whose averaged repeat probability is at most the tolerance; it is zero by convention when no positive alphabet size meets the tolerance.

Definition (Lean source)
T :
ℕ
eta delta :
ℝ
mStar T eta delta :
ℕ
sInf {m : ℕ | 0 < m ∧ birthdayRepeat T m eta ≤ delta}
Causalean.Mathlib.Probability.Birthday.mStar · Causalean/Mathlib/Probability/Birthday/ThresholdFinite.lean:16
theorem repeat_le_iff_mStar_le reviewed
Causalean.Mathlib.Probability.Birthday

For a valid success probability, positive tolerance, and positive alphabet, the averaged repeat probability is at most the tolerance exactly when the alphabet size is at least the least threshold.

Formal statement
T m :
ℕ
eta delta :
ℝ
heta :
eta ∈ Icc (0 : ℝ) 1
hdelta :
0 < delta
hm :
0 < m
birthdayRepeat T m eta ≤ delta ↔ mStar T eta delta ≤ m
Proof (Lean source)
theorem repeat_le_iff_mStar_le (T m : ℕ) (eta delta : ℝ) (heta : eta ∈ Icc (0 : ℝ) 1) (hdelta : 0 < delta) (hm : 0 < m) : birthdayRepeat T m eta ≤ delta ↔ mStar T eta delta ≤ m := by -- Forward: `Nat.sInf_le`; reverse: `Nat.sInf_mem` and `repeat_antitone`. constructor · intro hle exact Nat.sInf_le (s := {n : ℕ | 0 < n ∧ birthdayRepeat T n eta ≤ delta}) ⟨hm, hle⟩ · intro hle obtain ⟨n, hn, hbound⟩ := threshold_set_nonempty T eta delta heta hdelta have hs : 0 < mStar T eta delta ∧ birthdayRepeat T (mStar T eta delta) eta ≤ delta := by simpa only [mStar, Set.mem_ofPred_eq] using (Nat.sInf_mem (s := {k : ℕ | 0 < k ∧ birthdayRepeat T k eta ≤ delta}) ⟨n, hn, hbound⟩) exact (repeat_antitone T eta hs.1 hle heta).trans hs.2
Causalean.Mathlib.Probability.Birthday.repeat_le_iff_mStar_le · Causalean/Mathlib/Probability/Birthday/ThresholdFinite.lean:56 · uses birthdayRepeat , mStar
2 supporting declarations (lemmas, instances)
  • threshold_set_nonempty theorem — For a valid success probability and positive tolerance, some positive alphabet size has averaged repeat probability at most the tolerance.
    T :
    ℕ
    eta delta :
    ℝ
    heta :
    eta ∈ Icc (0 : ℝ) 1
    hdelta :
    0 < delta
    ∃ m : ℕ,
    conclusion 1
    0 < m
    conclusion 2
    birthdayRepeat T m eta ≤ delta
    Proof (Lean source)
    theorem threshold_set_nonempty (T : ℕ) (eta delta : ℝ) (heta : eta ∈ Icc (0 : ℝ) 1) (hdelta : 0 < delta) : ∃ m : ℕ, 0 < m ∧ birthdayRepeat T m eta ≤ delta := by -- Use `repeat_le_pairScale_div`; choose a natural m larger than A/delta. obtain ⟨n, hn⟩ := exists_nat_gt (pairScale T eta / delta) refine ⟨n + 1, Nat.succ_pos n, ?_⟩ have hA : pairScale T eta < (n : ℝ) * delta := (div_lt_iff₀ hdelta).mp hn have hpos : (0 : ℝ) < (n + 1 : ℕ) := by exact_mod_cast Nat.succ_pos n have hdiv : pairScale T eta / (↑(n + 1) : ℝ) ≤ delta := by apply (div_le_iff₀ hpos).mpr push_cast nlinarith exact (repeat_le_pairScale_div T (n + 1) eta (Nat.succ_pos n) heta).trans hdiv
    Causalean.Mathlib.Probability.Birthday.threshold_set_nonempty · Causalean/Mathlib/Probability/Birthday/ThresholdFinite.lean:24
  • mStar_pos theorem — For a valid success probability and positive tolerance, the least threshold is positive.
    T :
    ℕ
    eta delta :
    ℝ
    heta :
    eta ∈ Icc (0 : ℝ) 1
    hdelta :
    0 < delta
    0 < mStar T eta delta
    Proof (Lean source)
    theorem mStar_pos (T : ℕ) (eta delta : ℝ) (heta : eta ∈ Icc (0 : ℝ) 1) (hdelta : 0 < delta) : 0 < mStar T eta delta := by -- Apply `Nat.sInf_mem` to `threshold_set_nonempty`. obtain ⟨m, hm, hle⟩ := threshold_set_nonempty T eta delta heta hdelta have hs : 0 < mStar T eta delta ∧ birthdayRepeat T (mStar T eta delta) eta ≤ delta := by simpa only [mStar, Set.mem_ofPred_eq] using (Nat.sInf_mem (s := {m : ℕ | 0 < m ∧ birthdayRepeat T m eta ≤ delta}) ⟨m, hm, hle⟩) exact hs.1
    Causalean.Mathlib.Probability.Birthday.mStar_pos · Causalean/Mathlib/Probability/Birthday/ThresholdFinite.lean:42
Concentration 1 core · 5 supporting The variance identity and a relative-deviation estimate are stated for the finite averaging operator used by the birthday kernel. ★ binomial_relative_deviation_tendsto_zero

Binomial concentration at a diverging mean

The variance identity and a relative-deviation estimate are stated for the finite averaging operator used by the birthday kernel.

theorem binomial_relative_deviation_tendsto_zero reviewed
Causalean.Mathlib.Probability.Birthday

For valid success probabilities, a diverging expected count makes every relative-deviation binomial mass for a positive relative radius vanish.

Formal statement
Tseq :
ℕ → ℕ
etaseq :
ℕ → ℝ
heta :
∀ j, etaseq j ∈ Icc (0 : ℝ) 1
hmean :
Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
eps :
ℝ
heps :
0 < eps
Tendsto (fun j => binomialAverage (Tseq j) (etaseq j) (fun r => if eps * mean (Tseq j) (etaseq j) ≤ |(r : ℝ) - mean (Tseq j) (etaseq j)| then 1 else 0)) atTop (nhds 0)
Proof (Lean source)
theorem binomial_relative_deviation_tendsto_zero (Tseq : ℕ → ℕ) (etaseq : ℕ → ℝ) (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) {eps : ℝ} (heps : 0 < eps) : Tendsto (fun j => binomialAverage (Tseq j) (etaseq j) (fun r => if eps * mean (Tseq j) (etaseq j) ≤ |(r : ℝ) - mean (Tseq j) (etaseq j)| then 1 else 0)) atTop (nhds 0) := by have hpos : ∀ᶠ j : ℕ in atTop, 0 < mean (Tseq j) (etaseq j) := hmean.eventually_gt_atTop 0 have hupper : Tendsto (fun j => (eps ^ 2)⁻¹ * (mean (Tseq j) (etaseq j))⁻¹) atTop (nhds 0) := by simpa using (tendsto_const_nhds (x := (eps ^ 2)⁻¹)).mul (tendsto_inv_atTop_zero.comp hmean) apply squeeze_zero' _ _ hupper · filter_upwards with j exact binomialAverage_nonneg (Tseq j) (etaseq j) _ (heta j) (by intro r _; split_ifs <;> norm_num) · filter_upwards [hpos] with j hj have hband : 0 < eps * mean (Tseq j) (etaseq j) := mul_pos heps hj have hdev := binomialAverage_deviation_le (Tseq j) (heta j) hband have heps0 : eps ≠ 0 := ne_of_gt heps have hmu0 : mean (Tseq j) (etaseq j) ≠ 0 := ne_of_gt hj have hfac : mean (Tseq j) (etaseq j) * (1 - etaseq j) / (eps * mean (Tseq j) (etaseq j)) ^ 2 = (1 - etaseq j) * ((eps ^ 2)⁻¹ * (mean (Tseq j) (etaseq j))⁻¹) := by field_simp rw [hfac] at hdev exact hdev.trans (by have hc : 0 ≤ (eps ^ 2)⁻¹ * (mean (Tseq j) (etaseq j))⁻¹ := by positivity have heta1 : 1 - etaseq j ≤ 1 := by linarith [(heta j).1] simpa using mul_le_mul_of_nonneg_right heta1 hc)
Causalean.Mathlib.Probability.Birthday.binomial_relative_deviation_tendsto_zero · Causalean/Mathlib/Probability/Birthday/Concentration.lean:140 · uses binomialAverage , mean
5 supporting declarations (lemmas, instances)
  • binomialAverage_mono theorem — For a valid success probability, pointwise ordered count functions have ordered binomial averages.
    T :
    ℕ
    eta :
    ℝ
    f g :
    ℕ → ℝ
    heta :
    eta ∈ Icc (0 : ℝ) 1
    hfg :
    ∀ r
    if
    r ≤ T
    then
    f r ≤ g r
    binomialAverage T eta f ≤ binomialAverage T eta g
    Proof (Lean source)
    theorem binomialAverage_mono (T : ℕ) (eta : ℝ) (f g : ℕ → ℝ) (heta : eta ∈ Icc (0 : ℝ) 1) (hfg : ∀ r, r ≤ T → f r ≤ g r) : binomialAverage T eta f ≤ binomialAverage T eta g := by unfold binomialAverage apply Finset.sum_le_sum intro r hr have hw : 0 ≤ binomialWeight T eta r := by simp only [binomialWeight] exact mul_nonneg (mul_nonneg (Nat.cast_nonneg _) (pow_nonneg heta.1 _)) (pow_nonneg (sub_nonneg.mpr heta.2) _) have hrT : r ≤ T := Nat.lt_succ_iff.mp (Finset.mem_range.mp hr) exact mul_le_mul_of_nonneg_left (hfg r hrT) hw
    Causalean.Mathlib.Probability.Birthday.binomialAverage_mono · Causalean/Mathlib/Probability/Birthday/Concentration.lean:17
  • binomialAverage_nonneg theorem — For a valid success probability, a nonnegative count function has a nonnegative binomial average.
    T :
    ℕ
    eta :
    ℝ
    f :
    ℕ → ℝ
    heta :
    eta ∈ Icc (0 : ℝ) 1
    hf :
    ∀ r
    if
    r ≤ T
    then
    0 ≤ f r
    0 ≤ binomialAverage T eta f
    Proof (Lean source)
    theorem binomialAverage_nonneg (T : ℕ) (eta : ℝ) (f : ℕ → ℝ) (heta : eta ∈ Icc (0 : ℝ) 1) (hf : ∀ r, r ≤ T → 0 ≤ f r) : 0 ≤ binomialAverage T eta f := by have h := binomialAverage_mono T eta (fun _ => 0) f heta (by intro r hr exact hf r hr) simpa [binomialAverage] using h
    Causalean.Mathlib.Probability.Birthday.binomialAverage_nonneg · Causalean/Mathlib/Probability/Birthday/Concentration.lean:33
  • repeat_le_pairScale_div theorem — For a valid success probability and positive alphabet, the averaged repeat probability is at most the expected pair count divided by the alphabet size.
    T m :
    ℕ
    eta :
    ℝ
    hm :
    0 < m
    heta :
    eta ∈ Icc (0 : ℝ) 1
    birthdayRepeat T m eta ≤ pairScale T eta / (m : ℝ)
    Proof (Lean source)
    theorem repeat_le_pairScale_div (T m : ℕ) (eta : ℝ) (hm : 0 < m) (heta : eta ∈ Icc (0 : ℝ) 1) : birthdayRepeat T m eta ≤ pairScale T eta / (m : ℝ) := by have h := binomialAverage_mono T eta (repeatKernel m) (fun r => (r.choose 2 : ℝ) / (m : ℝ)) heta (by intro r _ exact repeatKernel_le_pairs m r hm) rw [← birthdayRepeat] at h have havg : binomialAverage T eta (fun r => (r.choose 2 : ℝ) / (m : ℝ)) = pairScale T eta / (m : ℝ) := by unfold binomialAverage calc _ = (∑ r ∈ range (T + 1), binomialWeight T eta r * (r.choose 2 : ℝ)) / (m : ℝ) := by rw [Finset.sum_div] apply Finset.sum_congr rfl intro r _ ring _ = _ := by rw [← binomialAverage, binomialAverage_pairs] exact h.trans_eq havg
    Causalean.Mathlib.Probability.Birthday.repeat_le_pairScale_div · Causalean/Mathlib/Probability/Birthday/Concentration.lean:44
  • binomialAverage_centered_sq theorem — The binomial average for a trial count and success probability of the squared centered count is the ordinary binomial variance.
    T :
    ℕ
    eta :
    ℝ
    binomialAverage T eta (fun r => ((r : ℝ) - mean T eta) ^ 2) = mean T eta * (1 - eta)
    Proof (Lean source)
    theorem binomialAverage_centered_sq (T : ℕ) (eta : ℝ) : binomialAverage T eta (fun r => ((r : ℝ) - mean T eta) ^ 2) = mean T eta * (1 - eta) := by have hpoly (r : ℕ) : ((r : ℝ) - mean T eta) ^ 2 = 2 * (r.choose 2 : ℝ) + (1 - 2 * mean T eta) * r + mean T eta ^ 2 := by rw [Nat.cast_choose_two ℝ] ring have hsum : binomialAverage T eta (fun r => ((r : ℝ) - mean T eta) ^ 2) = 2 * binomialAverage T eta (fun r => (r.choose 2 : ℝ)) + (1 - 2 * mean T eta) * binomialAverage T eta (fun r => (r : ℝ)) + mean T eta ^ 2 * binomialAverage T eta (fun _ => 1) := by unfold binomialAverage calc _ = ∑ r ∈ range (T + 1), (2 * (binomialWeight T eta r * (r.choose 2 : ℝ)) + (1 - 2 * mean T eta) * (binomialWeight T eta r * (r : ℝ)) + mean T eta ^ 2 * (binomialWeight T eta r * 1)) := by apply Finset.sum_congr rfl intro r _ change binomialWeight T eta r * ((r : ℝ) - mean T eta) ^ 2 = _ rw [hpoly] ring _ = _ := by simp only [Finset.sum_add_distrib, ← Finset.mul_sum] rw [hsum, binomialAverage_pairs, binomialAverage_count, binomialAverage_one] unfold pairScale mean rw [Nat.cast_choose_two ℝ] ring
    Causalean.Mathlib.Probability.Birthday.binomialAverage_centered_sq · Causalean/Mathlib/Probability/Birthday/Concentration.lean:69
  • binomialAverage_deviation_le theorem — For a valid success probability, the binomial mass outside a band with positive radius is at most variance divided by the squared band radius.
    T :
    ℕ
    eta a :
    ℝ
    heta :
    eta ∈ Icc (0 : ℝ) 1
    ha :
    0 < a
    binomialAverage T eta (fun r => if a ≤ |(r : ℝ) - mean T eta| then 1 else 0)
    ≤ mean T eta * (1 - eta) / a ^ 2
    Proof (Lean source)
    theorem binomialAverage_deviation_le (T : ℕ) {eta a : ℝ} (heta : eta ∈ Icc (0 : ℝ) 1) (ha : 0 < a) : binomialAverage T eta (fun r => if a ≤ |(r : ℝ) - mean T eta| then 1 else 0) ≤ mean T eta * (1 - eta) / a ^ 2 := by have hpoint (r : ℕ) : (if a ≤ |(r : ℝ) - mean T eta| then (1 : ℝ) else 0) ≤ ((r : ℝ) - mean T eta) ^ 2 / a ^ 2 := by have ha2 : 0 < a ^ 2 := sq_pos_of_pos ha split_ifs with h · apply (le_div_iff₀ ha2).2 have hs : a ^ 2 ≤ |(r : ℝ) - mean T eta| ^ 2 := by nlinarith nlinarith [sq_abs ((r : ℝ) - mean T eta)] · exact div_nonneg (sq_nonneg _) (le_of_lt ha2) have h := binomialAverage_mono T eta (fun r => if a ≤ |(r : ℝ) - mean T eta| then 1 else 0) (fun r => ((r : ℝ) - mean T eta) ^ 2 / a ^ 2) heta (by intro r _; exact hpoint r) have havg : binomialAverage T eta (fun r => ((r : ℝ) - mean T eta) ^ 2 / a ^ 2) = mean T eta * (1 - eta) / a ^ 2 := by unfold binomialAverage calc _ = (∑ r ∈ range (T + 1), binomialWeight T eta r * ((r : ℝ) - mean T eta) ^ 2) / a ^ 2 := by rw [Finset.sum_div] apply Finset.sum_congr rfl intro r _ ring _ = _ := by rw [← binomialAverage, binomialAverage_centered_sq] exact h.trans_eq havg
    Causalean.Mathlib.Probability.Birthday.binomialAverage_deviation_le · Causalean/Mathlib/Probability/Birthday/Concentration.lean:104
Finite 1 core · 7 supporting Pointwise collision estimates, monotonicity in the alphabet, and a finite binomial pair bound. ★ repeat_antitone

Finite birthday and binomial bounds

Pointwise collision estimates, monotonicity in the alphabet, and a finite binomial pair bound. These are the quantitative inputs for asymptotics and least-threshold existence.

theorem repeat_antitone reviewed
Causalean.Mathlib.Probability.Birthday

For a valid success probability, positive smaller alphabet, and ordered alphabet sizes, the averaged repeat probability is antitone.

Formal statement
T :
ℕ
eta :
ℝ
m n :
ℕ
hm :
0 < m
hmn :
m ≤ n
heta :
eta ∈ Icc (0 : ℝ) 1
birthdayRepeat T n eta ≤ birthdayRepeat T m eta
Proof (Lean source)
theorem repeat_antitone (T : ℕ) (eta : ℝ) {m n : ℕ} (hm : 0 < m) (hmn : m ≤ n) (heta : eta ∈ Icc (0 : ℝ) 1) : birthdayRepeat T n eta ≤ birthdayRepeat T m eta := by induction n, hmn using Nat.le_induction with | base => exact le_rfl | succ n hmn ih => exact (repeat_antitone_succ T n eta (hm.trans_le hmn) heta).trans ih
Causalean.Mathlib.Probability.Birthday.repeat_antitone · Causalean/Mathlib/Probability/Birthday/Finite.lean:264 · uses birthdayRepeat
7 supporting declarations (lemmas, instances)
  • repeatKernel_mem_Icc theorem — A positive alphabet gives a collision probability between zero and one for every draw count.
    m r :
    ℕ
    hm :
    0 < m
    repeatKernel m r ∈ Icc (0 : ℝ) 1
    Proof (Lean source)
    theorem repeatKernel_mem_Icc (m r : ℕ) (hm : 0 < m) : repeatKernel m r ∈ Icc (0 : ℝ) 1 := by have hmpos : (0 : ℝ) < m := by exact_mod_cast hm have hfac : (m.descFactorial r : ℝ) ≤ (m : ℝ) ^ r := by exact_mod_cast Nat.descFactorial_le_pow m r have hq : noRepeat m r ≤ 1 := by unfold noRepeat exact (div_le_iff₀ (pow_pos hmpos _)).2 (by simpa using hfac) change 0 ≤ repeatKernel m r ∧ repeatKernel m r ≤ 1 unfold repeatKernel constructor · linarith · have : 0 ≤ noRepeat m r := by unfold noRepeat; positivity linarith
    Causalean.Mathlib.Probability.Birthday.repeatKernel_mem_Icc · Causalean/Mathlib/Probability/Birthday/Finite.lean:16
  • repeatKernel_eq_one_of_lt theorem — If the draw count exceeds the alphabet, the repeat probability is one.
    m r :
    ℕ
    hr :
    m < r
    repeatKernel m r = 1
    Proof (Lean source)
    theorem repeatKernel_eq_one_of_lt (m r : ℕ) (hr : m < r) : repeatKernel m r = 1 := by simp [repeatKernel, noRepeat, Nat.descFactorial_eq_zero_iff_lt.mpr hr]
    Causalean.Mathlib.Probability.Birthday.repeatKernel_eq_one_of_lt · Causalean/Mathlib/Probability/Birthday/Finite.lean:33
  • repeatKernel_le_pairs theorem — For a positive alphabet, the repeat probability is at most the number of unordered draw pairs divided by the alphabet size.
    m r :
    ℕ
    hm :
    0 < m
    repeatKernel m r ≤ (r.choose 2 : ℝ) / (m : ℝ)
    Proof (Lean source)
    theorem repeatKernel_le_pairs (m r : ℕ) (hm : 0 < m) : repeatKernel m r ≤ (r.choose 2 : ℝ) / (m : ℝ) := by induction r with | zero => simp [repeatKernel, noRepeat] | succ r ih => have hmpos : (0 : ℝ) < m := by exact_mod_cast hm have hpow : 0 < (m : ℝ) ^ r := pow_pos hmpos _ have hfac : (m.descFactorial r : ℝ) ≤ (m : ℝ) ^ r := by exact_mod_cast Nat.descFactorial_le_pow m r have hq0 : 0 ≤ (m.descFactorial r : ℝ) / (m : ℝ) ^ r := by positivity have hq1 : (m.descFactorial r : ℝ) / (m : ℝ) ^ r ≤ 1 := by exact (div_le_iff₀ hpow).2 (by simpa using hfac) have hsub : (m : ℝ) - r ≤ (m - r : ℕ) := by by_cases h : r ≤ m · rw [Nat.cast_sub h] · have : (m : ℝ) ≤ r := by exact_mod_cast (le_of_lt (Nat.lt_of_not_ge h)) simp only [Nat.sub_eq_zero_of_le (le_of_lt (Nat.lt_of_not_ge h)), Nat.cast_zero] linarith have hsub1 : ((m - r : ℕ) : ℝ) ≤ m := by exact_mod_cast Nat.sub_le m r have hrec : (m.descFactorial (r + 1) : ℝ) / (m : ℝ) ^ (r + 1) = ((m - r : ℕ) : ℝ) / (m : ℝ) * ((m.descFactorial r : ℝ) / (m : ℝ) ^ r) := by rw [Nat.descFactorial_succ, Nat.cast_mul, pow_succ] ring have hchoose : ((r + 1).choose 2 : ℝ) = (r.choose 2 : ℝ) + r := by rw [Nat.choose_succ_succ'] simp ring unfold repeatKernel noRepeat at ih ⊢ rw [hrec, hchoose] have hratio0 : 0 ≤ 1 - ((m - r : ℕ) : ℝ) / (m : ℝ) := by apply sub_nonneg.mpr exact (div_le_iff₀ hmpos).2 (by simp [hsub1]) have hratio : 1 - ((m - r : ℕ) : ℝ) / (m : ℝ) ≤ (r : ℝ) / (m : ℝ) := by apply (le_div_iff₀ hmpos).2 have : (1 - ((m - r : ℕ) : ℝ) / (m : ℝ)) * (m : ℝ) = (m : ℝ) - (m - r : ℕ) := by field_simp rw [this] linarith have hmul : (1 - ((m - r : ℕ) : ℝ) / (m : ℝ)) * ((m.descFactorial r : ℝ) / (m : ℝ) ^ r) ≤ (r : ℝ) / (m : ℝ) := by calc _ ≤ 1 - ((m - r : ℕ) : ℝ) / (m : ℝ) := by nlinarith _ ≤ _ := hratio have hstep : 1 - ((m - r : ℕ) : ℝ) / (m : ℝ) * ((m.descFactorial r : ℝ) / (m : ℝ) ^ r) ≤ (1 - (m.descFactorial r : ℝ) / (m : ℝ) ^ r) + r / (m : ℝ) := by nlinarith [hmul] exact hstep.trans (by have := add_le_add_right ih (r / (m : ℝ)) simpa [add_div] using this)
    Causalean.Mathlib.Probability.Birthday.repeatKernel_le_pairs · Causalean/Mathlib/Probability/Birthday/Finite.lean:39
  • noRepeat_le_exp theorem — For a positive alphabet, the no-repeat probability is at most the exponential of minus the pair count over the alphabet size.
    m r :
    ℕ
    hm :
    0 < m
    noRepeat m r ≤ exp (-((r.choose 2 : ℕ) : ℝ) / (m : ℝ))
    Proof (Lean source)
    theorem noRepeat_le_exp (m r : ℕ) (hm : 0 < m) : noRepeat m r ≤ exp (-((r.choose 2 : ℕ) : ℝ) / (m : ℝ)) := by have hmpos : (0 : ℝ) < m := by exact_mod_cast hm induction r with | zero => simp [noRepeat] | succ r ih => by_cases h : r < m · have hcast : ((m - r : ℕ) : ℝ) = (m : ℝ) - r := Nat.cast_sub h.le have hfactor : ((m - r : ℕ) : ℝ) / m ≤ exp (-(r : ℝ) / m) := by rw [hcast] have hbasic := Real.one_sub_le_exp_neg ((r : ℝ) / m) have heq : ((m : ℝ) - r) / m = 1 - (r : ℝ) / m := by field_simp rw [heq] simpa only [neg_div] using hbasic have hrec : noRepeat m (r + 1) = ((m - r : ℕ) : ℝ) / m * noRepeat m r := by unfold noRepeat rw [Nat.descFactorial_succ, Nat.cast_mul, pow_succ] ring have hchoose : ((r + 1).choose 2 : ℝ) = (r.choose 2 : ℝ) + r := by rw [Nat.choose_succ_succ'] simp ring rw [hrec, hchoose] calc _ ≤ exp (-(r : ℝ) / m) * noRepeat m r := mul_le_mul_of_nonneg_right hfactor (by unfold noRepeat; positivity) _ ≤ exp (-(r : ℝ) / m) * exp (-((r.choose 2 : ℕ) : ℝ) / m) := mul_le_mul_of_nonneg_left ih (Real.exp_nonneg _) _ = exp (-(((r.choose 2 : ℕ) : ℝ) + r) / m) := by rw [← Real.exp_add] congr 1 ring · have hzero : m - r = 0 := Nat.sub_eq_zero_of_le (Nat.le_of_not_gt h) simpa [noRepeat, Nat.descFactorial_succ, hzero] using (Real.exp_nonneg (-(((r + 1).choose 2 : ℕ) : ℝ) / m))
    Causalean.Mathlib.Probability.Birthday.noRepeat_le_exp · Causalean/Mathlib/Probability/Birthday/Finite.lean:96
  • exp_le_noRepeat theorem — For a positive alphabet and draw count within it, the no-repeat probability is at least the exponential pair bound with the remaining alphabet size in its denominator.
    m r :
    ℕ
    hm :
    0 < m
    hr :
    r ≤ m
    exp (-((r.choose 2 : ℕ) : ℝ) / (m + 1 - r : ℕ)) ≤ noRepeat m r
    Proof (Lean source)
    theorem exp_le_noRepeat (m r : ℕ) (hm : 0 < m) (hr : r ≤ m) : exp (-((r.choose 2 : ℕ) : ℝ) / (m + 1 - r : ℕ)) ≤ noRepeat m r := by induction r with | zero => simp [noRepeat] | succ r ih => have hrm : r < m := Nat.lt_of_succ_le hr have hmpos : (0 : ℝ) < m := by exact_mod_cast hm have hden_nat : m + 1 - (r + 1) = m - r := by omega have hden_pos_nat : 0 < m - r := Nat.sub_pos_of_lt hrm have hden_pos : (0 : ℝ) < (m - r : ℕ) := by exact_mod_cast hden_pos_nat have hfactor : exp (-(r : ℝ) / (m - r : ℕ)) ≤ ((m - r : ℕ) : ℝ) / m := by have hx1 : (r : ℝ) / m < 1 := (div_lt_one hmpos).2 (by exact_mod_cast hrm) have hpos : 0 < 1 - (r : ℝ) / m := sub_pos.mpr hx1 have hlog := Real.one_sub_inv_le_log_of_pos hpos have hid : 1 - (1 - (r : ℝ) / m)⁻¹ = -((r : ℝ) / m) / (1 - (r : ℝ) / m) := by have hmr : (m : ℝ) - r ≠ 0 := by rw [← Nat.cast_sub hrm.le] exact ne_of_gt hden_pos field_simp [ne_of_gt hmpos, ne_of_gt hpos, hmr] ring rw [hid] at hlog have h := (Real.exp_le_exp.mpr hlog).trans (le_of_eq (Real.exp_log hpos)) have hone : 1 - (r : ℝ) / m = ((m - r : ℕ) : ℝ) / m := by rw [Nat.cast_sub hrm.le] field_simp have hexp : -((r : ℝ) / m) / (1 - (r : ℝ) / m) = -(r : ℝ) / (m - r : ℕ) := by rw [Nat.cast_sub hrm.le] field_simp rw [hexp, hone] at h exact h have ih' := ih (le_of_lt hrm) have hden_le : (m - r : ℕ) ≤ m + 1 - r := by omega have hchoose_nonneg : (0 : ℝ) ≤ (r.choose 2 : ℕ) := Nat.cast_nonneg _ have hweak : exp (-((r.choose 2 : ℕ) : ℝ) / (m - r : ℕ)) ≤ exp (-((r.choose 2 : ℕ) : ℝ) / (m + 1 - r : ℕ)) := by apply Real.exp_le_exp.mpr have hsmall_nat : 0 < m + 1 - r := by omega have hsmall : (0 : ℝ) < (m + 1 - r : ℕ) := by exact_mod_cast hsmall_nat have hcastle : ((m - r : ℕ) : ℝ) ≤ (m + 1 - r : ℕ) := by exact_mod_cast hden_le have := div_le_div_of_nonneg_left hchoose_nonneg hden_pos hcastle simpa only [neg_div] using neg_le_neg this have hrec : noRepeat m (r + 1) = (((m - r : ℕ) : ℝ) / m) * noRepeat m r := by unfold noRepeat rw [Nat.descFactorial_succ, Nat.cast_mul, pow_succ] ring rw [hden_nat, hrec] calc exp (-(((r + 1).choose 2 : ℕ) : ℝ) / (m - r : ℕ)) = exp (-(r : ℝ) / (m - r : ℕ)) * exp (-((r.choose 2 : ℕ) : ℝ) / (m - r : ℕ)) := by rw [← Real.exp_add, Nat.choose_succ_succ'] simp ring _ ≤ (((m - r : ℕ) : ℝ) / m) * exp (-((r.choose 2 : ℕ) : ℝ) / (m + 1 - r : ℕ)) := mul_le_mul hfactor hweak (Real.exp_nonneg _) (by positivity) _ ≤ (((m - r : ℕ) : ℝ) / m) * noRepeat m r := mul_le_mul_of_nonneg_left ih' (by positivity)
    Causalean.Mathlib.Probability.Birthday.exp_le_noRepeat · Causalean/Mathlib/Probability/Birthday/Finite.lean:139
  • noRepeat_mono_succ theorem — As the positive alphabet grows by one, the no-repeat probability increases.
    m r :
    ℕ
    hm :
    0 < m
    noRepeat m r ≤ noRepeat (m + 1) r
    Proof (Lean source)
    theorem noRepeat_mono_succ (m r : ℕ) (hm : 0 < m) : noRepeat m r ≤ noRepeat (m + 1) r := by induction r with | zero => simp [noRepeat] | succ r ih => by_cases hr : r < m · have hmpos : (0 : ℝ) < m := by exact_mod_cast hm have hm1pos : (0 : ℝ) < m + 1 := by positivity have hfac : ((m - r : ℕ) : ℝ) / m ≤ (((m + 1) - r : ℕ) : ℝ) / (m + 1) := by rw [Nat.cast_sub hr.le, Nat.cast_sub (by omega : r ≤ m + 1)] apply (div_le_div_iff₀ hmpos hm1pos).2 push_cast nlinarith have hleft : 0 ≤ noRepeat m r := by unfold noRepeat; positivity have hright : (0 : ℝ) ≤ (((m + 1) - r : ℕ) : ℝ) / (m + 1) := by positivity have hrecL : noRepeat m (r + 1) = (((m - r : ℕ) : ℝ) / m) * noRepeat m r := by unfold noRepeat rw [Nat.descFactorial_succ, Nat.cast_mul, pow_succ] ring have hrecR : noRepeat (m + 1) (r + 1) = ((((m + 1) - r : ℕ) : ℝ) / (m + 1 : ℝ)) * noRepeat (m + 1) r := by unfold noRepeat rw [Nat.descFactorial_succ, Nat.cast_mul, pow_succ] field_simp [ne_of_gt hm1pos] push_cast ring rw [hrecL, hrecR] exact mul_le_mul hfac ih hleft hright · have hzero : m.descFactorial (r + 1) = 0 := Nat.descFactorial_of_lt (by omega) rw [noRepeat, hzero, Nat.cast_zero, zero_div] unfold noRepeat positivity
    Causalean.Mathlib.Probability.Birthday.noRepeat_mono_succ · Causalean/Mathlib/Probability/Birthday/Finite.lean:208
  • repeat_antitone_succ theorem — For a valid success probability and positive alphabet, increasing the alphabet cannot raise the averaged repeat probability.
    T m :
    ℕ
    eta :
    ℝ
    hm :
    0 < m
    heta :
    eta ∈ Icc (0 : ℝ) 1
    birthdayRepeat T (m + 1) eta ≤ birthdayRepeat T m eta
    Proof (Lean source)
    theorem repeat_antitone_succ (T m : ℕ) (eta : ℝ) (hm : 0 < m) (heta : eta ∈ Icc (0 : ℝ) 1) : birthdayRepeat T (m + 1) eta ≤ birthdayRepeat T m eta := by unfold birthdayRepeat binomialAverage apply Finset.sum_le_sum intro r hr have hw : 0 ≤ binomialWeight T eta r := by simp only [binomialWeight] exact mul_nonneg (mul_nonneg (Nat.cast_nonneg _) (pow_nonneg heta.1 _)) (pow_nonneg (sub_nonneg.mpr heta.2) _) apply mul_le_mul_of_nonneg_left _ hw unfold repeatKernel linarith [noRepeat_mono_succ m r hm]
    Causalean.Mathlib.Probability.Birthday.repeat_antitone_succ · Causalean/Mathlib/Probability/Birthday/Finite.lean:248
Limit 1 core · 1 supporting The finite birthday sandwich gives uniform control on a relative mean band. ★ repeat_tendsto

The binomial birthday collision limit

The finite birthday sandwich gives uniform control on a relative mean band. Together with concentration, this yields the averaged collision limit.

theorem repeat_tendsto reviewed
Causalean.Mathlib.Probability.Birthday

For valid success probabilities, a diverging expected draw count, positive alphabets, and pair scale per label tending to a positive value q, the binomially averaged repeat probability tends to 1 − exp(−q), one minus the Poisson no-collision probability at that limiting scale.

Formal statement
Tseq mseq :
ℕ → ℕ
etaseq :
ℕ → ℝ
q :
ℝ
heta :
∀ j, etaseq j ∈ Icc (0 : ℝ) 1
hmean :
Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
hm :
∀ j, 0 < mseq j
hscale :
Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)
hq :
0 < q
Tendsto (fun j => birthdayRepeat (Tseq j) (mseq j) (etaseq j)) atTop (nhds (1 - exp (-q)))
Proof (Lean source)
theorem repeat_tendsto (Tseq mseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {q : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hm : ∀ j, 0 < mseq j) (hscale : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)) (hq : 0 < q) : Tendsto (fun j => birthdayRepeat (Tseq j) (mseq j) (etaseq j)) atTop (nhds (1 - exp (-q))) := by -- Apply `binomialAverage_tendsto_of_relative_band` to -- `fun j r => repeatKernel (mseq j) r`. The finite kernel bound is -- `repeatKernel_mem_Icc`; rewrite the average by `birthdayRepeat`. have hc : 1 - exp (-q) ∈ Icc (0 : ℝ) 1 := by constructor · have := (Real.exp_le_one_iff).2 (by linarith : -q ≤ 0) linarith · have := Real.exp_nonneg (-q) linarith have hbound : ∀ j r, r ≤ Tseq j → repeatKernel (mseq j) r ∈ Icc (0 : ℝ) 1 := by intro j r _ exact repeatKernel_mem_Icc (mseq j) r (hm j) have h := binomialAverage_tendsto_of_relative_band Tseq etaseq (fun j r => repeatKernel (mseq j) r) (1 - exp (-q)) heta hmean hc hbound (repeatKernel_uniform_on_relative_band Tseq mseq etaseq heta hmean hm hscale hq) simpa only [birthdayRepeat] using h
Causalean.Mathlib.Probability.Birthday.repeat_tendsto · Causalean/Mathlib/Probability/Birthday/Limit.lean:99 · uses birthdayRepeat , mean , pairScale
1 supporting declaration (lemmas, instances)
  • repeatKernel_uniform_on_relative_band theorem — If valid success probabilities have a diverging expected count, positive alphabets, and positive finite pair scale, then the birthday kernel approaches its Poisson collision value uniformly on a sufficiently narrow relative band around the binomial mean.
    Tseq mseq :
    ℕ → ℕ
    etaseq :
    ℕ → ℝ
    q :
    ℝ
    heta :
    ∀ j, etaseq j ∈ Icc (0 : ℝ) 1
    hmean :
    Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
    hm :
    ∀ j, 0 < mseq j
    hscale :
    Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)
    hq :
    0 < q
    δ :
    ℝ
    0 < δ
    ∃ ε : ℝ,
    conclusion 1
    0 < ε
    conclusion 2
    ∀ᶠ j in atTop, ∀ r : ℕ, r
    ≤ Tseq j → |(r : ℝ)
    - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |repeatKernel (mseq j) r
    - (1 - exp (-q))| ≤ δ
    Proof (Lean source)
    theorem repeatKernel_uniform_on_relative_band (Tseq mseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {q : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hm : ∀ j, 0 < mseq j) (hscale : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)) (hq : 0 < q) : ∀ δ : ℝ, 0 < δ → ∃ ε : ℝ, 0 < ε ∧ ∀ᶠ j in atTop, ∀ r : ℕ, r ≤ Tseq j → |(r : ℝ) - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |repeatKernel (mseq j) r - (1 - exp (-q))| ≤ δ := by -- Given δ, use continuity of x ↦ exp (-x) at q to choose a smaller -- exponent tolerance. Intersect the two uniform scale bands from -- LimitBand and shrink their widths with `min`; include the eventual -- `relative_band_below_alphabet` condition. The finite sandwich -- `exp_le_noRepeat` / `noRepeat_le_exp` then bounds noRepeat between -- exponentials whose arguments are both close to q. Subtract from 1. intro δ hδ have hcont : ContinuousAt (fun x : ℝ => exp (-x)) q := by fun_prop obtain ⟨ρ, hρ, hρexp⟩ := (Metric.continuousAt_iff.mp hcont) δ hδ obtain ⟨εa, hεa, ha⟩ := pairCount_div_alphabet_uniform_on_relative_band Tseq mseq etaseq heta hmean hm hscale hq (ρ / 2) (by positivity) obtain ⟨εb, hεb, hb⟩ := pairCount_div_remaining_uniform_on_relative_band Tseq mseq etaseq heta hmean hm hscale hq (ρ / 2) (by positivity) let ε : ℝ := min εa εb have hε : 0 < ε := lt_min hεa hεb have hbelow := relative_band_below_alphabet Tseq mseq etaseq heta hmean hm hscale hε refine ⟨ε, hε, ?_⟩ filter_upwards [ha, hb, hbelow, hmean.eventually_gt_atTop 0] with j haj hbj hjbelow hμ r hrT hrband have hbandA : |(r : ℝ) - mean (Tseq j) (etaseq j)| < εa * mean (Tseq j) (etaseq j) := lt_of_lt_of_le hrband (mul_le_mul_of_nonneg_right (min_le_left _ _) (le_of_lt hμ)) have hbandB : |(r : ℝ) - mean (Tseq j) (etaseq j)| < εb * mean (Tseq j) (etaseq j) := lt_of_lt_of_le hrband (mul_le_mul_of_nonneg_right (min_le_right _ _) (le_of_lt hμ)) have hrm : r ≤ mseq j := hjbelow r hrband have hA := haj r hbandA have hB := hbj r hrm hbandB have hAexp : |exp (-((r.choose 2 : ℝ) / (mseq j : ℝ))) - exp (-q)| ≤ δ := by have ht := hρexp (x := (r.choose 2 : ℝ) / (mseq j : ℝ)) (by simpa [Real.dist_eq] using (lt_of_le_of_lt hA (by linarith : ρ / 2 < ρ))) exact le_of_lt (by simpa [Real.dist_eq] using ht) have hBexp : |exp (-((r.choose 2 : ℝ) / (mseq j + 1 - r : ℕ))) - exp (-q)| ≤ δ := by have ht := hρexp (x := (r.choose 2 : ℝ) / (mseq j + 1 - r : ℕ)) (by simpa [Real.dist_eq] using (lt_of_le_of_lt hB (by linarith : ρ / 2 < ρ))) exact le_of_lt (by simpa [Real.dist_eq] using ht) have hlo := exp_le_noRepeat (mseq j) r (hm j) hrm have hhi := noRepeat_le_exp (mseq j) r (hm j) have hlo' : exp (-((r.choose 2 : ℝ) / (mseq j + 1 - r : ℕ))) ≤ noRepeat (mseq j) r := by convert hlo using 1 <;> ring have hhi' : noRepeat (mseq j) r ≤ exp (-((r.choose 2 : ℝ) / (mseq j : ℝ))) := by convert hhi using 1 <;> ring change |(1 - noRepeat (mseq j) r) - (1 - exp (-q))| ≤ δ rw [show (1 - noRepeat (mseq j) r) - (1 - exp (-q)) = exp (-q) - noRepeat (mseq j) r by ring] apply abs_le.mpr constructor · have := (abs_le.mp hAexp).2 linarith [hhi'] · have := (abs_le.mp hBexp).1 linarith [hlo']
    Causalean.Mathlib.Probability.Birthday.repeatKernel_uniform_on_relative_band · Causalean/Mathlib/Probability/Birthday/Limit.lean:18
Limit­Average 1 core · 0 supporting A bounded count kernel converges in binomial average when it is uniformly close to its target on a fixed relative band around a diverging mean. ★ binomialAverage_tendsto_of_relative_band

Averaging a kernel concentrated around the binomial mean

A bounded count kernel converges in binomial average when it is uniformly close to its target on a fixed relative band around a diverging mean.

theorem binomialAverage_tendsto_of_relative_band reviewed
Causalean.Mathlib.Probability.Birthday

A bounded count kernel that is uniformly close on a relative mean band has a convergent binomial average when the success parameters are valid, the mean diverges, and the target lies in the unit interval.

Formal statement
Tseq :
ℕ → ℕ
etaseq :
ℕ → ℝ
f :
ℕ → ℕ → ℝ
c :
ℝ
heta :
∀ j, etaseq j ∈ Icc (0 : ℝ) 1
hmean :
Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
hc :
c ∈ Icc (0 : ℝ) 1
hbound :
∀ j r
if
r ≤ Tseq j
then
f j r ∈ Icc (0 : ℝ) 1
hband :
∀ δ : ℝ,
0 < δ → ∃ ε : ℝ, 0 < ε ∧ ∀ᶠ j in atTop, ∀ r : ℕ, r
≤ Tseq j → |(r : ℝ)
- mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |f j r
- c| ≤ δ
Tendsto (fun j => binomialAverage (Tseq j) (etaseq j) (f j)) atTop (nhds c)
Proof (Lean source)
theorem binomialAverage_tendsto_of_relative_band (Tseq : ℕ → ℕ) (etaseq : ℕ → ℝ) (f : ℕ → ℕ → ℝ) (c : ℝ) (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hc : c ∈ Icc (0 : ℝ) 1) (hbound : ∀ j r, r ≤ Tseq j → f j r ∈ Icc (0 : ℝ) 1) (hband : ∀ δ : ℝ, 0 < δ → ∃ ε : ℝ, 0 < ε ∧ ∀ᶠ j in atTop, ∀ r : ℕ, r ≤ Tseq j → |(r : ℝ) - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |f j r - c| ≤ δ) : Tendsto (fun j => binomialAverage (Tseq j) (etaseq j) (f j)) atTop (nhds c) := by apply (Metric.tendsto_nhds).2 intro a ha obtain ⟨ε, hε, hbandε⟩ := hband (a / 2) (by positivity) have hbad := binomial_relative_deviation_tendsto_zero Tseq etaseq heta hmean hε have hsmall : ∀ᶠ j in atTop, binomialAverage (Tseq j) (etaseq j) (fun r => if ε * mean (Tseq j) (etaseq j) ≤ |(r : ℝ) - mean (Tseq j) (etaseq j)| then 1 else 0) < a / 2 := by have := (Metric.tendsto_nhds.mp hbad) (a / 2) (by positivity) filter_upwards [this] with j hj have hnn : 0 ≤ binomialAverage (Tseq j) (etaseq j) (fun r => if ε * mean (Tseq j) (etaseq j) ≤ |(r : ℝ) - mean (Tseq j) (etaseq j)| then 1 else 0) := by apply binomialAverage_nonneg (Tseq j) (etaseq j) _ (heta j) intro r _ split_ifs <;> norm_num simpa only [Real.dist_eq, sub_zero, abs_of_nonneg hnn] using hj filter_upwards [hbandε, hsmall] with j hjband hjbad let w : ℕ → ℝ := binomialWeight (Tseq j) (etaseq j) let b : ℕ → ℝ := fun r => if ε * mean (Tseq j) (etaseq j) ≤ |(r : ℝ) - mean (Tseq j) (etaseq j)| then 1 else 0 have hw (r : ℕ) : 0 ≤ w r := by dsimp [w, binomialWeight] exact mul_nonneg (mul_nonneg (Nat.cast_nonneg _) (pow_nonneg (heta j).1 _)) (pow_nonneg (sub_nonneg.mpr (heta j).2) _) have hp (r : ℕ) (hr : r ≤ Tseq j) : |f j r - c| ≤ a / 2 + b r := by dsimp [b] split_ifs with hb · have hf := hbound j r hr have : |f j r - c| ≤ 1 := abs_le.mpr ⟨by linarith [hf.1, hc.2], by linarith [hf.2, hc.1]⟩ linarith [le_of_lt ha] · simpa using hjband r hr (lt_of_not_ge hb) have hdiff : binomialAverage (Tseq j) (etaseq j) (f j) - c = ∑ r ∈ range (Tseq j + 1), w r * (f j r - c) := by calc _ = binomialAverage (Tseq j) (etaseq j) (f j) - c * binomialAverage (Tseq j) (etaseq j) (fun _ => 1) := by rw [binomialAverage_one]; ring _ = ∑ r ∈ range (Tseq j + 1), w r * (f j r - c) := by simp only [binomialAverage, mul_one] rw [Finset.mul_sum, ← Finset.sum_sub_distrib] apply Finset.sum_congr rfl intro r _ dsimp [w] ring have hboundavg : |binomialAverage (Tseq j) (etaseq j) (f j) - c| ≤ a / 2 + binomialAverage (Tseq j) (etaseq j) b := by rw [hdiff] calc |∑ r ∈ range (Tseq j + 1), w r * (f j r - c)| ≤ ∑ r ∈ range (Tseq j + 1), |w r * (f j r - c)| := Finset.abs_sum_le_sum_abs _ _ _ ≤ ∑ r ∈ range (Tseq j + 1), w r * (a / 2 + b r) := by apply Finset.sum_le_sum intro r hr rw [abs_mul, abs_of_nonneg (hw r)] exact mul_le_mul_of_nonneg_left (hp r (Nat.lt_succ_iff.mp (Finset.mem_range.mp hr))) (hw r) _ = a / 2 + binomialAverage (Tseq j) (etaseq j) b := by simp only [mul_add, Finset.sum_add_distrib] rw [← Finset.sum_mul] have hunit : (∑ r ∈ range (Tseq j + 1), w r) = 1 := by simpa [binomialAverage, w] using binomialAverage_one (Tseq j) (etaseq j) rw [hunit] change 1 * (a / 2) + binomialAverage (Tseq j) (etaseq j) b = _ ring change dist (binomialAverage (Tseq j) (etaseq j) (f j)) c < a rw [Real.dist_eq] change binomialAverage (Tseq j) (etaseq j) b < a / 2 at hjbad linarith
Causalean.Mathlib.Probability.Birthday.binomialAverage_tendsto_of_relative_band · Causalean/Mathlib/Probability/Birthday/LimitAverage.lean:17 · uses binomialAverage , mean
Limit­Band 1 core · 3 supporting The binomial mean is negligible relative to the alphabet at positive finite collision scale. ★ pairCount_div_remaining_uniform_on_relative_band

Relative-band scale estimates for the birthday limit

The binomial mean is negligible relative to the alphabet at positive finite collision scale. Pair counts on a relative mean band have uniform limits with both the full and the remaining-alphabet denominators.

theorem pairCount_div_remaining_uniform_on_relative_band reviewed
Causalean.Mathlib.Probability.Birthday

For valid success probabilities, a diverging mean, positive alphabets, and a positive finite collision scale, for every tolerance there is a relative band width such that, eventually, every draw count r not exceeding the alphabet size m and within that relative band of the mean has its pair count divided by the remaining alphabet m + 1 − r within the tolerance of that scale.

Formal statement
Tseq mseq :
ℕ → ℕ
etaseq :
ℕ → ℝ
q :
ℝ
heta :
∀ j, etaseq j ∈ Icc (0 : ℝ) 1
hmean :
Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
hm :
∀ j, 0 < mseq j
hscale :
Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)
hq :
0 < q
δ :
ℝ
0 < δ
∃ ε : ℝ,
conclusion 1
0 < ε
conclusion 2
∀ᶠ j in atTop, ∀ r : ℕ, r
≤ mseq j → |(r : ℝ)
- mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |(r.choose 2 : ℝ) / (mseq j + 1 - r : ℕ)
- q| ≤ δ
Proof (Lean source)
theorem pairCount_div_remaining_uniform_on_relative_band (Tseq mseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {q : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hm : ∀ j, 0 < mseq j) (hscale : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)) (hq : 0 < q) : ∀ δ : ℝ, 0 < δ → ∃ ε : ℝ, 0 < ε ∧ ∀ᶠ j in atTop, ∀ r : ℕ, r ≤ mseq j → |(r : ℝ) - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |(r.choose 2 : ℝ) / (mseq j + 1 - r : ℕ) - q| ≤ δ := by -- On the band, r/m→0 uniformly. Compare denominators using -- (m+1-r)/m = 1 + 1/m - r/m, then apply the full-denominator estimate. intro δ hδ obtain ⟨εa, hεa, ha⟩ := pairCount_div_alphabet_uniform_on_relative_band Tseq mseq etaseq heta hmean hm hscale hq (δ / 2) (by positivity) obtain ⟨εb, hεb, hb⟩ := pairCount_div_alphabet_uniform_on_relative_band Tseq mseq etaseq heta hmean hm hscale hq 1 (by norm_num) let ε : ℝ := min εa (min εb 1) have hε : 0 < ε := lt_min hεa (lt_min hεb (by norm_num)) have hεa' : ε ≤ εa := min_le_left _ _ have hεb' : ε ≤ εb := le_trans (min_le_right _ _) (min_le_left _ _) have hεone : ε ≤ 1 := le_trans (min_le_right _ _) (min_le_right _ _) refine ⟨ε, hε, ?_⟩ have hzero := mean_div_alphabet_tendsto_zero Tseq mseq etaseq heta hmean hm hscale have hQ : 0 < q + 1 := by linarith have hc : 0 < min (1 / 4 : ℝ) (δ / (8 * (q + 1))) := lt_min (by norm_num) (by positivity) have hsmall := hzero.eventually (eventually_lt_nhds hc) have hμpos := hmean.eventually_gt_atTop 0 filter_upwards [ha, hb, hsmall, hμpos] with j haj hbj hs hμ r hrle hr let μ : ℝ := mean (Tseq j) (etaseq j) let m : ℝ := mseq j let c : ℝ := (r.choose 2 : ℝ) let d : ℝ := (mseq j + 1 - r : ℕ) have hmpos : 0 < m := by dsimp [m]; exact_mod_cast hm j have hmne : m ≠ 0 := ne_of_gt hmpos have hbandA : |(r : ℝ) - μ| < εa * μ := by exact lt_of_lt_of_le hr (mul_le_mul_of_nonneg_right hεa' (le_of_lt hμ)) have hbandB : |(r : ℝ) - μ| < εb * μ := by exact lt_of_lt_of_le hr (mul_le_mul_of_nonneg_right hεb' (le_of_lt hμ)) have hnear : |c / m - q| ≤ δ / 2 := haj r hbandA have hupper : c / m ≤ q + 1 := by have ht := hbj r hbandB have := (abs_le.mp ht).2 linarith have hc0 : 0 ≤ c := by dsimp [c]; positivity have hcmax : c ≤ (q + 1) * m := (div_le_iff₀ hmpos).mp hupper have hμquarter : μ < m / 4 := by have ht : μ / m < (1 / 4 : ℝ) := lt_of_lt_of_le hs (min_le_left _ _) have ht' := (div_lt_iff₀ hmpos).mp ht nlinarith have hμdelta : (q + 1) * μ < (δ / 8) * m := by have ht : μ / m < δ / (8 * (q + 1)) := lt_of_lt_of_le hs (min_le_right _ _) have ht' := (lt_div_iff₀ (show 0 < 8 * (q + 1) by positivity)).mp ht have ht'' : μ * (8 * (q + 1)) < δ * m := by calc μ * (8 * (q + 1)) = (μ / m * (8 * (q + 1))) * m := by field_simp _ < δ * m := mul_lt_mul_of_pos_right ht' hmpos nlinarith have hrupper : (r : ℝ) ≤ 2 * μ := by have hh := mul_le_mul_of_nonneg_right hεone (le_of_lt hμ) have ht := (abs_lt.mp hr).2 nlinarith have hrhalf : (r : ℝ) ≤ m / 2 := by linarith have hrdelta : (q + 1) * (r : ℝ) ≤ (δ / 4) * m := by nlinarith [mul_le_mul_of_nonneg_left hrupper (le_of_lt hQ)] have hdidentity : d = m + 1 - (r : ℝ) := by dsimp [d, m] rw [Nat.cast_sub (by omega : r ≤ mseq j + 1)] push_cast ring have hdhalf : m / 2 ≤ d := by rw [hdidentity]; linarith have hdpos : 0 < d := by linarith have hdne : d ≠ 0 := ne_of_gt hdpos by_cases hrzero : r = 0 · subst r have ht : |q| ≤ δ / 2 := by simpa [c] using hnear simpa [c, d] using (le_trans ht (by linarith : δ / 2 ≤ δ)) have hrone : (1 : ℝ) ≤ r := by exact_mod_cast (Nat.one_le_iff_ne_zero.mpr hrzero) have hdiffident : c / d - c / m = c * ((r : ℝ) - 1) / (m * d) := by rw [hdidentity] have hdne' : m + 1 - (r : ℝ) ≠ 0 := by rw [← hdidentity]; exact hdne field_simp [hmne, hdne'] ring have hdiffnonneg : 0 ≤ c / d - c / m := by rw [hdiffident] positivity have hdiffcap : c / d - c / m ≤ δ / 2 := by rw [hdiffident] apply (div_le_iff₀ (mul_pos hmpos hdpos)).mpr have h1 : c * ((r : ℝ) - 1) ≤ c * (r : ℝ) := by nlinarith have h2 : c * (r : ℝ) ≤ ((q + 1) * m) * (r : ℝ) := mul_le_mul_of_nonneg_right hcmax (by positivity) have h3 : ((q + 1) * m) * (r : ℝ) ≤ (δ / 4) * m ^ 2 := by nlinarith [mul_le_mul_of_nonneg_right hrdelta (le_of_lt hmpos)] have h4 : (δ / 4) * m ^ 2 ≤ (δ / 2) * (m * d) := by nlinarith [mul_le_mul_of_nonneg_left hdhalf (by positivity : 0 ≤ (δ / 2) * m)] exact le_trans h1 (le_trans h2 (le_trans h3 h4)) have hfinal : |c / d - q| ≤ δ := by calc |c / d - q| = |(c / d - c / m) + (c / m - q)| := by congr 1; ring _ ≤ |c / d - c / m| + |c / m - q| := abs_add_le _ _ _ ≤ δ := by rw [abs_of_nonneg hdiffnonneg]; linarith simpa [c, d] using hfinal
Causalean.Mathlib.Probability.Birthday.pairCount_div_remaining_uniform_on_relative_band · Causalean/Mathlib/Probability/Birthday/LimitBand.lean:200 · uses mean , pairScale
3 supporting declarations (lemmas, instances)
  • mean_div_alphabet_tendsto_zero theorem — For valid success probabilities, a diverging mean, positive alphabets, and a convergent collision scale, the mean divided by the alphabet tends to zero.
    Tseq mseq :
    ℕ → ℕ
    etaseq :
    ℕ → ℝ
    q :
    ℝ
    heta :
    ∀ j, etaseq j ∈ Icc (0 : ℝ) 1
    hmean :
    Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
    hm :
    ∀ j, 0 < mseq j
    hscale :
    Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)
    Tendsto (fun j => mean (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds 0)
    Proof (Lean source)
    theorem mean_div_alphabet_tendsto_zero (Tseq mseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {q : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hm : ∀ j, 0 < mseq j) (hscale : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)) : Tendsto (fun j => mean (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds 0) := by -- Factor μ/m as (A/m)·(μ/A); A/(μ²/2)→1 and μ→∞. -- Alternatively derive m/μ→∞ from A/m→q and A~μ²/2. have hd : Tendsto (fun j => mean (Tseq j) (etaseq j) - etaseq j) atTop atTop := by apply tendsto_atTop.2 intro b filter_upwards [hmean.eventually_ge_atTop (b + 1)] with j hj have he := (heta j).2 linarith have hinv : Tendsto (fun j => (mean (Tseq j) (etaseq j) - etaseq j)⁻¹) atTop (nhds 0) := tendsto_inv_atTop_zero.comp hd have hprod := (hscale.const_mul 2).mul hinv have hpos := hd.eventually_gt_atTop 0 have hprod' : Tendsto (fun j => 2 * (pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) * (mean (Tseq j) (etaseq j) - etaseq j)⁻¹) atTop (nhds 0) := by simpa using hprod apply hprod'.congr' filter_upwards [hpos] with j hj have hmj : (mseq j : ℝ) ≠ 0 := by exact_mod_cast (Nat.ne_of_gt (hm j)) have hdj : mean (Tseq j) (etaseq j) - etaseq j ≠ 0 := ne_of_gt hj have hident : 2 * pairScale (Tseq j) (etaseq j) = mean (Tseq j) (etaseq j) * (mean (Tseq j) (etaseq j) - etaseq j) := by simp only [pairScale, mean, Nat.cast_choose_two] ring field_simp [hmj, hdj] nlinarith [hident]
    Causalean.Mathlib.Probability.Birthday.mean_div_alphabet_tendsto_zero · Causalean/Mathlib/Probability/Birthday/LimitBand.lean:18
  • relative_band_below_alphabet theorem — For valid success probabilities, a diverging mean, positive alphabets, a convergent collision scale, and a fixed relative band width, draw counts in that band are eventually below the alphabet.
    Tseq mseq :
    ℕ → ℕ
    etaseq :
    ℕ → ℝ
    q ε :
    ℝ
    heta :
    ∀ j, etaseq j ∈ Icc (0 : ℝ) 1
    hmean :
    Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
    hm :
    ∀ j, 0 < mseq j
    hscale :
    Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)
    hε :
    0 < ε
    ∀ᶠ j in atTop, ∀ r : ℕ, |(r : ℝ)
    - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → r
    ≤ mseq j
    Proof (Lean source)
    theorem relative_band_below_alphabet (Tseq mseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {q ε : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hm : ∀ j, 0 < mseq j) (hscale : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)) (hε : 0 < ε) : ∀ᶠ j in atTop, ∀ r : ℕ, |(r : ℝ) - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → r ≤ mseq j := by -- The band gives r < (1+ε)μ; μ/m→0 implies (1+ε)μ<m eventually. have hzero := mean_div_alphabet_tendsto_zero Tseq mseq etaseq heta hmean hm hscale have hc : (0 : ℝ) < 1 / (1 + ε) := by positivity have hsmall := hzero.eventually (eventually_lt_nhds hc) have hpos := hmean.eventually_gt_atTop 0 filter_upwards [hsmall, hpos] with j hs hμ r hr have hmj : (0 : ℝ) < (mseq j : ℝ) := by exact_mod_cast hm j have hmul : mean (Tseq j) (etaseq j) / (mseq j : ℝ) * (1 + ε) < 1 := (lt_div_iff₀ (by linarith : (0 : ℝ) < 1 + ε)).mp hs have hbound : mean (Tseq j) (etaseq j) * (1 + ε) < (mseq j : ℝ) := by have ht : mean (Tseq j) (etaseq j) * (1 + ε) / (mseq j : ℝ) < 1 := by calc mean (Tseq j) (etaseq j) * (1 + ε) / (mseq j : ℝ) = mean (Tseq j) (etaseq j) / (mseq j : ℝ) * (1 + ε) := by ring _ < 1 := hmul exact (div_lt_iff₀ hmj).mp ht |>.trans_eq (one_mul _) have hrlt : (r : ℝ) < (mseq j : ℝ) := by rw [abs_lt] at hr nlinarith [hr.2] exact le_of_lt (by exact_mod_cast hrlt)
    Causalean.Mathlib.Probability.Birthday.relative_band_below_alphabet · Causalean/Mathlib/Probability/Birthday/LimitBand.lean:58
  • pairCount_div_alphabet_uniform_on_relative_band theorem — For valid success probabilities, a diverging mean, positive alphabets, and a positive finite collision scale, the pair count per alphabet is uniformly close to that scale on a sufficiently narrow relative mean band.
    Tseq mseq :
    ℕ → ℕ
    etaseq :
    ℕ → ℝ
    q :
    ℝ
    heta :
    ∀ j, etaseq j ∈ Icc (0 : ℝ) 1
    hmean :
    Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
    hm :
    ∀ j, 0 < mseq j
    hscale :
    Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)
    hq :
    0 < q
    δ :
    ℝ
    0 < δ
    ∃ ε : ℝ,
    conclusion 1
    0 < ε
    conclusion 2
    ∀ᶠ j in atTop, ∀ r : ℕ, |(r : ℝ)
    - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |(r.choose 2 : ℝ) / (mseq j : ℝ)
    - q|
    ≤ δ
    Proof (Lean source)
    theorem pairCount_div_alphabet_uniform_on_relative_band (Tseq mseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {q : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hm : ∀ j, 0 < mseq j) (hscale : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mseq j : ℝ)) atTop (nhds q)) (hq : 0 < q) : ∀ δ : ℝ, 0 < δ → ∃ ε : ℝ, 0 < ε ∧ ∀ᶠ j in atTop, ∀ r : ℕ, |(r : ℝ) - mean (Tseq j) (etaseq j)| < ε * mean (Tseq j) (etaseq j) → |(r.choose 2 : ℝ) / (mseq j : ℝ) - q| ≤ δ := by -- Write choose(r,2)=r(r-1)/2 and A~μ²/2; choose ε to bound -- |(r/μ)²-1| and use μ/m→0 for the linear r term. intro δ hδ let C : ℝ := 2 * q + 3 have hC : 0 < C := by dsimp [C]; linarith let ε : ℝ := min (1 / 2) (δ / (12 * C)) have hε : 0 < ε := lt_min (by norm_num) (by positivity) have hεhalf : ε ≤ 1 / 2 := min_le_left _ _ have hεC : ε * C ≤ δ / 12 := by calc ε * C ≤ (δ / (12 * C)) * C := mul_le_mul_of_nonneg_right (min_le_right _ _) (le_of_lt hC) _ = δ / 12 := by field_simp refine ⟨ε, hε, ?_⟩ have hzero := mean_div_alphabet_tendsto_zero Tseq mseq etaseq heta hmean hm hscale have hsmall := hzero.eventually (eventually_lt_nhds (show (0 : ℝ) < δ / 12 by positivity)) have hone := hzero.eventually (eventually_lt_nhds (show (0 : ℝ) < 1 by norm_num)) have hμpos := hmean.eventually_gt_atTop 0 have hAnear := (Metric.tendsto_nhds.mp hscale) (δ / 4) (by positivity) have hAupper := hscale.eventually (eventually_lt_nhds (show q < q + 1 by linarith)) filter_upwards [hsmall, hone, hμpos, hAnear, hAupper] with j hs hμone hμ hn hAu r hr let μ : ℝ := mean (Tseq j) (etaseq j) let A : ℝ := pairScale (Tseq j) (etaseq j) let m : ℝ := mseq j have hmpos : 0 < m := by dsimp [m]; exact_mod_cast hm j have hmne : m ≠ 0 := ne_of_gt hmpos have hsmall' : μ < (δ / 12) * m := (div_lt_iff₀ hmpos).mp hs have hμone' : μ < m := by simpa using (div_lt_iff₀ hmpos).mp hμone have hAupper' : A < (q + 1) * m := (div_lt_iff₀ hmpos).mp hAu have hident : 2 * A = μ * (μ - etaseq j) := by dsimp [A, μ] simp only [pairScale, mean, Nat.cast_choose_two] ring have he0 : 0 ≤ etaseq j := (heta j).1 have he1 : etaseq j ≤ 1 := (heta j).2 have heμ : μ * etaseq j ≤ μ := by nlinarith [mul_nonneg (le_of_lt hμ) (sub_nonneg.mpr he1)] have hμsq : μ ^ 2 ≤ C * m := by dsimp [C] nlinarith [hident] have hsqcap : 3 * ε * μ ^ 2 ≤ (δ / 4) * m := by calc 3 * ε * μ ^ 2 ≤ (3 * ε) * (C * m) := mul_le_mul_of_nonneg_left hμsq (by positivity) _ = (3 * (ε * C)) * m := by ring _ ≤ (δ / 4) * m := mul_le_mul_of_nonneg_right (by nlinarith [hεC]) (le_of_lt hmpos) have hrband := (abs_lt.mp hr) have hrupper : (r : ℝ) ≤ 2 * μ := by have hh := mul_le_mul_of_nonneg_right hεhalf (le_of_lt hμ) nlinarith have hsum : 0 ≤ (r : ℝ) + μ := by positivity have hsumupper : (r : ℝ) + μ ≤ 3 * μ := by linarith have hsqabs : |(r : ℝ) ^ 2 - μ ^ 2| ≤ 3 * ε * μ ^ 2 := by have hf : (r : ℝ) ^ 2 - μ ^ 2 = ((r : ℝ) - μ) * ((r : ℝ) + μ) := by ring rw [hf, abs_mul, abs_of_nonneg hsum] calc |(r : ℝ) - μ| * ((r : ℝ) + μ) ≤ (ε * μ) * ((r : ℝ) + μ) := mul_le_mul_of_nonneg_right (le_of_lt hr) hsum _ ≤ (ε * μ) * (3 * μ) := mul_le_mul_of_nonneg_left hsumupper (by positivity) _ = 3 * ε * μ ^ 2 := by ring have hnum : |(r : ℝ) ^ 2 - (r : ℝ) - 2 * A| ≤ (δ / 2) * m := by rw [abs_le] have hsqbounds := abs_le.mp hsqabs constructor <;> nlinarith [hident, hsqcap, hsmall', hrupper, heμ] have hpairident : (r.choose 2 : ℝ) / m - A / m = ((r : ℝ) ^ 2 - (r : ℝ) - 2 * A) / (2 * m) := by rw [Nat.cast_choose_two] field_simp have hpair : |(r.choose 2 : ℝ) / m - A / m| ≤ δ / 4 := by rw [hpairident, abs_div, abs_of_pos (show 0 < 2 * m by positivity)] calc |(r : ℝ) ^ 2 - (r : ℝ) - 2 * A| / (2 * m) ≤ ((δ / 2) * m) / (2 * m) := div_le_div_of_nonneg_right hnum (by positivity) _ = δ / 4 := by field_simp; ring have hAnear' : |A / m - q| < δ / 4 := by simpa [Real.dist_eq, A, m] using hn have hfinal : |(r.choose 2 : ℝ) / m - q| ≤ δ := by calc |(r.choose 2 : ℝ) / m - q| ≤ |(r.choose 2 : ℝ) / m - A / m| + |A / m - q| := by calc |(r.choose 2 : ℝ) / m - q| = |((r.choose 2 : ℝ) / m - A / m) + (A / m - q)| := by congr 1; ring _ ≤ _ := abs_add_le _ _ _ ≤ δ := by linarith simpa [m] using hfinal
    Causalean.Mathlib.Probability.Birthday.pairCount_div_alphabet_uniform_on_relative_band · Causalean/Mathlib/Probability/Birthday/LimitBand.lean:94
Limit­Scale 1 core · 0 supporting For T trials with success probability η, the expected number of unordered pairs of successes is C(T, 2)·η², and the mean number of successes is T·η. ★ pairScale_div_half_mean_sq_tendsto_one

The binomial pair scale is asymptotically half the squared mean

For T trials with success probability η, the expected number of unordered pairs of successes is C(T, 2)·η², and the mean number of successes is T·η. Along any sequence of trial counts and probabilities in [0, 1] whose mean T·η tends to infinity, the ratio of C(T, 2)·η² to (T·η)²/2 tends to one, so the two normalizations of the birthday-collision scale are interchangeable in the limit.

Main results

* pairScale_div_half_mean_sq_tendsto_one — the ratio of the pair scale to half the squared mean converges to one when the mean diverges.

theorem pairScale_div_half_mean_sq_tendsto_one reviewed
Causalean.Mathlib.Probability.Birthday

For valid success probabilities and a diverging expected count, the pair scale divided by half the squared mean converges to one.

Formal statement
Tseq :
ℕ → ℕ
etaseq :
ℕ → ℝ
heta :
∀ j, etaseq j ∈ Icc (0 : ℝ) 1
hmean :
Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mean (Tseq j) (etaseq j) ^ 2 / 2)) atTop (nhds 1)
Proof (Lean source)
theorem pairScale_div_half_mean_sq_tendsto_one (Tseq : ℕ → ℕ) (etaseq : ℕ → ℝ) (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (mean (Tseq j) (etaseq j) ^ 2 / 2)) atTop (nhds 1) := by have hpos : ∀ᶠ j : ℕ in atTop, 0 < mean (Tseq j) (etaseq j) := hmean.eventually_gt_atTop 0 have hinv : Tendsto (fun j => (mean (Tseq j) (etaseq j))⁻¹) atTop (nhds 0) := tendsto_inv_atTop_zero.comp hmean have hratio : Tendsto (fun j => etaseq j / mean (Tseq j) (etaseq j)) atTop (nhds 0) := by apply squeeze_zero' _ _ hinv · filter_upwards [hpos] with j hj exact div_nonneg (heta j).1 (le_of_lt hj) · filter_upwards [hpos] with j hj simpa [div_eq_mul_inv] using mul_le_mul_of_nonneg_right (heta j).2 (inv_nonneg.mpr (le_of_lt hj)) have hlim : Tendsto (fun j => 1 - etaseq j / mean (Tseq j) (etaseq j)) atTop (nhds 1) := by simpa using (tendsto_const_nhds (x := (1 : ℝ))).sub hratio apply hlim.congr' filter_upwards [hpos] with j hj have hmu : mean (Tseq j) (etaseq j) ≠ 0 := ne_of_gt hj have hident : 2 * pairScale (Tseq j) (etaseq j) = mean (Tseq j) (etaseq j) * (mean (Tseq j) (etaseq j) - etaseq j) := by simp only [pairScale, mean, Nat.cast_choose_two] ring field_simp [hmu] nlinarith [hident]
Causalean.Mathlib.Probability.Birthday.pairScale_div_half_mean_sq_tendsto_one · Causalean/Mathlib/Probability/Birthday/LimitScale.lean:25 · uses mean , pairScale
Moments 1 core · 2 supporting The binomial weights have unit mass, expected count equal to the trial mean, and expected unordered pair count equal to the pair scale. ★ binomialAverage_pairs

Binomial count moments for birthday averaging

The binomial weights have unit mass, expected count equal to the trial mean, and expected unordered pair count equal to the pair scale.

theorem binomialAverage_pairs reviewed
Causalean.Mathlib.Probability.Birthday

The binomial average for a trial count and success probability of the unordered pair count is the expected pair scale.

Formal statement
T :
ℕ
eta :
ℝ
binomialAverage T eta (fun r => (r.choose 2 : ℝ)) = pairScale T eta
Proof (Lean source)
theorem binomialAverage_pairs (T : ℕ) (eta : ℝ) : binomialAverage T eta (fun r => (r.choose 2 : ℝ)) = pairScale T eta := by by_cases hT : T < 2 · interval_cases T <;> norm_num [binomialAverage, pairScale, binomialWeight, Finset.sum_range_succ] · have hT2 : 2 ≤ T := by omega unfold binomialAverage pairScale calc (∑ r ∈ range (T + 1), binomialWeight T eta r * (r.choose 2 : ℝ)) = ∑ j ∈ range (T - 1), (T.choose 2 : ℝ) * eta ^ 2 * binomialWeight (T - 2) eta j := by rw [Finset.sum_range_succ' (f := fun r => binomialWeight T eta r * (r.choose 2 : ℝ))] simp only [Nat.choose_zero_succ, Nat.cast_zero, mul_zero, add_zero] rw [show T = (T - 1) + 1 by omega, Finset.sum_range_succ' (f := fun j => binomialWeight (T - 1 + 1) eta (j + 1) * ((j + 1).choose 2 : ℝ))] simp only [Nat.sub_add_cancel (show 1 ≤ T by omega)] simp only [Nat.zero_add, show (1 : ℕ).choose 2 = 0 by decide, Nat.cast_zero, mul_zero, add_zero] apply Finset.sum_congr rfl intro j hj have hjlt : j < T - 1 := Finset.mem_range.mp hj have hchoose : (T.choose (j + 2) : ℝ) * ((j + 2).choose 2 : ℝ) = (T.choose 2 : ℝ) * ((T - 2).choose j : ℝ) := by have h := Nat.choose_mul (n := T) (k := j + 2) (s := 2) (by omega) have h' : T.choose (j + 2) * (j + 2).choose 2 = T.choose 2 * (T - 2).choose j := by simpa [show j + 2 - 2 = j by omega] using h exact_mod_cast h' have hsub : T - (j + 2) = (T - 2) - j := by omega simp only [binomialWeight, hsub, show j + 1 + 1 = j + 2 by omega, pow_add] calc (T.choose (j + 2) : ℝ) * (eta ^ j * eta ^ 2) * (1 - eta) ^ (T - 2 - j) * ((j + 2).choose 2 : ℝ) = ((T.choose (j + 2) : ℝ) * ((j + 2).choose 2 : ℝ)) * eta ^ 2 * (eta ^ j * (1 - eta) ^ (T - 2 - j)) := by ring _ = _ := by rw [hchoose]; ring _ = (T.choose 2 : ℝ) * eta ^ 2 * binomialAverage (T - 2) eta (fun _ => 1) := by simp only [binomialAverage, mul_one] rw [show T - 1 = (T - 2) + 1 by omega, Finset.mul_sum] _ = (T.choose 2 : ℝ) * eta ^ 2 := by rw [binomialAverage_one]; ring
Causalean.Mathlib.Probability.Birthday.binomialAverage_pairs · Causalean/Mathlib/Probability/Birthday/Moments.lean:73 · uses binomialAverage , pairScale
2 supporting declarations (lemmas, instances)
  • binomialAverage_one theorem — The binomial weights for a trial count and success probability sum to one.
    T :
    ℕ
    eta :
    ℝ
    binomialAverage T eta (fun _ => 1) = 1
    Proof (Lean source)
    theorem binomialAverage_one (T : ℕ) (eta : ℝ) : binomialAverage T eta (fun _ => 1) = 1 := by unfold binomialAverage simp only [mul_one] calc (∑ r ∈ range (T + 1), binomialWeight T eta r) = (eta + (1 - eta)) ^ T := by rw [add_pow] apply Finset.sum_congr rfl intro r hr simp only [binomialWeight] ring _ = 1 := by ring
    Causalean.Mathlib.Probability.Birthday.binomialAverage_one · Causalean/Mathlib/Probability/Birthday/Moments.lean:15
  • binomialAverage_count theorem — The binomial average for a trial count and success probability of the count equals its mean.
    T :
    ℕ
    eta :
    ℝ
    binomialAverage T eta (fun r => (r : ℝ)) = mean T eta
    Proof (Lean source)
    theorem binomialAverage_count (T : ℕ) (eta : ℝ) : binomialAverage T eta (fun r => (r : ℝ)) = mean T eta := by by_cases hT : T = 0 · subst T simp [binomialAverage, mean] · have hpos : 0 < T := Nat.pos_of_ne_zero hT unfold binomialAverage mean calc (∑ r ∈ range (T + 1), binomialWeight T eta r * (r : ℝ)) = ∑ j ∈ range T, (T : ℝ) * eta * binomialWeight (T - 1) eta j := by rw [Finset.sum_range_succ' (f := fun r => binomialWeight T eta r * (r : ℝ))] simp only [Nat.cast_zero, mul_zero, add_zero] apply Finset.sum_congr rfl intro j hj have hjlt : j < T := Finset.mem_range.mp hj have hchoose : (T.choose (j + 1) : ℝ) * (j + 1 : ℕ) = (T : ℝ) * ((T - 1).choose j : ℝ) := by rw [show T = (T - 1) + 1 by omega] exact_mod_cast (Nat.add_one_mul_choose_eq (T - 1) j).symm have hsub : T - (j + 1) = (T - 1) - j := by omega simp only [binomialWeight, hsub, pow_succ] push_cast rw [show (j : ℝ) + 1 = ((j + 1 : ℕ) : ℝ) by norm_num] calc (T.choose (j + 1) : ℝ) * (eta ^ j * eta) * (1 - eta) ^ (T - 1 - j) * ((j + 1 : ℕ) : ℝ) = ((T.choose (j + 1) : ℝ) * (j + 1 : ℕ)) * eta * (eta ^ j * (1 - eta) ^ (T - 1 - j)) := by ring _ = _ := by rw [hchoose]; ring _ = (T : ℝ) * eta * binomialAverage (T - 1) eta (fun _ => 1) := by simp only [binomialAverage, mul_one] rw [Nat.sub_add_cancel (show 1 ≤ T by omega), Finset.mul_sum] _ = (T : ℝ) * eta := by rw [binomialAverage_one]; ring
    Causalean.Mathlib.Probability.Birthday.binomialAverage_count · Causalean/Mathlib/Probability/Birthday/Moments.lean:32
Threshold 1 core · 0 supporting The least positive alphabet size that meets a fixed collision tolerance is asymptotic to the binomial pair scale divided by its logarithmic constant. ★ mStar_div_calibratedScale_tendsto_one

Asymptotic inversion of the least birthday threshold

The least positive alphabet size that meets a fixed collision tolerance is asymptotic to the binomial pair scale divided by its logarithmic constant.

theorem mStar_div_calibratedScale_tendsto_one reviewed
Causalean.Mathlib.Probability.Birthday

For valid success probabilities, a diverging expected draw count, and a tolerance strictly between zero and one, the least positive alphabet threshold divided by the calibrated pair scale converges to one.

Formal statement
Tseq :
ℕ → ℕ
etaseq :
ℕ → ℝ
delta :
ℝ
heta :
∀ j, etaseq j ∈ Icc (0 : ℝ) 1
hmean :
Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
hdelta :
delta ∈ Ioo (0 : ℝ) 1
Tendsto (fun j => (mStar (Tseq j) (etaseq j) delta : ℝ) / (pairScale (Tseq j) (etaseq j) / (-log (1 - delta)))) atTop (nhds 1)
Proof (Lean source)
theorem mStar_div_calibratedScale_tendsto_one (Tseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {delta : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hdelta : delta ∈ Ioo (0 : ℝ) 1) : Tendsto (fun j => (mStar (Tseq j) (etaseq j) delta : ℝ) / (pairScale (Tseq j) (etaseq j) / (-log (1 - delta)))) atTop (nhds 1) := by -- Set L = -log (1-delta) > 0 and a_j = pairScale_j/L, with a_j → ∞. -- Fix 0 < c₋ < 1 < c₊. At positiveCeil(c*a_j), `repeat_tendsto` -- and `pairScale_div_positiveCeil_tendsto` give limit 1-exp(-L/c). -- This is strictly above delta for c₋ and strictly below it for c₊; -- use `Real.exp_neg_log` / `Real.exp_log` and monotonicity of exp to -- identify delta = 1-exp(-L). Eventual strict inequalities and -- `repeat_le_iff_mStar_le` imply -- positiveCeil(c₋*a_j) < mStar_j ≤ positiveCeil(c₊*a_j). -- Divide by eventually positive a_j and apply -- `positiveCeil_mul_div_tendsto` for the two boundaries. To show -- convergence to 1, use `LinearOrderedAddCommGroup.tendsto_nhds`: -- for each ε>0 choose c₋ = 1-min (ε/2) (1/2) and c₊ = 1+ε/2, -- and combine the eventual bounds with the limits c₋ and c₊. let L : ℝ := -log (1 - delta) let a : ℕ → ℝ := fun j => pairScale (Tseq j) (etaseq j) / L let r : ℕ → ℝ := fun j => (mStar (Tseq j) (etaseq j) delta : ℝ) / a j have hL : 0 < L := neg_log_one_sub_pos hdelta have ha : Tendsto a atTop atTop := calibratedScale_tendsto_atTop Tseq etaseq heta hmean hdelta have hexp : exp (-L) = 1 - delta := by dsimp [L] rw [neg_neg, Real.exp_log (by linarith [hdelta.2])] have hboundary (c : ℝ) (hc : 0 < c) : Tendsto (fun j => birthdayRepeat (Tseq j) (positiveCeil (c * a j)) (etaseq j)) atTop (nhds (1 - exp (-(L / c)))) := by apply repeat_tendsto Tseq (fun j => positiveCeil (c * a j)) etaseq heta hmean (fun j => positiveCeil_pos _) · simpa only [a, L] using pairScale_div_positiveCeil_tendsto Tseq etaseq heta hmean hdelta hc · exact div_pos hL hc have hbelow (c : ℝ) (hc : 0 < c) (hc1 : c < 1) : ∀ᶠ j in atTop, (positiveCeil (c * a j) : ℝ) / a j < r j := by have hq : L < L / c := by apply (lt_div_iff₀ hc).2 nlinarith [mul_pos hL (sub_pos.mpr hc1)] have hlimit : delta < 1 - exp (-(L / c)) := by have he := Real.exp_strictMono (show -(L / c) < -L by linarith) linarith [hexp] have hev := (hboundary c hc).eventually (eventually_gt_nhds hlimit) filter_upwards [hev, ha.eventually_gt_atTop 0] with j hj haj have hm : positiveCeil (c * a j) < mStar (Tseq j) (etaseq j) delta := by by_contra hn have hle := (repeat_le_iff_mStar_le (Tseq j) (positiveCeil (c * a j)) (etaseq j) delta (heta j) hdelta.1 (positiveCeil_pos _)).2 (Nat.le_of_not_gt hn) exact (not_le_of_gt hj) hle exact (div_lt_div_iff_of_pos_right haj).2 (by exact_mod_cast hm) have habove (c : ℝ) (hc : 1 < c) : ∀ᶠ j in atTop, r j ≤ (positiveCeil (c * a j) : ℝ) / a j := by have hc0 : 0 < c := by linarith have hq : L / c < L := by apply (div_lt_iff₀ hc0).2 nlinarith [mul_pos hL (sub_pos.mpr hc)] have hlimit : 1 - exp (-(L / c)) < delta := by have he := Real.exp_strictMono (show -L < -(L / c) by linarith) linarith [hexp] have hev := (hboundary c hc0).eventually (eventually_lt_nhds hlimit) filter_upwards [hev, ha.eventually_gt_atTop 0] with j hj haj have hm : mStar (Tseq j) (etaseq j) delta ≤ positiveCeil (c * a j) := (repeat_le_iff_mStar_le (Tseq j) (positiveCeil (c * a j)) (etaseq j) delta (heta j) hdelta.1 (positiveCeil_pos _)).1 hj.le exact (div_le_div_iff_of_pos_right haj).2 (by exact_mod_cast hm) change Tendsto r atTop (nhds 1) apply tendsto_order.2 constructor · intro b hb let c : ℝ := max (1 / 2) ((b + 1) / 2) have hc : 0 < c := lt_of_lt_of_le (by norm_num) (le_max_left _ _) have hc1 : c < 1 := max_lt (by norm_num) (by dsimp [c] at *; linarith) have hbc : b < c := by dsimp [c] exact lt_of_lt_of_le (by linarith) (le_max_right _ _) filter_upwards [hbelow c hc hc1, (positiveCeil_mul_div_tendsto a ha hc).eventually (eventually_gt_nhds hbc)] with j hj hjc exact lt_trans hjc hj · intro b hb let c : ℝ := (b + 1) / 2 have hc : 1 < c := by dsimp [c]; linarith have hcb : c < b := by dsimp [c]; linarith filter_upwards [habove c hc, (positiveCeil_mul_div_tendsto a ha (by linarith : 0 < c)).eventually (eventually_lt_nhds hcb)] with j hj hjc exact lt_of_le_of_lt hj hjc
Causalean.Mathlib.Probability.Birthday.mStar_div_calibratedScale_tendsto_one · Causalean/Mathlib/Probability/Birthday/Threshold.lean:19 · uses mStar , mean , pairScale
Threshold­Scale 1 core · 2 supporting The logarithmic tolerance constant is positive, the calibrated pair scale diverges, and positive integer ceilings preserve its collision scale. ★ pairScale_div_positiveCeil_tendsto

Calibrating the birthday collision scale

The logarithmic tolerance constant is positive, the calibrated pair scale diverges, and positive integer ceilings preserve its collision scale.

theorem pairScale_div_positiveCeil_tendsto reviewed
Causalean.Mathlib.Probability.Birthday

For valid success probabilities, a diverging expected count, a tolerance between zero and one, and a positive multiplier, the pair scale per positive-ceiling alphabet tends to the logarithmic scale divided by that multiplier.

Formal statement
Tseq :
ℕ → ℕ
etaseq :
ℕ → ℝ
delta c :
ℝ
heta :
∀ j, etaseq j ∈ Icc (0 : ℝ) 1
hmean :
Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
hdelta :
delta ∈ Ioo (0 : ℝ) 1
hc :
0 < c
Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (positiveCeil (c * (pairScale (Tseq j) (etaseq j) / (-log (1 - delta)))) : ℝ)) atTop (nhds ((-log (1 - delta)) / c))
Proof (Lean source)
theorem pairScale_div_positiveCeil_tendsto (Tseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {delta c : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hdelta : delta ∈ Ioo (0 : ℝ) 1) (hc : 0 < c) : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (positiveCeil (c * (pairScale (Tseq j) (etaseq j) / (-log (1 - delta)))) : ℝ)) atTop (nhds ((-log (1 - delta)) / c)) := by let L : ℝ := -log (1 - delta) let a : ℕ → ℝ := fun j => pairScale (Tseq j) (etaseq j) / L have hL : 0 < L := neg_log_one_sub_pos hdelta have ha : Tendsto a atTop atTop := calibratedScale_tendsto_atTop Tseq etaseq heta hmean hdelta have hround : Tendsto (fun j => (positiveCeil (c * a j) : ℝ) / a j) atTop (nhds c) := positiveCeil_mul_div_tendsto a ha hc have hlim : Tendsto (fun j => L / ((positiveCeil (c * a j) : ℝ) / a j)) atTop (nhds (L / c)) := tendsto_const_nhds.div hround hc.ne' change Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (positiveCeil (c * a j) : ℝ)) atTop (nhds (L / c)) apply hlim.congr' filter_upwards [ha.eventually_gt_atTop 0] with j hj have hceil : (positiveCeil (c * a j) : ℝ) ≠ 0 := by exact_mod_cast (positiveCeil_pos (c * a j)).ne' have hane : a j ≠ 0 := hj.ne' have hident : pairScale (Tseq j) (etaseq j) = a j * L := by dsimp [a] field_simp [hL.ne'] rw [hident] field_simp
Causalean.Mathlib.Probability.Birthday.pairScale_div_positiveCeil_tendsto · Causalean/Mathlib/Probability/Birthday/ThresholdScale.lean:47 · uses mean , pairScale , positiveCeil
2 supporting declarations (lemmas, instances)
  • neg_log_one_sub_pos theorem — A tolerance strictly between zero and one has a positive logarithmic collision scale.
    delta :
    ℝ
    hdelta :
    delta ∈ Ioo (0 : ℝ) 1
    0 < -log (1 - delta)
    Proof (Lean source)
    theorem neg_log_one_sub_pos {delta : ℝ} (hdelta : delta ∈ Ioo (0 : ℝ) 1) : 0 < -log (1 - delta) := by have hpos : 0 < 1 - delta := by linarith [hdelta.2] have hlt : 1 - delta < 1 := by linarith [hdelta.1] exact neg_pos.mpr (Real.log_neg hpos hlt)
    Causalean.Mathlib.Probability.Birthday.neg_log_one_sub_pos · Causalean/Mathlib/Probability/Birthday/ThresholdScale.lean:18
  • calibratedScale_tendsto_atTop theorem — For valid success probabilities, a diverging expected count, and a tolerance between zero and one, the calibrated pair scale diverges.
    Tseq :
    ℕ → ℕ
    etaseq :
    ℕ → ℝ
    delta :
    ℝ
    heta :
    ∀ j, etaseq j ∈ Icc (0 : ℝ) 1
    hmean :
    Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop
    hdelta :
    delta ∈ Ioo (0 : ℝ) 1
    Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (-log (1 - delta))) atTop atTop
    Proof (Lean source)
    theorem calibratedScale_tendsto_atTop (Tseq : ℕ → ℕ) (etaseq : ℕ → ℝ) {delta : ℝ} (heta : ∀ j, etaseq j ∈ Icc (0 : ℝ) 1) (hmean : Tendsto (fun j => mean (Tseq j) (etaseq j)) atTop atTop) (hdelta : delta ∈ Ioo (0 : ℝ) 1) : Tendsto (fun j => pairScale (Tseq j) (etaseq j) / (-log (1 - delta))) atTop atTop := by have hden : Tendsto (fun j => mean (Tseq j) (etaseq j) ^ 2 / 2) atTop atTop := by simpa [pow_two] using (tendsto_mul_self_atTop.comp hmean).atTop_div_const (by norm_num : (0 : ℝ) < 2) have hpair : Tendsto (fun j => pairScale (Tseq j) (etaseq j)) atTop atTop := by exact Filter.Tendsto.num hden zero_lt_one (pairScale_div_half_mean_sq_tendsto_one Tseq etaseq heta hmean) exact hpair.atTop_div_const (neg_log_one_sub_pos hdelta)
    Causalean.Mathlib.Probability.Birthday.calibratedScale_tendsto_atTop · Causalean/Mathlib/Probability/Birthday/ThresholdScale.lean:26