The proof
Erdős problem 18 - b
**Conjecture 2.** Is it true that ? That is, for all , is for sufficiently large ?Source
Main.lean · 14043 lines · 735.7 kB
open Finset Filter
theorem exact_target_type :
(fcTypeOfName% "Erdos18.erdos_18b") =
(True ↔ ∀ ε : ℝ, 0 < ε → ∀ᶠ n : ℕ in Filter.atTop,
(Erdos18.practicalH n.factorial : ℝ) < (n : ℝ) ^ ε) := by
rfl
def HasShortDivisorSum (N R k : ℕ) : Prop :=
∃ D : Finset ℕ, D ⊆ N.divisors ∧ D.sum id = R ∧ D.card ≤ k
theorem short_sum_zero (N k : ℕ) : HasShortDivisorSum N 0 k := by
refine ⟨∅, ?_, ?_, ?_⟩ <;> simp
theorem short_sum_mono_count {N R k l : ℕ}
(h : HasShortDivisorSum N R k) (hkl : k ≤ l) :
HasShortDivisorSum N R l := by
obtain ⟨D, hD, hsum, hcard⟩ := h
exact ⟨D, hD, hsum, hcard.trans hkl⟩
theorem short_sum_mono_host {N M R k : ℕ}
(hNM : N ∣ M) (hM : M ≠ 0) (h : HasShortDivisorSum N R k) :
HasShortDivisorSum M R k := by
obtain ⟨D, hD, hsum, hcard⟩ := h
exact ⟨D, hD.trans (Nat.divisors_subset_of_dvd hM hNM), hsum, hcard⟩
theorem practicalH_le_of_short_sums (N k : ℕ)
(h : ∀ R ∈ Finset.Icc 1 N, HasShortDivisorSum N R k) :
Erdos18.practicalH N ≤ k := by
classical
unfold Erdos18.practicalH
apply Finset.sup_le
intro R hR
obtain ⟨D, hD, hsum, hcard⟩ := h R hR
apply le_trans ?_ hcard
apply Nat.sInf_le
exact ⟨D, hD, rfl, D, Set.Subset.rfl, hsum.symm⟩
theorem short_sum_of_practicalH {N R : ℕ}
(hN : Nat.IsPractical N) (hR : R ≤ N) :
HasShortDivisorSum N R (Erdos18.practicalH N) := by
classical
by_cases hzero : R = 0
· subst R
exact short_sum_zero _ _
have hRmem : R ∈ Finset.Icc 1 N := Finset.mem_Icc.mpr ⟨by omega, hR⟩
have hne : {k | ∃ D : Finset ℕ,
D ⊆ N.divisors ∧ D.card = k ∧ R ∈ subsetSums D}.Nonempty :=
⟨N.divisors.card, N.divisors, Finset.Subset.refl _, rfl, hN R hR⟩
obtain ⟨D, hD, hcard, E, hED, hsum⟩ := Nat.sInf_mem hne
have hsub : E ⊆ D := Finset.coe_subset.mp hED
refine ⟨E, hsub.trans hD, hsum.symm, ?_⟩
calc
E.card ≤ D.card := Finset.card_le_card hsub
_ = sInf {k | ∃ D : Finset ℕ,
D ⊆ N.divisors ∧ D.card = k ∧ R ∈ subsetSums D} := hcard
_ ≤ Erdos18.practicalH N := by
exact Finset.le_sup (f := fun m => sInf {k | ∃ D : Finset ℕ,
D ⊆ N.divisors ∧ D.card = k ∧ m ∈ subsetSums D}) hRmem
theorem short_sum_radix {M q a r k l : ℕ}
(hM : 0 < M) (hq : 0 < q) (hrq : r < q)
(ha : HasShortDivisorSum M a k)
(hr : HasShortDivisorSum (q * M) r l) :
HasShortDivisorSum (q * M) (q * a + r) (k + l) := by
classical
obtain ⟨A, hA, hAsum, hAcard⟩ := ha
obtain ⟨B, hB, hBsum, hBcard⟩ := hr
have hinj : Function.Injective (fun d : ℕ => q * d) :=
fun _ _ h => mul_left_cancel₀ (ne_of_gt hq) h
have hdisj : Disjoint (A.image (fun d => q * d)) B := by
apply Finset.disjoint_left.mpr
intro x hx hxB
obtain ⟨d, hd, rfl⟩ := Finset.mem_image.mp hx
have hdpos : 0 < d := Nat.pos_of_dvd_of_pos
(Nat.dvd_of_mem_divisors (hA hd)) hM
have hlow : q ≤ q * d := by nlinarith
have hhigh : q * d ≤ r := by
rw [← hBsum]
exact Finset.single_le_sum (f := id) (fun _ _ => Nat.zero_le _) hxB
omega
refine ⟨A.image (fun d => q * d) ∪ B, ?_, ?_, ?_⟩
· intro x hx
rcases Finset.mem_union.mp hx with hx | hx
· obtain ⟨d, hd, rfl⟩ := Finset.mem_image.mp hx
exact Nat.mem_divisors.mpr
⟨mul_dvd_mul_left q (Nat.dvd_of_mem_divisors (hA hd)),
ne_of_gt (Nat.mul_pos hq hM)⟩
· exact hB hx
· rw [Finset.sum_union hdisj, Finset.sum_image
(fun x _ y _ h => hinj h)]
change (∑ x ∈ A, q * x) + B.sum id = q * a + r
rw [← Finset.mul_sum, show (∑ x ∈ A, x) = a from hAsum, hBsum]
· rw [Finset.card_union_of_disjoint hdisj,
Finset.card_image_of_injective A hinj]
omega
theorem practicalH_radix {M q l : ℕ}
(hM : Nat.IsPractical M) (hMpos : 0 < M) (hq : 0 < q)
(hlocal : ∀ r < q, HasShortDivisorSum (q * M) r l) :
Erdos18.practicalH (q * M) ≤ Erdos18.practicalH M + l := by
apply practicalH_le_of_short_sums
intro R hR
have hquot : R / q ≤ M :=
Nat.div_le_of_le_mul (Finset.mem_Icc.mp hR).2
have hrep := short_sum_radix hMpos hq (Nat.mod_lt R hq)
(short_sum_of_practicalH hM hquot) (hlocal (R % q) (Nat.mod_lt R hq))
simpa only [Nat.div_add_mod] using hrep
theorem factorial_radix_recurrence {n m l : ℕ} (hmn : m ≤ n)
(hlocal : ∀ r < n.factorial / m.factorial,
HasShortDivisorSum n.factorial r l) :
Erdos18.practicalH n.factorial ≤ Erdos18.practicalH m.factorial + l := by
have hdiv : m.factorial ∣ n.factorial := Nat.factorial_dvd_factorial hmn
have heq : n.factorial / m.factorial * m.factorial = n.factorial :=
Nat.div_mul_cancel hdiv
have hq : 0 < n.factorial / m.factorial :=
Nat.div_pos (Nat.le_of_dvd (Nat.factorial_pos n) hdiv) (Nat.factorial_pos m)
have h := practicalH_radix (Erdos18.factorial_isPractical m)
(Nat.factorial_pos m) hq (by simpa only [heq] using hlocal)
simpa only [heq] using h
theorem positive_quotient_of_dvd {R S q : ℕ}
(hq : 0 < q) (hSR : S < R) (hdvd : q ∣ R - S) :
∃ t : ℕ, 0 < t ∧ R = S + q * t ∧ t ≤ R / q := by
refine ⟨(R - S) / q, ?_, ?_, ?_⟩
· exact Nat.div_pos (Nat.le_of_dvd (Nat.sub_pos_of_lt hSR) hdvd) hq
· rw [Nat.mul_div_cancel' hdvd]
exact (Nat.add_sub_of_le hSR.le).symm
· exact Nat.div_le_div_right (Nat.sub_le R S)
theorem polynomial_height_below_target {R S q D : ℕ}
(hq : 2 ≤ q) (hR : q ^ (D + 1) ≤ R) (hS : S ≤ q ^ D) :
S < R ∧ 2 * S ≤ R := by
have hpow : 0 < q ^ D := pow_pos (by omega) D
rw [pow_succ] at hR
constructor <;> nlinarith
theorem positive_lifting_of_polynomial_height {R S q D : ℕ}
(hq : 2 ≤ q) (hR : q ^ (D + 1) ≤ R) (hS : S ≤ q ^ D)
(hdvd : q ∣ R - S) :
∃ t : ℕ, 0 < t ∧ R = S + q * t ∧ t ≤ R / q := by
exact positive_quotient_of_dvd (by omega)
(polynomial_height_below_target hq hR hS).1 hdvd
theorem positive_lifting_of_congruence {R S q D : ℕ}
(hq : 2 ≤ q) (hR : q ^ (D + 1) ≤ R) (hS : S ≤ q ^ D)
(hmod : Nat.ModEq q S R) :
∃ t : ℕ, 0 < t ∧ R = S + q * t ∧ t ≤ R / q := by
exact positive_lifting_of_polynomial_height hq hR hS hmod.dvd'
theorem factorial_power_dvd (m r : ℕ) :
m.factorial ^ r ∣ (r * m).factorial := by
simpa using Nat.prod_factorial_dvd_factorial_sum (Finset.range r) (fun _ => m)
theorem factorial_binary_reserve (m k : ℕ) :
2 ^ k * m.factorial ∣ (m + 2 * k).factorial := by
have hpow : 2 ^ k ∣ (2 * k).factorial := by
simpa [Nat.factorial, Nat.mul_comm] using factorial_power_dvd 2 k
exact (mul_dvd_mul hpow (dvd_refl m.factorial)).trans
(by simpa [Nat.add_comm] using
Nat.factorial_mul_factorial_dvd_factorial_add (2 * k) m)
theorem shifted_divisor_dvd_factorial {m k b d : ℕ}
(hd : d ∣ m.factorial) (hb : b ≤ k) :
2 ^ b * d ∣ (m + 2 * k).factorial := by
exact (mul_dvd_mul (pow_dvd_pow 2 hb) hd).trans (factorial_binary_reserve m k)
theorem product_divisors_dvd_factorial_sum {ι : Type*}
(I : Finset ι) (d a : ι → ℕ)
(h : ∀ i ∈ I, d i ∣ (a i).factorial) :
(∏ i ∈ I, d i) ∣ (∑ i ∈ I, a i).factorial := by
exact (Finset.prod_dvd_prod_of_dvd d (fun i => (a i).factorial) h).trans
(Nat.prod_factorial_dvd_factorial_sum I a)
theorem distinctify_divisor_multiset (s : Multiset ℕ) {N : ℕ}
(hN : N ≠ 0) (hs : ∀ d ∈ s, d ∣ N) :
HasShortDivisorSum (2 ^ s.card * N) s.sum s.card := by
classical
have aux : ∀ k : ℕ, ∀ t : Multiset ℕ, t.card = k →
∀ M : ℕ, M ≠ 0 → (∀ d ∈ t, d ∣ M) →
HasShortDivisorSum (2 ^ k * M) t.sum k := by
intro k
induction k using Nat.strong_induction_on with
| h k ih =>
intro t hk M hM ht
by_cases hn : t.Nodup
· refine ⟨t.toFinset, ?_, ?_, ?_⟩
· intro d hd
exact Nat.mem_divisors.mpr
⟨dvd_mul_of_dvd_right (ht d (Multiset.mem_toFinset.mp hd)) (2 ^ k),
mul_ne_zero (pow_ne_zero _ (by decide)) hM⟩
· change (t.toFinset.val.map id).sum = t.sum
simp [hn.dedup]
· exact le_of_eq ((Multiset.toFinset_card_of_nodup hn).trans hk)
· rw [Multiset.nodup_iff_ne_cons_cons] at hn
push Not at hn
obtain ⟨a, u, rfl⟩ := hn
have hc : (2 * a ::ₘ u).card < k := by
simp only [Multiset.card_cons] at hk ⊢
omega
have hnew : ∀ d ∈ (2 * a ::ₘ u), d ∣ 2 * M := by
intro d hd
rcases Multiset.mem_cons.mp hd with rfl | hd
· exact mul_dvd_mul_left 2 (ht a (by simp))
· exact dvd_mul_of_dvd_right (ht d (by simp [hd])) 2
have hrep := ih _ hc (2 * a ::ₘ u) rfl (2 * M)
(mul_ne_zero (by decide) hM) hnew
have hhost : 2 ^ (2 * a ::ₘ u).card * (2 * M) = 2 ^ k * M := by
rw [← hk]
simp only [Multiset.card_cons, pow_succ]
ring
have hsum : (2 * a ::ₘ u).sum = (a ::ₘ a ::ₘ u).sum := by
simp [two_mul, add_assoc]
have hrep' := short_sum_mono_count hrep hc.le
simpa only [hhost, hsum] using hrep'
exact aux s.card s rfl N hN hs
theorem distinctify_factorial_divisors (s : Multiset ℕ) (F : ℕ)
(hs : ∀ d ∈ s, d ∣ F.factorial) :
HasShortDivisorSum (F + 2 * s.card).factorial s.sum s.card := by
exact short_sum_mono_host (factorial_binary_reserve F s.card)
(Nat.factorial_ne_zero _) (distinctify_divisor_multiset s (Nat.factorial_ne_zero F) hs)
def HasFactorialDivisorMultiset (F R u : ℕ) : Prop :=
∃ s : Multiset ℕ, (∀ d ∈ s, d ∣ F.factorial) ∧ s.sum = R ∧ s.card ≤ u
theorem factorial_multiset_zero (F u : ℕ) : HasFactorialDivisorMultiset F 0 u := by
exact ⟨0, by simp, by simp, by simp⟩
theorem factorial_multiset_singleton {F R : ℕ} (hR : R ∣ F.factorial) :
HasFactorialDivisorMultiset F R 1 := by
exact ⟨{R}, by simpa using hR, by simp, by simp⟩
theorem factorial_multiset_mono {F G R u v : ℕ}
(h : HasFactorialDivisorMultiset F R u) (hFG : F ≤ G) (huv : u ≤ v) :
HasFactorialDivisorMultiset G R v := by
obtain ⟨s, hs, hsum, hcard⟩ := h
exact ⟨s, fun d hd => (hs d hd).trans (Nat.factorial_dvd_factorial hFG),
hsum, hcard.trans huv⟩
theorem factorial_multiset_to_distinct {F R u : ℕ}
(h : HasFactorialDivisorMultiset F R u) :
HasShortDivisorSum (F + 2 * u).factorial R u := by
obtain ⟨s, hs, hsum, hcard⟩ := h
have hrep := distinctify_factorial_divisors s F hs
rw [hsum] at hrep
exact short_sum_mono_count
(short_sum_mono_host (Nat.factorial_dvd_factorial (by omega))
(Nat.factorial_ne_zero (F + 2 * u)) hrep) hcard
theorem factorial_multiset_add {F R S u v : ℕ}
(hR : HasFactorialDivisorMultiset F R u)
(hS : HasFactorialDivisorMultiset F S v) :
HasFactorialDivisorMultiset F (R + S) (u + v) := by
obtain ⟨s, hs, hsum, hcard⟩ := hR
obtain ⟨t, ht, htsum, htcard⟩ := hS
refine ⟨s + t, ?_, ?_, ?_⟩
· intro d hd
rcases Multiset.mem_add.mp hd with hd | hd
· exact hs d hd
· exact ht d hd
· simp only [Multiset.sum_add, hsum, htsum]
· simpa only [Multiset.card_add] using Nat.add_le_add hcard htcard
theorem factorial_multiset_scale {F G q R u : ℕ}
(hq : q ∣ F.factorial) (h : HasFactorialDivisorMultiset G R u) :
HasFactorialDivisorMultiset (F + G) (q * R) u := by
obtain ⟨s, hs, hsum, hcard⟩ := h
refine ⟨s.map (fun d => q * d), ?_, ?_, ?_⟩
· intro x hx
obtain ⟨d, hd, rfl⟩ := Multiset.mem_map.mp hx
exact (mul_dvd_mul hq (hs d hd)).trans
(Nat.factorial_mul_factorial_dvd_factorial_add F G)
· have hmul := Multiset.sum_map_mul_left (s := s) (a := q) (f := id)
simpa [hsum] using hmul
· simpa only [Multiset.card_map] using hcard
theorem multiset_sum_expansion (s t : Multiset ℕ) :
((s ×ˢ t).map (fun p => p.1 * p.2)).sum = s.sum * t.sum := by
refine Multiset.induction_on s (by simp) fun a s ih => ?_
have hmul := Multiset.sum_map_mul_left (s := t) (a := a) (f := id)
simp only [Multiset.cons_product, Multiset.map_add, Multiset.map_map,
Multiset.sum_add, Multiset.sum_cons, ih]
simpa [Function.comp_def, add_mul] using congrArg (fun x => x + s.sum * t.sum) hmul
theorem factorial_multiset_mul {F G R S u v : ℕ}
(hR : HasFactorialDivisorMultiset F R u)
(hS : HasFactorialDivisorMultiset G S v) :
HasFactorialDivisorMultiset (F + G) (R * S) (u * v) := by
obtain ⟨s, hs, hsum, hcard⟩ := hR
obtain ⟨t, ht, htsum, htcard⟩ := hS
refine ⟨(s ×ˢ t).map (fun p => p.1 * p.2), ?_, ?_, ?_⟩
· intro d hd
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Multiset.mem_map.mp hd
obtain ⟨ha, hb⟩ := Multiset.mem_product.mp hab
exact (mul_dvd_mul (hs a ha) (ht b hb)).trans
(Nat.factorial_mul_factorial_dvd_factorial_add F G)
· simp only [multiset_sum_expansion, hsum, htsum]
· simpa only [Multiset.card_map, Multiset.card_product] using
Nat.mul_le_mul hcard htcard
theorem factorial_multiset_lift {F G q R S T u v : ℕ}
(hq : q ∣ F.factorial) (hR : R = S + q * T)
(hS : HasFactorialDivisorMultiset F S u)
(hT : HasFactorialDivisorMultiset G T v) :
HasFactorialDivisorMultiset (F + G) R (u + v) := by
rw [hR]
exact factorial_multiset_add (factorial_multiset_mono hS (by omega) le_rfl)
(factorial_multiset_scale hq hT)
def HasBoundedModularRepresentatives (q F u D : ℕ) : Prop :=
∀ R : ℕ, ∃ S : ℕ, S ≤ q ^ D ∧ Nat.ModEq q S R ∧
HasFactorialDivisorMultiset F S u
theorem positive_modular_lifting_step {q F G u v D R : ℕ}
(hq : 2 ≤ q) (hdiv : q ∣ F.factorial) (hR : q ^ (D + 1) ≤ R)
(hmod : HasBoundedModularRepresentatives q F u D)
(hchild : ∀ T : ℕ, 0 < T → T ≤ R / q → HasFactorialDivisorMultiset G T v) :
HasFactorialDivisorMultiset (F + G) R (u + v) := by
obtain ⟨S, hS, hcongr, hrep⟩ := hmod R
obtain ⟨T, hTpos, hidentity, hTbound⟩ :=
positive_lifting_of_congruence hq hR hS hcongr
exact factorial_multiset_lift hdiv hidentity hrep (hchild T hTpos hTbound)
theorem positive_modular_lifting_step_distinct {q F G u v D R : ℕ}
(hq : 2 ≤ q) (hdiv : q ∣ F.factorial) (hR : q ^ (D + 1) ≤ R)
(hmod : HasBoundedModularRepresentatives q F u D)
(hchild : ∀ T : ℕ, 0 < T → T ≤ R / q → HasFactorialDivisorMultiset G T v) :
HasShortDivisorSum (F + G + 2 * (u + v)).factorial R (u + v) := by
exact factorial_multiset_to_distinct
(positive_modular_lifting_step hq hdiv hR hmod hchild)
theorem recursive_modular_lifting
(indexBudget countBudget : ℕ → ℕ) (threshold : ℕ)
(hbase : ∀ R < threshold,
HasFactorialDivisorMultiset (indexBudget R) R (countBudget R))
(hstep : ∀ R, threshold ≤ R → ∃ q F u D : ℕ,
2 ≤ q ∧ q ∣ F.factorial ∧ q ^ (D + 1) ≤ R ∧
HasBoundedModularRepresentatives q F u D ∧
∀ T : ℕ, 0 < T → T ≤ R / q →
F + indexBudget T ≤ indexBudget R ∧
u + countBudget T ≤ countBudget R) :
∀ R : ℕ, HasFactorialDivisorMultiset (indexBudget R) R (countBudget R) := by
intro R
induction R using Nat.strong_induction_on with
| h R ih =>
by_cases hsmall : R < threshold
· exact hbase R hsmall
obtain ⟨q, F, u, D, hq, hdiv, hheight, hmod, hbudget⟩ :=
hstep R (by omega)
obtain ⟨S, hS, hcongr, hrep⟩ := hmod R
obtain ⟨T, hTpos, hidentity, hTbound⟩ :=
positive_lifting_of_congruence hq hheight hS hcongr
have hRpos : 0 < R := lt_of_lt_of_le (pow_pos (by omega) _) hheight
have hTlt : T < R := hTbound.trans_lt (Nat.div_lt_self hRpos (by omega))
have hchild := ih T hTlt
obtain ⟨hF, hu⟩ := hbudget T hTpos hTbound
exact factorial_multiset_mono
(factorial_multiset_lift hdiv hidentity hrep hchild) hF hu
theorem bounded_recursive_modular_lifting
(φ ψ : ℕ → ℝ) (threshold : ℕ) (C E A B ρ σ : ℝ)
(hφ : ∀ R : ℕ, 0 < R → 1 ≤ φ R)
(hψ : ∀ R : ℕ, 0 < R → 1 ≤ ψ R)
(hC : (threshold : ℝ) ≤ C) (hCpos : 0 ≤ C)
(hE : 1 ≤ E)
(hindex : A + C * ρ ≤ C) (hcount : B + E * σ ≤ E)
(hstep : ∀ R : ℕ, 0 < R → threshold ≤ R → ∃ q F u D : ℕ,
2 ≤ q ∧ q ∣ F.factorial ∧ q ^ (D + 1) ≤ R ∧
HasBoundedModularRepresentatives q F u D ∧
(F : ℝ) ≤ A * φ R ∧ (u : ℝ) ≤ B * ψ R ∧
∀ T : ℕ, 0 < T → T ≤ R / q →
φ T ≤ ρ * φ R ∧ ψ T ≤ σ * ψ R) :
∀ R : ℕ, 0 < R → ∃ F u : ℕ,
HasFactorialDivisorMultiset F R u ∧
(F : ℝ) ≤ C * φ R ∧ (u : ℝ) ≤ E * ψ R := by
have hEpos : 0 ≤ E := by linarith
intro R
induction R using Nat.strong_induction_on with
| h R ih =>
intro hRpos
by_cases hsmall : R < threshold
· refine ⟨R, 1, factorial_multiset_singleton (Nat.dvd_factorial hRpos le_rfl), ?_, ?_⟩
· have hRle : (R : ℝ) ≤ threshold := by exact_mod_cast hsmall.le
have hprod : C ≤ C * φ R := by nlinarith [hφ R hRpos]
exact hRle.trans (hC.trans hprod)
· have hprod : E ≤ E * ψ R := by nlinarith [hψ R hRpos]
simpa only [Nat.cast_one] using hE.trans hprod
obtain ⟨q, F, u, D, hq, hdiv, hheight, hmod, hF, hu, hshrink⟩ :=
hstep R hRpos (by omega)
obtain ⟨S, hS, hcongr, hrep⟩ := hmod R
obtain ⟨T, hTpos, hidentity, hTbound⟩ :=
positive_lifting_of_congruence hq hheight hS hcongr
have hTlt : T < R := hTbound.trans_lt (Nat.div_lt_self hRpos (by omega))
obtain ⟨G, v, hchild, hG, hv⟩ := ih T hTlt hTpos
obtain ⟨hφT, hψT⟩ := hshrink T hTpos hTbound
refine ⟨F + G, u + v, factorial_multiset_lift hdiv hidentity hrep hchild, ?_, ?_⟩
· calc
((F + G : ℕ) : ℝ) = (F : ℝ) + G := Nat.cast_add _ _
_ ≤ A * φ R + C * φ T := add_le_add hF hG
_ ≤ A * φ R + C * (ρ * φ R) := by gcongr
_ = (A + C * ρ) * φ R := by ring
_ ≤ C * φ R := mul_le_mul_of_nonneg_right hindex (by linarith [hφ R hRpos])
· calc
((u + v : ℕ) : ℝ) = (u : ℝ) + v := Nat.cast_add _ _
_ ≤ B * ψ R + E * ψ T := add_le_add hu hv
_ ≤ B * ψ R + E * (σ * ψ R) := by gcongr
_ = (B + E * σ) * ψ R := by ring
_ ≤ E * ψ R := mul_le_mul_of_nonneg_right hcount (by linarith [hψ R hRpos])
def binaryLength (R : ℕ) : ℕ := Nat.log 2 R + 1
def liftingBits (R D : ℕ) : ℕ := Nat.log 2 R / (D + 1)
theorem binaryLength_pos (R : ℕ) : 0 < binaryLength R := by
simp [binaryLength]
theorem lifting_modulus_height {R D : ℕ} (hR : 0 < R) :
(2 ^ liftingBits R D) ^ (D + 1) ≤ R := by
unfold liftingBits
rw [← pow_mul]
exact (Nat.pow_le_pow_right (by decide : 0 < 2)
(Nat.div_mul_le_self (Nat.log 2 R) (D + 1))).trans
(Nat.pow_log_le_self 2 hR.ne')
theorem liftingBits_pos {R D : ℕ} (hR : D + 1 ≤ Nat.log 2 R) :
0 < liftingBits R D := by
exact Nat.div_pos hR (by omega)
theorem lifting_modulus_ge_two {R D : ℕ} (hR : D + 1 ≤ Nat.log 2 R) :
2 ≤ 2 ^ liftingBits R D := by
simpa using Nat.pow_le_pow_right (by decide : 0 < 2) (liftingBits_pos hR)
theorem liftingBits_le_binaryLength (R D : ℕ) :
liftingBits R D ≤ binaryLength R := by
exact (Nat.div_le_self _ _).trans (Nat.le_succ _)
noncomputable def liftingRatio (D : ℕ) : ℝ := 1 - 1 / (2 * ((D : ℝ) + 1))
theorem liftingRatio_pos (D : ℕ) : 0 < liftingRatio D := by
have hD : (0 : ℝ) ≤ D := Nat.cast_nonneg D
unfold liftingRatio
have : 1 / (2 * ((D : ℝ) + 1)) < 1 :=
(div_lt_one (by positivity)).mpr (by linarith)
linarith
theorem liftingRatio_lt_one (D : ℕ) : liftingRatio D < 1 := by
unfold liftingRatio
have : 0 < 1 / (2 * ((D : ℝ) + 1)) := by positivity
linarith
theorem binaryLength_quotient_shrink {R T D : ℕ}
(hR : D + 1 ≤ Nat.log 2 R) (hT : T ≤ R / 2 ^ liftingBits R D) :
(binaryLength T : ℝ) ≤ liftingRatio D * (binaryLength R : ℝ) := by
have hkpos : 0 < liftingBits R D := liftingBits_pos hR
have hk : liftingBits R D ≤ Nat.log 2 R := Nat.div_le_self _ _
have hlog : Nat.log 2 T ≤ Nat.log 2 R - liftingBits R D := by
calc
Nat.log 2 T ≤ Nat.log 2 (R / 2 ^ liftingBits R D) := Nat.log_mono_right hT
_ = Nat.log 2 R - liftingBits R D := Nat.log_div_base_pow 2 R _
have hsplit : Nat.log 2 T + liftingBits R D ≤ Nat.log 2 R := by omega
have hdiv : Nat.log 2 R < (D + 1) * (liftingBits R D + 1) :=
Nat.lt_mul_div_succ _ (by omega)
have hgap : binaryLength R ≤ 2 * (D + 1) * liftingBits R D := by
unfold binaryLength
nlinarith
have hsplitR : (binaryLength T : ℝ) + (liftingBits R D : ℝ) ≤ binaryLength R := by
exact_mod_cast (show binaryLength T + liftingBits R D ≤ binaryLength R by
unfold binaryLength
omega)
have hgapR : (binaryLength R : ℝ) ≤
(2 * ((D : ℝ) + 1)) * (liftingBits R D : ℝ) := by exact_mod_cast hgap
have hden : (0 : ℝ) < 2 * ((D : ℝ) + 1) := by positivity
have hquot : (binaryLength R : ℝ) / (2 * ((D : ℝ) + 1)) ≤ liftingBits R D :=
(div_le_iff₀ hden).mpr (by nlinarith [hgapR])
unfold liftingRatio
have hid : (1 - 1 / (2 * ((D : ℝ) + 1))) * (binaryLength R : ℝ) =
(binaryLength R : ℝ) - (binaryLength R : ℝ) / (2 * ((D : ℝ) + 1)) := by ring
rw [hid]
linarith
theorem binaryLength_rpow_quotient_shrink {R T D : ℕ} {a : ℝ}
(ha : 0 ≤ a) (hR : D + 1 ≤ Nat.log 2 R)
(hT : T ≤ R / 2 ^ liftingBits R D) :
(binaryLength T : ℝ) ^ a ≤ liftingRatio D ^ a * (binaryLength R : ℝ) ^ a := by
have h := Real.rpow_le_rpow (Nat.cast_nonneg (binaryLength T))
(binaryLength_quotient_shrink hR hT) ha
simpa only [Real.mul_rpow (liftingRatio_pos D).le (Nat.cast_nonneg _)] using h
def DyadicModularBounds (a b : ℝ) : Prop :=
∃ D k₀ : ℕ, ∃ A B : ℝ, 0 < A ∧ 0 < B ∧
∀ k : ℕ, k₀ ≤ k → ∃ F u : ℕ,
2 ^ k ∣ F.factorial ∧ HasBoundedModularRepresentatives (2 ^ k) F u D ∧
(F : ℝ) ≤ A * (k : ℝ) ^ a ∧ (u : ℝ) ≤ B * (k : ℝ) ^ b
theorem dyadic_modular_bounds_give_local_multisets {a b : ℝ}
(ha : 0 < a) (hb : 0 < b) (h : DyadicModularBounds a b) :
∃ C E : ℝ, 0 < C ∧ 0 < E ∧ ∀ R : ℕ, 0 < R → ∃ F u : ℕ,
HasFactorialDivisorMultiset F R u ∧
(F : ℝ) ≤ C * (binaryLength R : ℝ) ^ a ∧
(u : ℝ) ≤ E * (binaryLength R : ℝ) ^ b := by
obtain ⟨D, k₀, A, B, hA, hB, hmod⟩ := h
let threshold : ℕ := 2 ^ ((D + 1) * (k₀ + 1))
let ρ : ℝ := liftingRatio D ^ a
let σ : ℝ := liftingRatio D ^ b
have hρ : ρ < 1 := Real.rpow_lt_one (liftingRatio_pos D).le (liftingRatio_lt_one D) ha
have hσ : σ < 1 := Real.rpow_lt_one (liftingRatio_pos D).le (liftingRatio_lt_one D) hb
let C : ℝ := max (threshold : ℝ) (A / (1 - ρ))
let E : ℝ := max 1 (B / (1 - σ))
have hC : (threshold : ℝ) ≤ C := le_max_left _ _
have hE : 1 ≤ E := le_max_left _ _
have hCA : A / (1 - ρ) ≤ C := le_max_right _ _
have hEB : B / (1 - σ) ≤ E := le_max_right _ _
have hCpos : 0 < C := (div_pos hA (by linarith)).trans_le hCA
have hEpos : 0 < E := lt_of_lt_of_le zero_lt_one hE
have hindex : A + C * ρ ≤ C := by
have := (div_le_iff₀ (by linarith : 0 < 1 - ρ)).mp hCA
nlinarith
have hcount : B + E * σ ≤ E := by
have := (div_le_iff₀ (by linarith : 0 < 1 - σ)).mp hEB
nlinarith
refine ⟨C, E, hCpos, hEpos, ?_⟩
refine bounded_recursive_modular_lifting
(fun R => (binaryLength R : ℝ) ^ a) (fun R => (binaryLength R : ℝ) ^ b)
threshold C E A B ρ σ
(fun R _ => Real.one_le_rpow (by exact_mod_cast binaryLength_pos R) ha.le)
(fun R _ => Real.one_le_rpow (by exact_mod_cast binaryLength_pos R) hb.le)
hC hCpos.le hE hindex hcount ?_
intro R hR hlarge
have hlog : (D + 1) * (k₀ + 1) ≤ Nat.log 2 R :=
(Nat.le_log_iff_pow_le (by decide : 1 < 2) hR.ne').mpr hlarge
have hD : D + 1 ≤ Nat.log 2 R := by nlinarith
have hk₀ : k₀ ≤ liftingBits R D := by
apply (Nat.le_div_iff_mul_le (by omega : 0 < D + 1)).mpr
nlinarith
obtain ⟨F, u, hdiv, hrep, hF, hu⟩ := hmod (liftingBits R D) hk₀
refine ⟨2 ^ liftingBits R D, F, u, D, lifting_modulus_ge_two hD, hdiv,
lifting_modulus_height hR, hrep, ?_, ?_, ?_⟩
· exact hF.trans (mul_le_mul_of_nonneg_left
(Real.rpow_le_rpow (Nat.cast_nonneg _) (by exact_mod_cast liftingBits_le_binaryLength R D)
ha.le) hA.le)
· exact hu.trans (mul_le_mul_of_nonneg_left
(Real.rpow_le_rpow (Nat.cast_nonneg _) (by exact_mod_cast liftingBits_le_binaryLength R D)
hb.le) hB.le)
· intro T _ hT
exact ⟨binaryLength_rpow_quotient_shrink ha.le hD hT,
binaryLength_rpow_quotient_shrink hb.le hD hT⟩
def LocalFactorialBounds (a b : ℝ) : Prop :=
∃ C : ℝ, 0 < C ∧ ∀ R : ℕ, 0 < R → ∃ F u : ℕ,
HasShortDivisorSum F.factorial R u ∧
(F : ℝ) ≤ C * (binaryLength R : ℝ) ^ a ∧
(u : ℝ) ≤ C * (binaryLength R : ℝ) ^ b
theorem dyadic_modular_bounds_give_local_bounds {a b : ℝ}
(ha : 0 < a) (hb : 0 < b) (hba : b ≤ a) (h : DyadicModularBounds a b) :
LocalFactorialBounds a b := by
obtain ⟨C, E, hC, hE, hlocal⟩ := dyadic_modular_bounds_give_local_multisets ha hb h
refine ⟨C + 2 * E, by linarith, ?_⟩
intro R hR
obtain ⟨F, u, hrep, hF, hu⟩ := hlocal R hR
refine ⟨F + 2 * u, u, factorial_multiset_to_distinct hrep, ?_, ?_⟩
· have hpow : (binaryLength R : ℝ) ^ b ≤ (binaryLength R : ℝ) ^ a :=
Real.rpow_le_rpow_of_exponent_le (by exact_mod_cast binaryLength_pos R) hba
have htwice := mul_le_mul_of_nonneg_left hpow (by linarith : 0 ≤ 2 * E)
push_cast
nlinarith
· have hpow : 0 ≤ (binaryLength R : ℝ) ^ b := Real.rpow_nonneg (by positivity) _
nlinarith
theorem binaryLength_mono {R S : ℕ} (h : R ≤ S) : binaryLength R ≤ binaryLength S := by
exact Nat.add_le_add_right (Nat.log_mono_right h) 1
theorem local_bounds_uniform_remainders {a b C : ℝ} {n Q : ℕ}
(ha : 0 ≤ a) (hb : 0 ≤ b) (hC : 0 ≤ C)
(hlocal : ∀ R : ℕ, 0 < R → ∃ F u : ℕ,
HasShortDivisorSum F.factorial R u ∧
(F : ℝ) ≤ C * (binaryLength R : ℝ) ^ a ∧
(u : ℝ) ≤ C * (binaryLength R : ℝ) ^ b)
(hhost : C * (binaryLength Q : ℝ) ^ a ≤ n) :
∀ R < Q, HasShortDivisorSum n.factorial R ⌊C * (binaryLength Q : ℝ) ^ b⌋₊ := by
intro R hRQ
by_cases hzero : R = 0
· subst R
exact short_sum_zero _ _
obtain ⟨F, u, hrep, hF, hu⟩ := hlocal R (by omega)
have hlen : (binaryLength R : ℝ) ≤ binaryLength Q := by
exact_mod_cast binaryLength_mono hRQ.le
have hF' : (F : ℝ) ≤ n := hF.trans
((mul_le_mul_of_nonneg_left (Real.rpow_le_rpow (Nat.cast_nonneg _) hlen ha) hC).trans hhost)
have hu' : (u : ℝ) ≤ C * (binaryLength Q : ℝ) ^ b := hu.trans
(mul_le_mul_of_nonneg_left (Real.rpow_le_rpow (Nat.cast_nonneg _) hlen hb) hC)
exact short_sum_mono_count
(short_sum_mono_host (Nat.factorial_dvd_factorial (by exact_mod_cast hF'))
(Nat.factorial_ne_zero n) hrep) (Nat.le_floor hu')
theorem local_bounds_radix_recurrence {a b C : ℝ} {n m : ℕ}
(ha : 0 ≤ a) (hb : 0 ≤ b) (hC : 0 ≤ C) (hmn : m ≤ n)
(hlocal : ∀ R : ℕ, 0 < R → ∃ F u : ℕ,
HasShortDivisorSum F.factorial R u ∧
(F : ℝ) ≤ C * (binaryLength R : ℝ) ^ a ∧
(u : ℝ) ≤ C * (binaryLength R : ℝ) ^ b)
(hhost : C * (binaryLength (n.factorial / m.factorial) : ℝ) ^ a ≤ n) :
Erdos18.practicalH n.factorial ≤ Erdos18.practicalH m.factorial +
⌊C * (binaryLength (n.factorial / m.factorial) : ℝ) ^ b⌋₊ := by
exact factorial_radix_recurrence hmn (local_bounds_uniform_remainders ha hb hC hlocal hhost)
theorem binaryLength_le_of_le_pow {R w : ℕ} (h : R ≤ 2 ^ w) :
binaryLength R ≤ w + 1 := by
have hlog := Nat.log_mono_right h (b := 2)
rw [Nat.log_pow (by decide : 1 < 2)] at hlog
exact Nat.add_le_add_right hlog 1
theorem binaryLength_pow_le (n w : ℕ) : binaryLength (n ^ w) ≤ w * binaryLength n + 1 := by
apply binaryLength_le_of_le_pow
calc
n ^ w ≤ (2 ^ binaryLength n) ^ w :=
Nat.pow_le_pow_left (Nat.lt_pow_succ_log_self (by decide : 1 < 2) n).le w
_ = 2 ^ (w * binaryLength n) := by rw [← pow_mul, Nat.mul_comm]
theorem factorial_quotient_le_pow {n w : ℕ} (hw : w ≤ n) :
n.factorial / (n - w).factorial ≤ n ^ w := by
rw [← Nat.descFactorial_eq_div hw]
exact Nat.descFactorial_le_pow n w
theorem binaryLength_factorial_quotient_le {n w : ℕ} (hw : w ≤ n) :
binaryLength (n.factorial / (n - w).factorial) ≤ w * binaryLength n + 1 := by
exact (binaryLength_mono (factorial_quotient_le_pow hw)).trans (binaryLength_pow_le n w)
theorem rpow_difference_lower_bound {x y p : ℝ}
(hx : 0 < x) (hy : 0 ≤ y) (hp : 0 ≤ p) (hp1 : p ≤ 1) :
p * (x - y) * x ^ (p - 1) ≤ x ^ p - y ^ p := by
have hB := rpow_one_add_le_one_add_mul_self
(s := y / x - 1) (by have := div_nonneg hy hx.le; linarith) hp hp1
have hB' : y ^ p / x ^ p ≤ 1 + p * (y / x - 1) := by
simpa only [show 1 + (y / x - 1) = y / x by ring,
Real.div_rpow hy hx.le] using hB
have hpX : 0 < x ^ p := Real.rpow_pos_of_pos hx p
have hmul := (div_le_iff₀ hpX).mp hB'
have hid : (1 + p * (y / x - 1)) * x ^ p =
x ^ p - p * (x - y) * x ^ (p - 1) := by
rw [Real.rpow_sub hx, Real.rpow_one]
field_simp
ring
rw [hid] at hmul
linarith
theorem eventually_const_mul_rpow_le {a b C E : ℝ} (hab : a < b) (hE : 0 < E) :
∀ᶠ n : ℕ in Filter.atTop, C * (n : ℝ) ^ a ≤ E * (n : ℝ) ^ b := by
have h := (tendsto_rpow_atTop (sub_pos.mpr hab)).comp
(tendsto_natCast_atTop_atTop (R := ℝ))
filter_upwards [h.eventually_ge_atTop (C / E), eventually_ge_atTop (1 : ℕ)] with n hn hn1
have hnpos : (0 : ℝ) < n := by exact_mod_cast (show 0 < n by omega)
have hC : C ≤ E * (n : ℝ) ^ (b - a) := by
change C / E ≤ (n : ℝ) ^ (b - a) at hn
simpa only [mul_comm] using (div_le_iff₀ hE).mp hn
calc
C * (n : ℝ) ^ a ≤ (E * (n : ℝ) ^ (b - a)) * (n : ℝ) ^ a :=
mul_le_mul_of_nonneg_right hC (Real.rpow_nonneg (Nat.cast_nonneg n) a)
_ = E * (n : ℝ) ^ b := by
rw [mul_assoc, ← Real.rpow_add hnpos, sub_add_cancel]
theorem eventually_binaryLength_le_rpow {ε : ℝ} (hε : 0 < ε) :
∀ᶠ n : ℕ in Filter.atTop, (binaryLength n : ℝ) ≤ (n : ℝ) ^ ε := by
have hlog := ((isLittleO_log_rpow_atTop hε).const_mul_left (1 / Real.log 2)).comp_tendsto
(tendsto_natCast_atTop_atTop (R := ℝ))
have hconst := eventually_const_mul_rpow_le (C := 1) (E := 1 / 2) hε (by norm_num)
filter_upwards [hlog.def (by norm_num : (0 : ℝ) < 1 / 2), hconst] with n hn hc
have hl : (Nat.log 2 n : ℝ) ≤ (1 / Real.log 2) * Real.log (n : ℝ) := by
simpa only [Real.logb, Nat.cast_ofNat, div_eq_mul_inv, one_mul, mul_comm]
using Real.natLog_le_logb n 2
have hn' : (1 / Real.log 2) * Real.log (n : ℝ) ≤ (1 / 2) * (n : ℝ) ^ ε := by
have habs : |(1 / Real.log 2) * Real.log (n : ℝ)| ≤ (1 / 2) * (n : ℝ) ^ ε := by
simpa only [Function.comp_apply, Real.norm_eq_abs,
abs_of_nonneg (Real.rpow_nonneg (Nat.cast_nonneg n) ε)] using hn
exact (le_abs_self _).trans habs
have hc' : 1 ≤ (1 / 2) * (n : ℝ) ^ ε := by simpa using hc
change ((Nat.log 2 n + 1 : ℕ) : ℝ) ≤ (n : ℝ) ^ ε
rw [Nat.cast_add, Nat.cast_one]
calc
(Nat.log 2 n : ℝ) + 1 ≤ (1 / 2) * (n : ℝ) ^ ε + (1 / 2) * (n : ℝ) ^ ε :=
add_le_add (hl.trans hn') hc'
_ = (n : ℝ) ^ ε := by ring
noncomputable def radixWidth (n : ℕ) (θ : ℝ) : ℕ := ⌊(n : ℝ) ^ θ⌋₊
theorem eventually_radix_width_bounds {θ γ : ℝ}
(hθ : 0 < θ) (hθ1 : θ < 1) (hγ : 0 < γ) :
∀ᶠ n : ℕ in Filter.atTop,
0 < radixWidth n θ ∧ radixWidth n θ < n ∧
(n : ℝ) ^ θ / 2 ≤ (radixWidth n θ : ℝ) ∧
(binaryLength (n.factorial / (n - radixWidth n θ).factorial) : ℝ) ≤
2 * (n : ℝ) ^ (θ + γ) := by
have hlarge := ((tendsto_rpow_atTop hθ).comp
(tendsto_natCast_atTop_atTop (R := ℝ))).eventually_ge_atTop 2
have hsmall := eventually_const_mul_rpow_le (C := 1) (E := 1 / 2) hθ1 (by norm_num)
filter_upwards [hlarge, hsmall, eventually_binaryLength_le_rpow hγ,
eventually_ge_atTop (1 : ℕ)] with n hlarge hsmall hlen hn1
change (2 : ℝ) ≤ (n : ℝ) ^ θ at hlarge
have hnpos : (0 : ℝ) < n := by exact_mod_cast (show 0 < n by omega)
have hfloor : (radixWidth n θ : ℝ) ≤ (n : ℝ) ^ θ :=
Nat.floor_le (Real.rpow_nonneg (Nat.cast_nonneg n) θ)
have hfloorlt : (n : ℝ) ^ θ < (radixWidth n θ : ℝ) + 1 := Nat.lt_floor_add_one _
have hwpos : 0 < radixWidth n θ := by
apply Nat.le_floor
norm_num only [Nat.cast_succ, Nat.cast_zero, zero_add]
exact (by norm_num : (1 : ℝ) ≤ 2).trans hlarge
have hwlt : radixWidth n θ < n := by
have hsmall' : (n : ℝ) ^ θ ≤ (n : ℝ) / 2 := by
simpa [div_eq_mul_inv, mul_comm] using hsmall
exact_mod_cast hfloor.trans_lt (hsmall'.trans_lt (half_lt_self hnpos))
refine ⟨hwpos, hwlt, by linarith only [hlarge, hfloorlt], ?_⟩
have hlenQ : (binaryLength (n.factorial / (n - radixWidth n θ).factorial) : ℝ) ≤
(radixWidth n θ : ℝ) * (binaryLength n : ℝ) + 1 := by
exact_mod_cast binaryLength_factorial_quotient_le hwlt.le
have hprod := mul_le_mul hfloor hlen (Nat.cast_nonneg (binaryLength n))
(Real.rpow_nonneg (Nat.cast_nonneg n) θ)
have hpowone : 1 ≤ (n : ℝ) ^ (θ + γ) :=
Real.one_le_rpow (by exact_mod_cast hn1) (by linarith)
rw [← Real.rpow_add hnpos] at hprod
calc
(binaryLength (n.factorial / (n - radixWidth n θ).factorial) : ℝ) ≤
(radixWidth n θ : ℝ) * (binaryLength n : ℝ) + 1 := hlenQ
_ ≤ (n : ℝ) ^ (θ + γ) + 1 := add_le_add hprod (le_refl (1 : ℝ))
_ ≤ 2 * (n : ℝ) ^ (θ + γ) := by linarith only [hpowone]
theorem bounded_of_eventual_potential_decrease (f P : ℕ → ℝ)
(hP : ∀ n : ℕ, 0 ≤ P n)
(hstep : ∀ᶠ n : ℕ in Filter.atTop, ∃ m : ℕ, m < n ∧
f n ≤ f m + P n - P m) :
∃ K : ℝ, 0 ≤ K ∧ ∀ n : ℕ, f n ≤ K + P n := by
obtain ⟨N, hN⟩ := Filter.eventually_atTop.mp hstep
let K : ℝ := ∑ i ∈ Finset.range N, max 0 (f i)
refine ⟨K, Finset.sum_nonneg (fun _ _ => le_max_left _ _), ?_⟩
intro n
induction n using Nat.strong_induction_on with
| h n ih =>
by_cases hn : n < N
· have hf : f n ≤ K := (le_max_right 0 (f n)).trans
(Finset.single_le_sum (f := fun i => max 0 (f i))
(fun _ _ => le_max_left _ _) (Finset.mem_range.mpr hn))
linarith [hP n]
· obtain ⟨m, hmn, hfm⟩ := hN n (by omega)
linarith [ih m hmn]
theorem eventual_factorial_potential_decrease {a b p θ γ C : ℝ}
(ha : 0 ≤ a) (hb : 0 ≤ b) (hp : 0 < p) (hp1 : p ≤ 1)
(hθ : 0 < θ) (hθ1 : θ < 1) (hγ : 0 < γ) (hC : 0 ≤ C)
(hindex : (θ + γ) * a < 1) (hcount : (θ + γ) * b < θ + p - 1)
(hlocal : ∀ R : ℕ, 0 < R → ∃ F u : ℕ,
HasShortDivisorSum F.factorial R u ∧
(F : ℝ) ≤ C * (binaryLength R : ℝ) ^ a ∧
(u : ℝ) ≤ C * (binaryLength R : ℝ) ^ b) :
∀ᶠ n : ℕ in Filter.atTop, ∃ m : ℕ, m < n ∧
(Erdos18.practicalH n.factorial : ℝ) ≤
(Erdos18.practicalH m.factorial : ℝ) + (n : ℝ) ^ p - (m : ℝ) ^ p := by
have hhost := eventually_const_mul_rpow_le (C := C * (2 : ℝ) ^ a) (E := 1)
hindex zero_lt_one
have hcost := eventually_const_mul_rpow_le (C := C * (2 : ℝ) ^ b) (E := p / 2)
hcount (half_pos hp)
filter_upwards [eventually_radix_width_bounds hθ hθ1 hγ, hhost, hcost,
eventually_ge_atTop (1 : ℕ)] with n hw hhost hcost hn1
obtain ⟨hwpos, hwlt, hwhalf, hlen⟩ := hw
have hnpos : (0 : ℝ) < n := by exact_mod_cast (show 0 < n by omega)
let m := n - radixWidth n θ
let Q := n.factorial / m.factorial
have hpow (t : ℝ) (ht : 0 ≤ t) :
C * (binaryLength Q : ℝ) ^ t ≤
(C * (2 : ℝ) ^ t) * (n : ℝ) ^ ((θ + γ) * t) := by
calc
C * (binaryLength Q : ℝ) ^ t ≤ C * (2 * (n : ℝ) ^ (θ + γ)) ^ t :=
mul_le_mul_of_nonneg_left (Real.rpow_le_rpow (Nat.cast_nonneg _) hlen ht) hC
_ = (C * (2 : ℝ) ^ t) * (n : ℝ) ^ ((θ + γ) * t) := by
rw [Real.mul_rpow (by norm_num : (0 : ℝ) ≤ 2)
(Real.rpow_nonneg (Nat.cast_nonneg n) _), ← Real.rpow_mul (Nat.cast_nonneg n)]
ring
have hhost' : C * (binaryLength Q : ℝ) ^ a ≤ n :=
(hpow a ha).trans (by simpa only [Real.rpow_one, one_mul] using hhost)
have hrec := local_bounds_radix_recurrence ha hb hC (Nat.sub_le n (radixWidth n θ))
hlocal hhost'
have hcost' : (⌊C * (binaryLength Q : ℝ) ^ b⌋₊ : ℝ) ≤
(p / 2) * (n : ℝ) ^ (θ + p - 1) :=
(Nat.floor_le (mul_nonneg hC (Real.rpow_nonneg (Nat.cast_nonneg _) b))).trans
((hpow b hb).trans hcost)
have hdiff := rpow_difference_lower_bound hnpos (Nat.cast_nonneg m) hp.le hp1
have hnm : (n : ℝ) - (m : ℝ) = (radixWidth n θ : ℝ) := by
dsimp [m]
rw [Nat.cast_sub hwlt.le]
ring
rw [hnm] at hdiff
have hpoweq : (n : ℝ) ^ θ * (n : ℝ) ^ (p - 1) = (n : ℝ) ^ (θ + p - 1) := by
rw [← Real.rpow_add hnpos]
congr 1
ring
have hgap : (p / 2) * (n : ℝ) ^ (θ + p - 1) ≤
(n : ℝ) ^ p - (m : ℝ) ^ p := by
calc
(p / 2) * (n : ℝ) ^ (θ + p - 1) =
(p * ((n : ℝ) ^ θ / 2)) * (n : ℝ) ^ (p - 1) := by rw [← hpoweq]; ring
_ ≤ (p * (radixWidth n θ : ℝ)) * (n : ℝ) ^ (p - 1) :=
mul_le_mul_of_nonneg_right (mul_le_mul_of_nonneg_left hwhalf hp.le)
(Real.rpow_nonneg (Nat.cast_nonneg n) _)
_ ≤ (n : ℝ) ^ p - (m : ℝ) ^ p := hdiff
have hrec' : (Erdos18.practicalH n.factorial : ℝ) ≤
(Erdos18.practicalH m.factorial : ℝ) + (⌊C * (binaryLength Q : ℝ) ^ b⌋₊ : ℝ) := by
exact_mod_cast hrec
refine ⟨m, Nat.sub_lt (by omega) hwpos, ?_⟩
linarith
theorem local_bounds_give_power_bound {p : ℝ} (hp : 0 < p) (hp1 : p ≤ 1)
(hlocal : LocalFactorialBounds (1 + p / 16) (p / 4)) :
∃ K : ℝ, 0 ≤ K ∧ ∀ n : ℕ,
(Erdos18.practicalH n.factorial : ℝ) ≤ K + (n : ℝ) ^ p := by
obtain ⟨C, hC, hlocal⟩ := hlocal
apply bounded_of_eventual_potential_decrease
(fun n => (Erdos18.practicalH n.factorial : ℝ)) (fun n => (n : ℝ) ^ p)
(fun n => Real.rpow_nonneg (Nat.cast_nonneg n) p)
exact eventual_factorial_potential_decrease (a := 1 + p / 16) (b := p / 4)
(θ := 1 - p / 4) (γ := p / 8)
(by linarith) (by linarith) hp hp1 (by linarith) (by linarith) (by linarith)
hC.le (by nlinarith [sq_nonneg p]) (by nlinarith [sq_nonneg p]) hlocal
/- This intermediate conditional theorem verifies the
entire subsequent deduction, including both recursions and the strict bound. -/
theorem erdos18b_of_dyadic_modular_bounds
(h : ∀ a b : ℝ, 1 < a → 0 < b → DyadicModularBounds a b) :
fcTypeOfName% "Erdos18.erdos_18b" := by
constructor
· intro _ δ hδ
let p : ℝ := min (δ / 2) (1 / 2)
have hp : 0 < p := lt_min (half_pos hδ) (by norm_num)
have hp1 : p ≤ 1 := (min_le_right _ _).trans (by norm_num)
have hpδ : p < δ := (min_le_left _ _).trans_lt (half_lt_self hδ)
have ha : 0 < 1 + p / 16 := by linarith
have hb : 0 < p / 4 := by linarith
have hba : p / 4 ≤ 1 + p / 16 := by linarith
have hmod := h (1 + p / 16) (p / 4) (by linarith) hb
have hlocal := dyadic_modular_bounds_give_local_bounds ha hb hba hmod
obtain ⟨K, _, hbound⟩ := local_bounds_give_power_bound hp hp1 hlocal
have hpow := eventually_const_mul_rpow_le (C := 1) (E := 1 / 3) hpδ (by norm_num)
have hconst := eventually_const_mul_rpow_le (C := K) (E := 1 / 3) hδ (by norm_num)
filter_upwards [hpow, hconst, eventually_ge_atTop (1 : ℕ)] with n hn hK hn1
have hn' : (n : ℝ) ^ p ≤ (1 / 3) * (n : ℝ) ^ δ := by simpa using hn
have hK' : K ≤ (1 / 3) * (n : ℝ) ^ δ := by simpa using hK
have hpos : 0 < (n : ℝ) ^ δ := Real.rpow_pos_of_pos
(by exact_mod_cast (show 0 < n by omega)) δ
calc
(Erdos18.practicalH n.factorial : ℝ) ≤ K + (n : ℝ) ^ p := hbound n
_ ≤ (1 / 3) * (n : ℝ) ^ δ + (1 / 3) * (n : ℝ) ^ δ := add_le_add hK' hn'
_ < (n : ℝ) ^ δ := by nlinarith only [hpos]
· intro _
trivial
theorem subpolynomial_of_power_log_bounds (f : ℕ → ℝ)
(h : ∀ ε : ℝ, 0 < ε → ∃ C K : ℝ, ∀ᶠ n : ℕ in Filter.atTop,
f n ≤ C * (n : ℝ) ^ ε * (Real.log (n : ℝ)) ^ K) :
∀ δ : ℝ, 0 < δ → ∀ᶠ n : ℕ in Filter.atTop, f n < (n : ℝ) ^ δ := by
intro δ hδ
have hhalf : 0 < δ / 2 := half_pos hδ
obtain ⟨C, K, hbound⟩ := h (δ / 2) hhalf
have hsmall := ((isLittleO_log_rpow_rpow_atTop K hhalf).const_mul_left C).comp_tendsto
(tendsto_natCast_atTop_atTop (R := ℝ))
have hevent := hsmall.def (by norm_num : (0 : ℝ) < 1 / 2)
filter_upwards [hbound, hevent, eventually_ge_atTop (1 : ℕ)] with n hn he hn1
have hnpos : (0 : ℝ) < n := by exact_mod_cast (show 0 < n by omega)
have hp : 0 < (n : ℝ) ^ (δ / 2) := Real.rpow_pos_of_pos hnpos _
have hlog : C * (Real.log (n : ℝ)) ^ K < (n : ℝ) ^ (δ / 2) := by
have he' : |C * (Real.log (n : ℝ)) ^ K| ≤ (1 / 2) * (n : ℝ) ^ (δ / 2) := by
simpa only [Function.comp_apply, Real.norm_eq_abs, abs_of_pos hp] using he
have hle := le_abs_self (C * (Real.log (n : ℝ)) ^ K)
linarith
calc
f n ≤ C * (n : ℝ) ^ (δ / 2) * (Real.log (n : ℝ)) ^ K := hn
_ = (n : ℝ) ^ (δ / 2) * (C * (Real.log (n : ℝ)) ^ K) := by ring
_ < (n : ℝ) ^ (δ / 2) * (n : ℝ) ^ (δ / 2) :=
mul_lt_mul_of_pos_left hlog hp
_ = (n : ℝ) ^ δ := by
rw [← Real.rpow_add hnpos]
congr 1
ring
/- Final asymptotic deduction from the intermediate modular hypothesis. -/
theorem erdos18b_of_power_log_bounds
(h : ∀ ε : ℝ, 0 < ε → ∃ C K : ℝ, ∀ᶠ n : ℕ in Filter.atTop,
(Erdos18.practicalH n.factorial : ℝ) ≤
C * (n : ℝ) ^ ε * (Real.log (n : ℝ)) ^ K) :
fcTypeOfName% "Erdos18.erdos_18b" := by
constructor
· intro _
exact subpolynomial_of_power_log_bounds _ h
· intro _
trivial
noncomputable def cyclicConvolution {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (x : ZMod q) : ℂ := ∑ y, f y * g (x - y)
theorem dft_cyclicConvolution {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (k : ZMod q) :
ZMod.dft (cyclicConvolution f g) k = ZMod.dft f k * ZMod.dft g k := by
classical
simp only [ZMod.dft_apply, smul_eq_mul, cyclicConvolution]
rw [Finset.sum_mul]
simp_rw [Finset.mul_sum]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro y _
refine Fintype.sum_equiv (Equiv.subRight y) _ _ ?_
intro x
simp only [Equiv.subRight_apply]
have hchar : ZMod.stdAddChar (-(x * k)) =
ZMod.stdAddChar (-(y * k)) * ZMod.stdAddChar (-((x - y) * k)) := by
rw [← AddChar.map_add_eq_mul]
congr 1
ring
rw [hchar]
ring
noncomputable def cyclicConvolutionPow {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) : ℕ → ZMod q → ℂ
| 0 => fun x => if x = 0 then 1 else 0
| s + 1 => cyclicConvolution f (cyclicConvolutionPow f s)
theorem dft_cyclicConvolutionPow {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (s : ℕ) (k : ZMod q) :
ZMod.dft (cyclicConvolutionPow f s) k = (ZMod.dft f k) ^ s := by
classical
induction s with
| zero => simp [cyclicConvolutionPow, ZMod.dft_apply]
| succ s ih =>
rw [cyclicConvolutionPow, dft_cyclicConvolution, ih, pow_succ]
ring
theorem nonzero_of_fourier_norm_sum_lt_one {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (hzero : ZMod.dft f 0 = 1)
(hsmall : ∑ k ∈ (Finset.univ : Finset (ZMod q)).erase 0, ‖ZMod.dft f k‖ < 1) :
∀ x : ZMod q, f x ≠ 0 := by
classical
intro x hx
have hsum := congrFun (ZMod.dft_dft f) (-x)
rw [ZMod.dft_apply] at hsum
simp only [mul_neg, neg_neg, hx, smul_eq_mul, mul_zero] at hsum
have hsplit := Finset.sum_erase_add (Finset.univ : Finset (ZMod q))
(fun k => ZMod.stdAddChar (k * x) * ZMod.dft f k) (Finset.mem_univ 0)
have hrest : (∑ k ∈ (Finset.univ : Finset (ZMod q)).erase 0,
ZMod.stdAddChar (k * x) * ZMod.dft f k) = -1 := by
have hz : ZMod.stdAddChar (0 * x) * ZMod.dft f 0 = 1 := by simp [hzero]
rw [hz, hsum] at hsplit
exact eq_neg_of_add_eq_zero_left hsplit
have hnorm : ‖∑ k ∈ (Finset.univ : Finset (ZMod q)).erase 0,
ZMod.stdAddChar (k * x) * ZMod.dft f k‖ ≤
∑ k ∈ (Finset.univ : Finset (ZMod q)).erase 0, ‖ZMod.dft f k‖ := by
calc
_ ≤ ∑ k ∈ (Finset.univ : Finset (ZMod q)).erase 0,
‖ZMod.stdAddChar (k * x) * ZMod.dft f k‖ := norm_sum_le _ _
_ = _ := by simp only [norm_mul, ZMod.stdAddChar_apply, Circle.norm_coe, one_mul]
rw [hrest] at hnorm
norm_num only [norm_neg, norm_one] at hnorm
exact (hnorm.trans_lt hsmall).false
theorem convolution_pow_nonzero_of_fourier_bound {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (s : ℕ) (hzero : ZMod.dft f 0 = 1)
(hsmall : ∑ k ∈ (Finset.univ : Finset (ZMod q)).erase 0, ‖ZMod.dft f k‖ ^ s < 1) :
∀ x : ZMod q, cyclicConvolutionPow f s x ≠ 0 := by
apply nonzero_of_fourier_norm_sum_lt_one
· rw [dft_cyclicConvolutionPow, hzero, one_pow]
· simpa only [dft_cyclicConvolutionPow, norm_pow] using hsmall
theorem convolution_pow_support_representatives {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (F u H : ℕ)
(hsupport : ∀ x : ZMod q, f x ≠ 0 → ∃ S : ℕ,
S ≤ H ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset F S u) :
∀ s : ℕ, ∀ x : ZMod q, cyclicConvolutionPow f s x ≠ 0 → ∃ S : ℕ,
S ≤ s * H ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset F S (s * u) := by
classical
intro s
induction s with
| zero =>
intro x hx
have hxzero : x = 0 := by
by_contra hne
simp only [cyclicConvolutionPow, if_neg hne] at hx
exact hx rfl
subst x
exact ⟨0, by simp, by simp, by simpa using factorial_multiset_zero F 0⟩
| succ s ih =>
intro x hx
change (∑ y : ZMod q, f y * cyclicConvolutionPow f s (x - y)) ≠ 0 at hx
obtain ⟨y, _, hy⟩ := Finset.exists_ne_zero_of_sum_ne_zero hx
obtain ⟨hfy, hgs⟩ := mul_ne_zero_iff.mp hy
obtain ⟨A, hA, hAcast, hArep⟩ := hsupport y hfy
obtain ⟨B, hB, hBcast, hBrep⟩ := ih (x - y) hgs
refine ⟨A + B, ?_, ?_, ?_⟩
· calc
A + B ≤ H + s * H := Nat.add_le_add hA hB
_ = (s + 1) * H := by ring
· rw [Nat.cast_add, hAcast, hBcast]
abel
· simpa only [Nat.succ_mul, Nat.add_comm] using factorial_multiset_add hArep hBrep
theorem bounded_modular_representatives_of_fourier {q F u H D s : ℕ} [NeZero q]
(f : ZMod q → ℂ) (hzero : ZMod.dft f 0 = 1)
(hsmall : ∑ k ∈ (Finset.univ : Finset (ZMod q)).erase 0, ‖ZMod.dft f k‖ ^ s < 1)
(hsupport : ∀ x : ZMod q, f x ≠ 0 → ∃ S : ℕ,
S ≤ H ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset F S u)
(hheight : s * H ≤ q ^ D) :
HasBoundedModularRepresentatives q F (s * u) D := by
intro R
obtain ⟨S, hS, hScast, hrep⟩ := convolution_pow_support_representatives f F u H hsupport s
(R : ZMod q) (convolution_pow_nonzero_of_fourier_bound f s hzero hsmall (R : ZMod q))
exact ⟨S, hS.trans hheight, (ZMod.natCast_eq_natCast_iff S R q).mp hScast, hrep⟩
noncomputable def dyadicConductorLevel {K : ℕ} (x : ZMod (2 ^ K)) : ℕ :=
Nat.log 2 (addOrderOf x)
theorem dyadic_conductor_spec {K : ℕ} (x : ZMod (2 ^ K)) :
dyadicConductorLevel x ≤ K ∧ addOrderOf x = 2 ^ dyadicConductorLevel x := by
have hdvd : addOrderOf x ∣ 2 ^ K := by
simpa only [ZMod.card] using addOrderOf_dvd_card (x := x)
obtain ⟨j, hj, heq⟩ := (Nat.dvd_prime_pow Nat.prime_two).mp hdvd
have hlevel : dyadicConductorLevel x = j := by
simp only [dyadicConductorLevel, heq, Nat.log_pow (by decide : 1 < 2)]
exact ⟨hlevel ▸ hj, by rw [hlevel, heq]⟩
theorem dyadic_conductor_pos {K : ℕ} {x : ZMod (2 ^ K)} (hx : x ≠ 0) :
0 < dyadicConductorLevel x := by
by_contra h
have hz : dyadicConductorLevel x = 0 := by omega
have horder : addOrderOf x = 1 := by simpa only [hz, pow_zero] using (dyadic_conductor_spec x).2
exact hx (AddMonoid.addOrderOf_eq_one_iff.mp horder)
theorem dyadic_conductor_fiber_card_le {K j : ℕ} (hj : j ≤ K) :
(((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)).card ≤ 2 ^ j := by
classical
have hsub : (((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)) ⊆
(Finset.univ.filter (fun x : ZMod (2 ^ K) => addOrderOf x = 2 ^ j)) := by
intro x hx
obtain ⟨_, heq⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨Finset.mem_univ _, by rw [← heq]; exact (dyadic_conductor_spec x).2⟩
calc
_ ≤ (Finset.univ.filter (fun x : ZMod (2 ^ K) => addOrderOf x = 2 ^ j)).card :=
Finset.card_le_card hsub
_ = Nat.totient (2 ^ j) := IsAddCyclic.card_addOrderOf_eq_totient
(by simpa only [ZMod.card] using pow_dvd_pow 2 hj)
_ ≤ 2 ^ j := Nat.totient_le _
theorem dyadic_geometric_sum (K : ℕ) :
(∑ j ∈ Finset.Icc 1 K, (1 / 2 : ℝ) ^ j) = 1 - (1 / 2 : ℝ) ^ K := by
induction K with
| zero => simp
| succ K ih =>
rw [Finset.sum_Icc_succ_top (by omega : 1 ≤ K + 1), ih, pow_succ]
ring
theorem dyadic_fourier_norm_sum_lt_one {K s : ℕ} (f : ZMod (2 ^ K) → ℂ)
(hdecay : ∀ x : ZMod (2 ^ K), x ≠ 0 →
‖ZMod.dft f x‖ ^ s ≤ (1 / 4 : ℝ) ^ dyadicConductorLevel x) :
∑ x ∈ (Finset.univ : Finset (ZMod (2 ^ K))).erase 0, ‖ZMod.dft f x‖ ^ s < 1 := by
classical
have hmaps : ∀ x ∈ (Finset.univ : Finset (ZMod (2 ^ K))).erase 0,
dyadicConductorLevel x ∈ Finset.Icc 1 K := by
intro x hx
exact Finset.mem_Icc.mpr ⟨dyadic_conductor_pos (Finset.mem_erase.mp hx).1,
(dyadic_conductor_spec x).1⟩
have hbound :
(∑ x ∈ (Finset.univ : Finset (ZMod (2 ^ K))).erase 0, ‖ZMod.dft f x‖ ^ s) ≤
∑ j ∈ Finset.Icc 1 K, (1 / 2 : ℝ) ^ j := by
rw [← Finset.sum_fiberwise_of_maps_to hmaps (fun x => ‖ZMod.dft f x‖ ^ s)]
apply Finset.sum_le_sum
intro j hj
have hcard :
((((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)).card : ℝ) ≤ (2 : ℝ) ^ j := by
exact_mod_cast dyadic_conductor_fiber_card_le (Finset.mem_Icc.mp hj).2
calc
_ ≤ ∑ x ∈ (((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)), (1 / 4 : ℝ) ^ j := by
apply Finset.sum_le_sum
intro x hx
obtain ⟨hx, hlevel⟩ := Finset.mem_filter.mp hx
simpa only [hlevel] using hdecay x (Finset.mem_erase.mp hx).1
_ = ((((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)).card : ℝ) * (1 / 4 : ℝ) ^ j := by simp
_ ≤ (2 : ℝ) ^ j * (1 / 4 : ℝ) ^ j :=
mul_le_mul_of_nonneg_right hcard (by positivity)
_ = (1 / 2 : ℝ) ^ j := by rw [← mul_pow]; norm_num
rw [dyadic_geometric_sum] at hbound
have hpos : 0 < (1 / 2 : ℝ) ^ K := pow_pos (by norm_num) _
exact hbound.trans_lt (by linarith)
theorem powered_dyadic_decay_le {v t : ℝ} {s j : ℕ} (hv : 0 ≤ v)
(hdecay : v ≤ (2 : ℝ) ^ (-t * (j : ℝ))) (hs : 2 ≤ t * (s : ℝ)) :
v ^ s ≤ (1 / 4 : ℝ) ^ j := by
calc
v ^ s ≤ ((2 : ℝ) ^ (-t * (j : ℝ))) ^ s := pow_le_pow_left₀ hv hdecay s
_ = (2 : ℝ) ^ ((-t * (j : ℝ)) * (s : ℝ)) :=
(Real.rpow_mul_natCast (by norm_num) _ _).symm
_ ≤ (2 : ℝ) ^ ((-2 : ℝ) * (j : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith [mul_le_mul_of_nonneg_right hs (Nat.cast_nonneg j : (0 : ℝ) ≤ j)]
_ = (1 / 4 : ℝ) ^ j := by
rw [Real.rpow_mul_natCast (by norm_num)]
norm_num [Real.rpow_neg, Real.rpow_ofNat]
theorem exists_convolution_power_for_dyadic_decay {t : ℝ} (ht : 0 < t) :
∃ s : ℕ, 0 < s ∧ ∀ K : ℕ, ∀ f : ZMod (2 ^ K) → ℂ,
(∀ x : ZMod (2 ^ K), x ≠ 0 →
‖ZMod.dft f x‖ ≤ (2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ))) →
∑ x ∈ (Finset.univ : Finset (ZMod (2 ^ K))).erase 0, ‖ZMod.dft f x‖ ^ s < 1 := by
obtain ⟨s, hs⟩ := exists_nat_ge (2 / t)
have hts : 2 ≤ t * (s : ℝ) := by
have := (div_le_iff₀ ht).mp hs
nlinarith
have hspos : 0 < s := by
by_contra h
have : s = 0 := by omega
simp only [this, Nat.cast_zero, mul_zero] at hts
norm_num at hts
refine ⟨s, hspos, ?_⟩
intro K f hdecay
apply dyadic_fourier_norm_sum_lt_one
intro x hx
exact powered_dyadic_decay_le (norm_nonneg _) (hdecay x hx) hts
noncomputable def cyclicPushforward {α : Type*} [Fintype α] {q : ℕ} [NeZero q]
(w : α → ℂ) (T : α → ZMod q) (x : ZMod q) : ℂ :=
∑ a, if T a = x then w a else 0
theorem dft_cyclicPushforward {α : Type*} [Fintype α] {q : ℕ} [NeZero q]
(w : α → ℂ) (T : α → ZMod q) (k : ZMod q) :
ZMod.dft (cyclicPushforward w T) k = ∑ a, ZMod.stdAddChar (-(T a * k)) * w a := by
classical
simp only [ZMod.dft_apply, cyclicPushforward, smul_eq_mul, Finset.mul_sum]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro a _
simp only [mul_ite, mul_zero]
simp
theorem cyclicPushforward_support {α : Type*} [Fintype α] {q : ℕ} [NeZero q]
(w : α → ℂ) (T : α → ZMod q) {x : ZMod q}
(hx : cyclicPushforward w T x ≠ 0) : ∃ a : α, T a = x ∧ w a ≠ 0 := by
classical
obtain ⟨a, _, ha⟩ := Finset.exists_ne_zero_of_sum_ne_zero hx
by_cases h : T a = x
· exact ⟨a, h, by simpa only [h, if_true] using ha⟩
· simp only [h, if_false, ne_eq, not_true_eq_false] at ha
theorem dft_translate {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (a k : ZMod q) :
ZMod.dft (fun x => f (x - a)) k = ZMod.stdAddChar (-(a * k)) * ZMod.dft f k := by
classical
simp only [ZMod.dft_apply, smul_eq_mul, Finset.mul_sum]
refine Fintype.sum_equiv (Equiv.subRight a) _ _ ?_
intro x
simp only [Equiv.subRight_apply]
rw [← mul_assoc, ← AddChar.map_add_eq_mul]
congr 2
ring
noncomputable def cyclicBernoulliSmooth {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (x : ZMod q) : ℂ := (f x + f (x - 1)) / 2
theorem dft_cyclicBernoulliSmooth {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (k : ZMod q) :
ZMod.dft (cyclicBernoulliSmooth f) k =
ZMod.dft f k * ((1 + ZMod.stdAddChar (-k)) / 2) := by
have heq : cyclicBernoulliSmooth f =
(fun x => f x + f (x - 1)) * (fun _ => (2 : ℂ)⁻¹) := by
ext x
simp [cyclicBernoulliSmooth, div_eq_mul_inv]
rw [heq]
change ZMod.dft (fun x => (f x + f (x - 1)) * (2 : ℂ)⁻¹) k = _
rw [ZMod.dft_mul_const]
change ZMod.dft (fun x => f x + f (x - 1)) k * (2 : ℂ)⁻¹ = _
have hadd : ZMod.dft (fun x => f x + f (x - 1)) k =
ZMod.dft f k + ZMod.dft (fun x => f (x - 1)) k := by
exact congrFun (map_add ZMod.dft f (fun x => f (x - 1))) k
rw [hadd, dft_translate]
simp only [one_mul]
ring
theorem norm_dft_cyclicBernoulliSmooth_le {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (k : ZMod q) :
‖ZMod.dft (cyclicBernoulliSmooth f) k‖ ≤ ‖ZMod.dft f k‖ := by
have hnorm : ‖(1 + ZMod.stdAddChar (-k)) / (2 : ℂ)‖ ≤ 1 := by
rw [norm_div]
have ht := norm_add_le (1 : ℂ) (ZMod.stdAddChar (-k))
norm_num only [norm_one, ZMod.stdAddChar_apply, Circle.norm_coe, Complex.norm_ofNat] at *
linarith
rw [dft_cyclicBernoulliSmooth, norm_mul]
simpa only [mul_one] using mul_le_mul_of_nonneg_left hnorm (norm_nonneg _)
theorem dft_cyclicBernoulliSmooth_zero {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) {k : ZMod q} (hk : k ≠ 0) (h2 : (2 : ZMod q) * k = 0) :
ZMod.dft (cyclicBernoulliSmooth f) k = 0 := by
have hsq : ZMod.stdAddChar (-k) ^ 2 = (1 : ℂ) := by
rw [← AddChar.map_nsmul_eq_pow]
have hz : 2 • (-k) = 0 := by
norm_num only [nsmul_eq_mul, Nat.cast_ofNat, mul_neg, h2, neg_zero]
rw [hz, AddChar.map_zero_eq_one]
have hne : ZMod.stdAddChar (-k) ≠ (1 : ℂ) := by
intro h
have hzero : ZMod.stdAddChar (-k) = ZMod.stdAddChar (0 : ZMod q) := by simpa using h
exact hk (neg_eq_zero.mp (ZMod.injective_stdAddChar hzero))
have hchar := (sq_eq_one_iff.mp hsq).resolve_left hne
rw [dft_cyclicBernoulliSmooth, hchar]
simp
theorem sum_addChar_progression_eq_zero {q : ℕ} [NeZero q]
(ψ : AddChar (ZMod q) ℂ) (a b : ZMod q) (n : ℕ)
(hb : ψ b ≠ 1) (hn : ψ (n • b) = 1) :
∑ i ∈ Finset.range n, ψ (a + i • b) = 0 := by
have hpow : (ψ b) ^ n = 1 := by rw [← AddChar.map_nsmul_eq_pow, hn]
have hgeom := geom_sum_mul (ψ b) n
rw [hpow, sub_self] at hgeom
have hsum : (∑ i ∈ Finset.range n, (ψ b) ^ i) = 0 :=
(mul_eq_zero.mp hgeom).resolve_right (sub_ne_zero.mpr hb)
simp_rw [AddChar.map_add_eq_mul, AddChar.map_nsmul_eq_pow]
rw [← Finset.mul_sum, hsum, mul_zero]
theorem dyadic_conductor_twice_ne_zero {K : ℕ} {x : ZMod (2 ^ K)}
(hx : 2 ≤ dyadicConductorLevel x) : (2 : ZMod (2 ^ K)) * x ≠ 0 := by
intro hzero
have hsmul : 2 • x = 0 := by simpa only [nsmul_eq_mul, Nat.cast_ofNat] using hzero
have hdvd : addOrderOf x ∣ 2 := addOrderOf_dvd_iff_nsmul_eq_zero.mpr hsmul
rw [(dyadic_conductor_spec x).2] at hdvd
have hle := Nat.le_of_dvd (by decide : 0 < 2) hdvd
have hfour : 4 ≤ 2 ^ dyadicConductorLevel x := by
exact Nat.pow_le_pow_right (by decide : 0 < 2) hx
omega
theorem dyadic_conductor_power_nsmul_eq_zero {K b : ℕ} {x : ZMod (2 ^ K)}
(hx : dyadicConductorLevel x ≤ b) : (2 ^ b) • x = 0 := by
apply addOrderOf_dvd_iff_nsmul_eq_zero.mp
rw [(dyadic_conductor_spec x).2]
exact pow_dvd_pow 2 hx
noncomputable def cyclicOddDigit {K : ℕ} (b : ℕ) : ZMod (2 ^ K) → ℂ :=
cyclicPushforward (fun _ : Fin (2 ^ (b - 1)) => ((2 ^ (b - 1) : ℕ) : ℂ)⁻¹)
(fun i => ((2 * i.val + 1 : ℕ) : ZMod (2 ^ K)))
theorem dft_cyclicOddDigit_zero {K b : ℕ} {k : ZMod (2 ^ K)}
(hklo : 2 ≤ dyadicConductorLevel k) (hkhi : dyadicConductorLevel k ≤ b) :
ZMod.dft (cyclicOddDigit b) k = 0 := by
have hbpos : 0 < b := by omega
have hp : 2 ^ (b - 1) * 2 = 2 ^ b := by
rw [← pow_succ, Nat.sub_add_cancel hbpos]
have hchar : ZMod.stdAddChar (-(2 * k)) ≠ (1 : ℂ) := by
intro h
have hh : ZMod.stdAddChar (-(2 * k)) = ZMod.stdAddChar (0 : ZMod (2 ^ K)) := by
simpa using h
exact dyadic_conductor_twice_ne_zero hklo (neg_eq_zero.mp (ZMod.injective_stdAddChar hh))
have hperiod : ZMod.stdAddChar ((2 ^ (b - 1)) • (-(2 * k))) = (1 : ℂ) := by
have heq : ((2 ^ (b - 1) : ℕ) • (-(2 * k)) : ZMod (2 ^ K)) =
-((2 ^ b : ℕ) • k) := by
simp only [nsmul_eq_mul, Nat.cast_pow, Nat.cast_ofNat, mul_neg]
rw [← mul_assoc]
congr 2
simpa only [Nat.cast_mul, Nat.cast_pow, Nat.cast_ofNat] using
congrArg (fun n : ℕ => (n : ZMod (2 ^ K))) hp
rw [heq, dyadic_conductor_power_nsmul_eq_zero hkhi, neg_zero, AddChar.map_zero_eq_one]
have hsum := sum_addChar_progression_eq_zero ZMod.stdAddChar (-k) (-(2 * k))
(2 ^ (b - 1)) hchar hperiod
have hrewrite : ∀ i : ℕ,
ZMod.stdAddChar (-(((2 * i + 1 : ℕ) : ZMod (2 ^ K)) * k)) =
ZMod.stdAddChar (-k + i • (-(2 * k))) := by
intro i
congr 1
push_cast
simp only [nsmul_eq_mul]
ring
rw [cyclicOddDigit, dft_cyclicPushforward, ← Finset.sum_mul]
have hfin : (∑ i : Fin (2 ^ (b - 1)),
ZMod.stdAddChar (-(((2 * i.val + 1 : ℕ) : ZMod (2 ^ K)) * k))) = 0 := by
simpa only [hrewrite] using
(Fin.sum_univ_eq_sum_range
(fun i : ℕ => ZMod.stdAddChar (-k + i • (-(2 * k)))) (2 ^ (b - 1))).trans hsum
rw [hfin, zero_mul]
theorem dyadic_conductor_mul_unit {K : ℕ} (x y : ZMod (2 ^ K)) (hy : IsUnit y) :
dyadicConductorLevel (y * x) = dyadicConductorLevel x := by
obtain ⟨u, rfl⟩ := hy
have horder : addOrderOf ((u : ZMod (2 ^ K)) * x) = addOrderOf x :=
addOrderOf_injective (AddMonoidHom.mulLeft (u : ZMod (2 ^ K)))
(Units.mulLeft u).injective x
simp only [dyadicConductorLevel, horder]
noncomputable def cyclicMultiplicativeConvolution {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) : ZMod q → ℂ :=
cyclicPushforward (fun p : ZMod q × ZMod q => f p.1 * g p.2) (fun p => p.1 * p.2)
theorem dft_cyclicMultiplicativeConvolution {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (k : ZMod q) :
ZMod.dft (cyclicMultiplicativeConvolution f g) k =
∑ y : ZMod q, g y * ZMod.dft f (y * k) := by
classical
rw [cyclicMultiplicativeConvolution, dft_cyclicPushforward]
simp only [Fintype.sum_prod_type]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro y _
simp only [ZMod.dft_apply, smul_eq_mul, Finset.mul_sum, mul_assoc]
apply Finset.sum_congr rfl
intro x _
ring
theorem cyclicMultiplicativeConvolution_support_units {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (hf : ∀ x, f x ≠ 0 → IsUnit x)
(hg : ∀ x, g x ≠ 0 → IsUnit x) :
∀ x, cyclicMultiplicativeConvolution f g x ≠ 0 → IsUnit x := by
intro x hx
obtain ⟨⟨a, b⟩, hab, hw⟩ := cyclicPushforward_support
(fun p : ZMod q × ZMod q => f p.1 * g p.2) (fun p => p.1 * p.2) hx
obtain ⟨ha, hb⟩ := mul_ne_zero_iff.mp hw
rw [← hab]
exact (hf a ha).mul (hg b hb)
theorem cyclicMultiplicativeConvolution_support_representatives {q F G u v H J : ℕ}
[NeZero q] (f g : ZMod q → ℂ)
(hf : ∀ x, f x ≠ 0 → ∃ S : ℕ,
S ≤ H ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset F S u)
(hg : ∀ x, g x ≠ 0 → ∃ S : ℕ,
S ≤ J ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset G S v) :
∀ x, cyclicMultiplicativeConvolution f g x ≠ 0 → ∃ S : ℕ,
S ≤ H * J ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset (F + G) S (u * v) := by
intro x hx
obtain ⟨⟨a, b⟩, hab, hw⟩ := cyclicPushforward_support
(fun p : ZMod q × ZMod q => f p.1 * g p.2) (fun p => p.1 * p.2) hx
obtain ⟨ha, hb⟩ := mul_ne_zero_iff.mp hw
obtain ⟨A, hA, hAcast, hArep⟩ := hf a ha
obtain ⟨B, hB, hBcast, hBrep⟩ := hg b hb
exact ⟨A * B, Nat.mul_le_mul hA hB, by simpa only [Nat.cast_mul, hAcast, hBcast] using hab,
factorial_multiset_mul hArep hBrep⟩
theorem dft_cyclicMultiplicativeConvolution_zero {K lo hi : ℕ}
(f g : ZMod (2 ^ K) → ℂ)
(hf : ∀ x, lo ≤ dyadicConductorLevel x → dyadicConductorLevel x ≤ hi → ZMod.dft f x = 0)
(hg : ∀ x, g x ≠ 0 → IsUnit x) {k : ZMod (2 ^ K)}
(hklo : lo ≤ dyadicConductorLevel k) (hkhi : dyadicConductorLevel k ≤ hi) :
ZMod.dft (cyclicMultiplicativeConvolution f g) k = 0 := by
rw [dft_cyclicMultiplicativeConvolution]
apply Finset.sum_eq_zero
intro y _
by_cases hy : g y = 0
· simp only [hy, zero_mul]
· have hlevel := dyadic_conductor_mul_unit k y (hg y hy)
rw [hf (y * k) (by rwa [hlevel]) (by rwa [hlevel]), mul_zero]
noncomputable def cyclicProductPow {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) : ℕ → ZMod q → ℂ
| 0 => fun x => if x = 1 then 1 else 0
| r + 1 => cyclicMultiplicativeConvolution f (cyclicProductPow f r)
theorem cyclicProductPow_support_units {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (hf : ∀ x, f x ≠ 0 → IsUnit x) :
∀ r : ℕ, ∀ x, cyclicProductPow f r x ≠ 0 → IsUnit x := by
intro r
induction r with
| zero =>
intro x hx
have hxeq : x = 1 := by
by_contra h
simp only [cyclicProductPow, if_neg h, ne_eq, not_true_eq_false] at hx
rw [hxeq]
exact isUnit_one
| succ r ih =>
exact cyclicMultiplicativeConvolution_support_units f _ hf ih
theorem cyclicProductPow_support_representatives {q F u H : ℕ} [NeZero q]
(f : ZMod q → ℂ)
(hf : ∀ x, f x ≠ 0 → ∃ S : ℕ,
S ≤ H ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset F S u) :
∀ r : ℕ, ∀ x, cyclicProductPow f r x ≠ 0 → ∃ S : ℕ,
S ≤ H ^ r ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset (r * F) S (u ^ r) := by
intro r
induction r with
| zero =>
intro x hx
have hxeq : x = 1 := by
by_contra h
simp only [cyclicProductPow, if_neg h, ne_eq, not_true_eq_false] at hx
refine ⟨1, by simp, by simp [hxeq], ?_⟩
simpa using factorial_multiset_singleton (F := 0) (R := 1) (one_dvd _)
| succ r ih =>
intro x hx
have hrep := cyclicMultiplicativeConvolution_support_representatives f _ hf ih x hx
simpa only [Nat.succ_mul, pow_succ, Nat.add_comm, Nat.mul_comm] using hrep
theorem dft_cyclicProductPow_zero {K lo hi r : ℕ}
(f : ZMod (2 ^ K) → ℂ) (hr : 0 < r)
(hu : ∀ x, f x ≠ 0 → IsUnit x)
(hf : ∀ x, lo ≤ dyadicConductorLevel x → dyadicConductorLevel x ≤ hi → ZMod.dft f x = 0)
{k : ZMod (2 ^ K)} (hklo : lo ≤ dyadicConductorLevel k)
(hkhi : dyadicConductorLevel k ≤ hi) :
ZMod.dft (cyclicProductPow f r) k = 0 := by
obtain ⟨r, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (Nat.ne_of_gt hr)
exact dft_cyclicMultiplicativeConvolution_zero f _ hf
(cyclicProductPow_support_units f hu r) hklo hkhi
theorem dft_cyclicOddDigit_at_zero {K : ℕ} (b : ℕ) :
ZMod.dft (cyclicOddDigit (K := K) b) 0 = 1 := by
rw [cyclicOddDigit, dft_cyclicPushforward]
simp
theorem cyclicOddDigit_support_units {K b : ℕ} :
∀ x, cyclicOddDigit (K := K) b x ≠ 0 → IsUnit x := by
intro x hx
obtain ⟨i, hi, _⟩ := cyclicPushforward_support
(fun _ : Fin (2 ^ (b - 1)) => ((2 ^ (b - 1) : ℕ) : ℂ)⁻¹)
(fun i => ((2 * i.val + 1 : ℕ) : ZMod (2 ^ K))) hx
rw [← hi]
apply (ZMod.isUnit_iff_coprime _ _).mpr
have hc : Nat.Coprime (2 * i.val + 1) 2 := by
rw [Nat.coprime_comm, Nat.prime_two.coprime_iff_not_dvd]
omega
exact hc.pow_right K
theorem cyclicOddDigit_support_representatives {K b F : ℕ} (hb : 0 < b) (hF : 2 ^ b ≤ F) :
∀ x, cyclicOddDigit (K := K) b x ≠ 0 → ∃ S : ℕ,
S ≤ 2 ^ b ∧ (S : ZMod (2 ^ K)) = x ∧ HasFactorialDivisorMultiset F S 1 := by
intro x hx
obtain ⟨i, hi, _⟩ := cyclicPushforward_support
(fun _ : Fin (2 ^ (b - 1)) => ((2 ^ (b - 1) : ℕ) : ℂ)⁻¹)
(fun i => ((2 * i.val + 1 : ℕ) : ZMod (2 ^ K))) hx
have hp : 2 ^ b = 2 * 2 ^ (b - 1) := by
rw [← pow_succ', Nat.sub_add_cancel hb]
have hS : 2 * i.val + 1 ≤ 2 ^ b := by rw [hp]; omega
exact ⟨2 * i.val + 1, hS, hi,
factorial_multiset_singleton (Nat.dvd_factorial (by omega) (hS.trans hF))⟩
theorem dft_cyclicMultiplicativeConvolution_at_zero {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) :
ZMod.dft (cyclicMultiplicativeConvolution f g) 0 = ZMod.dft f 0 * ZMod.dft g 0 := by
rw [dft_cyclicMultiplicativeConvolution]
simp only [mul_zero, ← Finset.sum_mul, ZMod.dft_apply_zero]
ring
theorem dft_cyclicProductPow_at_zero {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (r : ℕ) : ZMod.dft (cyclicProductPow f r) 0 = (ZMod.dft f 0) ^ r := by
induction r with
| zero => simp [cyclicProductPow, ZMod.dft_apply_zero]
| succ r ih =>
rw [cyclicProductPow, dft_cyclicMultiplicativeConvolution_at_zero, ih, pow_succ]
ring
theorem dft_cyclicBernoulliSmooth_at_zero {q : ℕ} [NeZero q] (f : ZMod q → ℂ) :
ZMod.dft (cyclicBernoulliSmooth f) 0 = ZMod.dft f 0 := by
rw [dft_cyclicBernoulliSmooth]
simp
theorem cyclicBernoulliSmooth_support_representatives {q F u H : ℕ} [NeZero q]
(f : ZMod q → ℂ)
(hf : ∀ x, f x ≠ 0 → ∃ S : ℕ,
S ≤ H ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset F S u) :
∀ x, cyclicBernoulliSmooth f x ≠ 0 → ∃ S : ℕ,
S ≤ H + 1 ∧ (S : ZMod q) = x ∧ HasFactorialDivisorMultiset F S (u + 1) := by
intro x hx
by_cases hfx : f x = 0
· have hother : f (x - 1) ≠ 0 := by
intro h
simp only [cyclicBernoulliSmooth, hfx, h, add_zero, zero_div, ne_eq, not_true_eq_false] at hx
obtain ⟨S, hS, hScast, hrep⟩ := hf (x - 1) hother
refine ⟨S + 1, Nat.add_le_add_right hS 1, ?_, ?_⟩
· rw [Nat.cast_add, Nat.cast_one, hScast, sub_add_cancel]
· exact factorial_multiset_add hrep (factorial_multiset_singleton (one_dvd _))
· obtain ⟨S, hS, hScast, hrep⟩ := hf x hfx
exact ⟨S, by omega, hScast, factorial_multiset_mono hrep le_rfl (by omega)⟩
theorem dft_smooth_product_zero_at_low_conductor {K b r : ℕ}
(f : ZMod (2 ^ K) → ℂ) (hr : 0 < r)
(hu : ∀ x, f x ≠ 0 → IsUnit x)
(hf : ∀ x, 2 ≤ dyadicConductorLevel x → dyadicConductorLevel x ≤ b → ZMod.dft f x = 0)
{k : ZMod (2 ^ K)} (hk : k ≠ 0) (hkhi : dyadicConductorLevel k ≤ b) :
ZMod.dft (cyclicBernoulliSmooth (cyclicProductPow f r)) k = 0 := by
by_cases hklo : 2 ≤ dyadicConductorLevel k
· rw [dft_cyclicBernoulliSmooth, dft_cyclicProductPow_zero f hr hu hf hklo hkhi, zero_mul]
· have hlevel : dyadicConductorLevel k = 1 := by
have := dyadic_conductor_pos hk
omega
apply dft_cyclicBernoulliSmooth_zero _ hk
have horder : addOrderOf k = 2 := by simpa only [hlevel, pow_one] using (dyadic_conductor_spec k).2
simpa only [horder, nsmul_eq_mul, Nat.cast_ofNat] using addOrderOf_nsmul_eq_zero k
theorem exists_power_modular_representatives_of_product_decay {t : ℝ} (ht : 0 < t) :
∃ s : ℕ, 0 < s ∧ ∀ K b r F u : ℕ, 0 < r →
∀ f : ZMod (2 ^ K) → ℂ,
ZMod.dft f 0 = 1 →
(∀ x, f x ≠ 0 → IsUnit x) →
(∀ x, 2 ≤ dyadicConductorLevel x → dyadicConductorLevel x ≤ b → ZMod.dft f x = 0) →
(∀ x, b < dyadicConductorLevel x →
‖ZMod.dft (cyclicProductPow f r) x‖ ≤ (2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ))) →
(∀ x, f x ≠ 0 → ∃ S : ℕ,
S ≤ 2 ^ K ∧ (S : ZMod (2 ^ K)) = x ∧ HasFactorialDivisorMultiset F S u) →
2 * s ≤ 2 ^ K →
HasBoundedModularRepresentatives (2 ^ K) (r * F) (s * (u ^ r + 1)) (r + 1) := by
obtain ⟨s, hspos, hspower⟩ := exists_convolution_power_for_dyadic_decay ht
refine ⟨s, hspos, ?_⟩
intro K b r F u hr f hzero hunits hlow hhigh hsupport hheight
let g := cyclicBernoulliSmooth (cyclicProductPow f r)
have hdecay : ∀ x : ZMod (2 ^ K), x ≠ 0 →
‖ZMod.dft g x‖ ≤ (2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ)) := by
intro x hx
by_cases hxlo : dyadicConductorLevel x ≤ b
· have hz := dft_smooth_product_zero_at_low_conductor f hr hunits hlow hx hxlo
change ‖ZMod.dft (cyclicBernoulliSmooth (cyclicProductPow f r)) x‖ ≤ _
rw [hz, norm_zero]
positivity
· exact (norm_dft_cyclicBernoulliSmooth_le _ x).trans (hhigh x (by omega))
have hgzero : ZMod.dft g 0 = 1 := by
change ZMod.dft (cyclicBernoulliSmooth (cyclicProductPow f r)) 0 = 1
rw [dft_cyclicBernoulliSmooth_at_zero, dft_cyclicProductPow_at_zero, hzero, one_pow]
have hgsupport := cyclicBernoulliSmooth_support_representatives (cyclicProductPow f r)
(cyclicProductPow_support_representatives f hsupport r)
apply bounded_modular_representatives_of_fourier g hgzero (hspower K g hdecay) hgsupport
have hqpow : 1 ≤ (2 ^ K) ^ r := Nat.one_le_pow r (2 ^ K) (by positivity)
calc
s * ((2 ^ K) ^ r + 1) ≤ s * (2 * (2 ^ K) ^ r) := Nat.mul_le_mul_left s (by omega)
_ = (2 * s) * (2 ^ K) ^ r := by ring
_ ≤ (2 ^ K) * (2 ^ K) ^ r := Nat.mul_le_mul_right _ hheight
_ = (2 ^ K) ^ (r + 1) := (pow_succ' _ _).symm
def shortFactorialDigits (F l : ℕ) : Finset ℕ :=
insert 0 (F.factorial.divisors.filter (fun d => d < 2 ^ l))
theorem mem_shortFactorialDigits {F l d : ℕ} :
d ∈ shortFactorialDigits F l ↔ d < 2 ^ l ∧ (d = 0 ∨ d ∣ F.factorial) := by
constructor
· intro h
rcases Finset.mem_insert.mp h with hz | hd
· exact ⟨by rw [hz]; positivity, Or.inl hz⟩
· obtain ⟨hdiv, hlt⟩ := Finset.mem_filter.mp hd
exact ⟨hlt, Or.inr (Nat.dvd_of_mem_divisors hdiv)⟩
· rintro ⟨hlt, hz | hdvd⟩
· exact Finset.mem_insert.mpr (Or.inl hz)
· exact Finset.mem_insert.mpr (Or.inr (Finset.mem_filter.mpr
⟨Nat.mem_divisors.mpr ⟨hdvd, Nat.factorial_ne_zero F⟩, hlt⟩))
theorem shortFactorialDigits_small_integers {F l : ℕ} :
min (F + 1) (2 ^ l) ≤ (shortFactorialDigits F l).card := by
have hsub : Finset.range (min (F + 1) (2 ^ l)) ⊆ shortFactorialDigits F l := by
intro d hd
have hdlt := Finset.mem_range.mp hd
apply mem_shortFactorialDigits.mpr
refine ⟨lt_of_lt_of_le hdlt (min_le_right _ _), ?_⟩
by_cases hz : d = 0
· exact Or.inl hz
· exact Or.inr (Nat.dvd_factorial (by omega)
(by have := min_le_left (F + 1) (2 ^ l); omega))
simpa only [Finset.card_range] using Finset.card_le_card hsub
theorem prime_dvd_prime_product_iff {p : ℕ} (hp : Nat.Prime p)
(s : Finset ℕ) (hs : ∀ q ∈ s, Nat.Prime q) :
p ∣ s.prod id ↔ p ∈ s := by
constructor
· intro h
obtain ⟨q, hq, hpq⟩ := (hp.prime.dvd_finsetProd_iff id).mp h
have heq : q = p := (hs q hq).dvd_iff_eq hp.ne_one |>.mp hpq
exact heq ▸ hq
· exact Finset.dvd_prod_of_mem id
theorem prime_products_injective {s t : Finset ℕ}
(hs : ∀ p ∈ s, Nat.Prime p) (ht : ∀ p ∈ t, Nat.Prime p)
(heq : s.prod id = t.prod id) : s = t := by
apply Finset.Subset.antisymm
· intro p hp
apply (prime_dvd_prime_product_iff (hs p hp) t ht).mp
rw [← heq]
exact Finset.dvd_prod_of_mem id hp
· intro p hp
apply (prime_dvd_prime_product_iff (ht p hp) s hs).mp
rw [heq]
exact Finset.dvd_prod_of_mem id hp
theorem prime_subset_product_dvd_factorial {F : ℕ} {s : Finset ℕ}
(hs : s ⊆ Nat.primesLE F) : s.prod id ∣ F.factorial := by
rw [← Finset.prod_Ico_id_eq_factorial F]
apply Finset.prod_dvd_prod_of_subset s (Finset.Ico 1 (F + 1)) id
intro p hp
obtain ⟨hpF, hprime⟩ := Nat.mem_primesLE.mp (hs hp)
exact Finset.mem_Ico.mpr ⟨by have := hprime.two_le; omega, by omega⟩
theorem shortFactorialDigits_choose_lower {F l v : ℕ} (hheight : F ^ v < 2 ^ l) :
(Nat.primeCounting F).choose v ≤ (shortFactorialDigits F l).card := by
have hmap : Set.MapsTo (fun s : Finset ℕ => s.prod id)
((Nat.primesLE F).powersetCard v) (shortFactorialDigits F l) := by
intro s hs
obtain ⟨hs, hcard⟩ := Finset.mem_powersetCard.mp hs
apply mem_shortFactorialDigits.mpr
refine ⟨?_, Or.inr (prime_subset_product_dvd_factorial hs)⟩
have hprod : s.prod id ≤ F ^ v := by
calc
s.prod id ≤ ∏ _ ∈ s, F := Finset.prod_le_prod' (fun p hp => Nat.le_of_mem_primesLE (hs hp))
_ = F ^ v := by rw [Finset.prod_const, hcard]
exact hprod.trans_lt hheight
have hinj : Set.InjOn (fun s : Finset ℕ => s.prod id) ((Nat.primesLE F).powersetCard v) := by
intro s hs t ht heq
apply prime_products_injective _ _ heq
· intro p hp
exact Nat.prime_of_mem_primesLE ((Finset.mem_powersetCard.mp hs).1 hp)
· intro p hp
exact Nat.prime_of_mem_primesLE ((Finset.mem_powersetCard.mp ht).1 hp)
simpa only [Finset.card_powersetCard, Nat.primesLE_card_eq_primeCounting] using
Finset.card_le_card_of_injOn _ hmap hinj
theorem choose_lower_half_ratio {n v : ℕ} (hv : 0 < v) (hvn : 2 * v ≤ n) :
((n : ℝ) / 2 / (v : ℝ)) ^ v ≤ (n.choose v : ℝ) := by
have hvpos : (0 : ℝ) < v := by exact_mod_cast hv
have hnsub : (n : ℝ) / 2 ≤ ((n + 1 - v : ℕ) : ℝ) := by
rw [Nat.cast_sub (by omega : v ≤ n + 1), Nat.cast_add, Nat.cast_one]
have hh : (2 : ℝ) * v ≤ n := by exact_mod_cast hvn
linarith
have hfac : (v.factorial : ℝ) ≤ (v : ℝ) ^ v := by exact_mod_cast Nat.factorial_le_pow v
calc
((n : ℝ) / 2 / (v : ℝ)) ^ v = ((n : ℝ) / 2) ^ v / (v : ℝ) ^ v := div_pow _ _ _
_ ≤ (((n + 1 - v : ℕ) : ℝ) ^ v) / (v : ℝ) ^ v := by
exact div_le_div_of_nonneg_right (pow_le_pow_left₀ (by positivity) hnsub v) (by positivity)
_ ≤ (((n + 1 - v : ℕ) : ℝ) ^ v) / (v.factorial : ℝ) :=
div_le_div_of_nonneg_left (by positivity) (by positivity) hfac
_ ≤ (n.choose v : ℝ) := Nat.pow_le_choose v n
theorem eventually_primeCounting_ge_rpow {σ : ℝ} (hσ : σ < 1) :
∀ᶠ n : ℕ in Filter.atTop, (n : ℝ) ^ σ ≤ (Nat.primeCounting n : ℝ) := by
have hlogtwo : 0 < Real.log 2 := Real.log_pos (by norm_num)
have hlog := (isLittleO_log_rpow_atTop (sub_pos.mpr hσ)).comp_tendsto
(tendsto_natCast_atTop_atTop (R := ℝ))
obtain ⟨M, hM⟩ := Filter.eventually_atTop.mp
(Real.isLittleO_log_id_atTop.def (by positivity : (0 : ℝ) < Real.log 2 / 4))
filter_upwards [hlog.def (by positivity : (0 : ℝ) < Real.log 2 / 2),
(tendsto_natCast_atTop_atTop (R := ℝ)).eventually_ge_atTop M,
eventually_ge_atTop (2 : ℕ)] with n hn hnM hn2
have hnpos : (0 : ℝ) < n := by exact_mod_cast (show 0 < n by omega)
have hnreal : (2 : ℝ) ≤ n := by exact_mod_cast hn2
have hlogn : Real.log (n : ℝ) ≤ (Real.log 2 / 2) * (n : ℝ) ^ (1 - σ) := by
have hh : |Real.log (n : ℝ)| ≤ (Real.log 2 / 2) * (n : ℝ) ^ (1 - σ) := by
simpa only [Function.comp_apply, Real.norm_eq_abs,
abs_of_nonneg (Real.rpow_nonneg (Nat.cast_nonneg n) (1 - σ))] using hn
exact (le_abs_self _).trans hh
have hlognext : Real.log ((n : ℝ) + 1) ≤ (Real.log 2 / 2) * n := by
have hh := hM ((n : ℝ) + 1) (by linarith)
have hh' : |Real.log ((n : ℝ) + 1)| ≤ (Real.log 2 / 4) * ((n : ℝ) + 1) := by
simpa only [id_eq, Real.norm_eq_abs, abs_of_nonneg (by positivity : (0 : ℝ) ≤ n + 1)] using hh
have hle := (le_abs_self _).trans hh'
nlinarith
have hpi := Chebyshev.pi_ge n
have hlogpos : 0 < Real.log (n : ℝ) := Real.log_pos (by linarith)
have hmain := (div_le_iff₀ hlogpos).mp hpi
apply (mul_le_mul_iff_left₀
(show 0 < (Real.log 2 / 2) * (n : ℝ) ^ (1 - σ) by positivity)).mp
calc
(n : ℝ) ^ σ * ((Real.log 2 / 2) * (n : ℝ) ^ (1 - σ)) = (Real.log 2 / 2) * n := by
rw [mul_comm ((n : ℝ) ^ σ)]
rw [mul_assoc, ← Real.rpow_add hnpos, sub_add_cancel, Real.rpow_one]
_ ≤ (Nat.primeCounting n : ℝ) * Real.log (n : ℝ) := by linarith
_ ≤ (Nat.primeCounting n : ℝ) * ((Real.log 2 / 2) * (n : ℝ) ^ (1 - σ)) :=
mul_le_mul_of_nonneg_left hlogn (Nat.cast_nonneg _)
theorem half_binaryLength_rpow_le {F : ℕ} (hF : 2 ≤ F) :
(2 : ℝ) ^ ((binaryLength F : ℝ) / 2) ≤ (F : ℝ) := by
have hlog : 1 ≤ Nat.log 2 F := Nat.le_log_of_pow_le (by decide) (by simpa using hF)
have hlen : (binaryLength F : ℝ) / 2 ≤ (Nat.log 2 F : ℝ) := by
simp only [binaryLength, Nat.cast_add, Nat.cast_one]
have hh : (1 : ℝ) ≤ Nat.log 2 F := by exact_mod_cast hlog
linarith
calc
(2 : ℝ) ^ ((binaryLength F : ℝ) / 2) ≤ (2 : ℝ) ^ (Nat.log 2 F : ℝ) :=
Real.rpow_le_rpow_of_exponent_le (by norm_num) hlen
_ = ((2 ^ Nat.log 2 F : ℕ) : ℝ) := by simp
_ ≤ (F : ℝ) := by exact_mod_cast Nat.pow_log_le_self 2 (by omega : F ≠ 0)
theorem shortFactorialDigits_uniform_lower {F k : ℕ} {δ : ℝ}
(hF : 2 ≤ F) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hprimes : (2 * (k : ℝ)) * (F : ℝ) ^ δ ≤ (Nat.primeCounting F : ℝ)) :
∀ l : ℕ, 1 ≤ l → l ≤ k →
(2 : ℝ) ^ (δ * (l : ℝ) / 8) ≤ (shortFactorialDigits F l).card := by
intro l hlpos hlk
let a := binaryLength F
have ha : 0 < a := binaryLength_pos F
have hFa : (2 : ℝ) ^ ((a : ℝ) / 2) ≤ (F : ℝ) := half_binaryLength_rpow_le hF
by_cases hsmall : l ≤ 4 * a
· have hsmallreal : (l : ℝ) ≤ 4 * (a : ℝ) := by exact_mod_cast hsmall
have hfirst : (2 : ℝ) ^ (δ * (l : ℝ) / 8) ≤ (F + 1 : ℕ) := by
calc
(2 : ℝ) ^ (δ * (l : ℝ) / 8) ≤ (2 : ℝ) ^ ((a : ℝ) / 2) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith [mul_le_mul_of_nonneg_right hδ1 (Nat.cast_nonneg l : (0 : ℝ) ≤ l)]
_ ≤ (F : ℝ) := hFa
_ ≤ (F + 1 : ℕ) := by exact_mod_cast Nat.le_succ F
have hsecond : (2 : ℝ) ^ (δ * (l : ℝ) / 8) ≤ ((2 ^ l : ℕ) : ℝ) := by
rw [Nat.cast_pow, Nat.cast_ofNat, ← Real.rpow_natCast]
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith [mul_le_mul_of_nonneg_right hδ1 (Nat.cast_nonneg l : (0 : ℝ) ≤ l)]
have hmin : (2 : ℝ) ^ (δ * (l : ℝ) / 8) ≤ (min (F + 1) (2 ^ l) : ℕ) := by
rw [Nat.cast_min]
exact le_min hfirst hsecond
exact hmin.trans (by exact_mod_cast shortFactorialDigits_small_integers (F := F) (l := l))
· let v := l / (2 * a)
have hvpos : 0 < v := Nat.div_pos (by omega) (by omega)
have hvle : v ≤ k := (Nat.div_le_self l (2 * a)).trans hlk
have hmul : 2 * a * v ≤ l := Nat.mul_div_le l (2 * a)
have hupper : l < 2 * a * (v + 1) := Nat.lt_mul_div_succ l (by omega)
have halower : l ≤ 4 * a * v := by nlinarith
have hheight : F ^ v < 2 ^ l := by
calc
F ^ v ≤ (2 ^ a) ^ v := Nat.pow_le_pow_left
(Nat.lt_pow_succ_log_self (by decide : 1 < 2) F).le v
_ = 2 ^ (a * v) := (pow_mul _ _ _).symm
_ < 2 ^ l := Nat.pow_lt_pow_right (by decide : 1 < 2) (by nlinarith)
have hFpow : 1 ≤ (F : ℝ) ^ δ := Real.one_le_rpow (by exact_mod_cast (show 1 ≤ F by omega)) hδ.le
have htwov : 2 * v ≤ Nat.primeCounting F := by
have hkr : (v : ℝ) ≤ k := by exact_mod_cast hvle
have hk0 : (0 : ℝ) ≤ k := Nat.cast_nonneg k
have hreal : 2 * (v : ℝ) ≤ (Nat.primeCounting F : ℝ) := by nlinarith
exact_mod_cast hreal
have hratio : (F : ℝ) ^ δ ≤ (Nat.primeCounting F : ℝ) / 2 / (v : ℝ) := by
apply (le_div_iff₀ (by exact_mod_cast hvpos : (0 : ℝ) < v)).mpr
apply (le_div_iff₀ (by norm_num : (0 : ℝ) < 2)).mpr
have hkr : (v : ℝ) ≤ k := by exact_mod_cast hvle
have hF0 : 0 ≤ (F : ℝ) ^ δ := by positivity
nlinarith [mul_le_mul_of_nonneg_right hkr hF0]
have halowerreal : (l : ℝ) ≤ 4 * (a : ℝ) * (v : ℝ) := by exact_mod_cast halower
calc
(2 : ℝ) ^ (δ * (l : ℝ) / 8) ≤ (2 : ℝ) ^ (((a : ℝ) / 2 * δ) * (v : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith [mul_le_mul_of_nonneg_left halowerreal hδ.le]
_ = (((2 : ℝ) ^ ((a : ℝ) / 2)) ^ δ) ^ v := by
rw [Real.rpow_mul_natCast (by norm_num), Real.rpow_mul (by norm_num)]
_ ≤ ((F : ℝ) ^ δ) ^ v :=
pow_le_pow_left₀ (by positivity) (Real.rpow_le_rpow (by positivity) hFa hδ.le) v
_ ≤ ((Nat.primeCounting F : ℝ) / 2 / (v : ℝ)) ^ v :=
pow_le_pow_left₀ (by positivity) hratio v
_ ≤ ((Nat.primeCounting F).choose v : ℝ) := choose_lower_half_ratio hvpos htwov
_ ≤ (shortFactorialDigits F l).card := by exact_mod_cast shortFactorialDigits_choose_lower hheight
noncomputable def factorialDigitHost (a : ℝ) (k : ℕ) : ℕ := ⌈(k : ℝ) ^ a⌉₊
theorem factorialDigitHost_tendsto {a : ℝ} (ha : 0 < a) :
Filter.Tendsto (factorialDigitHost a) Filter.atTop Filter.atTop := by
have hp := (tendsto_rpow_atTop ha).comp (tendsto_natCast_atTop_atTop (R := ℝ))
apply Filter.tendsto_atTop.mpr
intro M
filter_upwards [hp.eventually_ge_atTop (M : ℝ)] with k hk
have hh : (M : ℝ) ≤ (k : ℝ) ^ a := hk
exact_mod_cast hh.trans (Nat.le_ceil _)
theorem factorialDigitHost_le {a : ℝ} {k : ℕ} (ha : 0 ≤ a) (hk : 1 ≤ k) :
(factorialDigitHost a k : ℝ) ≤ 2 * (k : ℝ) ^ a := by
have hone : 1 ≤ (k : ℝ) ^ a := Real.one_le_rpow (by exact_mod_cast hk) ha
have hceil := Nat.ceil_lt_add_one (Real.rpow_nonneg (Nat.cast_nonneg k) a)
change (⌈(k : ℝ) ^ a⌉₊ : ℝ) ≤ _
linarith
theorem shortFactorialDigits_uniform_asymptotic {a : ℝ} (ha : 1 < a) :
∃ c : ℝ, 0 < c ∧ ∀ᶠ k : ℕ in Filter.atTop,
(factorialDigitHost a k : ℝ) ≤ 2 * (k : ℝ) ^ a ∧
∀ l : ℕ, 1 ≤ l → l ≤ k →
(2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits (factorialDigitHost a k) l).card := by
let δ : ℝ := (a - 1) / (4 * a)
let σ : ℝ := 1 - δ
have hapos : 0 < a := by linarith
have hδ : 0 < δ := div_pos (by linarith) (by positivity)
have hδquarter : δ ≤ 1 / 4 := by
dsimp [δ]
apply (div_le_iff₀ (by positivity : (0 : ℝ) < 4 * a)).mpr
linarith
have hδeq : 4 * a * δ = a - 1 := by
dsimp [δ]
field_simp
have hσ : σ < 1 := by dsimp [σ]; linarith
have hgap : 0 < σ - δ := by dsimp [σ]; linarith
have hexponent : 1 < a * (σ - δ) := by
dsimp [σ]
nlinarith
have hhost := factorialDigitHost_tendsto hapos
have hprime := hhost.eventually (eventually_primeCounting_ge_rpow hσ)
have hpower := eventually_const_mul_rpow_le (C := 2) (E := 1) hexponent (by norm_num)
refine ⟨δ / 8, by positivity, ?_⟩
filter_upwards [hprime, hpower, hhost.eventually_ge_atTop 2, eventually_ge_atTop (1 : ℕ)]
with k hkprime hkpower hkhost hkone
refine ⟨factorialDigitHost_le hapos.le hkone, ?_⟩
have hFpos : (0 : ℝ) < factorialDigitHost a k := by exact_mod_cast (show 0 < factorialDigitHost a k by omega)
have h2k : 2 * (k : ℝ) ≤ (factorialDigitHost a k : ℝ) ^ (σ - δ) := by
calc
2 * (k : ℝ) ≤ (k : ℝ) ^ (a * (σ - δ)) := by
simpa only [Real.rpow_one, one_mul] using hkpower
_ = ((k : ℝ) ^ a) ^ (σ - δ) := Real.rpow_mul (Nat.cast_nonneg k) _ _
_ ≤ (factorialDigitHost a k : ℝ) ^ (σ - δ) :=
Real.rpow_le_rpow (by positivity) (Nat.le_ceil _) hgap.le
have hprimes : (2 * (k : ℝ)) * (factorialDigitHost a k : ℝ) ^ δ ≤
(Nat.primeCounting (factorialDigitHost a k) : ℝ) := by
calc
_ ≤ (factorialDigitHost a k : ℝ) ^ (σ - δ) * (factorialDigitHost a k : ℝ) ^ δ :=
mul_le_mul_of_nonneg_right h2k (by positivity)
_ = (factorialDigitHost a k : ℝ) ^ σ := by rw [← Real.rpow_add hFpos, sub_add_cancel]
_ ≤ _ := hkprime
intro l hl hlk
have hh := shortFactorialDigits_uniform_lower hkhost hδ (by linarith : δ ≤ 1) hprimes l hl hlk
convert hh using 1
congr 1
ring
def binaryAppend (A D : Finset ℕ) (b : ℕ) : Finset ℕ :=
(A ×ˢ D).image (fun p => p.1 + 2 ^ b * p.2)
def natResidueFiber (A : Finset ℕ) (q r : ℕ) : Finset ℕ :=
A.filter (fun x => Nat.ModEq q x r)
noncomputable def natResidueMass (A : Finset ℕ) (q r : ℕ) : ℝ :=
((natResidueFiber A q r).card : ℝ) / (A.card : ℝ)
theorem binary_append_injective {A D : Finset ℕ} {b : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) :
Set.InjOn (fun p : ℕ × ℕ => p.1 + 2 ^ b * p.2) (A ×ˢ D : Finset (ℕ × ℕ)) := by
intro p hp s hs heq
change p.1 + 2 ^ b * p.2 = s.1 + 2 ^ b * s.2 at heq
have hpA := hA p.1 (Finset.mem_product.mp hp).1
have hsA := hA s.1 (Finset.mem_product.mp hs).1
have hmod := congrArg (fun n => n % (2 ^ b)) heq
simp only [Nat.add_mul_mod_self_left, Nat.mod_eq_of_lt hpA, Nat.mod_eq_of_lt hsA] at hmod
have hmul : 2 ^ b * p.2 = 2 ^ b * s.2 := by omega
have hright := Nat.eq_of_mul_eq_mul_left (by positivity : 0 < 2 ^ b) hmul
exact Prod.ext hmod hright
theorem binary_append_card {A D : Finset ℕ} {b : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) : (binaryAppend A D b).card = A.card * D.card := by
rw [binaryAppend, Finset.card_image_of_injOn (binary_append_injective hA), Finset.card_product]
theorem binary_append_nonempty {A D : Finset ℕ} {b : ℕ}
(hA : A.Nonempty) (hD : D.Nonempty) : (binaryAppend A D b).Nonempty := by
exact (hA.product hD).image _
theorem binary_append_lt {A D : Finset ℕ} {b l : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) (hD : ∀ d ∈ D, d < 2 ^ l) :
∀ x ∈ binaryAppend A D b, x < 2 ^ (b + l) := by
intro x hx
obtain ⟨⟨a, d⟩, had, rfl⟩ := Finset.mem_image.mp hx
have ha := hA a (Finset.mem_product.mp had).1
have hd := hD d (Finset.mem_product.mp had).2
rw [pow_add]
nlinarith [mul_le_mul_of_nonneg_left (show d + 1 ≤ 2 ^ l by omega) (Nat.zero_le (2 ^ b))]
theorem nat_residue_fiber_mono_modulus {A : Finset ℕ} {q Q r : ℕ} (hq : q ∣ Q) :
natResidueFiber A Q r ⊆ natResidueFiber A q r := by
intro x hx
obtain ⟨hx, hmod⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨hx, hmod.of_dvd hq⟩
theorem nat_residue_fiber_card_le_one {A : Finset ℕ} {q r : ℕ}
(hA : ∀ x ∈ A, x < q) : (natResidueFiber A q r).card ≤ 1 := by
apply Finset.card_le_one.mpr
intro x hx y hy
obtain ⟨hxA, hxmod⟩ := Finset.mem_filter.mp hx
obtain ⟨hyA, hymod⟩ := Finset.mem_filter.mp hy
have hxy := hxmod.trans hymod.symm
simpa only [Nat.ModEq, Nat.mod_eq_of_lt (hA x hxA), Nat.mod_eq_of_lt (hA y hyA)] using hxy
theorem binary_append_residue_fiber {A D : Finset ℕ} {b q r : ℕ} (hq : q ∣ 2 ^ b) :
natResidueFiber (binaryAppend A D b) q r = binaryAppend (natResidueFiber A q r) D b := by
have hequiv (a d : ℕ) : Nat.ModEq q (a + 2 ^ b * d) r ↔ Nat.ModEq q a r := by
have hh : Nat.ModEq q (a + 2 ^ b * d) a := by
simpa only [add_zero] using (Nat.ModEq.refl a).add ((hq.trans (dvd_mul_right _ _)).modEq_zero_nat)
exact ⟨fun h => hh.symm.trans h, fun h => hh.trans h⟩
ext x
constructor
· intro hx
obtain ⟨hx, hm⟩ := Finset.mem_filter.mp hx
obtain ⟨⟨a, d⟩, had, rfl⟩ := Finset.mem_image.mp hx
exact Finset.mem_image.mpr ⟨(a, d), Finset.mem_product.mpr
⟨Finset.mem_filter.mpr ⟨(Finset.mem_product.mp had).1, (hequiv a d).mp hm⟩,
(Finset.mem_product.mp had).2⟩, rfl⟩
· intro hx
obtain ⟨⟨a, d⟩, had, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨ha, hd⟩ := Finset.mem_product.mp had
obtain ⟨ha, hm⟩ := Finset.mem_filter.mp ha
exact Finset.mem_filter.mpr ⟨Finset.mem_image.mpr ⟨(a, d), Finset.mem_product.mpr ⟨ha, hd⟩, rfl⟩,
(hequiv a d).mpr hm⟩
theorem binary_append_residue_fiber_card {A D : Finset ℕ} {b q r : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) (hq : q ∣ 2 ^ b) :
(natResidueFiber (binaryAppend A D b) q r).card = (natResidueFiber A q r).card * D.card := by
rw [binary_append_residue_fiber hq]
exact binary_append_card (fun x hx => hA x (Finset.mem_filter.mp hx).1)
theorem binary_append_residue_mass {A D : Finset ℕ} {b q r : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) (hD : D.Nonempty) (hq : q ∣ 2 ^ b) :
natResidueMass (binaryAppend A D b) q r = natResidueMass A q r := by
have hDc : (D.card : ℝ) ≠ 0 := by exact_mod_cast Finset.card_ne_zero.mpr hD
unfold natResidueMass
rw [binary_append_residue_fiber_card hA hq, binary_append_card hA, Nat.cast_mul, Nat.cast_mul]
exact mul_div_mul_right _ _ hDc
theorem binary_append_residue_mass_high {A D : Finset ℕ} {b j r : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) (hne : A.Nonempty) (hD : D.Nonempty) (hj : b ≤ j) :
natResidueMass (binaryAppend A D b) (2 ^ j) r ≤ 1 / (A.card : ℝ) := by
have hAc : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hne
calc
natResidueMass (binaryAppend A D b) (2 ^ j) r ≤
natResidueMass (binaryAppend A D b) (2 ^ b) r := by
apply div_le_div_of_nonneg_right _ (Nat.cast_nonneg _)
exact_mod_cast Finset.card_le_card (nat_residue_fiber_mono_modulus (pow_dvd_pow 2 hj))
_ = natResidueMass A (2 ^ b) r := binary_append_residue_mass hA hD (dvd_refl _)
_ ≤ 1 / (A.card : ℝ) := by
apply div_le_div_of_nonneg_right _ hAc.le
exact_mod_cast nat_residue_fiber_card_le_one hA
theorem nat_residue_fiber_range_card_le {q N r : ℕ} (hq : 0 < q) :
(natResidueFiber (Finset.range (q * N)) q r).card ≤ N := by
have hmap : Set.MapsTo (fun x : ℕ => x / q)
(natResidueFiber (Finset.range (q * N)) q r) (Finset.range N) := by
intro x hx
have hxlt := Finset.mem_range.mp (Finset.mem_filter.mp hx).1
exact Finset.mem_range.mpr ((Nat.div_lt_iff_lt_mul hq).mpr (by simpa only [mul_comm] using hxlt))
have hinj : Set.InjOn (fun x : ℕ => x / q)
(natResidueFiber (Finset.range (q * N)) q r) := by
intro x hx y hy heq
change x / q = y / q at heq
have hmod := (Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm
change x % q = y % q at hmod
have hxdiv := Nat.mod_add_div x q
have hydiv := Nat.mod_add_div y q
rw [heq, hmod] at hxdiv
omega
simpa only [Finset.card_range] using Finset.card_le_card_of_injOn _ hmap hinj
theorem nat_residue_fiber_bounded_card_le {A : Finset ℕ} {b j r : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) (hj : j ≤ b) :
(natResidueFiber A (2 ^ j) r).card ≤ 2 ^ (b - j) := by
have hpow : 2 ^ b = 2 ^ j * 2 ^ (b - j) := by rw [← pow_add, Nat.add_sub_of_le hj]
have hsub : natResidueFiber A (2 ^ j) r ⊆ natResidueFiber (Finset.range (2 ^ b)) (2 ^ j) r := by
intro x hx
obtain ⟨hxA, hmod⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨Finset.mem_range.mpr (hA x hxA), hmod⟩
refine (Finset.card_le_card hsub).trans ?_
rw [hpow]
exact nat_residue_fiber_range_card_le (by positivity)
def initialOddDigits (b : ℕ) : Finset ℕ :=
(Finset.range (2 ^ (b - 1))).image (fun i => 2 * i + 1)
theorem initial_odd_digits_card (b : ℕ) : (initialOddDigits b).card = 2 ^ (b - 1) := by
rw [initialOddDigits, Finset.card_image_of_injective]
· exact Finset.card_range _
· intro x y h
change 2 * x + 1 = 2 * y + 1 at h
omega
theorem initial_odd_digits_nonempty (b : ℕ) : (initialOddDigits b).Nonempty := by
apply Finset.card_pos.mp
rw [initial_odd_digits_card]
positivity
theorem initial_odd_digits_lt {b : ℕ} (hb : 0 < b) :
∀ x ∈ initialOddDigits b, x < 2 ^ b := by
intro x hx
obtain ⟨i, hi, rfl⟩ := Finset.mem_image.mp hx
have hi := Finset.mem_range.mp hi
have hp : 2 ^ b = 2 * 2 ^ (b - 1) := by rw [← pow_succ', Nat.sub_add_cancel hb]
rw [hp]
omega
theorem initial_odd_digits_odd {b x : ℕ} (hx : x ∈ initialOddDigits b) : Odd x := by
obtain ⟨i, _, rfl⟩ := Finset.mem_image.mp hx
exact ⟨i, by ring⟩
theorem initial_odd_digits_entropy {b : ℕ} {c : ℝ} (hb : 2 ≤ b) (hc : c ≤ 1 / 2) :
(2 : ℝ) ^ (c * (b : ℝ)) ≤ (initialOddDigits b).card := by
rw [initial_odd_digits_card, Nat.cast_pow, Nat.cast_ofNat, ← Real.rpow_natCast]
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
rw [Nat.cast_sub (by omega : 1 ≤ b), Nat.cast_one]
have hbr : (2 : ℝ) ≤ b := by exact_mod_cast hb
nlinarith [mul_le_mul_of_nonneg_right hc (Nat.cast_nonneg b : (0 : ℝ) ≤ b)]
theorem initial_odd_digits_spread {b j r : ℕ} {c : ℝ}
(hb : 2 ≤ b) (hj : 2 ≤ j) (hjb : j ≤ b) (hc : c ≤ 1) :
natResidueMass (initialOddDigits b) (2 ^ j) r ≤ (2 : ℝ) ^ (-(c / 2) * (j : ℝ)) := by
have hcard := nat_residue_fiber_bounded_card_le (r := r)
(initial_odd_digits_lt (by omega : 0 < b)) hjb
unfold natResidueMass
rw [initial_odd_digits_card]
calc
((natResidueFiber (initialOddDigits b) (2 ^ j) r).card : ℝ) / ((2 ^ (b - 1) : ℕ) : ℝ) ≤
((2 ^ (b - j) : ℕ) : ℝ) / ((2 ^ (b - 1) : ℕ) : ℝ) := by
apply div_le_div_of_nonneg_right _ (by positivity)
exact_mod_cast hcard
_ = (2 : ℝ) ^ (1 - (j : ℝ)) := by
simp only [Nat.cast_pow, Nat.cast_ofNat, ← Real.rpow_natCast,
← Real.rpow_sub (by norm_num : (0 : ℝ) < 2), Nat.cast_sub hjb,
Nat.cast_sub (by omega : 1 ≤ b), Nat.cast_one]
congr 1
ring
_ ≤ (2 : ℝ) ^ (-(c / 2) * (j : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hjr : (2 : ℝ) ≤ j := by exact_mod_cast hj
nlinarith [mul_le_mul_of_nonneg_right hc (Nat.cast_nonneg j : (0 : ℝ) ≤ j)]
theorem binary_append_entropy {A D : Finset ℕ} {b l : ℕ} {c : ℝ}
(hA : ∀ x ∈ A, x < 2 ^ b)
(hcA : (2 : ℝ) ^ (c * (b : ℝ)) ≤ A.card)
(hcD : (2 : ℝ) ^ (c * (l : ℝ)) ≤ D.card) :
(2 : ℝ) ^ (c * ((b + l : ℕ) : ℝ)) ≤ (binaryAppend A D b).card := by
rw [binary_append_card hA, Nat.cast_mul, Nat.cast_add, mul_add, Real.rpow_add (by norm_num)]
exact mul_le_mul hcA hcD (by positivity) (Nat.cast_nonneg _)
theorem binary_append_spread {A D : Finset ℕ} {b l : ℕ} {c : ℝ}
(hA : ∀ x ∈ A, x < 2 ^ b) (hne : A.Nonempty) (hD : D.Nonempty)
(hl : l ≤ b) (hc : 0 ≤ c)
(hcA : (2 : ℝ) ^ (c * (b : ℝ)) ≤ A.card)
(hspread : ∀ j : ℕ, 2 ≤ j → j ≤ b → ∀ r : ℕ,
natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-(c / 2) * (j : ℝ))) :
∀ j : ℕ, 2 ≤ j → j ≤ b + l → ∀ r : ℕ,
natResidueMass (binaryAppend A D b) (2 ^ j) r ≤ (2 : ℝ) ^ (-(c / 2) * (j : ℝ)) := by
intro j hj hjbl r
by_cases hjb : j ≤ b
· rw [binary_append_residue_mass hA hD (pow_dvd_pow 2 hjb)]
exact hspread j hj hjb r
· calc
natResidueMass (binaryAppend A D b) (2 ^ j) r ≤ 1 / (A.card : ℝ) :=
binary_append_residue_mass_high hA hne hD (by omega)
_ ≤ 1 / (2 : ℝ) ^ (c * (b : ℝ)) :=
one_div_le_one_div_of_le (by positivity) hcA
_ = (2 : ℝ) ^ (-(c * (b : ℝ))) := by rw [Real.rpow_neg (by norm_num), one_div]
_ ≤ (2 : ℝ) ^ (-(c / 2) * (j : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hltwo : (j : ℝ) ≤ 2 * (b : ℝ) := by exact_mod_cast (show j ≤ 2 * b by omega)
nlinarith [mul_le_mul_of_nonneg_left hltwo hc]
theorem short_factorial_digits_nonempty (F l : ℕ) : (shortFactorialDigits F l).Nonempty := by
exact ⟨0, Finset.mem_insert_self _ _⟩
theorem short_factorial_digits_entropy {F K : ℕ} {c : ℝ}
(h : ∀ l : ℕ, 1 ≤ l → l ≤ K → (2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits F l).card)
{l : ℕ} (hl : l ≤ K) : (2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits F l).card := by
by_cases hz : l = 0
· subst l
simp only [Nat.cast_zero, mul_zero, Real.rpow_zero]
exact_mod_cast Finset.card_pos.mpr (short_factorial_digits_nonempty F 0)
· exact h l (by omega) hl
theorem binary_append_odd {A D : Finset ℕ} {b : ℕ} (hb : 0 < b)
(hA : ∀ x ∈ A, Odd x) : ∀ x ∈ binaryAppend A D b, Odd x := by
intro x hx
obtain ⟨⟨a, d⟩, had, rfl⟩ := Finset.mem_image.mp hx
exact (hA a (Finset.mem_product.mp had).1).add_even
((even_two.pow_of_ne_zero (Nat.ne_of_gt hb)).mul_right d)
theorem binary_append_representations {A : Finset ℕ} {F K b l u : ℕ} (hb : b ≤ K)
(hA : ∀ x ∈ A, HasFactorialDivisorMultiset (F + 2 * K) x u) :
∀ x ∈ binaryAppend A (shortFactorialDigits F l) b,
HasFactorialDivisorMultiset (F + 2 * K) x (u + 1) := by
intro x hx
obtain ⟨⟨a, d⟩, had, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨ha, hd⟩ := Finset.mem_product.mp had
apply factorial_multiset_add (hA a ha)
rcases (mem_shortFactorialDigits.mp hd).2 with hz | hdiv
· rw [hz, mul_zero]
exact factorial_multiset_zero _ _
· exact factorial_multiset_singleton (shifted_divisor_dvd_factorial hdiv hb)
structure BinaryBlockProfile (F K b u : ℕ) (c : ℝ) (A : Finset ℕ) : Prop where
nonempty : A.Nonempty
bounded : ∀ x ∈ A, x < 2 ^ b
odd : ∀ x ∈ A, Odd x
representatives : ∀ x ∈ A, HasFactorialDivisorMultiset (F + 2 * K) x u
entropy : (2 : ℝ) ^ (c * (b : ℝ)) ≤ A.card
spread : ∀ j : ℕ, 2 ≤ j → j ≤ b → ∀ r : ℕ,
natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-(c / 2) * (j : ℝ))
theorem initial_odd_digits_profile {F K b : ℕ} {c : ℝ}
(hb : 2 ≤ b) (hF : 2 ^ b ≤ F) (hc : c ≤ 1 / 2) :
BinaryBlockProfile F K b 1 c (initialOddDigits b) := by
refine ⟨initial_odd_digits_nonempty b, initial_odd_digits_lt (by omega),
fun _ hx => initial_odd_digits_odd hx, ?_, initial_odd_digits_entropy hb hc, ?_⟩
· intro x hx
have hodd := initial_odd_digits_odd hx
have hpos : 0 < x := by obtain ⟨t, ht⟩ := hodd; omega
exact factorial_multiset_singleton (Nat.dvd_factorial hpos
(by have := initial_odd_digits_lt (by omega : 0 < b) x hx; omega))
· intro j hj hjb r
exact initial_odd_digits_spread hb hj hjb (by linarith)
theorem binary_append_profile {F K b l u : ℕ} {c : ℝ} {A : Finset ℕ}
(hA : BinaryBlockProfile F K b u c A) (hb : 0 < b) (hbK : b ≤ K) (hl : l ≤ b) (hc : 0 ≤ c)
(hD : (2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits F l).card) :
BinaryBlockProfile F K (b + l) (u + 1) c (binaryAppend A (shortFactorialDigits F l) b) := by
refine ⟨binary_append_nonempty hA.nonempty (short_factorial_digits_nonempty F l),
binary_append_lt hA.bounded (fun _ hd => (mem_shortFactorialDigits.mp hd).1),
binary_append_odd hb hA.odd, binary_append_representations hbK hA.representatives,
binary_append_entropy hA.bounded hA.entropy hD, ?_⟩
exact binary_append_spread hA.bounded hA.nonempty (short_factorial_digits_nonempty F l)
hl hc hA.entropy hA.spread
def binaryBlockEndpoint (K b₀ i : ℕ) : ℕ := min K (2 ^ i * b₀)
def binaryBlockWidth (K b₀ i : ℕ) : ℕ := binaryBlockEndpoint K b₀ (i + 1) - binaryBlockEndpoint K b₀ i
def binaryBlockSet (F K b₀ : ℕ) : ℕ → Finset ℕ
| 0 => initialOddDigits b₀
| i + 1 => binaryAppend (binaryBlockSet F K b₀ i)
(shortFactorialDigits F (binaryBlockWidth K b₀ i)) (binaryBlockEndpoint K b₀ i)
theorem binary_block_endpoint_zero {K b₀ : ℕ} (hb : b₀ ≤ K) : binaryBlockEndpoint K b₀ 0 = b₀ := by
simp only [binaryBlockEndpoint, pow_zero, one_mul, min_eq_right hb]
theorem binary_block_endpoint_bounds {K b₀ : ℕ} (hb : b₀ ≤ K) (i : ℕ) :
b₀ ≤ binaryBlockEndpoint K b₀ i ∧ binaryBlockEndpoint K b₀ i ≤ K := by
refine ⟨le_min hb ?_, min_le_left _ _⟩
nlinarith [show 1 ≤ 2 ^ i from Nat.one_le_two_pow]
theorem binary_block_endpoint_mono (K b₀ i : ℕ) :
binaryBlockEndpoint K b₀ i ≤ binaryBlockEndpoint K b₀ (i + 1) := by
apply min_le_min_left
exact Nat.mul_le_mul_right b₀ (Nat.pow_le_pow_right (by decide : 0 < 2) (by omega))
theorem binary_block_endpoint_succ_le_twice (K b₀ i : ℕ) :
binaryBlockEndpoint K b₀ (i + 1) ≤ 2 * binaryBlockEndpoint K b₀ i := by
unfold binaryBlockEndpoint
by_cases h : 2 ^ i * b₀ ≤ K
· rw [min_eq_right h]
calc
min K (2 ^ (i + 1) * b₀) ≤ 2 ^ (i + 1) * b₀ := min_le_right _ _
_ = 2 * (2 ^ i * b₀) := by rw [pow_succ]; ring
· rw [min_eq_left (by omega : K ≤ 2 ^ i * b₀)]
exact (min_le_left _ _).trans (by omega)
theorem binary_block_width_add (K b₀ i : ℕ) :
binaryBlockEndpoint K b₀ i + binaryBlockWidth K b₀ i = binaryBlockEndpoint K b₀ (i + 1) := by
exact Nat.add_sub_of_le (binary_block_endpoint_mono K b₀ i)
theorem binary_block_width_le (K b₀ i : ℕ) :
binaryBlockWidth K b₀ i ≤ binaryBlockEndpoint K b₀ i := by
have := binary_block_endpoint_succ_le_twice K b₀ i
unfold binaryBlockWidth
omega
theorem binary_block_endpoint_top {K b₀ : ℕ} (hb : 1 ≤ b₀) :
binaryBlockEndpoint K b₀ (binaryLength K) = K := by
apply min_eq_left
have hK : K < 2 ^ binaryLength K := Nat.lt_pow_succ_log_self (by decide : 1 < 2) K
nlinarith
theorem binary_block_set_profile {F K b₀ : ℕ} {c : ℝ}
(hb : 2 ≤ b₀) (hbK : b₀ ≤ K) (hF : 2 ^ b₀ ≤ F) (hc : 0 ≤ c) (hcsmall : c ≤ 1 / 2)
(hD : ∀ l : ℕ, 1 ≤ l → l ≤ K → (2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits F l).card) :
∀ i : ℕ, BinaryBlockProfile F K (binaryBlockEndpoint K b₀ i) (i + 1) c (binaryBlockSet F K b₀ i) := by
intro i
induction i with
| zero =>
rw [binary_block_endpoint_zero hbK]
exact initial_odd_digits_profile hb hF hcsmall
| succ i ih =>
have hbds := binary_block_endpoint_bounds hbK i
have hw := binary_block_width_le K b₀ i
have hstep := binary_append_profile ih (by omega) hbds.2 hw hc
(short_factorial_digits_entropy hD (hw.trans hbds.2))
rw [binary_block_width_add] at hstep
exact hstep
theorem binary_block_set_profile_top {F K b₀ : ℕ} {c : ℝ}
(hb : 2 ≤ b₀) (hbK : b₀ ≤ K) (hF : 2 ^ b₀ ≤ F) (hc : 0 ≤ c) (hcsmall : c ≤ 1 / 2)
(hD : ∀ l : ℕ, 1 ≤ l → l ≤ K → (2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits F l).card) :
BinaryBlockProfile F K K (binaryLength K + 1) c (binaryBlockSet F K b₀ (binaryLength K)) := by
have h := binary_block_set_profile hb hbK hF hc hcsmall hD (binaryLength K)
rwa [binary_block_endpoint_top (by omega : 1 ≤ b₀)] at h
noncomputable def cyclicUniformNatSet {q : ℕ} [NeZero q] (A : Finset ℕ) : ZMod q → ℂ :=
cyclicPushforward (fun _ : A => (A.card : ℂ)⁻¹) (fun n => (n.val : ZMod q))
theorem dft_cyclicUniformNatSet {q : ℕ} [NeZero q] (A : Finset ℕ) (k : ZMod q) :
ZMod.dft (cyclicUniformNatSet A) k =
(∑ n ∈ A, ZMod.stdAddChar (-((n : ZMod q) * k))) * (A.card : ℂ)⁻¹ := by
rw [cyclicUniformNatSet, dft_cyclicPushforward, ← Finset.sum_mul]
congr 1
exact Finset.sum_coe_sort A (fun n => ZMod.stdAddChar (-((n : ZMod q) * k)))
theorem dft_cyclicUniformNatSet_at_zero {q : ℕ} [NeZero q] {A : Finset ℕ} (hA : A.Nonempty) :
ZMod.dft (cyclicUniformNatSet (q := q) A) 0 = 1 := by
rw [dft_cyclicUniformNatSet]
have hcard : (A.card : ℂ) ≠ 0 := by exact_mod_cast Finset.card_ne_zero.mpr hA
simp [hcard]
theorem cyclicUniformNatSet_support {q : ℕ} [NeZero q] (A : Finset ℕ) {x : ZMod q}
(hx : cyclicUniformNatSet A x ≠ 0) : ∃ n ∈ A, (n : ZMod q) = x := by
obtain ⟨n, hn, _⟩ := cyclicPushforward_support (fun _ : A => (A.card : ℂ)⁻¹)
(fun n => (n.val : ZMod q)) hx
exact ⟨n.val, n.property, hn⟩
theorem dft_binary_append {q b : ℕ} [NeZero q] {A D : Finset ℕ}
(hA : ∀ x ∈ A, x < 2 ^ b) (k : ZMod q) :
ZMod.dft (cyclicUniformNatSet (binaryAppend A D b)) k =
ZMod.dft (cyclicUniformNatSet A) k *
((∑ d ∈ D, ZMod.stdAddChar (-(((2 ^ b * d : ℕ) : ZMod q) * k))) * (D.card : ℂ)⁻¹) := by
classical
rw [dft_cyclicUniformNatSet, binary_append_card hA, Nat.cast_mul, mul_inv_rev,
dft_cyclicUniformNatSet]
unfold binaryAppend
rw [Finset.sum_image (binary_append_injective hA), Finset.sum_product]
have hchar (a d : ℕ) : ZMod.stdAddChar (-(((a + 2 ^ b * d : ℕ) : ZMod q) * k)) =
ZMod.stdAddChar (-((a : ZMod q) * k)) * ZMod.stdAddChar (-(((2 ^ b * d : ℕ) : ZMod q) * k)) := by
rw [← AddChar.map_add_eq_mul]
congr 1
push_cast
ring
simp_rw [hchar, ← Finset.mul_sum, ← Finset.sum_mul]
ring
theorem dft_initialOddDigits {K b : ℕ} (k : ZMod (2 ^ K)) :
ZMod.dft (cyclicUniformNatSet (initialOddDigits b)) k = ZMod.dft (cyclicOddDigit b) k := by
rw [dft_cyclicUniformNatSet, initial_odd_digits_card, cyclicOddDigit, dft_cyclicPushforward,
← Finset.sum_mul]
congr 1
unfold initialOddDigits
rw [Finset.sum_image (by intro x hx y hy h; change 2 * x + 1 = 2 * y + 1 at h; omega)]
exact (Fin.sum_univ_eq_sum_range
(fun i : ℕ => ZMod.stdAddChar (-(((2 * i + 1 : ℕ) : ZMod (2 ^ K)) * k))) _).symm
theorem dft_binary_block_set_low {F K b₀ : ℕ} {c : ℝ}
(hb : 2 ≤ b₀) (hbK : b₀ ≤ K) (hF : 2 ^ b₀ ≤ F) (hc : 0 ≤ c) (hcsmall : c ≤ 1 / 2)
(hD : ∀ l : ℕ, 1 ≤ l → l ≤ K → (2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits F l).card)
{k : ZMod (2 ^ K)} (hklo : 2 ≤ dyadicConductorLevel k) (hkhi : dyadicConductorLevel k ≤ b₀) :
∀ i : ℕ, ZMod.dft (cyclicUniformNatSet (binaryBlockSet F K b₀ i)) k = 0 := by
intro i
induction i with
| zero =>
rw [binaryBlockSet, dft_initialOddDigits]
exact dft_cyclicOddDigit_zero hklo hkhi
| succ i ih =>
rw [binaryBlockSet, dft_binary_append (binary_block_set_profile hb hbK hF hc hcsmall hD i).bounded,
ih, zero_mul]
theorem cyclicUniformNatSet_eq_residue_mass {q : ℕ} [NeZero q] (A : Finset ℕ) (x : ZMod q) :
cyclicUniformNatSet A x = (natResidueMass A q x.val : ℂ) := by
classical
have hpred (n : ℕ) : ((n : ZMod q) = x) ↔ Nat.ModEq q n x.val := by
simpa only [ZMod.natCast_zmod_val] using (ZMod.natCast_eq_natCast_iff n x.val q)
unfold cyclicUniformNatSet cyclicPushforward
rw [Finset.sum_coe_sort A (fun n => if (n : ZMod q) = x then (A.card : ℂ)⁻¹ else 0)]
simp_rw [hpred]
rw [← Finset.sum_filter]
simp [natResidueMass, natResidueFiber, div_eq_mul_inv]
theorem norm_cyclicUniformNatSet {q : ℕ} [NeZero q] (A : Finset ℕ) (x : ZMod q) :
‖cyclicUniformNatSet A x‖ = natResidueMass A q x.val := by
rw [cyclicUniformNatSet_eq_residue_mass]
apply Complex.norm_of_nonneg
unfold natResidueMass
positivity
theorem cyclicUniformNatSet_probability {q : ℕ} [NeZero q] {A : Finset ℕ} (hA : A.Nonempty) :
(∀ x : ZMod q, 0 ≤ (cyclicUniformNatSet A x).re ∧ (cyclicUniformNatSet A x).im = 0) ∧
ZMod.dft (cyclicUniformNatSet (q := q) A) 0 = 1 := by
refine ⟨?_, dft_cyclicUniformNatSet_at_zero hA⟩
intro x
rw [cyclicUniformNatSet_eq_residue_mass]
simp only [Complex.ofReal_re, Complex.ofReal_im, and_true]
unfold natResidueMass
positivity
theorem binary_block_profile_law {F K u : ℕ} {c : ℝ} {A : Finset ℕ}
(hA : BinaryBlockProfile F K K u c A) :
(∀ x : ZMod (2 ^ K), cyclicUniformNatSet A x ≠ 0 → IsUnit x) ∧
(∀ x : ZMod (2 ^ K), cyclicUniformNatSet A x ≠ 0 → ∃ S : ℕ,
S ≤ 2 ^ K ∧ (S : ZMod (2 ^ K)) = x ∧ HasFactorialDivisorMultiset (F + 2 * K) S u) ∧
(∀ j : ℕ, 2 ≤ j → j ≤ K → ∀ x : ZMod (2 ^ j),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-(c / 2) * (j : ℝ))) := by
refine ⟨?_, ?_, ?_⟩
· intro x hx
obtain ⟨n, hn, hcast⟩ := cyclicUniformNatSet_support A hx
rw [← hcast]
apply (ZMod.isUnit_iff_coprime _ _).mpr
have hnodd := hA.odd n hn
have hcop : Nat.Coprime n 2 := by
rw [Nat.coprime_comm, Nat.prime_two.coprime_iff_not_dvd]
obtain ⟨t, ht⟩ := hnodd
omega
exact hcop.pow_right K
· intro x hx
obtain ⟨n, hn, hcast⟩ := cyclicUniformNatSet_support A hx
exact ⟨n, (hA.bounded n hn).le, hcast, hA.representatives n hn⟩
· intro j hj hjK x
rw [norm_cyclicUniformNatSet]
exact hA.spread j hj hjK x.val
noncomputable def factorialDigitBase (a : ℝ) (K : ℕ) : ℕ := Nat.log 2 (factorialDigitHost a K)
noncomputable def factorialBlockSet (a : ℝ) (K : ℕ) : Finset ℕ :=
binaryBlockSet (factorialDigitHost a K) K (factorialDigitBase a K) (binaryLength K)
noncomputable def factorialBlockLaw (a : ℝ) (K : ℕ) : ZMod (2 ^ K) → ℂ :=
cyclicUniformNatSet (factorialBlockSet a K)
theorem factorialDigitBase_tendsto {a : ℝ} (ha : 0 < a) :
Filter.Tendsto (factorialDigitBase a) Filter.atTop Filter.atTop := by
apply Filter.tendsto_atTop.mpr
intro M
filter_upwards [(factorialDigitHost_tendsto ha).eventually_ge_atTop (2 ^ M)] with K hK
exact Nat.le_log_of_pow_le (by decide) hK
theorem eventually_factorialDigitBase_bounds {a : ℝ} (ha : 0 < a) :
∀ᶠ K : ℕ in Filter.atTop, 2 ≤ factorialDigitBase a K ∧ factorialDigitBase a K ≤ K ∧
2 ^ factorialDigitBase a K ≤ factorialDigitHost a K := by
let ε : ℝ := 1 / (2 * a)
have hε : 0 < ε := by dsimp [ε]; positivity
have haε : a * ε = 1 / 2 := by dsimp [ε]; field_simp
have hhost := factorialDigitHost_tendsto ha
have hbit := hhost.eventually (eventually_binaryLength_le_rpow hε)
have hpower := eventually_const_mul_rpow_le (a := 1 / 2) (b := 1) (C := (2 : ℝ) ^ ε)
(E := 1) (by norm_num) (by norm_num)
filter_upwards [hbit, hpower, (factorialDigitBase_tendsto ha).eventually_ge_atTop 2,
hhost.eventually_ge_atTop 1, eventually_ge_atTop (1 : ℕ)] with K hKbit hKpower hKbase hKhost hKone
refine ⟨hKbase, ?_, Nat.pow_log_le_self 2 (by omega)⟩
have hlen : (binaryLength (factorialDigitHost a K) : ℝ) ≤ (K : ℝ) := by
calc
(binaryLength (factorialDigitHost a K) : ℝ) ≤ (factorialDigitHost a K : ℝ) ^ ε := hKbit
_ ≤ (2 * (K : ℝ) ^ a) ^ ε := Real.rpow_le_rpow (Nat.cast_nonneg _)
(factorialDigitHost_le ha.le hKone) hε.le
_ = (2 : ℝ) ^ ε * (K : ℝ) ^ (1 / 2 : ℝ) := by
rw [Real.mul_rpow (by norm_num) (by positivity), ← Real.rpow_mul (Nat.cast_nonneg K), haε]
_ ≤ (K : ℝ) := by simpa only [one_mul, Real.rpow_one] using hKpower
have hbitle : factorialDigitBase a K ≤ binaryLength (factorialDigitHost a K) := Nat.le_succ _
exact_mod_cast (show (factorialDigitBase a K : ℝ) ≤ (K : ℝ) from
(by exact_mod_cast hbitle : (factorialDigitBase a K : ℝ) ≤ binaryLength (factorialDigitHost a K)).trans hlen)
theorem factorial_block_set_profiles {a : ℝ} (ha : 1 < a) :
∃ c : ℝ, 0 < c ∧ c ≤ 1 / 2 ∧ ∀ᶠ K : ℕ in Filter.atTop,
BinaryBlockProfile (factorialDigitHost a K) K K (binaryLength K + 1) c (factorialBlockSet a K) ∧
(∀ x : ZMod (2 ^ K), 2 ≤ dyadicConductorLevel x →
dyadicConductorLevel x ≤ factorialDigitBase a K → ZMod.dft (factorialBlockLaw a K) x = 0) := by
obtain ⟨c₀, hc₀, hshort⟩ := shortFactorialDigits_uniform_asymptotic ha
let c := min c₀ (1 / 2)
have hc : 0 < c := lt_min hc₀ (by norm_num)
have hcc : c ≤ c₀ := min_le_left _ _
have hchalf : c ≤ 1 / 2 := min_le_right _ _
refine ⟨c, hc, hchalf, ?_⟩
filter_upwards [hshort, eventually_factorialDigitBase_bounds (by linarith : 0 < a)]
with K hKshort hKb
obtain ⟨hblo, hbK, hF⟩ := hKb
have hD : ∀ l : ℕ, 1 ≤ l → l ≤ K →
(2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits (factorialDigitHost a K) l).card := by
intro l hl hlK
exact (Real.rpow_le_rpow_of_exponent_le (by norm_num)
(mul_le_mul_of_nonneg_right hcc (Nat.cast_nonneg l))).trans (hKshort.2 l hl hlK)
refine ⟨binary_block_set_profile_top hblo hbK hF hc.le hchalf hD, ?_⟩
intro x hxlo hxhi
exact dft_binary_block_set_low hblo hbK hF hc.le hchalf hD hxlo hxhi (binaryLength K)
theorem factorial_block_laws {a : ℝ} (ha : 1 < a) :
∃ g : ℝ, 0 < g ∧ g ≤ 1 / 2 ∧ ∀ᶠ K : ℕ in Filter.atTop,
ZMod.dft (factorialBlockLaw a K) 0 = 1 ∧
(∀ x : ZMod (2 ^ K), 0 ≤ (factorialBlockLaw a K x).re ∧ (factorialBlockLaw a K x).im = 0) ∧
(∀ x : ZMod (2 ^ K), factorialBlockLaw a K x ≠ 0 → IsUnit x) ∧
(∀ x : ZMod (2 ^ K), factorialBlockLaw a K x ≠ 0 → ∃ S : ℕ,
S ≤ 2 ^ K ∧ (S : ZMod (2 ^ K)) = x ∧
HasFactorialDivisorMultiset (factorialDigitHost a K + 2 * K) S (binaryLength K + 1)) ∧
(∀ x : ZMod (2 ^ K), 2 ≤ dyadicConductorLevel x → dyadicConductorLevel x ≤ factorialDigitBase a K →
ZMod.dft (factorialBlockLaw a K) x = 0) ∧
(∀ j : ℕ, 2 ≤ j → j ≤ K → ∀ x : ZMod (2 ^ j),
‖cyclicUniformNatSet (factorialBlockSet a K) x‖ ≤ (2 : ℝ) ^ (-g * (j : ℝ))) := by
obtain ⟨c, hc, hchalf, hprofiles⟩ := factorial_block_set_profiles ha
refine ⟨c / 2, by positivity, by linarith, ?_⟩
filter_upwards [hprofiles] with K hK
obtain ⟨hprofile, hlow⟩ := hK
obtain ⟨hprob, hzero⟩ := cyclicUniformNatSet_probability (q := 2 ^ K) hprofile.nonempty
obtain ⟨hunit, hrep, hspread⟩ := binary_block_profile_law hprofile
exact ⟨hzero, hprob, hunit, hrep, hlow, hspread⟩
theorem dyadic_frequency_factor {K : ℕ} {x : ZMod (2 ^ K)} (hx : x ≠ 0) :
∃ a : ℕ, Odd a ∧ x = ((2 ^ (K - dyadicConductorLevel x) * a : ℕ) : ZMod (2 ^ K)) := by
let j := dyadicConductorLevel x
have hj : 0 < j := dyadic_conductor_pos hx
have hjK : j ≤ K := (dyadic_conductor_spec x).1
have horder : addOrderOf x = 2 ^ j := (dyadic_conductor_spec x).2
have hperiod : ((2 ^ j * x.val : ℕ) : ZMod (2 ^ K)) = 0 := by
have hh := addOrderOf_nsmul_eq_zero x
rw [horder] at hh
simpa only [nsmul_eq_mul, Nat.cast_mul, ZMod.natCast_zmod_val] using hh
have hdiv := (ZMod.natCast_eq_zero_iff _ _).mp hperiod
have hQ : 2 ^ K = 2 ^ j * 2 ^ (K - j) := by rw [← pow_add, Nat.add_sub_of_le hjK]
have hdiv' : 2 ^ j * 2 ^ (K - j) ∣ 2 ^ j * x.val := hQ.symm.dvd.trans hdiv
have hfactor := Nat.dvd_of_mul_dvd_mul_left (by positivity : 0 < 2 ^ j) hdiv'
obtain ⟨a, ha⟩ := hfactor
have hxa : x = ((2 ^ (K - j) * a : ℕ) : ZMod (2 ^ K)) := by
rw [← ha, ZMod.natCast_zmod_val]
refine ⟨a, ?_, hxa⟩
by_contra hodd
have heven : Even a := Nat.not_odd_iff_even.mp hodd
obtain ⟨t, ht⟩ := heven
have hnat : 2 ^ (j - 1) * (2 ^ (K - j) * a) = 2 ^ K * t := by
rw [ht, hQ]
have hp : 2 ^ j = 2 ^ (j - 1) * 2 := by rw [← pow_succ, Nat.sub_add_cancel hj]
rw [hp]
ring
have hsmul : (2 ^ (j - 1)) • x = 0 := by
rw [hxa, nsmul_eq_mul, ← Nat.cast_mul, hnat]
exact (ZMod.natCast_eq_zero_iff _ _).mpr (dvd_mul_right _ _)
have hdvd : 2 ^ j ∣ 2 ^ (j - 1) := by
rw [← horder]
exact addOrderOf_dvd_iff_nsmul_eq_zero.mpr hsmul
have hle := (Nat.pow_dvd_pow_iff_le_right (by decide : 1 < 2)).mp hdvd
omega
theorem stdAddChar_scaled_modulus {Q q d : ℕ} [NeZero Q] [NeZero q]
(hQ : Q = d * q) (m : ℤ) :
ZMod.stdAddChar (((d : ℤ) * m : ℤ) : ZMod Q) = ZMod.stdAddChar (m : ZMod q) := by
have hd : d ≠ 0 := by
intro h
have := NeZero.ne Q
simp [hQ, h] at this
rw [ZMod.stdAddChar_coe, ZMod.stdAddChar_coe]
congr 1
rw [hQ]
push_cast
have hdc : (d : ℂ) ≠ 0 := by exact_mod_cast hd
have hqc : (q : ℂ) ≠ 0 := by exact_mod_cast NeZero.ne q
field_simp
theorem dyadic_frequency_phase {K j a : ℕ} (hj : j ≤ K)
{x : ZMod (2 ^ K)} (hx : x = ((2 ^ (K - j) * a : ℕ) : ZMod (2 ^ K))) (n : ℕ) :
ZMod.stdAddChar (-((n : ZMod (2 ^ K)) * x)) =
ZMod.stdAddChar (-((n : ZMod (2 ^ j)) * (a : ZMod (2 ^ j)))) := by
have hQ : 2 ^ K = 2 ^ (K - j) * 2 ^ j := by rw [← pow_add, Nat.sub_add_cancel hj]
have hphase := stdAddChar_scaled_modulus hQ (-((n : ℤ) * (a : ℤ)))
rw [hx]
convert hphase using 1
· push_cast
congr 1
ring
· push_cast
rfl
theorem dft_product_uniform_succ {q : ℕ} [NeZero q]
(A : Finset ℕ) (r : ℕ) (k : ZMod q) :
ZMod.dft (cyclicProductPow (cyclicUniformNatSet A) (r + 1)) k =
(∑ a ∈ A, ZMod.dft (cyclicProductPow (cyclicUniformNatSet A) r) ((a : ZMod q) * k)) *
(A.card : ℂ)⁻¹ := by
classical
rw [cyclicProductPow, dft_cyclicMultiplicativeConvolution]
simp_rw [dft_cyclicUniformNatSet, ← mul_assoc, Finset.mul_sum]
rw [← Finset.sum_mul, Finset.sum_comm]
congr 1
apply Finset.sum_congr rfl
intro a _
rw [ZMod.dft_apply]
apply Finset.sum_congr rfl
intro y _
simp only [smul_eq_mul]
rw [show (a : ZMod q) * y * k = y * ((a : ZMod q) * k) by ring]
ring
theorem dft_product_uniform_transfer {Q q : ℕ} [NeZero Q] [NeZero q]
(A : Finset ℕ) : ∀ r : ℕ, ∀ x : ZMod Q, ∀ y : ZMod q,
(∀ n : ℕ, ZMod.stdAddChar (-((n : ZMod Q) * x)) = ZMod.stdAddChar (-((n : ZMod q) * y))) →
ZMod.dft (cyclicProductPow (cyclicUniformNatSet A) r) x =
ZMod.dft (cyclicProductPow (cyclicUniformNatSet A) r) y := by
intro r
induction r with
| zero =>
intro x y hphase
simpa [cyclicProductPow, ZMod.dft_apply] using hphase 1
| succ r ih =>
intro x y hphase
rw [dft_product_uniform_succ, dft_product_uniform_succ]
congr 1
apply Finset.sum_congr rfl
intro a _
apply ih
intro n
simpa only [Nat.cast_mul, mul_assoc] using hphase (n * a)
/-- The odd-law mixing property proved below by `weighted_dyadic_mixing`. -/
def WeightedDyadicMixing : Prop :=
∀ g : ℝ, 0 < g → g ≤ 1 / 2 → ∃ r : ℕ, ∃ t : ℝ, ∃ J₀ : ℕ,
0 < r ∧ 0 < t ∧ ∀ J : ℕ, J₀ ≤ J → ∀ A : Finset ℕ,
A.Nonempty → (∀ n ∈ A, Odd n) →
(∀ l : ℕ, 2 ≤ l → l ≤ J → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-g * (l : ℝ))) →
∀ a : ℕ, Odd a →
‖ZMod.dft (cyclicProductPow (cyclicUniformNatSet A) r) (a : ZMod (2 ^ J))‖ ≤
(2 : ℝ) ^ (-t * (J : ℝ))
theorem block_product_decay_of_weighted_mixing {a : ℝ} (ha : 1 < a) (hmix : WeightedDyadicMixing) :
∃ r : ℕ, ∃ t : ℝ, 0 < r ∧ 0 < t ∧ ∀ᶠ K : ℕ in Filter.atTop,
∀ x : ZMod (2 ^ K), factorialDigitBase a K < dyadicConductorLevel x →
‖ZMod.dft (cyclicProductPow (factorialBlockLaw a K) r) x‖ ≤
(2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ)) := by
obtain ⟨c, hc, hchalf, hprofiles⟩ := factorial_block_set_profiles ha
obtain ⟨r, t, J₀, hr, ht, hmix⟩ := hmix (c / 2) (by positivity) (by linarith)
refine ⟨r, t, hr, ht, ?_⟩
filter_upwards [hprofiles, (factorialDigitBase_tendsto (by linarith : 0 < a)).eventually_ge_atTop J₀]
with K hK hKbase
intro x hx
have hxne : x ≠ 0 := by
intro hzero
subst x
simp [dyadicConductorLevel] at hx
obtain ⟨m, hm, hfactor⟩ := dyadic_frequency_factor hxne
have hjK := (dyadic_conductor_spec x).1
have hspread := (binary_block_profile_law hK.1).2.2
have hbound := hmix (dyadicConductorLevel x) (by omega) (factorialBlockSet a K)
hK.1.nonempty hK.1.odd (fun l hl hlj => hspread l hl (hlj.trans hjK)) m hm
have htransfer := dft_product_uniform_transfer (factorialBlockSet a K) r x
(m : ZMod (2 ^ dyadicConductorLevel x)) (fun n => dyadic_frequency_phase hjK hfactor n)
change ‖ZMod.dft (cyclicProductPow (cyclicUniformNatSet (factorialBlockSet a K)) r) x‖ ≤ _
rw [htransfer]
exact hbound
theorem block_product_host_bound {a : ℝ} {K r : ℕ} (ha : 1 ≤ a) (hK : 1 ≤ K) :
((r * (factorialDigitHost a K + 2 * K) : ℕ) : ℝ) ≤
(4 * (r : ℝ)) * (K : ℝ) ^ a := by
have hhost := factorialDigitHost_le (by linarith : 0 ≤ a) hK
have hKpow : (K : ℝ) ≤ (K : ℝ) ^ a := by
simpa only [Real.rpow_one] using
Real.rpow_le_rpow_of_exponent_le (by exact_mod_cast hK : (1 : ℝ) ≤ K) ha
simp only [Nat.cast_mul, Nat.cast_add, Nat.cast_ofNat]
calc
(r : ℝ) * ((factorialDigitHost a K : ℝ) + 2 * K) ≤ (r : ℝ) * (4 * (K : ℝ) ^ a) :=
mul_le_mul_of_nonneg_left (by linarith) (Nat.cast_nonneg r)
_ = (4 * (r : ℝ)) * (K : ℝ) ^ a := by ring
theorem eventually_block_sum_count_bound {b : ℝ} {r : ℕ} (hb : 0 < b) (hr : 0 < r) (s : ℕ) :
∀ᶠ K : ℕ in Filter.atTop,
((s * ((binaryLength K + 1) ^ r + 1) : ℕ) : ℝ) ≤
((s : ℝ) * ((2 : ℝ) ^ r + 1)) * (K : ℝ) ^ b := by
have hrpos : (0 : ℝ) < r := by exact_mod_cast hr
have hε : 0 < b / (r : ℝ) := div_pos hb hrpos
filter_upwards [eventually_binaryLength_le_rpow hε, eventually_ge_atTop (1 : ℕ)] with K hK hKone
have hlenone : (1 : ℝ) ≤ binaryLength K := by exact_mod_cast binaryLength_pos K
have hlen : ((binaryLength K + 1 : ℕ) : ℝ) ≤ 2 * (K : ℝ) ^ (b / (r : ℝ)) := by
rw [Nat.cast_add, Nat.cast_one]
linarith
have hpow : (((binaryLength K + 1 : ℕ) : ℝ) ^ r) ≤ (2 : ℝ) ^ r * (K : ℝ) ^ b := by
calc
_ ≤ (2 * (K : ℝ) ^ (b / (r : ℝ))) ^ r := pow_le_pow_left₀ (by positivity) hlen r
_ = (2 : ℝ) ^ r * (K : ℝ) ^ b := by
rw [mul_pow, ← Real.rpow_mul_natCast (Nat.cast_nonneg K), div_mul_cancel₀ b hrpos.ne']
have hKpow : 1 ≤ (K : ℝ) ^ b := Real.one_le_rpow (by exact_mod_cast hKone) hb.le
simp only [Nat.cast_mul, Nat.cast_add, Nat.cast_pow, Nat.cast_one]
calc
(s : ℝ) * (((binaryLength K : ℝ) + 1) ^ r + 1) ≤
(s : ℝ) * (((2 : ℝ) ^ r + 1) * (K : ℝ) ^ b) := by
apply mul_le_mul_of_nonneg_left _ (Nat.cast_nonneg s)
push_cast at hpow
nlinarith
_ = ((s : ℝ) * ((2 : ℝ) ^ r + 1)) * (K : ℝ) ^ b := by ring
theorem dyadic_modular_bounds_of_block_product_decay {a b : ℝ}
(ha : 1 < a) (hb : 0 < b)
(hdecay : ∃ r : ℕ, ∃ t : ℝ, 0 < r ∧ 0 < t ∧ ∀ᶠ K : ℕ in Filter.atTop,
∀ x : ZMod (2 ^ K), factorialDigitBase a K < dyadicConductorLevel x →
‖ZMod.dft (cyclicProductPow (factorialBlockLaw a K) r) x‖ ≤
(2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ))) : DyadicModularBounds a b := by
obtain ⟨r, t, hr, ht, hdecay⟩ := hdecay
obtain ⟨s, hs, hmod⟩ := exists_power_modular_representatives_of_product_decay ht
obtain ⟨g, hg, hghalf, hlaws⟩ := factorial_block_laws ha
have hevent : ∀ᶠ K : ℕ in Filter.atTop, ∃ F u : ℕ,
2 ^ K ∣ F.factorial ∧ HasBoundedModularRepresentatives (2 ^ K) F u (r + 1) ∧
(F : ℝ) ≤ (4 * (r : ℝ)) * (K : ℝ) ^ a ∧
(u : ℝ) ≤ ((s : ℝ) * ((2 : ℝ) ^ r + 1)) * (K : ℝ) ^ b := by
filter_upwards [hdecay, hlaws, eventually_block_sum_count_bound hb hr s,
eventually_ge_atTop (2 * s), eventually_ge_atTop (1 : ℕ)] with K hKdecay hKlaw hKcount hKs hKone
obtain ⟨hzero, _, hunit, hrep, hlow, _⟩ := hKlaw
have hheight : 2 * s ≤ 2 ^ K := hKs.trans (Nat.lt_two_pow_self : K < 2 ^ K).le
have hmodK := hmod K (factorialDigitBase a K) r (factorialDigitHost a K + 2 * K)
(binaryLength K + 1) hr (factorialBlockLaw a K) hzero hunit hlow hKdecay hrep hheight
refine ⟨r * (factorialDigitHost a K + 2 * K), s * ((binaryLength K + 1) ^ r + 1),
?_, hmodK, block_product_host_bound ha.le hKone, hKcount⟩
have hreserve : 2 ^ K ∣ (factorialDigitHost a K + 2 * K).factorial :=
(dvd_mul_right (2 ^ K) (factorialDigitHost a K).factorial).trans
(factorial_binary_reserve (factorialDigitHost a K) K)
exact hreserve.trans (Nat.factorial_dvd_factorial (by nlinarith))
obtain ⟨K₀, hK₀⟩ := Filter.eventually_atTop.mp hevent
refine ⟨r + 1, K₀, 4 * (r : ℝ), (s : ℝ) * ((2 : ℝ) ^ r + 1), ?_, ?_, hK₀⟩ <;>
positivity
theorem dyadic_modular_bounds_of_weighted_dyadic_mixing {a b : ℝ}
(ha : 1 < a) (hb : 0 < b) (hmix : WeightedDyadicMixing) : DyadicModularBounds a b := by
exact dyadic_modular_bounds_of_block_product_decay ha hb (block_product_decay_of_weighted_mixing ha hmix)
theorem erdos18b_of_weighted_dyadic_mixing (hmix : WeightedDyadicMixing) :
fcTypeOfName% "Erdos18.erdos_18b" := by
exact erdos18b_of_dyadic_modular_bounds
(fun _ _ ha hb => dyadic_modular_bounds_of_weighted_dyadic_mixing ha hb hmix)
theorem binary_block_profile_spread_extended {F K b u J : ℕ} {c : ℝ} {A : Finset ℕ}
(hA : BinaryBlockProfile F K b u c A) (hc : 0 ≤ c) (hJ : J ≤ 2 * b) :
∀ l : ℕ, 2 ≤ l → l ≤ J → ∀ r : ℕ,
natResidueMass A (2 ^ l) r ≤ (2 : ℝ) ^ (-(c / 2) * (l : ℝ)) := by
intro l hl hlJ r
by_cases hlb : l ≤ b
· exact hA.spread l hl hlb r
· have hbound : ∀ x ∈ A, x < 2 ^ l := by
intro x hx
exact (hA.bounded x hx).trans_le (Nat.pow_le_pow_right (by decide : 0 < 2) (by omega))
calc
natResidueMass A (2 ^ l) r ≤ 1 / (A.card : ℝ) := by
apply div_le_div_of_nonneg_right _ (Nat.cast_nonneg _)
exact_mod_cast nat_residue_fiber_card_le_one hbound
_ ≤ 1 / (2 : ℝ) ^ (c * (b : ℝ)) := one_div_le_one_div_of_le (by positivity) hA.entropy
_ = (2 : ℝ) ^ (-(c * (b : ℝ))) := by rw [Real.rpow_neg (by norm_num), one_div]
_ ≤ (2 : ℝ) ^ (-(c / 2) * (l : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh : (l : ℝ) ≤ 2 * (b : ℝ) := by exact_mod_cast hlJ.trans hJ
nlinarith [mul_le_mul_of_nonneg_left hh hc]
def natTranslate (A : Finset ℕ) (c : ℕ) : Finset ℕ := A.image (fun n => n + c)
theorem nat_translate_card (A : Finset ℕ) (c : ℕ) : (natTranslate A c).card = A.card := by
apply Finset.card_image_of_injective
intro x y h
exact Nat.add_right_cancel h
theorem nat_translate_nonempty {A : Finset ℕ} (hA : A.Nonempty) (c : ℕ) : (natTranslate A c).Nonempty :=
hA.image _
theorem nat_translate_residue_mass {q : ℕ} [NeZero q] (A : Finset ℕ) (c r : ℕ) :
natResidueMass (natTranslate A c) q r = natResidueMass A q ((r : ZMod q) - (c : ZMod q)).val := by
let z : ZMod q := (r : ZMod q) - (c : ZMod q)
have hpred (n : ℕ) : Nat.ModEq q (n + c) r ↔ Nat.ModEq q n z.val := by
rw [← ZMod.natCast_eq_natCast_iff, ← ZMod.natCast_eq_natCast_iff]
simp only [Nat.cast_add, ZMod.natCast_zmod_val, z]
exact eq_sub_iff_add_eq.symm
have hfiber : natResidueFiber (natTranslate A c) q r = natTranslate (natResidueFiber A q z.val) c := by
ext x
constructor
· intro hx
obtain ⟨hxA, hxmod⟩ := Finset.mem_filter.mp hx
obtain ⟨n, hn, rfl⟩ := Finset.mem_image.mp hxA
exact Finset.mem_image.mpr ⟨n, Finset.mem_filter.mpr ⟨hn, (hpred n).mp hxmod⟩, rfl⟩
· intro hx
obtain ⟨n, hn, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨hnA, hnmod⟩ := Finset.mem_filter.mp hn
exact Finset.mem_filter.mpr ⟨Finset.mem_image.mpr ⟨n, hnA, rfl⟩, (hpred n).mpr hnmod⟩
unfold natResidueMass
rw [hfiber, nat_translate_card, nat_translate_card]
theorem bounded_nat_set_cast_injective {q : ℕ} {A : Finset ℕ} (hA : ∀ n ∈ A, n < q) :
Set.InjOn (fun n : ℕ => (n : ZMod q)) A := by
intro n hn m hm h
have heq := (ZMod.natCast_eq_natCast_iff n m q).mp h
simpa only [Nat.ModEq, Nat.mod_eq_of_lt (hA n hn), Nat.mod_eq_of_lt (hA m hm)] using heq
theorem translated_nat_set_cast_injective {q : ℕ} {A : Finset ℕ}
(hA : Set.InjOn (fun n : ℕ => (n : ZMod q)) A) (c : ℕ) :
Set.InjOn (fun n : ℕ => (n : ZMod q)) (natTranslate A c) := by
intro n hn m hm h
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨b, hb, rfl⟩ := Finset.mem_image.mp hm
have hab : (a : ZMod q) = (b : ZMod q) := by
change ((a + c : ℕ) : ZMod q) = ((b + c : ℕ) : ZMod q) at h
simpa only [Nat.cast_add, add_left_inj] using h
rw [hA ha hb hab]
theorem translated_binary_prefix_spread {F K b u J : ℕ} {c : ℝ} {A : Finset ℕ}
(hA : BinaryBlockProfile F K b u c A) (hc : 0 ≤ c) (hbJ : b ≤ J) (hJ : J ≤ 2 * b)
(d : ℕ) :
(natTranslate A d).Nonempty ∧
Set.InjOn (fun n : ℕ => (n : ZMod (2 ^ J))) (natTranslate A d) ∧
∀ l : ℕ, 2 ≤ l → l ≤ J → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet (natTranslate A d) x‖ ≤ (2 : ℝ) ^ (-(c / 2) * (l : ℝ)) := by
refine ⟨nat_translate_nonempty hA.nonempty d, ?_, ?_⟩
· apply translated_nat_set_cast_injective
apply bounded_nat_set_cast_injective
intro n hn
exact (hA.bounded n hn).trans_le (Nat.pow_le_pow_right (by decide : 0 < 2) hbJ)
· intro l hl hlJ x
rw [norm_cyclicUniformNatSet, nat_translate_residue_mass]
exact binary_block_profile_spread_extended hA hc hJ l hl hlJ _
theorem binary_block_endpoint_monotone (K b₀ : ℕ) : Monotone (binaryBlockEndpoint K b₀) := by
exact monotone_nat_of_le_succ (binary_block_endpoint_mono K b₀)
theorem binary_block_prefix_at_level {K b₀ J : ℕ}
(hb : 1 ≤ b₀) (hbJ : b₀ < J) (hJK : J ≤ K) :
∃ i : ℕ, i ≤ binaryLength K ∧ binaryBlockEndpoint K b₀ i ≤ J ∧
J ≤ 2 * binaryBlockEndpoint K b₀ i := by
have hex : ∃ i : ℕ, J ≤ binaryBlockEndpoint K b₀ i := by
refine ⟨binaryLength K, ?_⟩
rwa [binary_block_endpoint_top hb]
let m := Nat.find hex
have hm : J ≤ binaryBlockEndpoint K b₀ m := Nat.find_spec hex
have hmN : m ≤ binaryLength K := Nat.find_min' hex (by rwa [binary_block_endpoint_top hb])
have hmpos : 0 < m := by
by_contra h
have hmzero : m = 0 := by omega
rw [hmzero, binary_block_endpoint_zero (by omega)] at hm
omega
have hprev : binaryBlockEndpoint K b₀ (m - 1) < J := by
exact Nat.lt_of_not_ge (Nat.find_min hex (by change m - 1 < m; omega))
refine ⟨m - 1, by omega, hprev.le, ?_⟩
have hnext := binary_block_endpoint_succ_le_twice K b₀ (m - 1)
rw [Nat.sub_add_cancel hmpos] at hnext
exact hm.trans hnext
theorem binary_append_singleton_zero (A : Finset ℕ) (b : ℕ) : binaryAppend A {0} b = A := by
ext x
simp [binaryAppend]
theorem binary_append_assoc (A D E : Finset ℕ) (b l : ℕ) :
binaryAppend (binaryAppend A D b) E (b + l) = binaryAppend A (binaryAppend D E l) b := by
ext x
constructor
· intro hx
obtain ⟨⟨ad, e⟩, hade, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨had, he⟩ := Finset.mem_product.mp hade
obtain ⟨⟨a, d⟩, hapair, rfl⟩ := Finset.mem_image.mp had
obtain ⟨ha, hd⟩ := Finset.mem_product.mp hapair
refine Finset.mem_image.mpr ⟨(a, d + 2 ^ l * e), Finset.mem_product.mpr ⟨ha, ?_⟩, ?_⟩
· exact Finset.mem_image.mpr ⟨(d, e), Finset.mem_product.mpr ⟨hd, he⟩, rfl⟩
· simp only [pow_add]
ring
· intro hx
obtain ⟨⟨a, de⟩, hade, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨ha, hde⟩ := Finset.mem_product.mp hade
obtain ⟨⟨d, e⟩, hdepair, rfl⟩ := Finset.mem_image.mp hde
obtain ⟨hd, he⟩ := Finset.mem_product.mp hdepair
refine Finset.mem_image.mpr ⟨(a + 2 ^ b * d, e), Finset.mem_product.mpr ⟨?_, he⟩, ?_⟩
· exact Finset.mem_image.mpr ⟨(a, d), Finset.mem_product.mpr ⟨ha, hd⟩, rfl⟩
· simp only [pow_add]
ring
theorem binary_block_set_factors_at_prefix (F K b₀ i N : ℕ) (hiN : i ≤ N) :
∃ D : Finset ℕ, D.Nonempty ∧ binaryBlockSet F K b₀ N =
binaryAppend (binaryBlockSet F K b₀ i) D (binaryBlockEndpoint K b₀ i) := by
induction N, hiN using Nat.le_induction with
| base =>
exact ⟨{0}, Finset.singleton_nonempty 0, (binary_append_singleton_zero _ _).symm⟩
| succ N hiN ih =>
obtain ⟨D, hD, hfactor⟩ := ih
have hbN := binary_block_endpoint_monotone K b₀ hiN
have hsplit : binaryBlockEndpoint K b₀ N = binaryBlockEndpoint K b₀ i +
(binaryBlockEndpoint K b₀ N - binaryBlockEndpoint K b₀ i) := by omega
refine ⟨binaryAppend D (shortFactorialDigits F (binaryBlockWidth K b₀ N))
(binaryBlockEndpoint K b₀ N - binaryBlockEndpoint K b₀ i),
binary_append_nonempty hD (short_factorial_digits_nonempty _ _), ?_⟩
rw [binaryBlockSet, hfactor, hsplit, binary_append_assoc]
simp only [Nat.add_sub_cancel_left]
noncomputable def natProductAverage : List (Finset ℕ) → (ℕ → ℂ) → ℂ
| [], f => f 1
| A :: L, f => (∑ n ∈ A, natProductAverage L (fun m => f (n * m))) * (A.card : ℂ)⁻¹
theorem nat_product_average_congr (L : List (Finset ℕ)) {f g : ℕ → ℂ}
(h : ∀ n, f n = g n) : natProductAverage L f = natProductAverage L g := by
congr 1
exact funext h
theorem nat_product_average_binary_append_head {A D : Finset ℕ} {b : ℕ}
(hA : ∀ n ∈ A, n < 2 ^ b) (L : List (Finset ℕ)) (f : ℕ → ℂ) :
natProductAverage (binaryAppend A D b :: L) f =
(∑ d ∈ D, natProductAverage (natTranslate A (2 ^ b * d) :: L) f) * (D.card : ℂ)⁻¹ := by
simp only [natProductAverage, binary_append_card hA, Nat.cast_mul, mul_inv_rev,
nat_translate_card]
rw [binaryAppend, Finset.sum_image (binary_append_injective hA), Finset.sum_product,
Finset.sum_comm]
simp only [natTranslate, Finset.sum_image (fun _ _ _ _ h => Nat.add_right_cancel h)]
rw [← Finset.sum_mul]
ring
theorem nat_product_average_binary_append {A D : Finset ℕ} {b : ℕ}
(hA : ∀ n ∈ A, n < 2 ^ b) (P L : List (Finset ℕ)) (f : ℕ → ℂ) :
natProductAverage (P ++ binaryAppend A D b :: L) f =
(∑ d ∈ D, natProductAverage (P ++ natTranslate A (2 ^ b * d) :: L) f) * (D.card : ℂ)⁻¹ := by
induction P generalizing f with
| nil => exact nat_product_average_binary_append_head hA L f
| cons B P ih =>
simp only [List.cons_append, natProductAverage]
simp_rw [ih]
simp only [← Finset.sum_mul]
rw [Finset.sum_comm]
ring
theorem norm_finset_average_le {D : Finset ℕ} (hD : D.Nonempty) {f : ℕ → ℂ} {B : ℝ}
(h : ∀ d ∈ D, ‖f d‖ ≤ B) : ‖(∑ d ∈ D, f d) * (D.card : ℂ)⁻¹‖ ≤ B := by
have hDc : (0 : ℝ) < D.card := by exact_mod_cast Finset.card_pos.mpr hD
have hsum : ‖∑ d ∈ D, f d‖ ≤ (D.card : ℝ) * B := by
calc
_ ≤ ∑ d ∈ D, ‖f d‖ := norm_sum_le _ _
_ ≤ ∑ _d ∈ D, B := Finset.sum_le_sum h
_ = (D.card : ℝ) * B := by simp
calc
‖(∑ d ∈ D, f d) * (D.card : ℂ)⁻¹‖ = ‖∑ d ∈ D, f d‖ / (D.card : ℝ) := by
rw [norm_mul, norm_inv, Complex.norm_natCast, div_eq_mul_inv]
_ ≤ ((D.card : ℝ) * B) / (D.card : ℝ) := div_le_div_of_nonneg_right hsum hDc.le
_ = B := by field_simp
theorem norm_product_average_binary_append_le {A D : Finset ℕ} {b r : ℕ}
(hA : ∀ n ∈ A, n < 2 ^ b) (hD : D.Nonempty) (f : ℕ → ℂ) (M : ℝ)
(hbound : ∀ L : List (Finset ℕ), L.length = r →
(∀ B ∈ L, ∃ d ∈ D, B = natTranslate A (2 ^ b * d)) → ‖natProductAverage L f‖ ≤ M) :
‖natProductAverage (List.replicate r (binaryAppend A D b)) f‖ ≤ M := by
have haux : ∀ k : ℕ, ∀ P : List (Finset ℕ), P.length + k = r →
(∀ B ∈ P, ∃ d ∈ D, B = natTranslate A (2 ^ b * d)) →
‖natProductAverage (P ++ List.replicate k (binaryAppend A D b)) f‖ ≤ M := by
intro k
induction k with
| zero =>
intro P hlen hP
simp only [List.replicate_zero, List.append_nil]
apply hbound P (by simpa using hlen) hP
| succ k ih =>
intro P hlen hP
rw [List.replicate_succ, nat_product_average_binary_append hA]
apply norm_finset_average_le hD
intro d hd
have heq : P ++ natTranslate A (2 ^ b * d) :: List.replicate k (binaryAppend A D b) =
(P ++ [natTranslate A (2 ^ b * d)]) ++ List.replicate k (binaryAppend A D b) := by simp
rw [heq]
apply ih
· simp only [List.length_append, List.length_singleton]
omega
· intro B hB
rcases List.mem_append.mp hB with hBP | hBd
· exact hP B hBP
· exact ⟨d, hd, List.mem_singleton.mp hBd⟩
exact haux r [] (by simp) (by simp)
theorem nat_product_average_replicate_dft {q : ℕ} [NeZero q] (A : Finset ℕ) (r : ℕ) :
∀ k : ZMod q,
natProductAverage (List.replicate r A) (fun n => ZMod.stdAddChar (-((n : ZMod q) * k))) =
ZMod.dft (cyclicProductPow (cyclicUniformNatSet A) r) k := by
induction r with
| zero =>
intro k
simp [natProductAverage, cyclicProductPow, ZMod.dft_apply]
| succ r ih =>
intro k
rw [List.replicate_succ, natProductAverage, dft_product_uniform_succ]
congr 1
apply Finset.sum_congr rfl
intro n _
have heq : (fun m : ℕ => ZMod.stdAddChar (-(((n * m : ℕ) : ZMod q) * k))) =
(fun m : ℕ => ZMod.stdAddChar (-((m : ZMod q) * ((n : ZMod q) * k)))) := by
funext m
rw [Nat.cast_mul]
congr 2
ring
rw [heq]
exact ih _
def DyadicSetAdmissible (g : ℝ) (J : ℕ) (A : Finset ℕ) : Prop :=
A.Nonempty ∧ Set.InjOn (fun n : ℕ => (n : ZMod (2 ^ J))) A ∧
∀ l : ℕ, 2 ≤ l → l ≤ J → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-g * (l : ℝ))
/-- A set-valued analytic input. This proposition is not asserted as a theorem. -/
def DyadicSetMixing : Prop :=
∀ g : ℝ, 0 < g → g ≤ 1 / 2 → ∃ r : ℕ, ∃ t : ℝ, ∃ J₀ : ℕ,
0 < r ∧ 0 < t ∧ ∀ J : ℕ, J₀ ≤ J → ∀ L : List (Finset ℕ),
L.length = r → (∀ A ∈ L, DyadicSetAdmissible g J A) → ∀ a : ℕ, Odd a →
‖natProductAverage L (fun n => ZMod.stdAddChar (-((n : ZMod (2 ^ J)) * (a : ZMod (2 ^ J)))))‖ ≤
(2 : ℝ) ^ (-t * (J : ℝ))
theorem factorial_block_all_profiles {a : ℝ} (ha : 1 < a) :
∃ c : ℝ, 0 < c ∧ c ≤ 1 / 2 ∧ ∀ᶠ K : ℕ in Filter.atTop,
2 ≤ factorialDigitBase a K ∧ factorialDigitBase a K ≤ K ∧
∀ i : ℕ, BinaryBlockProfile (factorialDigitHost a K) K
(binaryBlockEndpoint K (factorialDigitBase a K) i) (i + 1) c
(binaryBlockSet (factorialDigitHost a K) K (factorialDigitBase a K) i) := by
obtain ⟨c₀, hc₀, hshort⟩ := shortFactorialDigits_uniform_asymptotic ha
let c := min c₀ (1 / 2)
have hc : 0 < c := lt_min hc₀ (by norm_num)
have hcc : c ≤ c₀ := min_le_left _ _
have hchalf : c ≤ 1 / 2 := min_le_right _ _
refine ⟨c, hc, hchalf, ?_⟩
filter_upwards [hshort, eventually_factorialDigitBase_bounds (by linarith : 0 < a)]
with K hKshort hKb
obtain ⟨hblo, hbK, hF⟩ := hKb
have hD : ∀ l : ℕ, 1 ≤ l → l ≤ K →
(2 : ℝ) ^ (c * (l : ℝ)) ≤ (shortFactorialDigits (factorialDigitHost a K) l).card := by
intro l hl hlK
exact (Real.rpow_le_rpow_of_exponent_le (by norm_num)
(mul_le_mul_of_nonneg_right hcc (Nat.cast_nonneg l))).trans (hKshort.2 l hl hlK)
exact ⟨hblo, hbK, binary_block_set_profile hblo hbK hF hc.le hchalf hD⟩
theorem block_product_decay_of_set_mixing {a : ℝ} (ha : 1 < a) (hmix : DyadicSetMixing) :
∃ r : ℕ, ∃ t : ℝ, 0 < r ∧ 0 < t ∧ ∀ᶠ K : ℕ in Filter.atTop,
∀ x : ZMod (2 ^ K), factorialDigitBase a K < dyadicConductorLevel x →
‖ZMod.dft (cyclicProductPow (factorialBlockLaw a K) r) x‖ ≤
(2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ)) := by
obtain ⟨c, hc, hchalf, hprofiles⟩ := factorial_block_all_profiles ha
obtain ⟨r, t, J₀, hr, ht, hmix⟩ := hmix (c / 2) (by positivity) (by linarith)
refine ⟨r, t, hr, ht, ?_⟩
filter_upwards [hprofiles, (factorialDigitBase_tendsto (by linarith : 0 < a)).eventually_ge_atTop J₀]
with K hK hKbase
intro x hx
have hxne : x ≠ 0 := by
intro hzero
subst x
simp [dyadicConductorLevel] at hx
obtain ⟨m, hm, hfrequency⟩ := dyadic_frequency_factor hxne
have hjK := (dyadic_conductor_spec x).1
obtain ⟨i, hi, hbi, hjb⟩ := binary_block_prefix_at_level (by omega : 1 ≤ factorialDigitBase a K) hx hjK
have hprefix := hK.2.2 i
obtain ⟨D, hD, hfactor⟩ := binary_block_set_factors_at_prefix (factorialDigitHost a K) K
(factorialDigitBase a K) i (binaryLength K) hi
have hfactor' : factorialBlockSet a K = binaryAppend
(binaryBlockSet (factorialDigitHost a K) K (factorialDigitBase a K) i) D
(binaryBlockEndpoint K (factorialDigitBase a K) i) := hfactor
have hbound : ‖natProductAverage (List.replicate r (factorialBlockSet a K))
(fun n => ZMod.stdAddChar (-((n : ZMod (2 ^ dyadicConductorLevel x)) *
(m : ZMod (2 ^ dyadicConductorLevel x)))))‖ ≤
(2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ)) := by
rw [hfactor']
apply norm_product_average_binary_append_le hprefix.bounded hD
intro L hlen hL
apply hmix (dyadicConductorLevel x) (by omega) L hlen _ m hm
intro B hB
obtain ⟨d, _, rfl⟩ := hL B hB
exact translated_binary_prefix_spread hprefix hc.le hbi hjb _
have htransfer := dft_product_uniform_transfer (factorialBlockSet a K) r x
(m : ZMod (2 ^ dyadicConductorLevel x)) (fun n => dyadic_frequency_phase hjK hfrequency n)
change ‖ZMod.dft (cyclicProductPow (cyclicUniformNatSet (factorialBlockSet a K)) r) x‖ ≤ _
rw [htransfer, ← nat_product_average_replicate_dft]
exact hbound
theorem dyadic_modular_bounds_of_dyadic_set_mixing {a b : ℝ}
(ha : 1 < a) (hb : 0 < b) (hmix : DyadicSetMixing) : DyadicModularBounds a b := by
exact dyadic_modular_bounds_of_block_product_decay ha hb (block_product_decay_of_set_mixing ha hmix)
theorem erdos18b_of_dyadic_set_mixing (hmix : DyadicSetMixing) :
fcTypeOfName% "Erdos18.erdos_18b" := by
exact erdos18b_of_dyadic_modular_bounds
(fun _ _ ha hb => dyadic_modular_bounds_of_dyadic_set_mixing ha hb hmix)
theorem nat_residue_mass_mod (A : Finset ℕ) (q y : ℕ) :
natResidueMass A q (y % q) = natResidueMass A q y := by
unfold natResidueMass natResidueFiber
simp only [Nat.ModEq, Nat.mod_mod]
rfl
theorem nat_residue_mass_lt_iff {A : Finset ℕ} (hA : A.Nonempty) (q y : ℕ) (z : ℝ) :
natResidueMass A q y < z ↔ ((natResidueFiber A q y).card : ℝ) < z * (A.card : ℝ) := by
have hcard : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hA
exact div_lt_iff₀ hcard
theorem dyadic_large_divisor_iff (ε : ℝ) (J l : ℕ) :
(((2 ^ J : ℕ) : ℝ) ^ ε < ((2 ^ l : ℕ) : ℝ)) ↔ ε * (J : ℝ) < (l : ℝ) := by
simp only [Nat.cast_pow, Nat.cast_ofNat, ← Real.rpow_natCast]
rw [← Real.rpow_mul (by norm_num), Real.rpow_lt_rpow_left_iff (by norm_num)]
rw [mul_comm]
/-- The dyadic specialization of the set estimate in Bourgain (2007), Theorem 2.
The casts are injective so that the natural-number sets represent uniform sets
modulo the full modulus. Only sufficiently large divisors have a fiber hypothesis.
This stronger optional proposition is not used by the final proof of `target`. -/
def BourgainDyadicSetEstimate : Prop :=
∀ γ : ℝ, 0 < γ → ∃ ε t : ℝ, ∃ r J₀ : ℕ,
0 < ε ∧ 0 < t ∧ 0 < r ∧ ∀ J : ℕ, J₀ ≤ J → ∀ L : List (Finset ℕ),
L.length = r →
(∀ A ∈ L, A.Nonempty ∧ Set.InjOn (fun n : ℕ => (n : ZMod (2 ^ J))) A ∧
∀ l : ℕ, l ≤ J → ε * (J : ℝ) < (l : ℝ) → ∀ y : ℕ,
natResidueMass A (2 ^ l) y < (2 : ℝ) ^ (-γ * (l : ℝ))) →
∀ a : ℕ, Odd a →
‖natProductAverage L (fun n => ZMod.stdAddChar (-((n : ZMod (2 ^ J)) * (a : ZMod (2 ^ J)))))‖ <
(2 : ℝ) ^ (-t * (J : ℝ))
theorem dyadic_set_mixing_of_bourgain_dyadic_set_estimate
(hB : BourgainDyadicSetEstimate) : DyadicSetMixing := by
intro g hg _
obtain ⟨ε, t, r, J₀, hε, ht, hr, hB⟩ := hB (g / 2) (by positivity)
refine ⟨r, t, max J₀ ⌈2 / ε⌉₊, hr, ht, ?_⟩
intro J hJ L hlen hL a ha
have hJ₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hJceil : ⌈2 / ε⌉₊ ≤ J := (le_max_right _ _).trans hJ
have hJeps : 2 ≤ ε * (J : ℝ) := by
have hcast : (2 / ε : ℝ) ≤ J := (Nat.le_ceil _).trans (by exact_mod_cast hJceil)
have hprod := (div_le_iff₀ hε).mp hcast
simpa only [mul_comm] using hprod
apply le_of_lt (hB J hJ₀ L hlen _ a ha)
intro A hA
obtain ⟨hne, hinj, hspread⟩ := hL A hA
refine ⟨hne, hinj, ?_⟩
intro l hlJ hlε y
have hlreal : (2 : ℝ) < l := hJeps.trans_lt hlε
have hl : 2 ≤ l := by exact_mod_cast hlreal.le
have hmass : natResidueMass A (2 ^ l) y ≤ (2 : ℝ) ^ (-g * (l : ℝ)) := by
simpa only [norm_cyclicUniformNatSet, ZMod.val_natCast, nat_residue_mass_mod]
using hspread l hl hlJ (y : ZMod (2 ^ l))
refine hmass.trans_lt (Real.rpow_lt_rpow_of_exponent_lt (by norm_num) ?_)
nlinarith [mul_pos hg (show (0 : ℝ) < l by linarith)]
theorem erdos18b_of_bourgain_dyadic_set_estimate (hB : BourgainDyadicSetEstimate) :
fcTypeOfName% "Erdos18.erdos_18b" := by
exact erdos18b_of_dyadic_set_mixing (dyadic_set_mixing_of_bourgain_dyadic_set_estimate hB)
/- Elementary Fourier estimates used in the fixed-prime analytic argument. -/
theorem conjugate_stdAddChar {q : ℕ} [NeZero q] (x : ZMod q) :
starRingEnd ℂ (ZMod.stdAddChar x) = ZMod.stdAddChar (-x) := by
rw [ZMod.stdAddChar_apply, ZMod.stdAddChar_apply, AddChar.map_neg_eq_inv,
Circle.coe_inv_eq_conj]
theorem dft_conjugate {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (k : ZMod q) :
ZMod.dft (fun x => starRingEnd ℂ (f x)) k = starRingEnd ℂ (ZMod.dft f (-k)) := by
simp only [ZMod.dft_apply, smul_eq_mul, map_sum, map_mul, mul_neg, neg_neg,
conjugate_stdAddChar]
theorem dft_bilinear_pairing {q : ℕ} [NeZero q] (f g : ZMod q → ℂ) :
(∑ k : ZMod q, ZMod.dft f k * g k) = ∑ x : ZMod q, f x * ZMod.dft g x := by
simp only [ZMod.dft_apply, smul_eq_mul, Finset.sum_mul, Finset.mul_sum]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro x _
apply Finset.sum_congr rfl
intro k _
rw [mul_comm k x]
ring
theorem dft_parseval {q : ℕ} [NeZero q] (f : ZMod q → ℂ) :
(∑ k : ZMod q, ‖ZMod.dft f k‖ ^ 2) = (q : ℝ) * ∑ x : ZMod q, ‖f x‖ ^ 2 := by
have hpair := dft_bilinear_pairing f (fun k => starRingEnd ℂ (ZMod.dft f k))
simp_rw [dft_conjugate] at hpair
simp only [ZMod.dft_dft, neg_neg, smul_eq_mul, map_mul, map_natCast] at hpair
have hcomplex : (∑ k : ZMod q, ZMod.dft f k * starRingEnd ℂ (ZMod.dft f k)) =
(q : ℂ) * ∑ x : ZMod q, f x * starRingEnd ℂ (f x) := by
rw [hpair, Finset.mul_sum]
apply Finset.sum_congr rfl
intro x _
ring
simp only [Complex.mul_conj'] at hcomplex
apply Complex.ofReal_injective
push_cast
exact hcomplex
theorem norm_dft_mulconv_sq_le {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) {k : ZMod q} (hk : IsUnit k) :
‖ZMod.dft (cyclicMultiplicativeConvolution f g) k‖ ^ 2 ≤
(∑ x : ZMod q, ‖g x‖ ^ 2) * ((q : ℝ) * ∑ x : ZMod q, ‖f x‖ ^ 2) := by
obtain ⟨u, rfl⟩ := hk
have hperm : (∑ x : ZMod q, ‖ZMod.dft f (x * (u : ZMod q))‖ ^ 2) =
∑ x : ZMod q, ‖ZMod.dft f x‖ ^ 2 := by
exact Fintype.sum_equiv u.mulRight _ _ (fun _ => rfl)
rw [dft_cyclicMultiplicativeConvolution]
calc
‖∑ x : ZMod q, g x * ZMod.dft f (x * (u : ZMod q))‖ ^ 2 ≤
(∑ x : ZMod q, ‖g x‖ * ‖ZMod.dft f (x * (u : ZMod q))‖) ^ 2 := by
apply pow_le_pow_left₀ (norm_nonneg _) _ 2
simpa only [norm_mul] using norm_sum_le Finset.univ
(fun x : ZMod q => g x * ZMod.dft f (x * (u : ZMod q)))
_ ≤ (∑ x : ZMod q, ‖g x‖ ^ 2) *
∑ x : ZMod q, ‖ZMod.dft f (x * (u : ZMod q))‖ ^ 2 :=
Finset.sum_mul_sq_le_sq_mul_sq _ _ _
_ = _ := by rw [hperm, dft_parseval]
theorem sum_norm_cyclicUniformNatSet {q : ℕ} [NeZero q] {A : Finset ℕ} (hA : A.Nonempty) :
(∑ x : ZMod q, ‖cyclicUniformNatSet A x‖) = 1 := by
have hsum := dft_cyclicUniformNatSet_at_zero (q := q) hA
rw [ZMod.dft_apply_zero] at hsum
have hre := congrArg Complex.re hsum
simp only [norm_cyclicUniformNatSet]
simpa only [Complex.re_sum, cyclicUniformNatSet_eq_residue_mass, Complex.ofReal_re,
Complex.one_re] using hre
theorem sum_sq_norm_cyclicUniformNatSet_le {q : ℕ} [NeZero q]
{A : Finset ℕ} (hA : A.Nonempty) {M : ℝ}
(hM : ∀ x : ZMod q, ‖cyclicUniformNatSet A x‖ ≤ M) :
(∑ x : ZMod q, ‖cyclicUniformNatSet A x‖ ^ 2) ≤ M := by
calc
_ ≤ ∑ x : ZMod q, M * ‖cyclicUniformNatSet A x‖ := by
apply Finset.sum_le_sum
intro x _
simpa only [pow_two] using mul_le_mul_of_nonneg_right (hM x) (norm_nonneg _)
_ = M := by rw [← Finset.mul_sum, sum_norm_cyclicUniformNatSet hA, mul_one]
theorem norm_dft_mulconv_uniform_sq_le {q : ℕ} [NeZero q]
{A B : Finset ℕ} (hA : A.Nonempty) (hB : B.Nonempty) {M₁ M₂ : ℝ}
(hM₁ : ∀ x : ZMod q, ‖cyclicUniformNatSet A x‖ ≤ M₁)
(hM₂ : ∀ x : ZMod q, ‖cyclicUniformNatSet B x‖ ≤ M₂)
{k : ZMod q} (hk : IsUnit k) :
‖ZMod.dft (cyclicMultiplicativeConvolution (cyclicUniformNatSet A)
(cyclicUniformNatSet B)) k‖ ^ 2 ≤ (q : ℝ) * M₁ * M₂ := by
have hM₂pos : 0 ≤ M₂ := (norm_nonneg (cyclicUniformNatSet B (0 : ZMod q))).trans (hM₂ 0)
calc
_ ≤ (∑ x : ZMod q, ‖cyclicUniformNatSet B x‖ ^ 2) *
((q : ℝ) * ∑ x : ZMod q, ‖cyclicUniformNatSet A x‖ ^ 2) :=
norm_dft_mulconv_sq_le _ _ hk
_ ≤ M₂ * ((q : ℝ) * M₁) := by
apply mul_le_mul (sum_sq_norm_cyclicUniformNatSet_le hB hM₂)
(mul_le_mul_of_nonneg_left (sum_sq_norm_cyclicUniformNatSet_le hA hM₁)
(Nat.cast_nonneg q))
· positivity
· exact hM₂pos
_ = _ := by ring
theorem norm_dft_mulconv_uniform_dyadic_le {J : ℕ} {A B : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) {g₁ g₂ : ℝ}
(hM₁ : ∀ x : ZMod (2 ^ J), ‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-g₁ * (J : ℝ)))
(hM₂ : ∀ x : ZMod (2 ^ J), ‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-g₂ * (J : ℝ)))
{k : ZMod (2 ^ J)} (hk : IsUnit k) :
‖ZMod.dft (cyclicMultiplicativeConvolution (cyclicUniformNatSet A)
(cyclicUniformNatSet B)) k‖ ≤ (2 : ℝ) ^ (-((g₁ + g₂ - 1) / 2) * (J : ℝ)) := by
have hs := norm_dft_mulconv_uniform_sq_le hA hB hM₁ hM₂ hk
have heq : ((2 ^ J : ℕ) : ℝ) * (2 : ℝ) ^ (-g₁ * (J : ℝ)) *
(2 : ℝ) ^ (-g₂ * (J : ℝ)) =
((2 : ℝ) ^ (-((g₁ + g₂ - 1) / 2) * (J : ℝ))) ^ 2 := by
rw [show ((2 ^ J : ℕ) : ℝ) = (2 : ℝ) ^ (J : ℝ) by simp,
← Real.rpow_add (by norm_num), ← Real.rpow_add (by norm_num),
← Real.rpow_mul_natCast (by norm_num)]
congr 1
push_cast
ring
rw [heq] at hs
have hp : 0 < (2 : ℝ) ^ (-((g₁ + g₂ - 1) / 2) * (J : ℝ)) :=
Real.rpow_pos_of_pos (by norm_num) _
nlinarith [norm_nonneg (ZMod.dft (cyclicMultiplicativeConvolution
(cyclicUniformNatSet A) (cyclicUniformNatSet B)) k)]
theorem sum_uniformNatSet_mul {q : ℕ} [NeZero q] (A : Finset ℕ) (F : ZMod q → ℂ) :
(∑ x : ZMod q, cyclicUniformNatSet A x * F x) =
(∑ n ∈ A, F (n : ZMod q)) * (A.card : ℂ)⁻¹ := by
classical
unfold cyclicUniformNatSet cyclicPushforward
simp only [Finset.sum_mul]
rw [Finset.sum_comm]
simp only [ite_mul, zero_mul]
simp only [Finset.sum_ite_eq, Finset.mem_univ, if_true]
rw [Finset.sum_coe_sort A (fun n : ℕ => (A.card : ℂ)⁻¹ * F (n : ZMod q))]
apply Finset.sum_congr rfl
intro n _
ring
theorem dft_mulconv_uniform {q : ℕ} [NeZero q] (A B : Finset ℕ) (k : ZMod q) :
ZMod.dft (cyclicMultiplicativeConvolution (cyclicUniformNatSet A)
(cyclicUniformNatSet B)) k =
(∑ b ∈ B, ZMod.dft (cyclicUniformNatSet A) ((b : ZMod q) * k)) * (B.card : ℂ)⁻¹ := by
rw [dft_cyclicMultiplicativeConvolution, sum_uniformNatSet_mul]
theorem dft_mulconv_uniform_transfer {Q q : ℕ} [NeZero Q] [NeZero q]
(A B : Finset ℕ) (x : ZMod Q) (y : ZMod q)
(hphase : ∀ n : ℕ, ZMod.stdAddChar (-((n : ZMod Q) * x)) =
ZMod.stdAddChar (-((n : ZMod q) * y))) :
ZMod.dft (cyclicMultiplicativeConvolution (cyclicUniformNatSet A)
(cyclicUniformNatSet B)) x =
ZMod.dft (cyclicMultiplicativeConvolution (cyclicUniformNatSet A)
(cyclicUniformNatSet B)) y := by
rw [dft_mulconv_uniform, dft_mulconv_uniform]
congr 1
apply Finset.sum_congr rfl
intro b _
rw [dft_cyclicUniformNatSet, dft_cyclicUniformNatSet]
congr 1
apply Finset.sum_congr rfl
intro a _
simpa only [Nat.cast_mul, mul_assoc] using hphase (a * b)
theorem odd_natCast_isUnit_dyadic (J : ℕ) {m : ℕ} (hm : Odd m) :
IsUnit (m : ZMod (2 ^ J)) := by
apply (ZMod.isUnit_iff_coprime _ _).mpr
have hcop : Nat.Coprime m 2 := by
rw [Nat.coprime_comm, Nat.prime_two.coprime_iff_not_dvd]
obtain ⟨t, ht⟩ := hm
omega
exact hcop.pow_right J
theorem norm_dft_mulconv_uniform_conductor_le {K : ℕ} {A B : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) {g₁ g₂ : ℝ}
(hM₁ : ∀ j : ℕ, 1 ≤ j → j ≤ K → ∀ x : ZMod (2 ^ j),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-g₁ * (j : ℝ)))
(hM₂ : ∀ j : ℕ, 1 ≤ j → j ≤ K → ∀ x : ZMod (2 ^ j),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-g₂ * (j : ℝ)))
{x : ZMod (2 ^ K)} (hx : x ≠ 0) :
‖ZMod.dft (cyclicMultiplicativeConvolution (cyclicUniformNatSet A)
(cyclicUniformNatSet B)) x‖ ≤
(2 : ℝ) ^ (-((g₁ + g₂ - 1) / 2) * (dyadicConductorLevel x : ℝ)) := by
have hj : 1 ≤ dyadicConductorLevel x := dyadic_conductor_pos hx
have hjK : dyadicConductorLevel x ≤ K := (dyadic_conductor_spec x).1
obtain ⟨m, hm, hfactor⟩ := dyadic_frequency_factor hx
rw [dft_mulconv_uniform_transfer A B x (m : ZMod (2 ^ dyadicConductorLevel x))
(fun n => dyadic_frequency_phase hjK hfactor n)]
exact norm_dft_mulconv_uniform_dyadic_le hA hB (hM₁ _ hj hjK) (hM₂ _ hj hjK)
(odd_natCast_isUnit_dyadic _ hm)
theorem exists_power_mulconv_uniform_nonzero {g₁ g₂ : ℝ} (hg : 1 < g₁ + g₂) :
∃ s : ℕ, 0 < s ∧ ∀ K : ℕ, ∀ A B : Finset ℕ, A.Nonempty → B.Nonempty →
(∀ j : ℕ, 1 ≤ j → j ≤ K → ∀ x : ZMod (2 ^ j),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-g₁ * (j : ℝ))) →
(∀ j : ℕ, 1 ≤ j → j ≤ K → ∀ x : ZMod (2 ^ j),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-g₂ * (j : ℝ))) →
∀ x : ZMod (2 ^ K), cyclicConvolutionPow
(cyclicMultiplicativeConvolution (cyclicUniformNatSet A) (cyclicUniformNatSet B)) s x ≠ 0 := by
obtain ⟨s, hs, hsum⟩ := exists_convolution_power_for_dyadic_decay
(show 0 < (g₁ + g₂ - 1) / 2 by linarith)
refine ⟨s, hs, ?_⟩
intro K A B hA hB hM₁ hM₂
apply convolution_pow_nonzero_of_fourier_bound
· rw [dft_cyclicMultiplicativeConvolution_at_zero, dft_cyclicUniformNatSet_at_zero hA,
dft_cyclicUniformNatSet_at_zero hB, mul_one]
· apply hsum
intro x hx
exact norm_dft_mulconv_uniform_conductor_le hA hB hM₁ hM₂ hx
theorem exists_subset_with_prescribed_fiber_card {α β : Type*} [DecidableEq α] [DecidableEq β]
(S : Finset α) (f : α → β) (P : Finset β) (k : ℕ)
(hk : ∀ b ∈ P, k ≤ (S.filter (fun a => f a = b)).card) :
∃ U : Finset α, U ⊆ S ∧ U.image f ⊆ P ∧
(∀ b ∈ P, (U.filter (fun a => f a = b)).card = k) ∧ U.card = P.card * k := by
classical
have hchoose : ∀ b : β, ∃ V : Finset α,
V ⊆ S.filter (fun a => f a = b) ∧ (b ∈ P → V.card = k) := by
intro b
by_cases hb : b ∈ P
· obtain ⟨V, hV, hcard⟩ := Finset.exists_subset_card_eq (hk b hb)
exact ⟨V, hV, fun _ => hcard⟩
· exact ⟨∅, Finset.empty_subset _, by simp [hb]⟩
choose V hV hcard using hchoose
let U := P.biUnion V
have hU : U ⊆ S := by
intro a ha
obtain ⟨b, hb, hab⟩ := Finset.mem_biUnion.mp ha
exact (Finset.mem_filter.mp (hV b hab)).1
have himage : U.image f ⊆ P := by
intro b hb
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hb
obtain ⟨c, hc, hac⟩ := Finset.mem_biUnion.mp ha
exact (Finset.mem_filter.mp (hV c hac)).2.symm ▸ hc
have hfiber : ∀ b ∈ P, U.filter (fun a => f a = b) = V b := by
intro b hb
ext a
constructor
· intro ha
obtain ⟨haU, hab⟩ := Finset.mem_filter.mp ha
obtain ⟨c, hc, hac⟩ := Finset.mem_biUnion.mp haU
have hcb : c = b := (Finset.mem_filter.mp (hV c hac)).2.symm.trans hab
exact hcb ▸ hac
· intro ha
exact Finset.mem_filter.mpr ⟨Finset.mem_biUnion.mpr ⟨b, hb, ha⟩,
(Finset.mem_filter.mp (hV b ha)).2⟩
have hdisjoint : (P : Set β).PairwiseDisjoint V := by
intro b hb c hc hbc
apply Finset.disjoint_left.mpr
intro a hab hac
exact hbc ((Finset.mem_filter.mp (hV b hab)).2.symm.trans (Finset.mem_filter.mp (hV c hac)).2)
refine ⟨U, hU, himage, ?_, ?_⟩
· intro b hb
rw [hfiber b hb, hcard b hb]
· change (P.biUnion V).card = _
rw [Finset.card_biUnion hdisjoint]
calc
∑ b ∈ P, (V b).card = ∑ _b ∈ P, k := Finset.sum_congr rfl hcard
_ = _ := by simp
theorem exists_dyadic_uniform_fibers {α β : Type*} [DecidableEq α] [DecidableEq β]
(S : Finset α) (f : α → β) (T : ℕ)
(hbound : ∀ b ∈ S.image f, (S.filter (fun a => f a = b)).card ≤ 2 ^ T) :
∃ k : ℕ, k ≤ T ∧ ∃ U : Finset α, U ⊆ S ∧
S.card ≤ 2 * (T + 1) * U.card ∧
∀ b ∈ U.image f, (U.filter (fun a => f a = b)).card = 2 ^ k := by
classical
let P := S.image f
let c : β → ℕ := fun b => (S.filter (fun a => f a = b)).card
let bucket : ℕ → Finset β := fun k => P.filter (fun b => Nat.log 2 (c b) = k)
let w : ℕ → ℕ := fun k => ∑ b ∈ bucket k, c b
have hcpos : ∀ b ∈ P, c b ≠ 0 := by
intro b hb
obtain ⟨a, ha, hab⟩ := Finset.mem_image.mp hb
exact Finset.card_ne_zero.mpr ⟨a, Finset.mem_filter.mpr ⟨ha, hab⟩⟩
have hmaps : ∀ b ∈ P, Nat.log 2 (c b) ∈ Finset.range (T + 1) := by
intro b hb
apply Finset.mem_range.mpr
have hlog := Nat.log_monotone (b := 2) (hbound b hb)
rw [Nat.log_pow (by decide : 1 < 2)] at hlog
change Nat.log 2 (c b) ≤ T at hlog
omega
have hsum : (∑ k ∈ Finset.range (T + 1), w k) = S.card := by
change (∑ k ∈ Finset.range (T + 1), ∑ b ∈ P.filter (fun b => Nat.log 2 (c b) = k), c b) = _
rw [Finset.sum_fiberwise_of_maps_to hmaps]
exact (Finset.card_eq_sum_card_image f S).symm
obtain ⟨k, hk, hmax⟩ := Finset.exists_max_image (Finset.range (T + 1)) w
(Finset.nonempty_range_iff.mpr (by omega))
have hbig : S.card ≤ (T + 1) * w k := by
rw [← hsum]
calc
_ ≤ ∑ _i ∈ Finset.range (T + 1), w k := Finset.sum_le_sum hmax
_ = _ := by simp
have hlo : ∀ b ∈ bucket k, 2 ^ k ≤ c b := by
intro b hb
obtain ⟨hbP, hlog⟩ := Finset.mem_filter.mp hb
rw [← hlog]
exact Nat.pow_log_le_self 2 (hcpos b hbP)
have hhi : ∀ b ∈ bucket k, c b ≤ 2 * 2 ^ k := by
intro b hb
have hlog := (Finset.mem_filter.mp hb).2
have hpow := (Nat.lt_pow_succ_log_self (by decide : 1 < 2) (c b)).le
simpa only [hlog, Nat.succ_eq_add_one, pow_succ, Nat.mul_comm] using hpow
obtain ⟨U, hUS, hUP, hfiber, hcard⟩ :=
exists_subset_with_prescribed_fiber_card S f (bucket k) (2 ^ k) hlo
have hw : w k ≤ 2 * U.card := by
change (∑ b ∈ bucket k, c b) ≤ _
calc
_ ≤ ∑ _b ∈ bucket k, 2 * 2 ^ k := Finset.sum_le_sum hhi
_ = 2 * U.card := by simp only [Finset.sum_const, smul_eq_mul, hcard]; ring
refine ⟨k, by have := Finset.mem_range.mp hk; omega, U, hUS, ?_, ?_⟩
· calc
S.card ≤ (T + 1) * w k := hbig
_ ≤ (T + 1) * (2 * U.card) := Nat.mul_le_mul_left _ hw
_ = _ := by ring
· intro b hb
exact hfiber b (hUP hb)
theorem exists_dyadic_first_split {A : Finset ℕ} {b e : ℕ}
(hcard : 1 < A.card) (hbound : ∀ x ∈ A, x < 2 ^ e)
(hbase : ∀ x ∈ A, ∀ y ∈ A, x % 2 ^ b = y % 2 ^ b) :
∃ m : ℕ, b ≤ m ∧ m < e ∧
(∀ x ∈ A, ∀ y ∈ A, x % 2 ^ m = y % 2 ^ m) ∧
∃ x ∈ A, ∃ y ∈ A, x % 2 ^ (m + 1) ≠ y % 2 ^ (m + 1) := by
classical
let P : ℕ → Prop := fun l => ∃ x ∈ A, ∃ y ∈ A, x % 2 ^ l ≠ y % 2 ^ l
have hPe : P e := by
obtain ⟨x, hx, y, hy, hxy⟩ := Finset.one_lt_card.mp hcard
refine ⟨x, hx, y, hy, ?_⟩
simpa only [Nat.mod_eq_of_lt (hbound x hx), Nat.mod_eq_of_lt (hbound y hy)] using hxy
have hex : ∃ l, P l := ⟨e, hPe⟩
let l := Nat.find hex
have hl : P l := Nat.find_spec hex
have hle : l ≤ e := Nat.find_min' hex hPe
have hbl : b < l := by
by_contra hn
have hlb : l ≤ b := by omega
obtain ⟨x, hx, y, hy, hxy⟩ := hl
have hmod : Nat.ModEq (2 ^ b) x y := hbase x hx y hy
exact hxy (hmod.of_dvd (pow_dvd_pow 2 hlb))
refine ⟨l - 1, by omega, by omega, ?_, ?_⟩
· intro x hx y hy
by_contra hxy
exact (Nat.find_min hex (show l - 1 < l by omega)) ⟨x, hx, y, hy, hxy⟩
· simpa only [Nat.sub_add_cancel (show 1 ≤ l by omega)] using hl
theorem dyadic_residue_fiber_card_le {A : Finset ℕ} {b T : ℕ}
(hbound : ∀ x ∈ A, x < 2 ^ (b + T)) (r : ℕ) :
(A.filter (fun x => x % 2 ^ b = r)).card ≤ 2 ^ T := by
classical
let S := A.filter (fun x => x % 2 ^ b = r)
have hinj : Set.InjOn (fun x : ℕ => x / 2 ^ b) S := by
intro x hx y hy hdiv
have hmod : x % 2 ^ b = y % 2 ^ b :=
(Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm
change x / 2 ^ b = y / 2 ^ b at hdiv
calc
x = x % 2 ^ b + 2 ^ b * (x / 2 ^ b) := (Nat.mod_add_div x (2 ^ b)).symm
_ = y % 2 ^ b + 2 ^ b * (y / 2 ^ b) := by rw [hmod, hdiv]
_ = y := Nat.mod_add_div y (2 ^ b)
have himage : S.image (fun x => x / 2 ^ b) ⊆ Finset.range (2 ^ T) := by
intro n hn
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hn
apply Finset.mem_range.mpr
apply (Nat.div_lt_iff_lt_mul (by positivity : 0 < 2 ^ b)).mpr
simpa only [pow_add, Nat.mul_comm] using hbound x (Finset.mem_filter.mp hx).1
calc
_ = (S.image (fun x => x / 2 ^ b)).card := (Finset.card_image_of_injOn hinj).symm
_ ≤ (Finset.range (2 ^ T)).card := Finset.card_le_card himage
_ = _ := Finset.card_range _
theorem exists_large_fiber {α β : Type*} [DecidableEq α] [DecidableEq β]
(S : Finset α) (f : α → β) (P : Finset β) (hP : P.Nonempty)
(hmaps : ∀ a ∈ S, f a ∈ P) :
∃ b ∈ P, S.card ≤ P.card * (S.filter (fun a => f a = b)).card := by
classical
obtain ⟨b, hb, hmax⟩ := Finset.exists_max_image P
(fun b => (S.filter (fun a => f a = b)).card) hP
refine ⟨b, hb, ?_⟩
calc
S.card = ∑ c ∈ P, (S.filter (fun a => f a = c)).card :=
Finset.card_eq_sum_card_fiberwise hmaps
_ ≤ ∑ _c ∈ P, (S.filter (fun a => f a = b)).card := Finset.sum_le_sum hmax
_ = _ := by simp
-- The auxiliary choice of a level is intentionally unconstrained outside the image of S.
theorem exists_dyadic_regular_block {A : Finset ℕ} {b T : ℕ} (hT : 0 < T)
(hbound : ∀ x ∈ A, x < 2 ^ (b + T)) :
∃ U : Finset ℕ, U ⊆ A ∧ ∃ m k : ℕ, b ≤ m ∧ m < b + T ∧ k ≤ T ∧
A.card ≤ 2 * (T + 1) ^ 2 * U.card ∧
(∀ x ∈ U, ∀ y ∈ U, x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m) ∧
∀ r ∈ U.image (fun x => x % 2 ^ m),
(U.filter (fun x => x % 2 ^ m = r)).card = 2 ^ k ∧
(0 < k → ∃ x ∈ U.filter (fun x => x % 2 ^ m = r),
∃ y ∈ U.filter (fun x => x % 2 ^ m = r), x % 2 ^ (m + 1) ≠ y % 2 ^ (m + 1)) := by
classical
obtain ⟨k, hkT, S, hSA, hsize, hcard⟩ := exists_dyadic_uniform_fibers A
(fun x => x % 2 ^ b) T (fun r _ => dyadic_residue_fiber_card_le hbound r)
by_cases hk : k = 0
· refine ⟨S, hSA, b, k, le_rfl, by omega, hkT, ?_, ?_, ?_⟩
· exact hsize.trans (Nat.mul_le_mul_right S.card (by nlinarith))
· intro x hx y hy hxy
exact hxy
· intro r hr
exact ⟨hcard r hr, by simp [hk]⟩
have hkpos : 0 < k := Nat.pos_of_ne_zero hk
let P := S.image (fun x => x % 2 ^ b)
let F : ℕ → Finset ℕ := fun r => S.filter (fun x => x % 2 ^ b = r)
have hchoose : ∀ r : ℕ, ∃ m : ℕ, r ∈ P → b ≤ m ∧ m < b + T ∧
(∀ x ∈ F r, ∀ y ∈ F r, x % 2 ^ m = y % 2 ^ m) ∧
∃ x ∈ F r, ∃ y ∈ F r, x % 2 ^ (m + 1) ≠ y % 2 ^ (m + 1) := by
intro r
by_cases hr : r ∈ P
· have hFr : 1 < (F r).card := by
rw [show (F r).card = 2 ^ k from hcard r hr]
exact one_lt_pow₀ (by decide : 1 < (2 : ℕ)) hkpos.ne'
obtain ⟨m, hm⟩ := exists_dyadic_first_split hFr
(fun x hx => hbound x (hSA (Finset.mem_filter.mp hx).1))
(fun x hx y hy => (Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm)
exact ⟨m, fun _ => hm⟩
· exact ⟨b, fun h => (hr h).elim⟩
choose level hlevel using hchoose
have hmaps : ∀ x ∈ S, level (x % 2 ^ b) ∈ Finset.Ico b (b + T) := by
intro x hx
have hh := hlevel (x % 2 ^ b) (Finset.mem_image_of_mem _ hx)
exact Finset.mem_Ico.mpr ⟨hh.1, hh.2.1⟩
obtain ⟨m, hm, hlarge⟩ := exists_large_fiber S (fun x => level (x % 2 ^ b))
(Finset.Ico b (b + T)) (Finset.nonempty_Ico.mpr (by omega)) hmaps
have hbm : b ≤ m := (Finset.mem_Ico.mp hm).1
have hme : m < b + T := (Finset.mem_Ico.mp hm).2
let U := S.filter (fun x => level (x % 2 ^ b) = m)
have hUS : U ⊆ S := Finset.filter_subset _ _
have hlarge' : S.card ≤ T * U.card := by simpa only [Nat.card_Ico, Nat.add_sub_cancel_left] using hlarge
have hcommon : ∀ x ∈ U, ∀ y ∈ U, x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m := by
intro x hx y hy hxy
have hxS : x ∈ S := hUS hx
have hh := hlevel (x % 2 ^ b) (Finset.mem_image_of_mem _ hxS)
have hxm : level (x % 2 ^ b) = m := (Finset.mem_filter.mp hx).2
rw [hxm] at hh
exact hh.2.2.1 x (Finset.mem_filter.mpr ⟨hxS, rfl⟩) y
(Finset.mem_filter.mpr ⟨hUS hy, hxy.symm⟩)
refine ⟨U, hUS.trans hSA, m, k, hbm, hme, hkT, ?_, hcommon, ?_⟩
· calc
A.card ≤ 2 * (T + 1) * S.card := hsize
_ ≤ 2 * (T + 1) * (T * U.card) := Nat.mul_le_mul_left _ hlarge'
_ = (2 * (T + 1) * T) * U.card := by ring
_ ≤ 2 * (T + 1) ^ 2 * U.card := Nat.mul_le_mul_right _ (by nlinarith)
· intro r hr
obtain ⟨a, haU, har⟩ := Finset.mem_image.mp hr
have haS := hUS haU
have habP : a % 2 ^ b ∈ P := Finset.mem_image_of_mem _ haS
have hla : level (a % 2 ^ b) = m := (Finset.mem_filter.mp haU).2
have hh := hlevel (a % 2 ^ b) habP
rw [hla] at hh
have hfiber : U.filter (fun x => x % 2 ^ m = r) = F (a % 2 ^ b) := by
ext x
constructor
· intro hx
obtain ⟨hxU, hxr⟩ := Finset.mem_filter.mp hx
have hxm : Nat.ModEq (2 ^ m) x a := hxr.trans har.symm
exact Finset.mem_filter.mpr ⟨hUS hxU, hxm.of_dvd (pow_dvd_pow 2 hbm)⟩
· intro hx
obtain ⟨hxS, hxb⟩ := Finset.mem_filter.mp hx
have hxU : x ∈ U := Finset.mem_filter.mpr ⟨hxS, by rw [hxb, hla]⟩
have hxa := hh.2.2.1 x (Finset.mem_filter.mpr ⟨hxS, hxb⟩) a
(Finset.mem_filter.mpr ⟨haS, rfl⟩)
exact Finset.mem_filter.mpr ⟨hxU, hxa.trans har⟩
refine ⟨?_, fun _ => ?_⟩
· rw [hfiber]
exact hcard _ habP
· rw [hfiber]
exact hh.2.2.2
def dyadicProjection (A : Finset ℕ) (j : ℕ) : Finset ℕ :=
A.image (fun x => x % 2 ^ j)
def dyadicLift (A : Finset ℕ) (j : ℕ) (P : Finset ℕ) : Finset ℕ :=
A.filter (fun x => x % 2 ^ j ∈ P)
theorem dyadic_projection_bounded (A : Finset ℕ) (j : ℕ) :
∀ x ∈ dyadicProjection A j, x < 2 ^ j := by
intro x hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
exact Nat.mod_lt _ (by positivity)
theorem dyadic_projection_self {A : Finset ℕ} {j : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ j) : dyadicProjection A j = A := by
ext x
constructor
· intro hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
simpa only [Nat.mod_eq_of_lt (hA a ha)] using ha
· intro hx
exact Finset.mem_image.mpr ⟨x, hx, Nat.mod_eq_of_lt (hA x hx)⟩
theorem dyadic_projection_trans (A : Finset ℕ) {j k : ℕ} (hjk : j ≤ k) :
dyadicProjection (dyadicProjection A k) j = dyadicProjection A j := by
unfold dyadicProjection
rw [Finset.image_image]
apply Finset.image_congr
intro x hx
exact Nat.mod_mod_of_dvd x (pow_dvd_pow 2 hjk)
theorem dyadic_lift_subset (A : Finset ℕ) (j : ℕ) (P : Finset ℕ) :
dyadicLift A j P ⊆ A := Finset.filter_subset _ _
theorem dyadic_projection_lift {A P : Finset ℕ} {j : ℕ}
(hP : P ⊆ dyadicProjection A j) : dyadicProjection (dyadicLift A j P) j = P := by
ext r
constructor
· intro hr
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hr
exact (Finset.mem_filter.mp ha).2
· intro hr
obtain ⟨a, ha, har⟩ := Finset.mem_image.mp (hP hr)
exact Finset.mem_image.mpr ⟨a, Finset.mem_filter.mpr ⟨ha, har.symm ▸ hr⟩, har⟩
theorem dyadic_lift_fiber {A P : Finset ℕ} {j r : ℕ} (hr : r ∈ P) :
(dyadicLift A j P).filter (fun x => x % 2 ^ j = r) =
A.filter (fun x => x % 2 ^ j = r) := by
ext x
constructor
· intro hx
obtain ⟨hx, hxr⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨(Finset.mem_filter.mp hx).1, hxr⟩
· intro hx
obtain ⟨hx, hxr⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨Finset.mem_filter.mpr ⟨hx, hxr.symm ▸ hr⟩, hxr⟩
theorem dyadic_lift_card {A P : Finset ℕ} {j v : ℕ}
(hcard : ∀ r ∈ P, (A.filter (fun x => x % 2 ^ j = r)).card = v) :
(dyadicLift A j P).card = P.card * v := by
have hmaps : ∀ x ∈ dyadicLift A j P, x % 2 ^ j ∈ P := by
intro x hx
exact (Finset.mem_filter.mp hx).2
rw [Finset.card_eq_sum_card_fiberwise hmaps]
calc
_ = ∑ _r ∈ P, v := by
apply Finset.sum_congr rfl
intro r hr
rw [dyadic_lift_fiber hr, hcard r hr]
_ = _ := by simp
structure DyadicTreeBlock (A : Finset ℕ) (b T m k : ℕ) : Prop where
base_le : b ≤ m
split_lt : m < b + T
count_le : k ≤ T
common : ∀ x ∈ A, ∀ y ∈ A, x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m
fiber_card : ∀ r ∈ dyadicProjection A m,
(A.filter (fun x => x % 2 ^ m = r)).card = 2 ^ k
splits : ∀ r ∈ dyadicProjection A m, 0 < k →
∃ x ∈ A.filter (fun x => x % 2 ^ m = r),
∃ y ∈ A.filter (fun x => x % 2 ^ m = r), x % 2 ^ (m + 1) ≠ y % 2 ^ (m + 1)
theorem exists_dyadic_tree_block {A : Finset ℕ} {b T : ℕ} (hT : 0 < T)
(hbound : ∀ x ∈ A, x < 2 ^ (b + T)) :
∃ U : Finset ℕ, U ⊆ A ∧ ∃ m k : ℕ,
DyadicTreeBlock U b T m k ∧ A.card ≤ 2 * (T + 1) ^ 2 * U.card := by
obtain ⟨U, hUA, m, k, hbm, hme, hk, hsize, hcommon, hfiber⟩ :=
exists_dyadic_regular_block hT hbound
exact ⟨U, hUA, m, k, ⟨hbm, hme, hk, hcommon,
fun r hr => (hfiber r hr).1, fun r hr => (hfiber r hr).2⟩, hsize⟩
theorem dyadic_tree_block_base_fiber {A : Finset ℕ} {b T m k a : ℕ}
(hA : DyadicTreeBlock A b T m k) (ha : a ∈ A) :
A.filter (fun x => x % 2 ^ b = a % 2 ^ b) =
A.filter (fun x => x % 2 ^ m = a % 2 ^ m) := by
ext x
constructor
· intro hx
obtain ⟨hxA, hxb⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨hxA, hA.common x hxA a ha hxb⟩
· intro hx
obtain ⟨hxA, hxm⟩ := Finset.mem_filter.mp hx
have hmod : Nat.ModEq (2 ^ m) x a := hxm
exact Finset.mem_filter.mpr ⟨hxA, hmod.of_dvd (pow_dvd_pow 2 hA.base_le)⟩
theorem dyadic_tree_block_base_card {A : Finset ℕ} {b T m k : ℕ}
(hA : DyadicTreeBlock A b T m k) :
∀ r ∈ dyadicProjection A b, (A.filter (fun x => x % 2 ^ b = r)).card = 2 ^ k := by
intro r hr
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hr
rw [dyadic_tree_block_base_fiber hA ha]
exact hA.fiber_card _ (Finset.mem_image_of_mem _ ha)
theorem dyadic_tree_block_card {A : Finset ℕ} {b T m k : ℕ}
(hA : DyadicTreeBlock A b T m k) : A.card = (dyadicProjection A b).card * 2 ^ k := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ b) A]
calc
_ = ∑ _r ∈ dyadicProjection A b, 2 ^ k :=
Finset.sum_congr rfl (dyadic_tree_block_base_card hA)
_ = _ := by simp
theorem dyadic_tree_block_lift {A : Finset ℕ} {b T m k : ℕ}
(hA : DyadicTreeBlock A b T m k) (P : Finset ℕ) :
DyadicTreeBlock (dyadicLift A b P) b T m k := by
have hsub := dyadic_lift_subset A b P
have hfiber : ∀ r ∈ dyadicProjection (dyadicLift A b P) m,
(dyadicLift A b P).filter (fun x => x % 2 ^ m = r) =
A.filter (fun x => x % 2 ^ m = r) := by
intro r hr
obtain ⟨a, ha, har⟩ := Finset.mem_image.mp hr
have haP : a % 2 ^ b ∈ P := (Finset.mem_filter.mp ha).2
ext x
constructor
· intro hx
obtain ⟨hx, hxr⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨hsub hx, hxr⟩
· intro hx
obtain ⟨hxA, hxr⟩ := Finset.mem_filter.mp hx
have hmod : Nat.ModEq (2 ^ m) x a := hxr.trans har.symm
have hxb : x % 2 ^ b = a % 2 ^ b := hmod.of_dvd (pow_dvd_pow 2 hA.base_le)
exact Finset.mem_filter.mpr ⟨Finset.mem_filter.mpr ⟨hxA, hxb.symm ▸ haP⟩, hxr⟩
have hproj : dyadicProjection (dyadicLift A b P) m ⊆ dyadicProjection A m :=
Finset.image_subset_image hsub
refine ⟨hA.base_le, hA.split_lt, hA.count_le, ?_, ?_, ?_⟩
· intro x hx y hy hxy
exact hA.common x (hsub hx) y (hsub hy) hxy
· intro r hr
rw [hfiber r hr]
exact hA.fiber_card r (hproj hr)
· intro r hr hk
rw [hfiber r hr]
exact hA.splits r (hproj hr) hk
def DyadicRegularTree (A : Finset ℕ) (T N : ℕ) : Prop :=
∀ i : ℕ, i < N → ∃ m k : ℕ,
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T m k
theorem exists_dyadic_regular_tree (T : ℕ) (hT : 0 < T) :
∀ N : ℕ, ∀ A : Finset ℕ, (∀ x ∈ A, x < 2 ^ (T * N)) →
∃ B : Finset ℕ, B ⊆ A ∧ DyadicRegularTree B T N ∧
A.card ≤ (2 * (T + 1) ^ 2) ^ N * B.card := by
intro N
induction N with
| zero =>
intro A hA
exact ⟨A, Finset.Subset.refl _, by intro i hi; omega, by simp⟩
| succ N ih =>
intro A hA
have hA' : ∀ x ∈ A, x < 2 ^ (T * N + T) := by
simpa only [Nat.mul_add, Nat.mul_one] using hA
obtain ⟨U, hUA, m, k, hblock, hsize⟩ := exists_dyadic_tree_block hT hA'
obtain ⟨B, hBP, htree, hBsize⟩ := ih (dyadicProjection U (T * N))
(dyadic_projection_bounded U (T * N))
let V := dyadicLift U (T * N) B
have hVU : V ⊆ U := dyadic_lift_subset _ _ _
have hVA : V ⊆ A := hVU.trans hUA
have hVB : dyadicProjection V (T * N) = B := dyadic_projection_lift hBP
have hVcard : V.card = B.card * 2 ^ k :=
dyadic_lift_card (fun r hr => dyadic_tree_block_base_card hblock r (hBP hr))
refine ⟨V, hVA, ?_, ?_⟩
· intro i hi
by_cases hiN : i < N
· obtain ⟨mi, ki, hBi⟩ := htree i hiN
have hle : T * (i + 1) ≤ T * N := Nat.mul_le_mul_left T (by omega)
have hproj : dyadicProjection V (T * (i + 1)) = dyadicProjection B (T * (i + 1)) := by
rw [← hVB]
exact (dyadic_projection_trans V hle).symm
exact ⟨mi, ki, hproj.symm ▸ hBi⟩
· have hiEq : i = N := by omega
subst i
refine ⟨m, k, ?_⟩
rw [dyadic_projection_self (fun x hx => hA x (hVA hx))]
exact dyadic_tree_block_lift hblock B
· calc
A.card ≤ 2 * (T + 1) ^ 2 * U.card := hsize
_ = (2 * (T + 1) ^ 2) * ((dyadicProjection U (T * N)).card * 2 ^ k) := by
rw [dyadic_tree_block_card hblock]
_ ≤ (2 * (T + 1) ^ 2) * (((2 * (T + 1) ^ 2) ^ N * B.card) * 2 ^ k) :=
Nat.mul_le_mul_left _ (Nat.mul_le_mul_right _ hBsize)
_ = (2 * (T + 1) ^ 2) ^ (N + 1) * V.card := by rw [hVcard, pow_succ]; ring
theorem eventually_dyadic_regularization_cost_le {η : ℝ} (hη : 0 < η) :
∀ᶠ T : ℕ in Filter.atTop,
(2 : ℝ) * ((T : ℝ) + 1) ^ 2 ≤ (2 : ℝ) ^ (η * (T : ℝ)) := by
have hb : 0 < Real.log 2 * η := mul_pos (Real.log_pos (by norm_num)) hη
have hsmall := ((isLittleO_pow_exp_pos_mul_atTop 2 hb).const_mul_left (8 : ℝ)).comp_tendsto
(tendsto_natCast_atTop_atTop (R := ℝ))
filter_upwards [hsmall.def (by norm_num : (0 : ℝ) < 1), eventually_ge_atTop (1 : ℕ)] with T hT hTpos
have hTreal : (1 : ℝ) ≤ T := by exact_mod_cast hTpos
have hexp : 8 * (T : ℝ) ^ 2 ≤ Real.exp ((Real.log 2 * η) * (T : ℝ)) := by
simpa only [Function.comp_apply, Real.norm_eq_abs, one_mul,
abs_of_nonneg (by positivity : (0 : ℝ) ≤ 8 * (T : ℝ) ^ 2),
abs_of_pos (Real.exp_pos _)] using hT
calc
(2 : ℝ) * ((T : ℝ) + 1) ^ 2 ≤ 8 * (T : ℝ) ^ 2 := by nlinarith
_ ≤ Real.exp ((Real.log 2 * η) * (T : ℝ)) := hexp
_ = (2 : ℝ) ^ (η * (T : ℝ)) := by rw [Real.rpow_def_of_pos (by norm_num), mul_assoc]
theorem exists_dyadic_regular_tree_small_loss {η : ℝ} (hη : 0 < η) :
∃ T : ℕ, 0 < T ∧ ∀ N : ℕ, ∀ A : Finset ℕ, (∀ x ∈ A, x < 2 ^ (T * N)) →
∃ B : Finset ℕ, B ⊆ A ∧ DyadicRegularTree B T N ∧
(A.card : ℝ) ≤ (2 : ℝ) ^ (η * ((T * N : ℕ) : ℝ)) * (B.card : ℝ) := by
obtain ⟨T₀, hT₀⟩ := Filter.eventually_atTop.mp (eventually_dyadic_regularization_cost_le hη)
let T := max T₀ 1
have hT : 0 < T := lt_of_lt_of_le (by decide : 0 < 1) (le_max_right _ _)
have hcost : (2 : ℝ) * ((T : ℝ) + 1) ^ 2 ≤ (2 : ℝ) ^ (η * (T : ℝ)) :=
hT₀ T (le_max_left _ _)
refine ⟨T, hT, ?_⟩
intro N A hA
obtain ⟨B, hBA, htree, hsize⟩ := exists_dyadic_regular_tree T hT N A hA
refine ⟨B, hBA, htree, ?_⟩
have hsize' : (A.card : ℝ) ≤ ((2 : ℝ) * ((T : ℝ) + 1) ^ 2) ^ N * (B.card : ℝ) := by
exact_mod_cast hsize
calc
(A.card : ℝ) ≤ ((2 : ℝ) * ((T : ℝ) + 1) ^ 2) ^ N * (B.card : ℝ) := hsize'
_ ≤ ((2 : ℝ) ^ (η * (T : ℝ))) ^ N * (B.card : ℝ) :=
mul_le_mul_of_nonneg_right (pow_le_pow_left₀ (by positivity) hcost N) (Nat.cast_nonneg _)
_ = (2 : ℝ) ^ (η * ((T * N : ℕ) : ℝ)) * (B.card : ℝ) := by
rw [← Real.rpow_mul_natCast (by norm_num), Nat.cast_mul, mul_assoc]
theorem dyadic_projection_fiber_self {A : Finset ℕ} {j r : ℕ}
(hr : r ∈ dyadicProjection A j) :
(dyadicProjection A j).filter (fun x => x % 2 ^ j = r) = {r} := by
ext x
constructor
· intro hx
obtain ⟨hxP, hxr⟩ := Finset.mem_filter.mp hx
have hxlt := dyadic_projection_bounded A j x hxP
rw [Nat.mod_eq_of_lt hxlt] at hxr
exact Finset.mem_singleton.mpr hxr
· intro hx
have hxr := Finset.mem_singleton.mp hx
subst x
exact Finset.mem_filter.mpr ⟨hr, Nat.mod_eq_of_lt (dyadic_projection_bounded A j r hr)⟩
theorem dyadic_lift_coarse_fiber (A : Finset ℕ) {b e : ℕ} (hbe : b ≤ e) (r : ℕ) :
dyadicLift A e ((dyadicProjection A e).filter (fun y => y % 2 ^ b = r)) =
A.filter (fun x => x % 2 ^ b = r) := by
ext x
constructor
· intro hx
obtain ⟨hxA, hxf⟩ := Finset.mem_filter.mp hx
have hmod := (Finset.mem_filter.mp hxf).2
rw [Nat.mod_mod_of_dvd x (pow_dvd_pow 2 hbe)] at hmod
exact Finset.mem_filter.mpr ⟨hxA, hmod⟩
· intro hx
obtain ⟨hxA, hxr⟩ := Finset.mem_filter.mp hx
refine Finset.mem_filter.mpr ⟨hxA, Finset.mem_filter.mpr ⟨Finset.mem_image_of_mem _ hxA, ?_⟩⟩
rwa [Nat.mod_mod_of_dvd x (pow_dvd_pow 2 hbe)]
theorem dyadic_fiber_card_mul (A : Finset ℕ) {b e v : ℕ} (hbe : b ≤ e)
(hcard : ∀ s ∈ dyadicProjection A e, (A.filter (fun x => x % 2 ^ e = s)).card = v) (r : ℕ) :
(A.filter (fun x => x % 2 ^ b = r)).card =
((dyadicProjection A e).filter (fun x => x % 2 ^ b = r)).card * v := by
rw [← dyadic_lift_coarse_fiber A hbe r]
exact dyadic_lift_card (fun s hs => hcard s (Finset.mem_filter.mp hs).1)
theorem dyadic_regular_tree_uniform_fibers {A : Finset ℕ} {T N : ℕ}
(htree : DyadicRegularTree A T N) : ∀ j : ℕ, j ≤ N → ∀ i : ℕ, i ≤ j →
∃ v : ℕ, 0 < v ∧ ∀ r ∈ dyadicProjection A (T * i),
((dyadicProjection A (T * j)).filter (fun x => x % 2 ^ (T * i) = r)).card = v := by
intro j
induction j with
| zero =>
intro hj i hi
have hi0 : i = 0 := by omega
subst i
refine ⟨1, by decide, ?_⟩
intro r hr
rw [dyadic_projection_fiber_self hr, Finset.card_singleton]
| succ j ih =>
intro hj i hi
by_cases hij : i = j + 1
· subst i
refine ⟨1, by decide, ?_⟩
intro r hr
rw [dyadic_projection_fiber_self hr, Finset.card_singleton]
have hij' : i ≤ j := by omega
obtain ⟨v, hv, hvc⟩ := ih (by omega) i hij'
obtain ⟨m, k, hblock⟩ := htree j (by omega)
refine ⟨v * 2 ^ k, by positivity, ?_⟩
intro r hr
rw [dyadic_fiber_card_mul _ (Nat.mul_le_mul_left T hij')
(dyadic_tree_block_base_card hblock) r]
rw [dyadic_projection_trans A (Nat.mul_le_mul_left T (show j ≤ j + 1 by omega)), hvc r hr]
theorem dyadic_regular_tree_residue_mass {A : Finset ℕ} {T N i r : ℕ}
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hi : i ≤ N) (hr : r ∈ dyadicProjection A (T * i)) :
natResidueMass A (2 ^ (T * i)) r = 1 / ((dyadicProjection A (T * i)).card : ℝ) := by
obtain ⟨v, hv, hvc⟩ := dyadic_regular_tree_uniform_fibers htree N le_rfl i hi
rw [dyadic_projection_self hbound] at hvc
have hcard : A.card = (dyadicProjection A (T * i)).card * v := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ (T * i)) A]
calc
_ = ∑ _s ∈ dyadicProjection A (T * i), v := Finset.sum_congr rfl hvc
_ = _ := by simp
have hfiber : (natResidueFiber A (2 ^ (T * i)) r).card = v := by
simpa only [natResidueFiber, Nat.ModEq,
Nat.mod_eq_of_lt (dyadic_projection_bounded A (T * i) r hr)] using hvc r hr
have hvR : (v : ℝ) ≠ 0 := by exact_mod_cast hv.ne'
have hcR : ((dyadicProjection A (T * i)).card : ℝ) ≠ 0 := by
exact_mod_cast Finset.card_ne_zero.mpr ⟨r, hr⟩
unfold natResidueMass
rw [hfiber, hcard, Nat.cast_mul]
field_simp
theorem nat_sumset_card_ge_projection_mul_fiber (A B : Finset ℕ) (q : ℕ)
(hB : ∀ x ∈ B, ∀ y ∈ B, x % q = y % q) :
(A.image (fun x => x % q)).card * B.card ≤
((A ×ˢ B).image (fun p => p.1 + p.2)).card := by
classical
have hnonempty : ∀ r ∈ A.image (fun x => x % q),
1 ≤ (A.filter (fun x => x % q = r)).card := by
intro r hr
obtain ⟨x, hx, hxr⟩ := Finset.mem_image.mp hr
exact Finset.card_pos.mpr ⟨x, Finset.mem_filter.mpr ⟨hx, hxr⟩⟩
obtain ⟨R, hRA, hRP, hfiber, hRcard⟩ := exists_subset_with_prescribed_fiber_card A
(fun x => x % q) (A.image (fun x => x % q)) 1 hnonempty
have hRinj : Set.InjOn (fun x : ℕ => x % q) R := by
intro x hx y hy hxy
have hcard : (R.filter (fun z => z % q = x % q)).card ≤ 1 := by
rw [hfiber _ (Finset.mem_image_of_mem _ (hRA hx))]
exact Finset.card_le_one.mp hcard x (Finset.mem_filter.mpr ⟨hx, rfl⟩) y
(Finset.mem_filter.mpr ⟨hy, hxy.symm⟩)
have hinj : Set.InjOn (fun p : ℕ × ℕ => p.1 + p.2) (R ×ˢ B : Finset (ℕ × ℕ)) := by
intro p hp s hs hsum
change p.1 + p.2 = s.1 + s.2 at hsum
obtain ⟨hpR, hpB⟩ := Finset.mem_product.mp hp
obtain ⟨hsR, hsB⟩ := Finset.mem_product.mp hs
have hmodB : Nat.ModEq q p.2 s.2 := hB _ hpB _ hsB
have hmodsum : Nat.ModEq q (p.1 + p.2) (s.1 + s.2) := by rw [hsum]
have hfst : p.1 = s.1 := hRinj hpR hsR (hmodB.add_right_cancel hmodsum)
have hsnd : p.2 = s.2 := by omega
exact Prod.ext hfst hsnd
calc
_ = R.card * B.card := by rw [hRcard, mul_one]
_ = (R ×ˢ B).card := (Finset.card_product R B).symm
_ = ((R ×ˢ B).image (fun p => p.1 + p.2)).card := (Finset.card_image_of_injOn hinj).symm
_ ≤ _ := Finset.card_le_card (Finset.image_subset_image
(Finset.product_subset_product hRA (Finset.Subset.refl B)))
theorem dyadic_projection_zero {A : Finset ℕ} (hA : A.Nonempty) : dyadicProjection A 0 = {0} := by
simpa only [dyadicProjection, pow_zero, Nat.mod_one] using Finset.image_const hA (0 : ℕ)
theorem exists_dyadic_prefix_growth {A : Finset ℕ} (hA : A.Nonempty) (T N : ℕ) (δ : ℝ) :
∃ i : ℕ, i ≤ N ∧ ((dyadicProjection A (T * i)).card : ℝ) ≤ (2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ)) ∧
∀ j : ℕ, i ≤ j → j ≤ N →
((dyadicProjection A (T * i)).card : ℝ) * (2 : ℝ) ^ (δ * ((T * (j - i) : ℕ) : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ) := by
classical
let w : ℕ → ℝ := fun i => ((dyadicProjection A (T * i)).card : ℝ) /
(2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ))
obtain ⟨i, hi, hmin⟩ := Finset.exists_min_image (Finset.range (N + 1)) w
(Finset.nonempty_range_iff.mpr (by omega))
have hpow (j : ℕ) : 0 < (2 : ℝ) ^ (δ * ((T * j : ℕ) : ℝ)) :=
Real.rpow_pos_of_pos (by norm_num) _
have hzero : w 0 = 1 := by
simp only [w, dyadic_projection_zero hA, Finset.card_singleton,
Nat.cast_one, Nat.cast_zero, mul_zero, Real.rpow_zero, div_one]
have hiupper : ((dyadicProjection A (T * i)).card : ℝ) ≤ (2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ)) := by
have hh := hmin 0 (Finset.mem_range.mpr (by omega : 0 < N + 1))
rw [hzero] at hh
exact (div_le_one (hpow i)).mp hh
refine ⟨i, by have := Finset.mem_range.mp hi; omega, hiupper, ?_⟩
intro j hij hjN
have hh : ((dyadicProjection A (T * i)).card : ℝ) / (2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ) / (2 : ℝ) ^ (δ * ((T * j : ℕ) : ℝ)) :=
hmin j (Finset.mem_range.mpr (by omega))
have hcross := (div_le_div_iff₀ (hpow i) (hpow j)).mp hh
have hfactor : (2 : ℝ) ^ (δ * ((T * j : ℕ) : ℝ)) =
(2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ)) * (2 : ℝ) ^ (δ * ((T * (j - i) : ℕ) : ℝ)) := by
rw [← Real.rpow_add (by norm_num)]
congr 1
simp only [Nat.cast_mul, Nat.cast_sub hij]
ring
rw [hfactor] at hcross
apply (mul_le_mul_iff_left₀ (hpow i)).mp
convert hcross using 1
ring
theorem dyadic_regular_tree_projection_growth_bound {A B : Finset ℕ} {T N i : ℕ}
(hBA : B ⊆ A) (hB : B.Nonempty) (htree : DyadicRegularTree B T N)
(hbound : ∀ x ∈ B, x < 2 ^ (T * N)) (hi : i ≤ N) :
(dyadicProjection A (T * i)).card * B.card ≤
(dyadicProjection B (T * i)).card * ((A ×ˢ A).image (fun p => p.1 + p.2)).card := by
obtain ⟨v, hv, hvc⟩ := dyadic_regular_tree_uniform_fibers htree N le_rfl i hi
rw [dyadic_projection_self hbound] at hvc
obtain ⟨a, ha⟩ := hB
let r := a % 2 ^ (T * i)
have hr : r ∈ dyadicProjection B (T * i) := Finset.mem_image_of_mem _ ha
let C := B.filter (fun x => x % 2 ^ (T * i) = r)
have hCB : C ⊆ B := Finset.filter_subset _ _
have hCA : C ⊆ A := hCB.trans hBA
have hCcard : C.card = v := hvc r hr
have hBcard : B.card = (dyadicProjection B (T * i)).card * v := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ (T * i)) B]
calc
_ = ∑ _s ∈ dyadicProjection B (T * i), v := Finset.sum_congr rfl hvc
_ = _ := by simp
have hsum : (dyadicProjection A (T * i)).card * v ≤
((A ×ˢ A).image (fun p => p.1 + p.2)).card := by
rw [← hCcard]
calc
_ ≤ ((A ×ˢ C).image (fun p => p.1 + p.2)).card :=
nat_sumset_card_ge_projection_mul_fiber A C (2 ^ (T * i))
(fun x hx y hy => (Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm)
_ ≤ _ := Finset.card_le_card (Finset.image_subset_image
(Finset.product_subset_product (Finset.Subset.refl A) hCA))
rw [hBcard]
calc
_ = (dyadicProjection B (T * i)).card * ((dyadicProjection A (T * i)).card * v) := by ring
_ ≤ _ := Nat.mul_le_mul_left _ hsum
theorem nat_modular_sumset_card_ge_projection_mul_fiber (A B : Finset ℕ) {q Q : ℕ}
(hq : q ∣ Q) (hbound : ∀ x ∈ B, x < Q)
(hB : ∀ x ∈ B, ∀ y ∈ B, x % q = y % q) :
(A.image (fun x => x % q)).card * B.card ≤
((A ×ˢ B).image (fun p => (p.1 + p.2) % Q)).card := by
classical
have hnonempty : ∀ r ∈ A.image (fun x => x % q),
1 ≤ (A.filter (fun x => x % q = r)).card := by
intro r hr
obtain ⟨x, hx, hxr⟩ := Finset.mem_image.mp hr
exact Finset.card_pos.mpr ⟨x, Finset.mem_filter.mpr ⟨hx, hxr⟩⟩
obtain ⟨R, hRA, hRP, hfiber, hRcard⟩ := exists_subset_with_prescribed_fiber_card A
(fun x => x % q) (A.image (fun x => x % q)) 1 hnonempty
have hRinj : Set.InjOn (fun x : ℕ => x % q) R := by
intro x hx y hy hxy
have hcard : (R.filter (fun z => z % q = x % q)).card ≤ 1 := by
rw [hfiber _ (Finset.mem_image_of_mem _ (hRA hx))]
exact Finset.card_le_one.mp hcard x (Finset.mem_filter.mpr ⟨hx, rfl⟩) y
(Finset.mem_filter.mpr ⟨hy, hxy.symm⟩)
have hinj : Set.InjOn (fun p : ℕ × ℕ => (p.1 + p.2) % Q) (R ×ˢ B : Finset (ℕ × ℕ)) := by
intro p hp s hs hsum
change (p.1 + p.2) % Q = (s.1 + s.2) % Q at hsum
obtain ⟨hpR, hpB⟩ := Finset.mem_product.mp hp
obtain ⟨hsR, hsB⟩ := Finset.mem_product.mp hs
have hmodB : Nat.ModEq q p.2 s.2 := hB _ hpB _ hsB
have hmodsum : Nat.ModEq Q (p.1 + p.2) (s.1 + s.2) := hsum
have hfst : p.1 = s.1 := hRinj hpR hsR (hmodB.add_right_cancel (hmodsum.of_dvd hq))
have hmodsnd : Nat.ModEq Q p.2 s.2 := by
rw [hfst] at hmodsum
exact (Nat.ModEq.refl s.1).add_left_cancel hmodsum
have hsnd : p.2 = s.2 := by
simpa only [Nat.ModEq, Nat.mod_eq_of_lt (hbound _ hpB), Nat.mod_eq_of_lt (hbound _ hsB)] using hmodsnd
exact Prod.ext hfst hsnd
calc
_ = R.card * B.card := by rw [hRcard, mul_one]
_ = (R ×ˢ B).card := (Finset.card_product R B).symm
_ = ((R ×ˢ B).image (fun p => (p.1 + p.2) % Q)).card := (Finset.card_image_of_injOn hinj).symm
_ ≤ _ := Finset.card_le_card (Finset.image_subset_image
(Finset.product_subset_product hRA (Finset.Subset.refl B)))
theorem dyadic_regular_tree_modular_growth_bound {A B : Finset ℕ} {T N i : ℕ}
(hBA : B ⊆ A) (hB : B.Nonempty) (htree : DyadicRegularTree B T N)
(hbound : ∀ x ∈ B, x < 2 ^ (T * N)) (hi : i ≤ N) :
(dyadicProjection A (T * i)).card * B.card ≤
(dyadicProjection B (T * i)).card *
((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card := by
obtain ⟨v, hv, hvc⟩ := dyadic_regular_tree_uniform_fibers htree N le_rfl i hi
rw [dyadic_projection_self hbound] at hvc
obtain ⟨a, ha⟩ := hB
let r := a % 2 ^ (T * i)
have hr : r ∈ dyadicProjection B (T * i) := Finset.mem_image_of_mem _ ha
let C := B.filter (fun x => x % 2 ^ (T * i) = r)
have hCB : C ⊆ B := Finset.filter_subset _ _
have hCA : C ⊆ A := hCB.trans hBA
have hCcard : C.card = v := hvc r hr
have hBcard : B.card = (dyadicProjection B (T * i)).card * v := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ (T * i)) B]
calc
_ = ∑ _s ∈ dyadicProjection B (T * i), v := Finset.sum_congr rfl hvc
_ = _ := by simp
have hsum : (dyadicProjection A (T * i)).card * v ≤
((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card := by
rw [← hCcard]
calc
_ ≤ ((A ×ˢ C).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card :=
nat_modular_sumset_card_ge_projection_mul_fiber A C (pow_dvd_pow 2 (Nat.mul_le_mul_left T hi))
(fun x hx => hbound x (hCB hx))
(fun x hx y hy => (Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm)
_ ≤ _ := Finset.card_le_card (Finset.image_subset_image
(Finset.product_subset_product (Finset.Subset.refl A) hCA))
rw [hBcard]
calc
_ = (dyadicProjection B (T * i)).card * ((dyadicProjection A (T * i)).card * v) := by ring
_ ≤ _ := Nat.mul_le_mul_left _ hsum
theorem dyadic_projection_card_of_common {A : Finset ℕ} {b m : ℕ} (hbm : b ≤ m)
(hcommon : ∀ x ∈ A, ∀ y ∈ A, x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m) :
(dyadicProjection A m).card = (dyadicProjection A b).card := by
have hinj : Set.InjOn (fun x : ℕ => x % 2 ^ b) (dyadicProjection A m) := by
intro x hx y hy hxy
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨c, hc, rfl⟩ := Finset.mem_image.mp hy
have hac : a % 2 ^ b = c % 2 ^ b := by
simpa only [Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hbm)] using hxy
exact hcommon a ha c hc hac
calc
_ = (dyadicProjection (dyadicProjection A m) b).card := (Finset.card_image_of_injOn hinj).symm
_ = _ := by rw [dyadic_projection_trans A hbm]
theorem exists_regular_tree_dense_tail {A B : Finset ℕ} {T N : ℕ}
(hT : 0 < T) (hBA : B ⊆ A) (hB : B.Nonempty) (htree : DyadicRegularTree B T N)
(hbound : ∀ x ∈ B, x < 2 ^ (T * N)) {γ δ ε η κ : ℝ}
(hgap : δ < γ) (hbudget : κ + η ≤ ε * (γ - δ))
(hlarge : (A.card : ℝ) ≤ (2 : ℝ) ^ (η * ((T * N : ℕ) : ℝ)) * (B.card : ℝ))
(hsmall : (((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card : ℝ) ≤
(2 : ℝ) ^ (κ * ((T * N : ℕ) : ℝ)) * (A.card : ℝ))
(hprojection : ∀ j : ℕ, j ≤ N → ε * (N : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * ((T * j : ℕ) : ℝ)) ≤ ((dyadicProjection A (T * j)).card : ℝ)) :
∃ i : ℕ, i ≤ N ∧ (i : ℝ) ≤ ε * (N : ℝ) ∧
((dyadicProjection B (T * i)).card : ℝ) ≤ (2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ)) ∧
∀ j : ℕ, i ≤ j → j ≤ N →
((dyadicProjection B (T * i)).card : ℝ) * (2 : ℝ) ^ (δ * ((T * (j - i) : ℕ) : ℝ)) ≤
((dyadicProjection B (T * j)).card : ℝ) := by
obtain ⟨i, hiN, hPi, htail⟩ := exists_dyadic_prefix_growth hB T N δ
refine ⟨i, hiN, ?_, hPi, htail⟩
by_contra hi
have hiε : ε * (N : ℝ) < (i : ℝ) := lt_of_not_ge hi
have hPA := hprojection i hiN hiε
have hgrowth : ((dyadicProjection A (T * i)).card : ℝ) * (B.card : ℝ) ≤
((dyadicProjection B (T * i)).card : ℝ) *
(((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card : ℝ) := by
exact_mod_cast dyadic_regular_tree_modular_growth_bound hBA hB htree hbound hiN
have hprod : (2 : ℝ) ^ (γ * ((T * i : ℕ) : ℝ)) * (B.card : ℝ) ≤
(2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ) + (κ + η) * ((T * N : ℕ) : ℝ)) * (B.card : ℝ) := by
calc
_ ≤ ((dyadicProjection A (T * i)).card : ℝ) * (B.card : ℝ) :=
mul_le_mul_of_nonneg_right hPA (Nat.cast_nonneg _)
_ ≤ _ := hgrowth
_ ≤ (2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ)) *
((2 : ℝ) ^ (κ * ((T * N : ℕ) : ℝ)) * (A.card : ℝ)) :=
mul_le_mul hPi hsmall (Nat.cast_nonneg _) (Real.rpow_nonneg (by norm_num) _)
_ ≤ (2 : ℝ) ^ (δ * ((T * i : ℕ) : ℝ)) *
((2 : ℝ) ^ (κ * ((T * N : ℕ) : ℝ)) *
((2 : ℝ) ^ (η * ((T * N : ℕ) : ℝ)) * (B.card : ℝ))) := by
apply mul_le_mul_of_nonneg_left
· exact mul_le_mul_of_nonneg_left hlarge (Real.rpow_nonneg (by norm_num) _)
· exact Real.rpow_nonneg (by norm_num) _
_ = _ := by
simp only [← mul_assoc]
rw [← Real.rpow_add (show (0 : ℝ) < 2 by norm_num),
← Real.rpow_add (show (0 : ℝ) < 2 by norm_num)]
congr 2
ring
have hBpos : (0 : ℝ) < B.card := by exact_mod_cast Finset.card_pos.mpr hB
have hpow := (mul_le_mul_iff_of_pos_right hBpos).mp hprod
have hexp := (Real.rpow_le_rpow_left_iff (by norm_num : (1 : ℝ) < 2)).mp hpow
simp only [Nat.cast_mul] at hexp
have hTpos : (0 : ℝ) < T := by exact_mod_cast hT
have htailbound : (γ - δ) * (i : ℝ) ≤ (κ + η) * (N : ℝ) := by
apply (mul_le_mul_iff_of_pos_left hTpos).mp
nlinarith [hexp]
have hbudgetN := mul_le_mul_of_nonneg_right hbudget (Nat.cast_nonneg N : (0 : ℝ) ≤ N)
have hcancel : (γ - δ) * (i : ℝ) ≤ (γ - δ) * (ε * (N : ℝ)) := by nlinarith
exact hi ((mul_le_mul_iff_of_pos_left (sub_pos.mpr hgap)).mp hcancel)
def dyadicZoom (A : Finset ℕ) (b r : ℕ) : Finset ℕ :=
(A.filter (fun x => x % 2 ^ b = r)).image (fun x => x / 2 ^ b)
theorem dyadic_zoom_card (A : Finset ℕ) (b r : ℕ) :
(dyadicZoom A b r).card = (A.filter (fun x => x % 2 ^ b = r)).card := by
apply Finset.card_image_of_injOn
intro x hx y hy hdiv
change x / 2 ^ b = y / 2 ^ b at hdiv
have hmod : x % 2 ^ b = y % 2 ^ b :=
(Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm
calc
x = x % 2 ^ b + 2 ^ b * (x / 2 ^ b) := (Nat.mod_add_div x (2 ^ b)).symm
_ = y % 2 ^ b + 2 ^ b * (y / 2 ^ b) := by rw [hmod, hdiv]
_ = y := Nat.mod_add_div y (2 ^ b)
theorem dyadic_zoom_nonempty {A : Finset ℕ} {b r : ℕ} (hr : r ∈ dyadicProjection A b) :
(dyadicZoom A b r).Nonempty := by
obtain ⟨a, ha, har⟩ := Finset.mem_image.mp hr
exact (show (A.filter (fun x => x % 2 ^ b = r)).Nonempty from
⟨a, Finset.mem_filter.mpr ⟨ha, har⟩⟩).image _
theorem dyadic_zoom_bounded {A : Finset ℕ} {b e : ℕ}
(hA : ∀ x ∈ A, x < 2 ^ (b + e)) (r : ℕ) :
∀ x ∈ dyadicZoom A b r, x < 2 ^ e := by
intro x hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
apply (Nat.div_lt_iff_lt_mul (by positivity : 0 < 2 ^ b)).mpr
simpa only [pow_add, Nat.mul_comm] using hA a (Finset.mem_filter.mp ha).1
theorem dyadic_projection_zoom (A : Finset ℕ) (b r l : ℕ) :
dyadicProjection (dyadicZoom A b r) l = dyadicZoom (dyadicProjection A (b + l)) b r := by
have hmod (a : ℕ) : a % 2 ^ (b + l) % 2 ^ b = a % 2 ^ b :=
Nat.mod_mod_of_dvd a (pow_dvd_pow 2 (by omega))
have hdiv (a : ℕ) : a % 2 ^ (b + l) / 2 ^ b = a / 2 ^ b % 2 ^ l := by
rw [pow_add]
exact Nat.mod_mul_right_div_self _ _ _
ext z
constructor
· intro hz
obtain ⟨y, hy, hyz⟩ := Finset.mem_image.mp hz
obtain ⟨a, ha, hay⟩ := Finset.mem_image.mp hy
obtain ⟨haA, har⟩ := Finset.mem_filter.mp ha
refine Finset.mem_image.mpr ⟨a % 2 ^ (b + l), ?_, ?_⟩
· exact Finset.mem_filter.mpr ⟨Finset.mem_image_of_mem _ haA, (hmod a).trans har⟩
· rw [hdiv a, hay, hyz]
· intro hz
obtain ⟨y, hy, hyz⟩ := Finset.mem_image.mp hz
obtain ⟨hyP, hyr⟩ := Finset.mem_filter.mp hy
obtain ⟨a, haA, hay⟩ := Finset.mem_image.mp hyP
have har : a % 2 ^ b = r := by rw [← hmod a, hay, hyr]
refine Finset.mem_image.mpr ⟨a / 2 ^ b, ?_, ?_⟩
· exact Finset.mem_image.mpr ⟨a, Finset.mem_filter.mpr ⟨haA, har⟩, rfl⟩
· rw [← hdiv a, hay, hyz]
theorem dyadic_regular_tree_zoom_projection_card {A : Finset ℕ} {T N i j r : ℕ}
(htree : DyadicRegularTree A T N) (hij : i + j ≤ N)
(hr : r ∈ dyadicProjection A (T * i)) :
(dyadicProjection A (T * i)).card *
(dyadicProjection (dyadicZoom A (T * i) r) (T * j)).card =
(dyadicProjection A (T * (i + j))).card := by
have hlevel : T * i ≤ T * (i + j) := Nat.mul_le_mul_left T (by omega)
obtain ⟨v, hv, hvc⟩ := dyadic_regular_tree_uniform_fibers htree (i + j) hij i (by omega)
have hcard : (dyadicProjection A (T * (i + j))).card = (dyadicProjection A (T * i)).card * v := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ (T * i)) (dyadicProjection A (T * (i + j)))]
change (∑ s ∈ dyadicProjection (dyadicProjection A (T * (i + j))) (T * i), _) = _
rw [dyadic_projection_trans A hlevel]
calc
_ = ∑ _s ∈ dyadicProjection A (T * i), v := Finset.sum_congr rfl hvc
_ = _ := by simp
rw [dyadic_projection_zoom, ← Nat.mul_add, dyadic_zoom_card, hvc r hr, hcard]
theorem dyadic_regular_tree_zoom_card {A : Finset ℕ} {T N i r : ℕ}
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N)) (hi : i ≤ N)
(hr : r ∈ dyadicProjection A (T * i)) :
(dyadicProjection A (T * i)).card * (dyadicZoom A (T * i) r).card = A.card := by
have hzoom := dyadic_zoom_bounded (b := T * i) (e := T * (N - i))
(by simpa only [← Nat.mul_add, Nat.add_sub_of_le hi] using hbound) r
have hh := dyadic_regular_tree_zoom_projection_card (j := N - i) htree (by omega) hr
simpa only [dyadic_projection_self hzoom, Nat.add_sub_of_le hi, dyadic_projection_self hbound] using hh
theorem dyadic_regular_tree_zoom_growth {A : Finset ℕ} {T N i r : ℕ} {δ : ℝ}
(htree : DyadicRegularTree A T N) (hr : r ∈ dyadicProjection A (T * i))
(hgrowth : ∀ j : ℕ, i ≤ j → j ≤ N →
((dyadicProjection A (T * i)).card : ℝ) * (2 : ℝ) ^ (δ * ((T * (j - i) : ℕ) : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) :
∀ j : ℕ, i + j ≤ N → (2 : ℝ) ^ (δ * ((T * j : ℕ) : ℝ)) ≤
((dyadicProjection (dyadicZoom A (T * i) r) (T * j)).card : ℝ) := by
intro j hj
have hpos : (0 : ℝ) < (dyadicProjection A (T * i)).card := by
exact_mod_cast Finset.card_pos.mpr ⟨r, hr⟩
have hh := hgrowth (i + j) (by omega) hj
rw [Nat.add_sub_cancel_left] at hh
have heq : ((dyadicProjection A (T * i)).card : ℝ) *
((dyadicProjection (dyadicZoom A (T * i) r) (T * j)).card : ℝ) =
((dyadicProjection A (T * (i + j))).card : ℝ) := by
exact_mod_cast dyadic_regular_tree_zoom_projection_card htree hj hr
rw [← heq] at hh
exact (mul_le_mul_iff_of_pos_left hpos).mp hh
theorem dyadic_join_injective (d r : ℕ) :
Function.Injective (fun x : ℕ => r + 2 ^ d * x) := by
intro x y hxy
exact Nat.eq_of_mul_eq_mul_left (by positivity : 0 < 2 ^ d) (Nat.add_left_cancel hxy)
theorem dyadic_join_div {d r : ℕ} (hr : r < 2 ^ d) (x : ℕ) :
(r + 2 ^ d * x) / 2 ^ d = x := by
rw [Nat.add_mul_div_left _ _ (by positivity), Nat.div_eq_of_lt hr, zero_add]
theorem dyadic_join_mod {d r : ℕ} (hr : r < 2 ^ d) (l x : ℕ) :
(r + 2 ^ d * x) % 2 ^ (d + l) = r + 2 ^ d * (x % 2 ^ l) := by
have hx : x % 2 ^ l < 2 ^ l := Nat.mod_lt _ (by positivity)
have hbound : r + 2 ^ d * (x % 2 ^ l) < 2 ^ (d + l) := by
rw [pow_add]
have hmul := Nat.mul_le_mul_left (2 ^ d) (show x % 2 ^ l + 1 ≤ 2 ^ l by omega)
nlinarith
have hdecomp : r + 2 ^ d * x =
(r + 2 ^ d * (x % 2 ^ l)) + 2 ^ (d + l) * (x / 2 ^ l) := by
calc
_ = r + 2 ^ d * (x % 2 ^ l + 2 ^ l * (x / 2 ^ l)) := by rw [Nat.mod_add_div]
_ = _ := by rw [pow_add]; ring
rw [hdecomp, Nat.add_mul_mod_self_left, Nat.mod_eq_of_lt hbound]
theorem dyadic_join_mod_eq_iff {d r : ℕ} (hr : r < 2 ^ d) (l x y : ℕ) :
(r + 2 ^ d * x) % 2 ^ (d + l) = (r + 2 ^ d * y) % 2 ^ (d + l) ↔
x % 2 ^ l = y % 2 ^ l := by
rw [dyadic_join_mod hr, dyadic_join_mod hr]
exact (dyadic_join_injective d r).eq_iff
theorem dyadic_zoom_mem {A : Finset ℕ} {d r x : ℕ} (hr : r < 2 ^ d) :
x ∈ dyadicZoom A d r ↔ r + 2 ^ d * x ∈ A := by
constructor
· intro hx
obtain ⟨a, ha, hax⟩ := Finset.mem_image.mp hx
obtain ⟨haA, har⟩ := Finset.mem_filter.mp ha
have hjoin : r + 2 ^ d * x = a := by rw [← hax, ← har, Nat.mod_add_div]
rwa [hjoin]
· intro hx
refine Finset.mem_image.mpr ⟨r + 2 ^ d * x, ?_, dyadic_join_div hr x⟩
exact Finset.mem_filter.mpr ⟨hx, by rw [Nat.add_mul_mod_self_left, Nat.mod_eq_of_lt hr]⟩
theorem dyadic_projection_zoom_mem_iff {A : Finset ℕ} {d r l s : ℕ} (hr : r < 2 ^ d) :
s ∈ dyadicProjection (dyadicZoom A d r) l ↔
r + 2 ^ d * s ∈ dyadicProjection A (d + l) := by
rw [dyadic_projection_zoom, dyadic_zoom_mem hr]
theorem dyadic_zoom_fiber_image (A : Finset ℕ) {d r : ℕ} (hr : r < 2 ^ d) (l s : ℕ) :
(((dyadicZoom A d r).filter (fun x => x % 2 ^ l = s)).image (fun x => r + 2 ^ d * x)) =
A.filter (fun y => y % 2 ^ (d + l) = r + 2 ^ d * s) := by
ext a
constructor
· intro ha
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp ha
obtain ⟨hxZ, hxs⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨(dyadic_zoom_mem hr).mp hxZ,
by rw [dyadic_join_mod hr, hxs]⟩
· intro ha
obtain ⟨haA, har⟩ := Finset.mem_filter.mp ha
have hlow : a % 2 ^ d = r := by
calc
_ = (a % 2 ^ (d + l)) % 2 ^ d := (Nat.mod_mod_of_dvd a (pow_dvd_pow 2 (by omega))).symm
_ = (r + 2 ^ d * s) % 2 ^ d := by rw [har]
_ = r := by rw [Nat.add_mul_mod_self_left, Nat.mod_eq_of_lt hr]
have hjoin : r + 2 ^ d * (a / 2 ^ d) = a := by rw [← hlow, Nat.mod_add_div]
have hhigh : a / 2 ^ d % 2 ^ l = s := by
have hh := congrArg (fun n => n / 2 ^ d) har
simpa only [pow_add, Nat.mod_mul_right_div_self, dyadic_join_div hr] using hh
refine Finset.mem_image.mpr ⟨a / 2 ^ d, Finset.mem_filter.mpr ⟨?_, hhigh⟩, hjoin⟩
exact (dyadic_zoom_mem hr).mpr (hjoin.symm ▸ haA)
theorem dyadic_zoom_fiber_card (A : Finset ℕ) {d r : ℕ} (hr : r < 2 ^ d) (l s : ℕ) :
((dyadicZoom A d r).filter (fun x => x % 2 ^ l = s)).card =
(A.filter (fun y => y % 2 ^ (d + l) = r + 2 ^ d * s)).card := by
rw [← dyadic_zoom_fiber_image A hr l s,
Finset.card_image_of_injective _ (dyadic_join_injective d r)]
theorem dyadic_tree_block_zoom {A : Finset ℕ} {b T m k d r : ℕ}
(hA : DyadicTreeBlock A b T m k) (hdb : d ≤ b) (hr : r < 2 ^ d) :
DyadicTreeBlock (dyadicZoom A d r) (b - d) T (m - d) k := by
have hdm : d ≤ m := hdb.trans hA.base_le
have hproj : ∀ s ∈ dyadicProjection (dyadicZoom A d r) (m - d),
r + 2 ^ d * s ∈ dyadicProjection A m := by
intro s hs
simpa only [Nat.add_sub_of_le hdm] using (dyadic_projection_zoom_mem_iff hr).mp hs
refine ⟨by have := hA.base_le; omega, by have := hA.split_lt; omega, hA.count_le, ?_, ?_, ?_⟩
· intro x hx y hy hxy
have hxyA : (r + 2 ^ d * x) % 2 ^ b = (r + 2 ^ d * y) % 2 ^ b := by
simpa only [Nat.add_sub_of_le hdb] using (dyadic_join_mod_eq_iff hr (b - d) x y).mpr hxy
have hxyM := hA.common _ ((dyadic_zoom_mem hr).mp hx) _ ((dyadic_zoom_mem hr).mp hy) hxyA
apply (dyadic_join_mod_eq_iff hr (m - d) x y).mp
simpa only [Nat.add_sub_of_le hdm] using hxyM
· intro s hs
rw [dyadic_zoom_fiber_card A hr, Nat.add_sub_of_le hdm]
exact hA.fiber_card _ (hproj s hs)
· intro s hs hk
obtain ⟨a, ha, c, hc, hac⟩ := hA.splits _ (hproj s hs) hk
have himage : (((dyadicZoom A d r).filter (fun x => x % 2 ^ (m - d) = s)).image
(fun x => r + 2 ^ d * x)) = A.filter (fun y => y % 2 ^ m = r + 2 ^ d * s) := by
simpa only [Nat.add_sub_of_le hdm] using dyadic_zoom_fiber_image A hr (m - d) s
rw [← himage] at ha hc
obtain ⟨x, hx, hxa⟩ := Finset.mem_image.mp ha
obtain ⟨y, hy, hyc⟩ := Finset.mem_image.mp hc
refine ⟨x, hx, y, hy, ?_⟩
intro hxy
have hjoined := (dyadic_join_mod_eq_iff hr (m - d + 1) x y).mpr hxy
have hindex : d + (m - d + 1) = m + 1 := by omega
rw [hindex, hxa, hyc] at hjoined
exact hac hjoined
theorem dyadic_regular_tree_zoom {A : Finset ℕ} {T N i r : ℕ}
(htree : DyadicRegularTree A T N) (hi : i ≤ N) (hr : r < 2 ^ (T * i)) :
DyadicRegularTree (dyadicZoom A (T * i) r) T (N - i) := by
intro j hj
obtain ⟨m, k, hblock⟩ := htree (i + j) (by omega)
have hdi : T * i ≤ T * (i + j) := Nat.mul_le_mul_left T (by omega)
have hzoom := dyadic_tree_block_zoom hblock hdi hr
have hbase : T * (i + j) - T * i = T * j := by rw [Nat.mul_add, Nat.add_sub_cancel_left]
have hend : T * i + T * (j + 1) = T * (i + j + 1) := by ring
refine ⟨m - T * i, k, ?_⟩
rw [dyadic_projection_zoom, hend]
simpa only [hbase] using hzoom
def branchPrefix (c : ℕ → ℕ) (n : ℕ) : ℕ := ∑ i ∈ Finset.range n, c i
theorem branch_prefix_zero (c : ℕ → ℕ) : branchPrefix c 0 = 0 := by simp [branchPrefix]
theorem branch_prefix_succ (c : ℕ → ℕ) (n : ℕ) :
branchPrefix c (n + 1) = branchPrefix c n + c n := Finset.sum_range_succ c n
theorem branch_prefix_mono (c : ℕ → ℕ) : Monotone (branchPrefix c) := by
intro a b hab
exact Finset.sum_le_sum_of_subset_of_nonneg (Finset.range_subset_range.mpr hab)
(fun _ _ _ => Nat.zero_le _)
theorem branch_prefix_add_interval (c : ℕ → ℕ) {a b : ℕ} (hab : a ≤ b) :
branchPrefix c a + (∑ i ∈ Finset.Ico a b, c i) = branchPrefix c b :=
Finset.sum_range_add_sum_Ico c hab
theorem branch_prefix_sub_eq_sum (c : ℕ → ℕ) {a b : ℕ} (hab : a ≤ b) :
branchPrefix c b - branchPrefix c a = ∑ i ∈ Finset.Ico a b, c i := by
have hh := branch_prefix_add_interval c hab
omega
theorem branch_prefix_sub_le (c : ℕ → ℕ) {a b T : ℕ} (hab : a ≤ b)
(hcap : ∀ i : ℕ, a ≤ i → i < b → c i ≤ T) :
branchPrefix c b - branchPrefix c a ≤ T * (b - a) := by
rw [branch_prefix_sub_eq_sum c hab]
calc
_ ≤ ∑ _i ∈ Finset.Ico a b, T := by
apply Finset.sum_le_sum
intro i hi
exact hcap i (Finset.mem_Ico.mp hi).1 (Finset.mem_Ico.mp hi).2
_ = _ := by simp [Nat.mul_comm]
theorem branch_prefix_eq_of_zero (c : ℕ → ℕ) {a b : ℕ} (hab : a ≤ b)
(hzero : ∀ i : ℕ, a ≤ i → i < b → c i = 0) : branchPrefix c b = branchPrefix c a := by
have hh := branch_prefix_add_interval c hab
have hsum : (∑ i ∈ Finset.Ico a b, c i) = 0 := by
apply Finset.sum_eq_zero
intro i hi
exact hzero i (Finset.mem_Ico.mp hi).1 (Finset.mem_Ico.mp hi).2
rw [hsum, add_zero] at hh
exact hh.symm
theorem dyadic_regular_tree_profile {A : Finset ℕ} {T N : ℕ}
(hA : A.Nonempty) (htree : DyadicRegularTree A T N) :
∃ m c : ℕ → ℕ,
(∀ i : ℕ, i < N → DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i)) ∧
∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j := by
classical
unfold DyadicRegularTree at htree
choose! m c hmc using htree
refine ⟨m, c, hmc, ?_⟩
intro j
induction j with
| zero =>
intro hj
simp only [Nat.mul_zero, dyadic_projection_zero hA, Finset.card_singleton, branch_prefix_zero, pow_zero]
| succ j ih =>
intro hj
have hblock := hmc j (by omega)
rw [branch_prefix_succ, pow_add, ← ih (by omega)]
have hc := dyadic_tree_block_card hblock
simpa only [dyadic_projection_trans A (Nat.mul_le_mul_left T (show j ≤ j + 1 by omega))] using hc
structure BranchingInterval (c : ℕ → ℕ) (T N R : ℕ) (α : ℝ) (a b : ℕ) : Prop where
width : a + R ≤ b
end_le : b ≤ N
branching : 0 < c a
sparse : ((branchPrefix c b - branchPrefix c a : ℕ) : ℝ) < α * (T : ℝ) * ((b - a : ℕ) : ℝ)
dense : ∀ j : ℕ, a + R ≤ j → j < b →
α * (T : ℝ) * ((j - a : ℕ) : ℝ) ≤ ((branchPrefix c j - branchPrefix c a : ℕ) : ℝ)
def BranchingIntervalChain (c : ℕ → ℕ) (T N R : ℕ) (α : ℝ) :
ℕ → List (ℕ × ℕ) → ℕ → Prop
| z, [], w => w = z
| z, (a, b) :: L, w => z ≤ a ∧ branchPrefix c a = branchPrefix c z ∧
BranchingInterval c T N R α a b ∧ BranchingIntervalChain c T N R α b L w
def BranchingIntervalTerminal (c : ℕ → ℕ) (T N R : ℕ) (α : ℝ) (z : ℕ) : Prop :=
branchPrefix c N - branchPrefix c z ≤ T * R ∨
∃ a : ℕ, z ≤ a ∧ a + R ≤ N ∧ branchPrefix c a = branchPrefix c z ∧
α * (T : ℝ) * ((N - a : ℕ) : ℝ) ≤ ((branchPrefix c N - branchPrefix c a : ℕ) : ℝ)
theorem exists_branching_interval_chain (c : ℕ → ℕ) (T N R : ℕ) (α : ℝ)
(hR : 0 < R) (hcap : ∀ i : ℕ, i < N → c i ≤ T) :
∀ z : ℕ, z ≤ N → ∃ L : List (ℕ × ℕ), ∃ w : ℕ,
z ≤ w ∧ w ≤ N ∧ BranchingIntervalChain c T N R α z L w ∧
BranchingIntervalTerminal c T N R α w := by
have aux : ∀ d : ℕ, ∀ z : ℕ, N - z = d → z ≤ N →
∃ L : List (ℕ × ℕ), ∃ w : ℕ,
z ≤ w ∧ w ≤ N ∧ BranchingIntervalChain c T N R α z L w ∧
BranchingIntervalTerminal c T N R α w := by
intro d
induction d using Nat.strong_induction_on with
| h d ih =>
intro z hdz hzN
by_cases hex : ∃ a : ℕ, z ≤ a ∧ a < N ∧ 0 < c a
· let a := Nat.find hex
obtain ⟨hza, haN, hac⟩ := Nat.find_spec hex
have hgap : branchPrefix c a = branchPrefix c z := by
apply branch_prefix_eq_of_zero c hza
intro i hzi hia
by_contra hi
exact (Nat.find_min hex hia) ⟨hzi, by omega, Nat.pos_of_ne_zero hi⟩
by_cases haR : a + R ≤ N
· let Q : ℕ → Prop := fun b => a + R ≤ b ∧ b ≤ N ∧
((branchPrefix c b - branchPrefix c a : ℕ) : ℝ) < α * (T : ℝ) * ((b - a : ℕ) : ℝ)
by_cases hdrop : ∃ b, Q b
· let b := Nat.find hdrop
obtain ⟨hab, hbN, hstop⟩ := Nat.find_spec hdrop
have hzb : z < b := by omega
have hinterval : BranchingInterval c T N R α a b := by
refine ⟨hab, hbN, hac, hstop, ?_⟩
intro j hjR hjb
by_contra hj
exact (Nat.find_min hdrop hjb) ⟨hjR, by omega, lt_of_not_ge hj⟩
obtain ⟨L, w, hbw, hwN, hchain, hterminal⟩ := ih (N - b) (by omega) b rfl hbN
refine ⟨(a, b) :: L, w, hzb.le.trans hbw, hwN, ?_, hterminal⟩
exact ⟨hza, hgap, hinterval, hchain⟩
· refine ⟨[], z, le_rfl, hzN, rfl, Or.inr ⟨a, hza, haR, hgap, ?_⟩⟩
apply le_of_not_gt
intro hfail
exact hdrop ⟨N, haR, le_rfl, hfail⟩
· refine ⟨[], z, le_rfl, hzN, rfl, Or.inl ?_⟩
rw [← hgap]
exact (branch_prefix_sub_le c (le_of_lt haN) (fun i _ hiN => hcap i hiN)).trans
(Nat.mul_le_mul_left T (by omega))
· have hgap : branchPrefix c N = branchPrefix c z := by
apply branch_prefix_eq_of_zero c hzN
intro i hzi hiN
by_contra hi
exact hex ⟨i, hzi, hiN, Nat.pos_of_ne_zero hi⟩
exact ⟨[], z, le_rfl, hzN, rfl, Or.inl (by rw [hgap, Nat.sub_self]; omega)⟩
intro z hzN
exact aux (N - z) z rfl hzN
theorem branching_interval_chain_le {c : ℕ → ℕ} {T N R : ℕ} {α : ℝ}
{z w : ℕ} {L : List (ℕ × ℕ)} (hchain : BranchingIntervalChain c T N R α z L w) :
z ≤ w := by
induction L generalizing z with
| nil =>
change w = z at hchain
omega
| cons p L ih =>
rcases p with ⟨a, b⟩
obtain ⟨hza, _, hblock, htail⟩ := hchain
have hab := hblock.width
have hbw := ih htail
omega
theorem branching_interval_chain_length {c : ℕ → ℕ} {T N R : ℕ} {α : ℝ}
{z w : ℕ} {L : List (ℕ × ℕ)} (hchain : BranchingIntervalChain c T N R α z L w) :
L.length * R ≤ w - z := by
induction L generalizing z with
| nil => simp
| cons p L ih =>
rcases p with ⟨a, b⟩
obtain ⟨hza, _, hblock, htail⟩ := hchain
have hab := hblock.width
have hbw := branching_interval_chain_le htail
have hlen := ih htail
simp only [List.length_cons, Nat.add_mul, Nat.one_mul]
omega
theorem branching_interval_chain_entropy {c : ℕ → ℕ} {T N R : ℕ} {α : ℝ}
{z w : ℕ} {L : List (ℕ × ℕ)} (hchain : BranchingIntervalChain c T N R α z L w) :
(L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum =
branchPrefix c w - branchPrefix c z := by
induction L generalizing z with
| nil =>
change w = z at hchain
simp [hchain]
| cons p L ih =>
rcases p with ⟨a, b⟩
obtain ⟨hza, hgap, hblock, htail⟩ := hchain
have hab : a ≤ b := by have := hblock.width; omega
have hbw := branching_interval_chain_le htail
have hEab := branch_prefix_mono c hab
have hEbw := branch_prefix_mono c hbw
simp only [List.map_cons, List.sum_cons]
rw [ih htail, hgap] at *
omega
theorem branching_interval_chain_mem {c : ℕ → ℕ} {T N R : ℕ} {α : ℝ}
{z w : ℕ} {L : List (ℕ × ℕ)} (hchain : BranchingIntervalChain c T N R α z L w) :
∀ p ∈ L, z ≤ p.1 ∧ p.2 ≤ w ∧ BranchingInterval c T N R α p.1 p.2 := by
induction L generalizing z with
| nil => simp
| cons p L ih =>
rcases p with ⟨a, b⟩
obtain ⟨hza, _, hblock, htail⟩ := hchain
intro q hq
rcases List.mem_cons.mp hq with rfl | hq
· exact ⟨hza, branching_interval_chain_le htail, hblock⟩
· obtain ⟨hbq, hqw, hqblock⟩ := ih htail q hq
have hab := hblock.width
exact ⟨by omega, hqw, hqblock⟩
theorem branching_terminal_entropy {c : ℕ → ℕ} {T N R w : ℕ} {α γ δ : ℝ}
(hT : 0 < T) (hwN : w ≤ N) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hα : 1 - δ / 2 ≤ α)
(hprefix : ∀ j : ℕ, j ≤ N → γ * (T : ℝ) * (j : ℝ) ≤ (branchPrefix c j : ℝ))
(hsize : (branchPrefix c N : ℝ) ≤ (1 - δ) * (T : ℝ) * (N : ℝ))
(hR : 2 * (R : ℝ) ≤ γ * (N : ℝ))
(hterminal : BranchingIntervalTerminal c T N R α w) :
γ * δ / 2 * (T : ℝ) * (N : ℝ) ≤ (branchPrefix c w : ℝ) := by
have hTr : (0 : ℝ) < T := by exact_mod_cast hT
have hNr : (0 : ℝ) ≤ N := Nat.cast_nonneg N
have hlower := hprefix N le_rfl
rcases hterminal with hshort | ⟨a, hwa, haR, hgap, hlong⟩
· have hEwN := branch_prefix_mono c hwN
have hshortR : (branchPrefix c N : ℝ) - (branchPrefix c w : ℝ) ≤ (T : ℝ) * (R : ℝ) := by
exact_mod_cast hshort
have hRmul := mul_le_mul_of_nonneg_left hR hTr.le
have hδmul : γ * δ / 2 * (T : ℝ) * (N : ℝ) ≤ γ / 2 * (T : ℝ) * (N : ℝ) := by
nlinarith [mul_nonneg hγ.le hTr.le,
mul_nonneg (mul_nonneg hγ.le hTr.le) hNr,
mul_nonneg (sub_nonneg.mpr hδ1) (mul_nonneg (mul_nonneg hγ.le hTr.le) hNr)]
nlinarith
· have haN : a ≤ N := by omega
have hEaN := branch_prefix_mono c haN
have hNa : (0 : ℝ) ≤ (N : ℝ) - (a : ℝ) := sub_nonneg.mpr (by exact_mod_cast haN)
have hlongR : α * (T : ℝ) * ((N : ℝ) - (a : ℝ)) ≤
(branchPrefix c N : ℝ) - (branchPrefix c a : ℝ) := by
simpa only [Nat.cast_sub haN, Nat.cast_sub hEaN] using hlong
have hαmul := mul_le_mul_of_nonneg_right
(mul_le_mul_of_nonneg_right hα hTr.le) hNa
have hEanonneg : (0 : ℝ) ≤ branchPrefix c a := Nat.cast_nonneg _
have hhalf : δ / 2 * (T : ℝ) * (N : ℝ) ≤ (T : ℝ) * (a : ℝ) := by
have hδa := mul_nonneg (mul_nonneg hδ.le hTr.le) (Nat.cast_nonneg a)
nlinarith
have hscaled := mul_le_mul_of_nonneg_left hhalf hγ.le
have hlowerA := hprefix a haN
have hgapR : (branchPrefix c a : ℝ) = (branchPrefix c w : ℝ) := by exact_mod_cast hgap
nlinarith
theorem exists_branching_intervals (c : ℕ → ℕ) (T N R : ℕ) (α γ δ : ℝ)
(hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hα : 1 - δ / 2 ≤ α) (hcap : ∀ i : ℕ, i < N → c i ≤ T)
(hprefix : ∀ j : ℕ, j ≤ N → γ * (T : ℝ) * (j : ℝ) ≤ (branchPrefix c j : ℝ))
(hsize : (branchPrefix c N : ℝ) ≤ (1 - δ) * (T : ℝ) * (N : ℝ))
(hRN : 2 * (R : ℝ) ≤ γ * (N : ℝ)) :
∃ L : List (ℕ × ℕ), ∃ w : ℕ,
w ≤ N ∧ BranchingIntervalChain c T N R α 0 L w ∧ L.length * R ≤ N ∧
γ * δ / 2 * (T : ℝ) * (N : ℝ) ≤
((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) := by
obtain ⟨L, w, _, hwN, hchain, hterminal⟩ :=
exists_branching_interval_chain c T N R α hR hcap 0 (Nat.zero_le N)
refine ⟨L, w, hwN, hchain, ?_, ?_⟩
· have hlen : L.length * R ≤ w := by
simpa only [Nat.sub_zero] using branching_interval_chain_length hchain
exact hlen.trans hwN
· rw [branching_interval_chain_entropy hchain, branch_prefix_zero, Nat.sub_zero]
exact branching_terminal_entropy hT hwN hγ hδ hδ1 hα hprefix hsize hRN hterminal
theorem dyadic_projection_card_mono (A : Finset ℕ) {j k : ℕ} (hjk : j ≤ k) :
(dyadicProjection A j).card ≤ (dyadicProjection A k).card := by
rw [← dyadic_projection_trans A hjk]
exact Finset.card_image_le
theorem dyadic_projection_common_lift {A : Finset ℕ} {b m e : ℕ}
(hbm : b ≤ m) (hme : m ≤ e)
(hcommon : ∀ x ∈ dyadicProjection A e, ∀ y ∈ dyadicProjection A e,
x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m) :
∀ x ∈ A, ∀ y ∈ A, x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m := by
intro x hx y hy hxy
have heq := hcommon (x % 2 ^ e) (Finset.mem_image_of_mem _ hx)
(y % 2 ^ e) (Finset.mem_image_of_mem _ hy)
simp only [Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 (hbm.trans hme)),
Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hme)] at heq
exact heq hxy
theorem dyadic_projection_common {A : Finset ℕ} {b m e : ℕ}
(hbm : b ≤ m) (hme : m ≤ e)
(hcommon : ∀ x ∈ A, ∀ y ∈ A,
x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m) :
∀ x ∈ dyadicProjection A e, ∀ y ∈ dyadicProjection A e,
x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m := by
intro x hx y hy hxy
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨d, hd, rfl⟩ := Finset.mem_image.mp hy
simp only [Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 (hbm.trans hme))] at hxy
simpa only [Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hme)] using hcommon a ha d hd hxy
theorem dyadic_fiber_eq_of_common {A : Finset ℕ} {b m r : ℕ} (hbm : b ≤ m)
(hcommon : ∀ x ∈ A, ∀ y ∈ A,
x % 2 ^ b = y % 2 ^ b → x % 2 ^ m = y % 2 ^ m)
(hr : r ∈ dyadicProjection A m) :
A.filter (fun x => x % 2 ^ m = r) = A.filter (fun x => x % 2 ^ b = r % 2 ^ b) := by
obtain ⟨a, ha, har⟩ := Finset.mem_image.mp hr
ext x
constructor
· intro hx
obtain ⟨hxA, hxr⟩ := Finset.mem_filter.mp hx
refine Finset.mem_filter.mpr ⟨hxA, ?_⟩
calc
_ = (x % 2 ^ m) % 2 ^ b := (Nat.mod_mod_of_dvd x (pow_dvd_pow 2 hbm)).symm
_ = _ := by rw [hxr]
· intro hx
obtain ⟨hxA, hxr⟩ := Finset.mem_filter.mp hx
have hxa : x % 2 ^ b = a % 2 ^ b := by
rw [hxr, ← har, Nat.mod_mod_of_dvd a (pow_dvd_pow 2 hbm)]
exact Finset.mem_filter.mpr ⟨hxA, (hcommon x hxA a ha hxa).trans har⟩
theorem dyadic_regular_profile_fiber_card {A : Finset ℕ} {T N : ℕ} {c : ℕ → ℕ}
(htree : DyadicRegularTree A T N)
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{a b r : ℕ} (hab : a ≤ b) (hbN : b ≤ N) (hr : r ∈ dyadicProjection A (T * a)) :
((dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (T * a) = r)).card =
2 ^ (branchPrefix c b - branchPrefix c a) := by
have hmul := dyadic_regular_tree_zoom_projection_card (i := a) (j := b - a) htree
(by omega) hr
rw [dyadic_projection_zoom, ← Nat.mul_add, Nat.add_sub_of_le hab,
dyadic_zoom_card, hprofile a (hab.trans hbN), hprofile b hbN] at hmul
have hEab := branch_prefix_mono c hab
have hpow : 2 ^ branchPrefix c b = 2 ^ branchPrefix c a * 2 ^ (branchPrefix c b - branchPrefix c a) := by
rw [← pow_add, Nat.add_sub_of_le hEab]
rw [hpow] at hmul
exact Nat.eq_of_mul_eq_mul_left (by positivity) hmul
theorem dyadic_regular_profile_fiber_card_le {A : Finset ℕ} {T N : ℕ} {c : ℕ → ℕ}
(htree : DyadicRegularTree A T N)
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{a b : ℕ} (hab : a ≤ b) (hbN : b ≤ N) (r : ℕ) :
((dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (T * a) = r)).card ≤
2 ^ (branchPrefix c b - branchPrefix c a) := by
by_cases hr : r ∈ dyadicProjection A (T * a)
· exact (dyadic_regular_profile_fiber_card htree hprofile hab hbN hr).le
· have hempty : (dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (T * a) = r) = ∅ := by
apply Finset.eq_empty_iff_forall_notMem.mpr
intro x hx
obtain ⟨hxP, hxr⟩ := Finset.mem_filter.mp hx
apply hr
rw [← dyadic_projection_trans A (Nat.mul_le_mul_left T hab), ← hxr]
exact Finset.mem_image_of_mem _ hxP
rw [hempty, Finset.card_empty]
exact Nat.zero_le _
theorem dyadic_regular_profile_split_fiber_card {A : Finset ℕ} {T N : ℕ} {m c : ℕ → ℕ}
(hblocks : ∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i))
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{a b r : ℕ} (hab : a < b) (hbN : b ≤ N) (hr : r ∈ dyadicProjection A (m a)) :
((dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (m a) = r)).card =
2 ^ (branchPrefix c b - branchPrefix c a) := by
have hblock := hblocks a (hab.trans_le hbN)
have hma : m a ≤ T * (a + 1) := by have := hblock.split_lt; nlinarith
have hmb : m a ≤ T * b := hma.trans (Nat.mul_le_mul_left T (by omega))
have hcommon := dyadic_projection_common_lift hblock.base_le hma hblock.common
have hprojected := dyadic_projection_common hblock.base_le hmb hcommon
have hr' : r ∈ dyadicProjection (dyadicProjection A (T * b)) (m a) := by
rwa [dyadic_projection_trans A hmb]
rw [dyadic_fiber_eq_of_common hblock.base_le hprojected hr']
apply dyadic_regular_profile_fiber_card (fun i hi => ⟨m i, c i, hblocks i hi⟩) hprofile hab.le hbN
rw [← dyadic_projection_trans A hblock.base_le]
exact Finset.mem_image_of_mem _ hr
theorem dyadic_fiber_card_antitone (A : Finset ℕ) {j k : ℕ} (hjk : j ≤ k) (r : ℕ) :
(A.filter (fun x => x % 2 ^ k = r)).card ≤
(A.filter (fun x => x % 2 ^ j = r % 2 ^ j)).card := by
apply Finset.card_le_card
intro x hx
obtain ⟨hxA, hxr⟩ := Finset.mem_filter.mp hx
refine Finset.mem_filter.mpr ⟨hxA, ?_⟩
calc
_ = (x % 2 ^ k) % 2 ^ j := (Nat.mod_mod_of_dvd x (pow_dvd_pow 2 hjk)).symm
_ = _ := by rw [hxr]
theorem dyadic_regular_profile_intermediate_fiber_card_le {A : Finset ℕ} {T N : ℕ}
{c : ℕ → ℕ} (htree : DyadicRegularTree A T N)
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{j b k : ℕ} (hjb : j ≤ b) (hbN : b ≤ N) (hjk : T * j ≤ k) (r : ℕ) :
((dyadicProjection A (T * b)).filter (fun x => x % 2 ^ k = r)).card ≤
2 ^ (branchPrefix c b - branchPrefix c j) := by
exact (dyadic_fiber_card_antitone _ hjk r).trans
(dyadic_regular_profile_fiber_card_le htree hprofile hjb hbN _)
theorem dyadic_regular_profile_split_fiber_mass_le {A : Finset ℕ} {T N : ℕ} {m c : ℕ → ℕ}
(hblocks : ∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i))
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{a b j k r : ℕ} (hab : a < b) (hbN : b ≤ N) (haj : a ≤ j) (hjb : j ≤ b)
(hjk : T * j ≤ k) (hr : r ∈ dyadicProjection A (m a)) (s : ℕ) :
natResidueMass ((dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (m a) = r))
(2 ^ k) s ≤ (2 : ℝ) ^ (-((branchPrefix c j - branchPrefix c a : ℕ) : ℝ)) := by
let S := (dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (m a) = r)
have hS : S.card = 2 ^ (branchPrefix c b - branchPrefix c a) :=
dyadic_regular_profile_split_fiber_card hblocks hprofile hab hbN hr
have hsub : natResidueFiber S (2 ^ k) s ⊆
(dyadicProjection A (T * b)).filter (fun x => x % 2 ^ k = s % 2 ^ k) := by
intro x hx
obtain ⟨hxS, hxs⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨(Finset.mem_filter.mp hxS).1, hxs⟩
have hfiber := (Finset.card_le_card hsub).trans
(dyadic_regular_profile_intermediate_fiber_card_le
(fun i hi => ⟨m i, c i, hblocks i hi⟩) hprofile hjb hbN hjk (s % 2 ^ k))
have hEaj := branch_prefix_mono c haj
have hEjb := branch_prefix_mono c hjb
have hEab := branch_prefix_mono c hab.le
have hpow : (2 : ℝ) ^ (-((branchPrefix c j - branchPrefix c a : ℕ) : ℝ)) *
(2 : ℝ) ^ (branchPrefix c b - branchPrefix c a) =
(2 : ℝ) ^ (branchPrefix c b - branchPrefix c j) := by
simp only [← Real.rpow_natCast, ← Real.rpow_add (show (0 : ℝ) < 2 by norm_num)]
congr 1
simp only [Nat.cast_sub hEaj, Nat.cast_sub hEjb, Nat.cast_sub hEab]
ring
change ((natResidueFiber S (2 ^ k) s).card : ℝ) / (S.card : ℝ) ≤ _
rw [hS, Nat.cast_pow, Nat.cast_ofNat]
apply (div_le_iff₀ (pow_pos (by norm_num : (0 : ℝ) < 2) _)).mpr
rw [hpow]
exact_mod_cast hfiber
theorem dyadic_regular_profile_split_witnesses {A : Finset ℕ} {T N : ℕ} {m c : ℕ → ℕ}
(hblocks : ∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i))
{a b r : ℕ} (hab : a < b) (hbN : b ≤ N) (hca : 0 < c a)
(hr : r ∈ dyadicProjection A (m a)) :
∃ x ∈ (dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (m a) = r),
∃ y ∈ (dyadicProjection A (T * b)).filter (fun x => x % 2 ^ (m a) = r),
x % 2 ^ (m a + 1) ≠ y % 2 ^ (m a + 1) := by
have hblock := hblocks a (hab.trans_le hbN)
have hme : m a + 1 ≤ T * (a + 1) := by have := hblock.split_lt; nlinarith
have heb : T * (a + 1) ≤ T * b := Nat.mul_le_mul_left T (by omega)
have hmb : m a + 1 ≤ T * b := hme.trans heb
have hr' : r ∈ dyadicProjection (dyadicProjection A (T * (a + 1))) (m a) := by
rwa [dyadic_projection_trans A (show m a ≤ T * (a + 1) by omega)]
obtain ⟨x, hx, y, hy, hxy⟩ := hblock.splits r hr' hca
obtain ⟨hxP, hxr⟩ := Finset.mem_filter.mp hx
obtain ⟨hyP, hyr⟩ := Finset.mem_filter.mp hy
obtain ⟨u, hu, hux⟩ := Finset.mem_image.mp hxP
obtain ⟨v, hv, hvy⟩ := Finset.mem_image.mp hyP
have hur : u % 2 ^ (m a) = r := by
rw [← hux, Nat.mod_mod_of_dvd u (pow_dvd_pow 2 (show m a ≤ T * (a + 1) by omega))] at hxr
exact hxr
have hvr : v % 2 ^ (m a) = r := by
rw [← hvy, Nat.mod_mod_of_dvd v (pow_dvd_pow 2 (show m a ≤ T * (a + 1) by omega))] at hyr
exact hyr
refine ⟨u % 2 ^ (T * b), Finset.mem_filter.mpr ⟨Finset.mem_image_of_mem _ hu, ?_⟩,
v % 2 ^ (T * b), Finset.mem_filter.mpr ⟨Finset.mem_image_of_mem _ hv, ?_⟩, ?_⟩
· rwa [Nat.mod_mod_of_dvd u (pow_dvd_pow 2 (show m a ≤ T * b by omega))]
· rwa [Nat.mod_mod_of_dvd v (pow_dvd_pow 2 (show m a ≤ T * b by omega))]
· intro heq
apply hxy
rw [← hux, ← hvy]
simpa only [Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hme),
Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hmb)] using heq
theorem branching_interval_sparse_physical {c : ℕ → ℕ} {T N R a b m : ℕ} {ρ : ℝ}
(hR : 0 < R) (hρ : 0 < ρ) (hρ1 : ρ ≤ 1)
(hρR : 1 ≤ ρ * (R : ℝ)) (hm : m < T * (a + 1))
(hinterval : BranchingInterval c T N R (1 - 2 * ρ) a b) :
((branchPrefix c b - branchPrefix c a : ℕ) : ℝ) < (1 - ρ) * ((T * b - m : ℕ) : ℝ) := by
have hab : a < b := by have := hinterval.width; omega
have hmb : m ≤ T * b := hm.le.trans (Nat.mul_le_mul_left T (by omega))
have hwidth : (R : ℝ) ≤ (b : ℝ) - (a : ℝ) := by
have hh : (a : ℝ) + (R : ℝ) ≤ (b : ℝ) := by exact_mod_cast hinterval.width
linarith
have hmR : (m : ℝ) ≤ (T : ℝ) * ((a : ℝ) + 1) := by exact_mod_cast hm.le
have hTr : (0 : ℝ) ≤ T := Nat.cast_nonneg T
have hρwidth := mul_le_mul_of_nonneg_left hwidth hρ.le
have hwidthT := mul_le_mul_of_nonneg_right (hρR.trans hρwidth) hTr
have hshift := mul_le_mul_of_nonneg_left hmR (sub_nonneg.mpr hρ1)
have hsparse := hinterval.sparse
rw [Nat.cast_sub hab.le] at hsparse
rw [Nat.cast_sub hmb, Nat.cast_mul]
nlinarith [mul_nonneg hρ.le hTr]
theorem branching_interval_dense_physical {c : ℕ → ℕ} {T N R a b m k : ℕ} {ρ : ℝ}
(hT : 0 < T) (hR : 0 < R) (hρ : 0 < ρ) (hρhalf : ρ ≤ 1 / 2)
(hρR : 1 ≤ ρ * (R : ℝ)) (hma : T * a ≤ m)
(hkmin : m + 2 * (T * R) ≤ k) (hkmax : k ≤ T * b)
(hinterval : BranchingInterval c T N R (1 - 2 * ρ) a b) :
∃ j : ℕ, a + R ≤ j ∧ j < b ∧ T * j ≤ k ∧
(1 - 3 * ρ) * ((k - m : ℕ) : ℝ) ≤
((branchPrefix c j - branchPrefix c a : ℕ) : ℝ) := by
let j := (k - 1) / T
have hTR : 0 < T * R := Nat.mul_pos hT hR
have hkpos : 0 < k := by omega
have hnear : k ≤ T * j + T := by
have hh := Nat.mod_lt (k - 1) hT
have hd := Nat.mod_add_div (k - 1) T
change (k - 1) % T + T * j = k - 1 at hd
omega
have hjk : T * j ≤ k := by
have hh := Nat.mul_div_le (k - 1) T
change T * j ≤ k - 1 at hh
omega
have haj : a + R ≤ j := by
apply (Nat.le_div_iff_mul_le hT).mpr
have hh : T * (a + R) < k := by
rw [Nat.mul_add]
omega
rw [Nat.mul_comm]
omega
have hjb : j < b := by
apply (Nat.div_lt_iff_lt_mul hT).mpr
rw [Nat.mul_comm]
omega
have hmkle : m ≤ k := by omega
have hajle : a ≤ j := by omega
have hTr : (0 : ℝ) ≤ T := Nat.cast_nonneg T
have hkmR : (T : ℝ) * (R : ℝ) ≤ (k : ℝ) - (m : ℝ) := by
have hh : (m : ℝ) + (T : ℝ) * (R : ℝ) ≤ (k : ℝ) := by
exact_mod_cast (show m + T * R ≤ k by omega)
linarith
have hρkm := mul_le_mul_of_nonneg_left hkmR hρ.le
have hρRT := mul_le_mul_of_nonneg_right hρR hTr
have hnearR : (k : ℝ) ≤ (T : ℝ) * (j : ℝ) + (T : ℝ) := by exact_mod_cast hnear
have hmaR : (T : ℝ) * (a : ℝ) ≤ (m : ℝ) := by exact_mod_cast hma
have hstep : (k : ℝ) - (m : ℝ) - (T : ℝ) ≤ (T : ℝ) * ((j : ℝ) - (a : ℝ)) := by nlinarith
have hstepmul := mul_le_mul_of_nonneg_left hstep (show 0 ≤ 1 - 2 * ρ by linarith)
have hdense := hinterval.dense j haj hjb
rw [Nat.cast_sub hajle] at hdense
refine ⟨j, haj, hjb, hjk, ?_⟩
rw [Nat.cast_sub hmkle]
nlinarith [mul_nonneg hρ.le hTr]
structure DyadicAmplificationBlock (A : Finset ℕ) (u v M e : ℕ) (ρ : ℝ) : Prop where
start_lt : u < v
fiber_card : ∀ r ∈ dyadicProjection A u,
((dyadicProjection A v).filter (fun x => x % 2 ^ u = r)).card = 2 ^ e
sparse : (e : ℝ) < (1 - ρ) * ((v - u : ℕ) : ℝ)
splits : ∀ r ∈ dyadicProjection A u,
∃ x ∈ (dyadicProjection A v).filter (fun x => x % 2 ^ u = r),
∃ y ∈ (dyadicProjection A v).filter (fun x => x % 2 ^ u = r),
x % 2 ^ (u + 1) ≠ y % 2 ^ (u + 1)
mass_le : ∀ k : ℕ, u + M ≤ k → k ≤ v → ∀ r ∈ dyadicProjection A u, ∀ s : ℕ,
natResidueMass ((dyadicProjection A v).filter (fun x => x % 2 ^ u = r)) (2 ^ k) s ≤
(2 : ℝ) ^ (-(1 - 3 * ρ) * ((k - u : ℕ) : ℝ))
theorem dyadic_amplification_block_of_branching_interval {A : Finset ℕ} {T N R : ℕ}
{m c : ℕ → ℕ} {a b : ℕ} {ρ : ℝ}
(hT : 0 < T) (hR : 0 < R) (hρ : 0 < ρ) (hρhalf : ρ ≤ 1 / 2)
(hρR : 1 ≤ ρ * (R : ℝ))
(hblocks : ∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i))
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
(hinterval : BranchingInterval c T N R (1 - 2 * ρ) a b) :
DyadicAmplificationBlock A (m a) (T * b) (2 * (T * R))
(branchPrefix c b - branchPrefix c a) ρ := by
have hab : a < b := by have := hinterval.width; omega
have haN : a < N := hab.trans_le hinterval.end_le
have hblock := hblocks a haN
have hm : m a < T * (a + 1) := by simpa only [Nat.mul_add, Nat.mul_one] using hblock.split_lt
refine ⟨hm.trans_le (Nat.mul_le_mul_left T (by omega)),
fun r hr => dyadic_regular_profile_split_fiber_card hblocks hprofile hab hinterval.end_le hr,
branching_interval_sparse_physical hR hρ (by linarith) hρR hm hinterval,
fun r hr => dyadic_regular_profile_split_witnesses hblocks hab hinterval.end_le hinterval.branching hr,
?_⟩
intro k hkmin hkmax r hr s
obtain ⟨j, haj, hjb, hjk, hbits⟩ := branching_interval_dense_physical hT hR hρ hρhalf hρR
hblock.base_le hkmin hkmax hinterval
have hmass := dyadic_regular_profile_split_fiber_mass_le hblocks hprofile hab hinterval.end_le
(show a ≤ j by omega) hjb.le hjk hr s
refine hmass.trans ?_
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith
theorem exists_dyadic_amplification_intervals {A : Finset ℕ} {T N R : ℕ} {γ δ ρ : ℝ}
(hA : A.Nonempty) (hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hρ : 0 < ρ) (hρδ : ρ ≤ δ / 4) (hρR : 1 ≤ ρ * (R : ℝ))
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hprefix : ∀ j : ℕ, j ≤ N →
(2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤ ((dyadicProjection A (T * j)).card : ℝ))
(hsize : (A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)))
(hRN : 2 * (R : ℝ) ≤ γ * (N : ℝ)) :
∃ m c : ℕ → ℕ, ∃ L : List (ℕ × ℕ), ∃ w : ℕ,
(∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i)) ∧
(∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j) ∧
w ≤ N ∧ BranchingIntervalChain c T N R (1 - 2 * ρ) 0 L w ∧ L.length * R ≤ N ∧
γ * δ / 2 * (T : ℝ) * (N : ℝ) ≤
((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) ∧
∀ p ∈ L, DyadicAmplificationBlock A (m p.1) (T * p.2) (2 * (T * R))
(branchPrefix c p.2 - branchPrefix c p.1) ρ := by
obtain ⟨m, c, hblocks, hprofile⟩ := dyadic_regular_tree_profile hA htree
have hprefixE : ∀ j : ℕ, j ≤ N → γ * (T : ℝ) * (j : ℝ) ≤ (branchPrefix c j : ℝ) := by
intro j hj
have hh := hprefix j hj
rw [hprofile j hj, Nat.cast_pow, Nat.cast_ofNat, ← Real.rpow_natCast] at hh
exact (Real.rpow_le_rpow_left_iff (by norm_num : (1 : ℝ) < 2)).mp hh
have hsizeE : (branchPrefix c N : ℝ) ≤ (1 - δ) * (T : ℝ) * (N : ℝ) := by
have hcard : A.card = 2 ^ branchPrefix c N := by
simpa only [dyadic_projection_self hbound] using hprofile N le_rfl
rw [hcard, Nat.cast_pow, Nat.cast_ofNat, ← Real.rpow_natCast] at hsize
exact (Real.rpow_le_rpow_left_iff (by norm_num : (1 : ℝ) < 2)).mp hsize
obtain ⟨L, w, hwN, hchain, hlength, hbits⟩ :=
exists_branching_intervals c T N R (1 - 2 * ρ) γ δ hT hR hγ hδ hδ1
(by linarith) (fun i hi => (hblocks i hi).count_le) hprefixE hsizeE hRN
refine ⟨m, c, L, w, hblocks, hprofile, hwN, hchain, hlength, hbits, ?_⟩
intro p hp
exact dyadic_amplification_block_of_branching_interval hT hR hρ (by linarith) hρR
hblocks hprofile (branching_interval_chain_mem hchain p hp).2.2
theorem nat_residue_mass_mono_modulus (A : Finset ℕ) {q Q : ℕ} (hq : q ∣ Q) (r : ℕ) :
natResidueMass A Q r ≤ natResidueMass A q r := by
unfold natResidueMass
exact div_le_div_of_nonneg_right
(by exact_mod_cast Finset.card_le_card (nat_residue_fiber_mono_modulus (A := A) (r := r) hq))
(Nat.cast_nonneg A.card)
theorem dyadic_regular_tree_residue_mass_le {A : Finset ℕ} {T N i : ℕ}
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hi : i ≤ N) (r : ℕ) :
natResidueMass A (2 ^ (T * i)) r ≤ 1 / ((dyadicProjection A (T * i)).card : ℝ) := by
by_cases hr : r % 2 ^ (T * i) ∈ dyadicProjection A (T * i)
· rw [← nat_residue_mass_mod A (2 ^ (T * i)) r]
exact (dyadic_regular_tree_residue_mass htree hbound hi hr).le
· have hempty : natResidueFiber A (2 ^ (T * i)) r = ∅ := by
apply Finset.eq_empty_iff_forall_notMem.mpr
intro x hx
obtain ⟨hxA, hxr⟩ := Finset.mem_filter.mp hx
apply hr
exact Finset.mem_image.mpr ⟨x, hxA, hxr⟩
simp only [natResidueMass, hempty, Finset.card_empty, Nat.cast_zero, zero_div]
positivity
theorem dyadic_regular_tree_mass_le_at_all_levels {A : Finset ℕ} {T N : ℕ} {γ : ℝ}
(hT : 0 < T) (hγ : 0 ≤ γ) (htree : DyadicRegularTree A T N)
(hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hprefix : ∀ j : ℕ, j ≤ N →
(2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤ ((dyadicProjection A (T * j)).card : ℝ))
{k : ℕ} (hkmin : 2 * T ≤ k) (hkmax : k ≤ T * N) (r : ℕ) :
natResidueMass A (2 ^ k) r ≤ (2 : ℝ) ^ (-(γ / 2) * (k : ℝ)) := by
let j := k / T
have hjk : T * j ≤ k := Nat.mul_div_le k T
have hjN : j ≤ N := by nlinarith
have hrem := Nat.mod_lt k hT
have hdiv := Nat.mod_add_div k T
change k % T + T * j = k at hdiv
have hgrid : k ≤ 2 * (T * j) := by omega
have hgridR : (k : ℝ) ≤ 2 * ((T : ℝ) * (j : ℝ)) := by exact_mod_cast hgrid
have hprefixJ := hprefix j hjN
calc
_ ≤ natResidueMass A (2 ^ (T * j)) r :=
nat_residue_mass_mono_modulus A (pow_dvd_pow 2 hjk) r
_ ≤ 1 / ((dyadicProjection A (T * j)).card : ℝ) :=
dyadic_regular_tree_residue_mass_le htree hbound hjN r
_ ≤ 1 / ((2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ))) :=
one_div_le_one_div_of_le (Real.rpow_pos_of_pos (by norm_num) _) hprefixJ
_ = (2 : ℝ) ^ (-(γ * (T : ℝ) * (j : ℝ))) := by
rw [Real.rpow_neg (by norm_num : (0 : ℝ) ≤ 2), one_div]
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith [mul_le_mul_of_nonneg_left hgridR hγ]
theorem branching_interval_chain_width_sum {c : ℕ → ℕ} {T N R : ℕ} {α : ℝ}
{z w : ℕ} {L : List (ℕ × ℕ)} (hchain : BranchingIntervalChain c T N R α z L w) :
(L.map (fun p => p.2 - p.1)).sum ≤ w - z := by
induction L generalizing z with
| nil => simp
| cons p L ih =>
rcases p with ⟨a, b⟩
obtain ⟨hza, _, hblock, htail⟩ := hchain
have hab := hblock.width
have hbw := branching_interval_chain_le htail
have hsum := ih htail
simp only [List.map_cons, List.sum_cons]
omega
theorem branching_interval_chain_physical_width_sum {c m : ℕ → ℕ} {T N R : ℕ} {α : ℝ}
{z w : ℕ} {L : List (ℕ × ℕ)} (hchain : BranchingIntervalChain c T N R α z L w)
(hm : ∀ i : ℕ, i < N → T * i ≤ m i) (hR : 0 < R) :
(L.map (fun p => T * p.2 - m p.1)).sum ≤ T * (w - z) := by
have hsum : (L.map (fun p => T * p.2 - m p.1)).sum ≤
T * (L.map (fun p => p.2 - p.1)).sum := by
induction L generalizing z with
| nil => simp
| cons p L ih =>
rcases p with ⟨a, b⟩
obtain ⟨_, _, hblock, htail⟩ := hchain
have hab : a < b := by have := hblock.width; omega
have haN : a < N := hab.trans_le hblock.end_le
have hma := hm a haN
have hsub : T * b - m a ≤ T * (b - a) := by
rw [Nat.mul_sub_left_distrib]
omega
have htailbound := ih htail
simp only [List.map_cons, List.sum_cons, Nat.mul_add]
omega
exact hsum.trans (Nat.mul_le_mul_left T (branching_interval_chain_width_sum hchain))
theorem dyadic_amplification_blocks_entropy_budget {A : Finset ℕ} {T M : ℕ}
{m c : ℕ → ℕ} {ρ : ℝ} {L : List (ℕ × ℕ)}
(hblocks : ∀ p ∈ L, DyadicAmplificationBlock A (m p.1) (T * p.2) M
(branchPrefix c p.2 - branchPrefix c p.1) ρ) :
((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) ≤
(1 - ρ) * ((L.map (fun p => T * p.2 - m p.1)).sum : ℝ) := by
induction L with
| nil => simp
| cons p L ih =>
have hhead := (hblocks p (by simp)).sparse.le
have htail := ih (fun q hq => hblocks q (List.mem_cons_of_mem p hq))
simp only [List.map_cons, List.sum_cons, Nat.cast_add]
nlinarith
theorem dyadic_amplification_blocks_entropy_gain {A : Finset ℕ} {T M : ℕ}
{m c : ℕ → ℕ} {ρ : ℝ} {L : List (ℕ × ℕ)} (hρ : 0 ≤ ρ)
(hblocks : ∀ p ∈ L, DyadicAmplificationBlock A (m p.1) (T * p.2) M
(branchPrefix c p.2 - branchPrefix c p.1) ρ) :
ρ * ((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) ≤
((L.map (fun p => T * p.2 - m p.1)).sum : ℝ) -
((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) := by
have hbudget := dyadic_amplification_blocks_entropy_budget hblocks
have hwidth_nonneg : (0 : ℝ) ≤ (L.map (fun p => T * p.2 - m p.1)).sum := Nat.cast_nonneg _
have hbits_width : ((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) ≤
((L.map (fun p => T * p.2 - m p.1)).sum : ℝ) := by
nlinarith [mul_nonneg hρ hwidth_nonneg]
nlinarith [mul_le_mul_of_nonneg_left hbits_width hρ]
theorem dyadic_regular_profile_no_branching_gap {A : Finset ℕ} {T N : ℕ} {m c : ℕ → ℕ}
(hblocks : ∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i))
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{z a : ℕ} (hza : z ≤ a) (haN : a < N) (hgap : branchPrefix c a = branchPrefix c z) :
(dyadicProjection A (m a)).card = (dyadicProjection A (T * z)).card := by
have hblock := hblocks a haN
have hma : m a ≤ T * (a + 1) := by have := hblock.split_lt; nlinarith
have hcommon := dyadic_projection_common_lift hblock.base_le hma hblock.common
rw [dyadic_projection_card_of_common hblock.base_le hcommon,
hprofile a haN.le, hprofile z (hza.trans haN.le), hgap]
noncomputable def finiteEntropy {ι : Type*} (S : Finset ι) (p : ι → ℝ) : ℝ :=
∑ x ∈ S, Real.negMulLog (p x)
theorem sum_mul_log_le_log_bound {ι : Type*} (S : Finset ι) (p : ι → ℝ) {M : ℝ}
(hp : ∀ x ∈ S, 0 ≤ p x) (hbound : ∀ x ∈ S, p x ≤ M) :
(∑ x ∈ S, p x * Real.log (p x)) ≤ (∑ x ∈ S, p x) * Real.log M := by
rw [Finset.sum_mul]
apply Finset.sum_le_sum
intro x hx
by_cases hpx : p x = 0
· simp [hpx]
· exact mul_le_mul_of_nonneg_left
(Real.log_le_log (lt_of_le_of_ne (hp x hx) (Ne.symm hpx)) (hbound x hx)) (hp x hx)
theorem finite_entropy_fiber_defect {ι : Type*} (S : Finset ι) (p : ι → ℝ) {q M : ℝ}
(hp : ∀ x ∈ S, 0 ≤ p x) (hq : 0 < q) (hM : 0 ≤ M) (hbound : ∀ x ∈ S, p x ≤ M) :
Real.negMulLog (∑ x ∈ S, p x) + (∑ x ∈ S, p x) * Real.log q - finiteEntropy S p ≤
q * M - ∑ x ∈ S, p x := by
let s := ∑ x ∈ S, p x
have hs : 0 ≤ s := Finset.sum_nonneg hp
by_cases hMzero : M = 0
· have hzero : ∀ x ∈ S, p x = 0 := fun x hx => le_antisymm (hMzero ▸ hbound x hx) (hp x hx)
have hsumzero : ∑ x ∈ S, p x = 0 := Finset.sum_eq_zero hzero
have hentropy : finiteEntropy S p = 0 := by
apply Finset.sum_eq_zero
intro x hx
simp [hzero x hx, Real.negMulLog_def]
simp [hsumzero, hentropy, hMzero, Real.negMulLog_def]
have hMpos : 0 < M := lt_of_le_of_ne hM (Ne.symm hMzero)
have hlog := sum_mul_log_le_log_bound S p hp hbound
have hentropy : finiteEntropy S p = -(∑ x ∈ S, p x * Real.log (p x)) := by
simp [finiteEntropy, Real.negMulLog_def, neg_mul, Finset.sum_neg_distrib]
change Real.negMulLog s + s * Real.log q - finiteEntropy S p ≤ q * M - s
rw [hentropy]
change -s * Real.log s + s * Real.log q - -(∑ x ∈ S, p x * Real.log (p x)) ≤ q * M - s
change (∑ x ∈ S, p x * Real.log (p x)) ≤ s * Real.log M at hlog
by_cases hszero : s = 0
· have hlogzero : (∑ x ∈ S, p x * Real.log (p x)) ≤ 0 := by
simpa only [hszero, zero_mul] using hlog
simpa only [hszero, neg_zero, zero_mul, zero_add, sub_neg_eq_add, sub_zero] using
hlogzero.trans (mul_nonneg hq.le hM)
have hspos : 0 < s := lt_of_le_of_ne hs (Ne.symm hszero)
have hratio := Real.log_le_sub_one_of_pos (div_pos (mul_pos hq hMpos) hspos)
rw [Real.log_div (mul_ne_zero hq.ne' hMpos.ne') hspos.ne', Real.log_mul hq.ne' hMpos.ne'] at hratio
have hscaled := mul_le_mul_of_nonneg_left hratio hs
have hcancel : s * (q * M / s) = q * M := by field_simp
nlinarith
theorem finite_entropy_le_log_card {ι : Type*} (S : Finset ι) (p : ι → ℝ)
(hp : ∀ x ∈ S, 0 ≤ p x) (hsum : ∑ x ∈ S, p x = 1) :
finiteEntropy S p ≤ Real.log (S.card : ℝ) := by
have hSne : S.Nonempty := by
by_contra hS
have he := Finset.not_nonempty_iff_eq_empty.mp hS
norm_num [he] at hsum
have hcard : (0 : ℝ) < S.card := by exact_mod_cast Finset.card_pos.mpr hSne
have hpoint : ∀ x ∈ S,
(S.card : ℝ) * Real.negMulLog (p x) ≤
1 - (S.card : ℝ) * p x + p x * (S.card : ℝ) * Real.log (S.card : ℝ) := by
intro x hx
have hh := Real.negMulLog_le_one_sub_self (mul_nonneg hcard.le (hp x hx))
rw [Real.negMulLog_mul] at hh
change p x * (-(S.card : ℝ) * Real.log (S.card : ℝ)) +
(S.card : ℝ) * Real.negMulLog (p x) ≤ 1 - (S.card : ℝ) * p x at hh
nlinarith
have htotal := Finset.sum_le_sum hpoint
simp only [Finset.sum_add_distrib, Finset.sum_sub_distrib, ← Finset.mul_sum,
← Finset.sum_mul, Finset.sum_const, nsmul_eq_mul, mul_one, hsum, one_mul] at htotal
apply (mul_le_mul_iff_of_pos_left hcard).mp
simpa only [finiteEntropy, sub_self, zero_add] using htotal
noncomputable def finitePushforward {ι κ : Type*} [Fintype ι] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) (b : κ) : ℝ := ∑ a : ι with π a = b, p a
theorem finite_pushforward_sum {ι κ : Type*} [Fintype ι] [Fintype κ] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) : ∑ b : κ, finitePushforward p π b = ∑ a : ι, p a := by
exact Finset.sum_fiberwise Finset.univ π p
theorem finite_entropy_projection_defect {ι κ : Type*} [Fintype ι] [Fintype κ] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) (M : κ → ℝ) {q : ℝ}
(hp : ∀ a, 0 ≤ p a) (hq : 0 < q) (hM : ∀ b, 0 ≤ M b)
(hbound : ∀ a, p a ≤ M (π a)) :
finiteEntropy Finset.univ (finitePushforward p π) + (∑ a : ι, p a) * Real.log q -
finiteEntropy Finset.univ p ≤ q * (∑ b : κ, M b) - ∑ a : ι, p a := by
have hfiber : ∀ b : κ,
Real.negMulLog (finitePushforward p π b) + finitePushforward p π b * Real.log q -
finiteEntropy (Finset.univ.filter (fun a => π a = b)) p ≤ q * M b - finitePushforward p π b := by
intro b
apply finite_entropy_fiber_defect _ p (fun a _ => hp a) hq (hM b)
intro a ha
have heq := (Finset.mem_filter.mp ha).2
simpa only [heq] using hbound a
have htotal := Finset.sum_le_sum (s := Finset.univ) (fun b _ => hfiber b)
have hentropy : (∑ b : κ, finiteEntropy (Finset.univ.filter (fun a => π a = b)) p) =
finiteEntropy Finset.univ p := Finset.sum_fiberwise Finset.univ π (fun a => Real.negMulLog (p a))
simp only [Finset.sum_add_distrib, Finset.sum_sub_distrib, ← Finset.sum_mul, ← Finset.mul_sum,
hentropy, finite_pushforward_sum] at htotal
exact htotal
theorem finite_pushforward_nonneg {ι κ : Type*} [Fintype ι] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) (hp : ∀ a, 0 ≤ p a) (b : κ) :
0 ≤ finitePushforward p π b := Finset.sum_nonneg (fun a _ => hp a)
theorem le_finite_pushforward {ι κ : Type*} [Fintype ι] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) (hp : ∀ a, 0 ≤ p a) (a : ι) :
p a ≤ finitePushforward p π (π a) := by
exact Finset.single_le_sum (fun b _ => hp b) (by simp)
theorem finite_entropy_mono_projection {ι κ : Type*} [Fintype ι] [Fintype κ] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) (hp : ∀ a, 0 ≤ p a) :
finiteEntropy Finset.univ (finitePushforward p π) ≤ finiteEntropy Finset.univ p := by
have hh := finite_entropy_projection_defect p π (finitePushforward p π) hp
(show (0 : ℝ) < 1 by norm_num) (finite_pushforward_nonneg p π hp) (le_finite_pushforward p π hp)
simp only [Real.log_one, mul_zero, add_zero, one_mul, finite_pushforward_sum, sub_self] at hh
linarith
theorem finite_entropy_le_log_support {ι : Type*} [Fintype ι] (p : ι → ℝ) (S : Finset ι)
(hp : ∀ a, 0 ≤ p a) (hmass : ∑ a : ι, p a = 1) (hzero : ∀ a, a ∉ S → p a = 0) :
finiteEntropy Finset.univ p ≤ Real.log (S.card : ℝ) := by
classical
have hsum : ∑ a ∈ S, p a = 1 := by
rw [Finset.sum_subset (Finset.subset_univ S) (fun a _ ha => hzero a ha)]
exact hmass
have hentropy : finiteEntropy S p = finiteEntropy Finset.univ p := by
apply Finset.sum_subset (Finset.subset_univ S)
intro a _ ha
simp [hzero a ha, Real.negMulLog_def]
rw [← hentropy]
exact finite_entropy_le_log_card S p (fun a _ => hp a) hsum
theorem branching_interval_chain_entropy_lower_bound {c m : ℕ → ℕ} {T N R : ℕ}
{α C : ℝ} {z w : ℕ} {L : List (ℕ × ℕ)} (H : ℕ → ℝ)
(hchain : BranchingIntervalChain c T N R α z L w) (hR : 0 < R)
(hH : Monotone H) (hm : ∀ i : ℕ, i < N → T * i ≤ m i)
(hstep : ∀ p ∈ L,
H (m p.1) + ((T * p.2 - m p.1 : ℕ) : ℝ) * Real.log 2 - C ≤ H (T * p.2)) :
H (T * z) + ((L.map (fun p => T * p.2 - m p.1)).sum : ℝ) * Real.log 2 -
C * (L.length : ℝ) ≤ H (T * w) := by
induction L generalizing z with
| nil =>
change w = z at hchain
simp [hchain]
| cons p L ih =>
rcases p with ⟨a, b⟩
obtain ⟨hza, _, hblock, htail⟩ := hchain
have hab : a < b := by have := hblock.width; omega
have haN : a < N := hab.trans_le hblock.end_le
have hstart := hH ((Nat.mul_le_mul_left T hza).trans (hm a haN))
have hhead := hstep (a, b) (by simp)
have hlast := ih htail (fun q hq => hstep q (List.mem_cons_of_mem (a, b) hq))
simp only [List.map_cons, List.sum_cons, List.length_cons, Nat.cast_add, Nat.cast_one]
nlinarith
theorem finite_entropy_projection_gain {ι κ : Type*} [Fintype ι] [Fintype κ] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) (M : κ → ℝ) {q C : ℝ}
(hp : ∀ a, 0 ≤ p a) (hmass : ∑ a : ι, p a = 1) (hq : 0 < q) (hM : ∀ b, 0 ≤ M b)
(hbound : ∀ a, p a ≤ M (π a)) (hpeak : q * (∑ b : κ, M b) ≤ C + 1) :
finiteEntropy Finset.univ (finitePushforward p π) + Real.log q - C ≤ finiteEntropy Finset.univ p := by
have hh := finite_entropy_projection_defect p π M hp hq hM hbound
rw [hmass, one_mul] at hh
linarith
theorem finite_pushforward_comp {ι κ ν : Type*} [Fintype ι] [Fintype κ]
[DecidableEq κ] [DecidableEq ν] (p : ι → ℝ) (π : ι → κ) (σ : κ → ν) :
finitePushforward (finitePushforward p π) σ = finitePushforward p (σ ∘ π) := by
funext b
unfold finitePushforward
simpa only [Finset.mem_filter, Finset.mem_univ, true_and, Function.comp_apply] using
Finset.sum_fiberwise_eq_sum_filter (Finset.univ : Finset ι)
(Finset.univ.filter (fun a => σ a = b)) π p
theorem finite_entropy_pushforward_le_log_image {ι κ : Type*} [Fintype ι] [Fintype κ]
[DecidableEq κ] (p : ι → ℝ) (π : ι → κ) (hp : ∀ a, 0 ≤ p a) (hmass : ∑ a : ι, p a = 1) :
finiteEntropy Finset.univ (finitePushforward p π) ≤
Real.log ((Finset.univ.image π).card : ℝ) := by
classical
apply finite_entropy_le_log_support (finitePushforward p π) (Finset.univ.image π)
(finite_pushforward_nonneg p π hp) (by rw [finite_pushforward_sum, hmass])
intro b hb
have he : Finset.univ.filter (fun a => π a = b) = ∅ := by
apply Finset.eq_empty_iff_forall_notMem.mpr
intro a ha
exact hb (Finset.mem_image.mpr ⟨a, Finset.mem_univ a, (Finset.mem_filter.mp ha).2⟩)
simp only [finitePushforward, he, Finset.sum_empty]
def dyadicIndex (k n : ℕ) : Fin (2 ^ k) := ⟨n % 2 ^ k, Nat.mod_lt n (by positivity)⟩
noncomputable def dyadicDistribution {ι : Type*} [Fintype ι] (p : ι → ℝ) (f : ι → ℕ) (k : ℕ) :
Fin (2 ^ k) → ℝ := finitePushforward p (fun a => dyadicIndex k (f a))
noncomputable def dyadicEntropy {ι : Type*} [Fintype ι] (p : ι → ℝ) (f : ι → ℕ) (k : ℕ) : ℝ :=
finiteEntropy Finset.univ (dyadicDistribution p f k)
theorem dyadic_distribution_project {ι : Type*} [Fintype ι] (p : ι → ℝ) (f : ι → ℕ)
{u v : ℕ} (huv : u ≤ v) :
finitePushforward (dyadicDistribution p f v) (fun a => dyadicIndex u a.val) = dyadicDistribution p f u := by
rw [dyadicDistribution, finite_pushforward_comp]
unfold dyadicDistribution
congr 1
funext a
apply Fin.ext
exact Nat.mod_mod_of_dvd (f a) (pow_dvd_pow 2 huv)
theorem dyadic_entropy_mono {ι : Type*} [Fintype ι] (p : ι → ℝ) (f : ι → ℕ)
(hp : ∀ a, 0 ≤ p a) : Monotone (dyadicEntropy p f) := by
intro u v huv
have hh := finite_entropy_mono_projection (dyadicDistribution p f v) (fun a => dyadicIndex u a.val)
(finite_pushforward_nonneg p _ hp)
rw [dyadic_distribution_project p f huv] at hh
exact hh
theorem dyadic_entropy_zero {ι : Type*} [Fintype ι] (p : ι → ℝ) (f : ι → ℕ)
(hmass : ∑ a : ι, p a = 1) : dyadicEntropy p f 0 = 0 := by
have hi : ∀ a : ι, dyadicIndex 0 (f a) = (0 : Fin (2 ^ 0)) := by
intro a
apply Fin.ext
simp [dyadicIndex]
have hvalue : dyadicDistribution p f 0 0 = 1 := by
simpa only [dyadicDistribution, finitePushforward, hi, Finset.filter_true] using hmass
have hr : ∀ r : Fin (2 ^ 0), r = 0 := by
intro r
apply Fin.ext
have hh := r.isLt
norm_num at hh
omega
unfold dyadicEntropy finiteEntropy
apply Finset.sum_eq_zero
intro r _
rw [hr r, hvalue]
simp [Real.negMulLog_def]
theorem dyadic_entropy_le_log_projection {ι : Type*} [Fintype ι] (p : ι → ℝ) (f : ι → ℕ)
(hp : ∀ a, 0 ≤ p a) (hmass : ∑ a : ι, p a = 1) (k : ℕ) :
dyadicEntropy p f k ≤ Real.log ((dyadicProjection (Finset.univ.image f) k).card : ℝ) := by
classical
have hh := finite_entropy_pushforward_le_log_image p (fun a => dyadicIndex k (f a)) hp hmass
have himage : (Finset.univ.image (fun a => dyadicIndex k (f a))).image Fin.val =
dyadicProjection (Finset.univ.image f) k := by
simp only [Finset.image_image, dyadicProjection, dyadicIndex]
rfl
have hcard : (Finset.univ.image (fun a => dyadicIndex k (f a))).card =
(dyadicProjection (Finset.univ.image f) k).card := by
rw [← himage, Finset.card_image_of_injective _ Fin.val_injective]
rw [hcard] at hh
exact hh
theorem dyadic_entropy_interval_gain {ι : Type*} [Fintype ι] (p : ι → ℝ) (f : ι → ℕ)
(hp : ∀ a, 0 ≤ p a) (hmass : ∑ a : ι, p a = 1) {u v : ℕ} (huv : u ≤ v)
(M : Fin (2 ^ u) → ℝ) {C : ℝ} (hM : ∀ b, 0 ≤ M b)
(hbound : ∀ a : Fin (2 ^ v), dyadicDistribution p f v a ≤ M (dyadicIndex u a.val))
(hpeak : (2 : ℝ) ^ (v - u) * (∑ b, M b) ≤ C + 1) :
dyadicEntropy p f u + ((v - u : ℕ) : ℝ) * Real.log 2 - C ≤ dyadicEntropy p f v := by
have hh := finite_entropy_projection_gain (dyadicDistribution p f v) (fun a => dyadicIndex u a.val) M
(finite_pushforward_nonneg p _ hp) (by rw [dyadicDistribution, finite_pushforward_sum, hmass])
(pow_pos (by norm_num : (0 : ℝ) < 2) _) hM hbound hpeak
rw [dyadic_distribution_project p f huv, Real.log_pow] at hh
exact hh
theorem branching_interval_chain_entropy_amplification {A : Finset ℕ} {c m : ℕ → ℕ}
{T N R M w : ℕ} {α C ρ B : ℝ} {L : List (ℕ × ℕ)} (H : ℕ → ℝ)
(hchain : BranchingIntervalChain c T N R α 0 L w) (hR : 0 < R) (hρ : 0 ≤ ρ)
(hH : Monotone H) (hH0 : H 0 = 0) (hm : ∀ i : ℕ, i < N → T * i ≤ m i)
(hblocks : ∀ p ∈ L, DyadicAmplificationBlock A (m p.1) (T * p.2) M
(branchPrefix c p.2 - branchPrefix c p.1) ρ)
(hstep : ∀ p ∈ L,
H (m p.1) + ((T * p.2 - m p.1 : ℕ) : ℝ) * Real.log 2 - C ≤ H (T * p.2))
(hbits : B ≤ ((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ))
(hloss : C * (L.length : ℝ) ≤ ρ / 2 * B * Real.log 2) :
(branchPrefix c w : ℝ) * Real.log 2 + ρ / 2 * B * Real.log 2 ≤ H (T * w) := by
have hchainH := branching_interval_chain_entropy_lower_bound H hchain hR hH hm hstep
rw [Nat.mul_zero, hH0, zero_add] at hchainH
have hgain := dyadic_amplification_blocks_entropy_gain hρ hblocks
have hlog : (0 : ℝ) ≤ Real.log 2 := Real.log_nonneg (by norm_num)
have hgainlog := mul_le_mul_of_nonneg_right hgain hlog
have hbitslog := mul_le_mul_of_nonneg_right (mul_le_mul_of_nonneg_left hbits hρ) hlog
have hsum : ((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) =
(branchPrefix c w : ℝ) := by
rw [branching_interval_chain_entropy hchain, branch_prefix_zero, Nat.sub_zero]
rw [hsum] at hgainlog hbitslog
nlinarith
theorem sum_test_cyclicPushforward {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(w : ι → ℂ) (π : ι → ZMod q) (h : ZMod q → ℂ) :
(∑ a : ZMod q, h a * cyclicPushforward w π a) = ∑ x : ι, h (π x) * w x := by
classical
simp only [cyclicPushforward, Finset.mul_sum]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro x _
simp only [mul_ite, mul_zero]
simp
theorem sum_test_cyclicConvolution {q : ℕ} [NeZero q] (f g h : ZMod q → ℂ) :
(∑ a : ZMod q, h a * cyclicConvolution f g a) =
∑ x : ZMod q, ∑ y : ZMod q, h (x + y) * f x * g y := by
simp only [cyclicConvolution, Finset.mul_sum]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro x _
refine Fintype.sum_equiv (Equiv.subRight x) _ _ ?_
intro z
simp only [Equiv.subRight_apply]
have hh : x + (z - x) = z := by abel
rw [hh]
ring
theorem cyclicConvolution_pushforward_left {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(w : ι → ℂ) (π : ι → ZMod q) (g : ZMod q → ℂ) (a : ZMod q) :
cyclicConvolution (cyclicPushforward w π) g a = ∑ x : ι, w x * g (a - π x) := by
simpa only [cyclicConvolution, mul_comm] using sum_test_cyclicPushforward w π (fun b => g (a - b))
theorem cyclicPushforward_convolution {Q q : ℕ} [NeZero Q] [NeZero q]
(f g : ZMod Q → ℂ) (π : ZMod Q →+ ZMod q) :
cyclicPushforward (cyclicConvolution f g) π =
cyclicConvolution (cyclicPushforward f π) (cyclicPushforward g π) := by
classical
funext a
calc
_ = ∑ z : ZMod Q, (if π z = a then (1 : ℂ) else 0) * cyclicConvolution f g z := by
simp only [cyclicPushforward, ite_mul, one_mul, zero_mul]
_ = ∑ x : ZMod Q, ∑ y : ZMod Q, (if π (x + y) = a then (1 : ℂ) else 0) * f x * g y :=
sum_test_cyclicConvolution f g _
_ = ∑ x : ZMod Q, f x * cyclicPushforward g π (a - π x) := by
apply Finset.sum_congr rfl
intro x _
rw [cyclicPushforward, Finset.mul_sum]
apply Finset.sum_congr rfl
intro y _
rw [map_add]
by_cases hy : π y = a - π x
· simp [hy]
· have hxy : π x + π y ≠ a := by
intro heq
apply hy
exact (eq_sub_iff_add_eq').mpr heq
simp [hy, hxy]
_ = _ := (cyclicConvolution_pushforward_left f π (cyclicPushforward g π) a).symm
noncomputable def cyclicTwist {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (k x : ZMod q) : ℂ :=
ZMod.stdAddChar (-(x * k)) * f x
theorem cyclicTwist_convolution {q : ℕ} [NeZero q] (f g : ZMod q → ℂ) (k : ZMod q) :
cyclicTwist (cyclicConvolution f g) k = cyclicConvolution (cyclicTwist f k) (cyclicTwist g k) := by
funext x
simp only [cyclicTwist, cyclicConvolution, Finset.mul_sum]
apply Finset.sum_congr rfl
intro y _
have hchar : ZMod.stdAddChar (-(x * k)) =
ZMod.stdAddChar (-(y * k)) * ZMod.stdAddChar (-((x - y) * k)) := by
rw [← AddChar.map_add_eq_mul]
congr 1
ring
rw [hchar]
ring
theorem sum_norm_cyclicConvolution_le {q : ℕ} [NeZero q] (f g : ZMod q → ℂ) :
(∑ x : ZMod q, ‖cyclicConvolution f g x‖) ≤
(∑ x : ZMod q, ‖f x‖) * (∑ x : ZMod q, ‖g x‖) := by
calc
_ ≤ ∑ x : ZMod q, ∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ := by
apply Finset.sum_le_sum
intro x _
simpa only [cyclicConvolution, norm_mul] using norm_sum_le Finset.univ (fun y => f y * g (x - y))
_ = ∑ y : ZMod q, ‖f y‖ * (∑ x : ZMod q, ‖g x‖) := by
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro y _
rw [← Finset.mul_sum]
congr 1
exact Fintype.sum_equiv (Equiv.subRight y) _ _ (fun _ => rfl)
_ = _ := (Finset.sum_mul _ _ _).symm
theorem sum_norm_cyclicConvolutionPow_le {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (r : ℕ) :
(∑ x : ZMod q, ‖cyclicConvolutionPow f r x‖) ≤ (∑ x : ZMod q, ‖f x‖) ^ r := by
induction r with
| zero =>
simp only [cyclicConvolutionPow, pow_zero]
have hh : (∑ x : ZMod q, ‖if x = 0 then (1 : ℂ) else 0‖) = 1 := by
calc
_ = ∑ x : ZMod q, if x = 0 then (1 : ℝ) else 0 := by
apply Finset.sum_congr rfl
intro x _
by_cases hx : x = 0 <;> simp [hx]
_ = _ := by simp
exact hh.le
| succ r ih =>
calc
_ ≤ (∑ x : ZMod q, ‖f x‖) * (∑ x : ZMod q, ‖cyclicConvolutionPow f r x‖) :=
sum_norm_cyclicConvolution_le f _
_ ≤ (∑ x : ZMod q, ‖f x‖) * (∑ x : ZMod q, ‖f x‖) ^ r :=
mul_le_mul_of_nonneg_left ih (Finset.sum_nonneg (fun _ _ => norm_nonneg _))
_ = _ := by rw [pow_succ]; ring
noncomputable def cyclicFiberDFT {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (k : ZMod Q) : ZMod q → ℂ :=
cyclicPushforward (cyclicTwist f k) π
noncomputable def cyclicFiberFourierNorm {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (k : ZMod Q) : ℝ :=
∑ a : ZMod q, ‖cyclicFiberDFT π f k a‖
theorem cyclicFiberDFT_convolution {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f g : ZMod Q → ℂ) (k : ZMod Q) :
cyclicFiberDFT π (cyclicConvolution f g) k =
cyclicConvolution (cyclicFiberDFT π f k) (cyclicFiberDFT π g k) := by
unfold cyclicFiberDFT
rw [cyclicTwist_convolution, cyclicPushforward_convolution]
theorem cyclicFiberDFT_convolutionPow {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (k : ZMod Q) (r : ℕ) :
cyclicFiberDFT π (cyclicConvolutionPow f r) k = cyclicConvolutionPow (cyclicFiberDFT π f k) r := by
induction r with
| zero =>
funext a
change (∑ x : ZMod Q, if π x = a then
ZMod.stdAddChar (-(x * k)) * (if x = 0 then (1 : ℂ) else 0) else 0) = if a = 0 then 1 else 0
have hh : ∀ x : ZMod Q,
(if π x = a then ZMod.stdAddChar (-(x * k)) * (if x = 0 then (1 : ℂ) else 0) else 0) =
if x = 0 then (if a = 0 then 1 else 0) else 0 := by
intro x
by_cases hx : x = 0
· subst x
simp [eq_comm]
· simp [hx]
simp_rw [hh]
simp
| succ r ih => rw [cyclicConvolutionPow, cyclicFiberDFT_convolution, ih, cyclicConvolutionPow]
theorem cyclicFiberFourierNorm_convolutionPow_le {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (k : ZMod Q) (r : ℕ) :
cyclicFiberFourierNorm π (cyclicConvolutionPow f r) k ≤ (cyclicFiberFourierNorm π f k) ^ r := by
unfold cyclicFiberFourierNorm
rw [cyclicFiberDFT_convolutionPow]
exact sum_norm_cyclicConvolutionPow_le _ r
theorem mul_norm_le_sum_norm_dft {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (x : ZMod q) :
(q : ℝ) * ‖f x‖ ≤ ∑ k : ZMod q, ‖ZMod.dft f k‖ := by
have hsum := congrFun (ZMod.dft_dft f) (-x)
rw [ZMod.dft_apply] at hsum
simp only [mul_neg, neg_neg, smul_eq_mul] at hsum
calc
_ = ‖(q : ℂ) * f x‖ := by simp
_ = ‖∑ k : ZMod q, ZMod.stdAddChar (k * x) * ZMod.dft f k‖ := by rw [hsum]
_ ≤ ∑ k : ZMod q, ‖ZMod.stdAddChar (k * x) * ZMod.dft f k‖ := norm_sum_le _ _
_ = _ := by simp only [norm_mul, ZMod.stdAddChar_apply, Circle.norm_coe, one_mul]
theorem dft_restrict_cyclic_fiber {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (a : ZMod q) (k : ZMod Q) :
ZMod.dft (fun x => if π x = a then f x else 0) k = cyclicFiberDFT π f k a := by
simp only [ZMod.dft_apply, smul_eq_mul, cyclicFiberDFT, cyclicPushforward, cyclicTwist,
mul_ite, mul_zero]
theorem cyclic_fiber_norm_bound {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (x : ZMod Q) :
(Q : ℝ) * ‖f x‖ ≤ ∑ k : ZMod Q, ‖cyclicFiberDFT π f k (π x)‖ := by
have hh := mul_norm_le_sum_norm_dft (fun y => if π y = π x then f y else 0) x
simpa only [if_true, dft_restrict_cyclic_fiber] using hh
theorem exists_cyclic_convolution_power_fiber_bound {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (r : ℕ) :
∃ M : ZMod q → ℝ, (∀ a, 0 ≤ M a) ∧
(∀ x, ‖cyclicConvolutionPow f r x‖ ≤ M (π x)) ∧
(Q : ℝ) * (∑ a : ZMod q, M a) ≤ ∑ k : ZMod Q, (cyclicFiberFourierNorm π f k) ^ r := by
let M : ZMod q → ℝ := fun a => (∑ k : ZMod Q, ‖cyclicFiberDFT π (cyclicConvolutionPow f r) k a‖) / Q
have hQ : (0 : ℝ) < Q := by exact_mod_cast NeZero.pos Q
refine ⟨M, fun a => div_nonneg (Finset.sum_nonneg (fun _ _ => norm_nonneg _)) hQ.le, ?_, ?_⟩
· intro x
apply (le_div_iff₀ hQ).mpr
simpa only [mul_comm] using cyclic_fiber_norm_bound π (cyclicConvolutionPow f r) x
· change (Q : ℝ) * (∑ a : ZMod q, (∑ k : ZMod Q, ‖cyclicFiberDFT π (cyclicConvolutionPow f r) k a‖) / Q) ≤ _
rw [← Finset.sum_div, mul_div_cancel₀ _ hQ.ne', Finset.sum_comm]
exact Finset.sum_le_sum (fun k _ => cyclicFiberFourierNorm_convolutionPow_le π f k r)
theorem sum_norm_cyclicPushforward_le {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(w : ι → ℂ) (π : ι → ZMod q) :
(∑ a : ZMod q, ‖cyclicPushforward w π a‖) ≤ ∑ x : ι, ‖w x‖ := by
classical
calc
_ ≤ ∑ a : ZMod q, ∑ x : ι, ‖if π x = a then w x else 0‖ :=
Finset.sum_le_sum (fun a _ => norm_sum_le _ _)
_ = _ := by
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro x _
simp [apply_ite]
theorem weighted_sum_sq_le {ι : Type*} (S : Finset ι) (w t : ι → ℝ)
(hw : ∀ i ∈ S, 0 ≤ w i) (hmass : ∑ i ∈ S, w i = 1) :
(∑ i ∈ S, w i * t i) ^ 2 ≤ ∑ i ∈ S, w i * (t i) ^ 2 := by
have hleft : (∑ i ∈ S, Real.sqrt (w i) * (Real.sqrt (w i) * t i)) = ∑ i ∈ S, w i * t i := by
apply Finset.sum_congr rfl
intro i hi
rw [← mul_assoc, Real.mul_self_sqrt (hw i hi)]
have hfirst : (∑ i ∈ S, (Real.sqrt (w i)) ^ 2) = 1 := by
calc
_ = ∑ i ∈ S, w i := Finset.sum_congr rfl (fun i hi => Real.sq_sqrt (hw i hi))
_ = _ := hmass
have hsecond : (∑ i ∈ S, (Real.sqrt (w i) * t i) ^ 2) = ∑ i ∈ S, w i * (t i) ^ 2 := by
apply Finset.sum_congr rfl
intro i hi
rw [mul_pow, Real.sq_sqrt (hw i hi)]
have hh := Finset.sum_mul_sq_le_sq_mul_sq S (fun i => Real.sqrt (w i)) (fun i => Real.sqrt (w i) * t i)
rwa [hleft, hfirst, hsecond, one_mul] at hh
noncomputable def cyclicMixture {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(w : ι → ℝ) (F : ι → ZMod q → ℂ) (x : ZMod q) : ℂ := ∑ i : ι, (w i : ℂ) * F i x
theorem cyclicFiberDFT_mixture {ι : Type*} [Fintype ι] {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (w : ι → ℝ) (F : ι → ZMod Q → ℂ) (k : ZMod Q) (a : ZMod q) :
cyclicFiberDFT π (cyclicMixture w F) k a = ∑ i : ι, (w i : ℂ) * cyclicFiberDFT π (F i) k a := by
classical
unfold cyclicFiberDFT cyclicPushforward cyclicTwist cyclicMixture
have hh : ∀ x : ZMod Q,
(if π x = a then ZMod.stdAddChar (-(x * k)) * (∑ i : ι, (w i : ℂ) * F i x) else 0) =
∑ i : ι, (w i : ℂ) * (if π x = a then ZMod.stdAddChar (-(x * k)) * F i x else 0) := by
intro x
by_cases hx : π x = a
· simp only [hx, if_true, Finset.mul_sum]
apply Finset.sum_congr rfl
intro i _
ring
· simp [hx]
simp_rw [hh, Finset.mul_sum]
rw [Finset.sum_comm]
theorem cyclicFiberDFT_of_coset_support {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (f : ZMod Q → ℂ) (k : ZMod Q) (b a : ZMod q)
(hsupport : ∀ x, f x ≠ 0 → π x = b) :
cyclicFiberDFT π f k a = if b = a then ZMod.dft f k else 0 := by
classical
by_cases hba : b = a
· subst b
rw [if_pos rfl, ← dft_restrict_cyclic_fiber]
have hrestrict : (fun x => if π x = a then f x else 0) = f := by
funext x
by_cases hx : π x = a
· simp [hx]
· have hzero : f x = 0 := by
by_contra hn
exact hx (hsupport x hn)
simp [hx, hzero]
rw [hrestrict]
· rw [if_neg hba]
unfold cyclicFiberDFT cyclicPushforward cyclicTwist
apply Finset.sum_eq_zero
intro x _
by_cases hx : π x = a
· have hzero : f x = 0 := by
by_contra hn
exact hba ((hsupport x hn).symm.trans hx)
simp [hx, hzero]
· simp [hx]
theorem cyclicFiberDFT_coset_mixture {ι : Type*} [Fintype ι] {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (w : ι → ℝ) (F : ι → ZMod Q → ℂ) (b : ι → ZMod q)
(hsupport : ∀ i x, F i x ≠ 0 → π x = b i) (k : ZMod Q) :
cyclicFiberDFT π (cyclicMixture w F) k =
cyclicPushforward (fun i => (w i : ℂ) * ZMod.dft (F i) k) b := by
funext a
rw [cyclicFiberDFT_mixture]
unfold cyclicPushforward
apply Finset.sum_congr rfl
intro i _
rw [cyclicFiberDFT_of_coset_support π (F i) k (b i) a (hsupport i)]
simp only [mul_ite, mul_zero]
theorem cyclicFiberFourierNorm_mixture_sq_le {ι : Type*} [Fintype ι] {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (w : ι → ℝ) (F : ι → ZMod Q → ℂ) (b : ι → ZMod q)
(hw : ∀ i, 0 ≤ w i) (hmass : ∑ i : ι, w i = 1)
(hsupport : ∀ i x, F i x ≠ 0 → π x = b i) (k : ZMod Q) :
(cyclicFiberFourierNorm π (cyclicMixture w F) k) ^ 2 ≤
∑ i : ι, w i * ‖ZMod.dft (F i) k‖ ^ 2 := by
have hnorm : cyclicFiberFourierNorm π (cyclicMixture w F) k ≤
∑ i : ι, w i * ‖ZMod.dft (F i) k‖ := by
unfold cyclicFiberFourierNorm
rw [cyclicFiberDFT_coset_mixture π w F b hsupport k]
calc
_ ≤ ∑ i : ι, ‖(w i : ℂ) * ZMod.dft (F i) k‖ := sum_norm_cyclicPushforward_le _ b
_ = _ := by
apply Finset.sum_congr rfl
intro i _
rw [norm_mul, Complex.norm_real, Real.norm_eq_abs, abs_of_nonneg (hw i)]
calc
_ ≤ (∑ i : ι, w i * ‖ZMod.dft (F i) k‖) ^ 2 :=
pow_le_pow_left₀ (Finset.sum_nonneg (fun _ _ => norm_nonneg _)) hnorm 2
_ ≤ _ := weighted_sum_sq_le Finset.univ w (fun i => ‖ZMod.dft (F i) k‖) (fun i _ => hw i) hmass
theorem exists_cyclic_mixture_power_fiber_bound {ι : Type*} [Fintype ι] {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+ ZMod q) (w : ι → ℝ) (F : ι → ZMod Q → ℂ) (b : ι → ZMod q)
(hw : ∀ i, 0 ≤ w i) (hmass : ∑ i : ι, w i = 1)
(hsupport : ∀ i x, F i x ≠ 0 → π x = b i) (B : ZMod Q → ℝ)
(henergy : ∀ k, (∑ i : ι, w i * ‖ZMod.dft (F i) k‖ ^ 2) ≤ B k) (r : ℕ) :
∃ M : ZMod q → ℝ, (∀ a, 0 ≤ M a) ∧
(∀ x, ‖cyclicConvolutionPow (cyclicMixture w F) (2 * r) x‖ ≤ M (π x)) ∧
(Q : ℝ) * (∑ a : ZMod q, M a) ≤ ∑ k : ZMod Q, (B k) ^ r := by
obtain ⟨M, hM, hbound, hsum⟩ := exists_cyclic_convolution_power_fiber_bound π (cyclicMixture w F) (2 * r)
refine ⟨M, hM, hbound, hsum.trans (Finset.sum_le_sum ?_)⟩
intro k _
have hh := (cyclicFiberFourierNorm_mixture_sq_le π w F b hw hmass hsupport k).trans (henergy k)
simpa only [pow_mul] using pow_le_pow_left₀ (sq_nonneg _) hh r
theorem sum_sq_norm_le_of_sum_norm_one {ι : Type*} [Fintype ι] (f : ι → ℂ) {M : ℝ}
(hmass : ∑ x : ι, ‖f x‖ = 1) (hbound : ∀ x, ‖f x‖ ≤ M) :
(∑ x : ι, ‖f x‖ ^ 2) ≤ M := by
calc
_ ≤ ∑ x : ι, M * ‖f x‖ := Finset.sum_le_sum (fun x _ => by
simpa only [pow_two] using mul_le_mul_of_nonneg_right (hbound x) (norm_nonneg _))
_ = M := by rw [← Finset.mul_sum, hmass, mul_one]
theorem weighted_fourier_energy_le {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (w : ZMod q → ℝ)
{M₁ M₂ : ℝ} (hmass : ∑ x : ZMod q, ‖f x‖ = 1)
(hM₁ : ∀ x, ‖f x‖ ≤ M₁) (hM₂ : ∀ x, w x ≤ M₂) (hM₂pos : 0 ≤ M₂)
{k : ZMod q} (hk : IsUnit k) :
(∑ x : ZMod q, w x * ‖ZMod.dft f (x * k)‖ ^ 2) ≤ (q : ℝ) * M₁ * M₂ := by
obtain ⟨u, rfl⟩ := hk
have hperm : (∑ x : ZMod q, ‖ZMod.dft f (x * (u : ZMod q))‖ ^ 2) =
∑ x : ZMod q, ‖ZMod.dft f x‖ ^ 2 :=
Fintype.sum_equiv u.mulRight _ _ (fun _ => rfl)
calc
_ ≤ ∑ x : ZMod q, M₂ * ‖ZMod.dft f (x * (u : ZMod q))‖ ^ 2 :=
Finset.sum_le_sum (fun x _ => mul_le_mul_of_nonneg_right (hM₂ x) (sq_nonneg _))
_ = M₂ * ((q : ℝ) * ∑ x : ZMod q, ‖f x‖ ^ 2) := by rw [← Finset.mul_sum, hperm, dft_parseval]
_ ≤ M₂ * ((q : ℝ) * M₁) := mul_le_mul_of_nonneg_left
(mul_le_mul_of_nonneg_left (sum_sq_norm_le_of_sum_norm_one f hmass hM₁) (Nat.cast_nonneg q)) hM₂pos
_ = _ := by ring
theorem norm_dft_le_sum_norm {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (k : ZMod q) :
‖ZMod.dft f k‖ ≤ ∑ x : ZMod q, ‖f x‖ := by
rw [ZMod.dft_apply]
calc
_ ≤ ∑ x : ZMod q, ‖ZMod.stdAddChar (-(x * k)) • f x‖ := norm_sum_le _ _
_ = _ := by simp only [smul_eq_mul, norm_mul, ZMod.stdAddChar_apply, Circle.norm_coe, one_mul]
theorem weighted_fourier_energy_le_one {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (w : ZMod q → ℝ)
(hfnorm : ∑ x : ZMod q, ‖f x‖ = 1) (hw : ∀ x, 0 ≤ w x) (hmass : ∑ x : ZMod q, w x = 1)
(k : ZMod q) : (∑ x : ZMod q, w x * ‖ZMod.dft f (x * k)‖ ^ 2) ≤ 1 := by
calc
_ ≤ ∑ x : ZMod q, w x := by
apply Finset.sum_le_sum
intro x _
have hnorm : ‖ZMod.dft f (x * k)‖ ≤ 1 := by simpa only [hfnorm] using norm_dft_le_sum_norm f (x * k)
have hsq : ‖ZMod.dft f (x * k)‖ ^ 2 ≤ 1 := by nlinarith [norm_nonneg (ZMod.dft f (x * k))]
simpa only [mul_one] using mul_le_mul_of_nonneg_left hsq (hw x)
_ = _ := hmass
theorem uniform_fourier_energy_eq {q : ℕ} [NeZero q] (f : ZMod q → ℂ) {k : ZMod q} (hk : IsUnit k) :
(∑ x : ZMod q, (1 / (q : ℝ)) * ‖ZMod.dft f (x * k)‖ ^ 2) = ∑ x : ZMod q, ‖f x‖ ^ 2 := by
obtain ⟨u, rfl⟩ := hk
have hperm : (∑ x : ZMod q, ‖ZMod.dft f (x * (u : ZMod q))‖ ^ 2) =
∑ x : ZMod q, ‖ZMod.dft f x‖ ^ 2 := Fintype.sum_equiv u.mulRight _ _ (fun _ => rfl)
rw [← Finset.mul_sum, hperm, dft_parseval]
have hq : (q : ℝ) ≠ 0 := by exact_mod_cast NeZero.ne q
field_simp
theorem probability_point_mass_le_of_two_atoms {ι : Type*} [Fintype ι] (p : ι → ℝ)
(hp : ∀ i, 0 ≤ p i) (hmass : ∑ i : ι, p i = 1) {a b : ι} (hab : a ≠ b)
{β : ℝ} (ha : β ≤ p a) (hb : β ≤ p b) : ∀ i, p i ≤ 1 - β := by
classical
have hpair : ∀ i j : ι, i ≠ j → p i + p j ≤ 1 := by
intro i j hij
have hh := Finset.sum_le_sum_of_subset_of_nonneg
(Finset.subset_univ ({i, j} : Finset ι)) (fun x _ _ => hp x)
simpa only [Finset.sum_pair hij, hmass] using hh
intro i
by_cases hia : i = a
· subst i
have hh := hpair a b hab
linarith
· have hh := hpair i a hia
linarith
theorem finite_probability_collision_le_of_two_atoms {ι : Type*} [Fintype ι] (p : ι → ℝ)
(hp : ∀ i, 0 ≤ p i) (hmass : ∑ i : ι, p i = 1) {a b : ι} (hab : a ≠ b)
{β : ℝ} (ha : β ≤ p a) (hb : β ≤ p b) : (∑ i : ι, (p i) ^ 2) ≤ 1 - β := by
have hbound := probability_point_mass_le_of_two_atoms p hp hmass hab ha hb
calc
_ ≤ ∑ i : ι, (1 - β) * p i := Finset.sum_le_sum (fun i _ => by
simpa only [pow_two] using mul_le_mul_of_nonneg_right (hbound i) (hp i))
_ = _ := by rw [← Finset.mul_sum, hmass, mul_one]
theorem finite_collision_le_pushforward_collision {ι κ : Type*} [Fintype ι] [Fintype κ]
[DecidableEq κ] (p : ι → ℝ) (π : ι → κ) (hp : ∀ i, 0 ≤ p i) :
(∑ i : ι, (p i) ^ 2) ≤ ∑ b : κ, (finitePushforward p π b) ^ 2 := by
calc
_ ≤ ∑ i : ι, p i * finitePushforward p π (π i) := Finset.sum_le_sum (fun i _ => by
simpa only [pow_two] using mul_le_mul_of_nonneg_left (le_finite_pushforward p π hp i) (hp i))
_ = ∑ b : κ, ∑ i : ι with π i = b, p i * finitePushforward p π (π i) :=
(Finset.sum_fiberwise Finset.univ π _).symm
_ = _ := by
apply Finset.sum_congr rfl
intro b _
calc
_ = ∑ i : ι with π i = b, p i * finitePushforward p π b := by
apply Finset.sum_congr rfl
intro i hi
rw [(Finset.mem_filter.mp hi).2]
_ = _ := by rw [← Finset.sum_mul, pow_two]; rfl
theorem uniform_fourier_energy_le_of_projected_atoms {κ : Type*} [Fintype κ] [DecidableEq κ]
{q : ℕ} [NeZero q] (f : ZMod q → ℂ) (π : ZMod q → κ)
(hmass : ∑ x : ZMod q, ‖f x‖ = 1) {a b : κ} (hab : a ≠ b) {β : ℝ}
(ha : β ≤ finitePushforward (fun x => ‖f x‖) π a)
(hb : β ≤ finitePushforward (fun x => ‖f x‖) π b)
{k : ZMod q} (hk : IsUnit k) :
(∑ x : ZMod q, (1 / (q : ℝ)) * ‖ZMod.dft f (x * k)‖ ^ 2) ≤ 1 - β := by
rw [uniform_fourier_energy_eq f hk]
exact (finite_collision_le_pushforward_collision (fun x => ‖f x‖) π (fun _ => norm_nonneg _)).trans
(finite_probability_collision_le_of_two_atoms _ (finite_pushforward_nonneg _ π (fun _ => norm_nonneg _))
(by rw [finite_pushforward_sum, hmass]) hab ha hb)
theorem sum_comp_le_of_fiber_card_le {ι κ : Type*} [Fintype ι] [Fintype κ] [DecidableEq κ]
(π : ι → κ) (f : κ → ℝ) {m : ℕ} (hf : ∀ a, 0 ≤ f a)
(hcard : ∀ a, (Finset.univ.filter (fun i => π i = a)).card ≤ m) :
(∑ i : ι, f (π i)) ≤ (m : ℝ) * ∑ a : κ, f a := by
rw [← Finset.sum_fiberwise' Finset.univ π f]
calc
_ = ∑ a : κ, ((Finset.univ.filter (fun i => π i = a)).card : ℝ) * f a := by
simp only [Finset.sum_const, nsmul_eq_mul]
_ ≤ ∑ a : κ, (m : ℝ) * f a := Finset.sum_le_sum (fun a _ =>
mul_le_mul_of_nonneg_right (by exact_mod_cast hcard a) (hf a))
_ = _ := (Finset.mul_sum _ _ _).symm
theorem dyadic_frequency_reduction_fiber_card_le (u L : ℕ) (a : ZMod (2 ^ L)) :
((Finset.univ : Finset (ZMod (2 ^ (u + L)))).filter
(fun k => (k.val : ZMod (2 ^ L)) = a)).card ≤ 2 ^ u := by
classical
let S := (Finset.univ : Finset (ZMod (2 ^ (u + L)))).filter
(fun k => (k.val : ZMod (2 ^ L)) = a)
have hsub : S.image ZMod.val ⊆ (Finset.range (2 ^ (u + L))).filter (fun x => x % 2 ^ L = a.val) := by
intro x hx
obtain ⟨k, hk, rfl⟩ := Finset.mem_image.mp hx
refine Finset.mem_filter.mpr ⟨Finset.mem_range.mpr k.val_lt, ?_⟩
have hh := congrArg ZMod.val (Finset.mem_filter.mp hk).2
simpa only [ZMod.val_natCast] using hh
calc
_ = (S.image ZMod.val).card := (Finset.card_image_of_injective S (ZMod.val_injective _)).symm
_ ≤ ((Finset.range (2 ^ (u + L))).filter (fun x => x % 2 ^ L = a.val)).card := Finset.card_le_card hsub
_ ≤ 2 ^ u := dyadic_residue_fiber_card_le (b := L) (T := u)
(fun x hx => by simpa only [Nat.add_comm] using Finset.mem_range.mp hx) a.val
theorem sum_dyadic_frequency_reduction_le (u L : ℕ) (f : ZMod (2 ^ L) → ℝ) (hf : ∀ a, 0 ≤ f a) :
(∑ k : ZMod (2 ^ (u + L)), f (k.val : ZMod (2 ^ L))) ≤
(2 : ℝ) ^ u * ∑ a : ZMod (2 ^ L), f a := by
simpa only [Nat.cast_pow, Nat.cast_ofNat] using sum_comp_le_of_fiber_card_le
(fun k : ZMod (2 ^ (u + L)) => (k.val : ZMod (2 ^ L))) f hf
(dyadic_frequency_reduction_fiber_card_le u L)
theorem dyadic_nonzero_sum_lt_one_of_quarter_bound {K : ℕ} (f : ZMod (2 ^ K) → ℝ)
(hbound : ∀ x, x ≠ 0 → f x ≤ (1 / 4 : ℝ) ^ dyadicConductorLevel x) :
(∑ x ∈ (Finset.univ : Finset (ZMod (2 ^ K))).erase 0, f x) < 1 := by
classical
have hmaps : ∀ x ∈ (Finset.univ : Finset (ZMod (2 ^ K))).erase 0,
dyadicConductorLevel x ∈ Finset.Icc 1 K := by
intro x hx
exact Finset.mem_Icc.mpr ⟨dyadic_conductor_pos (Finset.mem_erase.mp hx).1,
(dyadic_conductor_spec x).1⟩
have hsum : (∑ x ∈ (Finset.univ : Finset (ZMod (2 ^ K))).erase 0, f x) ≤
∑ j ∈ Finset.Icc 1 K, (1 / 2 : ℝ) ^ j := by
rw [← Finset.sum_fiberwise_of_maps_to hmaps f]
apply Finset.sum_le_sum
intro j hj
have hcard : ((((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)).card : ℝ) ≤ (2 : ℝ) ^ j := by
exact_mod_cast dyadic_conductor_fiber_card_le (Finset.mem_Icc.mp hj).2
calc
_ ≤ ∑ x ∈ (((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)), (1 / 4 : ℝ) ^ j := by
apply Finset.sum_le_sum
intro x hx
obtain ⟨hx, hlevel⟩ := Finset.mem_filter.mp hx
simpa only [hlevel] using hbound x (Finset.mem_erase.mp hx).1
_ = ((((Finset.univ : Finset (ZMod (2 ^ K))).erase 0).filter
(fun x => dyadicConductorLevel x = j)).card : ℝ) * (1 / 4 : ℝ) ^ j := by simp
_ ≤ (2 : ℝ) ^ j * (1 / 4 : ℝ) ^ j := mul_le_mul_of_nonneg_right hcard (by positivity)
_ = (1 / 2 : ℝ) ^ j := by rw [← mul_pow]; norm_num
rw [dyadic_geometric_sum] at hsum
exact hsum.trans_lt (by have := pow_pos (by norm_num : (0 : ℝ) < 1 / 2) K; linarith)
theorem exists_power_for_piecewise_dyadic_energy (S : ℕ) {θ t : ℝ}
(hθ : 0 ≤ θ) (hθ1 : θ < 1) (ht : 0 < t) :
∃ r : ℕ, 0 < r ∧ ∀ K : ℕ, ∀ B : ZMod (2 ^ K) → ℝ,
(∀ x, 0 ≤ B x) → B 0 ≤ 1 →
(∀ x, x ≠ 0 → dyadicConductorLevel x ≤ S → B x ≤ θ) →
(∀ x, S < dyadicConductorLevel x → B x ≤ (2 : ℝ) ^ (-t * (dyadicConductorLevel x : ℝ))) →
(∑ x : ZMod (2 ^ K), (B x) ^ r) < 2 := by
obtain ⟨r₀, hr₀⟩ : ∃ r₀ : ℕ, θ ^ r₀ < (1 / 4 : ℝ) ^ S :=
exists_pow_lt_of_lt_one (by positivity) hθ1
obtain ⟨r₁, hr₁⟩ := exists_nat_ge (2 / t)
let r := r₀ + r₁ + 1
have htr₁ : 2 ≤ t * (r₁ : ℝ) := by
have hh := (div_le_iff₀ ht).mp hr₁
nlinarith
have htr : 2 ≤ t * (r : ℝ) := htr₁.trans
(mul_le_mul_of_nonneg_left (by exact_mod_cast (show r₁ ≤ r by omega)) ht.le)
refine ⟨r, by omega, ?_⟩
intro K B hB hBzero hshort hlong
have hpoint : ∀ x : ZMod (2 ^ K), x ≠ 0 → (B x) ^ r ≤ (1 / 4 : ℝ) ^ dyadicConductorLevel x := by
intro x hx
by_cases hlevel : dyadicConductorLevel x ≤ S
· calc
_ ≤ θ ^ r := pow_le_pow_left₀ (hB x) (hshort x hx hlevel) r
_ ≤ θ ^ r₀ := pow_le_pow_of_le_one hθ hθ1.le (by omega)
_ ≤ (1 / 4 : ℝ) ^ S := hr₀.le
_ ≤ _ := pow_le_pow_of_le_one (by norm_num) (by norm_num) hlevel
· exact powered_dyadic_decay_le (hB x) (hlong x (by omega)) htr
have hnonzero := dyadic_nonzero_sum_lt_one_of_quarter_bound (fun x => (B x) ^ r) hpoint
have hzero : (B 0) ^ r ≤ 1 := by
simpa only [one_pow] using pow_le_pow_left₀ (hB 0) hBzero r
have hsum := Finset.sum_erase_add (Finset.univ : Finset (ZMod (2 ^ K)))
(fun x => (B x) ^ r) (Finset.mem_univ 0)
linarith
theorem dyadic_coset_mixture_peak_bound {ι : Type*} [Fintype ι] (u L r : ℕ)
(π : ZMod (2 ^ (u + L)) →+ ZMod (2 ^ u))
(w : ι → ℝ) (F : ι → ZMod (2 ^ (u + L)) → ℂ) (b : ι → ZMod (2 ^ u))
(hw : ∀ i, 0 ≤ w i) (hmass : ∑ i : ι, w i = 1)
(hsupport : ∀ i x, F i x ≠ 0 → π x = b i) (B : ZMod (2 ^ L) → ℝ) (hB : ∀ k, 0 ≤ B k)
(henergy : ∀ k : ZMod (2 ^ (u + L)),
(∑ i : ι, w i * ‖ZMod.dft (F i) k‖ ^ 2) ≤ B (k.val : ZMod (2 ^ L)))
(hsumB : (∑ k : ZMod (2 ^ L), (B k) ^ r) < 2) :
∃ M : ZMod (2 ^ u) → ℝ, (∀ a, 0 ≤ M a) ∧
(∀ x, ‖cyclicConvolutionPow (cyclicMixture w F) (2 * r) x‖ ≤ M (π x)) ∧
(2 : ℝ) ^ L * (∑ a : ZMod (2 ^ u), M a) < 2 := by
obtain ⟨M, hM, hbound, hsum⟩ := exists_cyclic_mixture_power_fiber_bound π w F b hw hmass hsupport
(fun k => B (k.val : ZMod (2 ^ L))) henergy r
refine ⟨M, hM, hbound, ?_⟩
have hreduce := sum_dyadic_frequency_reduction_le u L (fun k => (B k) ^ r) (fun k => pow_nonneg (hB k) r)
have hU : (0 : ℝ) < (2 : ℝ) ^ u := pow_pos (by norm_num) u
have hscaled := (hsum.trans hreduce).trans_lt (mul_lt_mul_of_pos_left hsumB hU)
simp only [Nat.cast_mul, Nat.cast_pow, Nat.cast_ofNat, pow_add, mul_assoc] at hscaled
exact (mul_lt_mul_iff_of_pos_left hU).mp hscaled
theorem dyadic_fiber_nested (A : Finset ℕ) {d r : ℕ} (hr : r < 2 ^ d) (l s : ℕ) :
(A.filter (fun x => x % 2 ^ d = r)).filter (fun x => x % 2 ^ (d + l) = r + 2 ^ d * s) =
A.filter (fun x => x % 2 ^ (d + l) = r + 2 ^ d * s) := by
ext x
constructor
· intro hx
obtain ⟨hxA, hxh⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨(Finset.mem_filter.mp hxA).1, hxh⟩
· intro hx
obtain ⟨hxA, hxh⟩ := Finset.mem_filter.mp hx
refine Finset.mem_filter.mpr ⟨Finset.mem_filter.mpr ⟨hxA, ?_⟩, hxh⟩
calc
x % 2 ^ d = (x % 2 ^ (d + l)) % 2 ^ d := (Nat.mod_mod_of_dvd x (pow_dvd_pow 2 (by omega))).symm
_ = (r + 2 ^ d * s) % 2 ^ d := by rw [hxh]
_ = r := by rw [Nat.add_mul_mod_self_left, Nat.mod_eq_of_lt hr]
theorem dyadic_zoom_residue_mass (A : Finset ℕ) {d r : ℕ} (hr : r < 2 ^ d) (l s : ℕ) :
natResidueMass (dyadicZoom A d r) (2 ^ l) s =
natResidueMass (A.filter (fun x => x % 2 ^ d = r)) (2 ^ (d + l))
(r + 2 ^ d * (s % 2 ^ l)) := by
classical
have hs : s % 2 ^ l < 2 ^ l := Nat.mod_lt s (by positivity)
have hjoin : r + 2 ^ d * (s % 2 ^ l) < 2 ^ (d + l) := by
rw [pow_add]
have hpow : 0 < 2 ^ d := by positivity
nlinarith
have hleft : natResidueFiber (dyadicZoom A d r) (2 ^ l) s =
(dyadicZoom A d r).filter (fun x => x % 2 ^ l = s % 2 ^ l) := by
ext x
simp only [natResidueFiber, Finset.mem_filter]
rfl
have hright : natResidueFiber (A.filter (fun x => x % 2 ^ d = r)) (2 ^ (d + l))
(r + 2 ^ d * (s % 2 ^ l)) = A.filter (fun x => x % 2 ^ (d + l) = r + 2 ^ d * (s % 2 ^ l)) := by
rw [← dyadic_fiber_nested A hr l (s % 2 ^ l)]
ext x
simp only [natResidueFiber, Finset.mem_filter, Nat.ModEq, Nat.mod_eq_of_lt hjoin]
unfold natResidueMass
rw [hleft, hright, dyadic_zoom_fiber_card A hr l (s % 2 ^ l), dyadic_zoom_card A d r]
theorem dyadic_amplification_block_zoom_card {A : Finset ℕ} {u v M e : ℕ} {ρ : ℝ}
(hblock : DyadicAmplificationBlock A u v M e ρ) {r : ℕ} (hr : r ∈ dyadicProjection A u) :
(dyadicZoom (dyadicProjection A v) u r).card = 2 ^ e := by
rw [dyadic_zoom_card, hblock.fiber_card r hr]
theorem dyadic_amplification_block_zoom_mass {A : Finset ℕ} {u v M e : ℕ} {ρ : ℝ}
(hblock : DyadicAmplificationBlock A u v M e ρ) {r : ℕ} (hr : r ∈ dyadicProjection A u)
{l : ℕ} (hlM : M ≤ l) (hlv : u + l ≤ v) (s : ℕ) :
natResidueMass (dyadicZoom (dyadicProjection A v) u r) (2 ^ l) s ≤
(2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ)) := by
rw [dyadic_zoom_residue_mass _ (dyadic_projection_bounded A u r hr)]
simpa only [Nat.add_sub_cancel_left] using
hblock.mass_le (u + l) (by omega) hlv r hr (r + 2 ^ u * (s % 2 ^ l))
theorem dyadic_zoom_residue_mass_of_mod (A : Finset ℕ) {d r x : ℕ} (hr : r < 2 ^ d)
(hxr : x % 2 ^ d = r) (l : ℕ) :
natResidueMass (dyadicZoom A d r) (2 ^ l) (x / 2 ^ d) =
natResidueMass (A.filter (fun y => y % 2 ^ d = r)) (2 ^ (d + l)) x := by
have hjoin : r + 2 ^ d * (x / 2 ^ d) = x := by rw [← hxr, Nat.mod_add_div]
have hmod := dyadic_join_mod hr l (x / 2 ^ d)
rw [hjoin] at hmod
rw [dyadic_zoom_residue_mass A hr l (x / 2 ^ d), ← hmod, nat_residue_mass_mod]
theorem dyadic_regular_profile_split_child_mass {A : Finset ℕ} {T N : ℕ} {m c : ℕ → ℕ}
(hblocks : ∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i))
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{a b r x : ℕ} (hab : a < b) (hbN : b ≤ N)
(hx : x ∈ dyadicProjection A (T * (a + 1))) (hxr : x % 2 ^ (m a) = r) :
(2 : ℝ) ^ (-(T : ℝ)) ≤
natResidueMass ((dyadicProjection A (T * b)).filter (fun y => y % 2 ^ (m a) = r))
(2 ^ (m a + 1)) x := by
classical
let F := (dyadicProjection A (T * b)).filter (fun y => y % 2 ^ (m a) = r)
let G := (dyadicProjection A (T * b)).filter (fun y => y % 2 ^ (T * (a + 1)) = x)
have hblock := hblocks a (hab.trans_le hbN)
have hme : m a + 1 ≤ T * (a + 1) := by have := hblock.split_lt; nlinarith
have hm : m a ≤ T * (a + 1) := by omega
have hr : r ∈ dyadicProjection A (m a) := by
rw [← dyadic_projection_trans A hm]
exact Finset.mem_image.mpr ⟨x, hx, hxr⟩
have hF : F.card = 2 ^ (branchPrefix c b - branchPrefix c a) :=
dyadic_regular_profile_split_fiber_card hblocks hprofile hab hbN hr
have hG : G.card = 2 ^ (branchPrefix c b - branchPrefix c (a + 1)) :=
dyadic_regular_profile_fiber_card (fun i hi => ⟨m i, c i, hblocks i hi⟩) hprofile (by omega) hbN hx
have hsub : G ⊆ natResidueFiber F (2 ^ (m a + 1)) x := by
intro y hy
obtain ⟨hyA, hyx⟩ := Finset.mem_filter.mp hy
have hlow : y % 2 ^ (m a) = r := by
calc
_ = (y % 2 ^ (T * (a + 1))) % 2 ^ (m a) := (Nat.mod_mod_of_dvd y (pow_dvd_pow 2 hm)).symm
_ = x % 2 ^ (m a) := by rw [hyx]
_ = r := hxr
refine Finset.mem_filter.mpr ⟨Finset.mem_filter.mpr ⟨hyA, hlow⟩, ?_⟩
change y % 2 ^ (m a + 1) = x % 2 ^ (m a + 1)
calc
_ = (y % 2 ^ (T * (a + 1))) % 2 ^ (m a + 1) := (Nat.mod_mod_of_dvd y (pow_dvd_pow 2 hme)).symm
_ = _ := by rw [hyx]
have hE := branch_prefix_mono c (show a + 1 ≤ b by omega)
have hsucc := branch_prefix_succ c a
have hsplit : branchPrefix c b - branchPrefix c a = c a + (branchPrefix c b - branchPrefix c (a + 1)) := by omega
have hcount : F.card ≤ 2 ^ T * (natResidueFiber F (2 ^ (m a + 1)) x).card := by
rw [hF, hsplit, pow_add, ← hG]
exact Nat.mul_le_mul (Nat.pow_le_pow_right (by decide : 0 < 2) hblock.count_le) (Finset.card_le_card hsub)
have hFR : (0 : ℝ) < F.card := by rw [hF]; positivity
have hTR : (0 : ℝ) < (2 : ℝ) ^ T := pow_pos (by norm_num) T
have hcountR : (F.card : ℝ) ≤ (2 : ℝ) ^ T * ((natResidueFiber F (2 ^ (m a + 1)) x).card : ℝ) := by
exact_mod_cast hcount
change (2 : ℝ) ^ (-(T : ℝ)) ≤ ((natResidueFiber F (2 ^ (m a + 1)) x).card : ℝ) / (F.card : ℝ)
rw [Real.rpow_neg (by norm_num : (0 : ℝ) ≤ 2), Real.rpow_natCast]
apply (le_div_iff₀ hFR).mpr
apply (mul_le_mul_iff_of_pos_left hTR).mp
calc
_ = (F.card : ℝ) := by rw [← mul_assoc, mul_inv_cancel₀ hTR.ne', one_mul]
_ ≤ _ := hcountR
theorem dyadic_regular_profile_zoom_split_mass {A : Finset ℕ} {T N : ℕ} {m c : ℕ → ℕ}
(hblocks : ∀ i : ℕ, i < N →
DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i))
(hprofile : ∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j)
{a b r : ℕ} (hab : a < b) (hbN : b ≤ N) (hca : 0 < c a)
(hr : r ∈ dyadicProjection A (m a)) :
∃ x y : ℕ, x % 2 ≠ y % 2 ∧
(2 : ℝ) ^ (-(T : ℝ)) ≤ natResidueMass (dyadicZoom (dyadicProjection A (T * b)) (m a) r) 2 x ∧
(2 : ℝ) ^ (-(T : ℝ)) ≤ natResidueMass (dyadicZoom (dyadicProjection A (T * b)) (m a) r) 2 y := by
have hblock := hblocks a (hab.trans_le hbN)
have hm : m a ≤ T * (a + 1) := by have := hblock.split_lt; nlinarith
have hr' : r ∈ dyadicProjection (dyadicProjection A (T * (a + 1))) (m a) := by
rwa [dyadic_projection_trans A hm]
obtain ⟨x, hx, y, hy, hxy⟩ := hblock.splits r hr' hca
obtain ⟨hxA, hxr⟩ := Finset.mem_filter.mp hx
obtain ⟨hyA, hyr⟩ := Finset.mem_filter.mp hy
have hrbound := dyadic_projection_bounded A (m a) r hr
have hxjoin : r + 2 ^ (m a) * (x / 2 ^ (m a)) = x := by rw [← hxr, Nat.mod_add_div]
have hyjoin : r + 2 ^ (m a) * (y / 2 ^ (m a)) = y := by rw [← hyr, Nat.mod_add_div]
refine ⟨x / 2 ^ (m a), y / 2 ^ (m a), ?_, ?_, ?_⟩
· intro heq
have hh := (dyadic_join_mod_eq_iff hrbound 1 (x / 2 ^ (m a)) (y / 2 ^ (m a))).mpr
(by simpa only [pow_one] using heq)
rw [hxjoin, hyjoin] at hh
exact hxy hh
· have hmass := dyadic_regular_profile_split_child_mass hblocks hprofile hab hbN hxA hxr
have heq := dyadic_zoom_residue_mass_of_mod (dyadicProjection A (T * b)) hrbound hxr 1
rw [pow_one] at heq
rw [heq]
exact hmass
· have hmass := dyadic_regular_profile_split_child_mass hblocks hprofile hab hbN hyA hyr
have heq := dyadic_zoom_residue_mass_of_mod (dyadicProjection A (T * b)) hrbound hyr 1
rw [pow_one] at heq
rw [heq]
exact hmass
theorem zmod_mul_zero_fiber_card_le {q : ℕ} [NeZero q] (z : ℕ) :
(Finset.univ.filter (fun x : ZMod q => x * (z : ZMod q) = 0)).card ≤ q.gcd z := by
classical
let d := addOrderOf (z : ZMod q)
have hdq : d * q.gcd z = q := by
rw [show d = q / q.gcd z from ZMod.addOrderOf_coe z (NeZero.ne q)]
exact Nat.div_mul_cancel (Nat.gcd_dvd_left q z)
have hd : 0 < d := by
have hq : 0 < q := NeZero.pos q
nlinarith
have hmap : Set.MapsTo (fun x : ZMod q => x.val)
(Finset.univ.filter (fun x : ZMod q => x * (z : ZMod q) = 0))
(natResidueFiber (Finset.range (d * q.gcd z)) d 0) := by
intro x hx
have hxz := (Finset.mem_filter.mp hx).2
have hdiv : d ∣ x.val := by
apply addOrderOf_dvd_iff_nsmul_eq_zero.mpr
simpa only [nsmul_eq_mul, ZMod.natCast_zmod_val] using hxz
refine Finset.mem_filter.mpr ⟨Finset.mem_range.mpr ?_, ?_⟩
· rw [hdq]
exact ZMod.val_lt x
· change x.val % d = 0 % d
simp only [Nat.mod_eq_zero_of_dvd hdiv, Nat.zero_mod]
have hinj : Set.InjOn (fun x : ZMod q => x.val)
(Finset.univ.filter (fun x : ZMod q => x * (z : ZMod q) = 0)) :=
(ZMod.val_injective q).injOn
exact (Finset.card_le_card_of_injOn _ hmap hinj).trans (nat_residue_fiber_range_card_le hd)
theorem zmod_mul_fiber_card_le {q : ℕ} [NeZero q] (z : ℕ) (a : ZMod q) :
(Finset.univ.filter (fun x : ZMod q => x * (z : ZMod q) = a)).card ≤ q.gcd z := by
classical
let F := Finset.univ.filter (fun x : ZMod q => x * (z : ZMod q) = a)
by_cases hF : F.Nonempty
· obtain ⟨x₀, hx₀⟩ := hF
have hx₀a := (Finset.mem_filter.mp hx₀).2
have hmap : Set.MapsTo (fun x : ZMod q => x - x₀) F
(Finset.univ.filter (fun x : ZMod q => x * (z : ZMod q) = 0)) := by
intro x hx
refine Finset.mem_filter.mpr ⟨Finset.mem_univ _, ?_⟩
rw [sub_mul, (Finset.mem_filter.mp hx).2, hx₀a, sub_self]
have hinj : Set.InjOn (fun x : ZMod q => x - x₀) F := by
intro x hx y hy hxy
exact sub_left_injective hxy
exact (Finset.card_le_card_of_injOn _ hmap hinj).trans (zmod_mul_zero_fiber_card_le z)
· change F.card ≤ q.gcd z
simpa only [Finset.not_nonempty_iff_eq_empty.mp hF, Finset.card_empty] using Nat.zero_le (q.gcd z)
theorem finite_pushforward_mul_le {q : ℕ} [NeZero q] (w : ZMod q → ℝ)
{M : ℝ} (hM : 0 ≤ M) (hw : ∀ x, w x ≤ M) (z : ℕ) (a : ZMod q) :
finitePushforward w (fun x => x * (z : ZMod q)) a ≤ (q.gcd z : ℝ) * M := by
classical
calc
_ ≤ ∑ x : ZMod q with x * (z : ZMod q) = a, M :=
Finset.sum_le_sum (fun x _ => hw x)
_ = ((Finset.univ.filter (fun x : ZMod q => x * (z : ZMod q) = a)).card : ℝ) * M := by
rw [Finset.sum_const, nsmul_eq_mul]
_ ≤ _ := mul_le_mul_of_nonneg_right (by exact_mod_cast zmod_mul_fiber_card_le z a) hM
theorem dyadic_gcd_le_divisor_sum {L S n : ℕ} (hn : 0 < n) (hnS : n ≤ 2 ^ S) :
(2 ^ L).gcd n ≤ ∑ v ∈ Finset.range (S + 1), if 2 ^ v ∣ n then 2 ^ v else 0 := by
obtain ⟨a, haL, hga⟩ := (Nat.dvd_prime_pow Nat.prime_two).mp (Nat.gcd_dvd_left (2 ^ L) n)
have hgn : (2 ^ L).gcd n ≤ n := Nat.le_of_dvd hn (Nat.gcd_dvd_right (2 ^ L) n)
have haS : a ≤ S := by
by_contra h
have hh := Nat.pow_le_pow_right (by decide : 0 < 2) (show S + 1 ≤ a by omega)
have hp : 0 < 2 ^ S := by positivity
rw [pow_succ] at hh
rw [hga] at hgn
nlinarith
have hadvd : 2 ^ a ∣ n := by rw [← hga]; exact Nat.gcd_dvd_right _ _
rw [hga]
calc
_ = (if 2 ^ a ∣ n then (2 : ℕ) ^ a else 0) := (if_pos hadvd).symm
_ ≤ _ := Finset.single_le_sum (s := Finset.range (S + 1))
(f := fun v : ℕ => if 2 ^ v ∣ n then (2 : ℕ) ^ v else 0) (a := a)
(fun v _ => Nat.zero_le _)
(Finset.mem_range.mpr (show a < S + 1 by omega))
theorem sum_dyadic_gcd_Ioc_le (L S : ℕ) :
(∑ n ∈ Finset.Ioc 0 (2 ^ S), (2 ^ L).gcd n) ≤ (S + 1) * 2 ^ S := by
classical
calc
_ ≤ ∑ n ∈ Finset.Ioc 0 (2 ^ S), ∑ v ∈ Finset.range (S + 1),
if 2 ^ v ∣ n then 2 ^ v else 0 := by
apply Finset.sum_le_sum
intro n hn
exact dyadic_gcd_le_divisor_sum (Finset.mem_Ioc.mp hn).1 (Finset.mem_Ioc.mp hn).2
_ = ∑ v ∈ Finset.range (S + 1), ∑ n ∈ Finset.Ioc 0 (2 ^ S),
if 2 ^ v ∣ n then 2 ^ v else 0 := Finset.sum_comm
_ = ∑ v ∈ Finset.range (S + 1), 2 ^ S := by
apply Finset.sum_congr rfl
intro v hv
have hvS : v ≤ S := by have := Finset.mem_range.mp hv; omega
rw [← Finset.sum_filter, Finset.sum_const, nsmul_eq_mul, Nat.Ioc_filter_dvd_card_eq_div,
Nat.pow_div hvS (by decide : 0 < 2), Nat.cast_id, ← pow_add, Nat.sub_add_cancel hvS]
_ = _ := by simp
noncomputable def cyclicMultiplierAverage {q : ℕ} [NeZero q]
(w : ZMod q → ℝ) (C : Finset ℕ) (a : ZMod q) : ℝ :=
(∑ c ∈ C, finitePushforward w (fun x => x * (c : ZMod q)) a) / (C.card : ℝ)
theorem cyclic_multiplier_average_nonneg {q : ℕ} [NeZero q]
(w : ZMod q → ℝ) (C : Finset ℕ) (hw : ∀ x, 0 ≤ w x) (a : ZMod q) :
0 ≤ cyclicMultiplierAverage w C a := by
apply div_nonneg _ (Nat.cast_nonneg _)
exact Finset.sum_nonneg (fun c _ => finite_pushforward_nonneg w _ hw a)
theorem cyclic_multiplier_average_sum {q : ℕ} [NeZero q]
(w : ZMod q → ℝ) {C : Finset ℕ} (hC : C.Nonempty) :
∑ a : ZMod q, cyclicMultiplierAverage w C a = ∑ x : ZMod q, w x := by
classical
have hcard : (C.card : ℝ) ≠ 0 := by exact_mod_cast (Finset.card_pos.mpr hC).ne'
simp only [cyclicMultiplierAverage, ← Finset.sum_div]
rw [Finset.sum_comm]
simp only [finite_pushforward_sum, Finset.sum_const, nsmul_eq_mul]
exact mul_div_cancel_left₀ _ hcard
theorem cyclic_multiplier_average_le {q : ℕ} [NeZero q]
(w : ZMod q → ℝ) (C : Finset ℕ) {M : ℝ} (hM : 0 ≤ M) (hw : ∀ x, w x ≤ M)
(a : ZMod q) :
cyclicMultiplierAverage w C a ≤ ((∑ c ∈ C, (q.gcd c : ℝ)) / (C.card : ℝ)) * M := by
calc
_ ≤ (∑ c ∈ C, (q.gcd c : ℝ) * M) / (C.card : ℝ) := by
apply div_le_div_of_nonneg_right _ (Nat.cast_nonneg _)
exact Finset.sum_le_sum (fun c _ => finite_pushforward_mul_le w hM hw c a)
_ = _ := by rw [← Finset.sum_mul]; ring
theorem dyadic_multiplier_average_le (L S : ℕ) (w : ZMod (2 ^ L) → ℝ)
{M : ℝ} (hM : 0 ≤ M) (hw : ∀ x, w x ≤ M) (a : ZMod (2 ^ L)) :
cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S)) a ≤ ((S : ℝ) + 1) * M := by
have hcard : ((Finset.Ioc 0 (2 ^ S)).card : ℝ) = (2 : ℝ) ^ S := by simp
have hsum : (∑ c ∈ Finset.Ioc 0 (2 ^ S), ((2 ^ L).gcd c : ℝ)) ≤
((S : ℝ) + 1) * (2 : ℝ) ^ S := by
exact_mod_cast sum_dyadic_gcd_Ioc_le L S
refine (cyclic_multiplier_average_le w _ hM hw a).trans (mul_le_mul_of_nonneg_right ?_ hM)
rw [hcard]
exact (div_le_iff₀ (by positivity : (0 : ℝ) < (2 : ℝ) ^ S)).mpr hsum
theorem nat_residue_fiber_range_card {q N : ℕ} (hq : 0 < q) (r : ℕ) :
(natResidueFiber (Finset.range (q * N)) q r).card = N := by
have hh := Nat.count_modEq_card (q * N) hq r
rw [Nat.count_eq_card_filter_range] at hh
simpa only [natResidueFiber, Nat.mul_div_right _ hq, Nat.mul_mod_right,
Nat.not_lt_zero, if_false, add_zero] using hh
theorem nat_residue_mass_range_mul {q N : ℕ} (hq : 0 < q) (hN : 0 < N) (r : ℕ) :
natResidueMass (Finset.range (q * N)) q r = 1 / (q : ℝ) := by
have hqR : (q : ℝ) ≠ 0 := by exact_mod_cast hq.ne'
have hNR : (N : ℝ) ≠ 0 := by exact_mod_cast hN.ne'
unfold natResidueMass
rw [nat_residue_fiber_range_card hq, Finset.card_range, Nat.cast_mul]
field_simp
theorem nat_Ioc_eq_translate_range (N : ℕ) :
Finset.Ioc 0 N = natTranslate (Finset.range N) 1 := by
ext x
constructor
· intro hx
obtain ⟨hx0, hxN⟩ := Finset.mem_Ioc.mp hx
exact Finset.mem_image.mpr ⟨x - 1, Finset.mem_range.mpr (by omega), by omega⟩
· intro hx
obtain ⟨n, hn, rfl⟩ := Finset.mem_image.mp hx
have hnN := Finset.mem_range.mp hn
exact Finset.mem_Ioc.mpr ⟨by omega, by omega⟩
theorem nat_residue_mass_Ioc_mul {q N : ℕ} (hq : 0 < q) (hN : 0 < N) (r : ℕ) :
natResidueMass (Finset.Ioc 0 (q * N)) q r = 1 / (q : ℝ) := by
have : NeZero q := ⟨hq.ne'⟩
rw [nat_Ioc_eq_translate_range, nat_translate_residue_mass]
exact nat_residue_mass_range_mul hq hN _
theorem nat_residue_mass_dyadic_Ioc {l S : ℕ} (hlS : l ≤ S) (r : ℕ) :
natResidueMass (Finset.Ioc 0 (2 ^ S)) (2 ^ l) r = 1 / (2 : ℝ) ^ l := by
have hpow : 2 ^ S = 2 ^ l * 2 ^ (S - l) := by rw [← pow_add, Nat.add_sub_of_le hlS]
rw [hpow]
simpa only [Nat.cast_pow, Nat.cast_ofNat] using
nat_residue_mass_Ioc_mul (by positivity : 0 < 2 ^ l) (by positivity : 0 < 2 ^ (S - l)) r
theorem cyclic_multiplier_average_uniform {q : ℕ} [NeZero q]
(w : ZMod q → ℝ) (C : Finset ℕ) (hmass : ∑ x : ZMod q, w x = 1)
(hsupport : ∀ x, w x ≠ 0 → IsUnit x)
(hC : ∀ r : ℕ, natResidueMass C q r = 1 / (q : ℝ)) (a : ZMod q) :
cyclicMultiplierAverage w C a = 1 / (q : ℝ) := by
classical
unfold cyclicMultiplierAverage finitePushforward
simp only [Finset.sum_filter]
rw [Finset.sum_comm, Finset.sum_div]
calc
_ = ∑ x : ZMod q, w x * (1 / (q : ℝ)) := by
apply Finset.sum_congr rfl
intro x hx
by_cases hx0 : w x = 0
· simp only [hx0, ite_self, Finset.sum_const_zero, zero_div, zero_mul]
· obtain ⟨u, rfl⟩ := hsupport x hx0
let b : ZMod q := ↑(u⁻¹) * a
have hpred (c : ℕ) : (u : ZMod q) * (c : ZMod q) = a ↔ Nat.ModEq q c b.val := by
rw [← ZMod.natCast_eq_natCast_iff, ZMod.natCast_zmod_val]
constructor
· intro hc
have hh := congrArg (fun z : ZMod q => ↑(u⁻¹) * z) hc
simpa only [← mul_assoc, Units.inv_mul, one_mul] using hh
· intro hc
rw [hc]
simp only [b, ← mul_assoc, Units.mul_inv, one_mul]
have hsum : (∑ c ∈ C, if (u : ZMod q) * (c : ZMod q) = a then w ↑u else 0) =
((natResidueFiber C q b.val).card : ℝ) * w ↑u := by
simp_rw [hpred]
rw [← Finset.sum_filter, Finset.sum_const, nsmul_eq_mul]
rfl
rw [hsum]
calc
_ = w ↑u * natResidueMass C q b.val := by unfold natResidueMass; ring
_ = _ := by rw [hC]
_ = _ := by rw [← Finset.sum_mul, hmass, one_mul]
theorem dyadic_multiplier_average_uniform {l S : ℕ} (hlS : l ≤ S)
(w : ZMod (2 ^ l) → ℝ) (hmass : ∑ x : ZMod (2 ^ l), w x = 1)
(hsupport : ∀ x, w x ≠ 0 → IsUnit x) (a : ZMod (2 ^ l)) :
cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S)) a = 1 / (2 : ℝ) ^ l := by
simpa only [Nat.cast_pow, Nat.cast_ofNat] using
cyclic_multiplier_average_uniform w (Finset.Ioc 0 (2 ^ S)) hmass hsupport
(fun r => by simpa only [Nat.cast_pow, Nat.cast_ofNat] using nat_residue_mass_dyadic_Ioc hlS r) a
theorem sum_test_finitePushforward {ι κ : Type*} [Fintype ι] [Fintype κ] [DecidableEq κ]
(p : ι → ℝ) (π : ι → κ) (h : κ → ℝ) :
(∑ b : κ, finitePushforward p π b * h b) = ∑ a : ι, p a * h (π a) := by
classical
calc
_ = ∑ b : κ, ∑ a : ι with π a = b, p a * h b := by
simp only [finitePushforward, Finset.sum_mul]
_ = ∑ b : κ, ∑ a : ι with π a = b, p a * h (π a) := by
apply Finset.sum_congr rfl
intro b _
apply Finset.sum_congr rfl
intro a ha
rw [(Finset.mem_filter.mp ha).2]
_ = _ := Finset.sum_fiberwise Finset.univ π _
theorem sum_test_cyclicMultiplierAverage {q : ℕ} [NeZero q]
(w : ZMod q → ℝ) (C : Finset ℕ) (h : ZMod q → ℝ) :
(∑ a : ZMod q, cyclicMultiplierAverage w C a * h a) =
(∑ c ∈ C, ∑ x : ZMod q, w x * h (x * (c : ZMod q))) / (C.card : ℝ) := by
classical
calc
_ = (∑ a : ZMod q, ∑ c ∈ C,
finitePushforward w (fun x => x * (c : ZMod q)) a * h a) / (C.card : ℝ) := by
simp only [cyclicMultiplierAverage, Finset.sum_mul, Finset.sum_div, div_mul_eq_mul_div]
_ = _ := by
rw [Finset.sum_comm]
congr 1
apply Finset.sum_congr rfl
intro c hc
exact sum_test_finitePushforward w _ h
theorem finite_pushforward_cyclicMultiplierAverage {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+* ZMod q) (w : ZMod Q → ℝ) (C : Finset ℕ) :
finitePushforward (cyclicMultiplierAverage w C) π =
cyclicMultiplierAverage (finitePushforward w π) C := by
classical
funext a
unfold finitePushforward cyclicMultiplierAverage
simp only [← Finset.sum_div]
rw [Finset.sum_comm]
congr 1
apply Finset.sum_congr rfl
intro c hc
change finitePushforward (finitePushforward w (fun x => x * (c : ZMod Q))) π a =
finitePushforward (finitePushforward w π) (fun x => x * (c : ZMod q)) a
rw [finite_pushforward_comp, finite_pushforward_comp]
congr 1
funext x
simp only [Function.comp_apply, map_mul, map_natCast]
theorem cyclicUniformNatSet_support_odd {A : Finset ℕ} (hodd : ∀ n ∈ A, Odd n)
(L : ℕ) (x : ZMod (2 ^ L)) (hx : ‖cyclicUniformNatSet A x‖ ≠ 0) : IsUnit x := by
have hx' : cyclicUniformNatSet A x ≠ 0 := by
intro h
exact hx (by rw [h, norm_zero])
obtain ⟨n, hn, hnx⟩ := cyclicUniformNatSet_support A hx'
rw [← hnx]
exact odd_natCast_isUnit_dyadic L (hodd n hn)
theorem dyadic_multiplier_average_decay {g : ℝ} (hg : 0 ≤ g) {S l : ℕ}
(hS : (S : ℝ) + 1 ≤ (2 : ℝ) ^ (g * (S : ℝ))) (hSl : S ≤ l)
(w : ZMod (2 ^ l) → ℝ) (hw : ∀ x, w x ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ)))
(a : ZMod (2 ^ l)) :
cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S)) a ≤ (2 : ℝ) ^ (-g * (l : ℝ)) := by
have hSlR : (S : ℝ) ≤ l := by exact_mod_cast hSl
have hfactor : (S : ℝ) + 1 ≤ (2 : ℝ) ^ (g * (l : ℝ)) := hS.trans
(Real.rpow_le_rpow_of_exponent_le (by norm_num) (mul_le_mul_of_nonneg_left hSlR hg))
calc
_ ≤ ((S : ℝ) + 1) * (2 : ℝ) ^ (-(2 * g) * (l : ℝ)) :=
dyadic_multiplier_average_le l S w (by positivity) hw a
_ ≤ (2 : ℝ) ^ (g * (l : ℝ)) * (2 : ℝ) ^ (-(2 * g) * (l : ℝ)) :=
mul_le_mul_of_nonneg_right hfactor (by positivity)
_ = _ := by rw [← Real.rpow_add (by norm_num)]; congr 1; ring
theorem dyadic_multiplier_fourier_energy_le {S l : ℕ}
(f : ZMod (2 ^ l) → ℂ) (w : ZMod (2 ^ l) → ℝ) {M₁ M₂ : ℝ}
(hmass : ∑ x : ZMod (2 ^ l), ‖f x‖ = 1) (hf : ∀ x, ‖f x‖ ≤ M₁)
(hM₂ : 0 ≤ M₂) (hw : ∀ x, w x ≤ M₂) {k : ZMod (2 ^ l)} (hk : IsUnit k) :
(∑ x : ZMod (2 ^ l), cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S)) x *
‖ZMod.dft f (x * k)‖ ^ 2) ≤ (2 : ℝ) ^ l * M₁ * (((S : ℝ) + 1) * M₂) := by
simpa only [Nat.cast_pow, Nat.cast_ofNat] using weighted_fourier_energy_le f
(cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S))) hmass hf
(dyadic_multiplier_average_le l S w hM₂ hw) (by positivity) hk
theorem dyadic_multiplier_fourier_energy_decay {g ρ : ℝ} (hg : 0 ≤ g) {S l : ℕ}
(hS : (S : ℝ) + 1 ≤ (2 : ℝ) ^ (g * (S : ℝ))) (hSl : S ≤ l)
(f : ZMod (2 ^ l) → ℂ) (w : ZMod (2 ^ l) → ℝ)
(hmass : ∑ x : ZMod (2 ^ l), ‖f x‖ = 1)
(hf : ∀ x, ‖f x‖ ≤ (2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ)))
(hw : ∀ x, w x ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ)))
{k : ZMod (2 ^ l)} (hk : IsUnit k) :
(∑ x : ZMod (2 ^ l), cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S)) x *
‖ZMod.dft f (x * k)‖ ^ 2) ≤ (2 : ℝ) ^ (-(g - 3 * ρ) * (l : ℝ)) := by
have hh := weighted_fourier_energy_le f (cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S)))
hmass hf (dyadic_multiplier_average_decay hg hS hSl w hw) (by positivity) hk
apply hh.trans_eq
rw [Nat.cast_pow, Nat.cast_ofNat, ← Real.rpow_natCast, ← Real.rpow_add (by norm_num),
← Real.rpow_add (by norm_num)]
congr 1; ring
theorem dyadic_multiplier_fourier_energy_gap {κ : Type*} [Fintype κ] [DecidableEq κ]
{l S : ℕ} (hlS : l ≤ S) (f : ZMod (2 ^ l) → ℂ) (w : ZMod (2 ^ l) → ℝ)
(π : ZMod (2 ^ l) → κ) (hfnorm : ∑ x : ZMod (2 ^ l), ‖f x‖ = 1)
(hmass : ∑ x : ZMod (2 ^ l), w x = 1) (hsupport : ∀ x, w x ≠ 0 → IsUnit x)
{a b : κ} (hab : a ≠ b) {β : ℝ}
(ha : β ≤ finitePushforward (fun x => ‖f x‖) π a)
(hb : β ≤ finitePushforward (fun x => ‖f x‖) π b)
{k : ZMod (2 ^ l)} (hk : IsUnit k) :
(∑ x : ZMod (2 ^ l), cyclicMultiplierAverage w (Finset.Ioc 0 (2 ^ S)) x *
‖ZMod.dft f (x * k)‖ ^ 2) ≤ 1 - β := by
simp_rw [dyadic_multiplier_average_uniform hlS w hmass hsupport]
simpa only [Nat.cast_pow, Nat.cast_ofNat] using
uniform_fourier_energy_le_of_projected_atoms f π hfnorm hab ha hb hk
theorem exists_dyadic_multiplier_cutoff {g : ℝ} (hg : 0 < g) (M : ℕ) :
∃ S : ℕ, M ≤ S ∧ 0 < S ∧ (S : ℝ) + 1 ≤ (2 : ℝ) ^ (g * (S : ℝ)) := by
obtain ⟨S₀, hS₀⟩ := Filter.eventually_atTop.mp (eventually_dyadic_regularization_cost_le hg)
let S := max S₀ (max M 1)
have hS : 0 < S := lt_of_lt_of_le (by decide : 0 < 1)
((le_max_right M 1).trans (le_max_right S₀ (max M 1)))
refine ⟨S, (le_max_left M 1).trans (le_max_right S₀ (max M 1)), hS, ?_⟩
have hh := hS₀ S (le_max_left _ _)
have hnonneg : (0 : ℝ) ≤ S := Nat.cast_nonneg _
nlinarith [sq_nonneg (S : ℝ)]
theorem cyclicPushforward_ofReal {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(p : ι → ℝ) (π : ι → ZMod q) (a : ZMod q) :
cyclicPushforward (fun i => (p i : ℂ)) π a = (finitePushforward p π a : ℂ) := by
classical
simp only [cyclicPushforward, finitePushforward, Finset.sum_filter, Complex.ofReal_sum,
apply_ite, Complex.ofReal_zero]
theorem norm_cyclicPushforward_ofReal {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(p : ι → ℝ) (π : ι → ZMod q) (hp : ∀ i, 0 ≤ p i) (a : ZMod q) :
‖cyclicPushforward (fun i => (p i : ℂ)) π a‖ = finitePushforward p π a := by
rw [cyclicPushforward_ofReal]
exact Complex.norm_of_nonneg (finite_pushforward_nonneg p π hp a)
theorem norm_cyclicUniformNatSet_eq_pushforward {q : ℕ} [NeZero q] (A : Finset ℕ) :
(fun x : ZMod q => ‖cyclicUniformNatSet A x‖) =
finitePushforward (fun _ : A => (A.card : ℝ)⁻¹) (fun n => (n.val : ZMod q)) := by
funext x
have hh := norm_cyclicPushforward_ofReal (fun _ : A => (A.card : ℝ)⁻¹)
(fun n : A => (n.val : ZMod q)) (fun _ => by positivity) x
simpa only [cyclicUniformNatSet, Complex.ofReal_inv, Complex.ofReal_natCast] using hh
theorem finite_pushforward_norm_cyclicUniformNatSet {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+* ZMod q) (A : Finset ℕ) :
finitePushforward (fun x : ZMod Q => ‖cyclicUniformNatSet A x‖) π =
(fun x : ZMod q => ‖cyclicUniformNatSet A x‖) := by
rw [norm_cyclicUniformNatSet_eq_pushforward, finite_pushforward_comp,
norm_cyclicUniformNatSet_eq_pushforward]
congr 1
funext n
simp only [Function.comp_apply, map_natCast]
theorem sum_test_norm_cyclicUniformNatSet {q : ℕ} [NeZero q]
(A : Finset ℕ) (h : ZMod q → ℝ) :
(∑ x : ZMod q, ‖cyclicUniformNatSet A x‖ * h x) =
(∑ n ∈ A, h (n : ZMod q)) / (A.card : ℝ) := by
have hp (x : ZMod q) : ‖cyclicUniformNatSet A x‖ =
finitePushforward (fun _ : A => (A.card : ℝ)⁻¹) (fun n => (n.val : ZMod q)) x :=
congrFun (norm_cyclicUniformNatSet_eq_pushforward A) x
simp_rw [hp]
rw [sum_test_finitePushforward]
simp only [← Finset.mul_sum]
rw [Finset.sum_coe_sort A (fun n => h (n : ZMod q))]
ring
theorem dyadic_uniform_parity_mass {A : Finset ℕ} {l : ℕ} (hl : 1 ≤ l) (r : ℕ) :
finitePushforward (fun x : ZMod (2 ^ l) => ‖cyclicUniformNatSet A x‖)
(ZMod.castHom (pow_dvd_pow 2 hl) (ZMod 2)) (r : ZMod 2) = natResidueMass A 2 r := by
rw [finite_pushforward_norm_cyclicUniformNatSet]
dsimp only
rw [norm_cyclicUniformNatSet, ZMod.val_natCast, nat_residue_mass_mod]
theorem dyadic_uniform_multiplier_energy_gap {A B : Finset ℕ} {l S : ℕ}
(hl : 1 ≤ l) (hlS : l ≤ S) (hA : A.Nonempty) (hB : B.Nonempty)
(hBodd : ∀ n ∈ B, Odd n) {a b : ℕ} (hab : a % 2 ≠ b % 2) {β : ℝ}
(ha : β ≤ natResidueMass A 2 a) (hb : β ≤ natResidueMass A 2 b)
{k : ZMod (2 ^ l)} (hk : IsUnit k) :
(∑ x : ZMod (2 ^ l),
cyclicMultiplierAverage (fun y : ZMod (2 ^ l) => ‖cyclicUniformNatSet B y‖)
(Finset.Ioc 0 (2 ^ S)) x * ‖ZMod.dft (cyclicUniformNatSet A) (x * k)‖ ^ 2) ≤ 1 - β := by
apply dyadic_multiplier_fourier_energy_gap hlS (cyclicUniformNatSet A) _
(ZMod.castHom (pow_dvd_pow 2 hl) (ZMod 2))
(sum_norm_cyclicUniformNatSet hA) (sum_norm_cyclicUniformNatSet hB)
(cyclicUniformNatSet_support_odd hBodd l) (a := (a : ZMod 2)) (b := (b : ZMod 2)) ?_ ?_ ?_ hk
· intro heq
have hh := congrArg ZMod.val heq
exact hab (by simpa only [ZMod.val_natCast] using hh)
· rwa [dyadic_uniform_parity_mass hl]
· rwa [dyadic_uniform_parity_mass hl]
noncomputable def natMultiplierEnergy {q : ℕ} [NeZero q]
(A B C : Finset ℕ) (k : ZMod q) : ℝ :=
(∑ c ∈ C, ∑ b ∈ B, ‖ZMod.dft (cyclicUniformNatSet A)
(((b * c : ℕ) : ZMod q) * k)‖ ^ 2) / ((B.card : ℝ) * (C.card : ℝ))
theorem natMultiplierEnergy_eq_weighted {q : ℕ} [NeZero q]
(A B C : Finset ℕ) (k : ZMod q) :
natMultiplierEnergy A B C k =
∑ x : ZMod q, cyclicMultiplierAverage (fun y : ZMod q => ‖cyclicUniformNatSet B y‖) C x *
‖ZMod.dft (cyclicUniformNatSet A) (x * k)‖ ^ 2 := by
rw [sum_test_cyclicMultiplierAverage]
simp_rw [sum_test_norm_cyclicUniformNatSet]
rw [← Finset.sum_div, div_div]
simp only [natMultiplierEnergy, Nat.cast_mul]
theorem natMultiplierEnergy_nonneg {q : ℕ} [NeZero q]
(A B C : Finset ℕ) (k : ZMod q) : 0 ≤ natMultiplierEnergy A B C k := by
unfold natMultiplierEnergy
positivity
theorem natMultiplierEnergy_le_one {q : ℕ} [NeZero q]
{A B C : Finset ℕ} (hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (k : ZMod q) :
natMultiplierEnergy A B C k ≤ 1 := by
rw [natMultiplierEnergy_eq_weighted]
exact weighted_fourier_energy_le_one (cyclicUniformNatSet A) _ (sum_norm_cyclicUniformNatSet hA)
(cyclic_multiplier_average_nonneg _ C (fun _ => norm_nonneg _))
(by rw [cyclic_multiplier_average_sum _ hC, sum_norm_cyclicUniformNatSet hB]) k
theorem natMultiplierEnergy_transfer {Q q : ℕ} [NeZero Q] [NeZero q]
(A B C : Finset ℕ) (x : ZMod Q) (y : ZMod q)
(hphase : ∀ n : ℕ, ZMod.stdAddChar (-((n : ZMod Q) * x)) =
ZMod.stdAddChar (-((n : ZMod q) * y))) :
natMultiplierEnergy A B C x = natMultiplierEnergy A B C y := by
unfold natMultiplierEnergy
congr 1
apply Finset.sum_congr rfl
intro c hc
apply Finset.sum_congr rfl
intro b hb
have hterm : ZMod.dft (cyclicUniformNatSet A) (((b * c : ℕ) : ZMod Q) * x) =
ZMod.dft (cyclicUniformNatSet A) (((b * c : ℕ) : ZMod q) * y) := by
rw [dft_cyclicUniformNatSet, dft_cyclicUniformNatSet]
congr 1
apply Finset.sum_congr rfl
intro n hn
simpa only [Nat.cast_mul, mul_assoc] using hphase (n * (b * c))
rw [hterm]
theorem natMultiplierEnergy_dyadic_short {K S : ℕ} {A B : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hBodd : ∀ n ∈ B, Odd n)
{a b : ℕ} (hab : a % 2 ≠ b % 2) {β : ℝ}
(ha : β ≤ natResidueMass A 2 a) (hb : β ≤ natResidueMass A 2 b)
{k : ZMod (2 ^ K)} (hk : k ≠ 0) (hlevel : dyadicConductorLevel k ≤ S) :
natMultiplierEnergy A B (Finset.Ioc 0 (2 ^ S)) k ≤ 1 - β := by
have hl : 1 ≤ dyadicConductorLevel k := dyadic_conductor_pos hk
have hlK : dyadicConductorLevel k ≤ K := (dyadic_conductor_spec k).1
obtain ⟨m, hm, hfactor⟩ := dyadic_frequency_factor hk
rw [natMultiplierEnergy_transfer A B (Finset.Ioc 0 (2 ^ S)) k
(m : ZMod (2 ^ dyadicConductorLevel k)) (fun n => dyadic_frequency_phase hlK hfactor n),
natMultiplierEnergy_eq_weighted]
exact dyadic_uniform_multiplier_energy_gap hl hlevel hA hB hBodd hab ha hb
(odd_natCast_isUnit_dyadic _ hm)
theorem natMultiplierEnergy_dyadic_long {g ρ : ℝ} (hg : 0 ≤ g) {K S : ℕ}
(hS : (S : ℝ) + 1 ≤ (2 : ℝ) ^ (g * (S : ℝ))) {A B : Finset ℕ} (hA : A.Nonempty)
(hAmass : ∀ l : ℕ, S < l → l ≤ K → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ)))
(hBmass : ∀ l : ℕ, S < l → l ≤ K → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ)))
{k : ZMod (2 ^ K)} (hlevel : S < dyadicConductorLevel k) :
natMultiplierEnergy A B (Finset.Ioc 0 (2 ^ S)) k ≤
(2 : ℝ) ^ (-(g - 3 * ρ) * (dyadicConductorLevel k : ℝ)) := by
have hk : k ≠ 0 := by
intro hk
subst k
simp [dyadicConductorLevel] at hlevel
have hlK : dyadicConductorLevel k ≤ K := (dyadic_conductor_spec k).1
obtain ⟨m, hm, hfactor⟩ := dyadic_frequency_factor hk
rw [natMultiplierEnergy_transfer A B (Finset.Ioc 0 (2 ^ S)) k
(m : ZMod (2 ^ dyadicConductorLevel k)) (fun n => dyadic_frequency_phase hlK hfactor n),
natMultiplierEnergy_eq_weighted]
exact dyadic_multiplier_fourier_energy_decay hg hS hlevel.le (cyclicUniformNatSet A) _
(sum_norm_cyclicUniformNatSet hA) (hAmass _ hlevel hlK) (hBmass _ hlevel hlK)
(odd_natCast_isUnit_dyadic _ hm)
theorem exists_power_for_dyadic_multiplier_energy {g ρ β : ℝ}
(hg : 0 < g) (hρ : 3 * ρ < g) (hβ : 0 < β) (hβ1 : β ≤ 1) (M : ℕ) :
∃ S r : ℕ, M ≤ S ∧ 0 < S ∧ 0 < r ∧
∀ K : ℕ, ∀ A B : Finset ℕ, A.Nonempty → B.Nonempty → (∀ n ∈ B, Odd n) →
(∃ a b : ℕ, a % 2 ≠ b % 2 ∧ β ≤ natResidueMass A 2 a ∧ β ≤ natResidueMass A 2 b) →
(∀ l : ℕ, S < l → l ≤ K → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ))) →
(∀ l : ℕ, S < l → l ≤ K → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
(∑ k : ZMod (2 ^ K), (natMultiplierEnergy A B (Finset.Ioc 0 (2 ^ S)) k) ^ r) < 2 := by
obtain ⟨S, hMS, hSpos, hS⟩ := exists_dyadic_multiplier_cutoff hg M
obtain ⟨r, hr, hpower⟩ := exists_power_for_piecewise_dyadic_energy S
(show 0 ≤ 1 - β by linarith) (show 1 - β < 1 by linarith) (show 0 < g - 3 * ρ by linarith)
refine ⟨S, r, hMS, hSpos, hr, ?_⟩
intro K A B hA hB hBodd hsplit hAmass hBmass
obtain ⟨a, b, hab, ha, hb⟩ := hsplit
have hC : (Finset.Ioc 0 (2 ^ S)).Nonempty := Finset.nonempty_Ioc.mpr (by positivity)
exact hpower K _ (natMultiplierEnergy_nonneg _ _ _)
(natMultiplierEnergy_le_one hA hB hC 0)
(fun k hk hlevel => natMultiplierEnergy_dyadic_short hA hB hBodd hab ha hb hk hlevel)
(fun k hlevel => natMultiplierEnergy_dyadic_long hg.le hS hA hAmass hBmass hlevel)
theorem stdAddChar_dyadic_affine_phase (u L r n z : ℕ) (k : ZMod (2 ^ (u + L))) :
ZMod.stdAddChar (-((((r + 2 ^ u * n) * z : ℕ) : ZMod (2 ^ (u + L))) * k)) =
ZMod.stdAddChar (-(((r * z : ℕ) : ZMod (2 ^ (u + L))) * k)) *
ZMod.stdAddChar (-(((n * z : ℕ) : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L)))) := by
have hs : ZMod.stdAddChar (-((((2 ^ u * n) * z : ℕ) : ZMod (2 ^ (u + L))) * k)) =
ZMod.stdAddChar (-(((n * z : ℕ) : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L)))) := by
have hh := stdAddChar_scaled_modulus (show 2 ^ (u + L) = 2 ^ u * 2 ^ L by rw [pow_add])
(-((n : ℤ) * (z : ℤ) * (k.val : ℤ)))
convert hh using 1
· push_cast
rw [ZMod.natCast_zmod_val]
congr 1
ring
· push_cast
rfl
rw [← hs, ← AddChar.map_add_eq_mul]
congr 1
push_cast
ring
noncomputable def cyclicAffineNatSet {q : ℕ} [NeZero q]
(A : Finset ℕ) (r d z : ℕ) : ZMod q → ℂ :=
cyclicPushforward (fun _ : A => (A.card : ℂ)⁻¹)
(fun n => (((r + d * n.val) * z : ℕ) : ZMod q))
theorem dft_cyclicAffineNatSet (u L : ℕ) (A : Finset ℕ) (r z : ℕ) (k : ZMod (2 ^ (u + L))) :
ZMod.dft (cyclicAffineNatSet A r (2 ^ u) z) k =
ZMod.stdAddChar (-(((r * z : ℕ) : ZMod (2 ^ (u + L))) * k)) *
ZMod.dft (cyclicUniformNatSet A) ((z : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L))) := by
rw [cyclicAffineNatSet, dft_cyclicPushforward, dft_cyclicUniformNatSet]
simp_rw [stdAddChar_dyadic_affine_phase, Nat.cast_mul, mul_assoc]
rw [← Finset.mul_sum, ← Finset.sum_mul]
rw [Finset.sum_coe_sort A (fun n : ℕ => ZMod.stdAddChar
(-((n : ZMod (2 ^ L)) * ((z : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L))))))]
theorem norm_dft_cyclicAffineNatSet (u L : ℕ) (A : Finset ℕ) (r z : ℕ)
(k : ZMod (2 ^ (u + L))) :
‖ZMod.dft (cyclicAffineNatSet A r (2 ^ u) z) k‖ =
‖ZMod.dft (cyclicUniformNatSet A) ((z : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L)))‖ := by
rw [dft_cyclicAffineNatSet, norm_mul]
simp only [ZMod.stdAddChar_apply, Circle.norm_coe, one_mul]
theorem cyclicAffineNatSet_coset_support (u L : ℕ) (A : Finset ℕ) (r z : ℕ)
(x : ZMod (2 ^ (u + L))) (hx : cyclicAffineNatSet A r (2 ^ u) z x ≠ 0) :
ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u)) x =
((r * z : ℕ) : ZMod (2 ^ u)) := by
obtain ⟨n, hn, hnw⟩ := cyclicPushforward_support (fun _ : A => (A.card : ℂ)⁻¹)
(fun n : A => (((r + 2 ^ u * n.val) * z : ℕ) : ZMod (2 ^ (u + L)))) hx
rw [← hn, map_natCast]
have hd : ((2 ^ u : ℕ) : ZMod (2 ^ u)) = 0 := ZMod.natCast_self _
simp only [Nat.cast_mul, Nat.cast_add, hd, zero_mul, add_zero]
noncomputable def cyclicAffineProductLaw {q : ℕ} [NeZero q]
(A B C : Finset ℕ) (r d : ℕ) : ZMod q → ℂ :=
cyclicMixture (fun _ : B × C => ((B.card : ℝ) * (C.card : ℝ))⁻¹)
(fun i => cyclicAffineNatSet A r d (i.1.val * i.2.val))
theorem sum_uniform_pair_weight {B C : Finset ℕ} (hB : B.Nonempty) (hC : C.Nonempty) :
(∑ _ : B × C, ((B.card : ℝ) * (C.card : ℝ))⁻¹) = 1 := by
have hBcard : (B.card : ℝ) ≠ 0 := by exact_mod_cast (Finset.card_pos.mpr hB).ne'
have hCcard : (C.card : ℝ) ≠ 0 := by exact_mod_cast (Finset.card_pos.mpr hC).ne'
simp only [Finset.sum_const, nsmul_eq_mul, Finset.card_univ, Fintype.card_prod,
Fintype.card_coe, Nat.cast_mul]
exact mul_inv_cancel₀ (mul_ne_zero hBcard hCcard)
theorem cyclicAffineProductLaw_energy (u L : ℕ) (A B C : Finset ℕ) (r : ℕ)
(k : ZMod (2 ^ (u + L))) :
(∑ i : B × C, ((B.card : ℝ) * (C.card : ℝ))⁻¹ *
‖ZMod.dft (cyclicAffineNatSet A r (2 ^ u) (i.1.val * i.2.val)) k‖ ^ 2) =
natMultiplierEnergy A B C (k.val : ZMod (2 ^ L)) := by
simp only [norm_dft_cyclicAffineNatSet]
rw [← Finset.mul_sum]
have hsum : (∑ i : B × C,
‖ZMod.dft (cyclicUniformNatSet A)
(((i.1.val * i.2.val : ℕ) : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L)))‖ ^ 2) =
∑ c ∈ C, ∑ b ∈ B, ‖ZMod.dft (cyclicUniformNatSet A)
(((b * c : ℕ) : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L)))‖ ^ 2 := by
rw [Fintype.sum_prod_type, Finset.sum_comm]
rw [Finset.sum_coe_sort C (fun c : ℕ => ∑ b : B, ‖ZMod.dft (cyclicUniformNatSet A)
(((b.val * c : ℕ) : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L)))‖ ^ 2)]
apply Finset.sum_congr rfl
intro c hc
exact Finset.sum_coe_sort B (fun b : ℕ => ‖ZMod.dft (cyclicUniformNatSet A)
(((b * c : ℕ) : ZMod (2 ^ L)) * (k.val : ZMod (2 ^ L)))‖ ^ 2)
rw [hsum]
unfold natMultiplierEnergy
ring
theorem dyadic_affine_product_peak_bound (u L s : ℕ) (A B C : Finset ℕ) (r : ℕ)
(hB : B.Nonempty) (hC : C.Nonempty)
(henergy : (∑ k : ZMod (2 ^ L), (natMultiplierEnergy A B C k) ^ s) < 2) :
∃ M : ZMod (2 ^ u) → ℝ, (∀ a, 0 ≤ M a) ∧
(∀ x : ZMod (2 ^ (u + L)), ‖cyclicConvolutionPow (cyclicAffineProductLaw A B C r (2 ^ u))
(2 * s) x‖ ≤ M ((ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega))
(ZMod (2 ^ u))) x)) ∧
(2 : ℝ) ^ L * (∑ a : ZMod (2 ^ u), M a) < 2 := by
exact dyadic_coset_mixture_peak_bound u L s
(ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u))).toAddMonoidHom
(fun _ : B × C => ((B.card : ℝ) * (C.card : ℝ))⁻¹)
(fun i => cyclicAffineNatSet A r (2 ^ u) (i.1.val * i.2.val))
(fun i => ((r * (i.1.val * i.2.val) : ℕ) : ZMod (2 ^ u)))
(fun _ => by positivity) (sum_uniform_pair_weight hB hC)
(fun i x hx => cyclicAffineNatSet_coset_support u L A r (i.1.val * i.2.val) x hx)
(natMultiplierEnergy A B C) (natMultiplierEnergy_nonneg A B C)
(fun k => (cyclicAffineProductLaw_energy u L A B C r k).le) henergy
theorem exists_dyadic_multiplier_energy_majorant {g ρ β : ℝ}
(hg : 0 < g) (hρ : 3 * ρ < g) (hβ : 0 < β) (hβ1 : β ≤ 1) (M : ℕ) :
∃ S s : ℕ, M ≤ S ∧ 0 < S ∧ 0 < s ∧ ∀ K : ℕ,
∃ E : ZMod (2 ^ K) → ℝ, (∀ k, 0 ≤ E k) ∧ (∑ k : ZMod (2 ^ K), (E k) ^ s) < 2 ∧
∀ A B : Finset ℕ, A.Nonempty → B.Nonempty → (∀ n ∈ B, Odd n) →
(∃ a b : ℕ, a % 2 ≠ b % 2 ∧ β ≤ natResidueMass A 2 a ∧ β ≤ natResidueMass A 2 b) →
(∀ l : ℕ, S < l → l ≤ K → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ))) →
(∀ l : ℕ, S < l → l ≤ K → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
∀ k : ZMod (2 ^ K), natMultiplierEnergy A B (Finset.Ioc 0 (2 ^ S)) k ≤ E k := by
obtain ⟨S, hMS, hSpos, hS⟩ := exists_dyadic_multiplier_cutoff hg M
obtain ⟨s, hs, hpower⟩ := exists_power_for_piecewise_dyadic_energy S
(show 0 ≤ 1 - β by linarith) (show 1 - β < 1 by linarith) (show 0 < g - 3 * ρ by linarith)
refine ⟨S, s, hMS, hSpos, hs, ?_⟩
intro K
let E : ZMod (2 ^ K) → ℝ := fun k => if k = 0 then 1 else
if dyadicConductorLevel k ≤ S then 1 - β else (2 : ℝ) ^ (-(g - 3 * ρ) * (dyadicConductorLevel k : ℝ))
have hE : ∀ k, 0 ≤ E k := by
intro k
dsimp only [E]
split_ifs <;> positivity
have hEzero : E 0 ≤ 1 := by simp only [E, if_pos rfl, le_refl]
have hshort : ∀ k, k ≠ 0 → dyadicConductorLevel k ≤ S → E k ≤ 1 - β := by
intro k hk hlevel
simp only [E, if_neg hk, if_pos hlevel, le_refl]
have hlong : ∀ k, S < dyadicConductorLevel k → E k ≤
(2 : ℝ) ^ (-(g - 3 * ρ) * (dyadicConductorLevel k : ℝ)) := by
intro k hlevel
have hk : k ≠ 0 := by
intro hk
subst k
simp [dyadicConductorLevel] at hlevel
simp only [E, if_neg hk, if_neg (not_le.mpr hlevel), le_refl]
refine ⟨E, hE, hpower K E hE hEzero hshort hlong, ?_⟩
intro A B hA hB hBodd hsplit hAmass hBmass k
obtain ⟨a, b, hab, ha, hb⟩ := hsplit
by_cases hk : k = 0
· subst k
simpa only [E, if_pos rfl] using natMultiplierEnergy_le_one hA hB
(Finset.nonempty_Ioc.mpr (by positivity : 0 < 2 ^ S)) (0 : ZMod (2 ^ K))
· by_cases hlevel : dyadicConductorLevel k ≤ S
· simpa only [E, if_neg hk, if_pos hlevel] using
natMultiplierEnergy_dyadic_short hA hB hBodd hab ha hb hk hlevel
· simpa only [E, if_neg hk, if_neg hlevel] using
natMultiplierEnergy_dyadic_long hg.le hS hA hAmass hBmass (lt_of_not_ge hlevel)
noncomputable def cyclicAffineMixtureProductLaw {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(w : ι → ℝ) (A : ι → Finset ℕ) (B C : Finset ℕ) (r : ι → ℕ) (d : ℕ) : ZMod q → ℂ :=
cyclicMixture (fun i : ι × (B × C) => w i.1 / ((B.card : ℝ) * (C.card : ℝ)))
(fun i => cyclicAffineNatSet (A i.1) (r i.1) d (i.2.1.val * i.2.2.val))
theorem sum_mixture_pair_weight {ι : Type*} [Fintype ι] (w : ι → ℝ)
(hmass : ∑ i : ι, w i = 1) {B C : Finset ℕ} (hB : B.Nonempty) (hC : C.Nonempty) :
(∑ i : ι × (B × C), w i.1 / ((B.card : ℝ) * (C.card : ℝ))) = 1 := by
rw [Fintype.sum_prod_type]
simp only [div_eq_mul_inv, ← Finset.mul_sum, sum_uniform_pair_weight hB hC, mul_one, hmass]
theorem cyclicAffineMixtureProductLaw_energy {ι : Type*} [Fintype ι] (u L : ℕ)
(w : ι → ℝ) (A : ι → Finset ℕ) (B C : Finset ℕ) (r : ι → ℕ) (k : ZMod (2 ^ (u + L))) :
(∑ i : ι × (B × C), (w i.1 / ((B.card : ℝ) * (C.card : ℝ))) *
‖ZMod.dft (cyclicAffineNatSet (A i.1) (r i.1) (2 ^ u) (i.2.1.val * i.2.2.val)) k‖ ^ 2) =
∑ i : ι, w i * natMultiplierEnergy (A i) B C (k.val : ZMod (2 ^ L)) := by
rw [Fintype.sum_prod_type]
apply Finset.sum_congr rfl
intro i hi
rw [← cyclicAffineProductLaw_energy u L (A i) B C (r i) k, Finset.mul_sum]
apply Finset.sum_congr rfl
intro j hj
dsimp only
ring
theorem dyadic_affine_mixture_peak_bound {ι : Type*} [Fintype ι] (u L s : ℕ)
(w : ι → ℝ) (A : ι → Finset ℕ) (B C : Finset ℕ) (r : ι → ℕ)
(hw : ∀ i, 0 ≤ w i) (hmass : ∑ i : ι, w i = 1) (hB : B.Nonempty) (hC : C.Nonempty)
(E : ZMod (2 ^ L) → ℝ) (hE : ∀ k, 0 ≤ E k)
(hmajor : ∀ i k, natMultiplierEnergy (A i) B C k ≤ E k)
(henergy : (∑ k : ZMod (2 ^ L), (E k) ^ s) < 2) :
∃ M : ZMod (2 ^ u) → ℝ, (∀ a, 0 ≤ M a) ∧
(∀ x : ZMod (2 ^ (u + L)),
‖cyclicConvolutionPow (cyclicAffineMixtureProductLaw w A B C r (2 ^ u)) (2 * s) x‖ ≤
M ((ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u))) x)) ∧
(2 : ℝ) ^ L * (∑ a : ZMod (2 ^ u), M a) < 2 := by
apply dyadic_coset_mixture_peak_bound u L s
(ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u))).toAddMonoidHom
(fun i : ι × (B × C) => w i.1 / ((B.card : ℝ) * (C.card : ℝ)))
(fun i => cyclicAffineNatSet (A i.1) (r i.1) (2 ^ u) (i.2.1.val * i.2.2.val))
(fun i => ((r i.1 * (i.2.1.val * i.2.2.val) : ℕ) : ZMod (2 ^ u)))
(fun i => div_nonneg (hw i.1) (by positivity)) (sum_mixture_pair_weight w hmass hB hC)
(fun i x hx => cyclicAffineNatSet_coset_support u L (A i.1) (r i.1)
(i.2.1.val * i.2.2.val) x hx) E hE ?_ henergy
intro k
rw [cyclicAffineMixtureProductLaw_energy]
calc
_ ≤ ∑ i : ι, w i * E (k.val : ZMod (2 ^ L)) :=
Finset.sum_le_sum (fun i _ => mul_le_mul_of_nonneg_left (hmajor i _) (hw i))
_ = _ := by rw [← Finset.sum_mul, hmass, one_mul]
theorem exists_dyadic_affine_mixture_peak {g ρ β : ℝ}
(hg : 0 < g) (hρ : 3 * ρ < g) (hβ : 0 < β) (hβ1 : β ≤ 1) (M₀ : ℕ) :
∃ S s : ℕ, M₀ ≤ S ∧ 0 < S ∧ 0 < s ∧
∀ u L : ℕ, ∀ (ι : Type) [Fintype ι], ∀ (w : ι → ℝ) (A : ι → Finset ℕ)
(r : ι → ℕ) (B : Finset ℕ),
(∀ i, 0 ≤ w i) → (∑ i : ι, w i = 1) → (∀ i, (A i).Nonempty) → B.Nonempty →
(∀ n ∈ B, Odd n) →
(∀ i, ∃ a b : ℕ, a % 2 ≠ b % 2 ∧ β ≤ natResidueMass (A i) 2 a ∧ β ≤ natResidueMass (A i) 2 b) →
(∀ i, ∀ l : ℕ, S < l → l ≤ L → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet (A i) x‖ ≤ (2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ))) →
(∀ l : ℕ, S < l → l ≤ L → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
∃ M : ZMod (2 ^ u) → ℝ, (∀ a, 0 ≤ M a) ∧
(∀ x : ZMod (2 ^ (u + L)),
‖cyclicConvolutionPow
(cyclicAffineMixtureProductLaw w A B (Finset.Ioc 0 (2 ^ S)) r (2 ^ u)) (2 * s) x‖ ≤
M ((ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u))) x)) ∧
(2 : ℝ) ^ L * (∑ a : ZMod (2 ^ u), M a) < 2 := by
obtain ⟨S, s, hMS, hS, hs, hbound⟩ := exists_dyadic_multiplier_energy_majorant hg hρ hβ hβ1 M₀
refine ⟨S, s, hMS, hS, hs, ?_⟩
intro u L ι inst w A r B hw hmass hA hB hBodd hsplit hAmass hBmass
obtain ⟨E, hE, hEsum, hmajor⟩ := hbound L
exact dyadic_affine_mixture_peak_bound u L s w A B (Finset.Ioc 0 (2 ^ S)) r hw hmass hB
(Finset.nonempty_Ioc.mpr (by positivity)) E hE
(fun i k => hmajor (A i) B (hA i) hB hBodd (hsplit i) (hAmass i) hBmass k) hEsum
theorem sum_dyadic_zoom {R : Type*} [AddCommMonoid R] (A : Finset ℕ) (u r : ℕ) (h : ℕ → R) :
(∑ n ∈ dyadicZoom A u r, h (r + 2 ^ u * n)) =
∑ n ∈ A.filter (fun n => n % 2 ^ u = r), h n := by
rw [dyadicZoom, Finset.sum_image]
· apply Finset.sum_congr rfl
intro n hn
rw [← (Finset.mem_filter.mp hn).2, Nat.mod_add_div]
· intro x hx y hy hxy
change x / 2 ^ u = y / 2 ^ u at hxy
have hmod : x % 2 ^ u = y % 2 ^ u :=
(Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm
calc
x = x % 2 ^ u + 2 ^ u * (x / 2 ^ u) := (Nat.mod_add_div x (2 ^ u)).symm
_ = y % 2 ^ u + 2 ^ u * (y / 2 ^ u) := by rw [hmod, hxy]
_ = y := Nat.mod_add_div y (2 ^ u)
theorem sum_dyadic_fibers {R : Type*} [AddCommMonoid R] (A : Finset ℕ) (u : ℕ) (h : ℕ → R) :
(∑ r ∈ dyadicProjection A u, ∑ n ∈ A.filter (fun n => n % 2 ^ u = r), h n) = ∑ n ∈ A, h n := by
have hmaps : ∀ n ∈ A, n % 2 ^ u ∈ dyadicProjection A u :=
fun n hn => Finset.mem_image.mpr ⟨n, hn, rfl⟩
exact Finset.sum_fiberwise_of_maps_to hmaps h
noncomputable def dyadicFiberWeight (A : Finset ℕ) (u r : ℕ) : ℝ :=
((dyadicZoom A u r).card : ℝ) / (A.card : ℝ)
theorem dyadic_fiber_weight_nonneg (A : Finset ℕ) (u r : ℕ) : 0 ≤ dyadicFiberWeight A u r := by
unfold dyadicFiberWeight
positivity
theorem sum_dyadic_fiber_weight {A : Finset ℕ} (hA : A.Nonempty) (u : ℕ) :
(∑ r : dyadicProjection A u, dyadicFiberWeight A u r.val) = 1 := by
have hcard : (A.card : ℝ) ≠ 0 := by exact_mod_cast (Finset.card_pos.mpr hA).ne'
rw [Finset.sum_coe_sort (dyadicProjection A u) (dyadicFiberWeight A u)]
simp only [dyadicFiberWeight, dyadic_zoom_card, ← Finset.sum_div]
have hh := sum_dyadic_fibers A u (fun _ => (1 : ℝ))
simp only [Finset.sum_const, nsmul_eq_mul, mul_one] at hh
rw [hh, div_self hcard]
theorem cyclicAffineNatSet_apply {q : ℕ} [NeZero q] (A : Finset ℕ) (r d z : ℕ) (x : ZMod q) :
cyclicAffineNatSet A r d z x =
(∑ n ∈ A, if ((((r + d * n) * z : ℕ) : ZMod q)) = x then (1 : ℂ) else 0) / (A.card : ℂ) := by
classical
rw [cyclicAffineNatSet, cyclicPushforward]
rw [Finset.sum_coe_sort A (fun n => if ((((r + d * n) * z : ℕ) : ZMod q)) = x then
(A.card : ℂ)⁻¹ else 0)]
rw [div_eq_mul_inv, Finset.sum_mul]
apply Finset.sum_congr rfl
intro n hn
split_ifs <;> simp only [one_mul, zero_mul]
theorem cyclicAffineNatSet_zoom_apply {q : ℕ} [NeZero q]
(A : Finset ℕ) (u r z : ℕ) (x : ZMod q) :
cyclicAffineNatSet (dyadicZoom A u r) r (2 ^ u) z x =
(∑ n ∈ A.filter (fun n => n % 2 ^ u = r),
if ((n * z : ℕ) : ZMod q) = x then (1 : ℂ) else 0) /
((A.filter (fun n => n % 2 ^ u = r)).card : ℂ) := by
rw [cyclicAffineNatSet_apply, dyadic_zoom_card]
congr 1
exact sum_dyadic_zoom A u r (fun n => if ((n * z : ℕ) : ZMod q) = x then (1 : ℂ) else 0)
theorem cyclicAffineNatSet_dyadic_disintegration {q : ℕ} [NeZero q]
{A : Finset ℕ} (hA : A.Nonempty) (u z : ℕ) :
cyclicMixture (fun r : dyadicProjection A u => dyadicFiberWeight A u r.val)
(fun r => cyclicAffineNatSet (dyadicZoom A u r.val) r.val (2 ^ u) z) =
(cyclicAffineNatSet A 0 1 z : ZMod q → ℂ) := by
classical
have hAcard : (A.card : ℂ) ≠ 0 := by exact_mod_cast (Finset.card_pos.mpr hA).ne'
funext x
unfold cyclicMixture
have hterm (r : dyadicProjection A u) :
(dyadicFiberWeight A u r.val : ℂ) *
cyclicAffineNatSet (dyadicZoom A u r.val) r.val (2 ^ u) z x =
(∑ n ∈ A.filter (fun n => n % 2 ^ u = r.val),
if ((n * z : ℕ) : ZMod q) = x then (1 : ℂ) else 0) / (A.card : ℂ) := by
have hcard : ((dyadicZoom A u r.val).card : ℂ) ≠ 0 := by
exact_mod_cast (Finset.card_pos.mpr (dyadic_zoom_nonempty r.property)).ne'
rw [dyadic_zoom_card] at hcard
rw [cyclicAffineNatSet_zoom_apply]
simp only [dyadicFiberWeight, dyadic_zoom_card, Complex.ofReal_div, Complex.ofReal_natCast]
field_simp
simp_rw [hterm]
rw [Finset.sum_coe_sort (dyadicProjection A u) (fun r =>
(∑ n ∈ A.filter (fun n => n % 2 ^ u = r),
if ((n * z : ℕ) : ZMod q) = x then (1 : ℂ) else 0) / (A.card : ℂ))]
rw [← Finset.sum_div, sum_dyadic_fibers, cyclicAffineNatSet_apply]
simp only [one_mul, zero_add]
theorem cyclicAffineProductLaw_dyadic_disintegration {q : ℕ} [NeZero q]
{A : Finset ℕ} (hA : A.Nonempty) (u : ℕ) (B C : Finset ℕ) :
cyclicAffineMixtureProductLaw
(fun r : dyadicProjection A u => dyadicFiberWeight A u r.val)
(fun r => dyadicZoom A u r.val) B C (fun r => r.val) (2 ^ u) =
(cyclicAffineProductLaw A B C 0 1 : ZMod q → ℂ) := by
funext x
unfold cyclicAffineMixtureProductLaw cyclicAffineProductLaw cyclicMixture
rw [Fintype.sum_prod_type, Finset.sum_comm]
apply Finset.sum_congr rfl
intro j hj
dsimp only
have hdis := congrFun (cyclicAffineNatSet_dyadic_disintegration (q := q) hA u
(j.1.val * j.2.val)) x
change (∑ r : dyadicProjection A u, (dyadicFiberWeight A u r.val : ℂ) *
cyclicAffineNatSet (dyadicZoom A u r.val) r.val (2 ^ u) (j.1.val * j.2.val) x) =
cyclicAffineNatSet A 0 1 (j.1.val * j.2.val) x at hdis
rw [← hdis, Finset.mul_sum]
apply Finset.sum_congr rfl
intro r hr
simp only [Complex.ofReal_div, Complex.ofReal_inv]
ring
theorem exists_dyadic_set_product_peak {g ρ β : ℝ}
(hg : 0 < g) (hρ : 3 * ρ < g) (hβ : 0 < β) (hβ1 : β ≤ 1) (M₀ : ℕ) :
∃ S s : ℕ, M₀ ≤ S ∧ 0 < S ∧ 0 < s ∧ ∀ u L : ℕ, ∀ A B : Finset ℕ,
A.Nonempty → B.Nonempty → (∀ n ∈ B, Odd n) →
(∀ r ∈ dyadicProjection A u, ∃ a b : ℕ, a % 2 ≠ b % 2 ∧
β ≤ natResidueMass (dyadicZoom A u r) 2 a ∧ β ≤ natResidueMass (dyadicZoom A u r) 2 b) →
(∀ r ∈ dyadicProjection A u, ∀ l : ℕ, S < l → l ≤ L → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet (dyadicZoom A u r) x‖ ≤ (2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ))) →
(∀ l : ℕ, S < l → l ≤ L → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
∃ M : ZMod (2 ^ u) → ℝ, (∀ a, 0 ≤ M a) ∧
(∀ x : ZMod (2 ^ (u + L)),
‖cyclicConvolutionPow (cyclicAffineProductLaw A B (Finset.Ioc 0 (2 ^ S)) 0 1) (2 * s) x‖ ≤
M ((ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u))) x)) ∧
(2 : ℝ) ^ L * (∑ a : ZMod (2 ^ u), M a) < 2 := by
obtain ⟨S, s, hMS, hS, hs, hpeak⟩ := exists_dyadic_affine_mixture_peak hg hρ hβ hβ1 M₀
refine ⟨S, s, hMS, hS, hs, ?_⟩
intro u L A B hA hB hBodd hsplit hAmass hBmass
obtain ⟨M, hM, hpoint, hsum⟩ := hpeak u L (dyadicProjection A u)
(fun r => dyadicFiberWeight A u r.val) (fun r => dyadicZoom A u r.val) (fun r => r.val) B
(fun r => dyadic_fiber_weight_nonneg A u r.val) (sum_dyadic_fiber_weight hA u)
(fun r => dyadic_zoom_nonempty r.property) hB hBodd
(fun r => hsplit r.val r.property) (fun r => hAmass r.val r.property) hBmass
refine ⟨M, hM, ?_, hsum⟩
rw [cyclicAffineProductLaw_dyadic_disintegration hA u B (Finset.Ioc 0 (2 ^ S))] at hpoint
exact hpoint
structure FiniteComplexProbability {ι : Type*} [Fintype ι] (f : ι → ℂ) : Prop where
norm_cast : ∀ x, f x = (‖f x‖ : ℂ)
sum_eq_one : ∑ x : ι, f x = 1
theorem finite_complex_probability_ofReal {ι : Type*} [Fintype ι] (p : ι → ℝ)
(hp : ∀ x, 0 ≤ p x) (hmass : ∑ x : ι, p x = 1) :
FiniteComplexProbability (fun x => (p x : ℂ)) := by
refine ⟨?_, ?_⟩
· intro x
rw [Complex.norm_of_nonneg (hp x)]
· rw [← Complex.ofReal_sum, hmass, Complex.ofReal_one]
theorem finite_complex_probability_sum_norm {ι : Type*} [Fintype ι] {f : ι → ℂ}
(hf : FiniteComplexProbability f) : ∑ x : ι, ‖f x‖ = 1 := by
have hre (x : ι) : (f x).re = ‖f x‖ := by
simpa only [Complex.ofReal_re] using congrArg Complex.re (hf.norm_cast x)
have hh := congrArg Complex.re hf.sum_eq_one
simpa only [Complex.re_sum, Complex.one_re, hre] using hh
theorem sum_cyclicPushforward {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(p : ι → ℂ) (π : ι → ZMod q) : ∑ x : ZMod q, cyclicPushforward p π x = ∑ i : ι, p i := by
simpa only [one_mul] using sum_test_cyclicPushforward p π (fun _ => 1)
theorem cyclicPushforward_eq_norm_pushforward {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(p : ι → ℂ) (π : ι → ZMod q) (hp : ∀ i, p i = (‖p i‖ : ℂ)) (x : ZMod q) :
cyclicPushforward p π x = (finitePushforward (fun i => ‖p i‖) π x : ℂ) := by
calc
_ = cyclicPushforward (fun i => (‖p i‖ : ℂ)) π x := by
congr 1
exact funext hp
_ = _ := cyclicPushforward_ofReal _ π x
theorem norm_cyclicPushforward_of_probability {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
{p : ι → ℂ} (hp : FiniteComplexProbability p) (π : ι → ZMod q) (x : ZMod q) :
‖cyclicPushforward p π x‖ = finitePushforward (fun i => ‖p i‖) π x := by
rw [cyclicPushforward_eq_norm_pushforward p π hp.norm_cast]
exact Complex.norm_of_nonneg (finite_pushforward_nonneg _ π (fun _ => norm_nonneg _) x)
theorem cyclicPushforward_probability {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
{p : ι → ℂ} (hp : FiniteComplexProbability p) (π : ι → ZMod q) :
FiniteComplexProbability (cyclicPushforward p π) := by
refine ⟨?_, ?_⟩
· intro x
rw [norm_cyclicPushforward_of_probability hp]
exact cyclicPushforward_eq_norm_pushforward p π hp.norm_cast x
· rw [sum_cyclicPushforward, hp.sum_eq_one]
theorem sum_cyclicConvolution {q : ℕ} [NeZero q] (f g : ZMod q → ℂ) :
(∑ x : ZMod q, cyclicConvolution f g x) = (∑ x : ZMod q, f x) * ∑ x : ZMod q, g x := by
simpa only [one_mul, ← Finset.mul_sum, ← Finset.sum_mul] using
sum_test_cyclicConvolution f g (fun _ => 1)
theorem cyclicConvolution_probability {q : ℕ} [NeZero q] {f g : ZMod q → ℂ}
(hf : FiniteComplexProbability f) (hg : FiniteComplexProbability g) :
FiniteComplexProbability (cyclicConvolution f g) := by
refine ⟨?_, ?_⟩
· intro x
have hrep : cyclicConvolution f g x =
((∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ : ℝ) : ℂ) := by
unfold cyclicConvolution
rw [Complex.ofReal_sum]
apply Finset.sum_congr rfl
intro y hy
calc
_ = (‖f y‖ : ℂ) * (‖g (x - y)‖ : ℂ) :=
congrArg₂ (fun a b : ℂ => a * b) (hf.norm_cast y) (hg.norm_cast (x - y))
_ = _ := (Complex.ofReal_mul _ _).symm
have hnonneg : 0 ≤ ∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ :=
Finset.sum_nonneg (fun y _ => mul_nonneg (norm_nonneg _) (norm_nonneg _))
rw [hrep, Complex.norm_of_nonneg hnonneg]
· rw [sum_cyclicConvolution, hf.sum_eq_one, hg.sum_eq_one, mul_one]
theorem cyclicConvolutionPow_probability {q : ℕ} [NeZero q] {f : ZMod q → ℂ}
(hf : FiniteComplexProbability f) (s : ℕ) : FiniteComplexProbability (cyclicConvolutionPow f s) := by
classical
induction s with
| zero =>
refine ⟨?_, ?_⟩
· intro x
by_cases hx : x = 0 <;> simp [cyclicConvolutionPow, hx]
· simp [cyclicConvolutionPow]
| succ s ih => exact cyclicConvolution_probability hf ih
theorem cyclicMixture_probability {ι : Type*} [Fintype ι] {q : ℕ} [NeZero q]
(w : ι → ℝ) (F : ι → ZMod q → ℂ) (hw : ∀ i, 0 ≤ w i) (hmass : ∑ i : ι, w i = 1)
(hF : ∀ i, FiniteComplexProbability (F i)) : FiniteComplexProbability (cyclicMixture w F) := by
refine ⟨?_, ?_⟩
· intro x
have hrep : cyclicMixture w F x = ((∑ i : ι, w i * ‖F i x‖ : ℝ) : ℂ) := by
unfold cyclicMixture
rw [Complex.ofReal_sum]
apply Finset.sum_congr rfl
intro i hi
calc
_ = (w i : ℂ) * (‖F i x‖ : ℂ) := congrArg (fun z : ℂ => (w i : ℂ) * z) ((hF i).norm_cast x)
_ = _ := (Complex.ofReal_mul _ _).symm
have hnonneg : 0 ≤ ∑ i : ι, w i * ‖F i x‖ :=
Finset.sum_nonneg (fun i _ => mul_nonneg (hw i) (norm_nonneg _))
rw [hrep, Complex.norm_of_nonneg hnonneg]
· have hFsum (i : ι) : ∑ x : ZMod q, F i x = 1 := (hF i).sum_eq_one
unfold cyclicMixture
rw [Finset.sum_comm]
simp only [← Finset.mul_sum, hFsum, mul_one, ← Complex.ofReal_sum, hmass, Complex.ofReal_one]
theorem cyclicAffineNatSet_probability {q : ℕ} [NeZero q] {A : Finset ℕ}
(hA : A.Nonempty) (r d z : ℕ) : FiniteComplexProbability (cyclicAffineNatSet (q := q) A r d z) := by
have hcard : (A.card : ℝ) ≠ 0 := by exact_mod_cast (Finset.card_pos.mpr hA).ne'
have hmass : (∑ _ : A, (A.card : ℝ)⁻¹) = 1 := by
simp only [Finset.sum_const, nsmul_eq_mul, Finset.card_univ, Fintype.card_coe]
exact mul_inv_cancel₀ hcard
have hp := finite_complex_probability_ofReal (fun _ : A => (A.card : ℝ)⁻¹)
(fun _ => by positivity) hmass
have hh := cyclicPushforward_probability hp (fun n : A => (((r + d * n.val) * z : ℕ) : ZMod q))
simpa only [cyclicAffineNatSet, Complex.ofReal_inv, Complex.ofReal_natCast] using hh
theorem cyclicAffineProductLaw_probability {q : ℕ} [NeZero q] {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (r d : ℕ) :
FiniteComplexProbability (cyclicAffineProductLaw (q := q) A B C r d) := by
exact cyclicMixture_probability _ _ (fun _ => by positivity) (sum_uniform_pair_weight hB hC)
(fun i => cyclicAffineNatSet_probability hA r d (i.1.val * i.2.val))
theorem cyclicPushforward_comp {ι : Type*} [Fintype ι] {Q q : ℕ} [NeZero Q] [NeZero q]
(w : ι → ℂ) (T : ι → ZMod Q) (π : ZMod Q → ZMod q) :
cyclicPushforward (cyclicPushforward w T) π = cyclicPushforward w (π ∘ T) := by
classical
funext a
simpa only [cyclicPushforward, Function.comp_apply, ite_mul, one_mul, zero_mul] using
sum_test_cyclicPushforward w T (fun x => if π x = a then (1 : ℂ) else 0)
theorem cyclicPushforward_mixture {ι : Type*} [Fintype ι] {Q q : ℕ} [NeZero Q] [NeZero q]
(w : ι → ℝ) (F : ι → ZMod Q → ℂ) (π : ZMod Q → ZMod q) :
cyclicPushforward (cyclicMixture w F) π = cyclicMixture w (fun i => cyclicPushforward (F i) π) := by
classical
funext a
have hterm (x : ZMod Q) : (if π x = a then ∑ i : ι, (w i : ℂ) * F i x else 0) =
∑ i : ι, (w i : ℂ) * (if π x = a then F i x else 0) := by
by_cases hx : π x = a <;> simp [hx]
change (∑ x : ZMod Q, if π x = a then ∑ i : ι, (w i : ℂ) * F i x else 0) =
∑ i : ι, (w i : ℂ) * ∑ x : ZMod Q, if π x = a then F i x else 0
simp_rw [hterm, Finset.mul_sum]
rw [Finset.sum_comm]
theorem cyclicPushforward_convolutionPow {Q q : ℕ} [NeZero Q] [NeZero q]
(f : ZMod Q → ℂ) (π : ZMod Q →+ ZMod q) (s : ℕ) :
cyclicPushforward (cyclicConvolutionPow f s) π = cyclicConvolutionPow (cyclicPushforward f π) s := by
classical
induction s with
| zero =>
funext a
have hterm (x : ZMod Q) : (if π x = a then (if x = 0 then (1 : ℂ) else 0) else 0) =
if x = 0 then (if a = 0 then (1 : ℂ) else 0) else 0 := by
by_cases hx : x = 0
· subst x
simp [eq_comm]
· simp only [if_neg hx, ite_self]
simp only [cyclicConvolutionPow, cyclicPushforward, hterm]
simp
| succ s ih => rw [cyclicConvolutionPow, cyclicPushforward_convolution, ih, cyclicConvolutionPow]
theorem cyclicPushforward_cyclicUniformNatSet {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+* ZMod q) (A : Finset ℕ) :
cyclicPushforward (cyclicUniformNatSet (q := Q) A) π = cyclicUniformNatSet (q := q) A := by
unfold cyclicUniformNatSet
rw [cyclicPushforward_comp]
congr 1
funext n
simp only [Function.comp_apply, map_natCast]
theorem cyclicPushforward_cyclicAffineNatSet {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+* ZMod q) (A : Finset ℕ) (r d z : ℕ) :
cyclicPushforward (cyclicAffineNatSet (q := Q) A r d z) π = cyclicAffineNatSet (q := q) A r d z := by
unfold cyclicAffineNatSet
rw [cyclicPushforward_comp]
congr 1
funext n
simp only [Function.comp_apply, map_natCast]
theorem cyclicPushforward_cyclicAffineProductLaw {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+* ZMod q) (A B C : Finset ℕ) (r d : ℕ) :
cyclicPushforward (cyclicAffineProductLaw (q := Q) A B C r d) π =
cyclicAffineProductLaw (q := q) A B C r d := by
unfold cyclicAffineProductLaw
rw [cyclicPushforward_mixture]
congr 1
funext i
exact cyclicPushforward_cyclicAffineNatSet π A r d (i.1.val * i.2.val)
noncomputable def dyadicProductSumLaw (A B C : Finset ℕ) (s k : ℕ) : ZMod (2 ^ k) → ℂ :=
cyclicConvolutionPow (cyclicAffineProductLaw A B C 0 1) s
noncomputable def dyadicProductSumEntropy (A B C : Finset ℕ) (s k : ℕ) : ℝ :=
finiteEntropy Finset.univ (fun x : ZMod (2 ^ k) => ‖dyadicProductSumLaw A B C s k x‖)
theorem dyadic_product_sum_law_probability {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (s k : ℕ) :
FiniteComplexProbability (dyadicProductSumLaw A B C s k) :=
cyclicConvolutionPow_probability (cyclicAffineProductLaw_probability hA hB hC 0 1) s
theorem dyadic_product_sum_law_project (A B C : Finset ℕ) (s : ℕ) {u v : ℕ} (huv : u ≤ v) :
cyclicPushforward (dyadicProductSumLaw A B C s v)
(ZMod.castHom (pow_dvd_pow 2 huv) (ZMod (2 ^ u))) = dyadicProductSumLaw A B C s u := by
unfold dyadicProductSumLaw
have hh := cyclicPushforward_convolutionPow (cyclicAffineProductLaw A B C 0 1)
(ZMod.castHom (pow_dvd_pow 2 huv) (ZMod (2 ^ u))).toAddMonoidHom s
change cyclicPushforward (cyclicConvolutionPow (cyclicAffineProductLaw A B C 0 1) s)
(ZMod.castHom (pow_dvd_pow 2 huv) (ZMod (2 ^ u))) =
cyclicConvolutionPow (cyclicPushforward (cyclicAffineProductLaw A B C 0 1)
(ZMod.castHom (pow_dvd_pow 2 huv) (ZMod (2 ^ u)))) s at hh
rw [cyclicPushforward_cyclicAffineProductLaw] at hh
exact hh
theorem dyadic_product_sum_mass_project {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (s : ℕ) {u v : ℕ} (huv : u ≤ v) :
finitePushforward (fun x : ZMod (2 ^ v) => ‖dyadicProductSumLaw A B C s v x‖)
(ZMod.castHom (pow_dvd_pow 2 huv) (ZMod (2 ^ u))) =
(fun x : ZMod (2 ^ u) => ‖dyadicProductSumLaw A B C s u x‖) := by
funext x
rw [← norm_cyclicPushforward_of_probability (dyadic_product_sum_law_probability hA hB hC s v),
dyadic_product_sum_law_project A B C s huv]
theorem dyadic_product_sum_entropy_mono {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (s : ℕ) :
Monotone (dyadicProductSumEntropy A B C s) := by
intro u v huv
have hh := finite_entropy_mono_projection (fun x : ZMod (2 ^ v) => ‖dyadicProductSumLaw A B C s v x‖)
(ZMod.castHom (pow_dvd_pow 2 huv) (ZMod (2 ^ u))) (fun _ => norm_nonneg _)
rw [dyadic_product_sum_mass_project hA hB hC s huv] at hh
exact hh
theorem dyadic_product_sum_entropy_zero {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (s : ℕ) :
dyadicProductSumEntropy A B C s 0 = 0 := by
have hz : ∀ x : ZMod (2 ^ 0), x = 0 := by
have : Subsingleton (ZMod (2 ^ 0)) := ZMod.subsingleton_iff.mpr (by norm_num)
exact fun x => Subsingleton.elim x 0
have hmass := finite_complex_probability_sum_norm (dyadic_product_sum_law_probability hA hB hC s 0)
have hvalue : ‖dyadicProductSumLaw A B C s 0 0‖ = 1 := by
have hu : (Finset.univ : Finset (ZMod (2 ^ 0))) = {0} := by
ext x
simp only [Finset.mem_univ, Finset.mem_singleton, hz x]
rw [hu, Finset.sum_singleton] at hmass
exact hmass
unfold dyadicProductSumEntropy finiteEntropy
apply Finset.sum_eq_zero
intro x hx
change Real.negMulLog (‖dyadicProductSumLaw A B C s 0 x‖) = 0
rw [hz x, hvalue]
simp [Real.negMulLog_def]
theorem dyadic_product_sum_entropy_interval_gain {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (s u L : ℕ)
(M : ZMod (2 ^ u) → ℝ) (hM : ∀ a, 0 ≤ M a)
(hbound : ∀ x : ZMod (2 ^ (u + L)), ‖dyadicProductSumLaw A B C s (u + L) x‖ ≤
M ((ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u))) x))
(hpeak : (2 : ℝ) ^ L * (∑ a : ZMod (2 ^ u), M a) ≤ 2) :
dyadicProductSumEntropy A B C s u + (L : ℝ) * Real.log 2 - 1 ≤
dyadicProductSumEntropy A B C s (u + L) := by
have hh := finite_entropy_projection_gain
(fun x : ZMod (2 ^ (u + L)) => ‖dyadicProductSumLaw A B C s (u + L) x‖)
(ZMod.castHom (pow_dvd_pow 2 (show u ≤ u + L by omega)) (ZMod (2 ^ u))) M
(fun _ => norm_nonneg _) (finite_complex_probability_sum_norm
(dyadic_product_sum_law_probability hA hB hC s (u + L)))
(show (0 : ℝ) < (2 : ℝ) ^ L by positivity) hM hbound
(show (2 : ℝ) ^ L * (∑ a : ZMod (2 ^ u), M a) ≤ (1 : ℝ) + 1 by linarith)
rw [dyadic_product_sum_mass_project hA hB hC s (show u ≤ u + L by omega), Real.log_pow] at hh
exact hh
theorem exists_dyadic_set_product_entropy_gain {g ρ β : ℝ}
(hg : 0 < g) (hρ : 3 * ρ < g) (hβ : 0 < β) (hβ1 : β ≤ 1) (M₀ : ℕ) :
∃ S s : ℕ, M₀ ≤ S ∧ 0 < S ∧ 0 < s ∧ ∀ u L : ℕ, ∀ A B : Finset ℕ,
A.Nonempty → B.Nonempty → (∀ n ∈ B, Odd n) →
(∀ r ∈ dyadicProjection A u, ∃ a b : ℕ, a % 2 ≠ b % 2 ∧
β ≤ natResidueMass (dyadicZoom A u r) 2 a ∧ β ≤ natResidueMass (dyadicZoom A u r) 2 b) →
(∀ r ∈ dyadicProjection A u, ∀ l : ℕ, S < l → l ≤ L → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet (dyadicZoom A u r) x‖ ≤ (2 : ℝ) ^ (-(1 - 3 * ρ) * (l : ℝ))) →
(∀ l : ℕ, S < l → l ≤ L → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s) u + (L : ℝ) * Real.log 2 - 1 ≤
dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s) (u + L) := by
obtain ⟨S, s, hMS, hS, hs, hpeak⟩ := exists_dyadic_set_product_peak hg hρ hβ hβ1 M₀
refine ⟨S, s, hMS, hS, hs, ?_⟩
intro u L A B hA hB hBodd hsplit hAmass hBmass
obtain ⟨M, hM, hbound, hsum⟩ := hpeak u L A B hA hB hBodd hsplit hAmass hBmass
exact dyadic_product_sum_entropy_interval_gain hA hB (Finset.nonempty_Ioc.mpr (by positivity))
(2 * s) u L M hM hbound hsum.le
theorem cyclicUniformNatSet_bounded_apply {q : ℕ} [NeZero q] (A : Finset ℕ)
(hA : ∀ n ∈ A, n < q) (x : ZMod q) :
cyclicUniformNatSet A x = if x.val ∈ A then (A.card : ℂ)⁻¹ else 0 := by
classical
unfold cyclicUniformNatSet cyclicPushforward
rw [Finset.sum_coe_sort A (fun n => if (n : ZMod q) = x then (A.card : ℂ)⁻¹ else 0)]
have hsum : (∑ n ∈ A, if (n : ZMod q) = x then (A.card : ℂ)⁻¹ else 0) =
∑ n ∈ A, if n = x.val then (A.card : ℂ)⁻¹ else 0 := by
apply Finset.sum_congr rfl
intro n hn
have heq : (n : ZMod q) = x ↔ n = x.val := by
constructor
· intro h
have hh := congrArg ZMod.val h
simpa only [ZMod.val_natCast, Nat.mod_eq_of_lt (hA n hn)] using hh
· intro h
rw [h, ZMod.natCast_zmod_val]
by_cases h : n = x.val
· simp only [if_pos h, if_pos (heq.mpr h)]
· simp only [if_neg h, if_neg (fun hc => h (heq.mp hc))]
rw [hsum]
simp
theorem cyclicUniformNatSet_regular_projection {A : Finset ℕ} {T N i : ℕ}
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N)) (hi : i ≤ N) :
cyclicUniformNatSet (q := 2 ^ (T * i)) A = cyclicUniformNatSet (dyadicProjection A (T * i)) := by
funext x
rw [cyclicUniformNatSet_bounded_apply _ (dyadic_projection_bounded A (T * i))]
by_cases hx : x.val ∈ dyadicProjection A (T * i)
· rw [if_pos hx, cyclicUniformNatSet_eq_residue_mass, dyadic_regular_tree_residue_mass htree hbound hi hx]
simp only [one_div, Complex.ofReal_inv, Complex.ofReal_natCast]
· rw [if_neg hx]
by_contra hn
obtain ⟨n, hnA, hnx⟩ := cyclicUniformNatSet_support A hn
apply hx
have hh := congrArg ZMod.val hnx
exact Finset.mem_image.mpr ⟨n, hnA, by simpa only [ZMod.val_natCast] using hh⟩
theorem cyclicUniformNatSet_congr_reduction {Q q : ℕ} [NeZero Q] [NeZero q]
(π : ZMod Q →+* ZMod q) {A A' : Finset ℕ}
(hA : cyclicUniformNatSet (q := Q) A = cyclicUniformNatSet A') :
cyclicUniformNatSet (q := q) A = cyclicUniformNatSet A' := by
have hh := congrArg (fun f : ZMod Q → ℂ => cyclicPushforward f π) hA
simpa only [cyclicPushforward_cyclicUniformNatSet] using hh
theorem cyclicUniformNatSet_regular_projection_lower {A : Finset ℕ} {T N i k : ℕ}
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hi : i ≤ N) (hk : k ≤ T * i) :
cyclicUniformNatSet (q := 2 ^ k) A = cyclicUniformNatSet (dyadicProjection A (T * i)) := by
exact cyclicUniformNatSet_congr_reduction (ZMod.castHom (pow_dvd_pow 2 hk) (ZMod (2 ^ k)))
(cyclicUniformNatSet_regular_projection htree hbound hi)
theorem cyclicAffineNatSet_eq_mul_pushforward {q : ℕ} [NeZero q] (A : Finset ℕ) (z : ℕ) :
cyclicAffineNatSet (q := q) A 0 1 z =
cyclicPushforward (cyclicUniformNatSet A) (fun x : ZMod q => x * (z : ZMod q)) := by
unfold cyclicAffineNatSet cyclicUniformNatSet
rw [cyclicPushforward_comp]
congr 1
funext n
simp only [Function.comp_apply, one_mul, zero_add, Nat.cast_mul]
theorem cyclicAffineProductLaw_congr_input {q : ℕ} [NeZero q] {A A' : Finset ℕ}
(hA : cyclicUniformNatSet (q := q) A = cyclicUniformNatSet A') (B C : Finset ℕ) :
cyclicAffineProductLaw (q := q) A B C 0 1 = cyclicAffineProductLaw A' B C 0 1 := by
funext x
unfold cyclicAffineProductLaw cyclicMixture
apply Finset.sum_congr rfl
intro i hi
dsimp only
rw [cyclicAffineNatSet_eq_mul_pushforward, cyclicAffineNatSet_eq_mul_pushforward, hA]
theorem dyadic_product_sum_entropy_congr_input {A A' : Finset ℕ} {k : ℕ}
(hA : cyclicUniformNatSet (q := 2 ^ k) A = cyclicUniformNatSet A') (B C : Finset ℕ) (s : ℕ) :
dyadicProductSumEntropy A B C s k = dyadicProductSumEntropy A' B C s k := by
unfold dyadicProductSumEntropy dyadicProductSumLaw
rw [cyclicAffineProductLaw_congr_input hA B C]
theorem exists_regular_tree_product_entropy_step (T M₀ : ℕ) {g ρ : ℝ}
(hg : 0 < g) (hρ : 3 * ρ < g) :
∃ S s : ℕ, M₀ ≤ S ∧ 0 < S ∧ 0 < s ∧
∀ (N : ℕ) (A B : Finset ℕ) (m c : ℕ → ℕ) (a b e : ℕ),
A.Nonempty → B.Nonempty → (∀ x ∈ A, x < 2 ^ (T * N)) → (∀ n ∈ B, Odd n) →
(∀ i : ℕ, i < N → DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i)) →
(∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j) →
a < b → b ≤ N → 0 < c a → DyadicAmplificationBlock A (m a) (T * b) M₀ e ρ →
(∀ l : ℕ, S < l → l ≤ T * N → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s) (m a) +
((T * b - m a : ℕ) : ℝ) * Real.log 2 - 1 ≤
dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s) (T * b) := by
have hβ : (0 : ℝ) < (2 : ℝ) ^ (-(T : ℝ)) := by positivity
have hβ1 : (2 : ℝ) ^ (-(T : ℝ)) ≤ 1 := by
calc
_ ≤ (2 : ℝ) ^ (0 : ℝ) := Real.rpow_le_rpow_of_exponent_le (by norm_num)
(neg_nonpos.mpr (Nat.cast_nonneg T))
_ = _ := by rw [Real.rpow_zero]
obtain ⟨S, s, hMS, hS, hs, hstep⟩ := exists_dyadic_set_product_entropy_gain hg hρ hβ hβ1 M₀
refine ⟨S, s, hMS, hS, hs, ?_⟩
intro N A B m c a b e hA hB hbound hBodd hblocks hprofile hab hbN hca hblock hBmass
have huv : m a ≤ T * b := hblock.start_lt.le
have hwidth : m a + (T * b - m a) = T * b := Nat.add_sub_of_le huv
have htree : DyadicRegularTree A T N := fun i hi => ⟨m i, c i, hblocks i hi⟩
have hlocal := hstep (m a) (T * b - m a) (dyadicProjection A (T * b)) B (hA.image _) hB hBodd
(fun r hr => dyadic_regular_profile_zoom_split_mass hblocks hprofile hab hbN hca
(by simpa only [dyadic_projection_trans A huv] using hr))
(fun r hr l hl hlL x => by
rw [norm_cyclicUniformNatSet]
exact dyadic_amplification_block_zoom_mass hblock
(by simpa only [dyadic_projection_trans A huv] using hr) (by omega) (by omega) x.val)
(fun l hl hlL => hBmass l hl (by
have hh := Nat.mul_le_mul_left T hbN
omega))
rw [hwidth] at hlocal
have hlow := dyadic_product_sum_entropy_congr_input
(cyclicUniformNatSet_regular_projection_lower htree hbound hbN huv) B (Finset.Ioc 0 (2 ^ S)) (2 * s)
have hhigh := dyadic_product_sum_entropy_congr_input
(cyclicUniformNatSet_regular_projection htree hbound hbN) B (Finset.Ioc 0 (2 ^ S)) (2 * s)
rw [← hlow, ← hhigh] at hlocal
exact hlocal
theorem exists_regular_tree_product_entropy_amplification (T R M₀ : ℕ) (hR : 0 < R) {g ρ : ℝ}
(hg : 0 < g) (hρ : 0 ≤ ρ) (hρg : 3 * ρ < g) :
∃ S s : ℕ, M₀ ≤ S ∧ 0 < S ∧ 0 < s ∧
∀ (N : ℕ) (A B : Finset ℕ) (m c : ℕ → ℕ) (L : List (ℕ × ℕ)) (w : ℕ) (B₀ : ℝ),
A.Nonempty → B.Nonempty → (∀ x ∈ A, x < 2 ^ (T * N)) → (∀ n ∈ B, Odd n) →
(∀ i : ℕ, i < N → DyadicTreeBlock (dyadicProjection A (T * (i + 1))) (T * i) T (m i) (c i)) →
(∀ j : ℕ, j ≤ N → (dyadicProjection A (T * j)).card = 2 ^ branchPrefix c j) →
BranchingIntervalChain c T N R (1 - 2 * ρ) 0 L w →
(∀ p ∈ L, DyadicAmplificationBlock A (m p.1) (T * p.2) M₀
(branchPrefix c p.2 - branchPrefix c p.1) ρ) →
(∀ l : ℕ, S < l → l ≤ T * N → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
B₀ ≤ ((L.map (fun p => branchPrefix c p.2 - branchPrefix c p.1)).sum : ℝ) →
(L.length : ℝ) ≤ ρ / 2 * B₀ * Real.log 2 →
(branchPrefix c w : ℝ) * Real.log 2 + ρ / 2 * B₀ * Real.log 2 ≤
dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s) (T * w) := by
obtain ⟨S, s, hMS, hS, hs, hstep⟩ := exists_regular_tree_product_entropy_step T M₀ hg hρg
refine ⟨S, s, hMS, hS, hs, ?_⟩
intro N A B m c L w B₀ hA hB hbound hBodd hblocks hprofile hchain hselected hBmass hbits hloss
have hC : (Finset.Ioc 0 (2 ^ S)).Nonempty := Finset.nonempty_Ioc.mpr (by positivity)
have hlocal : ∀ p ∈ L,
dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s) (m p.1) +
((T * p.2 - m p.1 : ℕ) : ℝ) * Real.log 2 - 1 ≤
dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s) (T * p.2) := by
intro p hp
have hinterval := (branching_interval_chain_mem hchain p hp).2.2
have hab : p.1 < p.2 := by have := hinterval.width; omega
exact hstep N A B m c p.1 p.2 (branchPrefix c p.2 - branchPrefix c p.1)
hA hB hbound hBodd hblocks hprofile hab hinterval.end_le hinterval.branching (hselected p hp) hBmass
exact branching_interval_chain_entropy_amplification (C := 1)
(dyadicProductSumEntropy A B (Finset.Ioc 0 (2 ^ S)) (2 * s)) hchain hR hρ
(dyadic_product_sum_entropy_mono hA hB hC (2 * s)) (dyadic_product_sum_entropy_zero hA hB hC (2 * s))
(fun i hi => (hblocks i hi).base_le) hselected hlocal hbits (by simpa only [one_mul] using hloss)
theorem nat_residue_mass_subset_le {D A : Finset ℕ} (hDA : D ⊆ A) (hD : D.Nonempty)
{K : ℝ} (hsize : (A.card : ℝ) ≤ K * (D.card : ℝ)) (q r : ℕ) :
natResidueMass D q r ≤ K * natResidueMass A q r := by
have hA : A.Nonempty := hD.mono hDA
have hDc : (0 : ℝ) < D.card := by exact_mod_cast Finset.card_pos.mpr hD
have hAc : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hA
have hsub : natResidueFiber D q r ⊆ natResidueFiber A q r := by
intro n hn
exact Finset.mem_filter.mpr ⟨hDA (Finset.mem_filter.mp hn).1, (Finset.mem_filter.mp hn).2⟩
have hcard : ((natResidueFiber D q r).card : ℝ) ≤ (natResidueFiber A q r).card := by
exact_mod_cast Finset.card_le_card hsub
unfold natResidueMass
rw [← mul_div_assoc]
apply (div_le_div_iff₀ hDc hAc).mpr
calc
_ ≤ ((natResidueFiber A q r).card : ℝ) * (A.card : ℝ) := mul_le_mul_of_nonneg_right hcard hAc.le
_ ≤ ((natResidueFiber A q r).card : ℝ) * (K * (D.card : ℝ)) :=
mul_le_mul_of_nonneg_left hsize (Nat.cast_nonneg _)
_ = _ := by ring
theorem exists_large_odd_translated_subset {A : Finset ℕ} (hA : A.Nonempty) :
∃ D : Finset ℕ, ∃ δ : ℕ, D ⊆ A ∧ D.Nonempty ∧ δ ≤ 1 ∧
A.card ≤ 2 * D.card ∧ ∀ n ∈ D, Odd (n + δ) := by
classical
have hcard := Finset.card_filter_add_card_filter_not (s := A) (fun n : ℕ => Even n)
have hApos := Finset.card_pos.mpr hA
by_cases heven : A.card ≤ 2 * (A.filter (fun n => Even n)).card
· refine ⟨A.filter (fun n => Even n), 1, Finset.filter_subset _ _, ?_, le_rfl, heven, ?_⟩
· exact Finset.card_pos.mp (by omega)
· intro n hn
have hn0 := Nat.mod_eq_zero_of_dvd (Finset.mem_filter.mp hn).2.two_dvd
exact Nat.odd_iff.mpr (by omega)
· refine ⟨A.filter (fun n => ¬Even n), 0, Finset.filter_subset _ _, ?_, by omega, by omega, ?_⟩
· exact Finset.card_pos.mp (by omega)
· intro n hn
simpa only [Nat.add_zero] using Nat.not_even_iff_odd.mp (Finset.mem_filter.mp hn).2
theorem norm_cyclicUniformNatSet_translate_subset_le {q : ℕ} [NeZero q] {D A : Finset ℕ}
(hDA : D ⊆ A) (hD : D.Nonempty) (hsize : A.card ≤ 2 * D.card) (δ : ℕ)
{M : ℝ} (hM : ∀ x : ZMod q, ‖cyclicUniformNatSet A x‖ ≤ M) (x : ZMod q) :
‖cyclicUniformNatSet (natTranslate D δ) x‖ ≤ 2 * M := by
rw [norm_cyclicUniformNatSet, nat_translate_residue_mass]
have hh := nat_residue_mass_subset_le hDA hD
(show (A.card : ℝ) ≤ (2 : ℝ) * (D.card : ℝ) by exact_mod_cast hsize)
q ((x.val : ZMod q) - (δ : ZMod q)).val
rw [← norm_cyclicUniformNatSet A ((x.val : ZMod q) - (δ : ZMod q))] at hh
exact hh.trans (mul_le_mul_of_nonneg_left (hM _) (by norm_num))
theorem two_mul_dyadic_decay_le {a b : ℝ} {l : ℕ}
(hmargin : 1 ≤ (a - b) * (l : ℝ)) :
2 * (2 : ℝ) ^ (-a * (l : ℝ)) ≤ (2 : ℝ) ^ (-b * (l : ℝ)) := by
calc
_ = (2 : ℝ) ^ ((1 : ℝ) + (-a * (l : ℝ))) := by
rw [Real.rpow_add (by norm_num), Real.rpow_one]
_ ≤ _ := Real.rpow_le_rpow_of_exponent_le (by norm_num) (by nlinarith)
theorem odd_translated_subset_dyadic_mass {D A : Finset ℕ} (hDA : D ⊆ A)
(hD : D.Nonempty) (hsize : A.card ≤ 2 * D.card) (δ : ℕ) {a b : ℝ} {l : ℕ}
(hmargin : 1 ≤ (a - b) * (l : ℝ))
(hA : ∀ x : ZMod (2 ^ l), ‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-a * (l : ℝ))) :
∀ x : ZMod (2 ^ l), ‖cyclicUniformNatSet (natTranslate D δ) x‖ ≤ (2 : ℝ) ^ (-b * (l : ℝ)) := by
intro x
exact (norm_cyclicUniformNatSet_translate_subset_le hDA hD hsize δ hA x).trans
(two_mul_dyadic_decay_le hmargin)
def natTripleProductSet (A B C : Finset ℕ) : Finset ℕ :=
((A ×ˢ B) ×ˢ C).image (fun p => p.1.1 * p.1.2 * p.2)
def natProductSumSet (A B C : Finset ℕ) : ℕ → Finset ℕ
| 0 => {0}
| s + 1 => (natTripleProductSet A B C ×ˢ natProductSumSet A B C s).image (fun p => p.1 + p.2)
theorem nat_triple_product_set_nonempty {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) : (natTripleProductSet A B C).Nonempty :=
((hA.product hB).product hC).image _
theorem nat_product_sum_set_nonempty {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (s : ℕ) :
(natProductSumSet A B C s).Nonempty := by
induction s with
| zero => exact Finset.singleton_nonempty 0
| succ s ih => exact ((nat_triple_product_set_nonempty hA hB hC).product ih).image _
theorem cyclicAffineProductLaw_support {q : ℕ} [NeZero q] (A B C : Finset ℕ)
{x : ZMod q} (hx : cyclicAffineProductLaw A B C 0 1 x ≠ 0) :
∃ n ∈ natTripleProductSet A B C, (n : ZMod q) = x := by
classical
obtain ⟨i, hi, hterm⟩ := Finset.exists_ne_zero_of_sum_ne_zero hx
have hF : cyclicAffineNatSet A 0 1 (i.1.val * i.2.val) x ≠ 0 := (mul_ne_zero_iff.mp hterm).2
obtain ⟨n, hnx, hnw⟩ := cyclicPushforward_support (fun _ : A => (A.card : ℂ)⁻¹)
(fun n : A => (((0 + 1 * n.val) * (i.1.val * i.2.val) : ℕ) : ZMod q)) hF
refine ⟨n.val * i.1.val * i.2.val, ?_, ?_⟩
· exact Finset.mem_image.mpr ⟨((n.val, i.1.val), i.2.val),
Finset.mem_product.mpr ⟨Finset.mem_product.mpr ⟨n.property, i.1.property⟩, i.2.property⟩, rfl⟩
· simpa only [one_mul, zero_add, mul_assoc] using hnx
theorem dyadic_product_sum_law_support (A B C : Finset ℕ) (s k : ℕ)
{x : ZMod (2 ^ k)} (hx : dyadicProductSumLaw A B C s k x ≠ 0) :
∃ n ∈ natProductSumSet A B C s, (n : ZMod (2 ^ k)) = x := by
classical
induction s generalizing x with
| zero =>
have hx0 : x = 0 := by
by_contra h
exact hx (by simp [dyadicProductSumLaw, cyclicConvolutionPow, h])
exact ⟨0, Finset.mem_singleton_self _, by simpa only [Nat.cast_zero] using hx0.symm⟩
| succ s ih =>
change (∑ y : ZMod (2 ^ k), cyclicAffineProductLaw A B C 0 1 y *
dyadicProductSumLaw A B C s k (x - y)) ≠ 0 at hx
obtain ⟨y, hy, hterm⟩ := Finset.exists_ne_zero_of_sum_ne_zero hx
obtain ⟨hfy, hgy⟩ := mul_ne_zero_iff.mp hterm
obtain ⟨a, ha, hay⟩ := cyclicAffineProductLaw_support A B C hfy
obtain ⟨b, hb, hbx⟩ := ih hgy
refine ⟨a + b, Finset.mem_image.mpr ⟨(a, b), Finset.mem_product.mpr ⟨ha, hb⟩, rfl⟩, ?_⟩
rw [Nat.cast_add, hay, hbx]
abel
theorem dyadic_product_sum_entropy_le_log_card {A B C : Finset ℕ}
(hA : A.Nonempty) (hB : B.Nonempty) (hC : C.Nonempty) (s k : ℕ) :
dyadicProductSumEntropy A B C s k ≤
Real.log ((dyadicProjection (natProductSumSet A B C s) k).card : ℝ) := by
classical
let S : Finset (ZMod (2 ^ k)) := (natProductSumSet A B C s).image (fun n : ℕ => (n : ZMod (2 ^ k)))
have hzero : ∀ x : ZMod (2 ^ k), x ∉ S → ‖dyadicProductSumLaw A B C s k x‖ = 0 := by
intro x hx
apply norm_eq_zero.mpr
by_contra hn
obtain ⟨n, hnS, hnx⟩ := dyadic_product_sum_law_support A B C s k hn
exact hx (Finset.mem_image.mpr ⟨n, hnS, hnx⟩)
have hh := finite_entropy_le_log_support (fun x : ZMod (2 ^ k) => ‖dyadicProductSumLaw A B C s k x‖)
S (fun _ => norm_nonneg _) (finite_complex_probability_sum_norm
(dyadic_product_sum_law_probability hA hB hC s k)) hzero
have himage : S.image ZMod.val = dyadicProjection (natProductSumSet A B C s) k := by
simp only [S, Finset.image_image, Function.comp_def, ZMod.val_natCast, dyadicProjection]
have hcard : S.card = (dyadicProjection (natProductSumSet A B C s) k).card := by
rw [← himage, Finset.card_image_of_injective _ (ZMod.val_injective _)]
rw [hcard] at hh
exact hh
theorem exists_regular_tree_product_growth (T R : ℕ) {γ δ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hρ : 0 < ρ) (hρδ : ρ ≤ δ / 4) (hρR : 1 ≤ ρ * (R : ℝ))
(hg : 0 < g) (hρg : 3 * ρ < g)
(hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ)) :
∃ S s : ℕ, 2 * (T * R) ≤ S ∧ 0 < S ∧ 0 < s ∧ ∀ (N : ℕ) (A B : Finset ℕ),
A.Nonempty → B.Nonempty → (∀ n ∈ B, Odd n) →
DyadicRegularTree A T N → (∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
2 * (R : ℝ) ≤ γ * (N : ℝ) →
(∀ l : ℕ, S < l → l ≤ T * N → ∀ x : ZMod (2 ^ l),
‖cyclicUniformNatSet B x‖ ≤ (2 : ℝ) ^ (-(2 * g) * (l : ℝ))) →
∃ w : ℕ, w ≤ N ∧
Real.log ((dyadicProjection A (T * w)).card : ℝ) +
ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ)) * Real.log 2 ≤
Real.log ((dyadicProjection (natProductSumSet A B (Finset.Ioc 0 (2 ^ S)) (2 * s)) (T * w)).card : ℝ) := by
obtain ⟨S, s, hMS, hS, hs, hamp⟩ := exists_regular_tree_product_entropy_amplification
T R (2 * (T * R)) hR hg hρ.le hρg
refine ⟨S, s, hMS, hS, hs, ?_⟩
intro N A B hA hB hBodd htree hbound hprefix hsize hRN hBmass
obtain ⟨m, c, L, w, hblocks, hprofile, hwN, hchain, hlength, hbits, hselected⟩ :=
exists_dyadic_amplification_intervals hA hT hR hγ hδ hδ1 hρ hρδ hρR htree hbound hprefix hsize hRN
have hlengthR : (L.length : ℝ) * (R : ℝ) ≤ N := by exact_mod_cast hlength
have hcoef : 0 ≤ ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2 := by
have hlog : 0 < Real.log 2 := Real.log_pos (by norm_num)
positivity
have hloss : (L.length : ℝ) ≤ ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ)) * Real.log 2 := by
calc
_ = (L.length : ℝ) * 1 := (mul_one _).symm
_ ≤ (L.length : ℝ) * ((ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ)) :=
mul_le_mul_of_nonneg_left hbudget (Nat.cast_nonneg _)
_ = (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * ((L.length : ℝ) * (R : ℝ)) := by ring
_ ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (N : ℝ) :=
mul_le_mul_of_nonneg_left hlengthR hcoef
_ = _ := by ring
have hgain := hamp N A B m c L w (γ * δ / 2 * (T : ℝ) * (N : ℝ))
hA hB hbound hBodd hblocks hprofile hchain hselected hBmass hbits hloss
have hlogP : Real.log ((dyadicProjection A (T * w)).card : ℝ) =
(branchPrefix c w : ℝ) * Real.log 2 := by
rw [hprofile w hwN, Nat.cast_pow, Nat.cast_ofNat, Real.log_pow]
refine ⟨w, hwN, ?_⟩
rw [hlogP]
exact hgain.trans (dyadic_product_sum_entropy_le_log_card hA hB
(Finset.nonempty_Ioc.mpr (by positivity)) (2 * s) (T * w))
theorem odd_translated_subset_regular_mass {T R N S l : ℕ} {γ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hg : 0 < g) (hγg : 8 * g ≤ γ)
(hρg : 3 * ρ < g) (hρR : 1 ≤ ρ * (R : ℝ)) (hS : 2 * (T * R) ≤ S)
{A D : Finset ℕ} (hDA : D ⊆ A) (hD : D.Nonempty) (hsize : A.card ≤ 2 * D.card) (τ : ℕ)
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hprefix : ∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) (hl : S < l) (hlN : l ≤ T * N) :
∀ x : ZMod (2 ^ l), ‖cyclicUniformNatSet (natTranslate D τ) x‖ ≤
(2 : ℝ) ^ (-(2 * g) * (l : ℝ)) := by
have hTR : T ≤ T * R := by simpa only [Nat.mul_one] using Nat.mul_le_mul_left T (show 1 ≤ R by omega)
have hRT : R ≤ T * R := by simpa only [Nat.one_mul] using Nat.mul_le_mul_right R (show 1 ≤ T by omega)
have hmin : 2 * T ≤ l := by omega
have hRl : (R : ℝ) ≤ l := by exact_mod_cast (show R ≤ l by omega)
have hRpos : (0 : ℝ) < R := by exact_mod_cast hR
have hgap : 0 ≤ γ / 2 - 2 * g := by linarith
have hmarginR : 1 ≤ (γ / 2 - 2 * g) * (R : ℝ) := by
have hh := mul_le_mul_of_nonneg_right hγg hRpos.le
have hh' := mul_lt_mul_of_pos_right hρg hRpos
nlinarith
apply odd_translated_subset_dyadic_mass hDA hD hsize τ
(hmarginR.trans (mul_le_mul_of_nonneg_left hRl hgap))
intro x
rw [norm_cyclicUniformNatSet]
exact dyadic_regular_tree_mass_le_at_all_levels hT (by linarith : 0 ≤ γ)
htree hbound hprefix hmin hlN x.val
theorem exists_regular_tree_translated_product_growth (T R : ℕ) {γ δ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hρ : 0 < ρ) (hρδ : ρ ≤ δ / 4) (hρR : 1 ≤ ρ * (R : ℝ))
(hg : 0 < g) (hγg : 8 * g ≤ γ) (hρg : 3 * ρ < g)
(hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ)) :
∃ S s : ℕ, 2 * (T * R) ≤ S ∧ 0 < S ∧ 0 < s ∧ ∀ (N : ℕ) (A : Finset ℕ),
A.Nonempty → DyadicRegularTree A T N → (∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
2 * (R : ℝ) ≤ γ * (N : ℝ) →
∃ D : Finset ℕ, ∃ τ w : ℕ, D ⊆ A ∧ D.Nonempty ∧ τ ≤ 1 ∧ A.card ≤ 2 * D.card ∧ w ≤ N ∧
Real.log ((dyadicProjection A (T * w)).card : ℝ) +
ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ)) * Real.log 2 ≤
Real.log ((dyadicProjection
(natProductSumSet A (natTranslate D τ) (Finset.Ioc 0 (2 ^ S)) (2 * s)) (T * w)).card : ℝ) := by
obtain ⟨S, s, hMS, hS, hs, hgrowth⟩ := exists_regular_tree_product_growth T R
hT hR hγ hδ hδ1 hρ hρδ hρR hg hρg hbudget
refine ⟨S, s, hMS, hS, hs, ?_⟩
intro N A hA htree hbound hprefix hsize hRN
obtain ⟨D, τ, hDA, hD, hτ, hDsize, hDodd⟩ := exists_large_odd_translated_subset hA
have hBodd : ∀ n ∈ natTranslate D τ, Odd n := by
intro n hn
obtain ⟨d, hd, rfl⟩ := Finset.mem_image.mp hn
exact hDodd d hd
obtain ⟨w, hwN, hgain⟩ := hgrowth N A (natTranslate D τ) hA (nat_translate_nonempty hD τ)
hBodd htree hbound hprefix hsize hRN
(fun l hl hlN => odd_translated_subset_regular_mass hT hR hg hγg hρg hρR hMS
hDA hD hDsize τ htree hbound hprefix hl hlN)
exact ⟨D, τ, w, hDA, hD, hτ, hDsize, hwN, hgain⟩
def natBoundedSums (A : Finset ℕ) : ℕ → Finset ℕ
| 0 => {0}
| k + 1 => (insert 0 A ×ˢ natBoundedSums A k).image (fun p => p.1 + p.2)
def natLinearQuadraticSet (A : Finset ℕ) : Finset ℕ := A ∪ (A ×ˢ A).image (fun p => p.1 * p.2)
theorem zero_mem_nat_bounded_sums (A : Finset ℕ) (k : ℕ) : 0 ∈ natBoundedSums A k := by
induction k with
| zero => exact Finset.mem_singleton_self _
| succ k ih =>
exact Finset.mem_image.mpr ⟨(0, 0), Finset.mem_product.mpr ⟨Finset.mem_insert_self _ _, ih⟩, by simp⟩
theorem nat_bounded_sums_mono (A : Finset ℕ) : Monotone (natBoundedSums A) := by
apply monotone_nat_of_le_succ
intro k n hn
exact Finset.mem_image.mpr ⟨(0, n), Finset.mem_product.mpr ⟨Finset.mem_insert_self _ _, hn⟩, by simp⟩
theorem mem_nat_bounded_sums_one {A : Finset ℕ} {n : ℕ} (hn : n ∈ A) : n ∈ natBoundedSums A 1 := by
exact Finset.mem_image.mpr ⟨(n, 0), Finset.mem_product.mpr
⟨Finset.mem_insert_of_mem hn, Finset.mem_singleton_self _⟩, by simp⟩
theorem add_mem_nat_bounded_sums {A : Finset ℕ} {k l a b : ℕ}
(ha : a ∈ natBoundedSums A k) (hb : b ∈ natBoundedSums A l) :
a + b ∈ natBoundedSums A (k + l) := by
induction k generalizing a with
| zero =>
have ha0 : a = 0 := Finset.mem_singleton.mp ha
simpa only [ha0, Nat.zero_add] using hb
| succ k ih =>
obtain ⟨⟨x, y⟩, hxy, rfl⟩ := Finset.mem_image.mp ha
obtain ⟨hx, hy⟩ := Finset.mem_product.mp hxy
have hi := ih hy
have hkl : k + 1 + l = (k + l) + 1 := by omega
rw [hkl]
exact Finset.mem_image.mpr ⟨(x, y + b), Finset.mem_product.mpr ⟨hx, hi⟩, by simp [Nat.add_assoc]⟩
theorem mul_mem_nat_bounded_sums {A : Finset ℕ} {k a : ℕ}
(ha : a ∈ natBoundedSums A k) (c : ℕ) : a * c ∈ natBoundedSums A (k * c) := by
induction c with
| zero => simpa only [Nat.mul_zero] using zero_mem_nat_bounded_sums A 0
| succ c ih =>
simpa only [Nat.mul_succ] using add_mem_nat_bounded_sums ih ha
theorem translated_product_mem_bounded_sums {A D : Finset ℕ} (hDA : D ⊆ A) {τ : ℕ} (hτ : τ ≤ 1)
{a b c M : ℕ} (ha : a ∈ A) (hb : b ∈ natTranslate D τ) (hc : c ≤ M) :
a * b * c ∈ natBoundedSums (natLinearQuadraticSet A) (2 * M) := by
obtain ⟨d, hd, rfl⟩ := Finset.mem_image.mp hb
have had : a * d ∈ natBoundedSums (natLinearQuadraticSet A) 1 :=
mem_nat_bounded_sums_one (Finset.mem_union_right A
(Finset.mem_image.mpr ⟨(a, d), Finset.mem_product.mpr ⟨ha, hDA hd⟩, rfl⟩))
have ha' : a ∈ natBoundedSums (natLinearQuadraticSet A) 1 :=
mem_nat_bounded_sums_one (Finset.mem_union_left _ ha)
have haτ : a * τ ∈ natBoundedSums (natLinearQuadraticSet A) 1 := by
have hh := mul_mem_nat_bounded_sums ha' τ
exact nat_bounded_sums_mono _ (by simpa only [Nat.one_mul] using hτ) hh
have hbase : a * (d + τ) ∈ natBoundedSums (natLinearQuadraticSet A) 2 := by
simpa only [Nat.mul_add] using add_mem_nat_bounded_sums had haτ
exact nat_bounded_sums_mono _ (Nat.mul_le_mul_left 2 hc) (mul_mem_nat_bounded_sums hbase c)
theorem nat_product_sum_set_subset_bounded_sums (A B C E : Finset ℕ) (K : ℕ)
(hproducts : natTripleProductSet A B C ⊆ natBoundedSums E K) (s : ℕ) :
natProductSumSet A B C s ⊆ natBoundedSums E (K * s) := by
induction s with
| zero =>
intro n hn
have hn0 : n = 0 := Finset.mem_singleton.mp hn
simpa only [hn0, Nat.mul_zero] using zero_mem_nat_bounded_sums E 0
| succ s ih =>
intro n hn
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
have hh := add_mem_nat_bounded_sums (hproducts ha) (ih hb)
have hindex : K * (s + 1) = K + K * s := by ring
rw [hindex]
exact hh
theorem translated_product_sum_subset_bounded_sums {A D : Finset ℕ}
(hDA : D ⊆ A) {τ : ℕ} (hτ : τ ≤ 1) (M s : ℕ) :
natProductSumSet A (natTranslate D τ) (Finset.Ioc 0 M) s ⊆
natBoundedSums (natLinearQuadraticSet A) (2 * M * s) := by
apply nat_product_sum_set_subset_bounded_sums
intro n hn
obtain ⟨⟨⟨a, b⟩, c⟩, habc, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨hab, hc⟩ := Finset.mem_product.mp habc
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
exact translated_product_mem_bounded_sums hDA hτ ha hb (Finset.mem_Ioc.mp hc).2
theorem log_gain_implies_dyadic_growth {x y t : ℝ} (hx : 0 < x) (hy : 0 < y)
(hgain : Real.log x + t * Real.log 2 ≤ Real.log y) : (2 : ℝ) ^ t * x ≤ y := by
have hh := Real.exp_le_exp.mpr hgain
rw [Real.exp_add, Real.exp_log hx, Real.exp_log hy] at hh
calc
_ = x * Real.exp (t * Real.log 2) := by
rw [Real.rpow_def_of_pos (by norm_num), mul_comm t (Real.log 2)]
ring
_ ≤ _ := hh
theorem exists_regular_tree_bounded_sum_projected_growth (T R : ℕ) {γ δ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hρ : 0 < ρ) (hρδ : ρ ≤ δ / 4) (hρR : 1 ≤ ρ * (R : ℝ))
(hg : 0 < g) (hγg : 8 * g ≤ γ) (hρg : 3 * ρ < g)
(hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ)) :
∃ K : ℕ, 0 < K ∧ ∀ (N : ℕ) (A : Finset ℕ),
A.Nonempty → DyadicRegularTree A T N → (∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
2 * (R : ℝ) ≤ γ * (N : ℝ) →
∃ w : ℕ, w ≤ N ∧ (2 : ℝ) ^ (ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ))) *
((dyadicProjection A (T * w)).card : ℝ) ≤
((dyadicProjection (natBoundedSums (natLinearQuadraticSet A) K) (T * w)).card : ℝ) := by
obtain ⟨S, s, hMS, hS, hs, hgrowth⟩ := exists_regular_tree_translated_product_growth T R
hT hR hγ hδ hδ1 hρ hρδ hρR hg hγg hρg hbudget
let K := 2 * 2 ^ S * (2 * s)
refine ⟨K, by dsimp [K]; positivity, ?_⟩
intro N A hA htree hbound hprefix hsize hRN
obtain ⟨D, τ, w, hDA, hD, hτ, hDsize, hwN, hgain⟩ :=
hgrowth N A hA htree hbound hprefix hsize hRN
have hsub := translated_product_sum_subset_bounded_sums hDA hτ (2 ^ S) (2 * s)
have hcard : ((dyadicProjection
(natProductSumSet A (natTranslate D τ) (Finset.Ioc 0 (2 ^ S)) (2 * s)) (T * w)).card : ℝ) ≤
((dyadicProjection (natBoundedSums (natLinearQuadraticSet A) K) (T * w)).card : ℝ) := by
exact_mod_cast Finset.card_le_card (Finset.image_subset_image hsub)
have hprod : (0 : ℝ) < (dyadicProjection
(natProductSumSet A (natTranslate D τ) (Finset.Ioc 0 (2 ^ S)) (2 * s)) (T * w)).card := by
exact_mod_cast Finset.card_pos.mpr ((nat_product_sum_set_nonempty hA (nat_translate_nonempty hD τ)
(Finset.nonempty_Ioc.mpr (by positivity)) (2 * s)).image (fun n => n % 2 ^ (T * w)))
have hAP : (0 : ℝ) < (dyadicProjection A (T * w)).card := by
exact_mod_cast Finset.card_pos.mpr (hA.image (fun n => n % 2 ^ (T * w)))
exact ⟨w, hwN, log_gain_implies_dyadic_growth hAP (hprod.trans_le hcard)
(hgain.trans (Real.log_le_log hprod hcard))⟩
theorem regular_tree_bounded_sum_growth_of_projected {A : Finset ℕ} {T N w K : ℕ}
(hA : A.Nonempty) (htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hwN : w ≤ N) (hK : 0 < K) {Λ : ℝ}
(hprojected : Λ * ((dyadicProjection A (T * w)).card : ℝ) ≤
((dyadicProjection (natBoundedSums (natLinearQuadraticSet A) K) (T * w)).card : ℝ)) :
Λ * (A.card : ℝ) ≤ ((dyadicProjection
(natBoundedSums (natLinearQuadraticSet A) (2 * K)) (T * N)).card : ℝ) := by
let G := natBoundedSums (natLinearQuadraticSet A) K
have hAG : A ⊆ G := by
intro a ha
exact nat_bounded_sums_mono _ (show 1 ≤ K by omega)
(mem_nat_bounded_sums_one (Finset.mem_union_left _ ha))
have hraw := dyadic_regular_tree_modular_growth_bound hAG hA htree hbound hwN
have hsub : ((G ×ˢ G).image (fun p => (p.1 + p.2) % 2 ^ (T * N))) ⊆
dyadicProjection (natBoundedSums (natLinearQuadraticSet A) (2 * K)) (T * N) := by
intro n hn
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
refine Finset.mem_image.mpr ⟨a + b, ?_, rfl⟩
simpa only [two_mul] using add_mem_nat_bounded_sums ha hb
have hrawR : ((dyadicProjection G (T * w)).card : ℝ) * (A.card : ℝ) ≤
((dyadicProjection A (T * w)).card : ℝ) *
((dyadicProjection (natBoundedSums (natLinearQuadraticSet A) (2 * K)) (T * N)).card : ℝ) := by
exact_mod_cast hraw.trans (Nat.mul_le_mul_left _ (Finset.card_le_card hsub))
have hP : (0 : ℝ) < (dyadicProjection A (T * w)).card := by
exact_mod_cast Finset.card_pos.mpr (hA.image (fun n => n % 2 ^ (T * w)))
apply (mul_le_mul_iff_of_pos_left hP).mp
calc
_ = (Λ * ((dyadicProjection A (T * w)).card : ℝ)) * (A.card : ℝ) := by ring
_ ≤ ((dyadicProjection G (T * w)).card : ℝ) * (A.card : ℝ) :=
mul_le_mul_of_nonneg_right hprojected (Nat.cast_nonneg _)
_ ≤ _ := hrawR
theorem exists_regular_tree_bounded_sum_growth (T R : ℕ) {γ δ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hρ : 0 < ρ) (hρδ : ρ ≤ δ / 4) (hρR : 1 ≤ ρ * (R : ℝ))
(hg : 0 < g) (hγg : 8 * g ≤ γ) (hρg : 3 * ρ < g)
(hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ)) :
∃ K : ℕ, 0 < K ∧ ∀ (N : ℕ) (A : Finset ℕ),
A.Nonempty → DyadicRegularTree A T N → (∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
2 * (R : ℝ) ≤ γ * (N : ℝ) →
(2 : ℝ) ^ (ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ))) * (A.card : ℝ) ≤
((dyadicProjection (natBoundedSums (natLinearQuadraticSet A) K) (T * N)).card : ℝ) := by
obtain ⟨K, hK, hgrowth⟩ := exists_regular_tree_bounded_sum_projected_growth T R
hT hR hγ hδ hδ1 hρ hρδ hρR hg hγg hρg hbudget
refine ⟨2 * K, by positivity, ?_⟩
intro N A hA htree hbound hprefix hsize hRN
obtain ⟨w, hwN, hprojected⟩ := hgrowth N A hA htree hbound hprefix hsize hRN
exact regular_tree_bounded_sum_growth_of_projected hA htree hbound hwN hK hprojected
theorem exists_uniform_regular_tree_amplification {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ η : ℝ, 0 < η ∧ ∀ T : ℕ, 0 < T → ∃ K N₀ : ℕ, 0 < K ∧
∀ N : ℕ, N₀ ≤ N → ∀ A : Finset ℕ, A.Nonempty → DyadicRegularTree A T N →
(∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
(2 : ℝ) ^ (η * (T : ℝ) * (N : ℝ)) * (A.card : ℝ) ≤
((dyadicProjection (natBoundedSums (natLinearQuadraticSet A) K) (T * N)).card : ℝ) := by
let g := γ / 16
let ρ := min (δ / 8) (γ / 128)
let η := ρ / 2 * (γ * δ / 2)
have hg : 0 < g := by dsimp [g]; positivity
have hρ : 0 < ρ := lt_min (by positivity) (by positivity)
have hρδ8 : ρ ≤ δ / 8 := min_le_left _ _
have hργ128 : ρ ≤ γ / 128 := min_le_right _ _
have hρδ : ρ ≤ δ / 4 := by linarith
have hγg : 8 * g ≤ γ := by dsimp [g]; linarith
have hρg : 3 * ρ < g := by dsimp [g]; linarith
have hη : 0 < η := by dsimp [η]; positivity
refine ⟨η, hη, ?_⟩
intro T hT
have hTr : (0 : ℝ) < T := by exact_mod_cast hT
have hlog : 0 < Real.log 2 := Real.log_pos (by norm_num)
have hcoef : 0 < η * (T : ℝ) * Real.log 2 := by positivity
obtain ⟨R, hRbound⟩ := exists_nat_ge (max (1 : ℝ) (max (1 / ρ) (1 / (η * (T : ℝ) * Real.log 2))))
have hR1 : (1 : ℝ) ≤ R := (le_max_left _ _).trans hRbound
have hR : 0 < R := by
have hh : 1 ≤ R := by exact_mod_cast hR1
omega
have hρrecip : 1 / ρ ≤ (R : ℝ) := (le_max_left _ _).trans ((le_max_right _ _).trans hRbound)
have hcoefrecip : 1 / (η * (T : ℝ) * Real.log 2) ≤ (R : ℝ) :=
(le_max_right _ _).trans ((le_max_right _ _).trans hRbound)
have hρR : 1 ≤ ρ * (R : ℝ) := by
have hh := (div_le_iff₀ hρ).mp hρrecip
nlinarith
have hcoefR : 1 ≤ (η * (T : ℝ) * Real.log 2) * (R : ℝ) := by
have hh := (div_le_iff₀ hcoef).mp hcoefrecip
nlinarith
have hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ) := by
calc
_ ≤ (η * (T : ℝ) * Real.log 2) * (R : ℝ) := hcoefR
_ = _ := by dsimp [η]; ring
obtain ⟨K, hK, hgrowth⟩ := exists_regular_tree_bounded_sum_growth T R
hT hR hγ hδ hδ1 hρ hρδ hρR hg hγg hρg hbudget
obtain ⟨N₀, hN₀⟩ := exists_nat_ge (2 * (R : ℝ) / γ)
refine ⟨K, N₀, hK, ?_⟩
intro N hN A hA htree hbound hprefix hsize
have hRN : 2 * (R : ℝ) ≤ γ * (N : ℝ) := by
have hh := (div_le_iff₀ hγ).mp (hN₀.trans (show (N₀ : ℝ) ≤ N by exact_mod_cast hN))
nlinarith
have hh := hgrowth N A hA htree hbound hprefix hsize hRN
have hexponent : ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ)) = η * (T : ℝ) * (N : ℝ) := by
dsimp [η]
ring
rwa [hexponent] at hh
theorem dyadic_projection_card_le (A : Finset ℕ) (k : ℕ) :
(dyadicProjection A k).card ≤ 2 ^ k := by
calc
_ ≤ (Finset.range (2 ^ k)).card := Finset.card_le_card (by
intro x hx
exact Finset.mem_range.mpr (dyadic_projection_bounded A k x hx))
_ = _ := Finset.card_range _
theorem nat_factor_of_dyadic_residue {n r T v u : ℕ} (hv : v < T)
(hr : r = 2 ^ v * u) (hu : Odd u) (hn : n % 2 ^ T = r) :
∃ b : ℕ, Odd b ∧ n = 2 ^ v * b := by
have hpow : 2 ^ T = 2 ^ v * 2 ^ (T - v) := by
rw [← pow_add, Nat.add_sub_of_le hv.le]
have heven : Even (2 ^ (T - v) * (n / 2 ^ T)) := by
apply even_iff_two_dvd.mpr
exact (pow_dvd_pow 2 (show 1 ≤ T - v by omega)).trans (dvd_mul_right _ _)
refine ⟨u + 2 ^ (T - v) * (n / 2 ^ T), hu.add_even heven, ?_⟩
calc
n = n % 2 ^ T + 2 ^ T * (n / 2 ^ T) := (Nat.mod_add_div _ _).symm
_ = _ := by rw [hn, hr, hpow]; ring
theorem exists_regular_tree_odd_divided_subset {A : Finset ℕ} {T N : ℕ}
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hN : 1 ≤ N) (hsize : 1 < (dyadicProjection A T).card) :
∃ v : ℕ, v < T ∧ ∃ B : Finset ℕ, B.Nonempty ∧ (∀ b ∈ B, Odd b) ∧
(∀ b ∈ B, 2 ^ v * b ∈ A) ∧ A.card ≤ 2 ^ T * B.card := by
obtain ⟨r, hr, hr0⟩ : ∃ r ∈ dyadicProjection A T, r ≠ 0 := by
by_contra h
push Not at h
have hsub : dyadicProjection A T ⊆ {0} := by
intro x hx
exact Finset.mem_singleton.mpr (h x hx)
have hh := Finset.card_le_card hsub
simp only [Finset.card_singleton] at hh
omega
obtain ⟨v, u, hu, hru⟩ := Nat.exists_eq_two_pow_mul_odd hr0
have hv : v < T := by
have hrbound := dyadic_projection_bounded A T r hr
have hu0 : 0 < u := by obtain ⟨t, ht⟩ := hu; omega
have hvr : 2 ^ v ≤ r := by rw [hru]; nlinarith [pow_pos (by decide : 0 < 2) v]
by_contra h
have hp := Nat.pow_le_pow_right (by decide : 0 < 2) (show T ≤ v by omega)
omega
let D := A.filter (fun x => x % 2 ^ T = r)
let B := D.image (fun x => x / 2 ^ v)
have hfactor : ∀ n ∈ D, ∃ b : ℕ, Odd b ∧ n = 2 ^ v * b := by
intro n hn
exact nat_factor_of_dyadic_residue hv hru hu (Finset.mem_filter.mp hn).2
have hD : D.Nonempty := by
obtain ⟨a, ha, har⟩ := Finset.mem_image.mp hr
exact ⟨a, Finset.mem_filter.mpr ⟨ha, har⟩⟩
have hcard : B.card = D.card := by
apply Finset.card_image_of_injOn
intro x hx y hy hxy
obtain ⟨b, hb, rfl⟩ := hfactor x hx
obtain ⟨c, hc, rfl⟩ := hfactor y hy
simp only [Nat.mul_div_right _ (by positivity : 0 < 2 ^ v)] at hxy
rw [hxy]
refine ⟨v, hv, B, hD.image _, ?_, ?_, ?_⟩
· intro b hb
obtain ⟨n, hn, rfl⟩ := Finset.mem_image.mp hb
obtain ⟨c, hc, rfl⟩ := hfactor n hn
simpa only [Nat.mul_div_right _ (by positivity : 0 < 2 ^ v)] using hc
· intro b hb
obtain ⟨n, hn, rfl⟩ := Finset.mem_image.mp hb
obtain ⟨c, hc, hnc⟩ := hfactor n hn
have heq : 2 ^ v * (n / 2 ^ v) = n := by
rw [hnc, Nat.mul_div_right _ (by positivity : 0 < 2 ^ v)]
rw [heq]
exact (Finset.mem_filter.mp hn).1
· obtain ⟨c, hc, hfiber⟩ := dyadic_regular_tree_uniform_fibers htree N le_rfl 1 hN
rw [dyadic_projection_self hbound] at hfiber
simp only [Nat.mul_one] at hfiber
have hDcard : D.card = c := hfiber r hr
have hAcard : A.card = (dyadicProjection A T).card * c := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ T) A]
calc
_ = ∑ _r ∈ dyadicProjection A T, c := Finset.sum_congr rfl hfiber
_ = _ := by simp
rw [hcard, hDcard, hAcard]
exact Nat.mul_le_mul_right _ (dyadic_projection_card_le A T)
theorem nat_residue_mass_scaled_subset_le {A B : Finset ℕ} {d : ℕ} (hd : 0 < d)
(hBA : ∀ b ∈ B, d * b ∈ A) {L : ℝ} (hB : B.Nonempty)
(hsize : (A.card : ℝ) ≤ L * (B.card : ℝ)) (q r : ℕ) :
natResidueMass B q r ≤ L * natResidueMass A q (d * r) := by
have hA : A.Nonempty := by obtain ⟨b, hb⟩ := hB; exact ⟨d * b, hBA b hb⟩
have hmap : Set.MapsTo (fun b : ℕ => d * b) (natResidueFiber B q r)
(natResidueFiber A q (d * r)) := by
intro b hb
obtain ⟨hbB, hbr⟩ := Finset.mem_filter.mp hb
exact Finset.mem_filter.mpr ⟨hBA b hbB, (Nat.ModEq.refl d).mul hbr⟩
have hinj : Function.Injective (fun b : ℕ => d * b) := fun _ _ h => Nat.mul_left_cancel hd h
have hfiber : ((natResidueFiber B q r).card : ℝ) ≤
((natResidueFiber A q (d * r)).card : ℝ) := by
exact_mod_cast Finset.card_le_card_of_injOn _ hmap hinj.injOn
have hAp : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hA
have hBp : (0 : ℝ) < B.card := by exact_mod_cast Finset.card_pos.mpr hB
unfold natResidueMass
rw [← mul_div_assoc, div_le_div_iff₀ hBp hAp]
calc
_ ≤ ((natResidueFiber A q (d * r)).card : ℝ) * (A.card : ℝ) :=
mul_le_mul_of_nonneg_right hfiber hAp.le
_ ≤ ((natResidueFiber A q (d * r)).card : ℝ) * (L * (B.card : ℝ)) :=
mul_le_mul_of_nonneg_left hsize (Nat.cast_nonneg _)
_ = _ := by ring
theorem dyadic_power_times_decay_le {T : ℕ} {a b l : ℝ}
(hmargin : (T : ℝ) ≤ (a - b) * l) :
(2 : ℝ) ^ T * (2 : ℝ) ^ (-a * l) ≤ (2 : ℝ) ^ (-b * l) := by
rw [← Real.rpow_natCast, ← Real.rpow_add (by norm_num)]
exact Real.rpow_le_rpow_of_exponent_le (by norm_num) (by linarith)
theorem odd_divided_subset_regular_mass {T R N S l v : ℕ} {γ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hg : 0 < g) (hγg : 8 * g ≤ γ)
(hρg : 3 * ρ < g) (hρR : 1 ≤ ρ * (R : ℝ)) (hS : 2 * (T * R) ≤ S)
{A B : Finset ℕ} (hB : B.Nonempty) (hBA : ∀ b ∈ B, 2 ^ v * b ∈ A)
(hsize : A.card ≤ 2 ^ T * B.card)
(htree : DyadicRegularTree A T N) (hbound : ∀ x ∈ A, x < 2 ^ (T * N))
(hprefix : ∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) (hl : S < l) (hlN : l ≤ T * N) :
∀ x : ZMod (2 ^ l), ‖cyclicUniformNatSet B x‖ ≤
(2 : ℝ) ^ (-(2 * g) * (l : ℝ)) := by
have hTR : T ≤ T * R := by simpa only [Nat.mul_one] using Nat.mul_le_mul_left T (show 1 ≤ R by omega)
have hmin : 2 * T ≤ l := by omega
have hTl : (T : ℝ) * (R : ℝ) ≤ l := by exact_mod_cast (show T * R ≤ l by omega)
have hRpos : (0 : ℝ) < R := by exact_mod_cast hR
have hTpos : (0 : ℝ) < T := by exact_mod_cast hT
have hgap : 0 ≤ γ / 2 - 2 * g := by linarith
have hmarginR : 1 ≤ (γ / 2 - 2 * g) * (R : ℝ) := by
have hh := mul_le_mul_of_nonneg_right hγg hRpos.le
have hh' := mul_lt_mul_of_pos_right hρg hRpos
nlinarith
have hmargin : (T : ℝ) ≤ (γ / 2 - 2 * g) * (l : ℝ) := by
have hh := mul_le_mul_of_nonneg_left hmarginR hTpos.le
have hh' := mul_le_mul_of_nonneg_left hTl hgap
nlinarith
intro x
rw [norm_cyclicUniformNatSet]
calc
_ ≤ (2 : ℝ) ^ T * natResidueMass A (2 ^ l) (2 ^ v * x.val) :=
nat_residue_mass_scaled_subset_le (by positivity) hBA hB (by exact_mod_cast hsize) _ _
_ ≤ (2 : ℝ) ^ T * (2 : ℝ) ^ (-(γ / 2) * (l : ℝ)) :=
mul_le_mul_of_nonneg_left (dyadic_regular_tree_mass_le_at_all_levels hT (by linarith)
htree hbound hprefix hmin hlN _) (by positivity)
_ ≤ _ := dyadic_power_times_decay_le hmargin
theorem zmod_card_le_gcd_mul_image {q : ℕ} [NeZero q] (S : Finset (ZMod q)) (d : ℕ) :
S.card ≤ q.gcd d * (S.image (fun x => x * (d : ZMod q))).card := by
rw [Finset.card_eq_sum_card_image (fun x : ZMod q => x * (d : ZMod q)) S]
calc
_ ≤ ∑ _y ∈ S.image (fun x => x * (d : ZMod q)), q.gcd d := by
apply Finset.sum_le_sum
intro y hy
exact (Finset.card_le_card (Finset.filter_subset_filter _ (Finset.subset_univ S))).trans
(zmod_mul_fiber_card_le d y)
_ = _ := by simp [Nat.mul_comm]
theorem nat_modular_projection_mul_card (A : Finset ℕ) {q : ℕ} [NeZero q] (d : ℕ) :
(A.image (fun x => x % q)).card ≤
q.gcd d * (A.image (fun x => (d * x) % q)).card := by
let S := A.image (fun x : ℕ => (x : ZMod q))
have hfirst : S.card = (A.image (fun x => x % q)).card := by
rw [← Finset.card_image_of_injective S (ZMod.val_injective q)]
simp only [S, Finset.image_image, Function.comp_def, ZMod.val_natCast]
have hsecond : (S.image (fun x => x * (d : ZMod q))).card =
(A.image (fun x => (d * x) % q)).card := by
rw [← Finset.card_image_of_injective (S.image (fun x => x * (d : ZMod q))) (ZMod.val_injective q)]
simp only [S, Finset.image_image, Function.comp_def]
congr 1
apply Finset.image_congr
intro x hx
dsimp only
rw [mul_comm, ← Nat.cast_mul, ZMod.val_natCast]
have hh := zmod_card_le_gcd_mul_image S d
rwa [hfirst, hsecond] at hh
theorem dyadic_projection_mul_card_le (A : Finset ℕ) (k d D : ℕ)
(hgcd : (2 ^ k).gcd d ≤ D) :
(dyadicProjection A k).card ≤ D * (dyadicProjection (A.image (fun x => d * x)) k).card := by
have hh := nat_modular_projection_mul_card (q := 2 ^ k) A d
have heq : A.image (fun x => d * x % 2 ^ k) = dyadicProjection (A.image (fun x => d * x)) k := by
simp only [dyadicProjection, Finset.image_image, Function.comp_def]
rw [heq] at hh
exact hh.trans (Nat.mul_le_mul_right _ hgcd)
theorem dyadic_gcd_scaled_odd_le {b v T : ℕ} (hb : Odd b) (hv : v ≤ T) (k : ℕ) :
(2 ^ k).gcd (2 ^ v * b) ≤ 2 ^ T := by
have hcop : (2 ^ k).gcd b = 1 := by
have hh := (ZMod.isUnit_iff_coprime b (2 ^ k)).mp (odd_natCast_isUnit_dyadic k hb)
exact hh.symm
rw [Nat.gcd_mul_left_right_of_gcd_eq_one hcop]
exact (Nat.gcd_le_right _ (by positivity : 0 < 2 ^ v)).trans
(Nat.pow_le_pow_right (by decide : 0 < 2) hv)
def natQuadraticSet (A : Finset ℕ) : Finset ℕ := (A ×ˢ A).image (fun p => p.1 * p.2)
theorem scaled_product_sum_mem_quadratic_sums {A B : Finset ℕ} {d : ℕ}
(hBA : ∀ b ∈ B, d * b ∈ A) (M s : ℕ) :
∀ n ∈ natProductSumSet A B (Finset.Ioc 0 M) s,
d * n ∈ natBoundedSums (natQuadraticSet A) (M * s) := by
induction s with
| zero =>
intro n hn
have hn0 : n = 0 := Finset.mem_singleton.mp hn
simpa only [hn0, Nat.mul_zero] using zero_mem_nat_bounded_sums (natQuadraticSet A) 0
| succ s ih =>
intro n hn
obtain ⟨⟨x, y⟩, hxy, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨hx, hy⟩ := Finset.mem_product.mp hxy
obtain ⟨⟨⟨a, b⟩, c⟩, habc, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨hab, hc⟩ := Finset.mem_product.mp habc
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
have hprod : a * (d * b) ∈ natBoundedSums (natQuadraticSet A) 1 :=
mem_nat_bounded_sums_one (Finset.mem_image.mpr ⟨(a, d * b),
Finset.mem_product.mpr ⟨ha, hBA b hb⟩, rfl⟩)
have hterm : d * (a * b * c) ∈ natBoundedSums (natQuadraticSet A) M := by
have hh := nat_bounded_sums_mono (natQuadraticSet A)
(show 1 * c ≤ M by simpa only [Nat.one_mul] using (Finset.mem_Ioc.mp hc).2)
(mul_mem_nat_bounded_sums hprod c)
have heq : d * (a * b * c) = a * (d * b) * c := by ring
rw [heq]
exact hh
have hindex : M * (s + 1) = M + M * s := by ring
rw [hindex, Nat.mul_add]
exact add_mem_nat_bounded_sums hterm (ih y hy)
theorem exists_regular_tree_quadratic_projected_growth (T R : ℕ) {γ δ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hρ : 0 < ρ) (hρδ : ρ ≤ δ / 4) (hρR : 1 ≤ ρ * (R : ℝ))
(hg : 0 < g) (hγg : 8 * g ≤ γ) (hρg : 3 * ρ < g)
(hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ)) :
∃ K : ℕ, 0 < K ∧ ∀ (N : ℕ) (A : Finset ℕ),
A.Nonempty → DyadicRegularTree A T N → (∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
1 ≤ N → 2 * (R : ℝ) ≤ γ * (N : ℝ) →
∃ w a : ℕ, w ≤ N ∧ a ∈ A ∧ (∀ k : ℕ, (2 ^ k).gcd a ≤ 2 ^ T) ∧
(2 : ℝ) ^ (ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ))) *
((dyadicProjection A (T * w)).card : ℝ) ≤
(2 : ℝ) ^ T * ((dyadicProjection (natBoundedSums (natQuadraticSet A) K) (T * w)).card : ℝ) := by
obtain ⟨S, s, hMS, hS, hs, hgrowth⟩ := exists_regular_tree_product_growth T R
hT hR hγ hδ hδ1 hρ hρδ hρR hg hρg hbudget
let K := 2 ^ S * (2 * s)
refine ⟨K, by dsimp [K]; positivity, ?_⟩
intro N A hA htree hbound hprefix hsize hN hRN
have hfirst : 1 < (dyadicProjection A T).card := by
have hh := hprefix 1 hN
simp only [Nat.cast_one, mul_one] at hh
have hp : (1 : ℝ) < (2 : ℝ) ^ (γ * (T : ℝ)) :=
Real.one_lt_rpow (by norm_num) (mul_pos hγ (by exact_mod_cast hT))
exact_mod_cast hp.trans_le hh
obtain ⟨v, hv, B, hB, hBodd, hBA, hAB⟩ :=
exists_regular_tree_odd_divided_subset htree hbound hN hfirst
obtain ⟨w, hwN, hgain⟩ := hgrowth N A B hA hB hBodd htree hbound hprefix hsize hRN
(fun l hl hlN => odd_divided_subset_regular_mass hT hR hg hγg hρg hρR hMS
hB hBA hAB htree hbound hprefix hl hlN)
obtain ⟨b, hb⟩ := hB
have hB : B.Nonempty := ⟨b, hb⟩
refine ⟨w, 2 ^ v * b, hwN, hBA b hb,
fun k => dyadic_gcd_scaled_odd_le (hBodd b hb) hv.le k, ?_⟩
let P := natProductSumSet A B (Finset.Ioc 0 (2 ^ S)) (2 * s)
have hP : (0 : ℝ) < (dyadicProjection P (T * w)).card := by
exact_mod_cast Finset.card_pos.mpr ((nat_product_sum_set_nonempty hA hB
(Finset.nonempty_Ioc.mpr (by positivity)) (2 * s)).image (fun n => n % 2 ^ (T * w)))
have hAP : (0 : ℝ) < (dyadicProjection A (T * w)).card := by
exact_mod_cast Finset.card_pos.mpr (hA.image (fun n => n % 2 ^ (T * w)))
have hscale : (dyadicProjection P (T * w)).card ≤
2 ^ T * (dyadicProjection (natBoundedSums (natQuadraticSet A) K) (T * w)).card := by
have hh := dyadic_projection_mul_card_le P (T * w) (2 ^ v) (2 ^ T)
((Nat.gcd_le_right _ (by positivity : 0 < 2 ^ v)).trans
(Nat.pow_le_pow_right (by decide : 0 < 2) hv.le))
apply hh.trans
apply Nat.mul_le_mul_left
apply Finset.card_le_card
apply Finset.image_subset_image
intro n hn
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hn
exact scaled_product_sum_mem_quadratic_sums hBA (2 ^ S) (2 * s) x hx
exact (log_gain_implies_dyadic_growth hAP hP hgain).trans (by exact_mod_cast hscale)
theorem nat_modular_scaled_fiber_growth (H F : Finset ℕ) {q Q a D : ℕ}
[NeZero Q] (hq : q ∣ Q) (hbound : ∀ x ∈ F, x < Q)
(hcommon : ∀ x ∈ F, ∀ y ∈ F, x % q = y % q) (hgcd : Q.gcd a ≤ D) :
(H.image (fun x => x % q)).card * F.card ≤
D * ((H ×ˢ F).image (fun p => (p.1 + a * p.2) % Q)).card := by
let V := F.image (fun x => a * x % Q)
have hself : F.image (fun x => x % Q) = F := by
calc
_ = F.image id := Finset.image_congr (fun x hx => Nat.mod_eq_of_lt (hbound x hx))
_ = F := Finset.image_id
have hcard : F.card ≤ D * V.card := by
have hh := nat_modular_projection_mul_card (q := Q) F a
rw [hself] at hh
exact hh.trans (Nat.mul_le_mul_right _ hgcd)
have hVbound : ∀ x ∈ V, x < Q := by
intro x hx
obtain ⟨y, hy, rfl⟩ := Finset.mem_image.mp hx
exact Nat.mod_lt _ (NeZero.pos Q)
have hVcommon : ∀ x ∈ V, ∀ y ∈ V, x % q = y % q := by
intro x hx y hy
obtain ⟨s, hs, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨t, ht, rfl⟩ := Finset.mem_image.mp hy
rw [Nat.mod_mod_of_dvd _ hq, Nat.mod_mod_of_dvd _ hq]
exact (Nat.ModEq.refl a).mul (hcommon s hs t ht)
have hsub : ((H ×ˢ V).image (fun p => (p.1 + p.2) % Q)) ⊆
((H ×ˢ F).image (fun p => (p.1 + a * p.2) % Q)) := by
intro z hz
obtain ⟨⟨h, v⟩, hhv, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨hh, hv⟩ := Finset.mem_product.mp hhv
obtain ⟨f, hf, rfl⟩ := Finset.mem_image.mp hv
exact Finset.mem_image.mpr ⟨(h, f), Finset.mem_product.mpr ⟨hh, hf⟩,
by simp only [Nat.add_mod_mod]⟩
calc
_ ≤ (H.image (fun x => x % q)).card * (D * V.card) := Nat.mul_le_mul_left _ hcard
_ = D * ((H.image (fun x => x % q)).card * V.card) := by ring
_ ≤ D * ((H ×ˢ V).image (fun p => (p.1 + p.2) % Q)).card :=
Nat.mul_le_mul_left _ (nat_modular_sumset_card_ge_projection_mul_fiber H V hq hVbound hVcommon)
_ ≤ _ := Nat.mul_le_mul_left _ (Finset.card_le_card hsub)
theorem regular_tree_quadratic_growth_of_projected {A : Finset ℕ} {T N w K a D : ℕ}
(hA : A.Nonempty) (htree : DyadicRegularTree A T N)
(hbound : ∀ x ∈ A, x < 2 ^ (T * N)) (hwN : w ≤ N) (ha : a ∈ A)
(hgcd : (2 ^ (T * N)).gcd a ≤ D) {Λ : ℝ}
(hprojected : Λ * ((dyadicProjection A (T * w)).card : ℝ) ≤
(D : ℝ) * ((dyadicProjection (natBoundedSums (natQuadraticSet A) K) (T * w)).card : ℝ)) :
Λ * (A.card : ℝ) ≤ (D : ℝ) ^ 2 *
((dyadicProjection (natBoundedSums (natQuadraticSet A) (K + 1)) (T * N)).card : ℝ) := by
let H := natBoundedSums (natQuadraticSet A) K
obtain ⟨c, hc, hfiber⟩ := dyadic_regular_tree_uniform_fibers htree N le_rfl w hwN
rw [dyadic_projection_self hbound] at hfiber
obtain ⟨x₀, hx₀⟩ := hA
let r := x₀ % 2 ^ (T * w)
let F := A.filter (fun x => x % 2 ^ (T * w) = r)
have hFA : F ⊆ A := Finset.filter_subset _ _
have hr : r ∈ dyadicProjection A (T * w) := Finset.mem_image_of_mem _ hx₀
have hFc : F.card = c := hfiber r hr
have hAcard : A.card = (dyadicProjection A (T * w)).card * c := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ (T * w)) A]
calc
_ = ∑ _s ∈ dyadicProjection A (T * w), c := Finset.sum_congr rfl hfiber
_ = _ := by simp
have hraw := nat_modular_scaled_fiber_growth H F (pow_dvd_pow 2 (Nat.mul_le_mul_left T hwN))
(fun x hx => hbound x (hFA hx))
(fun x hx y hy => (Finset.mem_filter.mp hx).2.trans (Finset.mem_filter.mp hy).2.symm) hgcd
have hsub : ((H ×ˢ F).image (fun p => (p.1 + a * p.2) % 2 ^ (T * N))) ⊆
dyadicProjection (natBoundedSums (natQuadraticSet A) (K + 1)) (T * N) := by
intro z hz
obtain ⟨⟨h, f⟩, hhf, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨hh, hf⟩ := Finset.mem_product.mp hhf
refine Finset.mem_image.mpr ⟨h + a * f, ?_, rfl⟩
exact add_mem_nat_bounded_sums hh (mem_nat_bounded_sums_one
(Finset.mem_image.mpr ⟨(a, f), Finset.mem_product.mpr ⟨ha, hFA hf⟩, rfl⟩))
rw [hFc] at hraw
have hrawR : ((dyadicProjection H (T * w)).card : ℝ) * (c : ℝ) ≤ (D : ℝ) *
((dyadicProjection (natBoundedSums (natQuadraticSet A) (K + 1)) (T * N)).card : ℝ) := by
exact_mod_cast hraw.trans (Nat.mul_le_mul_left _ (Finset.card_le_card hsub))
calc
_ = (Λ * ((dyadicProjection A (T * w)).card : ℝ)) * (c : ℝ) := by
rw [hAcard, Nat.cast_mul]; ring
_ ≤ ((D : ℝ) * ((dyadicProjection H (T * w)).card : ℝ)) * (c : ℝ) :=
mul_le_mul_of_nonneg_right hprojected (Nat.cast_nonneg _)
_ = (D : ℝ) * (((dyadicProjection H (T * w)).card : ℝ) * (c : ℝ)) := by ring
_ ≤ (D : ℝ) * ((D : ℝ) *
((dyadicProjection (natBoundedSums (natQuadraticSet A) (K + 1)) (T * N)).card : ℝ)) :=
mul_le_mul_of_nonneg_left hrawR (Nat.cast_nonneg _)
_ = _ := by ring
theorem exists_regular_tree_quadratic_growth (T R : ℕ) {γ δ ρ g : ℝ}
(hT : 0 < T) (hR : 0 < R) (hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1)
(hρ : 0 < ρ) (hρδ : ρ ≤ δ / 4) (hρR : 1 ≤ ρ * (R : ℝ))
(hg : 0 < g) (hγg : 8 * g ≤ γ) (hρg : 3 * ρ < g)
(hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ)) :
∃ K : ℕ, 0 < K ∧ ∀ (N : ℕ) (A : Finset ℕ),
A.Nonempty → DyadicRegularTree A T N → (∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
1 ≤ N → 2 * (R : ℝ) ≤ γ * (N : ℝ) →
(2 : ℝ) ^ (ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ))) * (A.card : ℝ) ≤
((2 : ℝ) ^ T) ^ 2 *
((dyadicProjection (natBoundedSums (natQuadraticSet A) K) (T * N)).card : ℝ) := by
obtain ⟨K, hK, hgrowth⟩ := exists_regular_tree_quadratic_projected_growth T R
hT hR hγ hδ hδ1 hρ hρδ hρR hg hγg hρg hbudget
refine ⟨K + 1, by omega, ?_⟩
intro N A hA htree hbound hprefix hsize hN hRN
obtain ⟨w, a, hwN, ha, hgcd, hprojected⟩ := hgrowth N A hA htree hbound hprefix hsize hN hRN
have hh := regular_tree_quadratic_growth_of_projected hA htree hbound hwN ha (hgcd (T * N))
(by simpa only [Nat.cast_pow, Nat.cast_ofNat] using hprojected)
simpa only [Nat.cast_pow, Nat.cast_ofNat] using hh
theorem dyadic_quadratic_growth_absorb_loss {α : ℝ} {T N : ℕ} {a b : ℝ}
(ha : 0 ≤ a) (hN : 4 ≤ α * (N : ℝ))
(hgain : (2 : ℝ) ^ (α * (T : ℝ) * (N : ℝ)) * a ≤ ((2 : ℝ) ^ T) ^ 2 * b) :
(2 : ℝ) ^ (α / 2 * (T : ℝ) * (N : ℝ)) * a ≤ b := by
have hpow : ((2 : ℝ) ^ T) ^ 2 = (2 : ℝ) ^ (2 * (T : ℝ)) := by
rw [← pow_mul, ← Real.rpow_natCast, Nat.cast_mul, Nat.cast_ofNat, mul_comm]
rw [hpow] at hgain
apply (mul_le_mul_iff_of_pos_left (Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) (2 * (T : ℝ)))).mp
calc
_ = (2 : ℝ) ^ (2 * (T : ℝ) + α / 2 * (T : ℝ) * (N : ℝ)) * a := by
rw [Real.rpow_add (by norm_num)]; ring
_ ≤ (2 : ℝ) ^ (α * (T : ℝ) * (N : ℝ)) * a := by
apply mul_le_mul_of_nonneg_right _ ha
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_right hN (Nat.cast_nonneg T : (0 : ℝ) ≤ T)
nlinarith
_ ≤ _ := hgain
theorem exists_uniform_regular_tree_quadratic_amplification {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ η : ℝ, 0 < η ∧ ∀ T : ℕ, 0 < T → ∃ K N₀ : ℕ, 0 < K ∧
∀ N : ℕ, N₀ ≤ N → ∀ A : Finset ℕ, A.Nonempty → DyadicRegularTree A T N →
(∀ x ∈ A, x < 2 ^ (T * N)) →
(∀ j : ℕ, j ≤ N → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection A (T * j)).card : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
(2 : ℝ) ^ (η * (T : ℝ) * (N : ℝ)) * (A.card : ℝ) ≤
((dyadicProjection (natBoundedSums (natQuadraticSet A) K) (T * N)).card : ℝ) := by
let g := γ / 16
let ρ := min (δ / 8) (γ / 128)
let α := ρ / 2 * (γ * δ / 2)
have hg : 0 < g := by dsimp [g]; positivity
have hρ : 0 < ρ := lt_min (by positivity) (by positivity)
have hρδ8 : ρ ≤ δ / 8 := min_le_left _ _
have hργ128 : ρ ≤ γ / 128 := min_le_right _ _
have hρδ : ρ ≤ δ / 4 := by linarith
have hγg : 8 * g ≤ γ := by dsimp [g]; linarith
have hρg : 3 * ρ < g := by dsimp [g]; linarith
have hα : 0 < α := by dsimp [α]; positivity
refine ⟨α / 2, by positivity, ?_⟩
intro T hT
have hTr : (0 : ℝ) < T := by exact_mod_cast hT
have hlog : 0 < Real.log 2 := Real.log_pos (by norm_num)
have hcoef : 0 < α * (T : ℝ) * Real.log 2 := by positivity
obtain ⟨R, hRbound⟩ := exists_nat_ge (max (1 : ℝ) (max (1 / ρ) (1 / (α * (T : ℝ) * Real.log 2))))
have hR1 : (1 : ℝ) ≤ R := (le_max_left _ _).trans hRbound
have hR : 0 < R := by
have hh : 1 ≤ R := by exact_mod_cast hR1
omega
have hρrecip : 1 / ρ ≤ (R : ℝ) := (le_max_left _ _).trans ((le_max_right _ _).trans hRbound)
have hcoefrecip : 1 / (α * (T : ℝ) * Real.log 2) ≤ (R : ℝ) :=
(le_max_right _ _).trans ((le_max_right _ _).trans hRbound)
have hρR : 1 ≤ ρ * (R : ℝ) := by
have hh := (div_le_iff₀ hρ).mp hρrecip
nlinarith
have hcoefR : 1 ≤ (α * (T : ℝ) * Real.log 2) * (R : ℝ) := by
have hh := (div_le_iff₀ hcoef).mp hcoefrecip
nlinarith
have hbudget : 1 ≤ (ρ / 2 * (γ * δ / 2 * (T : ℝ)) * Real.log 2) * (R : ℝ) := by
calc
_ ≤ (α * (T : ℝ) * Real.log 2) * (R : ℝ) := hcoefR
_ = _ := by dsimp [α]; ring
obtain ⟨K, hK, hgrowth⟩ := exists_regular_tree_quadratic_growth T R
hT hR hγ hδ hδ1 hρ hρδ hρR hg hγg hρg hbudget
obtain ⟨N₀, hN₀⟩ := exists_nat_ge (max (1 : ℝ) (max (2 * (R : ℝ) / γ) (4 / α)))
refine ⟨K, N₀, hK, ?_⟩
intro N hN A hA htree hbound hprefix hsize
have hNbound : max (1 : ℝ) (max (2 * (R : ℝ) / γ) (4 / α)) ≤ N :=
hN₀.trans (by exact_mod_cast hN)
have hN1 : 1 ≤ N := by exact_mod_cast (le_max_left _ _).trans hNbound
have hRN : 2 * (R : ℝ) ≤ γ * (N : ℝ) := by
have hh := (div_le_iff₀ hγ).mp ((le_max_left _ _).trans ((le_max_right _ _).trans hNbound))
nlinarith
have hαN : 4 ≤ α * (N : ℝ) := by
have hh := (div_le_iff₀ hα).mp ((le_max_right _ _).trans ((le_max_right _ _).trans hNbound))
nlinarith
have hh := hgrowth N A hA htree hbound hprefix hsize hN1 hRN
have hexponent : ρ / 2 * (γ * δ / 2 * (T : ℝ) * (N : ℝ)) = α * (T : ℝ) * (N : ℝ) := by
dsimp [α]
ring
rw [hexponent] at hh
exact dyadic_quadratic_growth_absorb_loss (Nat.cast_nonneg _) hαN hh
theorem dyadic_tree_block_image {A : Finset ℕ} {b T m k : ℕ} (hA : DyadicTreeBlock A b T m k)
(f : ℕ → ℕ) (hinj : Set.InjOn f A)
(hmod : ∀ j : ℕ, j ≤ b + T → ∀ x ∈ A, ∀ y ∈ A,
f x % 2 ^ j = f y % 2 ^ j ↔ x % 2 ^ j = y % 2 ^ j) :
DyadicTreeBlock (A.image f) b T m k := by
have hfiber : ∀ a ∈ A,
(A.image f).filter (fun y => y % 2 ^ m = f a % 2 ^ m) =
(A.filter (fun x => x % 2 ^ m = a % 2 ^ m)).image f := by
intro a ha
ext y
constructor
· intro hy
obtain ⟨hyA, hym⟩ := Finset.mem_filter.mp hy
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hyA
exact Finset.mem_image.mpr ⟨x, Finset.mem_filter.mpr
⟨hx, (hmod m hA.split_lt.le x hx a ha).mp hym⟩, rfl⟩
· intro hy
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hy
obtain ⟨hxA, hxm⟩ := Finset.mem_filter.mp hx
exact Finset.mem_filter.mpr ⟨Finset.mem_image_of_mem _ hxA,
(hmod m hA.split_lt.le x hxA a ha).mpr hxm⟩
refine ⟨hA.base_le, hA.split_lt, hA.count_le, ?_, ?_, ?_⟩
· intro x hx y hy hxy
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨c, hc, rfl⟩ := Finset.mem_image.mp hy
exact (hmod m hA.split_lt.le a ha c hc).mpr
(hA.common a ha c hc ((hmod b (by omega) a ha c hc).mp hxy))
· intro r hr
obtain ⟨y, hy, rfl⟩ := Finset.mem_image.mp hr
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hy
rw [hfiber a ha, Finset.card_image_of_injOn (hinj.mono (Finset.filter_subset _ _))]
exact hA.fiber_card _ (Finset.mem_image_of_mem _ ha)
· intro r hr hk
obtain ⟨y, hy, rfl⟩ := Finset.mem_image.mp hr
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hy
obtain ⟨x, hx, z, hz, hxz⟩ := hA.splits _ (Finset.mem_image_of_mem _ ha) hk
rw [hfiber a ha]
refine ⟨f x, Finset.mem_image_of_mem _ hx, f z, Finset.mem_image_of_mem _ hz, ?_⟩
intro h
exact hxz ((hmod (m + 1) (by have := hA.split_lt; omega) x (Finset.mem_filter.mp hx).1
z (Finset.mem_filter.mp hz).1).mp h)
theorem dyadic_translation_mod_eq_iff {j e : ℕ} (hje : j ≤ e) (c x y : ℕ) :
(x + c) % 2 ^ e % 2 ^ j = (y + c) % 2 ^ e % 2 ^ j ↔ x % 2 ^ j = y % 2 ^ j := by
rw [Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hje), Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hje)]
constructor
· exact (Nat.ModEq.refl c).add_right_cancel
· intro h
exact (show Nat.ModEq (2 ^ j) x y from h).add (Nat.ModEq.refl c)
theorem dyadic_translation_injOn {A : Finset ℕ} {e : ℕ} (hA : ∀ x ∈ A, x < 2 ^ e) (c : ℕ) :
Set.InjOn (fun x => (x + c) % 2 ^ e) A := by
intro x hx y hy hxy
have h := (dyadic_translation_mod_eq_iff (le_refl e) c x y).mp (congrArg (fun n => n % 2 ^ e) hxy)
simpa only [Nat.mod_eq_of_lt (hA x hx), Nat.mod_eq_of_lt (hA y hy)] using h
theorem dyadic_projection_translate_trans (A : Finset ℕ) (e c : ℕ) :
dyadicProjection (natTranslate (dyadicProjection A e) c) e =
dyadicProjection (natTranslate A c) e := by
simp only [dyadicProjection, natTranslate, Finset.image_image, Function.comp_def]
apply Finset.image_congr
intro x hx
dsimp only
exact Nat.mod_add_mod _ _ _
theorem dyadic_tree_block_mod_translate {A : Finset ℕ} {b T m k : ℕ}
(hA : DyadicTreeBlock A b T m k) (hbound : ∀ x ∈ A, x < 2 ^ (b + T)) (c : ℕ) :
DyadicTreeBlock (dyadicProjection (natTranslate A c) (b + T)) b T m k := by
have hh := dyadic_tree_block_image hA (fun x => (x + c) % 2 ^ (b + T))
(dyadic_translation_injOn hbound c)
(fun j hj x hx y hy => dyadic_translation_mod_eq_iff hj c x y)
simpa only [dyadicProjection, natTranslate, Finset.image_image, Function.comp_def] using hh
theorem dyadic_regular_tree_mod_translate {A : Finset ℕ} {T N : ℕ}
(htree : DyadicRegularTree A T N) (c : ℕ) :
DyadicRegularTree (dyadicProjection (natTranslate A c) (T * N)) T N := by
intro i hi
obtain ⟨m, k, hblock⟩ := htree i hi
have he : T * i + T = T * (i + 1) := by ring
have hh := dyadic_tree_block_mod_translate hblock
(by simpa only [he] using dyadic_projection_bounded A (T * (i + 1))) c
rw [he, dyadic_projection_translate_trans] at hh
refine ⟨m, k, ?_⟩
rw [dyadic_projection_trans _ (Nat.mul_le_mul_left T (show i + 1 ≤ N by omega))]
exact hh
theorem dyadic_projection_translate_card (A : Finset ℕ) (e c : ℕ) :
(dyadicProjection (natTranslate A c) e).card = (dyadicProjection A e).card := by
rw [← dyadic_projection_translate_trans A e c]
change (((dyadicProjection A e).image (fun x => x + c)).image (fun x => x % 2 ^ e)).card = _
rw [Finset.image_image]
exact Finset.card_image_of_injOn (dyadic_translation_injOn (dyadic_projection_bounded A e) c)
def natCenter (A : Finset ℕ) (a : ℕ) : Finset ℕ := A.image (fun x => x - a)
theorem nat_center_eq_mod_translate {A : Finset ℕ} {a e : ℕ}
(ha : a < 2 ^ e) (hbase : ∀ x ∈ A, a ≤ x) (hbound : ∀ x ∈ A, x < 2 ^ e) :
natCenter A a = dyadicProjection (natTranslate A (2 ^ e - a)) e := by
simp only [natCenter, dyadicProjection, natTranslate, Finset.image_image, Function.comp_def]
apply Finset.image_congr
intro x hx
have heq : x + (2 ^ e - a) = x - a + 2 ^ e := by have := hbase x hx; omega
dsimp only
rw [heq, Nat.add_mod_right, Nat.mod_eq_of_lt (lt_of_le_of_lt (Nat.sub_le x a) (hbound x hx))]
theorem nat_center_card {A : Finset ℕ} {a : ℕ} (hbase : ∀ x ∈ A, a ≤ x) :
(natCenter A a).card = A.card := by
apply Finset.card_image_of_injOn
intro x hx y hy hxy
change x - a = y - a at hxy
have := hbase x hx
have := hbase y hy
omega
theorem dyadic_regular_tree_center {A : Finset ℕ} {a T N : ℕ}
(htree : DyadicRegularTree A T N) (ha : a ∈ A)
(hbase : ∀ x ∈ A, a ≤ x) (hbound : ∀ x ∈ A, x < 2 ^ (T * N)) :
DyadicRegularTree (natCenter A a) T N := by
rw [nat_center_eq_mod_translate (hbound a ha) hbase hbound]
exact dyadic_regular_tree_mod_translate htree _
theorem dyadic_center_projection_card {A : Finset ℕ} {a e j : ℕ}
(ha : a ∈ A) (hbase : ∀ x ∈ A, a ≤ x) (hbound : ∀ x ∈ A, x < 2 ^ e) (hj : j ≤ e) :
(dyadicProjection (natCenter A a) j).card = (dyadicProjection A j).card := by
rw [nat_center_eq_mod_translate (hbound a ha) hbase hbound,
dyadic_projection_trans _ hj, dyadic_projection_translate_card]
theorem scaled_mem_nat_bounded_sums {A B : Finset ℕ} {d : ℕ}
(hmap : ∀ a ∈ A, d * a ∈ B) (K : ℕ) :
∀ n ∈ natBoundedSums A K, d * n ∈ natBoundedSums B K := by
induction K with
| zero =>
intro n hn
have hn0 : n = 0 := Finset.mem_singleton.mp hn
simpa only [hn0, Nat.mul_zero] using zero_mem_nat_bounded_sums B 0
| succ K ih =>
intro n hn
obtain ⟨⟨a, x⟩, hax, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨ha, hx⟩ := Finset.mem_product.mp hax
have hda : d * a ∈ insert 0 B := by
rcases Finset.mem_insert.mp ha with rfl | ha
· simp only [Nat.mul_zero, Finset.mem_insert_self]
· exact Finset.mem_insert_of_mem (hmap a ha)
exact Finset.mem_image.mpr ⟨(d * a, d * x), Finset.mem_product.mpr ⟨hda, ih x hx⟩,
(Nat.mul_add d a x).symm⟩
theorem scaled_quadratic_sums_mem {A B : Finset ℕ} {d : ℕ}
(hmap : ∀ a ∈ A, d * a ∈ B) (K : ℕ) :
∀ n ∈ natBoundedSums (natQuadraticSet A) K,
d ^ 2 * n ∈ natBoundedSums (natQuadraticSet B) K := by
apply scaled_mem_nat_bounded_sums
intro a ha
obtain ⟨⟨x, y⟩, hxy, rfl⟩ := Finset.mem_image.mp ha
obtain ⟨hx, hy⟩ := Finset.mem_product.mp hxy
exact Finset.mem_image.mpr ⟨(d * x, d * y), Finset.mem_product.mpr ⟨hmap x hx, hmap y hy⟩,
by dsimp only; ring⟩
theorem dyadic_scaled_quadratic_card {A B : Finset ℕ} {d e J : ℕ}
(hmap : ∀ a ∈ A, 2 ^ d * a ∈ B) (heJ : e ≤ J) (K : ℕ) :
(dyadicProjection (natBoundedSums (natQuadraticSet A) K) e).card ≤
2 ^ (2 * d) * (dyadicProjection (natBoundedSums (natQuadraticSet B) K) J).card := by
have hpow : (2 ^ d : ℕ) ^ 2 = 2 ^ (2 * d) := by rw [← pow_mul, Nat.mul_comm]
have hsub : (natBoundedSums (natQuadraticSet A) K).image (fun x => 2 ^ (2 * d) * x) ⊆
natBoundedSums (natQuadraticSet B) K := by
intro n hn
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hn
simpa only [hpow] using scaled_quadratic_sums_mem hmap K x hx
calc
_ ≤ (dyadicProjection (natBoundedSums (natQuadraticSet A) K) J).card :=
dyadic_projection_card_mono _ heJ
_ ≤ 2 ^ (2 * d) * (dyadicProjection
((natBoundedSums (natQuadraticSet A) K).image (fun x => 2 ^ (2 * d) * x)) J).card :=
dyadic_projection_mul_card_le _ J _ _ (Nat.gcd_le_right _ (by positivity))
_ ≤ _ := Nat.mul_le_mul_left _ (Finset.card_le_card (Finset.image_subset_image hsub))
def natDifferenceSet (A : Finset ℕ) : Finset ℕ := (A ×ˢ A).image (fun p => p.1 - p.2)
theorem centered_zoom_scaled_mem_difference {A B : Finset ℕ} {d r a : ℕ}
(hBA : B ⊆ A) (hr : r < 2 ^ d) (ha : a ∈ dyadicZoom B d r) :
∀ x ∈ natCenter (dyadicZoom B d r) a, 2 ^ d * x ∈ natDifferenceSet A := by
intro x hx
obtain ⟨y, hy, rfl⟩ := Finset.mem_image.mp hx
have hyB := (dyadic_zoom_mem hr).mp hy
have haB := (dyadic_zoom_mem hr).mp ha
refine Finset.mem_image.mpr ⟨(r + 2 ^ d * y, r + 2 ^ d * a),
Finset.mem_product.mpr ⟨hBA hyB, hBA haB⟩, ?_⟩
dsimp only
rw [Nat.add_sub_add_left, Nat.mul_sub_left_distrib]
theorem exists_centered_regular_tail {A B : Finset ℕ} {T N i : ℕ} {γ : ℝ}
(hBA : B ⊆ A) (hB : B.Nonempty) (htree : DyadicRegularTree B T N)
(hbound : ∀ x ∈ B, x < 2 ^ (T * N)) (hiN : i ≤ N)
(htail : ∀ j : ℕ, i ≤ j → j ≤ N →
((dyadicProjection B (T * i)).card : ℝ) * (2 : ℝ) ^ (γ * ((T * (j - i) : ℕ) : ℝ)) ≤
((dyadicProjection B (T * j)).card : ℝ)) :
∃ C : Finset ℕ, C.Nonempty ∧ DyadicRegularTree C T (N - i) ∧
(∀ x ∈ C, x < 2 ^ (T * (N - i))) ∧
(∀ j : ℕ, j ≤ N - i → (2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤
((dyadicProjection C (T * j)).card : ℝ)) ∧
C.card ≤ A.card ∧ B.card ≤ 2 ^ (T * i) * C.card ∧
(∀ x ∈ C, 2 ^ (T * i) * x ∈ natDifferenceSet A) := by
obtain ⟨r, hr⟩ := hB.image (fun x => x % 2 ^ (T * i))
have hrB : r ∈ dyadicProjection B (T * i) := hr
have hrlt := dyadic_projection_bounded B (T * i) r hrB
let Z := dyadicZoom B (T * i) r
have hZ : Z.Nonempty := dyadic_zoom_nonempty hrB
have hZbound : ∀ x ∈ Z, x < 2 ^ (T * (N - i)) :=
dyadic_zoom_bounded (by simpa only [← Nat.mul_add, Nat.add_sub_of_le hiN] using hbound) r
obtain ⟨a, ha, hamin⟩ := Finset.exists_min_image Z id hZ
have hbase : ∀ x ∈ Z, a ≤ x := hamin
let C := natCenter Z a
have hCcard : C.card = Z.card := nat_center_card hbase
refine ⟨C, hZ.image _, dyadic_regular_tree_center (dyadic_regular_tree_zoom htree hiN hrlt)
ha hbase hZbound, ?_, ?_, ?_, ?_, ?_⟩
· intro x hx
obtain ⟨y, hy, rfl⟩ := Finset.mem_image.mp hx
exact lt_of_le_of_lt (Nat.sub_le _ _) (hZbound y hy)
· intro j hj
rw [dyadic_center_projection_card ha hbase hZbound (Nat.mul_le_mul_left T hj)]
simpa only [Nat.cast_mul, mul_assoc] using
dyadic_regular_tree_zoom_growth htree hrB htail j (by omega)
· rw [hCcard, dyadic_zoom_card]
exact (Finset.card_filter_le _ _).trans (Finset.card_le_card hBA)
· rw [hCcard, ← dyadic_regular_tree_zoom_card htree hbound hiN hrB]
exact Nat.mul_le_mul_right _ (dyadic_projection_card_le B (T * i))
· exact centered_zoom_scaled_mem_difference hBA hrlt ha
theorem exists_general_dyadic_growth_dichotomy {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ κ ε : ℝ, 0 < κ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧
∃ T K N₀ : ℕ, 0 < T ∧ 0 < K ∧ ∀ N : ℕ, N₀ ≤ N →
∀ A : Finset ℕ, A.Nonempty → (∀ x ∈ A, x < 2 ^ (T * N)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
(∀ j : ℕ, j ≤ N → ε * (N : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤ ((dyadicProjection A (T * j)).card : ℝ)) →
(2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) * (A.card : ℝ) ≤
(((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card : ℝ) ∨
(2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) * (A.card : ℝ) ≤
((dyadicProjection (natBoundedSums (natQuadraticSet (natDifferenceSet A)) K) (T * N)).card : ℝ) := by
obtain ⟨α, hα, hamp⟩ := exists_uniform_regular_tree_quadratic_amplification
(show 0 < γ / 2 by positivity) (show 0 < δ / 2 by positivity) (show δ / 2 ≤ 1 by linarith)
let ε := min (1 / 4 : ℝ) (min (δ / 4) (α / 16))
let κ := min (ε * γ / 8) (α / 16)
have hε : 0 < ε := lt_min (by norm_num) (lt_min (by positivity) (by positivity))
have hε4 : ε ≤ 1 / 4 := min_le_left _ _
have hεδ : ε ≤ δ / 4 := (min_le_right _ _).trans (min_le_left _ _)
have hεα : ε ≤ α / 16 := (min_le_right _ _).trans (min_le_right _ _)
have hκ : 0 < κ := lt_min (by positivity) (by positivity)
have hκε : κ ≤ ε * γ / 8 := min_le_left _ _
have hκα : κ ≤ α / 16 := min_le_right _ _
have hbudget : κ + κ ≤ ε * (γ - γ / 2) := by nlinarith [mul_pos hε hγ]
have htotal : 2 * κ + (α + 3) * ε ≤ α := by
have hh := mul_le_mul_of_nonneg_left hε4 hα.le
nlinarith
obtain ⟨T, hT, hregular⟩ := exists_dyadic_regular_tree_small_loss hκ
obtain ⟨K, N₁, hK, hampT⟩ := hamp T hT
refine ⟨κ, ε, hκ, hε, hε4, T, K, 2 * N₁ + 1, hT, hK, ?_⟩
intro N hN A hA hbound hsize hprojection
by_cases hsum : (2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) * (A.card : ℝ) ≤
(((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card : ℝ)
· exact Or.inl hsum
apply Or.inr
have hsmall : (((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ (T * N))).card : ℝ) ≤
(2 : ℝ) ^ (κ * ((T * N : ℕ) : ℝ)) * (A.card : ℝ) := by
simpa only [Nat.cast_mul, mul_assoc] using (lt_of_not_ge hsum).le
obtain ⟨B, hBA, htree, hlarge⟩ := hregular N A hbound
have hB : B.Nonempty := by
apply Finset.card_pos.mp
have hApos : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hA
have hpow : 0 < (2 : ℝ) ^ (κ * ((T * N : ℕ) : ℝ)) := by positivity
have hBpos : (0 : ℝ) < B.card := by nlinarith
exact_mod_cast hBpos
have hBbound : ∀ x ∈ B, x < 2 ^ (T * N) := fun x hx => hbound x (hBA hx)
obtain ⟨i, hiN, hiε, hPi, htail⟩ := exists_regular_tree_dense_tail hT hBA hB htree hBbound
(show γ / 2 < γ by linarith) hbudget hlarge hsmall
(by intro j hj hεj; simpa only [Nat.cast_mul, mul_assoc] using hprojection j hj hεj)
obtain ⟨C, hC, hCtree, hCbound, hCprefix, hCA, hBC, hmap⟩ :=
exists_centered_regular_tail hBA hB htree hBbound hiN htail
have hi2 : 2 * i ≤ N := by
have hh := mul_le_mul_of_nonneg_right hε4 (Nat.cast_nonneg N : (0 : ℝ) ≤ N)
have hh' : (2 : ℝ) * (i : ℝ) ≤ N := by nlinarith
exact_mod_cast hh'
have htailN : N₁ ≤ N - i := by omega
have hdensity : (1 - δ) * (N : ℝ) ≤ (1 - δ / 2) * ((N - i : ℕ) : ℝ) := by
have hh := mul_le_mul_of_nonneg_right hεδ (Nat.cast_nonneg N : (0 : ℝ) ≤ N)
rw [Nat.cast_sub hiN]
nlinarith [mul_nonneg hδ.le (Nat.cast_nonneg i : (0 : ℝ) ≤ i)]
have hCsize : (C.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ / 2) * (T : ℝ) * ((N - i : ℕ) : ℝ)) := by
calc
_ ≤ (A.card : ℝ) := by exact_mod_cast hCA
_ ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) := hsize
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_left hdensity (Nat.cast_nonneg T : (0 : ℝ) ≤ T)
nlinarith
have hgrowth := hampT (N - i) htailN C hC hCtree hCbound hCprefix hCsize
let Z := ((dyadicProjection (natBoundedSums (natQuadraticSet (natDifferenceSet A)) K) (T * N)).card : ℝ)
have hlift : ((dyadicProjection (natBoundedSums (natQuadraticSet C) K) (T * (N - i))).card : ℝ) ≤
(2 : ℝ) ^ (2 * (T : ℝ) * (i : ℝ)) * Z := by
have hh := dyadic_scaled_quadratic_card hmap (Nat.mul_le_mul_left T (Nat.sub_le N i)) K
have hhR : ((dyadicProjection (natBoundedSums (natQuadraticSet C) K) (T * (N - i))).card : ℝ) ≤
(2 : ℝ) ^ (2 * (T * i)) * Z := by dsimp only [Z]; exact_mod_cast hh
simpa only [← Real.rpow_natCast, Nat.cast_mul, Nat.cast_ofNat, mul_assoc] using hhR
have hlargeC : (A.card : ℝ) ≤
(2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ) + (T : ℝ) * (i : ℝ)) * (C.card : ℝ) := by
have hBCR : (B.card : ℝ) ≤ (2 : ℝ) ^ ((T : ℝ) * (i : ℝ)) * (C.card : ℝ) := by
have hh : (B.card : ℝ) ≤ (2 : ℝ) ^ (T * i) * (C.card : ℝ) := by exact_mod_cast hBC
simpa only [← Real.rpow_natCast, Nat.cast_mul] using hh
calc
_ ≤ (2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) * (B.card : ℝ) := by
simpa only [Nat.cast_mul, mul_assoc] using hlarge
_ ≤ (2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) *
((2 : ℝ) ^ ((T : ℝ) * (i : ℝ)) * (C.card : ℝ)) :=
mul_le_mul_of_nonneg_left hBCR (by positivity)
_ = _ := by rw [← mul_assoc, ← Real.rpow_add (by norm_num)]
have hexp : 2 * κ * (T : ℝ) * (N : ℝ) + 3 * (T : ℝ) * (i : ℝ) ≤
α * (T : ℝ) * ((N - i : ℕ) : ℝ) := by
have hh := mul_le_mul_of_nonneg_right htotal (Nat.cast_nonneg N : (0 : ℝ) ≤ N)
have hh' := mul_le_mul_of_nonneg_left hiε (show 0 ≤ α + 3 by linarith)
have hi : 2 * κ * (N : ℝ) + 3 * (i : ℝ) ≤ α * ((N - i : ℕ) : ℝ) := by
rw [Nat.cast_sub hiN]
nlinarith
have hh'' := mul_le_mul_of_nonneg_left hi (Nat.cast_nonneg T : (0 : ℝ) ≤ T)
nlinarith
apply (mul_le_mul_iff_of_pos_left
(Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) (2 * (T : ℝ) * (i : ℝ)))).mp
calc
_ ≤ (2 : ℝ) ^ (2 * (T : ℝ) * (i : ℝ)) *
((2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) *
((2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ) + (T : ℝ) * (i : ℝ)) * (C.card : ℝ))) :=
mul_le_mul_of_nonneg_left (mul_le_mul_of_nonneg_left hlargeC (by positivity)) (by positivity)
_ = (2 : ℝ) ^ (2 * κ * (T : ℝ) * (N : ℝ) + 3 * (T : ℝ) * (i : ℝ)) * (C.card : ℝ) := by
simp only [← mul_assoc]
rw [← Real.rpow_add (by norm_num : (0 : ℝ) < 2),
← Real.rpow_add (by norm_num : (0 : ℝ) < 2)]
congr 2
ring
_ ≤ (2 : ℝ) ^ (α * (T : ℝ) * ((N - i : ℕ) : ℝ)) * (C.card : ℝ) :=
mul_le_mul_of_nonneg_right (Real.rpow_le_rpow_of_exponent_le (by norm_num) hexp) (Nat.cast_nonneg _)
_ ≤ _ := hgrowth.trans hlift
def natSignedResidueHull (E : Finset ℕ) (K q : ℕ) : Finset ℕ :=
(natBoundedSums E K ×ˢ natBoundedSums E K).image
(fun p => ((p.1 : ZMod q) - (p.2 : ZMod q)).val)
theorem quadratic_difference_signed_representation (A : Finset ℕ) (q : ℕ) :
∀ x ∈ natQuadraticSet (natDifferenceSet A),
∃ p ∈ natBoundedSums (natLinearQuadraticSet A) 2,
∃ n ∈ natBoundedSums (natLinearQuadraticSet A) 2,
(x : ZMod q) = (p : ZMod q) - (n : ZMod q) := by
intro x hx
obtain ⟨⟨s, t⟩, hst, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨hs, ht⟩ := Finset.mem_product.mp hst
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Finset.mem_image.mp hs
obtain ⟨⟨c, d⟩, hcd, rfl⟩ := Finset.mem_image.mp ht
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
obtain ⟨hc, hd⟩ := Finset.mem_product.mp hcd
have hzero : 0 ∈ natBoundedSums (natLinearQuadraticSet A) 2 := zero_mem_nat_bounded_sums _ _
by_cases hba : b ≤ a
· by_cases hdc : d ≤ c
· have hprod : ∀ u ∈ A, ∀ v ∈ A, u * v ∈ natBoundedSums (natLinearQuadraticSet A) 1 := by
intro u hu v hv
exact mem_nat_bounded_sums_one (Finset.mem_union_right A
(Finset.mem_image.mpr ⟨(u, v), Finset.mem_product.mpr ⟨hu, hv⟩, rfl⟩))
refine ⟨a * c + b * d, add_mem_nat_bounded_sums (hprod a ha c hc) (hprod b hb d hd),
a * d + b * c, add_mem_nat_bounded_sums (hprod a ha d hd) (hprod b hb c hc), ?_⟩
simp only [Nat.cast_mul, Nat.cast_sub hba, Nat.cast_sub hdc, Nat.cast_add]
ring
· refine ⟨0, hzero, 0, hzero, ?_⟩
simp only [Nat.sub_eq_zero_of_le (by omega : c ≤ d), Nat.mul_zero, Nat.cast_zero, sub_self]
· refine ⟨0, hzero, 0, hzero, ?_⟩
simp only [Nat.sub_eq_zero_of_le (by omega : a ≤ b), Nat.zero_mul, Nat.cast_zero, sub_self]
theorem nat_bounded_sums_signed_representation {A E : Finset ℕ} {q K : ℕ}
(hrep : ∀ a ∈ A, ∃ p ∈ natBoundedSums E K, ∃ n ∈ natBoundedSums E K,
(a : ZMod q) = (p : ZMod q) - (n : ZMod q)) (s : ℕ) :
∀ x ∈ natBoundedSums A s, ∃ p ∈ natBoundedSums E (K * s),
∃ n ∈ natBoundedSums E (K * s), (x : ZMod q) = (p : ZMod q) - (n : ZMod q) := by
induction s with
| zero =>
intro x hx
have hx0 : x = 0 := Finset.mem_singleton.mp hx
refine ⟨0, ?_, 0, ?_, ?_⟩
· exact zero_mem_nat_bounded_sums _ _
· exact zero_mem_nat_bounded_sums _ _
· simp only [hx0, Nat.cast_zero, sub_self]
| succ s ih =>
intro x hx
obtain ⟨⟨a, y⟩, hay, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨ha, hy⟩ := Finset.mem_product.mp hay
have harep : ∃ p ∈ natBoundedSums E K, ∃ n ∈ natBoundedSums E K,
(a : ZMod q) = (p : ZMod q) - (n : ZMod q) := by
rcases Finset.mem_insert.mp ha with rfl | ha
· exact ⟨0, zero_mem_nat_bounded_sums _ _, 0, zero_mem_nat_bounded_sums _ _, by simp⟩
· exact hrep a ha
obtain ⟨p, hp, n, hn, hapn⟩ := harep
obtain ⟨p', hp', n', hn', hyrep⟩ := ih y hy
have hindex : K * (s + 1) = K + K * s := by ring
refine ⟨p + p', ?_, n + n', ?_, ?_⟩
· rw [hindex]
exact add_mem_nat_bounded_sums hp hp'
· rw [hindex]
exact add_mem_nat_bounded_sums hn hn'
· simp only [Nat.cast_add, hapn, hyrep]
ring
theorem mem_nat_signed_residue_hull {E : Finset ℕ} {K q x p n : ℕ} [NeZero q]
(hp : p ∈ natBoundedSums E K) (hn : n ∈ natBoundedSums E K)
(hrep : (x : ZMod q) = (p : ZMod q) - (n : ZMod q)) :
x % q ∈ natSignedResidueHull E K q := by
refine Finset.mem_image.mpr ⟨(p, n), Finset.mem_product.mpr ⟨hp, hn⟩, ?_⟩
dsimp only
rw [← hrep, ZMod.val_natCast]
theorem quadratic_difference_projection_subset_signed_hull (A : Finset ℕ) (K J : ℕ) :
dyadicProjection (natBoundedSums (natQuadraticSet (natDifferenceSet A)) K) J ⊆
natSignedResidueHull (natLinearQuadraticSet A) (2 * K + 2) (2 ^ J) := by
intro x hx
obtain ⟨y, hy, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨p, hp, n, hn, hrep⟩ := nat_bounded_sums_signed_representation
(quadratic_difference_signed_representation A (2 ^ J)) K y hy
exact mem_nat_signed_residue_hull (nat_bounded_sums_mono _ (by omega : 2 * K ≤ 2 * K + 2) hp)
(nat_bounded_sums_mono _ (by omega : 2 * K ≤ 2 * K + 2) hn) hrep
theorem nat_sumset_subset_signed_linear_quadratic_hull (A : Finset ℕ) (K J : ℕ) :
((A ×ˢ A).image (fun p => (p.1 + p.2) % 2 ^ J)) ⊆
natSignedResidueHull (natLinearQuadraticSet A) (2 * K + 2) (2 ^ J) := by
intro x hx
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
have hp : a + b ∈ natBoundedSums (natLinearQuadraticSet A) 2 :=
add_mem_nat_bounded_sums (mem_nat_bounded_sums_one (Finset.mem_union_left _ ha))
(mem_nat_bounded_sums_one (Finset.mem_union_left _ hb))
exact mem_nat_signed_residue_hull (nat_bounded_sums_mono _ (by omega : 2 ≤ 2 * K + 2) hp)
(zero_mem_nat_bounded_sums _ _) (by simp)
theorem exists_general_dyadic_signed_sum_product_growth {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ κ ε : ℝ, 0 < κ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧
∃ T K N₀ : ℕ, 0 < T ∧ 0 < K ∧ ∀ N : ℕ, N₀ ≤ N →
∀ A : Finset ℕ, A.Nonempty → (∀ x ∈ A, x < 2 ^ (T * N)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) →
(∀ j : ℕ, j ≤ N → ε * (N : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * (T : ℝ) * (j : ℝ)) ≤ ((dyadicProjection A (T * j)).card : ℝ)) →
(2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) * (A.card : ℝ) ≤
((natSignedResidueHull (natLinearQuadraticSet A) K (2 ^ (T * N))).card : ℝ) := by
obtain ⟨κ, ε, hκ, hε, hε4, T, K, N₀, hT, hK, hgrowth⟩ :=
exists_general_dyadic_growth_dichotomy hγ hδ hδ1
refine ⟨κ, ε, hκ, hε, hε4, T, 2 * K + 2, N₀, hT, by omega, ?_⟩
intro N hN A hA hbound hsize hprojection
rcases hgrowth N hN A hA hbound hsize hprojection with hsum | hquad
· apply hsum.trans
exact_mod_cast Finset.card_le_card (nat_sumset_subset_signed_linear_quadratic_hull A K (T * N))
· apply hquad.trans
exact_mod_cast Finset.card_le_card (quadratic_difference_projection_subset_signed_hull A K (T * N))
theorem dyadic_card_le_projection_mul {A : Finset ℕ} {b d : ℕ}
(hbound : ∀ x ∈ A, x < 2 ^ (b + d)) :
A.card ≤ 2 ^ d * (dyadicProjection A b).card := by
rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ b) A]
calc
_ ≤ ∑ _r ∈ dyadicProjection A b, 2 ^ d :=
Finset.sum_le_sum (fun r _ => dyadic_residue_fiber_card_le hbound r)
_ = _ := by simp [Nat.mul_comm]
theorem dyadic_sub_val_mod {j m : ℕ} (hjm : j ≤ m) (a b : ℕ) :
((a : ZMod (2 ^ m)) - (b : ZMod (2 ^ m))).val % 2 ^ j =
((a : ZMod (2 ^ j)) - (b : ZMod (2 ^ j))).val := by
let π : ZMod (2 ^ m) →+* ZMod (2 ^ j) := ZMod.castHom (pow_dvd_pow 2 hjm) _
have heq : (((((a : ZMod (2 ^ m)) - (b : ZMod (2 ^ m))).val) : ℕ) : ZMod (2 ^ j)) =
(a : ZMod (2 ^ j)) - (b : ZMod (2 ^ j)) := by
calc
_ = π ((a : ZMod (2 ^ m)) - (b : ZMod (2 ^ m))) := by
rw [ZMod.castHom_apply, ZMod.cast_eq_val]
_ = _ := by rw [map_sub, map_natCast, map_natCast]
have hh := congrArg ZMod.val heq
simpa only [ZMod.val_natCast] using hh
theorem dyadic_signed_hull_project (E : Finset ℕ) (K : ℕ) {j m : ℕ} (hjm : j ≤ m) :
dyadicProjection (natSignedResidueHull E K (2 ^ m)) j = natSignedResidueHull E K (2 ^ j) := by
unfold dyadicProjection natSignedResidueHull
rw [Finset.image_image]
apply Finset.image_congr
intro p hp
exact dyadic_sub_val_mod hjm p.1 p.2
theorem nat_signed_residue_hull_bounded (E : Finset ℕ) (K : ℕ) {q : ℕ} [NeZero q] :
∀ x ∈ natSignedResidueHull E K q, x < q := by
intro x hx
obtain ⟨p, hp, rfl⟩ := Finset.mem_image.mp hx
exact ZMod.val_lt _
theorem dyadic_signed_hull_card_le (E : Finset ℕ) (K : ℕ) {j m d : ℕ}
(hjm : j ≤ m) (hmd : m ≤ j + d) :
(natSignedResidueHull E K (2 ^ m)).card ≤ 2 ^ d * (natSignedResidueHull E K (2 ^ j)).card := by
have hb : ∀ x ∈ natSignedResidueHull E K (2 ^ m), x < 2 ^ (j + d) := by
intro x hx
exact (nat_signed_residue_hull_bounded E K x hx).trans_le
(Nat.pow_le_pow_right (by decide : 0 < 2) hmd)
have hh := dyadic_card_le_projection_mul hb
rwa [dyadic_signed_hull_project E K hjm] at hh
theorem exists_dyadic_signed_sum_product_growth {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ κ ε : ℝ, 0 < κ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧
∃ K J₀ : ℕ, 0 < K ∧ ∀ J : ℕ, J₀ ≤ J → ∀ A : Finset ℕ,
A.Nonempty → (∀ x ∈ A, x < 2 ^ J) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * (j : ℝ)) ≤ ((dyadicProjection A j).card : ℝ)) →
(2 : ℝ) ^ (κ * (J : ℝ)) * (A.card : ℝ) ≤
((natSignedResidueHull (natLinearQuadraticSet A) K (2 ^ J)).card : ℝ) := by
obtain ⟨κ, ε, hκ, hε, hε4, T, K, N₀, hT, hK, hgrowth⟩ :=
exists_general_dyadic_signed_sum_product_growth (show 0 < γ / 2 by positivity) hδ hδ1
obtain ⟨J₀, hJ₀⟩ := exists_nat_ge (max (T : ℝ) (max ((T * N₀ : ℕ) : ℝ) (2 * (T : ℝ) / κ)))
refine ⟨κ / 2, ε, by positivity, hε, hε4, K, J₀, hK, ?_⟩
intro J hJ A hA hbound hsize hprojection
have hJbound : max (T : ℝ) (max ((T * N₀ : ℕ) : ℝ) (2 * (T : ℝ) / κ)) ≤ J :=
hJ₀.trans (by exact_mod_cast hJ)
have hTJ : T ≤ J := by exact_mod_cast (le_max_left _ _).trans hJbound
have hTNJ : T * N₀ ≤ J := by
exact_mod_cast (le_max_left _ _).trans ((le_max_right _ _).trans hJbound)
have hκJ : 2 * (T : ℝ) ≤ κ * (J : ℝ) := by
have hh := (div_le_iff₀ hκ).mp ((le_max_right _ _).trans ((le_max_right _ _).trans hJbound))
nlinarith
let N := J / T + 1
have hdecomp : J % T + T * (J / T) = J := Nat.mod_add_div J T
have hrem : J % T < T := Nat.mod_lt J hT
have hJm : J ≤ T * N := by dsimp only [N]; rw [Nat.mul_add, Nat.mul_one]; omega
have hmJ : T * N ≤ J + T := by dsimp only [N]; rw [Nat.mul_add, Nat.mul_one]; omega
have hm2J : T * N ≤ 2 * J := by omega
have hN : N₀ ≤ N := by
have hh : N₀ ≤ J / T := (Nat.le_div_iff_mul_le hT).mpr (by simpa only [Nat.mul_comm] using hTNJ)
dsimp [N]
omega
have hJpos : (0 : ℝ) < J := by exact_mod_cast (lt_of_lt_of_le hT hTJ)
have hεJ : ε * (J : ℝ) < J := by nlinarith
have hfull : (2 : ℝ) ^ (γ * (J : ℝ)) ≤ (A.card : ℝ) := by
simpa only [dyadic_projection_self hbound] using hprojection J le_rfl hεJ
have hbound' : ∀ x ∈ A, x < 2 ^ (T * N) := fun x hx =>
(hbound x hx).trans_le (Nat.pow_le_pow_right (by decide : 0 < 2) hJm)
have hsize' : (A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (T : ℝ) * (N : ℝ)) := by
apply hsize.trans
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_left (show (J : ℝ) ≤ (T : ℝ) * (N : ℝ) by exact_mod_cast hJm)
(show 0 ≤ 1 - δ by linarith)
nlinarith
have hprefix : ∀ j : ℕ, j ≤ N → ε * (N : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ / 2 * (T : ℝ) * (j : ℝ)) ≤ ((dyadicProjection A (T * j)).card : ℝ) := by
intro j hj hεj
by_cases hjJ : T * j ≤ J
· have hlarge : ε * (J : ℝ) < ((T * j : ℕ) : ℝ) := by
have hh := mul_lt_mul_of_pos_left hεj (show (0 : ℝ) < T by exact_mod_cast hT)
have hh' := mul_le_mul_of_nonneg_left (show (J : ℝ) ≤ (T : ℝ) * (N : ℝ) by exact_mod_cast hJm) hε.le
simp only [Nat.cast_mul]
nlinarith
apply (Real.rpow_le_rpow_of_exponent_le (by norm_num : (1 : ℝ) ≤ 2) ?_).trans
(hprojection (T * j) hjJ hlarge)
simp only [Nat.cast_mul]
nlinarith [mul_nonneg (mul_nonneg hγ.le (Nat.cast_nonneg T)) (Nat.cast_nonneg j)]
· have hJtj : J ≤ T * j := by omega
rw [dyadic_projection_self (fun x hx => (hbound x hx).trans_le
(Nat.pow_le_pow_right (by decide : 0 < 2) hJtj))]
apply (Real.rpow_le_rpow_of_exponent_le (by norm_num : (1 : ℝ) ≤ 2) ?_).trans hfull
have hle : (T : ℝ) * (j : ℝ) ≤ 2 * (J : ℝ) := by
exact_mod_cast (Nat.mul_le_mul_left T hj).trans hm2J
nlinarith [mul_le_mul_of_nonneg_left hle hγ.le]
have hh := hgrowth N hN A hA hbound' hsize' hprefix
have hreduce : ((natSignedResidueHull (natLinearQuadraticSet A) K (2 ^ (T * N))).card : ℝ) ≤
(2 : ℝ) ^ T * ((natSignedResidueHull (natLinearQuadraticSet A) K (2 ^ J)).card : ℝ) := by
exact_mod_cast dyadic_signed_hull_card_le (natLinearQuadraticSet A) K hJm hmJ
apply (mul_le_mul_iff_of_pos_left (pow_pos (by norm_num : (0 : ℝ) < 2) T)).mp
calc
_ = (2 : ℝ) ^ ((T : ℝ) + κ / 2 * (J : ℝ)) * (A.card : ℝ) := by
rw [Real.rpow_add (by norm_num), Real.rpow_natCast]; ring
_ ≤ (2 : ℝ) ^ (κ * (T : ℝ) * (N : ℝ)) * (A.card : ℝ) := by
apply mul_le_mul_of_nonneg_right _ (Nat.cast_nonneg _)
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hm : (J : ℝ) ≤ (T : ℝ) * (N : ℝ) := by exact_mod_cast hJm
nlinarith [mul_le_mul_of_nonneg_left hm hκ.le]
_ ≤ _ := hh.trans hreduce
theorem one_le_projection_card_mul_mass {A : Finset ℕ} (hA : A.Nonempty) (j : ℕ) {M : ℝ}
(hM : ∀ r : ℕ, natResidueMass A (2 ^ j) r ≤ M) :
1 ≤ ((dyadicProjection A j).card : ℝ) * M := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hA
have hfiber : ∀ r ∈ dyadicProjection A j,
((A.filter (fun x => x % 2 ^ j = r)).card : ℝ) ≤ M * (A.card : ℝ) := by
intro r hr
have hh := (div_le_iff₀ hAp).mp (hM r)
simpa only [natResidueFiber, Nat.ModEq,
Nat.mod_eq_of_lt (dyadic_projection_bounded A j r hr)] using hh
have hcard : (A.card : ℝ) ≤ ((dyadicProjection A j).card : ℝ) * (M * (A.card : ℝ)) := by
conv_lhs => rw [Finset.card_eq_sum_card_image (fun x => x % 2 ^ j) A, Nat.cast_sum]
calc
_ ≤ ∑ _r ∈ dyadicProjection A j, M * (A.card : ℝ) := Finset.sum_le_sum hfiber
_ = _ := by simp
apply (mul_le_mul_iff_of_pos_right hAp).mp
simpa only [one_mul, mul_assoc] using hcard
theorem dyadic_projection_growth_of_mass {A : Finset ℕ} (hA : A.Nonempty) (j : ℕ) {γ : ℝ}
(hM : ∀ r : ℕ, natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-γ * (j : ℝ))) :
(2 : ℝ) ^ (γ * (j : ℝ)) ≤ ((dyadicProjection A j).card : ℝ) := by
have hh := one_le_projection_card_mul_mass hA j hM
have hinv : (2 : ℝ) ^ (-γ * (j : ℝ)) * (2 : ℝ) ^ (γ * (j : ℝ)) = 1 := by
rw [← Real.rpow_add (by norm_num), show -γ * (j : ℝ) + γ * (j : ℝ) = 0 by ring, Real.rpow_zero]
calc
_ = 1 * (2 : ℝ) ^ (γ * (j : ℝ)) := (one_mul _).symm
_ ≤ (((dyadicProjection A j).card : ℝ) * (2 : ℝ) ^ (-γ * (j : ℝ))) *
(2 : ℝ) ^ (γ * (j : ℝ)) := mul_le_mul_of_nonneg_right hh (by positivity)
_ = _ := by rw [mul_assoc, hinv, mul_one]
theorem exists_dyadic_signed_sum_product_growth_of_mass {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ κ ε : ℝ, 0 < κ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧
∃ K J₀ : ℕ, 0 < K ∧ ∀ J : ℕ, J₀ ≤ J → ∀ A : Finset ℕ,
A.Nonempty → (∀ x ∈ A, x < 2 ^ J) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) → ∀ r : ℕ,
natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-γ * (j : ℝ))) →
(2 : ℝ) ^ (κ * (J : ℝ)) * (A.card : ℝ) ≤
((natSignedResidueHull (natLinearQuadraticSet A) K (2 ^ J)).card : ℝ) := by
obtain ⟨κ, ε, hκ, hε, hε4, K, J₀, hK, hgrowth⟩ := exists_dyadic_signed_sum_product_growth hγ hδ hδ1
refine ⟨κ, ε, hκ, hε, hε4, K, J₀, hK, ?_⟩
intro J hJ A hA hbound hsize hmass
exact hgrowth J hJ A hA hbound hsize (fun j hj hεj =>
dyadic_projection_growth_of_mass hA j (hmass j hj hεj))
open scoped Pointwise
def natResidueGenerators (E : Finset ℕ) (q : ℕ) : Finset (ZMod q) :=
insert 0 (E.image (fun n : ℕ => (n : ZMod q)))
theorem nat_sumset_cast_image (A B : Finset ℕ) (q : ℕ) :
(((A ×ˢ B).image (fun p => p.1 + p.2)).image (fun n : ℕ => (n : ZMod q))) =
A.image (fun n : ℕ => (n : ZMod q)) + B.image (fun n : ℕ => (n : ZMod q)) := by
ext z
constructor
· intro hz
obtain ⟨n, hn, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
exact Finset.mem_add.mpr ⟨(a : ZMod q), Finset.mem_image_of_mem _ ha,
(b : ZMod q), Finset.mem_image_of_mem _ hb, (Nat.cast_add a b).symm⟩
· intro hz
obtain ⟨x, hx, y, hy, rfl⟩ := Finset.mem_add.mp hz
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨b, hb, rfl⟩ := Finset.mem_image.mp hy
exact Finset.mem_image.mpr ⟨a + b, Finset.mem_image.mpr
⟨(a, b), Finset.mem_product.mpr ⟨ha, hb⟩, rfl⟩, Nat.cast_add a b⟩
theorem nat_bounded_sums_cast_image (E : Finset ℕ) (K q : ℕ) :
(natBoundedSums E K).image (fun n : ℕ => (n : ZMod q)) = K • natResidueGenerators E q := by
induction K with
| zero =>
simp only [natBoundedSums, Finset.image_singleton, Nat.cast_zero, zero_nsmul]
rfl
| succ K ih =>
rw [natBoundedSums, nat_sumset_cast_image, ih, succ_nsmul']
simp only [Finset.image_insert, Nat.cast_zero, natResidueGenerators]
theorem nat_signed_residue_hull_eq_image (E : Finset ℕ) (K q : ℕ) :
natSignedResidueHull E K q =
(K • natResidueGenerators E q - K • natResidueGenerators E q).image ZMod.val := by
rw [← nat_bounded_sums_cast_image]
ext z
constructor
· intro hz
obtain ⟨⟨p, n⟩, hpn, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨hp, hn⟩ := Finset.mem_product.mp hpn
exact Finset.mem_image.mpr ⟨(p : ZMod q) - (n : ZMod q),
Finset.mem_sub.mpr ⟨(p : ZMod q), Finset.mem_image_of_mem _ hp,
(n : ZMod q), Finset.mem_image_of_mem _ hn, rfl⟩, rfl⟩
· intro hz
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨p, hp, n, hn, rfl⟩ := Finset.mem_sub.mp hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hp
obtain ⟨b, hb, rfl⟩ := Finset.mem_image.mp hn
exact Finset.mem_image.mpr ⟨(a, b), Finset.mem_product.mpr ⟨ha, hb⟩, rfl⟩
theorem nat_signed_residue_hull_card (E : Finset ℕ) (K : ℕ) {q : ℕ} [NeZero q] :
(natSignedResidueHull E K q).card =
(K • natResidueGenerators E q - K • natResidueGenerators E q).card := by
rw [nat_signed_residue_hull_eq_image, Finset.card_image_of_injective _ (ZMod.val_injective q)]
theorem nat_signed_hull_pluennecke_bound (E : Finset ℕ) (K : ℕ) {q : ℕ} [NeZero q] :
((natSignedResidueHull E K q).card : ℝ) ≤
(((natResidueGenerators E q + natResidueGenerators E q).card : ℝ) /
((natResidueGenerators E q).card : ℝ)) ^ (2 * K) * ((natResidueGenerators E q).card : ℝ) := by
have hF : (natResidueGenerators E q).Nonempty := ⟨0, Finset.mem_insert_self _ _⟩
have hh := Finset.pluennecke_ruzsa_inequality_nsmul_sub_nsmul_add hF (natResidueGenerators E q) K K
have hhR : ((K • natResidueGenerators E q - K • natResidueGenerators E q).card : ℝ) ≤
(((natResidueGenerators E q + natResidueGenerators E q).card : ℝ) /
((natResidueGenerators E q).card : ℝ)) ^ (K + K) * ((natResidueGenerators E q).card : ℝ) := by
have hhQ : ((K • natResidueGenerators E q - K • natResidueGenerators E q).card : ℚ) ≤
(((natResidueGenerators E q + natResidueGenerators E q).card : ℚ) /
((natResidueGenerators E q).card : ℚ)) ^ (K + K) * ((natResidueGenerators E q).card : ℚ) := by
exact_mod_cast (NNRat.coe_mono hh)
have hhCast := (Rat.cast_le (K := ℝ)).mpr hhQ
push_cast at hhCast
exact hhCast
simpa only [nat_signed_residue_hull_card, two_mul] using hhR
theorem nat_linear_quadratic_generators_card_ge {A : Finset ℕ} {q : ℕ} [NeZero q]
(hbound : ∀ x ∈ A, x < q) :
A.card ≤ (natResidueGenerators (natLinearQuadraticSet A) q).card := by
have hinj : Set.InjOn (fun n : ℕ => (n : ZMod q)) A := by
intro x hx y hy hxy
have hh := congrArg ZMod.val hxy
simpa only [ZMod.val_natCast, Nat.mod_eq_of_lt (hbound x hx), Nat.mod_eq_of_lt (hbound y hy)] using hh
calc
_ = (A.image (fun n : ℕ => (n : ZMod q))).card := (Finset.card_image_of_injOn hinj).symm
_ ≤ _ := Finset.card_le_card (by
intro x hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
exact Finset.mem_insert_of_mem (Finset.mem_image_of_mem _ (Finset.mem_union_left _ ha)))
theorem nat_signed_hull_bound_of_double_bound (E : Finset ℕ) (K : ℕ) {q : ℕ} [NeZero q]
{a L : ℝ} (ha : a ≤ ((natResidueGenerators E q).card : ℝ)) (hL : 0 ≤ L)
(hdouble : ((natResidueGenerators E q + natResidueGenerators E q).card : ℝ) ≤ L * a) :
((natSignedResidueHull E K q).card : ℝ) ≤ L ^ (2 * K + 1) * a := by
let F := natResidueGenerators E q
have hF : F.Nonempty := ⟨0, Finset.mem_insert_self _ _⟩
have hFp : (0 : ℝ) < F.card := by exact_mod_cast Finset.card_pos.mpr hF
have hsub : F ⊆ F + F := by
intro x hx
exact Finset.mem_add.mpr ⟨x, hx, 0, Finset.mem_insert_self _ _, add_zero x⟩
have hsize : (F.card : ℝ) ≤ L * a := (show (F.card : ℝ) ≤ (F + F).card by
exact_mod_cast Finset.card_le_card hsub).trans hdouble
have hratio : ((F + F).card : ℝ) / (F.card : ℝ) ≤ L :=
(div_le_iff₀ hFp).mpr (hdouble.trans (mul_le_mul_of_nonneg_left ha hL))
have hratio0 : 0 ≤ ((F + F).card : ℝ) / (F.card : ℝ) := by positivity
calc
_ ≤ (((F + F).card : ℝ) / (F.card : ℝ)) ^ (2 * K) * (F.card : ℝ) :=
nat_signed_hull_pluennecke_bound E K
_ ≤ L ^ (2 * K) * (F.card : ℝ) :=
mul_le_mul_of_nonneg_right (pow_le_pow_left₀ hratio0 hratio _) hFp.le
_ ≤ L ^ (2 * K) * (L * a) := mul_le_mul_of_nonneg_left hsize (pow_nonneg hL _)
_ = _ := by rw [pow_succ]; ring
theorem exists_dyadic_sum_product_double_growth {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ σ ε : ℝ, 0 < σ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A : Finset ℕ,
A.Nonempty → (∀ x ∈ A, x < 2 ^ J) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) → ∀ r : ℕ,
natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-γ * (j : ℝ))) →
(2 : ℝ) ^ (σ * (J : ℝ)) * (A.card : ℝ) ≤
((natResidueGenerators (natLinearQuadraticSet A) (2 ^ J) +
natResidueGenerators (natLinearQuadraticSet A) (2 ^ J)).card : ℝ) := by
obtain ⟨κ, ε, hκ, hε, hε4, K, J₀, hK, hgrowth⟩ :=
exists_dyadic_signed_sum_product_growth_of_mass hγ hδ hδ1
let σ := κ / (4 * (K : ℝ) + 2)
have hden : 0 < 4 * (K : ℝ) + 2 := by positivity
have hσ : 0 < σ := div_pos hκ hden
have hexp : σ * ((2 * K + 1 : ℕ) : ℝ) = κ / 2 := by
dsimp [σ]
push_cast
field_simp
ring
refine ⟨σ, ε, hσ, hε, hε4, max J₀ 1, ?_⟩
intro J hJ A hA hbound hsize hmass
have hJ₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hJ1 : 1 ≤ J := (le_max_right _ _).trans hJ
have hJp : (0 : ℝ) < J := by exact_mod_cast (show 0 < J by omega)
have hAp : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hA
by_contra h
have hupper := nat_signed_hull_bound_of_double_bound (natLinearQuadraticSet A) K
(q := 2 ^ J) (by exact_mod_cast nat_linear_quadratic_generators_card_ge hbound)
(show 0 ≤ (2 : ℝ) ^ (σ * (J : ℝ)) by positivity) (lt_of_not_ge h).le
have hpowlt : ((2 : ℝ) ^ (σ * (J : ℝ))) ^ (2 * K + 1) < (2 : ℝ) ^ (κ * (J : ℝ)) := by
rw [← Real.rpow_mul_natCast (by norm_num)]
apply Real.rpow_lt_rpow_of_exponent_lt (by norm_num)
have hEq : σ * (J : ℝ) * ((2 * K + 1 : ℕ) : ℝ) = κ / 2 * (J : ℝ) := by
rw [mul_right_comm, hexp]
rw [hEq]
nlinarith [mul_pos hκ hJp]
exact (not_lt_of_ge (hgrowth J hJ₀ A hA hbound hsize hmass))
(hupper.trans_lt (mul_lt_mul_of_pos_right hpowlt hAp))
theorem nat_productset_cast_image (A B : Finset ℕ) (q : ℕ) :
(((A ×ˢ B).image (fun p => p.1 * p.2)).image (fun n : ℕ => (n : ZMod q))) =
A.image (fun n : ℕ => (n : ZMod q)) * B.image (fun n : ℕ => (n : ZMod q)) := by
ext z
constructor
· intro hz
obtain ⟨n, hn, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Finset.mem_image.mp hn
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
exact Finset.mem_mul.mpr ⟨(a : ZMod q), Finset.mem_image_of_mem _ ha,
(b : ZMod q), Finset.mem_image_of_mem _ hb, (Nat.cast_mul a b).symm⟩
· intro hz
obtain ⟨x, hx, y, hy, rfl⟩ := Finset.mem_mul.mp hz
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨b, hb, rfl⟩ := Finset.mem_image.mp hy
exact Finset.mem_image.mpr ⟨a * b, Finset.mem_image.mpr
⟨(a, b), Finset.mem_product.mpr ⟨ha, hb⟩, rfl⟩, Nat.cast_mul a b⟩
theorem nat_linear_quadratic_residue_generators (A : Finset ℕ) (q : ℕ) :
natResidueGenerators (natLinearQuadraticSet A) q =
insert 0 (A.image (fun n : ℕ => (n : ZMod q)) ∪
A.image (fun n : ℕ => (n : ZMod q)) * A.image (fun n : ℕ => (n : ZMod q))) := by
unfold natResidueGenerators natLinearQuadraticSet
rw [Finset.image_union, nat_productset_cast_image]
theorem dyadic_projection_cast_image (A : Finset ℕ) (J : ℕ) :
(dyadicProjection A J).image (fun n : ℕ => (n : ZMod (2 ^ J))) =
A.image (fun n : ℕ => (n : ZMod (2 ^ J))) := by
unfold dyadicProjection
rw [Finset.image_image]
apply Finset.image_congr
intro n hn
exact (ZMod.natCast_eq_natCast_iff' _ _ _).mpr (Nat.mod_mod n _)
theorem dyadic_projection_card_of_cast_inj {A : Finset ℕ} {J : ℕ}
(hinj : Set.InjOn (fun n : ℕ => (n : ZMod (2 ^ J))) A) :
(dyadicProjection A J).card = A.card := by
apply Finset.card_image_of_injOn
intro a ha b hb hab
exact hinj ha hb ((ZMod.natCast_eq_natCast_iff' _ _ _).mpr hab)
theorem nat_residue_mass_dyadic_projection {A : Finset ℕ} {J j : ℕ}
(hinj : Set.InjOn (fun n : ℕ => (n : ZMod (2 ^ J))) A) (hj : j ≤ J) (r : ℕ) :
natResidueMass (dyadicProjection A J) (2 ^ j) r = natResidueMass A (2 ^ j) r := by
have heq : natResidueFiber (dyadicProjection A J) (2 ^ j) r =
(natResidueFiber A (2 ^ j) r).image (fun n => n % 2 ^ J) := by
ext x
constructor
· intro hx
obtain ⟨hxP, hxr⟩ := Finset.mem_filter.mp hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hxP
have har : Nat.ModEq (2 ^ j) a r := by
simpa only [Nat.ModEq, Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hj)] using hxr
exact Finset.mem_image.mpr ⟨a, Finset.mem_filter.mpr ⟨ha, har⟩, rfl⟩
· intro hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨haA, har⟩ := Finset.mem_filter.mp ha
refine Finset.mem_filter.mpr ⟨Finset.mem_image_of_mem _ haA, ?_⟩
simpa only [Nat.ModEq, Nat.mod_mod_of_dvd _ (pow_dvd_pow 2 hj)] using har
have hi : Set.InjOn (fun n : ℕ => n % 2 ^ J) (natResidueFiber A (2 ^ j) r) := by
intro a ha b hb hab
exact hinj (Finset.mem_filter.mp ha).1 (Finset.mem_filter.mp hb).1
((ZMod.natCast_eq_natCast_iff' _ _ _).mpr hab)
unfold natResidueMass
rw [heq, Finset.card_image_of_injOn hi, dyadic_projection_card_of_cast_inj hinj]
theorem dyadic_linear_quadratic_generators_projection (A : Finset ℕ) (J : ℕ) :
natResidueGenerators (natLinearQuadraticSet (dyadicProjection A J)) (2 ^ J) =
natResidueGenerators (natLinearQuadraticSet A) (2 ^ J) := by
rw [nat_linear_quadratic_residue_generators, nat_linear_quadratic_residue_generators,
dyadic_projection_cast_image]
theorem exists_dyadic_sum_product_double_growth_injective {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ σ ε : ℝ, 0 < σ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A : Finset ℕ, A.Nonempty →
Set.InjOn (fun n : ℕ => (n : ZMod (2 ^ J))) A →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) → ∀ r : ℕ,
natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-γ * (j : ℝ))) →
(2 : ℝ) ^ (σ * (J : ℝ)) * (A.card : ℝ) ≤
((natResidueGenerators (natLinearQuadraticSet A) (2 ^ J) +
natResidueGenerators (natLinearQuadraticSet A) (2 ^ J)).card : ℝ) := by
obtain ⟨σ, ε, hσ, hε, hε4, J₀, hgrowth⟩ := exists_dyadic_sum_product_double_growth hγ hδ hδ1
refine ⟨σ, ε, hσ, hε, hε4, J₀, ?_⟩
intro J hJ A hA hinj hsize hmass
have hh := hgrowth J hJ (dyadicProjection A J) (hA.image _) (dyadic_projection_bounded A J)
(by simpa only [dyadic_projection_card_of_cast_inj hinj] using hsize)
(fun j hj hεj r => by rw [nat_residue_mass_dyadic_projection hinj hj]; exact hmass j hj hεj r)
simpa only [dyadic_projection_card_of_cast_inj hinj, dyadic_linear_quadratic_generators_projection] using hh
theorem dyadic_large_subset_mass {A B : Finset ℕ} {J j : ℕ} {γ ε τ : ℝ}
(hBA : B ⊆ A) (hB : B.Nonempty) (hγ : 0 < γ) (hτ : τ ≤ γ * ε / 2)
(hlarge : (A.card : ℝ) ≤ (2 : ℝ) ^ (τ * (J : ℝ)) * (B.card : ℝ))
(hj : ε * (J : ℝ) < (j : ℝ))
(hmass : ∀ r : ℕ, natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-γ * (j : ℝ))) :
∀ r : ℕ, natResidueMass B (2 ^ j) r ≤ (2 : ℝ) ^ (-(γ / 2) * (j : ℝ)) := by
intro r
calc
_ ≤ (2 : ℝ) ^ (τ * (J : ℝ)) * natResidueMass A (2 ^ j) r :=
nat_residue_mass_subset_le hBA hB hlarge _ _
_ ≤ (2 : ℝ) ^ (τ * (J : ℝ)) * (2 : ℝ) ^ (-γ * (j : ℝ)) :=
mul_le_mul_of_nonneg_left (hmass r) (by positivity)
_ = (2 : ℝ) ^ (τ * (J : ℝ) - γ * (j : ℝ)) := by
rw [← Real.rpow_add (by norm_num)]
congr 1
ring
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_right hτ (Nat.cast_nonneg J : (0 : ℝ) ≤ J)
have hh' := mul_lt_mul_of_pos_left hj hγ
nlinarith
theorem exists_hereditary_dyadic_sum_product_growth {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ σ ε τ : ℝ, 0 < σ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ 0 < τ ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A B : Finset ℕ,
B ⊆ A → B.Nonempty → Set.InjOn (fun n : ℕ => (n : ZMod (2 ^ J))) A →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(A.card : ℝ) ≤ (2 : ℝ) ^ (τ * (J : ℝ)) * (B.card : ℝ) →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) → ∀ r : ℕ,
natResidueMass A (2 ^ j) r ≤ (2 : ℝ) ^ (-γ * (j : ℝ))) →
(2 : ℝ) ^ (σ * (J : ℝ)) * (B.card : ℝ) ≤
((natResidueGenerators (natLinearQuadraticSet B) (2 ^ J) +
natResidueGenerators (natLinearQuadraticSet B) (2 ^ J)).card : ℝ) := by
obtain ⟨σ, ε, hσ, hε, hε4, J₀, hgrowth⟩ :=
exists_dyadic_sum_product_double_growth_injective (show 0 < γ / 2 by positivity) hδ hδ1
refine ⟨σ, ε, γ * ε / 4, hσ, hε, hε4, by positivity, J₀, ?_⟩
intro J hJ A B hBA hB hinj hsize hlarge hmass
apply hgrowth J hJ B hB (hinj.mono hBA)
· exact (show (B.card : ℝ) ≤ A.card by exact_mod_cast Finset.card_le_card hBA).trans hsize
· intro j hj hεj
exact dyadic_large_subset_mass hBA hB hγ (by nlinarith [mul_pos hγ hε]) hlarge hεj (hmass j hj hεj)
/- Quantitative inverse energy via weighted translate selection and common-neighbor counting. -/
open scoped BigOperators Pointwise
section FiniteInverseEnergy
variable {G : Type*} [AddCommGroup G] [Fintype G] [DecidableEq G]
def finiteDifferenceFiber (A B : Finset G) (x : G) : Finset (G × G) :=
(A ×ˢ B).filter (fun p => p.1 - p.2 = x)
def finiteDifferenceCount (A B : Finset G) (x : G) : ℕ :=
(finiteDifferenceFiber A B x).card
def finiteDifferenceEnergy (A B : Finset G) : ℕ :=
∑ x : G, finiteDifferenceCount A B x ^ 2
def finiteShiftOverlap (A B : Finset G) (s : G) : Finset G :=
A.filter (fun a => a - s ∈ B)
theorem finite_difference_count_eq_overlap (A B : Finset G) (s : G) :
finiteDifferenceCount A B s = (finiteShiftOverlap A B s).card := by
unfold finiteDifferenceCount finiteDifferenceFiber finiteShiftOverlap
apply Finset.card_bij (fun p _ => p.1)
· rintro ⟨a, b⟩ hp
obtain ⟨⟨ha, hb⟩, hs⟩ := by simpa only [Finset.mem_filter, Finset.mem_product] using hp
refine Finset.mem_filter.mpr ⟨ha, ?_⟩
rw [← hs, sub_sub_cancel]
exact hb
· intro p hp q hq hpq
apply Prod.ext hpq
have hh := (Finset.mem_filter.mp hp).2.trans (Finset.mem_filter.mp hq).2.symm
simpa only [hpq, sub_right_inj] using hh
· intro a ha
obtain ⟨haA, haB⟩ := Finset.mem_filter.mp ha
exact ⟨(a, a - s), Finset.mem_filter.mpr
⟨Finset.mem_product.mpr ⟨haA, haB⟩, sub_sub_cancel a s⟩, rfl⟩
theorem finite_difference_count_le_right (A B : Finset G) (s : G) :
finiteDifferenceCount A B s ≤ B.card := by
apply Finset.card_le_card_of_injOn (fun p => p.2)
· intro p hp
exact (Finset.mem_product.mp (Finset.mem_filter.mp hp).1).2
· intro p hp q hq hpq
apply Prod.ext ?_ hpq
have hh := (Finset.mem_filter.mp hp).2.trans (Finset.mem_filter.mp hq).2.symm
simpa only [hpq, sub_left_inj] using hh
theorem finite_difference_count_sum (A B : Finset G) :
∑ s : G, finiteDifferenceCount A B s = A.card * B.card := by
unfold finiteDifferenceCount finiteDifferenceFiber
rw [← Finset.card_product]
exact (Finset.card_eq_sum_card_fiberwise (f := fun p : G × G => p.1 - p.2)
(t := Finset.univ) (fun _ _ => Finset.mem_univ _)).symm
theorem finite_difference_count_sum_real (A B : Finset G) :
∑ s : G, (finiteDifferenceCount A B s : ℝ) = (A.card : ℝ) * (B.card : ℝ) := by
exact_mod_cast finite_difference_count_sum A B
theorem finite_difference_energy_sum_real (A B : Finset G) :
∑ s : G, (finiteDifferenceCount A B s : ℝ) ^ 2 = (finiteDifferenceEnergy A B : ℝ) := by
unfold finiteDifferenceEnergy
push_cast
rfl
theorem finite_difference_cubic_moment (A B : Finset G) :
(finiteDifferenceEnergy A B : ℝ) ^ 2 ≤
((A.card : ℝ) * (B.card : ℝ)) * ∑ s : G, (finiteDifferenceCount A B s : ℝ) ^ 3 := by
let r := fun s => (finiteDifferenceCount A B s : ℝ)
let f := fun s => Real.sqrt (r s)
have hf (s : G) : f s ^ 2 = r s := Real.sq_sqrt (Nat.cast_nonneg _)
have h₁ : ∑ s : G, f s ^ 2 = (A.card : ℝ) * (B.card : ℝ) := by
simp_rw [hf]
exact finite_difference_count_sum_real A B
have h₂ : ∑ s : G, f s * (f s * r s) = (finiteDifferenceEnergy A B : ℝ) := by
calc
_ = ∑ s : G, r s ^ 2 := Finset.sum_congr rfl (fun s _ => by
calc _ = f s ^ 2 * r s := by ring
_ = r s ^ 2 := by rw [hf]; ring)
_ = _ := finite_difference_energy_sum_real A B
have h₃ : ∑ s : G, (f s * r s) ^ 2 = ∑ s : G, r s ^ 3 := by
apply Finset.sum_congr rfl
intro s hs
rw [mul_pow, hf]
ring
have hh := Finset.sum_mul_sq_le_sq_mul_sq Finset.univ f (fun s => f s * r s)
rwa [h₁, h₂, h₃] at hh
theorem finite_common_shift_count (B : Finset G) (a b : G) :
(Finset.univ.filter (fun s : G => a - s ∈ B ∧ b - s ∈ B)).card =
finiteDifferenceCount B B (a - b) := by
unfold finiteDifferenceCount finiteDifferenceFiber
apply Finset.card_bij (fun s _ => (a - s, b - s))
· intro s hs
obtain ⟨ha, hb⟩ := (Finset.mem_filter.mp hs).2
exact Finset.mem_filter.mpr ⟨Finset.mem_product.mpr ⟨ha, hb⟩, sub_sub_sub_cancel_right a b s⟩
· intro s hs t ht hst
simpa only [Prod.mk.injEq, sub_right_inj, and_self] using hst
· rintro ⟨c, d⟩ hp
obtain ⟨⟨hc, hd⟩, hcd⟩ := by simpa only [Finset.mem_filter, Finset.mem_product] using hp
have heq : b - (a - c) = d := by
rw [(sub_eq_iff_eq_add).mp hcd]
abel
refine ⟨a - c, Finset.mem_filter.mpr ⟨Finset.mem_univ _, ?_⟩, ?_⟩
· simpa only [sub_sub_cancel, heq] using And.intro hc hd
· simp only [sub_sub_cancel, heq]
def finiteShiftPairCount (B : Finset G) (H : Finset (G × G)) (s : G) : ℕ :=
(H.filter (fun p => p.1 - s ∈ B ∧ p.2 - s ∈ B)).card
theorem finite_shift_pair_count_sum (B : Finset G) (H : Finset (G × G)) :
∑ s : G, finiteShiftPairCount B H s =
∑ p ∈ H, finiteDifferenceCount B B (p.1 - p.2) := by
unfold finiteShiftPairCount
simp_rw [Finset.card_eq_sum_ones, Finset.sum_filter]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro p hp
simpa only [Finset.card_eq_sum_ones, Finset.sum_filter] using finite_common_shift_count B p.1 p.2
theorem finite_weighted_shift_pair_bound (A B : Finset G) (H : Finset (G × G)) :
∑ s : G, (finiteDifferenceCount A B s : ℝ) * (finiteShiftPairCount B H s : ℝ) ≤
(B.card : ℝ) * ∑ p ∈ H, (finiteDifferenceCount B B (p.1 - p.2) : ℝ) := by
calc
_ ≤ ∑ s : G, (B.card : ℝ) * (finiteShiftPairCount B H s : ℝ) := by
apply Finset.sum_le_sum
intro s hs
exact mul_le_mul_of_nonneg_right (by exact_mod_cast finite_difference_count_le_right A B s)
(Nat.cast_nonneg _)
_ = _ := by
rw [← Finset.mul_sum]
congr 1
exact_mod_cast finite_shift_pair_count_sum B H
theorem finite_difference_energy_eq_card (A B : Finset G) :
finiteDifferenceEnergy A B =
(((A ×ˢ B) ×ˢ (A ×ˢ B)).filter
(fun p => p.1.1 - p.1.2 = p.2.1 - p.2.2)).card := by
let Q := (((A ×ˢ B) ×ˢ (A ×ˢ B)).filter
(fun p => p.1.1 - p.1.2 = p.2.1 - p.2.2))
have hf (x : G) : Q.filter (fun p => p.1.1 - p.1.2 = x) =
finiteDifferenceFiber A B x ×ˢ finiteDifferenceFiber A B x := by
ext p
simp only [Q, finiteDifferenceFiber, Finset.mem_filter, Finset.mem_product]
aesop
calc
_ = ∑ x : G, (finiteDifferenceFiber A B x ×ˢ finiteDifferenceFiber A B x).card := by
simp only [finiteDifferenceEnergy, finiteDifferenceCount, Finset.card_product, pow_two]
_ = ∑ x : G, (Q.filter (fun p => p.1.1 - p.1.2 = x)).card := by simp only [hf]
_ = Q.card := (Finset.card_eq_sum_card_fiberwise
(f := fun p : (G × G) × (G × G) => p.1.1 - p.1.2)
(t := Finset.univ) (fun _ _ => Finset.mem_univ _)).symm
theorem finite_difference_energy_eq_addEnergy (A B : Finset G) :
finiteDifferenceEnergy A B = Finset.addEnergy A B := by
rw [finite_difference_energy_eq_card]
unfold Finset.addEnergy
apply Finset.card_bij (fun p _ => ((p.1.1, p.2.1), (p.2.2, p.1.2)))
· intro p hp
simpa only [Finset.mem_filter, Finset.mem_product, sub_eq_sub_iff_add_eq_add, and_assoc] using
(show (p.1.1 ∈ A ∧ p.2.1 ∈ A) ∧ (p.2.2 ∈ B ∧ p.1.2 ∈ B) ∧
p.1.1 - p.1.2 = p.2.1 - p.2.2 from by
simpa only [Finset.mem_filter, Finset.mem_product, and_assoc, and_left_comm, and_comm] using hp)
· intro p hp q hq hpq
aesop
· intro p hp
refine ⟨((p.1.1, p.2.2), (p.1.2, p.2.1)), ?_, by simp⟩
simpa only [Finset.mem_filter, Finset.mem_product, sub_eq_sub_iff_add_eq_add,
and_assoc, and_left_comm, and_comm] using hp
theorem finite_energy_lower_cubic {A B : Finset G} {K : ℝ}
(hA : A.Nonempty) (hB : B.Nonempty) (hK : 0 ≤ K)
(hE : (A.card : ℝ) ^ 2 * (B.card : ℝ) ≤ K * (finiteDifferenceEnergy A B : ℝ)) :
(A.card : ℝ) ^ 3 * (B.card : ℝ) ≤
K ^ 2 * ∑ s : G, (finiteDifferenceCount A B s : ℝ) ^ 3 := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hBp : (0 : ℝ) < B.card := by exact_mod_cast hB.card_pos
have hsq := pow_le_pow_left₀ (by positivity : (0 : ℝ) ≤ (A.card : ℝ) ^ 2 * B.card) hE 2
have hmoment := mul_le_mul_of_nonneg_left (finite_difference_cubic_moment A B)
(sq_nonneg K)
apply (mul_le_mul_iff_left₀ (mul_pos hAp hBp)).mp
calc
_ = ((A.card : ℝ) ^ 2 * (B.card : ℝ)) ^ 2 := by ring
_ ≤ (K * (finiteDifferenceEnergy A B : ℝ)) ^ 2 := hsq
_ = K ^ 2 * (finiteDifferenceEnergy A B : ℝ) ^ 2 := mul_pow _ _ _
_ ≤ _ := hmoment
_ = _ := by ring
theorem finite_weighted_bad_pair_bound {A B : Finset G} {H : Finset (G × G)} {K : ℝ}
(hH : H ⊆ A ×ˢ A)
(hbad : ∀ p ∈ H, 16 * K ^ 2 * (finiteDifferenceCount B B (p.1 - p.2) : ℝ) ≤ A.card) :
16 * K ^ 2 *
(∑ s : G, (finiteDifferenceCount A B s : ℝ) * (finiteShiftPairCount B H s : ℝ)) ≤
(A.card : ℝ) ^ 3 * (B.card : ℝ) := by
have hcard : (H.card : ℝ) ≤ (A.card : ℝ) ^ 2 := by
exact_mod_cast (Finset.card_le_card hH).trans_eq (by simp [pow_two])
calc
_ ≤ 16 * K ^ 2 * ((B.card : ℝ) * ∑ p ∈ H,
(finiteDifferenceCount B B (p.1 - p.2) : ℝ)) :=
mul_le_mul_of_nonneg_left (finite_weighted_shift_pair_bound A B H) (by positivity)
_ = (B.card : ℝ) * ∑ p ∈ H, 16 * K ^ 2 * (finiteDifferenceCount B B (p.1 - p.2) : ℝ) := by
rw [← Finset.mul_sum]
ring
_ ≤ (B.card : ℝ) * ∑ _p ∈ H, (A.card : ℝ) :=
mul_le_mul_of_nonneg_left (Finset.sum_le_sum hbad) (Nat.cast_nonneg _)
_ = (B.card : ℝ) * ((H.card : ℝ) * (A.card : ℝ)) := by simp
_ ≤ (B.card : ℝ) * ((A.card : ℝ) ^ 2 * (A.card : ℝ)) := by gcongr
_ = _ := by ring
theorem finite_exists_good_shift {A B : Finset G} {H : Finset (G × G)} {K : ℝ}
(hA : A.Nonempty) (hB : B.Nonempty) (hK : 0 ≤ K)
(hE : (A.card : ℝ) ^ 2 * (B.card : ℝ) ≤ K * (finiteDifferenceEnergy A B : ℝ))
(hH : H ⊆ A ×ˢ A)
(hbad : ∀ p ∈ H, 16 * K ^ 2 * (finiteDifferenceCount B B (p.1 - p.2) : ℝ) ≤ A.card) :
∃ s : G, (A.card : ℝ) ^ 2 + 16 * K ^ 2 * (finiteShiftPairCount B H s : ℝ) ≤
2 * K ^ 2 * ((finiteShiftOverlap A B s).card : ℝ) ^ 2 := by
have htotal :
(∑ s : G, (finiteDifferenceCount A B s : ℝ) *
((A.card : ℝ) ^ 2 + 16 * K ^ 2 * (finiteShiftPairCount B H s : ℝ))) ≤
∑ s : G, (finiteDifferenceCount A B s : ℝ) *
(2 * K ^ 2 * ((finiteShiftOverlap A B s).card : ℝ) ^ 2) := by
calc
_ = (A.card : ℝ) ^ 3 * (B.card : ℝ) + 16 * K ^ 2 *
(∑ s : G, (finiteDifferenceCount A B s : ℝ) * (finiteShiftPairCount B H s : ℝ)) := by
simp only [mul_add, Finset.sum_add_distrib]
rw [← Finset.sum_mul, finite_difference_count_sum_real]
have heq : (∑ s : G, (finiteDifferenceCount A B s : ℝ) *
(16 * K ^ 2 * (finiteShiftPairCount B H s : ℝ))) =
16 * K ^ 2 * ∑ s : G, (finiteDifferenceCount A B s : ℝ) * (finiteShiftPairCount B H s : ℝ) := by
rw [Finset.mul_sum]
apply Finset.sum_congr rfl
intro s hs
ring
rw [heq]
ring
_ ≤ 2 * ((A.card : ℝ) ^ 3 * (B.card : ℝ)) := by
linarith [finite_weighted_bad_pair_bound hH hbad]
_ ≤ 2 * (K ^ 2 * ∑ s : G, (finiteDifferenceCount A B s : ℝ) ^ 3) :=
mul_le_mul_of_nonneg_left (finite_energy_lower_cubic hA hB hK hE) (by norm_num)
_ = _ := by
rw [← mul_assoc, Finset.mul_sum]
apply Finset.sum_congr rfl
intro s hs
rw [← finite_difference_count_eq_overlap]
ring
by_contra! hn
apply not_lt_of_ge htotal
apply Finset.sum_lt_sum
· intro s hs
exact mul_le_mul_of_nonneg_left (hn s).le (Nat.cast_nonneg _)
· obtain ⟨a, ha⟩ := hA
obtain ⟨b, hb⟩ := hB
have hpos : (0 : ℝ) < finiteDifferenceCount A B (a - b) := by
exact_mod_cast (Finset.card_pos.mpr
⟨(a, b), Finset.mem_filter.mpr ⟨Finset.mem_product.mpr ⟨ha, hb⟩, rfl⟩⟩ :
0 < (finiteDifferenceFiber A B (a - b)).card)
exact ⟨a - b, Finset.mem_univ _, mul_lt_mul_of_pos_left (hn _) hpos⟩
theorem finite_energy_dense_overlap {A B : Finset G} {K : ℝ}
(hA : A.Nonempty) (hB : B.Nonempty) (hK : 0 < K)
(hE : (A.card : ℝ) ^ 2 * (B.card : ℝ) ≤ K * (Finset.addEnergy A B : ℝ)) :
∃ s : G, (A.card : ℝ) / (2 * K) ≤ ((finiteShiftOverlap A B s).card : ℝ) ∧
(7 / 8 : ℝ) * ((finiteShiftOverlap A B s).card : ℝ) ^ 2 ≤
(((finiteShiftOverlap A B s ×ˢ finiteShiftOverlap A B s).filter
(fun p => (A.card : ℝ) ≤ 16 * K ^ 2 *
(finiteDifferenceCount B B (p.1 - p.2) : ℝ))).card : ℝ) := by
classical
let P := fun p : G × G => (A.card : ℝ) ≤
16 * K ^ 2 * (finiteDifferenceCount B B (p.1 - p.2) : ℝ)
let H := (A ×ˢ A).filter (fun p => ¬ P p)
have hbad : ∀ p ∈ H, 16 * K ^ 2 * (finiteDifferenceCount B B (p.1 - p.2) : ℝ) ≤ A.card := by
intro p hp
exact (lt_of_not_ge (Finset.mem_filter.mp hp).2).le
obtain ⟨s, hs⟩ := finite_exists_good_shift hA hB hK.le
(by rwa [finite_difference_energy_eq_addEnergy]) (Finset.filter_subset _ _) hbad
let X := finiteShiftOverlap A B s
have hbadEq : finiteShiftPairCount B H s = ((X ×ˢ X).filter (fun p => ¬ P p)).card := by
unfold finiteShiftPairCount
congr 1
ext p
simp only [H, X, finiteShiftOverlap, Finset.mem_filter, Finset.mem_product]
aesop
have hpart : (((X ×ˢ X).filter P).card : ℝ) + (finiteShiftPairCount B H s : ℝ) = (X.card : ℝ) ^ 2 := by
rw [hbadEq]
exact_mod_cast (Finset.card_filter_add_card_filter_not (s := X ×ˢ X) P).trans
(by simp [pow_two])
have hs' : (A.card : ℝ) ^ 2 ≤ 2 * K ^ 2 * (X.card : ℝ) ^ 2 :=
(le_add_of_nonneg_right (by positivity)).trans hs
have hsize : (A.card : ℝ) ≤ 2 * K * (X.card : ℝ) := by
apply (sq_le_sq₀ (Nat.cast_nonneg _) (by positivity)).mp
nlinarith [sq_nonneg (K * (X.card : ℝ))]
have hbadSmall : 8 * (finiteShiftPairCount B H s : ℝ) ≤ (X.card : ℝ) ^ 2 := by
apply (mul_le_mul_iff_left₀ (show 0 < 2 * K ^ 2 by positivity)).mp
nlinarith [sq_nonneg (A.card : ℝ)]
refine ⟨s, (div_le_iff₀ (by positivity)).mpr (by nlinarith [hsize]), ?_⟩
change (7 / 8 : ℝ) * (X.card : ℝ) ^ 2 ≤ (((X ×ˢ X).filter P).card : ℝ)
nlinarith
def finiteGraphRow (X : Finset G) (H : Finset (G × G)) (a : G) : Finset G :=
X.filter (fun b => (a, b) ∈ H)
noncomputable def finiteGraphCore (X : Finset G) (H : Finset (G × G)) : Finset G := by
classical
exact X.filter (fun a => (3 / 4 : ℝ) * (X.card : ℝ) ≤ (finiteGraphRow X H a).card)
theorem finite_graph_row_fiber {X : Finset G} {H : Finset (G × G)}
(hH : H ⊆ X ×ˢ X) (a : G) :
(H.filter (fun p => p.1 = a)).card = (finiteGraphRow X H a).card := by
apply Finset.card_bij (fun p _ => p.2)
· intro p hp
obtain ⟨hpH, hpa⟩ := Finset.mem_filter.mp hp
exact Finset.mem_filter.mpr ⟨(Finset.mem_product.mp (hH hpH)).2, by simpa only [← hpa] using hpH⟩
· intro p hp q hq hpq
exact Prod.ext ((Finset.mem_filter.mp hp).2.trans (Finset.mem_filter.mp hq).2.symm) hpq
· intro b hb
exact ⟨(a, b), Finset.mem_filter.mpr ⟨(Finset.mem_filter.mp hb).2, rfl⟩, rfl⟩
theorem finite_graph_row_sum {X : Finset G} {H : Finset (G × G)}
(hH : H ⊆ X ×ˢ X) :
∑ a ∈ X, (finiteGraphRow X H a).card = H.card := by
simp_rw [← finite_graph_row_fiber hH]
exact (Finset.card_eq_sum_card_fiberwise (f := Prod.fst)
(fun _ hp => (Finset.mem_product.mp (hH hp)).1)).symm
theorem finite_graph_core_card {X : Finset G} {H : Finset (G × G)}
(hH : H ⊆ X ×ˢ X) (hdense : (7 / 8 : ℝ) * (X.card : ℝ) ^ 2 ≤ H.card) :
(X.card : ℝ) / 8 ≤ (finiteGraphCore X H).card := by
classical
let C := finiteGraphCore X H
have hCX : C ⊆ X := Finset.filter_subset _ _
have hrow : ∀ a ∈ X, ((finiteGraphRow X H a).card : ℝ) ≤
(3 / 4 : ℝ) * (X.card : ℝ) + if a ∈ C then (X.card : ℝ) else 0 := by
intro a ha
by_cases hc : a ∈ C
· rw [if_pos hc]
have hh : ((finiteGraphRow X H a).card : ℝ) ≤ X.card := by
exact_mod_cast Finset.card_le_card (Finset.filter_subset _ _)
nlinarith [show (0 : ℝ) ≤ X.card from Nat.cast_nonneg _]
· rw [if_neg hc, add_zero]
have hn : ¬ (3 / 4 : ℝ) * (X.card : ℝ) ≤ (finiteGraphRow X H a).card := by
intro hh
exact hc (Finset.mem_filter.mpr ⟨ha, hh⟩)
exact (lt_of_not_ge hn).le
have hbound : (H.card : ℝ) ≤ (3 / 4 : ℝ) * (X.card : ℝ) ^ 2 + (C.card : ℝ) * (X.card : ℝ) := by
calc
_ = ∑ a ∈ X, ((finiteGraphRow X H a).card : ℝ) := by
exact_mod_cast (finite_graph_row_sum hH).symm
_ ≤ ∑ a ∈ X, ((3 / 4 : ℝ) * (X.card : ℝ) + if a ∈ C then (X.card : ℝ) else 0) :=
Finset.sum_le_sum hrow
_ = _ := by
rw [Finset.sum_add_distrib, ← Finset.sum_filter, Finset.filter_mem_eq_inter,
Finset.inter_eq_right.mpr hCX]
simp only [Finset.sum_const, nsmul_eq_mul]
ring
by_cases hX : X.card = 0
· simp only [hX, Nat.cast_zero, zero_div]
positivity
· have hXp : (0 : ℝ) < X.card := by exact_mod_cast Nat.pos_of_ne_zero hX
apply (mul_le_mul_iff_left₀ hXp).mp
nlinarith
theorem finite_graph_core_common {X : Finset G} {H : Finset (G × G)} {a b : G}
(ha : a ∈ finiteGraphCore X H) (hb : b ∈ finiteGraphCore X H) :
(X.card : ℝ) / 2 ≤ ((finiteGraphRow X H a ∩ finiteGraphRow X H b).card : ℝ) := by
have ha' := (Finset.mem_filter.mp ha).2
have hb' := (Finset.mem_filter.mp hb).2
have hu : (finiteGraphRow X H a ∪ finiteGraphRow X H b) ⊆ X :=
Finset.union_subset (Finset.filter_subset _ _) (Finset.filter_subset _ _)
have huc : ((finiteGraphRow X H a ∪ finiteGraphRow X H b).card : ℝ) ≤ X.card := by
exact_mod_cast Finset.card_le_card hu
have hh : ((finiteGraphRow X H a ∪ finiteGraphRow X H b).card : ℝ) +
((finiteGraphRow X H a ∩ finiteGraphRow X H b).card : ℝ) =
((finiteGraphRow X H a).card : ℝ) + ((finiteGraphRow X H b).card : ℝ) := by
exact_mod_cast Finset.card_union_add_card_inter (finiteGraphRow X H a) (finiteGraphRow X H b)
nlinarith
def finiteQuadDifferenceFiber (B : Finset G) (x : G) : Finset ((G × G) × (G × G)) :=
((B ×ˢ B) ×ˢ (B ×ˢ B)).filter (fun p => (p.1.1 - p.1.2) - (p.2.1 - p.2.2) = x)
theorem finite_quad_difference_sum (B : Finset G) :
∑ x : G, (finiteQuadDifferenceFiber B x).card = B.card ^ 4 := by
unfold finiteQuadDifferenceFiber
calc
_ = ((B ×ˢ B) ×ˢ (B ×ˢ B)).card :=
(Finset.card_eq_sum_card_fiberwise
(f := fun p : (G × G) × (G × G) => (p.1.1 - p.1.2) - (p.2.1 - p.2.2))
(t := Finset.univ) (fun _ _ => Finset.mem_univ _)).symm
_ = _ := by simp only [Finset.card_product]; ring
theorem finite_common_neighbors_inject_quad (B C : Finset G) (a b : G) :
(C.sigma (fun c => finiteDifferenceFiber B B (a - c) ×ˢ finiteDifferenceFiber B B (b - c))).card ≤
(finiteQuadDifferenceFiber B (a - b)).card := by
apply Finset.card_le_card_of_injOn (fun p : Σ _c : G, (G × G) × (G × G) => p.2)
· intro p hp
obtain ⟨hc, hp'⟩ := Finset.mem_sigma.mp hp
obtain ⟨hu, hv⟩ := Finset.mem_product.mp hp'
obtain ⟨huB, hue⟩ := Finset.mem_filter.mp hu
obtain ⟨hvB, hve⟩ := Finset.mem_filter.mp hv
exact Finset.mem_filter.mpr ⟨Finset.mem_product.mpr ⟨huB, hvB⟩,
by rw [hue, hve, sub_sub_sub_cancel_right]⟩
· intro p hp q hq hpq
dsimp only at hpq
have hp₁ := (Finset.mem_filter.mp (Finset.mem_product.mp (Finset.mem_sigma.mp hp).2).1).2
have hq₁ := (Finset.mem_filter.mp (Finset.mem_product.mp (Finset.mem_sigma.mp hq).2).1).2
have heq : a - p.1 = a - q.1 := by
rw [← hp₁, ← hq₁, hpq]
have hpq₁ : p.1 = q.1 := sub_right_injective heq
exact Sigma.ext hpq₁ (heq_of_eq hpq)
theorem finite_graph_core_quad_lower {X B : Finset G} {H : Finset (G × G)} {a b : G} {L : ℝ}
(hL : 0 ≤ L) (ha : a ∈ finiteGraphCore X H) (hb : b ∈ finiteGraphCore X H)
(hrep : ∀ p ∈ H, L ≤ (finiteDifferenceCount B B (p.1 - p.2) : ℝ)) :
(X.card : ℝ) / 2 * L ^ 2 ≤ (finiteQuadDifferenceFiber B (a - b)).card := by
let C := finiteGraphRow X H a ∩ finiteGraphRow X H b
calc
_ ≤ (C.card : ℝ) * L ^ 2 :=
mul_le_mul_of_nonneg_right (finite_graph_core_common ha hb) (sq_nonneg L)
_ = ∑ _c ∈ C, L ^ 2 := by simp
_ ≤ ∑ c ∈ C, ((finiteDifferenceFiber B B (a - c) ×ˢ finiteDifferenceFiber B B (b - c)).card : ℝ) := by
apply Finset.sum_le_sum
intro c hc
obtain ⟨hca, hcb⟩ := Finset.mem_inter.mp hc
have h₁ := hrep (a, c) (Finset.mem_filter.mp hca).2
have h₂ := hrep (b, c) (Finset.mem_filter.mp hcb).2
simpa only [Finset.card_product, Nat.cast_mul, pow_two, finiteDifferenceCount] using
mul_le_mul h₁ h₂ hL (Nat.cast_nonneg _)
_ = ((C.sigma (fun c => finiteDifferenceFiber B B (a - c) ×ˢ finiteDifferenceFiber B B (b - c))).card : ℝ) := by
rw [Finset.card_sigma, Nat.cast_sum]
_ ≤ _ := by exact_mod_cast finite_common_neighbors_inject_quad B C a b
theorem finite_graph_core_difference_bound {X B : Finset G} {H : Finset (G × G)} {L : ℝ}
(hL : 0 ≤ L)
(hrep : ∀ p ∈ H, L ≤ (finiteDifferenceCount B B (p.1 - p.2) : ℝ)) :
((finiteGraphCore X H - finiteGraphCore X H).card : ℝ) * ((X.card : ℝ) / 2 * L ^ 2) ≤
(B.card : ℝ) ^ 4 := by
let C := finiteGraphCore X H
calc
_ = ∑ _x ∈ C - C, (X.card : ℝ) / 2 * L ^ 2 := by simp [C]
_ ≤ ∑ x ∈ C - C, ((finiteQuadDifferenceFiber B x).card : ℝ) := by
apply Finset.sum_le_sum
intro x hx
obtain ⟨a, ha, b, hb, rfl⟩ := Finset.mem_sub.mp hx
exact finite_graph_core_quad_lower hL ha hb hrep
_ ≤ ∑ x : G, ((finiteQuadDifferenceFiber B x).card : ℝ) :=
Finset.sum_le_sum_of_subset_of_nonneg (Finset.subset_univ _) (fun _ _ _ => Nat.cast_nonneg _)
_ = _ := by exact_mod_cast finite_quad_difference_sum B
/-- A quantitative inverse-energy theorem for two sets in any finite abelian group.
The extracted set lies in a translate overlap and has a controlled difference set. -/
theorem finite_bsg_overlap {A B : Finset G} {K : ℝ}
(hA : A.Nonempty) (hB : B.Nonempty) (hK : 0 < K)
(hE : (A.card : ℝ) ^ 2 * (B.card : ℝ) ≤ K * (Finset.addEnergy A B : ℝ)) :
∃ s : G, ∃ C : Finset G, C ⊆ finiteShiftOverlap A B s ∧
(A.card : ℝ) ≤ 16 * K * (C.card : ℝ) ∧
(A.card : ℝ) ^ 3 * ((C - C).card : ℝ) ≤ 1024 * K ^ 5 * (B.card : ℝ) ^ 4 := by
classical
obtain ⟨s, hlarge, hdense⟩ := finite_energy_dense_overlap hA hB hK hE
let X := finiteShiftOverlap A B s
let H := (X ×ˢ X).filter (fun p => (A.card : ℝ) ≤
16 * K ^ 2 * (finiteDifferenceCount B B (p.1 - p.2) : ℝ))
let C := finiteGraphCore X H
have hH : H ⊆ X ×ˢ X := Finset.filter_subset _ _
have hcore : (X.card : ℝ) / 8 ≤ (C.card : ℝ) := finite_graph_core_card hH hdense
have hrep : ∀ p ∈ H, (A.card : ℝ) / (16 * K ^ 2) ≤
(finiteDifferenceCount B B (p.1 - p.2) : ℝ) := by
intro p hp
exact (div_le_iff₀ (by positivity)).mpr (by
simpa only [mul_comm] using (Finset.mem_filter.mp hp).2)
have hdiff := finite_graph_core_difference_bound
(X := X) (B := B) (H := H) (by positivity : (0 : ℝ) ≤ (A.card : ℝ) / (16 * K ^ 2)) hrep
have hpref : (A.card : ℝ) ^ 3 / (1024 * K ^ 5) ≤
(X.card : ℝ) / 2 * ((A.card : ℝ) / (16 * K ^ 2)) ^ 2 := by
calc
_ = ((A.card : ℝ) / (2 * K)) / 2 * ((A.card : ℝ) / (16 * K ^ 2)) ^ 2 := by
field_simp
ring
_ ≤ _ := mul_le_mul_of_nonneg_right (div_le_div_of_nonneg_right hlarge (by norm_num)) (by positivity)
have hdiff' : ((C - C).card : ℝ) * ((A.card : ℝ) ^ 3 / (1024 * K ^ 5)) ≤ (B.card : ℝ) ^ 4 :=
(mul_le_mul_of_nonneg_left hpref (Nat.cast_nonneg _)).trans hdiff
refine ⟨s, C, Finset.filter_subset _ _, ?_, ?_⟩
· have hh : (A.card : ℝ) / (16 * K) ≤ (C.card : ℝ) := by
calc
_ = ((A.card : ℝ) / (2 * K)) / 8 := by ring
_ ≤ (X.card : ℝ) / 8 := div_le_div_of_nonneg_right hlarge (by norm_num)
_ ≤ _ := hcore
have hh' := (div_le_iff₀ (show 0 < 16 * K by positivity)).mp hh
nlinarith
· rw [← mul_div_assoc] at hdiff'
have hh := (div_le_iff₀ (show 0 < 1024 * K ^ 5 by positivity)).mp hdiff'
nlinarith
/-- Self-energy at least `|A|³/K` yields a subset of size at least `|A|/(16K)`
whose difference set is bounded by an explicit power of `K`. -/
theorem finite_bsg_self {A : Finset G} {K : ℝ}
(hA : A.Nonempty) (hK : 0 < K)
(hE : (A.card : ℝ) ^ 3 ≤ K * (Finset.addEnergy A A : ℝ)) :
∃ C : Finset G, C ⊆ A ∧ C.Nonempty ∧
(A.card : ℝ) ≤ 16 * K * (C.card : ℝ) ∧
((C - C).card : ℝ) ≤ 16384 * K ^ 6 * (C.card : ℝ) := by
obtain ⟨s, C, hCA, hsize, hdiff⟩ := finite_bsg_overlap hA hA hK (by nlinarith [hE])
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hCp : (0 : ℝ) < C.card := by
by_contra hn
have hc : (C.card : ℝ) = 0 := le_antisymm (le_of_not_gt hn) (Nat.cast_nonneg _)
rw [hc, mul_zero] at hsize
exact not_le_of_gt hAp hsize
refine ⟨C, hCA.trans (Finset.filter_subset _ _), by exact_mod_cast Finset.card_pos.mp (show 0 < C.card by exact_mod_cast hCp), hsize, ?_⟩
have hdiff' : ((C - C).card : ℝ) ≤ 1024 * K ^ 5 * (A.card : ℝ) := by
apply (mul_le_mul_iff_right₀ (show (0 : ℝ) < (A.card : ℝ) ^ 3 by positivity)).mp
calc
_ ≤ 1024 * K ^ 5 * (A.card : ℝ) ^ 4 := hdiff
_ = _ := by ring
calc
_ ≤ 1024 * K ^ 5 * (A.card : ℝ) := hdiff'
_ ≤ 1024 * K ^ 5 * (16 * K * (C.card : ℝ)) :=
mul_le_mul_of_nonneg_left hsize (by positivity)
_ = _ := by ring
theorem finite_sub_translated_image (C : Finset G) (s : G) :
C - C.image (fun x => x - s) = (C - C).image (fun x => x + s) := by
ext z
constructor
· intro hz
obtain ⟨a, ha, y, hy, rfl⟩ := Finset.mem_sub.mp hz
obtain ⟨b, hb, rfl⟩ := Finset.mem_image.mp hy
exact Finset.mem_image.mpr ⟨a - b, Finset.mem_sub.mpr ⟨a, ha, b, hb, rfl⟩, by
simp only [sub_eq_add_neg, neg_add_rev, neg_neg]
abel⟩
· intro hz
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨a, ha, b, hb, rfl⟩ := Finset.mem_sub.mp hx
exact Finset.mem_sub.mpr ⟨a, ha, b - s, Finset.mem_image_of_mem _ hb, by
simp only [sub_eq_add_neg, neg_add_rev, neg_neg]
abel⟩
/-- Two subsets of equal cardinality with a controlled mixed difference set. -/
theorem finite_bsg_two_sets {A B : Finset G} {K : ℝ}
(hA : A.Nonempty) (hB : B.Nonempty) (hK : 0 < K)
(hE : (A.card : ℝ) ^ 2 * (B.card : ℝ) ≤ K * (Finset.addEnergy A B : ℝ)) :
∃ C D : Finset G, C ⊆ A ∧ D ⊆ B ∧ C.Nonempty ∧ D.card = C.card ∧
(A.card : ℝ) ≤ 16 * K * (C.card : ℝ) ∧
(A.card : ℝ) ^ 3 * ((C - D).card : ℝ) ≤ 1024 * K ^ 5 * (B.card : ℝ) ^ 4 := by
obtain ⟨s, C, hC, hsize, hdiff⟩ := finite_bsg_overlap hA hB hK hE
let D := C.image (fun x => x - s)
have hDB : D ⊆ B := by
intro d hd
obtain ⟨c, hc, rfl⟩ := Finset.mem_image.mp hd
exact (Finset.mem_filter.mp (hC hc)).2
have hDcard : D.card = C.card := Finset.card_image_of_injective C (fun _ _ h => sub_left_injective h)
have hdiffcard : (C - D).card = (C - C).card := by
dsimp only [D]
rw [finite_sub_translated_image, Finset.card_image_of_injective _ (fun _ _ h => add_right_cancel h)]
have hCp : (0 : ℝ) < C.card := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
by_contra hn
have hc : (C.card : ℝ) = 0 := le_antisymm (le_of_not_gt hn) (Nat.cast_nonneg _)
rw [hc, mul_zero] at hsize
exact not_le_of_gt hAp hsize
refine ⟨C, D, hC.trans (Finset.filter_subset _ _), hDB,
Finset.card_pos.mp (by exact_mod_cast hCp), hDcard, hsize, ?_⟩
simpa only [hdiffcard] using hdiff
end FiniteInverseEnergy
noncomputable def cyclicSetIndicator {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (x : ZMod q) : ℂ := if x ∈ A then 1 else 0
theorem finite_sum_fiber_card {G : Type*} [AddCommGroup G] [DecidableEq G]
(A B : Finset G) (x : G) :
((A ×ˢ B).filter (fun p => p.1 + p.2 = x)).card =
(A.filter (fun a => x - a ∈ B)).card := by
apply Finset.card_bij (fun p _ => p.1)
· intro p hp
obtain ⟨hpAB, heq⟩ := Finset.mem_filter.mp hp
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hpAB
exact Finset.mem_filter.mpr ⟨ha, by simpa only [← heq, add_sub_cancel_left] using hb⟩
· intro p hp q hq hpq
apply Prod.ext hpq
have hh := (Finset.mem_filter.mp hp).2.trans (Finset.mem_filter.mp hq).2.symm
simpa only [hpq, add_left_cancel_iff] using hh
· intro a ha
obtain ⟨haA, haB⟩ := Finset.mem_filter.mp ha
exact ⟨(a, x - a), Finset.mem_filter.mpr
⟨Finset.mem_product.mpr ⟨haA, haB⟩, add_sub_cancel a x⟩, rfl⟩
theorem cyclic_set_indicator_convolution {q : ℕ} [NeZero q]
(A B : Finset (ZMod q)) (x : ZMod q) :
cyclicConvolution (cyclicSetIndicator A) (cyclicSetIndicator B) x =
(((A ×ˢ B).filter (fun p => p.1 + p.2 = x)).card : ℂ) := by
classical
rw [finite_sum_fiber_card]
simp only [cyclicConvolution, cyclicSetIndicator, ite_mul, one_mul, zero_mul,
← Finset.sum_filter, Finset.filter_mem_eq_inter, Finset.univ_inter,
Finset.sum_const, nsmul_eq_mul, mul_one]
theorem cyclic_set_convolution_energy {q : ℕ} [NeZero q] (A B : Finset (ZMod q)) :
(∑ x : ZMod q, ‖cyclicConvolution (cyclicSetIndicator A) (cyclicSetIndicator B) x‖ ^ 2) =
(Finset.addEnergy A B : ℝ) := by
simp_rw [cyclic_set_indicator_convolution, Complex.norm_natCast]
exact_mod_cast (Finset.addEnergy_eq_sum_sq A B).symm
theorem cyclic_set_fourier_energy {q : ℕ} [NeZero q] (A B : Finset (ZMod q)) :
(∑ k : ZMod q, ‖ZMod.dft (cyclicSetIndicator A) k‖ ^ 2 *
‖ZMod.dft (cyclicSetIndicator B) k‖ ^ 2) = (q : ℝ) * (Finset.addEnergy A B : ℝ) := by
have hh := dft_parseval (cyclicConvolution (cyclicSetIndicator A) (cyclicSetIndicator B))
simpa only [dft_cyclicConvolution, norm_mul, mul_pow, cyclic_set_convolution_energy] using hh
theorem cyclic_large_fourier_energy_subset {q : ℕ} [NeZero q]
{A : Finset (ZMod q)} {K : ℝ} (hA : A.Nonempty) (hK : 0 < K)
(hFourier : (q : ℝ) * (A.card : ℝ) ^ 3 ≤
K * ∑ k : ZMod q, ‖ZMod.dft (cyclicSetIndicator A) k‖ ^ 4) :
∃ C : Finset (ZMod q), C ⊆ A ∧ C.Nonempty ∧
(A.card : ℝ) ≤ 16 * K * (C.card : ℝ) ∧
((C - C).card : ℝ) ≤ 16384 * K ^ 6 * (C.card : ℝ) := by
apply finite_bsg_self hA hK
have hsum : (∑ k : ZMod q, ‖ZMod.dft (cyclicSetIndicator A) k‖ ^ 4) =
(q : ℝ) * (Finset.addEnergy A A : ℝ) := by
convert cyclic_set_fourier_energy A A using 1
apply Finset.sum_congr rfl
intro k hk
ring
rw [hsum] at hFourier
have hq : (0 : ℝ) < q := by exact_mod_cast NeZero.pos q
apply (mul_le_mul_iff_right₀ hq).mp
simpa only [mul_left_comm K (q : ℝ)] using hFourier
/- Common intersections and Ruzsa bounds for assembling inverse-energy subsets. -/
theorem finite_sub_card_comm {G : Type*} [AddCommGroup G] [DecidableEq G]
(A B : Finset G) : (A - B).card = (B - A).card := by
apply Finset.card_bij (fun x _ => -x)
· intro x hx
obtain ⟨a, ha, b, hb, rfl⟩ := Finset.mem_sub.mp hx
exact Finset.mem_sub.mpr ⟨b, hb, a, ha, (neg_sub a b).symm⟩
· intro x hx y hy hxy
exact neg_injective hxy
· intro y hy
obtain ⟨b, hb, a, ha, rfl⟩ := Finset.mem_sub.mp hy
exact ⟨a - b, Finset.mem_sub.mpr ⟨a, ha, b, hb, rfl⟩, neg_sub a b⟩
theorem finite_sum_card_common_difference {G : Type*} [AddCommGroup G] [DecidableEq G]
(X Y U V : Finset G) :
(U + V).card * (X ∩ Y).card ≤ (X - U).card * (Y - V).card := by
have hh := Finset.ruzsa_triangle_inequality_add_add_add U (-(X ∩ Y)) V
have h₁ : (U + -(X ∩ Y)).card ≤ (X - U).card := by
rw [← sub_eq_add_neg, finite_sub_card_comm]
exact Finset.card_le_card (Finset.sub_subset_sub_right Finset.inter_subset_left)
have h₂ : (-(X ∩ Y) + V).card ≤ (Y - V).card := by
rw [add_comm, ← sub_eq_add_neg, finite_sub_card_comm]
exact Finset.card_le_card (Finset.sub_subset_sub_right Finset.inter_subset_right)
simp only [Finset.card_neg] at hh
exact hh.trans (Nat.mul_le_mul h₁ h₂)
theorem finite_sum_card_common_middle {G : Type*} [AddCommGroup G] [DecidableEq G]
(U V W : Finset G) :
(U + W).card * (V ∩ W).card ≤ (U + V).card * (W + W).card := by
have hh := Finset.ruzsa_triangle_inequality_add_add_add U (V ∩ W) W
apply hh.trans
apply Nat.mul_le_mul
· exact Finset.card_le_card (Finset.add_subset_add_left Finset.inter_subset_left)
· exact Finset.card_le_card (Finset.add_subset_add_right Finset.inter_subset_right)
theorem finite_common_structure_card_bound {G : Type*} [AddCommGroup G] [DecidableEq G]
(X Y U V W : Finset G) (hdouble : (W + W).card = (U + U).card) :
(U + W).card * (V ∩ W).card * (X ∩ Y).card * X.card ≤
(X - U).card ^ 3 * (Y - V).card := by
have hcross := finite_sum_card_common_difference X Y U V
have hself : (U + U).card * X.card ≤ (X - U).card ^ 2 := by
simpa only [Finset.inter_self, pow_two] using finite_sum_card_common_difference X X U U
calc
_ ≤ ((U + V).card * (W + W).card) * (X ∩ Y).card * X.card :=
Nat.mul_le_mul_right _ (Nat.mul_le_mul_right _ (finite_sum_card_common_middle U V W))
_ = ((U + V).card * (X ∩ Y).card) * ((U + U).card * X.card) := by rw [hdouble]; ring
_ ≤ ((X - U).card * (Y - V).card) * (X - U).card ^ 2 := Nat.mul_le_mul hcross hself
_ = _ := by ring
theorem finite_family_incidence_sum {α ι : Type*} [DecidableEq α] [DecidableEq ι]
(I : Finset ι) (S : Finset α) (F : ι → Finset α)
(hF : ∀ i ∈ I, F i ⊆ S) :
(∑ x ∈ S, (I.filter (fun i => x ∈ F i)).card) = ∑ i ∈ I, (F i).card := by
classical
calc
_ = ∑ i ∈ I, (S.filter (fun x => x ∈ F i)).card := by
simp only [Finset.card_eq_sum_ones, Finset.sum_filter]
exact Finset.sum_comm
_ = _ := Finset.sum_congr rfl (fun i hi => by
rw [Finset.filter_mem_eq_inter, Finset.inter_eq_right.mpr (hF i hi)])
theorem finite_family_intersection_moment {α ι : Type*} [DecidableEq α] [DecidableEq ι]
(I : Finset ι) (S : Finset α) (F : ι → Finset α)
(hF : ∀ i ∈ I, F i ⊆ S) :
(∑ i ∈ I, ∑ j ∈ I, (F i ∩ F j).card) =
∑ x ∈ S, (I.filter (fun i => x ∈ F i)).card ^ 2 := by
classical
let f := fun x i => if x ∈ F i then (1 : ℕ) else 0
have hinter (i j : ι) (hi : i ∈ I) :
(F i ∩ F j).card = ∑ x ∈ S, f x i * f x j := by
have heq : S.filter (fun x => x ∈ F i ∧ x ∈ F j) = F i ∩ F j := by
ext x
simp only [Finset.mem_filter, Finset.mem_inter]
exact ⟨fun h => h.2, fun h => ⟨hF i hi h.1, h⟩⟩
rw [← heq, Finset.card_eq_sum_ones, Finset.sum_filter]
apply Finset.sum_congr rfl
intro x hx
simp only [f]
split_ifs <;> simp_all
calc
_ = ∑ i ∈ I, ∑ j ∈ I, ∑ x ∈ S, f x i * f x j := by
apply Finset.sum_congr rfl
intro i hi
exact Finset.sum_congr rfl (fun j hj => hinter i j hi)
_ = ∑ i ∈ I, ∑ x ∈ S, ∑ j ∈ I, f x i * f x j := by
apply Finset.sum_congr rfl
intro i hi
exact Finset.sum_comm
_ = ∑ x ∈ S, ∑ i ∈ I, ∑ j ∈ I, f x i * f x j := Finset.sum_comm
_ = _ := by
apply Finset.sum_congr rfl
intro x hx
rw [← Finset.sum_mul_sum]
simp only [f, Finset.card_eq_sum_ones, Finset.sum_filter, pow_two]
theorem finite_family_intersection_lower {α ι : Type*} [DecidableEq α] [DecidableEq ι]
{I : Finset ι} {S : Finset α} {F : ι → Finset α} {δ : ℝ}
(hS : S.Nonempty) (hδ : 0 ≤ δ) (hF : ∀ i ∈ I, F i ⊆ S)
(hlarge : ∀ i ∈ I, δ * (S.card : ℝ) ≤ (F i).card) :
δ ^ 2 * (I.card : ℝ) ^ 2 * (S.card : ℝ) ≤
∑ i ∈ I, ∑ j ∈ I, ((F i ∩ F j).card : ℝ) := by
classical
have hsum : δ * (I.card : ℝ) * (S.card : ℝ) ≤ ∑ i ∈ I, ((F i).card : ℝ) := by
calc
_ = ∑ _i ∈ I, δ * (S.card : ℝ) := by simp; ring
_ ≤ _ := Finset.sum_le_sum hlarge
have hsum' : δ * (I.card : ℝ) * (S.card : ℝ) ≤
∑ x ∈ S, ((I.filter (fun i => x ∈ F i)).card : ℝ) := by
have heq : (∑ x ∈ S, ((I.filter (fun i => x ∈ F i)).card : ℝ)) =
∑ i ∈ I, ((F i).card : ℝ) := by exact_mod_cast finite_family_incidence_sum I S F hF
rwa [heq]
have hsq := pow_le_pow_left₀ (by positivity : (0 : ℝ) ≤ δ * I.card * S.card) hsum' 2
have hc := Finset.sum_mul_sq_le_sq_mul_sq S (fun _ => (1 : ℝ))
(fun x => ((I.filter (fun i => x ∈ F i)).card : ℝ))
simp only [one_mul, one_pow, Finset.sum_const, nsmul_eq_mul, mul_one] at hc
have hm : (∑ x ∈ S, ((I.filter (fun i => x ∈ F i)).card : ℝ) ^ 2) =
∑ i ∈ I, ∑ j ∈ I, ((F i ∩ F j).card : ℝ) := by
exact_mod_cast (finite_family_intersection_moment I S F hF).symm
rw [hm] at hc
have hSp : (0 : ℝ) < S.card := by exact_mod_cast hS.card_pos
apply (mul_le_mul_iff_right₀ hSp).mp
calc
_ = (δ * (I.card : ℝ) * (S.card : ℝ)) ^ 2 := by ring
_ ≤ _ := hsq.trans hc
theorem finite_family_large_intersections {α ι : Type*} [DecidableEq α] [DecidableEq ι]
{I : Finset ι} {S : Finset α} {F : ι → Finset α} {δ : ℝ}
(hI : I.Nonempty) (hS : S.Nonempty) (hδ : 0 ≤ δ) (hF : ∀ i ∈ I, F i ⊆ S)
(hlarge : ∀ i ∈ I, δ * (S.card : ℝ) ≤ (F i).card) :
∃ i ∈ I, δ ^ 2 / 2 * (I.card : ℝ) ≤
((I.filter (fun j => δ ^ 2 / 2 * (S.card : ℝ) ≤ ((F i ∩ F j).card : ℝ))).card : ℝ) := by
classical
have htotal := finite_family_intersection_lower hS hδ hF hlarge
have hex : ∃ i ∈ I, δ ^ 2 * (I.card : ℝ) * (S.card : ℝ) ≤
∑ j ∈ I, ((F i ∩ F j).card : ℝ) := by
by_contra! hn
have hh : (∑ i ∈ I, ∑ j ∈ I, ((F i ∩ F j).card : ℝ)) <
∑ _i ∈ I, δ ^ 2 * (I.card : ℝ) * (S.card : ℝ) := by
apply Finset.sum_lt_sum
· intro i hi
exact (hn i hi).le
· obtain ⟨i, hi⟩ := hI
exact ⟨i, hi, hn i hi⟩
have heq : (∑ _i ∈ I, δ ^ 2 * (I.card : ℝ) * (S.card : ℝ)) =
δ ^ 2 * (I.card : ℝ) ^ 2 * (S.card : ℝ) := by simp; ring
rw [heq] at hh
exact not_lt_of_ge htotal hh
obtain ⟨i, hi, hrow⟩ := hex
let C := I.filter (fun j => δ ^ 2 / 2 * (S.card : ℝ) ≤ ((F i ∩ F j).card : ℝ))
have hpoint : ∀ j ∈ I, ((F i ∩ F j).card : ℝ) ≤
δ ^ 2 / 2 * (S.card : ℝ) + if j ∈ C then (S.card : ℝ) else 0 := by
intro j hj
by_cases hc : j ∈ C
· rw [if_pos hc]
have hcard : ((F i ∩ F j).card : ℝ) ≤ S.card := by
exact_mod_cast Finset.card_le_card ((Finset.inter_subset_left).trans (hF i hi))
have hnonneg : 0 ≤ δ ^ 2 / 2 * (S.card : ℝ) := by positivity
linarith
· rw [if_neg hc, add_zero]
have hn : ¬ δ ^ 2 / 2 * (S.card : ℝ) ≤ ((F i ∩ F j).card : ℝ) := by
intro hh
exact hc (Finset.mem_filter.mpr ⟨hj, hh⟩)
exact (lt_of_not_ge hn).le
have hbound : (∑ j ∈ I, ((F i ∩ F j).card : ℝ)) ≤
(I.card : ℝ) * (δ ^ 2 / 2 * (S.card : ℝ)) + (C.card : ℝ) * (S.card : ℝ) := by
calc
_ ≤ ∑ j ∈ I, (δ ^ 2 / 2 * (S.card : ℝ) + if j ∈ C then (S.card : ℝ) else 0) :=
Finset.sum_le_sum hpoint
_ = _ := by
rw [Finset.sum_add_distrib, ← Finset.sum_filter, Finset.filter_mem_eq_inter,
Finset.inter_eq_right.mpr (Finset.filter_subset _ _)]
simp [C]
refine ⟨i, hi, ?_⟩
have hSp : (0 : ℝ) < S.card := by exact_mod_cast hS.card_pos
apply (mul_le_mul_iff_left₀ hSp).mp
change δ ^ 2 / 2 * (I.card : ℝ) * (S.card : ℝ) ≤ (C.card : ℝ) * (S.card : ℝ)
nlinarith
theorem finite_common_structure_quantitative {G : Type*} [AddCommGroup G] [DecidableEq G]
{X Y U V W : Finset G} {a α δ M : ℝ}
(ha : 0 < a) (hα : 0 < α) (hδ : 0 < δ) (hM : 0 ≤ M)
(hX : α * a ≤ (X.card : ℝ)) (hU : α * a ≤ (U.card : ℝ))
(hXY : δ * a ≤ ((X ∩ Y).card : ℝ)) (hVW : δ * a ≤ ((V ∩ W).card : ℝ))
(hXU : ((X - U).card : ℝ) ≤ M * a) (hYV : ((Y - V).card : ℝ) ≤ M * a)
(hdouble : (W + W).card = (U + U).card) :
((U + W).card : ℝ) ≤ M ^ 4 / (α ^ 2 * δ ^ 2) * (U.card : ℝ) := by
have hc : ((U + W).card : ℝ) * ((V ∩ W).card : ℝ) * ((X ∩ Y).card : ℝ) * (X.card : ℝ) ≤
((X - U).card : ℝ) ^ 3 * ((Y - V).card : ℝ) := by
exact_mod_cast finite_common_structure_card_bound X Y U V W hdouble
have hprefix : α * δ ^ 2 * a ^ 3 ≤ ((V ∩ W).card : ℝ) * ((X ∩ Y).card : ℝ) * (X.card : ℝ) := by
calc
_ = (δ * a) * (δ * a) * (α * a) := by ring
_ ≤ _ := by gcongr
have hpow : ((X - U).card : ℝ) ^ 3 * ((Y - V).card : ℝ) ≤ M ^ 4 * a ^ 4 := by
calc
_ ≤ (M * a) ^ 3 * (M * a) := by gcongr
_ = _ := by ring
have htotal : ((U + W).card : ℝ) * (α * δ ^ 2 * a ^ 3) ≤ M ^ 4 * a ^ 4 := by
calc
_ ≤ ((U + W).card : ℝ) * (((V ∩ W).card : ℝ) * ((X ∩ Y).card : ℝ) * (X.card : ℝ)) :=
mul_le_mul_of_nonneg_left hprefix (Nat.cast_nonneg _)
_ = ((U + W).card : ℝ) * ((V ∩ W).card : ℝ) * ((X ∩ Y).card : ℝ) * (X.card : ℝ) := by ring
_ ≤ _ := hc.trans hpow
have hcancel : ((U + W).card : ℝ) * (α * δ ^ 2) ≤ M ^ 4 * a := by
apply (mul_le_mul_iff_left₀ (show 0 < a ^ 3 by positivity)).mp
calc
_ = ((U + W).card : ℝ) * (α * δ ^ 2 * a ^ 3) := by ring
_ ≤ M ^ 4 * a ^ 4 := htotal
_ = _ := by ring
have hfinal : ((U + W).card : ℝ) * (α ^ 2 * δ ^ 2) ≤ M ^ 4 * (U.card : ℝ) := by
calc
_ = (((U + W).card : ℝ) * (α * δ ^ 2)) * α := by ring
_ ≤ (M ^ 4 * a) * α := mul_le_mul_of_nonneg_right hcancel hα.le
_ = M ^ 4 * (α * a) := by ring
_ ≤ _ := mul_le_mul_of_nonneg_left hU (by positivity)
calc
_ ≤ M ^ 4 * (U.card : ℝ) / (α ^ 2 * δ ^ 2) :=
(le_div_iff₀ (by positivity)).mpr hfinal
_ = _ := by ring
theorem finite_bsg_common_structure {G : Type*} [AddCommGroup G] [DecidableEq G]
{X Y U V W : Finset G} {a K : ℝ} (ha : 0 < a) (hK : 0 < K)
(hX : a / (16 * K) ≤ (X.card : ℝ)) (hU : a / (16 * K) ≤ (U.card : ℝ))
(hXY : a / (131072 * K ^ 4) ≤ ((X ∩ Y).card : ℝ))
(hVW : a / (131072 * K ^ 4) ≤ ((V ∩ W).card : ℝ))
(hXU : ((X - U).card : ℝ) ≤ 1024 * K ^ 5 * a)
(hYV : ((Y - V).card : ℝ) ≤ 1024 * K ^ 5 * a)
(hdouble : (W + W).card = (U + U).card) :
((U + W).card : ℝ) ≤ (2 : ℝ) ^ (82 : ℕ) * K ^ 30 * (U.card : ℝ) := by
have hh := finite_common_structure_quantitative (X := X) (Y := Y) (U := U) (V := V) (W := W)
(a := a) (α := (16 * K)⁻¹) (δ := (131072 * K ^ 4)⁻¹) (M := 1024 * K ^ 5)
ha (by positivity) (by positivity) (by positivity)
(by simpa only [inv_mul_eq_div] using hX) (by simpa only [inv_mul_eq_div] using hU)
(by simpa only [inv_mul_eq_div] using hXY) (by simpa only [inv_mul_eq_div] using hVW)
hXU hYV hdouble
have heq : (1024 * K ^ 5) ^ 4 / ((16 * K)⁻¹ ^ 2 * (131072 * K ^ 4)⁻¹ ^ 2) =
(2 : ℝ) ^ (82 : ℕ) * K ^ 30 := by
field_simp
ring
rwa [heq] at hh
/- Simultaneous inverse energy and sum-product closure of additive stabilizers. -/
theorem finite_add_equiv_image_add {G : Type*} [AddCommGroup G] [DecidableEq G]
(φ : G ≃+ G) (A B : Finset G) :
(A + B).image φ = A.image φ + B.image φ := by
ext z
constructor
· intro hz
obtain ⟨x, hx, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨a, ha, b, hb, rfl⟩ := Finset.mem_add.mp hx
exact Finset.mem_add.mpr ⟨φ a, Finset.mem_image_of_mem _ ha,
φ b, Finset.mem_image_of_mem _ hb, (map_add φ a b).symm⟩
· intro hz
obtain ⟨x, hx, y, hy, rfl⟩ := Finset.mem_add.mp hz
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
obtain ⟨b, hb, rfl⟩ := Finset.mem_image.mp hy
exact Finset.mem_image.mpr ⟨a + b, Finset.mem_add.mpr ⟨a, ha, b, hb, rfl⟩, map_add φ a b⟩
theorem finite_add_equiv_sum_card {G : Type*} [AddCommGroup G] [DecidableEq G]
(φ : G ≃+ G) (A B : Finset G) :
(A.image φ + B.image φ).card = (A + B).card := by
rw [← finite_add_equiv_image_add, Finset.card_image_of_injective _ φ.injective]
theorem finite_add_equiv_inter_card {G : Type*} [AddCommGroup G] [DecidableEq G]
(φ : G ≃+ G) (A B : Finset G) :
(A.image φ ∩ B.image φ).card = (A ∩ B).card := by
rw [← Finset.image_inter _ _ φ.injective, Finset.card_image_of_injective _ φ.injective]
theorem finite_bsg_add_equiv {G : Type*} [AddCommGroup G] [Fintype G] [DecidableEq G]
{A : Finset G} {K : ℝ} (φ : G ≃+ G) (hA : A.Nonempty) (hK : 0 < K)
(hE : (A.card : ℝ) ^ 3 ≤ K * (Finset.addEnergy A (A.image φ) : ℝ)) :
∃ X Y : Finset G, X ⊆ A ∧ Y ⊆ A ∧
(A.card : ℝ) / (16 * K) ≤ (X.card : ℝ) ∧
(A.card : ℝ) / (16 * K) ≤ (Y.card : ℝ) ∧
((X - Y.image φ).card : ℝ) ≤ 1024 * K ^ 5 * (A.card : ℝ) := by
have hBcard : (A.image φ).card = A.card := Finset.card_image_of_injective _ φ.injective
have hE' : (A.card : ℝ) ^ 2 * ((A.image φ).card : ℝ) ≤
K * (Finset.addEnergy A (A.image φ) : ℝ) := by
calc
_ = (A.card : ℝ) ^ 3 := by rw [hBcard]; ring
_ ≤ _ := hE
obtain ⟨X, D, hXA, hDB, hX, hDcard, hsize, hdiff⟩ := finite_bsg_two_sets hA (hA.image φ) hK hE'
let Y := D.image φ.symm
have hYA : Y ⊆ A := by
intro y hy
obtain ⟨d, hd, rfl⟩ := Finset.mem_image.mp hy
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp (hDB hd)
simpa only [AddEquiv.symm_apply_apply] using ha
have hYcard : Y.card = X.card := (Finset.card_image_of_injective _ φ.symm.injective).trans hDcard
have hYimage : Y.image φ = D := by
ext d
simp only [Y, Finset.mem_image]
constructor
· rintro ⟨y, ⟨x, hx, rfl⟩, rfl⟩
simpa only [AddEquiv.apply_symm_apply] using hx
· intro hd
exact ⟨φ.symm d, ⟨d, hd, rfl⟩, φ.apply_symm_apply d⟩
have hsize' : (A.card : ℝ) / (16 * K) ≤ (X.card : ℝ) :=
(div_le_iff₀ (by positivity)).mpr (by simpa only [mul_comm] using hsize)
refine ⟨X, Y, hXA, hYA, hsize', by simpa only [hYcard] using hsize', ?_⟩
rw [hYimage]
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
apply (mul_le_mul_iff_right₀ (show (0 : ℝ) < (A.card : ℝ) ^ 3 by positivity)).mp
calc
_ ≤ 1024 * K ^ 5 * ((A.image φ).card : ℝ) ^ 4 := hdiff
_ = _ := by rw [hBcard]; ring
theorem finite_large_product_intersections {G : Type*} [DecidableEq G]
{A X Y U V : Finset G} {d : ℝ} (hA : A.Nonempty) (hXA : X ⊆ A) (hYA : Y ⊆ A)
(hlarge : d * (A.card : ℝ) ^ 2 ≤ (((X ×ˢ Y) ∩ (U ×ˢ V)).card : ℝ)) :
d * (A.card : ℝ) ≤ ((X ∩ U).card : ℝ) ∧ d * (A.card : ℝ) ≤ ((Y ∩ V).card : ℝ) := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hX : ((X ∩ U).card : ℝ) ≤ A.card := by
exact_mod_cast Finset.card_le_card ((Finset.inter_subset_left).trans hXA)
have hY : ((Y ∩ V).card : ℝ) ≤ A.card := by
exact_mod_cast Finset.card_le_card ((Finset.inter_subset_left).trans hYA)
rw [Finset.product_inter_product, Finset.card_product, Nat.cast_mul] at hlarge
constructor
· apply (mul_le_mul_iff_left₀ hAp).mp
calc
_ = d * (A.card : ℝ) ^ 2 := by ring
_ ≤ _ := hlarge
_ ≤ _ := mul_le_mul_of_nonneg_left hY (Nat.cast_nonneg _)
· apply (mul_le_mul_iff_right₀ hAp).mp
calc
_ = d * (A.card : ℝ) ^ 2 := by ring
_ ≤ _ := hlarge
_ ≤ _ := mul_le_mul_of_nonneg_right hX (Nat.cast_nonneg _)
/-- High additive energy for many automorphisms gives one common large subset
with controlled mixed sumsets for a large subfamily. -/
theorem finite_many_automorphisms_small_sumsets {G ι : Type*}
[AddCommGroup G] [Fintype G] [DecidableEq G] [DecidableEq ι]
{A : Finset G} {I : Finset ι} {K : ℝ} (φ : ι → G ≃+ G)
(hA : A.Nonempty) (hI : I.Nonempty) (hK : 0 < K)
(hE : ∀ i ∈ I, (A.card : ℝ) ^ 3 ≤ K * (Finset.addEnergy A (A.image (φ i)) : ℝ)) :
∃ B : Finset G, B ⊆ A ∧ B.Nonempty ∧ (A.card : ℝ) / (16 * K) ≤ (B.card : ℝ) ∧
∃ i₀ ∈ I, ∃ J : Finset ι, J ⊆ I ∧
(I.card : ℝ) / (131072 * K ^ 4) ≤ (J.card : ℝ) ∧
∀ i ∈ J, ((B.image (φ i₀) + B.image (φ i)).card : ℝ) ≤
(2 : ℝ) ^ (82 : ℕ) * K ^ 30 * (B.card : ℝ) := by
classical
have hex : ∀ i : ι, ∃ X Y : Finset G, i ∈ I → X ⊆ A ∧ Y ⊆ A ∧
(A.card : ℝ) / (16 * K) ≤ (X.card : ℝ) ∧
(A.card : ℝ) / (16 * K) ≤ (Y.card : ℝ) ∧
((X - Y.image (φ i)).card : ℝ) ≤ 1024 * K ^ 5 * (A.card : ℝ) := by
intro i
by_cases hi : i ∈ I
· obtain ⟨X, Y, hXY⟩ := finite_bsg_add_equiv (φ i) hA hK (hE i hi)
exact ⟨X, Y, fun _ => hXY⟩
· exact ⟨∅, ∅, fun h => False.elim (hi h)⟩
choose X Y hXY using hex
let F := fun i => X i ×ˢ Y i
let δ : ℝ := (16 * K)⁻¹ ^ 2
have hF : ∀ i ∈ I, F i ⊆ A ×ˢ A := by
intro i hi
exact Finset.product_subset_product (hXY i hi).1 (hXY i hi).2.1
have hlarge : ∀ i ∈ I, δ * ((A ×ˢ A).card : ℝ) ≤ (F i).card := by
intro i hi
obtain ⟨hXi, hYi, hXsize, hYsize, hsmall⟩ := hXY i hi
dsimp only [F, δ]
rw [Finset.card_product, Finset.card_product, Nat.cast_mul, Nat.cast_mul]
calc
_ = ((A.card : ℝ) / (16 * K)) * ((A.card : ℝ) / (16 * K)) := by ring
_ ≤ _ := mul_le_mul hXsize hYsize (by positivity) (Nat.cast_nonneg _)
obtain ⟨i₀, hi₀, hmany⟩ := finite_family_large_intersections hI (hA.product hA)
(show 0 ≤ δ by positivity) hF hlarge
let J := I.filter (fun i => δ ^ 2 / 2 * ((A ×ˢ A).card : ℝ) ≤ ((F i₀ ∩ F i).card : ℝ))
have hconstant : δ ^ 2 / 2 = (131072 * K ^ 4)⁻¹ := by
dsimp only [δ]
field_simp
ring
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hYpos : (0 : ℝ) < (Y i₀).card :=
(div_pos hAp (by positivity)).trans_le (hXY i₀ hi₀).2.2.2.1
refine ⟨Y i₀, (hXY i₀ hi₀).2.1, Finset.card_pos.mp (by exact_mod_cast hYpos),
(hXY i₀ hi₀).2.2.2.1, i₀, hi₀, J, Finset.filter_subset _ _, ?_, ?_⟩
· have hh : δ ^ 2 / 2 * (I.card : ℝ) ≤ (J.card : ℝ) := hmany
simpa only [hconstant, inv_mul_eq_div] using hh
· intro i hi
obtain ⟨hiI, hgood⟩ := Finset.mem_filter.mp hi
have hgood' : δ ^ 2 / 2 * (A.card : ℝ) ^ 2 ≤ ((F i₀ ∩ F i).card : ℝ) := by
simpa only [Finset.card_product, Nat.cast_mul, pow_two] using hgood
obtain ⟨hXinter, hYinter⟩ := finite_large_product_intersections hA
(hXY i₀ hi₀).1 (hXY i₀ hi₀).2.1 hgood'
have hXinter' : (A.card : ℝ) / (131072 * K ^ 4) ≤ ((X i₀ ∩ X i).card : ℝ) := by
simpa only [hconstant, inv_mul_eq_div] using hXinter
have hYinter' : (A.card : ℝ) / (131072 * K ^ 4) ≤ ((Y i ∩ Y i₀).card : ℝ) := by
simpa only [hconstant, inv_mul_eq_div, Finset.inter_comm] using hYinter
have hh := finite_bsg_common_structure (X := X i₀) (Y := X i)
(U := (Y i₀).image (φ i₀)) (V := (Y i).image (φ i)) (W := (Y i₀).image (φ i)) hAp hK
(hXY i₀ hi₀).2.2.1
(by simpa only [Finset.card_image_of_injective _ (φ i₀).injective] using (hXY i₀ hi₀).2.2.2.1)
hXinter'
(by simpa only [finite_add_equiv_inter_card] using hYinter')
(hXY i₀ hi₀).2.2.2.2 (hXY i hiI).2.2.2.2
(by rw [finite_add_equiv_sum_card, finite_add_equiv_sum_card])
simpa only [Finset.card_image_of_injective _ (φ i₀).injective] using hh
def ringDilate {R : Type*} [Ring R] [DecidableEq R] (a : R) (A : Finset R) : Finset R :=
A.image (fun x => a * x)
def ringUnitMulAddEquiv {R : Type*} [Ring R] (u : Rˣ) : R ≃+ R where
toFun x := (u : R) * x
invFun x := (u⁻¹ : Rˣ) * x
left_inv x := by simp only [← mul_assoc, Units.inv_mul, one_mul]
right_inv x := by simp only [← mul_assoc, Units.mul_inv, one_mul]
map_add' x y := mul_add _ _ _
theorem ring_dilate_add {R : Type*} [Ring R] [DecidableEq R] (a : R) (A B : Finset R) :
ringDilate a (A + B) = ringDilate a A + ringDilate a B := by
exact Finset.image_add (AddMonoidHom.mulLeft a)
theorem ring_dilate_sub {R : Type*} [Ring R] [DecidableEq R] (a : R) (A B : Finset R) :
ringDilate a (A - B) = ringDilate a A - ringDilate a B := by
exact Finset.image_image₂_distrib (map_sub (AddMonoidHom.mulLeft a))
theorem ring_dilate_mul {R : Type*} [Ring R] [DecidableEq R] (a b : R) (A : Finset R) :
ringDilate a (ringDilate b A) = ringDilate (a * b) A := by
unfold ringDilate
rw [Finset.image_image]
apply Finset.image_congr
intro x hx
exact (mul_assoc a b x).symm
theorem ring_dilate_one {R : Type*} [Ring R] [DecidableEq R] (A : Finset R) :
ringDilate 1 A = A := by simp [ringDilate]
theorem ring_dilate_unit_card {R : Type*} [Ring R] [DecidableEq R] (u : Rˣ) (A : Finset R) :
(ringDilate (u : R) A).card = A.card :=
Finset.card_image_of_injective A (ringUnitMulAddEquiv u).injective
theorem ring_unit_relative_sum_card {R : Type*} [Ring R] [DecidableEq R]
(u v : Rˣ) (A : Finset R) :
(A + ringDilate ((u⁻¹ * v : Rˣ) : R) A).card =
(ringDilate (u : R) A + ringDilate (v : R) A).card := by
have heq : ringDilate ((u⁻¹ : Rˣ) : R) (ringDilate (u : R) A + ringDilate (v : R) A) =
A + ringDilate ((u⁻¹ * v : Rˣ) : R) A := by
rw [ring_dilate_add, ring_dilate_mul, ring_dilate_mul, Units.inv_mul, ring_dilate_one]
rfl
rw [← heq, ring_dilate_unit_card]
noncomputable def ringSumStabilizer {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
(A : Finset R) (K : ℝ) : Finset R := by
classical
exact Finset.univ.filter (fun a => ((A + ringDilate a A).card : ℝ) ≤ K * (A.card : ℝ))
theorem mem_ring_sum_stabilizer {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
(A : Finset R) (K : ℝ) (a : R) :
a ∈ ringSumStabilizer A K ↔ ((A + ringDilate a A).card : ℝ) ≤ K * (A.card : ℝ) := by
classical
simp only [ringSumStabilizer, Finset.mem_filter, Finset.mem_univ, true_and]
/-- A large family of unit dilates with high energy yields many normalized
unit multipliers stabilizing the additive size of one common large subset. -/
theorem finite_many_unit_dilates_stabilizer {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {T : Finset Rˣ} {K : ℝ} (hA : A.Nonempty) (hT : T.Nonempty) (hK : 0 < K)
(hE : ∀ u ∈ T, (A.card : ℝ) ^ 3 ≤ K * (Finset.addEnergy A (ringDilate (u : R) A) : ℝ)) :
∃ B : Finset R, B ⊆ A ∧ B.Nonempty ∧ (A.card : ℝ) / (16 * K) ≤ (B.card : ℝ) ∧
∃ u₀ ∈ T, ∃ S : Finset R,
S ⊆ T.image (fun u => ((u₀⁻¹ * u : Rˣ) : R)) ∧ S.Nonempty ∧
(T.card : ℝ) / (131072 * K ^ 4) ≤ (S.card : ℝ) ∧
(∀ x ∈ S, IsUnit x) ∧ S ⊆ ringSumStabilizer B ((2 : ℝ) ^ (82 : ℕ) * K ^ 30) := by
classical
obtain ⟨B, hBA, hB, hsize, u₀, hu₀, J, hJT, hJsize, hsmall⟩ :=
finite_many_automorphisms_small_sumsets (fun u : Rˣ => ringUnitMulAddEquiv u) hA hT hK hE
let S := J.image (fun u => ((u₀⁻¹ * u : Rˣ) : R))
have hinj : Function.Injective (fun u : Rˣ => ((u₀⁻¹ * u : Rˣ) : R)) := by
intro u v huv
exact mul_left_cancel (Units.val_injective huv)
have hScard : S.card = J.card := Finset.card_image_of_injective _ hinj
have hTp : (0 : ℝ) < T.card := by exact_mod_cast hT.card_pos
have hJp : (0 : ℝ) < J.card := (div_pos hTp (by positivity)).trans_le hJsize
have hJ : J.Nonempty := Finset.card_pos.mp (by exact_mod_cast hJp)
refine ⟨B, hBA, hB, hsize, u₀, hu₀, S, Finset.image_subset_image hJT, hJ.image _,
by simpa only [hScard] using hJsize, ?_, ?_⟩
· intro x hx
obtain ⟨u, hu, rfl⟩ := Finset.mem_image.mp hx
exact ⟨u₀⁻¹ * u, rfl⟩
· intro x hx
obtain ⟨u, hu, rfl⟩ := Finset.mem_image.mp hx
rw [mem_ring_sum_stabilizer, ring_unit_relative_sum_card]
exact hsmall u hu
theorem finite_signed_sum_card_bound {G : Type*} [AddCommGroup G] [DecidableEq G]
{A : Finset G} {D : ℝ} (hA : A.Nonempty) (hD : 0 ≤ D)
(hdouble : ((A + A).card : ℝ) ≤ D * (A.card : ℝ)) (m n : ℕ) :
((m • A - n • A).card : ℝ) ≤ D ^ (m + n) * (A.card : ℝ) := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hh := Finset.pluennecke_ruzsa_inequality_nsmul_sub_nsmul_add hA A m n
have hhQ : ((m • A - n • A).card : ℚ) ≤
(((A + A).card : ℚ) / (A.card : ℚ)) ^ (m + n) * (A.card : ℚ) := by
exact_mod_cast (NNRat.coe_mono hh)
have hhR := (Rat.cast_le (K := ℝ)).mpr hhQ
push_cast at hhR
have hratio : ((A + A).card : ℝ) / (A.card : ℝ) ≤ D := (div_le_iff₀ hAp).mpr hdouble
exact hhR.trans (mul_le_mul_of_nonneg_right
(pow_le_pow_left₀ (by positivity) hratio _) hAp.le)
theorem finite_three_two_hull_card {G : Type*} [AddCommGroup G] [DecidableEq G]
{A : Finset G} {D : ℝ} (hA : A.Nonempty) (hD : 0 ≤ D)
(hdouble : ((A + A).card : ℝ) ≤ D * (A.card : ℝ)) :
(((A + (A - A)) + (A - A)).card : ℝ) ≤ D ^ (5 : ℕ) * (A.card : ℝ) := by
have heq : (A + (A - A)) + (A - A) = (3 : ℕ) • A - (2 : ℕ) • A := by
simp only [succ_nsmul, zero_nsmul, zero_add, sub_eq_add_neg, neg_add_rev,
neg_zero, add_zero]
ac_rfl
rw [heq]
exact finite_signed_sum_card_bound hA hD hdouble 3 2
theorem ring_sum_stabilizer_cover {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {K : ℝ} {x : R} (hA : A.Nonempty) (hx : x ∈ ringSumStabilizer A K) :
∃ F : Finset R, F ⊆ ringDilate x A ∧ (F.card : ℝ) ≤ K ∧ ringDilate x A ⊆ F + (A - A) := by
exact Finset.ruzsa_covering_add hA (by
rw [add_comm]
exact (mem_ring_sum_stabilizer A K x).mp hx)
theorem ring_dilate_subset {R : Type*} [Ring R] [DecidableEq R] (x : R)
{A B : Finset R} (hAB : A ⊆ B) : ringDilate x A ⊆ ringDilate x B :=
Finset.image_subset_image hAB
theorem ring_dilate_scalar_add_subset {R : Type*} [Ring R] [DecidableEq R] (x y : R) (A : Finset R) :
ringDilate (x + y) A ⊆ ringDilate x A + ringDilate y A := by
intro z hz
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hz
exact Finset.mem_add.mpr ⟨x * a, Finset.mem_image_of_mem _ ha,
y * a, Finset.mem_image_of_mem _ ha, (add_mul x y a).symm⟩
theorem finite_three_sum_card_bound {G : Type*} [AddCommGroup G] [DecidableEq G]
(A B C : Finset G) : (A + B + C).card ≤ A.card * B.card * C.card :=
Finset.card_add_le.trans (Nat.mul_le_mul_right _ Finset.card_add_le)
theorem ring_sum_stabilizer_add {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {D K L : ℝ} {x y : R} (hA : A.Nonempty)
(hD : 0 ≤ D) (hK : 0 ≤ K) (hL : 0 ≤ L)
(hdouble : ((A + A).card : ℝ) ≤ D * (A.card : ℝ))
(hx : x ∈ ringSumStabilizer A K) (hy : y ∈ ringSumStabilizer A L) :
x + y ∈ ringSumStabilizer A (K * L * D ^ (5 : ℕ)) := by
obtain ⟨F, hFx, hF, hcoverx⟩ := ring_sum_stabilizer_cover hA hx
obtain ⟨G, hGy, hG, hcovery⟩ := ring_sum_stabilizer_cover hA hy
let H := (A + (A - A)) + (A - A)
have hsub : A + ringDilate (x + y) A ⊆ F + G + H := by
calc
_ ⊆ A + (ringDilate x A + ringDilate y A) :=
Finset.add_subset_add_left (ring_dilate_scalar_add_subset x y A)
_ ⊆ A + ((F + (A - A)) + (G + (A - A))) :=
Finset.add_subset_add_left (Finset.add_subset_add hcoverx hcovery)
_ = _ := by dsimp only [H]; ac_rfl
rw [mem_ring_sum_stabilizer]
calc
_ ≤ ((F + G + H).card : ℝ) := by exact_mod_cast Finset.card_le_card hsub
_ ≤ (F.card : ℝ) * (G.card : ℝ) * (H.card : ℝ) := by
exact_mod_cast finite_three_sum_card_bound F G H
_ ≤ K * L * (D ^ (5 : ℕ) * (A.card : ℝ)) := by
gcongr
exact finite_three_two_hull_card hA hD hdouble
_ = _ := by ring
theorem ring_sum_stabilizer_mul {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {D K L : ℝ} {x y : R} (hA : A.Nonempty)
(hD : 0 ≤ D) (hK : 0 ≤ K) (hL : 0 ≤ L)
(hdouble : ((A + A).card : ℝ) ≤ D * (A.card : ℝ))
(hx : x ∈ ringSumStabilizer A K) (hy : y ∈ ringSumStabilizer A L) :
x * y ∈ ringSumStabilizer A (K ^ 2 * L * D ^ (5 : ℕ)) := by
obtain ⟨F, hFx, hF, hcoverx⟩ := ring_sum_stabilizer_cover hA hx
obtain ⟨G, hGy, hG, hcovery⟩ := ring_sum_stabilizer_cover hA hy
let H := (A + (A - A)) + (A - A)
have hsub : A + ringDilate (x * y) A ⊆ (ringDilate x G + (F - F)) + H := by
calc
_ = A + ringDilate x (ringDilate y A) := by rw [ring_dilate_mul]
_ ⊆ A + ringDilate x (G + (A - A)) :=
Finset.add_subset_add_left (ring_dilate_subset x hcovery)
_ = A + (ringDilate x G + (ringDilate x A - ringDilate x A)) := by
rw [ring_dilate_add, ring_dilate_sub]
_ ⊆ A + (ringDilate x G + ((F + (A - A)) - (F + (A - A)))) :=
Finset.add_subset_add_left (Finset.add_subset_add_left (Finset.sub_subset_sub hcoverx hcoverx))
_ = _ := by
dsimp only [H]
simp only [sub_eq_add_neg, neg_add_rev, neg_neg]
ac_rfl
have hcardx : ((ringDilate x G).card : ℝ) ≤ G.card := by exact_mod_cast Finset.card_image_le
have hcardF : ((F - F).card : ℝ) ≤ (F.card : ℝ) ^ 2 := by
exact_mod_cast (Finset.card_sub_le : (F - F).card ≤ F.card * F.card).trans_eq (pow_two F.card).symm
rw [mem_ring_sum_stabilizer]
calc
_ ≤ (((ringDilate x G + (F - F)) + H).card : ℝ) := by exact_mod_cast Finset.card_le_card hsub
_ ≤ ((ringDilate x G).card : ℝ) * ((F - F).card : ℝ) * (H.card : ℝ) := by
exact_mod_cast finite_three_sum_card_bound (ringDilate x G) (F - F) H
_ ≤ L * K ^ 2 * (D ^ (5 : ℕ) * (A.card : ℝ)) := by
gcongr
· exact hcardx.trans hG
· exact hcardF.trans (pow_le_pow_left₀ (Nat.cast_nonneg _) hF 2)
· exact finite_three_two_hull_card hA hD hdouble
_ = _ := by ring
theorem ring_dilate_neg {R : Type*} [Ring R] [DecidableEq R] (x : R) (A : Finset R) :
ringDilate (-x) A = -(ringDilate x A) := by
ext z
simp only [ringDilate, Finset.mem_image, Finset.mem_neg, neg_mul, neg_eq_iff_eq_neg]
aesop
theorem ring_sum_stabilizer_neg {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {D K : ℝ} {x : R} (hA : A.Nonempty) (hD : 0 ≤ D) (hK : 0 ≤ K)
(hdouble : ((A + A).card : ℝ) ≤ D * (A.card : ℝ))
(hx : x ∈ ringSumStabilizer A K) : -x ∈ ringSumStabilizer A (D * K) := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hh : ((A - ringDilate x A).card : ℝ) * (A.card : ℝ) ≤
((A + A).card : ℝ) * ((ringDilate x A + A).card : ℝ) := by
exact_mod_cast Finset.ruzsa_triangle_inequality_sub_add_add A A (ringDilate x A)
have hx' : ((ringDilate x A + A).card : ℝ) ≤ K * (A.card : ℝ) := by
rw [add_comm]
exact (mem_ring_sum_stabilizer A K x).mp hx
rw [mem_ring_sum_stabilizer, ring_dilate_neg, ← sub_eq_add_neg]
apply (mul_le_mul_iff_left₀ hAp).mp
calc
_ ≤ _ := hh
_ ≤ (D * (A.card : ℝ)) * (K * (A.card : ℝ)) := by gcongr
_ = _ := by ring
theorem ring_sum_stabilizer_mono {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
(A : Finset R) {K L : ℝ} (hKL : K ≤ L) : ringSumStabilizer A K ⊆ ringSumStabilizer A L := by
intro x hx
rw [mem_ring_sum_stabilizer] at hx ⊢
exact hx.trans (mul_le_mul_of_nonneg_right hKL (Nat.cast_nonneg _))
theorem ring_sum_stabilizer_zero {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {K : ℝ} (hA : A.Nonempty) (hK : 1 ≤ K) : 0 ∈ ringSumStabilizer A K := by
have hz : ringDilate (0 : R) A = {0} := by
ext z
simp only [ringDilate, Finset.mem_image, zero_mul, Finset.mem_singleton]
constructor
· rintro ⟨a, ha, hz⟩
exact hz.symm
· intro hz
obtain ⟨a, ha⟩ := hA
exact ⟨a, ha, hz.symm⟩
rw [mem_ring_sum_stabilizer, hz]
have heq : A + ({0} : Finset R) = A := by change A + 0 = A; exact add_zero A
rw [heq]
simpa only [one_mul] using mul_le_mul_of_nonneg_right hK (Nat.cast_nonneg A.card : (0 : ℝ) ≤ A.card)
theorem ring_sum_stabilizer_one {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {K : ℝ} (hdouble : ((A + A).card : ℝ) ≤ K * (A.card : ℝ)) :
1 ∈ ringSumStabilizer A K := by
rw [mem_ring_sum_stabilizer, ring_dilate_one]
exact hdouble
theorem ring_sum_stabilizer_unit_doubling {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {K : ℝ} (hA : A.Nonempty) (hK : 0 ≤ K) (u : Rˣ)
(hu : (u : R) ∈ ringSumStabilizer A K) :
((A + A).card : ℝ) ≤ K ^ 2 * (A.card : ℝ) := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hh : ((A + A).card : ℝ) * (A.card : ℝ) ≤
((A + ringDilate (u : R) A).card : ℝ) ^ 2 := by
have hh' := Finset.ruzsa_triangle_inequality_add_add_add A (ringDilate (u : R) A) A
rw [ring_dilate_unit_card, add_comm (ringDilate (u : R) A) A] at hh'
exact_mod_cast hh'.trans_eq (pow_two (A + ringDilate (u : R) A).card).symm
have hbound := (mem_ring_sum_stabilizer A K (u : R)).mp hu
apply (mul_le_mul_iff_left₀ hAp).mp
calc
_ ≤ _ := hh
_ ≤ (K * (A.card : ℝ)) ^ 2 := pow_le_pow_left₀ (Nat.cast_nonneg _) hbound 2
_ = _ := by ring
theorem ring_sum_stabilizer_add_power {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {K : ℝ} {x y : R} (hA : A.Nonempty) (hK : 1 ≤ K)
(hdouble : ((A + A).card : ℝ) ≤ K * (A.card : ℝ))
(hx : x ∈ ringSumStabilizer A K) (hy : y ∈ ringSumStabilizer A K) :
x + y ∈ ringSumStabilizer A (K ^ (8 : ℕ)) := by
have hK0 : 0 ≤ K := (by norm_num : (0 : ℝ) ≤ 1).trans hK
have hh := ring_sum_stabilizer_add hA hK0 hK0 hK0 hdouble hx hy
apply ring_sum_stabilizer_mono A (show K * K * K ^ (5 : ℕ) ≤ K ^ (8 : ℕ) from ?_) hh
calc
_ = K ^ (7 : ℕ) := by ring
_ ≤ _ := pow_le_pow_right₀ hK (by norm_num)
theorem ring_sum_stabilizer_mul_power {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {K : ℝ} {x y : R} (hA : A.Nonempty) (hK : 1 ≤ K)
(hdouble : ((A + A).card : ℝ) ≤ K * (A.card : ℝ))
(hx : x ∈ ringSumStabilizer A K) (hy : y ∈ ringSumStabilizer A K) :
x * y ∈ ringSumStabilizer A (K ^ (8 : ℕ)) := by
have hK0 : 0 ≤ K := (by norm_num : (0 : ℝ) ≤ 1).trans hK
have hh := ring_sum_stabilizer_mul hA hK0 hK0 hK0 hdouble hx hy
have heq : K ^ (2 : ℕ) * K * K ^ (5 : ℕ) = K ^ (8 : ℕ) := by ring
rwa [heq] at hh
theorem ring_sum_stabilizer_neg_power {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A : Finset R} {K : ℝ} {x : R} (hA : A.Nonempty) (hK : 1 ≤ K)
(hdouble : ((A + A).card : ℝ) ≤ K * (A.card : ℝ))
(hx : x ∈ ringSumStabilizer A K) : -x ∈ ringSumStabilizer A (K ^ (8 : ℕ)) := by
have hK0 : 0 ≤ K := (by norm_num : (0 : ℝ) ≤ 1).trans hK
have hh := ring_sum_stabilizer_neg hA hK0 hK0 hdouble hx
apply ring_sum_stabilizer_mono A (show K * K ≤ K ^ (8 : ℕ) from ?_) hh
calc
_ = K ^ (2 : ℕ) := by ring
_ ≤ _ := pow_le_pow_right₀ hK (by norm_num)
/-- The sum-product closure used in the growth theorem remains a stabilizer,
with a fixed power loss in the parameter. This does not require units. -/
theorem ring_sum_stabilizer_quadratic_closure {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A S : Finset R} {K : ℝ} (hA : A.Nonempty) (hK : 1 ≤ K)
(hdouble : ((A + A).card : ℝ) ≤ K * (A.card : ℝ)) (hS : S ⊆ ringSumStabilizer A K) :
(insert 0 (S ∪ S * S) + insert 0 (S ∪ S * S)) ⊆ ringSumStabilizer A (K ^ (64 : ℕ)) := by
have hKK : K ≤ K ^ (8 : ℕ) := by
simpa only [pow_one] using pow_le_pow_right₀ hK (show 1 ≤ (8 : ℕ) by norm_num)
have hF : insert 0 (S ∪ S * S) ⊆ ringSumStabilizer A (K ^ (8 : ℕ)) := by
intro x hx
rcases Finset.mem_insert.mp hx with rfl | hx
· exact ring_sum_stabilizer_mono A hKK (ring_sum_stabilizer_zero hA hK)
· rcases Finset.mem_union.mp hx with hx | hx
· exact ring_sum_stabilizer_mono A hKK (hS hx)
· obtain ⟨a, ha, b, hb, rfl⟩ := Finset.mem_mul.mp hx
exact ring_sum_stabilizer_mul_power hA hK hdouble (hS ha) (hS hb)
intro z hz
obtain ⟨x, hx, y, hy, rfl⟩ := Finset.mem_add.mp hz
have hdouble' : ((A + A).card : ℝ) ≤ K ^ (8 : ℕ) * (A.card : ℝ) :=
hdouble.trans (mul_le_mul_of_nonneg_right hKK (Nat.cast_nonneg _))
have hh := ring_sum_stabilizer_add_power hA (one_le_pow₀ hK) hdouble' (hF hx) (hF hy)
simpa only [← pow_mul, show (8 : ℕ) * 8 = 64 from rfl] using hh
/- Fourier averaging and a density bound for all additive stabilizers. -/
theorem cyclic_set_indicator_norm {q : ℕ} [NeZero q] (A : Finset (ZMod q)) (x : ZMod q) :
‖cyclicSetIndicator A x‖ = if x ∈ A then (1 : ℝ) else 0 := by
classical
by_cases hx : x ∈ A <;> simp [cyclicSetIndicator, hx]
theorem cyclic_set_indicator_norm_sum {q : ℕ} [NeZero q] (A : Finset (ZMod q)) :
(∑ x : ZMod q, ‖cyclicSetIndicator A x‖) = (A.card : ℝ) := by
classical
simp [cyclic_set_indicator_norm]
theorem cyclic_set_indicator_sq_norm_sum {q : ℕ} [NeZero q] (A : Finset (ZMod q)) :
(∑ x : ZMod q, ‖cyclicSetIndicator A x‖ ^ 2) = (A.card : ℝ) := by
classical
simp [cyclic_set_indicator_norm, ite_pow]
theorem cyclic_set_indicator_pushforward {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (T : ZMod q → ZMod q) (z : ZMod q) :
cyclicPushforward (cyclicSetIndicator A) T z = ((A.filter (fun x => T x = z)).card : ℂ) := by
classical
have heq (x : ZMod q) : (if T x = z then (if x ∈ A then (1 : ℂ) else 0) else 0) =
if x ∈ A then (if T x = z then (1 : ℂ) else 0) else 0 := by
by_cases hx : x ∈ A <;> by_cases hz : T x = z <;> simp [hx, hz]
unfold cyclicPushforward cyclicSetIndicator
simp_rw [heq]
simp only [← Finset.sum_filter, Finset.filter_mem_eq_inter, Finset.univ_inter,
Finset.sum_const, nsmul_eq_mul, mul_one]
theorem cyclic_set_pushforward_norm_sum {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (T : ZMod q → ZMod q) :
(∑ z : ZMod q, ‖cyclicPushforward (cyclicSetIndicator A) T z‖) = (A.card : ℝ) := by
simp_rw [cyclic_set_indicator_pushforward, Complex.norm_natCast]
exact_mod_cast (Finset.card_eq_sum_card_fiberwise (f := T) (s := A)
(t := Finset.univ) (fun _ _ => Finset.mem_univ _)).symm
theorem dft_cyclic_pushforward_mul {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (k x : ZMod q) :
ZMod.dft (cyclicPushforward f (fun a => a * k)) x = ZMod.dft f (x * k) := by
rw [dft_cyclicPushforward, ZMod.dft_apply]
apply Finset.sum_congr rfl
intro a ha
simp only [smul_eq_mul]
rw [show a * k * x = a * (x * k) by ring]
theorem uniform_mul_fourier_energy_eq_pushforward {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (k : ZMod q) :
(∑ x : ZMod q, (1 / (q : ℝ)) * ‖ZMod.dft f (x * k)‖ ^ 2) =
∑ z : ZMod q, ‖cyclicPushforward f (fun a => a * k) z‖ ^ 2 := by
have hh := dft_parseval (cyclicPushforward f (fun a => a * k))
simp_rw [dft_cyclic_pushforward_mul] at hh
rw [← Finset.mul_sum, hh]
have hq : (q : ℝ) ≠ 0 := by exact_mod_cast NeZero.ne q
field_simp
theorem uniform_set_fourier_energy_le_fibers {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (k : ZMod q) {M : ℝ}
(hM : ∀ z : ZMod q, ((A.filter (fun a => a * k = z)).card : ℝ) ≤ M) :
(∑ x : ZMod q, (1 / (q : ℝ)) * ‖ZMod.dft (cyclicSetIndicator A) (x * k)‖ ^ 2) ≤
M * (A.card : ℝ) := by
rw [uniform_mul_fourier_energy_eq_pushforward]
calc
_ ≤ ∑ z : ZMod q, M * ‖cyclicPushforward (cyclicSetIndicator A) (fun a => a * k) z‖ := by
apply Finset.sum_le_sum
intro z hz
have hb : ‖cyclicPushforward (cyclicSetIndicator A) (fun a => a * k) z‖ ≤ M := by
simpa only [cyclic_set_indicator_pushforward, Complex.norm_natCast] using hM z
simpa only [pow_two] using mul_le_mul_of_nonneg_right hb (norm_nonneg _)
_ = _ := by rw [← Finset.mul_sum, cyclic_set_pushforward_norm_sum]
theorem finite_fiber_card_le_of_kernel {α β κ : Type*} [DecidableEq α] [DecidableEq β] [DecidableEq κ]
(A : Finset α) (f : α → β) (g : α → κ) {M : ℝ} (hM : 0 ≤ M)
(hkernel : ∀ a b : α, f a = f b → g a = g b)
(hbound : ∀ r : κ, ((A.filter (fun a => g a = r)).card : ℝ) ≤ M) :
∀ z : β, ((A.filter (fun a => f a = z)).card : ℝ) ≤ M := by
classical
intro z
by_cases hF : (A.filter (fun a => f a = z)).Nonempty
· obtain ⟨a₀, ha₀⟩ := hF
have hsub : A.filter (fun a => f a = z) ⊆ A.filter (fun a => g a = g a₀) := by
intro a ha
obtain ⟨haA, haz⟩ := Finset.mem_filter.mp ha
exact Finset.mem_filter.mpr ⟨haA, hkernel a a₀ (haz.trans (Finset.mem_filter.mp ha₀).2.symm)⟩
exact (show ((A.filter (fun a => f a = z)).card : ℝ) ≤
((A.filter (fun a => g a = g a₀)).card : ℝ) by exact_mod_cast Finset.card_le_card hsub).trans (hbound _)
· simpa only [Finset.not_nonempty_iff_eq_empty.mp hF, Finset.card_empty, Nat.cast_zero] using hM
theorem dyadic_mul_kernel_refines_coarse {J L : ℕ} (hL : L ≤ J) {k : ZMod (2 ^ J)}
(hk : L ≤ dyadicConductorLevel k) (a b : ZMod (2 ^ J)) (hab : a * k = b * k) :
(a.val : ZMod (2 ^ L)) = (b.val : ZMod (2 ^ L)) := by
have hkill : (a - b) * k = 0 := by rw [sub_mul, hab, sub_self]
have hd : addOrderOf k ∣ (a - b).val := by
apply addOrderOf_dvd_iff_nsmul_eq_zero.mpr
simpa only [nsmul_eq_mul, ZMod.natCast_zmod_val] using hkill
rw [(dyadic_conductor_spec k).2] at hd
have hdL : 2 ^ L ∣ (a - b).val := (pow_dvd_pow 2 hk).trans hd
have hh := dyadic_sub_val_mod hL a.val b.val
simp only [ZMod.natCast_zmod_val] at hh
have hzero : ((a.val : ZMod (2 ^ L)) - (b.val : ZMod (2 ^ L))).val = 0 :=
hh.symm.trans (Nat.mod_eq_zero_of_dvd hdL)
apply sub_eq_zero.mp
apply ZMod.val_injective (2 ^ L)
simpa only [ZMod.val_zero] using hzero
theorem dyadic_uniform_set_fourier_energy_coarse {J L : ℕ} (hL : L ≤ J)
(A : Finset (ZMod (2 ^ J))) {M : ℝ} (hM : 0 ≤ M)
(hbound : ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤ M * (A.card : ℝ))
{k : ZMod (2 ^ J)} (hk : L ≤ dyadicConductorLevel k) :
(∑ x : ZMod (2 ^ J), (1 / ((2 ^ J : ℕ) : ℝ)) *
‖ZMod.dft (cyclicSetIndicator A) (x * k)‖ ^ 2) ≤ M * (A.card : ℝ) ^ 2 := by
have hfiber := finite_fiber_card_le_of_kernel A (fun a => a * k)
(fun a => (a.val : ZMod (2 ^ L))) (show 0 ≤ M * (A.card : ℝ) by positivity)
(dyadic_mul_kernel_refines_coarse hL hk) hbound
have hh := uniform_set_fourier_energy_le_fibers A k hfiber
simpa only [mul_assoc, pow_two] using hh
theorem dyadic_low_conductor_card_le {J L : ℕ} (hL : L ≤ J) :
(Finset.univ.filter (fun k : ZMod (2 ^ J) => dyadicConductorLevel k ≤ L)).card ≤ 2 ^ L := by
classical
have hsub : (Finset.univ.filter (fun k : ZMod (2 ^ J) => dyadicConductorLevel k ≤ L)) ⊆
Finset.univ.filter (fun k : ZMod (2 ^ J) => k * ((2 ^ L : ℕ) : ZMod (2 ^ J)) = 0) := by
intro k hk
have hh := dyadic_conductor_power_nsmul_eq_zero (Finset.mem_filter.mp hk).2
exact Finset.mem_filter.mpr ⟨Finset.mem_univ _, by
simpa only [nsmul_eq_mul, mul_comm] using hh⟩
calc
_ ≤ (Finset.univ.filter (fun k : ZMod (2 ^ J) => k * ((2 ^ L : ℕ) : ZMod (2 ^ J)) = 0)).card :=
Finset.card_le_card hsub
_ ≤ (2 ^ J).gcd (2 ^ L) := zmod_mul_zero_fiber_card_le (2 ^ L)
_ = _ := Nat.gcd_eq_right (pow_dvd_pow 2 hL)
noncomputable def cyclicSetDilateCollision {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (x : ZMod q) : ℝ :=
∑ z : ZMod q, ‖cyclicConvolution (cyclicSetIndicator A)
(cyclicPushforward (cyclicSetIndicator A) (fun a => a * x)) z‖ ^ 2
theorem cyclic_set_dilate_collision_nonneg {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (x : ZMod q) : 0 ≤ cyclicSetDilateCollision A x := by
unfold cyclicSetDilateCollision
positivity
theorem cyclic_set_dilate_collision_fourier {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (x : ZMod q) :
(q : ℝ) * cyclicSetDilateCollision A x =
∑ k : ZMod q, ‖ZMod.dft (cyclicSetIndicator A) k‖ ^ 2 *
‖ZMod.dft (cyclicSetIndicator A) (k * x)‖ ^ 2 := by
unfold cyclicSetDilateCollision
rw [← dft_parseval]
simp only [dft_cyclicConvolution, dft_cyclic_pushforward_mul, norm_mul, mul_pow]
theorem cyclic_set_dilate_collision_sum_fourier {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) :
(q : ℝ) * (∑ x : ZMod q, cyclicSetDilateCollision A x) =
∑ k : ZMod q, ‖ZMod.dft (cyclicSetIndicator A) k‖ ^ 2 *
(∑ x : ZMod q, ‖ZMod.dft (cyclicSetIndicator A) (x * k)‖ ^ 2) := by
rw [Finset.mul_sum]
simp_rw [cyclic_set_dilate_collision_fourier]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro k hk
rw [Finset.mul_sum]
apply Finset.sum_congr rfl
intro x hx
rw [mul_comm x k]
/-- Coarse residue control bounds the average additive collision of all dilates,
including multiplication by nonunits. -/
theorem dyadic_set_dilate_collision_sum_bound {J L : ℕ} (hL : L ≤ J)
(A : Finset (ZMod (2 ^ J))) {M : ℝ} (hM : 0 ≤ M)
(hbound : ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤ M * (A.card : ℝ)) :
(∑ x : ZMod (2 ^ J), cyclicSetDilateCollision A x) ≤
(2 : ℝ) ^ L * (A.card : ℝ) ^ 4 + (2 : ℝ) ^ J * M * (A.card : ℝ) ^ 3 := by
classical
let F := fun k : ZMod (2 ^ J) => ‖ZMod.dft (cyclicSetIndicator A) k‖ ^ 2
let Q : ℝ := (2 : ℝ) ^ J
let Z := Finset.univ.filter (fun k : ZMod (2 ^ J) => dyadicConductorLevel k ≤ L)
have hQ : 0 < Q := by dsimp only [Q]; positivity
have hF (k : ZMod (2 ^ J)) : 0 ≤ F k := sq_nonneg _
have hFbound (k : ZMod (2 ^ J)) : F k ≤ (A.card : ℝ) ^ 2 := by
have hh := norm_dft_le_sum_norm (cyclicSetIndicator A) k
rw [cyclic_set_indicator_norm_sum] at hh
exact pow_le_pow_left₀ (norm_nonneg _) hh 2
have hsumF : (∑ k : ZMod (2 ^ J), F k) = Q * (A.card : ℝ) := by
simpa only [F, Q, Nat.cast_pow, Nat.cast_ofNat, cyclic_set_indicator_sq_norm_sum] using
dft_parseval (cyclicSetIndicator A)
have hsum (k : ZMod (2 ^ J)) : (∑ x : ZMod (2 ^ J), F (x * k)) ≤ Q * (A.card : ℝ) ^ 2 := by
calc
_ ≤ ∑ _x : ZMod (2 ^ J), (A.card : ℝ) ^ 2 := Finset.sum_le_sum (fun x _ => hFbound _)
_ = _ := by simp [Q]
have hhigh (k : ZMod (2 ^ J)) (hk : k ∉ Z) :
(∑ x : ZMod (2 ^ J), F (x * k)) ≤ Q * M * (A.card : ℝ) ^ 2 := by
have hkL : L ≤ dyadicConductorLevel k := by
have hh : ¬ dyadicConductorLevel k ≤ L := by
intro hh
exact hk (Finset.mem_filter.mpr ⟨Finset.mem_univ _, hh⟩)
omega
have hh := dyadic_uniform_set_fourier_energy_coarse hL A hM hbound hkL
have heq : (∑ x : ZMod (2 ^ J), F (x * k)) =
Q * (∑ x : ZMod (2 ^ J), (1 / ((2 ^ J : ℕ) : ℝ)) * F (x * k)) := by
rw [← Finset.mul_sum]
simp only [Nat.cast_pow, Nat.cast_ofNat]
dsimp only [Q]
field_simp
calc
_ = _ := heq
_ ≤ Q * (M * (A.card : ℝ) ^ 2) := mul_le_mul_of_nonneg_left hh hQ.le
_ = _ := by ring
have hpoint (k : ZMod (2 ^ J)) : F k * (∑ x : ZMod (2 ^ J), F (x * k)) ≤
(if k ∈ Z then Q * (A.card : ℝ) ^ 4 else 0) + Q * M * (A.card : ℝ) ^ 2 * F k := by
by_cases hk : k ∈ Z
· rw [if_pos hk]
calc
_ ≤ (A.card : ℝ) ^ 2 * (Q * (A.card : ℝ) ^ 2) :=
mul_le_mul (hFbound k) (hsum k) (Finset.sum_nonneg (fun _ _ => hF _)) (by positivity)
_ = Q * (A.card : ℝ) ^ 4 := by ring
_ ≤ _ := le_add_of_nonneg_right (by positivity)
· rw [if_neg hk, zero_add]
calc
_ ≤ F k * (Q * M * (A.card : ℝ) ^ 2) := mul_le_mul_of_nonneg_left (hhigh k hk) (hF k)
_ = _ := by ring
have hZ : (Z.card : ℝ) ≤ (2 : ℝ) ^ L := by exact_mod_cast dyadic_low_conductor_card_le hL
apply (mul_le_mul_iff_right₀ hQ).mp
calc
_ = ∑ k : ZMod (2 ^ J), F k * (∑ x : ZMod (2 ^ J), F (x * k)) := by
simpa only [Q, F, Nat.cast_pow, Nat.cast_ofNat] using cyclic_set_dilate_collision_sum_fourier A
_ ≤ ∑ k : ZMod (2 ^ J), ((if k ∈ Z then Q * (A.card : ℝ) ^ 4 else 0) +
Q * M * (A.card : ℝ) ^ 2 * F k) := Finset.sum_le_sum (fun k _ => hpoint k)
_ = (Z.card : ℝ) * (Q * (A.card : ℝ) ^ 4) + Q * M * (A.card : ℝ) ^ 2 * (Q * (A.card : ℝ)) := by
rw [Finset.sum_add_distrib, ← Finset.mul_sum, hsumF]
rw [← Finset.sum_filter, Finset.filter_mem_eq_inter, Finset.univ_inter]
simp
_ ≤ (2 : ℝ) ^ L * (Q * (A.card : ℝ) ^ 4) + Q * M * (A.card : ℝ) ^ 2 * (Q * (A.card : ℝ)) := by
gcongr
_ = _ := by dsimp only [Q]; ring
theorem cyclic_convolution_set_indicator_left {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (g : ZMod q → ℂ) (z : ZMod q) :
cyclicConvolution (cyclicSetIndicator A) g z = ∑ a ∈ A, g (z - a) := by
classical
simp only [cyclicConvolution, cyclicSetIndicator, ite_mul, one_mul, zero_mul,
← Finset.sum_filter, Finset.filter_mem_eq_inter, Finset.univ_inter]
theorem cyclic_set_dilate_convolution_card {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (x z : ZMod q) :
cyclicConvolution (cyclicSetIndicator A)
(cyclicPushforward (cyclicSetIndicator A) (fun a => a * x)) z =
(((A ×ˢ A).filter (fun p => p.1 + p.2 * x = z)).card : ℂ) := by
classical
rw [cyclic_convolution_set_indicator_left]
simp_rw [cyclic_set_indicator_pushforward]
simp only [Finset.card_eq_sum_ones, Nat.cast_sum, Nat.cast_one,
Finset.sum_filter, Finset.sum_product]
apply Finset.sum_congr rfl
intro a ha
apply Finset.sum_congr rfl
intro b hb
have heq : b * x = z - a ↔ a + b * x = z := by
constructor
· intro h
rw [h, add_sub_cancel]
· intro h
rw [← h, add_sub_cancel_left]
simp only [heq, Nat.cast_ite, Nat.cast_one, Nat.cast_zero]
theorem finite_map_collision_lower {α β : Type*} [DecidableEq α] [DecidableEq β] [Fintype β]
(A : Finset α) (f : α → β) :
(A.card : ℝ) ^ 2 ≤ ((A.image f).card : ℝ) *
∑ y : β, ((A.filter (fun a => f a = y)).card : ℝ) ^ 2 := by
have hsum : (∑ y ∈ A.image f, ((A.filter (fun a => f a = y)).card : ℝ)) = (A.card : ℝ) := by
exact_mod_cast (Finset.card_eq_sum_card_image f A).symm
have hh := Finset.sum_mul_sq_le_sq_mul_sq (A.image f) (fun _ => (1 : ℝ))
(fun y => ((A.filter (fun a => f a = y)).card : ℝ))
simp only [one_mul, one_pow, Finset.sum_const, nsmul_eq_mul, mul_one, hsum] at hh
exact hh.trans (mul_le_mul_of_nonneg_left
(Finset.sum_le_sum_of_subset_of_nonneg (Finset.subset_univ _) (fun _ _ _ => sq_nonneg _))
(Nat.cast_nonneg _))
theorem ring_sum_dilate_product_image {R : Type*} [CommRing R] [DecidableEq R]
(A : Finset R) (x : R) :
(A ×ˢ A).image (fun p => p.1 + p.2 * x) = A + ringDilate x A := by
ext z
constructor
· intro hz
obtain ⟨⟨a, b⟩, hab, rfl⟩ := Finset.mem_image.mp hz
obtain ⟨ha, hb⟩ := Finset.mem_product.mp hab
exact Finset.mem_add.mpr ⟨a, ha, x * b, Finset.mem_image_of_mem _ hb, by rw [mul_comm x b]⟩
· intro hz
obtain ⟨a, ha, y, hy, rfl⟩ := Finset.mem_add.mp hz
obtain ⟨b, hb, rfl⟩ := Finset.mem_image.mp hy
exact Finset.mem_image.mpr ⟨(a, b), Finset.mem_product.mpr ⟨ha, hb⟩, by rw [mul_comm b x]⟩
theorem cyclic_set_dilate_sumset_collision {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (x : ZMod q) :
(A.card : ℝ) ^ 4 ≤ ((A + ringDilate x A).card : ℝ) * cyclicSetDilateCollision A x := by
have hh := finite_map_collision_lower (A ×ˢ A) (fun p => p.1 + p.2 * x)
rw [ring_sum_dilate_product_image] at hh
have heq : cyclicSetDilateCollision A x =
∑ z : ZMod q, (((A ×ˢ A).filter (fun p => p.1 + p.2 * x = z)).card : ℝ) ^ 2 := by
simp only [cyclicSetDilateCollision, cyclic_set_dilate_convolution_card, Complex.norm_natCast]
rw [heq]
calc
_ = ((A ×ˢ A).card : ℝ) ^ 2 := by rw [Finset.card_product, Nat.cast_mul]; ring
_ ≤ _ := hh
theorem ring_sum_stabilizer_collision_lower {q : ℕ} [NeZero q]
{A : Finset (ZMod q)} {K : ℝ} {x : ZMod q} (hA : A.Nonempty)
(hx : x ∈ ringSumStabilizer A K) :
(A.card : ℝ) ^ 3 ≤ K * cyclicSetDilateCollision A x := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hx' := (mem_ring_sum_stabilizer A K x).mp hx
apply (mul_le_mul_iff_right₀ hAp).mp
calc
_ = (A.card : ℝ) ^ 4 := by ring
_ ≤ _ := cyclic_set_dilate_sumset_collision A x
_ ≤ (K * (A.card : ℝ)) * cyclicSetDilateCollision A x :=
mul_le_mul_of_nonneg_right hx' (cyclic_set_dilate_collision_nonneg A x)
_ = _ := by ring
/-- A single coarse fiber bound controls the size of the full stabilizer,
without restricting its multipliers to units. -/
theorem dyadic_sum_stabilizer_card_bound {J L : ℕ} (hL : L ≤ J)
{A : Finset (ZMod (2 ^ J))} {M K : ℝ} (hA : A.Nonempty) (hM : 0 ≤ M) (hK : 0 ≤ K)
(hbound : ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤ M * (A.card : ℝ)) :
((ringSumStabilizer A K).card : ℝ) ≤ K * ((2 : ℝ) ^ L * (A.card : ℝ) + (2 : ℝ) ^ J * M) := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
apply (mul_le_mul_iff_left₀ (show (0 : ℝ) < (A.card : ℝ) ^ 3 by positivity)).mp
calc
_ = ∑ _x ∈ ringSumStabilizer A K, (A.card : ℝ) ^ 3 := by simp
_ ≤ ∑ x ∈ ringSumStabilizer A K, K * cyclicSetDilateCollision A x :=
Finset.sum_le_sum (fun x hx => ring_sum_stabilizer_collision_lower hA hx)
_ ≤ ∑ x : ZMod (2 ^ J), K * cyclicSetDilateCollision A x :=
Finset.sum_le_sum_of_subset_of_nonneg (Finset.subset_univ _)
(fun x _ _ => mul_nonneg hK (cyclic_set_dilate_collision_nonneg A x))
_ = K * ∑ x : ZMod (2 ^ J), cyclicSetDilateCollision A x := (Finset.mul_sum _ _ _).symm
_ ≤ K * ((2 : ℝ) ^ L * (A.card : ℝ) ^ 4 + (2 : ℝ) ^ J * M * (A.card : ℝ) ^ 3) :=
mul_le_mul_of_nonneg_left (dyadic_set_dilate_collision_sum_bound hL A hM hbound) hK
_ = _ := by ring
/-- Nonconcentration and a density deficit force a power-saving upper bound
on every additive stabilizer, uniformly in its parameter. -/
theorem exists_dyadic_sum_stabilizer_density_bound {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ c ε : ℝ, 0 < c ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A : Finset (ZMod (2 ^ J)), A.Nonempty →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ)) →
∀ K : ℝ, 0 ≤ K → ((ringSumStabilizer A K).card : ℝ) ≤
K * (2 : ℝ) ^ ((1 - c) * (J : ℝ)) := by
let c₀ := min (δ / 2) (γ * δ / 4)
have hc₀ : 0 < c₀ := lt_min (by positivity) (by positivity)
have hcδ : c₀ ≤ δ / 2 := min_le_left _ _
have hcγ : c₀ ≤ γ * δ / 4 := min_le_right _ _
obtain ⟨J₀, hJ₀⟩ := exists_nat_ge (max (8 / δ) (2 / c₀))
refine ⟨c₀ / 2, δ / 8, by positivity, by positivity, by linarith, J₀, ?_⟩
intro J hJ A hA hsize hmass K hK
have hJr : (J₀ : ℝ) ≤ J := by exact_mod_cast hJ
have hJ8 : 8 / δ ≤ (J : ℝ) := (le_max_left _ _).trans (hJ₀.trans hJr)
have hJ2 : 2 / c₀ ≤ (J : ℝ) := (le_max_right _ _).trans (hJ₀.trans hJr)
have hδJ : 8 ≤ δ * (J : ℝ) := by
have hh := (div_le_iff₀ hδ).mp hJ8
nlinarith
have hcJ : 2 ≤ c₀ * (J : ℝ) := by
have hh := (div_le_iff₀ hc₀).mp hJ2
nlinarith
let L := Nat.floor (δ * (J : ℝ) / 2)
have hLupper : (L : ℝ) ≤ δ * (J : ℝ) / 2 := Nat.floor_le (by positivity)
have hLlt : δ * (J : ℝ) / 2 < (L : ℝ) + 1 := Nat.lt_floor_add_one _
have hLlower : δ * (J : ℝ) / 4 ≤ (L : ℝ) := by linarith
have hεL : δ / 8 * (J : ℝ) < (L : ℝ) := by nlinarith
have hLJ : L ≤ J := by
have hh : (L : ℝ) ≤ (J : ℝ) := by nlinarith [show (0 : ℝ) ≤ J from Nat.cast_nonneg _]
exact_mod_cast hh
have hcard := dyadic_sum_stabilizer_card_bound hLJ hA
(show (0 : ℝ) ≤ (2 : ℝ) ^ (-γ * (L : ℝ)) by positivity) hK (hmass L hLJ hεL)
have hfirst : (2 : ℝ) ^ L * (A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - c₀) * (J : ℝ)) := by
calc
_ ≤ (2 : ℝ) ^ L * (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) :=
mul_le_mul_of_nonneg_left hsize (by positivity)
_ = (2 : ℝ) ^ ((L : ℝ) + (1 - δ) * (J : ℝ)) := by
rw [← Real.rpow_natCast, ← Real.rpow_add (by norm_num)]
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_right hcδ (Nat.cast_nonneg J : (0 : ℝ) ≤ J)
nlinarith
have hsecond : (2 : ℝ) ^ J * (2 : ℝ) ^ (-γ * (L : ℝ)) ≤
(2 : ℝ) ^ ((1 - c₀) * (J : ℝ)) := by
calc
_ = (2 : ℝ) ^ ((J : ℝ) - γ * (L : ℝ)) := by
rw [← Real.rpow_natCast, ← Real.rpow_add (by norm_num)]
congr 1
ring
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_right hcγ (Nat.cast_nonneg J : (0 : ℝ) ≤ J)
have hl := mul_le_mul_of_nonneg_left hLlower hγ.le
nlinarith
have htwo : (2 : ℝ) ≤ (2 : ℝ) ^ ((c₀ / 2) * (J : ℝ)) := by
calc
_ = (2 : ℝ) ^ (1 : ℝ) := (Real.rpow_one 2).symm
_ ≤ _ := Real.rpow_le_rpow_of_exponent_le (by norm_num) (by nlinarith)
calc
_ ≤ K * ((2 : ℝ) ^ L * (A.card : ℝ) + (2 : ℝ) ^ J * (2 : ℝ) ^ (-γ * (L : ℝ))) := hcard
_ ≤ K * ((2 : ℝ) ^ ((1 - c₀) * (J : ℝ)) + (2 : ℝ) ^ ((1 - c₀) * (J : ℝ))) := by gcongr
_ = K * (2 * (2 : ℝ) ^ ((1 - c₀) * (J : ℝ))) := by ring
_ ≤ K * ((2 : ℝ) ^ ((c₀ / 2) * (J : ℝ)) * (2 : ℝ) ^ ((1 - c₀) * (J : ℝ))) := by gcongr
_ = _ := by
rw [← Real.rpow_add (by norm_num)]
congr 2
ring
/- Iterated stabilizer growth and energy saving for unit dilates. -/
theorem exists_dyadic_sum_product_double_growth_of_projection {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ σ ε : ℝ, 0 < σ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A : Finset ℕ,
A.Nonempty → (∀ x ∈ A, x < 2 ^ J) →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * (j : ℝ)) ≤ ((dyadicProjection A j).card : ℝ)) →
(2 : ℝ) ^ (σ * (J : ℝ)) * (A.card : ℝ) ≤
((natResidueGenerators (natLinearQuadraticSet A) (2 ^ J) +
natResidueGenerators (natLinearQuadraticSet A) (2 ^ J)).card : ℝ) := by
obtain ⟨κ, ε, hκ, hε, hε4, K, J₀, hK, hgrowth⟩ :=
exists_dyadic_signed_sum_product_growth hγ hδ hδ1
let σ := κ / (4 * (K : ℝ) + 2)
have hden : 0 < 4 * (K : ℝ) + 2 := by positivity
have hσ : 0 < σ := div_pos hκ hden
have hexp : σ * ((2 * K + 1 : ℕ) : ℝ) = κ / 2 := by
dsimp [σ]
push_cast
field_simp
ring
refine ⟨σ, ε, hσ, hε, hε4, max J₀ 1, ?_⟩
intro J hJ A hA hbound hsize hmass
have hJ₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hJ1 : 1 ≤ J := (le_max_right _ _).trans hJ
have hJp : (0 : ℝ) < J := by exact_mod_cast (show 0 < J by omega)
have hAp : (0 : ℝ) < A.card := by exact_mod_cast Finset.card_pos.mpr hA
by_contra h
have hupper := nat_signed_hull_bound_of_double_bound (natLinearQuadraticSet A) K
(q := 2 ^ J) (by exact_mod_cast nat_linear_quadratic_generators_card_ge hbound)
(show 0 ≤ (2 : ℝ) ^ (σ * (J : ℝ)) by positivity) (lt_of_not_ge h).le
have hpowlt : ((2 : ℝ) ^ (σ * (J : ℝ))) ^ (2 * K + 1) < (2 : ℝ) ^ (κ * (J : ℝ)) := by
rw [← Real.rpow_mul_natCast (by norm_num)]
apply Real.rpow_lt_rpow_of_exponent_lt (by norm_num)
have hEq : σ * (J : ℝ) * ((2 * K + 1 : ℕ) : ℝ) = κ / 2 * (J : ℝ) := by
rw [mul_right_comm, hexp]
rw [hEq]
nlinarith [mul_pos hκ hJp]
exact (not_lt_of_ge (hgrowth J hJ₀ A hA hbound hsize hmass))
(hupper.trans_lt (mul_lt_mul_of_pos_right hpowlt hAp))
def ringQuadraticClosure {R : Type*} [Ring R] [DecidableEq R] (S : Finset R) : Finset R :=
insert 0 (S ∪ S * S) + insert 0 (S ∪ S * S)
def ringQuadraticIterate {R : Type*} [Ring R] [DecidableEq R] (S : Finset R) : ℕ → Finset R
| 0 => S
| n + 1 => ringQuadraticClosure (ringQuadraticIterate S n)
def dyadicRingProjection {J : ℕ} (A : Finset (ZMod (2 ^ J))) (j : ℕ) : Finset (ZMod (2 ^ j)) :=
A.image (fun x => (x.val : ZMod (2 ^ j)))
theorem ring_quadratic_closure_extensive {R : Type*} [Ring R] [DecidableEq R] (S : Finset R) :
S ⊆ ringQuadraticClosure S := by
intro x hx
exact Finset.mem_add.mpr ⟨x, Finset.mem_insert_of_mem (Finset.mem_union_left _ hx),
0, Finset.mem_insert_self _ _, add_zero x⟩
theorem ring_quadratic_iterate_extensive {R : Type*} [Ring R] [DecidableEq R]
(S : Finset R) (n : ℕ) : S ⊆ ringQuadraticIterate S n := by
induction n with
| zero => exact Finset.Subset.refl _
| succ n ih => exact ih.trans (ring_quadratic_closure_extensive _)
theorem ring_quadratic_iterate_stabilizer {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
{A S : Finset R} {K : ℝ} (hA : A.Nonempty) (hK : 1 ≤ K)
(hdouble : ((A + A).card : ℝ) ≤ K * (A.card : ℝ))
(hS : S ⊆ ringSumStabilizer A K) (n : ℕ) :
ringQuadraticIterate S n ⊆ ringSumStabilizer A (K ^ (64 ^ n)) := by
induction n with
| zero => simpa only [ringQuadraticIterate, pow_zero, pow_one] using hS
| succ n ih =>
have hKK : K ≤ K ^ (64 ^ n) := by
have hn : 1 ≤ (64 : ℕ) ^ n := Nat.succ_le_of_lt (pow_pos (by norm_num) n)
simpa only [pow_one] using pow_le_pow_right₀ hK hn
have hd : ((A + A).card : ℝ) ≤ K ^ (64 ^ n) * (A.card : ℝ) :=
hdouble.trans (mul_le_mul_of_nonneg_right hKK (Nat.cast_nonneg _))
have hh := ring_sum_stabilizer_quadratic_closure hA (one_le_pow₀ hK) hd ih
have heq : (K ^ (64 ^ n)) ^ (64 : ℕ) = K ^ (64 ^ (n + 1)) := by
rw [← pow_mul, ← pow_succ]
rw [heq] at hh
exact hh
theorem dyadic_ring_projection_mono {J : ℕ} {A B : Finset (ZMod (2 ^ J))}
(hAB : A ⊆ B) (j : ℕ) : dyadicRingProjection A j ⊆ dyadicRingProjection B j :=
Finset.image_subset_image hAB
theorem dyadic_ring_projection_card {J : ℕ} (A : Finset (ZMod (2 ^ J))) (j : ℕ) :
(dyadicRingProjection A j).card = (dyadicProjection (A.image ZMod.val) j).card := by
rw [← Finset.card_image_of_injective (dyadicRingProjection A j) (ZMod.val_injective _)]
simp only [dyadicRingProjection, dyadicProjection, Finset.image_image, Function.comp_def,
ZMod.val_natCast]
theorem zmod_cast_image_val {q : ℕ} [NeZero q] (A : Finset (ZMod q)) :
(A.image ZMod.val).image (fun n : ℕ => (n : ZMod q)) = A := by
simp [Finset.image_image]
/-- Sum-product growth in the native residue ring, under projection lower bounds.
These hypotheses pass to every superset, as needed for iteration. -/
theorem exists_dyadic_ring_quadratic_growth {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ σ ε : ℝ, 0 < σ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A : Finset (ZMod (2 ^ J)), A.Nonempty →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * (j : ℝ)) ≤ ((dyadicRingProjection A j).card : ℝ)) →
(2 : ℝ) ^ (σ * (J : ℝ)) * (A.card : ℝ) ≤ ((ringQuadraticClosure A).card : ℝ) := by
obtain ⟨σ, ε, hσ, hε, hε4, J₀, hg⟩ :=
exists_dyadic_sum_product_double_growth_of_projection hγ hδ hδ1
refine ⟨σ, ε, hσ, hε, hε4, J₀, ?_⟩
intro J hJ A hA hsize hproj
have hcard : (A.image ZMod.val).card = A.card :=
Finset.card_image_of_injective _ (ZMod.val_injective _)
have hb : ∀ x ∈ A.image ZMod.val, x < 2 ^ J := by
intro x hx
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hx
exact ZMod.val_lt _
have hh := hg J hJ (A.image ZMod.val) (hA.image _) hb
(by simpa only [hcard] using hsize)
(fun j hj hjε => by simpa only [← dyadic_ring_projection_card] using hproj j hj hjε)
simpa only [hcard, nat_linear_quadratic_residue_generators, zmod_cast_image_val,
ringQuadraticClosure] using hh
theorem dyadic_ring_quadratic_iterate_card_growth {J R : ℕ}
{S : Finset (ZMod (2 ^ J))} {g B γ ε : ℝ} (hS : S.Nonempty) (hg : 0 ≤ g)
(hproj : ∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * (j : ℝ)) ≤ ((dyadicRingProjection S j).card : ℝ))
(hgrowth : ∀ U : Finset (ZMod (2 ^ J)), U.Nonempty → (U.card : ℝ) ≤ B →
(∀ j : ℕ, j ≤ J → ε * (J : ℝ) < (j : ℝ) →
(2 : ℝ) ^ (γ * (j : ℝ)) ≤ ((dyadicRingProjection U j).card : ℝ)) →
g * (U.card : ℝ) ≤ ((ringQuadraticClosure U).card : ℝ))
(hsize : ∀ i : ℕ, i < R → ((ringQuadraticIterate S i).card : ℝ) ≤ B) :
g ^ R * (S.card : ℝ) ≤ ((ringQuadraticIterate S R).card : ℝ) := by
have hi : ∀ i : ℕ, i ≤ R → g ^ i * (S.card : ℝ) ≤ ((ringQuadraticIterate S i).card : ℝ) := by
intro i
induction i with
| zero => intro _; simp [ringQuadraticIterate]
| succ i ih =>
intro hi
have hsub := ring_quadratic_iterate_extensive S i
calc
_ = g * (g ^ i * (S.card : ℝ)) := by rw [pow_succ]; ring
_ ≤ g * ((ringQuadraticIterate S i).card : ℝ) :=
mul_le_mul_of_nonneg_left (ih (by omega)) hg
_ ≤ _ := hgrowth _ (hS.mono hsub) (hsize i (by omega)) (fun j hj hεj =>
(hproj j hj hεj).trans (by exact_mod_cast Finset.card_le_card (dyadic_ring_projection_mono hsub j)))
exact hi R le_rfl
/-- A nonconcentrated set of moderate size cannot have a well-projecting
family of stabilizers at a sufficiently small power of the modulus. -/
theorem exists_dyadic_no_projecting_stabilizer {α β δ : ℝ}
(hα : 0 < α) (hβ : 0 < β) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ η ε : ℝ, 0 < η ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A S : Finset (ZMod (2 ^ J)), A.Nonempty → S.Nonempty →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-α * (L : ℝ)) * (A.card : ℝ)) →
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) →
(2 : ℝ) ^ (β * (L : ℝ)) ≤ ((dyadicRingProjection S L).card : ℝ)) →
((A + A).card : ℝ) ≤ (2 : ℝ) ^ (η * (J : ℝ)) * (A.card : ℝ) →
¬ S ⊆ ringSumStabilizer A ((2 : ℝ) ^ (η * (J : ℝ))) := by
obtain ⟨c₀, ε₀, hc₀, hε₀, hε₀4, J₀, hstab⟩ :=
exists_dyadic_sum_stabilizer_density_bound hα hδ hδ1
let c := min c₀ 1
have hc : 0 < c := lt_min hc₀ (by norm_num)
have hcc₀ : c ≤ c₀ := min_le_left _ _
have hc1 : c ≤ 1 := min_le_right _ _
obtain ⟨σ, ε₁, hσ, hε₁, hε₁4, J₁, hgrowth⟩ :=
exists_dyadic_ring_quadratic_growth hβ (show 0 < c / 2 by positivity) (by linarith)
obtain ⟨R, hR⟩ := exists_nat_ge (2 / σ)
have hσR : 2 ≤ σ * (R : ℝ) := by
have hh := (div_le_iff₀ hσ).mp hR
nlinarith
let η := c / (2 * ((64 ^ R : ℕ) : ℝ))
have hden : (0 : ℝ) < (64 ^ R : ℕ) := by positivity
have hη : 0 < η := div_pos hc (mul_pos (by norm_num) hden)
have hηR : η * ((64 ^ R : ℕ) : ℝ) = c / 2 := by
dsimp [η]
field_simp
refine ⟨η, min ε₀ ε₁, hη, lt_min hε₀ hε₁,
(min_le_left _ _).trans hε₀4, max (max J₀ J₁) 1, ?_⟩
intro J hJ A S hA hS hsize hmass hproj hdouble hSstab
have hJ₀ : J₀ ≤ J := (le_max_left _ _).trans ((le_max_left _ _).trans hJ)
have hJ₁ : J₁ ≤ J := (le_max_right _ _).trans ((le_max_left _ _).trans hJ)
have hJp : (0 : ℝ) < J := by exact_mod_cast (lt_of_lt_of_le (by norm_num : 0 < (1 : ℕ)) ((le_max_right _ _).trans hJ))
have hJ0 := hJp.le
have hm : ∀ L : ℕ, L ≤ J → ε₀ * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-α * (L : ℝ)) * (A.card : ℝ) := by
intro L hL hεL
exact hmass L hL ((mul_le_mul_of_nonneg_right (min_le_left _ _) hJ0).trans_lt hεL)
have hp : ∀ L : ℕ, L ≤ J → ε₁ * (J : ℝ) < (L : ℝ) →
(2 : ℝ) ^ (β * (L : ℝ)) ≤ ((dyadicRingProjection S L).card : ℝ) := by
intro L hL hεL
exact hproj L hL ((mul_le_mul_of_nonneg_right (min_le_right _ _) hJ0).trans_lt hεL)
let K := (2 : ℝ) ^ (η * (J : ℝ))
have hK : 1 ≤ K := Real.one_le_rpow (by norm_num) (mul_nonneg hη.le hJ0)
have hiter : ∀ i : ℕ, i ≤ R →
((ringQuadraticIterate S i).card : ℝ) ≤ (2 : ℝ) ^ ((1 - c / 2) * (J : ℝ)) := by
intro i hi
have hsub := ring_quadratic_iterate_stabilizer hA hK hdouble hSstab i
have hexp : η * ((64 ^ i : ℕ) : ℝ) ≤ c / 2 := by
rw [← hηR]
apply mul_le_mul_of_nonneg_left _ hη.le
exact_mod_cast Nat.pow_le_pow_right (by norm_num : 0 < (64 : ℕ)) hi
calc
_ ≤ ((ringSumStabilizer A (K ^ (64 ^ i))).card : ℝ) := by exact_mod_cast Finset.card_le_card hsub
_ ≤ K ^ (64 ^ i) * (2 : ℝ) ^ ((1 - c₀) * (J : ℝ)) :=
hstab J hJ₀ A hA hsize hm _ (by positivity)
_ = (2 : ℝ) ^ ((η * ((64 ^ i : ℕ) : ℝ) + 1 - c₀) * (J : ℝ)) := by
dsimp only [K]
rw [← Real.rpow_mul_natCast (by norm_num), ← Real.rpow_add (by norm_num)]
congr 1
ring
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
apply mul_le_mul_of_nonneg_right _ hJ0
linarith
have hlower := dyadic_ring_quadratic_iterate_card_growth hS
(show (0 : ℝ) ≤ (2 : ℝ) ^ (σ * (J : ℝ)) by positivity) hp
(hgrowth J hJ₁) (fun i hi => hiter i hi.le)
have hcard : ((ringQuadraticIterate S R).card : ℝ) ≤ (2 : ℝ) ^ J := by
have hh : (ringQuadraticIterate S R).card ≤ 2 ^ J := by
simpa only [ZMod.card] using (Finset.card_le_univ (s := ringQuadraticIterate S R))
exact_mod_cast hh
have hS1 : (1 : ℝ) ≤ S.card := by exact_mod_cast hS.card_pos
have hupper : ((2 : ℝ) ^ (σ * (J : ℝ))) ^ R ≤ (2 : ℝ) ^ J := by
calc
_ = ((2 : ℝ) ^ (σ * (J : ℝ))) ^ R * 1 := (mul_one _).symm
_ ≤ ((2 : ℝ) ^ (σ * (J : ℝ))) ^ R * (S.card : ℝ) :=
mul_le_mul_of_nonneg_left hS1 (by positivity)
_ ≤ _ := hlower.trans hcard
have hlt : (2 : ℝ) ^ J < ((2 : ℝ) ^ (σ * (J : ℝ))) ^ R := by
rw [← Real.rpow_natCast, ← Real.rpow_mul_natCast (by norm_num)]
apply Real.rpow_lt_rpow_of_exponent_lt (by norm_num)
have hh := mul_le_mul_of_nonneg_right hσR hJ0
nlinarith
exact (not_lt_of_ge hupper) hlt
theorem dyadic_ring_projection_growth_of_fiber_bound {J L : ℕ}
{A : Finset (ZMod (2 ^ J))} {γ : ℝ} (hA : A.Nonempty)
(hmass : ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ)) :
(2 : ℝ) ^ (γ * (L : ℝ)) ≤ ((dyadicRingProjection A L).card : ℝ) := by
have hAp : (0 : ℝ) < A.card := by exact_mod_cast hA.card_pos
have hh : (A.card : ℝ) ≤ ((dyadicRingProjection A L).card : ℝ) *
((2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ)) := by
conv_lhs => rw [Finset.card_eq_sum_card_image (fun a => (a.val : ZMod (2 ^ L))) A, Nat.cast_sum]
calc
_ ≤ ∑ _r ∈ dyadicRingProjection A L,
(2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ) :=
Finset.sum_le_sum (fun r _ => hmass r)
_ = _ := by simp
have hbound : 1 ≤ ((dyadicRingProjection A L).card : ℝ) * (2 : ℝ) ^ (-γ * (L : ℝ)) := by
apply (mul_le_mul_iff_left₀ hAp).mp
simpa only [one_mul, mul_assoc] using hh
have hinv : (2 : ℝ) ^ (-γ * (L : ℝ)) * (2 : ℝ) ^ (γ * (L : ℝ)) = 1 := by
rw [← Real.rpow_add (by norm_num), show -γ * (L : ℝ) + γ * (L : ℝ) = 0 by ring,
Real.rpow_zero]
calc
_ = 1 * (2 : ℝ) ^ (γ * (L : ℝ)) := (one_mul _).symm
_ ≤ (((dyadicRingProjection A L).card : ℝ) * (2 : ℝ) ^ (-γ * (L : ℝ))) *
(2 : ℝ) ^ (γ * (L : ℝ)) := mul_le_mul_of_nonneg_right hbound (by positivity)
_ = _ := by rw [mul_assoc, hinv, mul_one]
theorem finite_fiber_bound_large_subset {X Y : Type*} [DecidableEq X] [DecidableEq Y]
{A B : Finset X} (π : X → Y) {D M : ℝ} (hBA : B ⊆ A) (hM : 0 ≤ M)
(hsize : (A.card : ℝ) ≤ D * (B.card : ℝ))
(hbound : ∀ r : Y, ((A.filter (fun a => π a = r)).card : ℝ) ≤ M * (A.card : ℝ)) :
∀ r : Y, ((B.filter (fun a => π a = r)).card : ℝ) ≤ (D * M) * (B.card : ℝ) := by
intro r
calc
_ ≤ ((A.filter (fun a => π a = r)).card : ℝ) := by
exact_mod_cast Finset.card_le_card (Finset.filter_subset_filter _ hBA)
_ ≤ M * (A.card : ℝ) := hbound r
_ ≤ M * (D * (B.card : ℝ)) := mul_le_mul_of_nonneg_left hsize hM
_ = _ := by ring
theorem ring_unit_dilate_fiber_card {R Q : Type*} [Ring R] [Ring Q]
[DecidableEq R] [DecidableEq Q] (π : R →+* Q) (u : Rˣ) (A : Finset R) (r : Q) :
((ringDilate (u : R) A).filter (fun a => π a = r)).card =
(A.filter (fun a => π a = π ((u⁻¹ : Rˣ) : R) * r)).card := by
unfold ringDilate
have hinj : Function.Injective (fun x : R => (u : R) * x) := (ringUnitMulAddEquiv u).injective
rw [Finset.filter_image, Finset.card_image_of_injective _ hinj]
congr 1
apply Finset.filter_congr
intro x hx
rw [map_mul]
exact (Units.eq_inv_mul_iff_mul_eq (Units.map π.toMonoidHom u)).symm
theorem dyadic_unit_dilate_fiber_bound {J L : ℕ} (hL : L ≤ J)
(u : (ZMod (2 ^ J))ˣ) {A : Finset (ZMod (2 ^ J))} {M : ℝ}
(hbound : ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤ M * (A.card : ℝ)) :
∀ r : ZMod (2 ^ L),
(((ringDilate (u : ZMod (2 ^ J)) A).filter
(fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤ M * (A.card : ℝ) := by
let π : ZMod (2 ^ J) →+* ZMod (2 ^ L) := ZMod.castHom (pow_dvd_pow 2 hL) _
have hπ : ∀ x : ZMod (2 ^ J), π x = (x.val : ZMod (2 ^ L)) := by
intro x
exact ZMod.cast_eq_val _
intro r
have hh := ring_unit_dilate_fiber_card π u A r
simp only [hπ] at hh
rw [hh]
exact hbound _
theorem unit_relative_image_eq_dilate {R : Type*} [Ring R] [DecidableEq R]
(u : Rˣ) (T : Finset Rˣ) :
T.image (fun v => ((u⁻¹ * v : Rˣ) : R)) =
ringDilate ((u⁻¹ : Rˣ) : R) (T.image (fun v : Rˣ => (v : R))) := by
simp only [ringDilate, Finset.image_image, Function.comp_def, Units.val_mul]
theorem exists_dyadic_fixed_power_absorption (a p : ℕ) {τ ξ : ℝ}
(hgap : (p : ℝ) * τ < ξ) :
∃ J₀ : ℕ, ∀ J : ℕ, J₀ ≤ J →
(2 : ℝ) ^ a * ((2 : ℝ) ^ (τ * (J : ℝ))) ^ p ≤ (2 : ℝ) ^ (ξ * (J : ℝ)) := by
have hg : 0 < ξ - (p : ℝ) * τ := sub_pos.mpr hgap
obtain ⟨J₀, hJ₀⟩ := exists_nat_ge ((a : ℝ) / (ξ - (p : ℝ) * τ))
refine ⟨J₀, ?_⟩
intro J hJ
have hJr : (J₀ : ℝ) ≤ (J : ℝ) := by exact_mod_cast hJ
have hh := (div_le_iff₀ hg).mp (hJ₀.trans hJr)
calc
_ = (2 : ℝ) ^ ((a : ℝ) + τ * (J : ℝ) * (p : ℝ)) := by
rw [← Real.rpow_natCast, ← Real.rpow_mul_natCast (by norm_num),
← Real.rpow_add (by norm_num)]
_ ≤ _ := Real.rpow_le_rpow_of_exponent_le (by norm_num) (by nlinarith)
theorem dyadic_unit_extraction_fiber_bounds {J : ℕ} {γ ε H : ℝ}
(hγ : 0 < γ) {A B S : Finset (ZMod (2 ^ J))} {T : Finset (ZMod (2 ^ J))ˣ}
(u₀ : (ZMod (2 ^ J))ˣ) (hBA : B ⊆ A)
(hST : S ⊆ T.image (fun u : (ZMod (2 ^ J))ˣ => ((u₀⁻¹ * u : (ZMod (2 ^ J))ˣ) : ZMod (2 ^ J))))
(hBlarge : (A.card : ℝ) ≤ H * (B.card : ℝ))
(hSlarge : (T.card : ℝ) ≤ H * (S.card : ℝ))
(hHcap : H ≤ (2 : ℝ) ^ ((γ * ε / 2) * (J : ℝ)))
(hAmass : ∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ))
(hTmass : ∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
(((T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).filter
(fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (T.card : ℝ)) :
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((B.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) * (B.card : ℝ)) ∧
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((S.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) * (S.card : ℝ)) := by
classical
have hloss : ∀ L : ℕ, ε * (J : ℝ) < (L : ℝ) →
H * (2 : ℝ) ^ (-γ * (L : ℝ)) ≤ (2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) := by
intro L hL
calc
_ ≤ (2 : ℝ) ^ ((γ * ε / 2) * (J : ℝ)) * (2 : ℝ) ^ (-γ * (L : ℝ)) :=
mul_le_mul_of_nonneg_right hHcap (by positivity)
_ = (2 : ℝ) ^ ((γ * ε / 2) * (J : ℝ) - γ * (L : ℝ)) := by
rw [← Real.rpow_add (by norm_num)]; congr 1; ring
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith only [mul_lt_mul_of_pos_left hL hγ]
have hBmass : ∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((B.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) * (B.card : ℝ) := by
intro L hL hεL r
exact (finite_fiber_bound_large_subset (fun a : ZMod (2 ^ J) => (a.val : ZMod (2 ^ L))) hBA
(show 0 ≤ (2 : ℝ) ^ (-γ * (L : ℝ)) by positivity) hBlarge (hAmass L hL hεL) r).trans
(mul_le_mul_of_nonneg_right (hloss L hεL) (Nat.cast_nonneg _))
let U := ringDilate ((u₀⁻¹ : (ZMod (2 ^ J))ˣ) : ZMod (2 ^ J))
(T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J))))
have hTcard : (T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).card = T.card :=
Finset.card_image_of_injective _ Units.val_injective
have hUcard : U.card = T.card := by rw [ring_dilate_unit_card, hTcard]
have hSU : S ⊆ U := by simpa only [unit_relative_image_eq_dilate] using hST
have hSmass : ∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((S.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) * (S.card : ℝ) := by
intro L hL hεL r
have huMass : ∀ r : ZMod (2 ^ L),
((U.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (U.card : ℝ) := by
intro r
have hh := dyadic_unit_dilate_fiber_bound hL u₀⁻¹
(A := T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J))))
(M := (2 : ℝ) ^ (-γ * (L : ℝ)))
(fun r => by simpa only [hTcard] using hTmass L hL hεL r) r
simpa only [hTcard, hUcard] using hh
exact (finite_fiber_bound_large_subset (fun a : ZMod (2 ^ J) => (a.val : ZMod (2 ^ L))) hSU
(show 0 ≤ (2 : ℝ) ^ (-γ * (L : ℝ)) by positivity)
(by simpa only [hUcard] using hSlarge) huMass r).trans
(mul_le_mul_of_nonneg_right (hloss L hεL) (Nat.cast_nonneg _))
exact ⟨hBmass, hSmass⟩
theorem dyadic_energy_parameter_square (K : ℝ) :
((2 : ℝ) ^ (82 : ℕ) * K ^ 30) ^ 2 = (2 : ℝ) ^ (164 : ℕ) * K ^ 60 := by
ring
theorem dyadic_energy_parameter_lower (K : ℝ) (hK : 1 ≤ K) :
16 * K ≤ (2 : ℝ) ^ (17 : ℕ) * K ^ 4 := by
have hh : K ≤ K ^ (4 : ℕ) := by
simpa only [pow_one] using pow_le_pow_right₀ hK (show 1 ≤ (4 : ℕ) by norm_num)
norm_num only [Nat.reducePow]
nlinarith only [hh, hK]
theorem exists_dyadic_unit_dilate_energy_saving {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A : Finset (ZMod (2 ^ J)), ∀ T : Finset (ZMod (2 ^ J))ˣ,
A.Nonempty → T.Nonempty → (A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ)) →
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
(((T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).filter
(fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (T.card : ℝ)) →
∃ u ∈ T, (2 : ℝ) ^ (τ * (J : ℝ)) *
(Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) A) : ℝ) < (A.card : ℝ) ^ 3 := by
classical
obtain ⟨η, ε, hη, hε, hε4, J₀, hobstruct⟩ :=
exists_dyadic_no_projecting_stabilizer (show 0 < γ / 2 by positivity)
(show 0 < γ / 2 by positivity) hδ hδ1
let τ := min (η / 120) (γ * ε / 16)
have hτ : 0 < τ := lt_min (by positivity) (by positivity)
have hτη : τ ≤ η / 120 := min_le_left _ _
have hτγε : τ ≤ γ * ε / 16 := min_le_right _ _
obtain ⟨J₁, hJ₁⟩ := exists_dyadic_fixed_power_absorption 164 60
(show (60 : ℝ) * τ < η by nlinarith only [hη, hτη])
obtain ⟨J₂, hJ₂⟩ := exists_dyadic_fixed_power_absorption 17 4
(show (4 : ℝ) * τ < γ * ε / 2 by nlinarith only [hτγε, mul_pos hγ hε])
refine ⟨τ, ε, hτ, hε, hε4, max J₀ (max J₁ J₂), ?_⟩
intro J hJ A T hA hT hsize hAmass hTmass
have hj₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hj₁ : J₁ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans hJ)
have hj₂ : J₂ ≤ J := (le_max_right _ _).trans ((le_max_right _ _).trans hJ)
let K := (2 : ℝ) ^ (τ * (J : ℝ))
have hKp : 0 < K := by positivity
have hK : 1 ≤ K := Real.one_le_rpow (by norm_num) (mul_nonneg hτ.le (Nat.cast_nonneg J))
by_contra h
push Not at h
obtain ⟨B, hBA, hB, hBsize, u₀, hu₀, S, hST, hS, hSsize, hunit, hstab⟩ :=
finite_many_unit_dilates_stabilizer hA hT hKp h
let H := (2 : ℝ) ^ (17 : ℕ) * K ^ 4
let D := (2 : ℝ) ^ (82 : ℕ) * K ^ 30
have hD : 1 ≤ D := by
exact one_le_mul_of_one_le_of_one_le (by norm_num) (one_le_pow₀ hK)
have hDcap : D ^ 2 ≤ (2 : ℝ) ^ (η * (J : ℝ)) := by
have heq : D ^ 2 = (2 : ℝ) ^ (164 : ℕ) * K ^ 60 := dyadic_energy_parameter_square K
rw [heq]
exact hJ₁ J hj₁
have hHcap : H ≤ (2 : ℝ) ^ ((γ * ε / 2) * (J : ℝ)) := hJ₂ J hj₂
have h16 : 16 * K ≤ H := dyadic_energy_parameter_lower K hK
have hBlarge : (A.card : ℝ) ≤ H * (B.card : ℝ) := by
have hh := (div_le_iff₀ (show 0 < 16 * K by positivity)).mp hBsize
calc
_ ≤ (16 * K) * (B.card : ℝ) := by simpa only [mul_comm] using hh
_ ≤ _ := mul_le_mul_of_nonneg_right h16 (Nat.cast_nonneg _)
have hSlarge : (T.card : ℝ) ≤ H * (S.card : ℝ) := by
have hh := (div_le_iff₀ (show 0 < 131072 * K ^ 4 by positivity)).mp hSsize
simpa only [H, show (2 : ℝ) ^ (17 : ℕ) = 131072 by norm_num, mul_comm] using hh
obtain ⟨hBmass, hSmass⟩ := dyadic_unit_extraction_fiber_bounds hγ u₀ hBA hST
hBlarge hSlarge hHcap hAmass hTmass
have hBbound : (B.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) :=
(show (B.card : ℝ) ≤ A.card by exact_mod_cast Finset.card_le_card hBA).trans hsize
have hSproj : ∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) →
(2 : ℝ) ^ ((γ / 2) * (L : ℝ)) ≤ ((dyadicRingProjection S L).card : ℝ) :=
fun L hL hεL => dyadic_ring_projection_growth_of_fiber_bound hS (hSmass L hL hεL)
obtain ⟨x, hx⟩ := hS
obtain ⟨u, hu⟩ := hunit x hx
have hdouble : ((B + B).card : ℝ) ≤ (2 : ℝ) ^ (η * (J : ℝ)) * (B.card : ℝ) := by
have hh := ring_sum_stabilizer_unit_doubling hB (show 0 ≤ D by positivity) u
(by simpa only [hu] using hstab hx)
exact hh.trans (mul_le_mul_of_nonneg_right hDcap (Nat.cast_nonneg _))
have hSstab : S ⊆ ringSumStabilizer B ((2 : ℝ) ^ (η * (J : ℝ))) := by
have hDD : D ≤ D ^ (2 : ℕ) := by
simpa only [pow_one] using pow_le_pow_right₀ hD (show 1 ≤ (2 : ℕ) by norm_num)
exact hstab.trans (ring_sum_stabilizer_mono B (hDD.trans hDcap))
exact hobstruct J hj₀ B S hB ⟨x, hx⟩ hBbound hBmass hSproj hdouble hSstab
theorem finite_add_energy_upper {G : Type*} [AddCommGroup G] [Fintype G] [DecidableEq G]
(A B : Finset G) : (Finset.addEnergy A B : ℝ) ≤ (A.card : ℝ) * (B.card : ℝ) ^ 2 := by
rw [← finite_difference_energy_eq_addEnergy, ← finite_difference_energy_sum_real]
calc
_ ≤ ∑ x : G, (B.card : ℝ) * (finiteDifferenceCount A B x : ℝ) := by
apply Finset.sum_le_sum
intro x hx
have hh : (finiteDifferenceCount A B x : ℝ) ≤ B.card := by
exact_mod_cast finite_difference_count_le_right A B x
simpa only [pow_two] using mul_le_mul_of_nonneg_right hh
(Nat.cast_nonneg (finiteDifferenceCount A B x) : (0 : ℝ) ≤ finiteDifferenceCount A B x)
_ = _ := by rw [← Finset.mul_sum, finite_difference_count_sum_real]; ring
theorem ring_unit_dilate_energy_upper {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
(A : Finset R) (u : Rˣ) :
(Finset.addEnergy A (ringDilate (u : R) A) : ℝ) ≤ (A.card : ℝ) ^ 3 := by
have hh := finite_add_energy_upper A (ringDilate (u : R) A)
rw [ring_dilate_unit_card] at hh
calc _ ≤ (A.card : ℝ) * (A.card : ℝ) ^ 2 := hh
_ = _ := by ring
/-- A small value in every sufficiently large subset bounds the full average. -/
theorem finite_sum_bound_of_hereditary_small_value {X : Type*} [DecidableEq X]
{T : Finset X} {f : X → ℝ} {ρ a M : ℝ}
(hT : T.Nonempty) (hρ : 0 < ρ) (ha : 0 ≤ a) (hM : 0 ≤ M)
(hupper : ∀ x ∈ T, f x ≤ M)
(hsmall : ∀ U : Finset X, U ⊆ T → U.Nonempty →
ρ * (T.card : ℝ) ≤ (U.card : ℝ) → ∃ x ∈ U, f x < a * M) :
∑ x ∈ T, f x ≤ (ρ + a) * (T.card : ℝ) * M := by
classical
let U := T.filter (fun x => a * M ≤ f x)
have hU : (U.card : ℝ) < ρ * (T.card : ℝ) := by
by_contra h
have hh := le_of_not_gt h
have hTp : (0 : ℝ) < T.card := by exact_mod_cast hT.card_pos
have hUp : (0 : ℝ) < U.card := (mul_pos hρ hTp).trans_le hh
obtain ⟨x, hx, hfx⟩ := hsmall U (Finset.filter_subset _ _)
(Finset.card_pos.mp (by exact_mod_cast hUp)) hh
exact (not_lt_of_ge (Finset.mem_filter.mp hx).2) hfx
have hsplit : ∑ x ∈ T, f x =
(∑ x ∈ T.filter (fun x => a * M ≤ f x), f x) +
∑ x ∈ T.filter (fun x => ¬ a * M ≤ f x), f x := by
rw [Finset.sum_filter, Finset.sum_filter, ← Finset.sum_add_distrib]
apply Finset.sum_congr rfl
intro x hx
split_ifs <;> simp_all
rw [hsplit]
calc
_ ≤ (∑ _x ∈ U, M) + ∑ _x ∈ T.filter (fun x => ¬ a * M ≤ f x), a * M := by
apply add_le_add
· exact Finset.sum_le_sum (fun x hx => hupper x (Finset.mem_filter.mp hx).1)
· exact Finset.sum_le_sum (fun x hx => (lt_of_not_ge (Finset.mem_filter.mp hx).2).le)
_ = (U.card : ℝ) * M + ((T.filter (fun x => ¬ a * M ≤ f x)).card : ℝ) * (a * M) := by simp
_ ≤ (ρ * (T.card : ℝ)) * M + (T.card : ℝ) * (a * M) := by
apply add_le_add (mul_le_mul_of_nonneg_right hU.le hM)
apply mul_le_mul_of_nonneg_right _ (mul_nonneg ha hM)
exact_mod_cast Finset.card_filter_le T (fun x => ¬ a * M ≤ f x)
_ = _ := by ring
/-- Uniform power-saving decay for the average mixed additive energy over a
nonconcentrated family of unit dilates. -/
theorem exists_dyadic_average_unit_energy_decay {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A : Finset (ZMod (2 ^ J)), ∀ T : Finset (ZMod (2 ^ J))ˣ,
A.Nonempty → T.Nonempty → (A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ)) →
(∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
(((T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).filter
(fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (T.card : ℝ)) →
(∑ u ∈ T, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) A) : ℝ)) ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * (T.card : ℝ) * (A.card : ℝ) ^ 3 := by
classical
obtain ⟨κ, ε, hκ, hε, hε4, J₀, hpoint⟩ :=
exists_dyadic_unit_dilate_energy_saving (show 0 < γ / 2 by positivity) hδ hδ1
let ρ := min κ (γ * ε / 4)
have hρ : 0 < ρ := lt_min hκ (by positivity)
have hρκ : ρ ≤ κ := min_le_left _ _
have hργε : ρ ≤ γ * ε / 4 := min_le_right _ _
obtain ⟨J₁, hJ₁⟩ := exists_dyadic_fixed_power_absorption 1 0 (τ := 0)
(ξ := ρ / 2) (by simpa using (show 0 < ρ / 2 by positivity))
refine ⟨ρ / 2, ε, by positivity, hε, hε4, max J₀ J₁, ?_⟩
intro J hJ A T hA hT hsize hAmass hTmass
have hj₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hj₁ : J₁ ≤ J := (le_max_right _ _).trans hJ
have hJ0 : (0 : ℝ) ≤ J := Nat.cast_nonneg _
have hTcard : (T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).card = T.card :=
Finset.card_image_of_injective _ Units.val_injective
have hAmass' : ∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) * (A.card : ℝ) := by
intro L hL hεL r
apply (hAmass L hL hεL r).trans
apply mul_le_mul_of_nonneg_right _ (Nat.cast_nonneg _)
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith only [mul_nonneg hγ.le (Nat.cast_nonneg L : (0 : ℝ) ≤ L)]
have hhereditary : ∀ U : Finset (ZMod (2 ^ J))ˣ, U ⊆ T → U.Nonempty →
(2 : ℝ) ^ (-ρ * (J : ℝ)) * (T.card : ℝ) ≤ (U.card : ℝ) →
∃ u ∈ U, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) A) : ℝ) <
(2 : ℝ) ^ (-κ * (J : ℝ)) * (A.card : ℝ) ^ 3 := by
intro U hUT hU hlarge
have hUcard : (U.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).card = U.card :=
Finset.card_image_of_injective _ Units.val_injective
have hinv : (2 : ℝ) ^ (ρ * (J : ℝ)) * (2 : ℝ) ^ (-ρ * (J : ℝ)) = 1 := by
rw [← Real.rpow_add (by norm_num), show ρ * (J : ℝ) + -ρ * (J : ℝ) = 0 by ring,
Real.rpow_zero]
have hratio : (T.card : ℝ) ≤ (2 : ℝ) ^ (ρ * (J : ℝ)) * (U.card : ℝ) := by
calc
_ = (2 : ℝ) ^ (ρ * (J : ℝ)) * ((2 : ℝ) ^ (-ρ * (J : ℝ)) * (T.card : ℝ)) := by
rw [← mul_assoc, hinv, one_mul]
_ ≤ _ := mul_le_mul_of_nonneg_left hlarge (by positivity)
have hUmass : ∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
(((U.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).filter
(fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) * (U.card : ℝ) := by
intro L hL hεL r
have hh := finite_fiber_bound_large_subset (fun a : ZMod (2 ^ J) => (a.val : ZMod (2 ^ L)))
(Finset.image_subset_image (f := fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J))) hUT)
(show 0 ≤ (2 : ℝ) ^ (-γ * (L : ℝ)) by positivity)
(D := (2 : ℝ) ^ (ρ * (J : ℝ)))
(by simpa only [hTcard, hUcard] using hratio)
(fun r => by simpa only [hTcard] using hTmass L hL hεL r) r
simp only [hUcard] at hh
apply hh.trans
apply mul_le_mul_of_nonneg_right _ (Nat.cast_nonneg _)
rw [← Real.rpow_add (by norm_num)]
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hρJ := mul_le_mul_of_nonneg_right hργε hJ0
have hγL := mul_lt_mul_of_pos_left hεL hγ
nlinarith only [hρJ, hγL, mul_nonneg hγ.le (Nat.cast_nonneg L : (0 : ℝ) ≤ L)]
obtain ⟨u, hu, hE⟩ := hpoint J hj₀ A U hA hU hsize hAmass' hUmass
refine ⟨u, hu, ?_⟩
apply (mul_lt_mul_iff_of_pos_left
(Real.rpow_pos_of_pos (by norm_num : (0 : ℝ) < 2) (κ * (J : ℝ)))).mp
calc
_ < (A.card : ℝ) ^ 3 := hE
_ = _ := by
rw [← mul_assoc, ← Real.rpow_add (by norm_num),
show κ * (J : ℝ) + -κ * (J : ℝ) = 0 by ring, Real.rpow_zero, one_mul]
have havg := finite_sum_bound_of_hereditary_small_value hT
(show 0 < (2 : ℝ) ^ (-ρ * (J : ℝ)) by positivity)
(show 0 ≤ (2 : ℝ) ^ (-κ * (J : ℝ)) by positivity)
(show 0 ≤ (A.card : ℝ) ^ 3 by positivity)
(fun u _ => ring_unit_dilate_energy_upper A u) hhereditary
have htwo : (2 : ℝ) ≤ (2 : ℝ) ^ ((ρ / 2) * (J : ℝ)) := by
simpa using hJ₁ J hj₁
have hcoef : (2 : ℝ) ^ (-ρ * (J : ℝ)) + (2 : ℝ) ^ (-κ * (J : ℝ)) ≤
(2 : ℝ) ^ (-(ρ / 2) * (J : ℝ)) := by
have hpow : (2 : ℝ) ^ (-κ * (J : ℝ)) ≤ (2 : ℝ) ^ (-ρ * (J : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_right hρκ hJ0
linarith only [hh]
calc
_ ≤ 2 * (2 : ℝ) ^ (-ρ * (J : ℝ)) := by linarith only [hpow]
_ ≤ (2 : ℝ) ^ ((ρ / 2) * (J : ℝ)) * (2 : ℝ) ^ (-ρ * (J : ℝ)) :=
mul_le_mul_of_nonneg_right htwo (by positivity)
_ = _ := by rw [← Real.rpow_add (by norm_num)]; congr 1; ring
exact havg.trans (mul_le_mul_of_nonneg_right
(mul_le_mul_of_nonneg_right hcoef (Nat.cast_nonneg _)) (by positivity))
theorem finite_fiber_bound_union {X Y : Type*} [DecidableEq X] [DecidableEq Y]
(π : X → Y) {A B : Finset X} {M : ℝ} (hM : 0 ≤ M)
(hA : ∀ r : Y, ((A.filter (fun x => π x = r)).card : ℝ) ≤ M * (A.card : ℝ))
(hB : ∀ r : Y, ((B.filter (fun x => π x = r)).card : ℝ) ≤ M * (B.card : ℝ)) :
∀ r : Y, (((A ∪ B).filter (fun x => π x = r)).card : ℝ) ≤
(2 * M) * ((A ∪ B).card : ℝ) := by
intro r
have hAU : (A.card : ℝ) ≤ (A ∪ B).card := by
exact_mod_cast Finset.card_le_card (Finset.subset_union_left : A ⊆ A ∪ B)
have hBU : (B.card : ℝ) ≤ (A ∪ B).card := by
exact_mod_cast Finset.card_le_card (Finset.subset_union_right : B ⊆ A ∪ B)
calc
_ ≤ ((A.filter (fun x => π x = r)).card : ℝ) + ((B.filter (fun x => π x = r)).card : ℝ) := by
rw [Finset.filter_union]
exact_mod_cast Finset.card_union_le _ _
_ ≤ M * (A.card : ℝ) + M * (B.card : ℝ) := add_le_add (hA r) (hB r)
_ ≤ M * ((A ∪ B).card : ℝ) + M * ((A ∪ B).card : ℝ) := by gcongr
_ = _ := by ring
/-- Interpolate the union bound and the elementary mixed-energy bound. -/
theorem ordered_mixed_energy_square_bound {e a b t v r w : ℝ}
(he : 0 ≤ e) (ha : 0 ≤ a) (hb : 0 ≤ b) (ht : 0 ≤ t) (hv : 0 ≤ v)
(hr : 0 ≤ r) (hw : 0 ≤ w) (hab : a ≤ b)
(hbalance : 64 * v ^ 2 * r ^ 3 ≤ w) (hinverse : 1 ≤ w * r)
(hunion : e ≤ v * t * (a + b) ^ 3) (htrivial : e ≤ t * a ^ 2 * b) :
e ^ 2 ≤ w * t ^ 2 * a ^ 3 * b ^ 3 := by
by_cases hratio : b ≤ r * a
· have he' : e ≤ v * t * (2 * b) ^ 3 := by
apply hunion.trans
gcongr
linarith only [hab]
have hb' : b ^ 3 ≤ r ^ 3 * a ^ 3 := by
simpa only [mul_pow] using pow_le_pow_left₀ hb hratio 3
calc
_ ≤ (v * t * (2 * b) ^ 3) ^ 2 := pow_le_pow_left₀ he he' 2
_ = (64 * v ^ 2 * t ^ 2 * b ^ 3) * b ^ 3 := by ring
_ ≤ (64 * v ^ 2 * t ^ 2 * b ^ 3) * (r ^ 3 * a ^ 3) :=
mul_le_mul_of_nonneg_left hb' (by positivity)
_ = (64 * v ^ 2 * r ^ 3) * (t ^ 2 * a ^ 3 * b ^ 3) := by ring
_ ≤ w * (t ^ 2 * a ^ 3 * b ^ 3) := mul_le_mul_of_nonneg_right hbalance (by positivity)
_ = _ := by ring
· have hratio' : r * a ≤ b := (lt_of_not_ge hratio).le
have haw : a ≤ w * b := by
calc
_ = 1 * a := (one_mul _).symm
_ ≤ (w * r) * a := mul_le_mul_of_nonneg_right hinverse ha
_ = w * (r * a) := by ring
_ ≤ _ := mul_le_mul_of_nonneg_left hratio' hw
calc
_ ≤ (t * a ^ 2 * b) ^ 2 := pow_le_pow_left₀ he htrivial 2
_ = (t ^ 2 * a ^ 3 * b ^ 2) * a := by ring
_ ≤ (t ^ 2 * a ^ 3 * b ^ 2) * (w * b) := mul_le_mul_of_nonneg_left haw (by positivity)
_ = _ := by ring
theorem mixed_energy_square_bound {e a b t v r w : ℝ}
(he : 0 ≤ e) (ha : 0 ≤ a) (hb : 0 ≤ b) (ht : 0 ≤ t) (hv : 0 ≤ v)
(hr : 0 ≤ r) (hw : 0 ≤ w)
(hbalance : 64 * v ^ 2 * r ^ 3 ≤ w) (hinverse : 1 ≤ w * r)
(hunion : e ≤ v * t * (a + b) ^ 3)
(hleft : e ≤ t * a ^ 2 * b) (hright : e ≤ t * a * b ^ 2) :
e ^ 2 ≤ w * t ^ 2 * a ^ 3 * b ^ 3 := by
rcases le_total a b with hab | hba
· exact ordered_mixed_energy_square_bound he ha hb ht hv hr hw hab hbalance hinverse hunion hleft
· have hh := ordered_mixed_energy_square_bound he hb ha ht hv hr hw hba hbalance hinverse
(by simpa only [add_comm] using hunion)
(by simpa only [mul_assoc, mul_comm, mul_left_comm] using hright)
calc _ ≤ w * t ^ 2 * b ^ 3 * a ^ 3 := hh
_ = _ := by ring
theorem ring_unit_mixed_energy_upper_left {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
(A B : Finset R) (u : Rˣ) :
(Finset.addEnergy A (ringDilate (u : R) B) : ℝ) ≤ (A.card : ℝ) ^ 2 * (B.card : ℝ) := by
rw [Finset.addEnergy_comm]
have hh := finite_add_energy_upper (ringDilate (u : R) B) A
rw [ring_dilate_unit_card] at hh
simpa only [mul_comm] using hh
theorem ring_unit_mixed_energy_upper_right {R : Type*} [Ring R] [Fintype R] [DecidableEq R]
(A B : Finset R) (u : Rˣ) :
(Finset.addEnergy A (ringDilate (u : R) B) : ℝ) ≤ (A.card : ℝ) * (B.card : ℝ) ^ 2 := by
have hh := finite_add_energy_upper A (ringDilate (u : R) B)
simpa only [ring_dilate_unit_card] using hh
def DyadicRingSetNonconcentration {J : ℕ} (γ ε : ℝ) (A : Finset (ZMod (2 ^ J))) : Prop :=
∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
((A.filter (fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (A.card : ℝ)
def DyadicUnitSetNonconcentration {J : ℕ} (γ ε : ℝ) (T : Finset (ZMod (2 ^ J))ˣ) : Prop :=
∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
(((T.image (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J)))).filter
(fun a => (a.val : ZMod (2 ^ L)) = r)).card : ℝ) ≤
(2 : ℝ) ^ (-γ * (L : ℝ)) * (T.card : ℝ)
/-- Average mixed energy of two distinct nonconcentrated sets, with a
cardinality-symmetric normalization suitable for weighted level sets. -/
theorem exists_dyadic_average_mixed_energy_decay {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ A B : Finset (ZMod (2 ^ J)), ∀ T : Finset (ZMod (2 ^ J))ˣ,
A.Nonempty → B.Nonempty → T.Nonempty →
(A.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
(B.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) →
DyadicRingSetNonconcentration γ ε A → DyadicRingSetNonconcentration γ ε B →
DyadicUnitSetNonconcentration γ ε T →
(∑ u ∈ T, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) B) : ℝ)) ^ 2 ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * (T.card : ℝ) ^ 2 * (A.card : ℝ) ^ 3 * (B.card : ℝ) ^ 3 := by
classical
obtain ⟨κ, ε, hκ, hε, hε4, J₀, havg⟩ := exists_dyadic_average_unit_energy_decay
(show 0 < γ / 2 by positivity) (show 0 < δ / 2 by positivity) (by linarith only [hδ1])
obtain ⟨J₁, hJ₁⟩ := exists_dyadic_fixed_power_absorption 1 0 (τ := 0) (ξ := δ / 2)
(by simpa using (show 0 < δ / 2 by positivity))
obtain ⟨J₂, hJ₂⟩ := exists_dyadic_fixed_power_absorption 1 0 (τ := 0) (ξ := γ * ε / 2)
(by simpa using (show 0 < γ * ε / 2 by positivity))
obtain ⟨J₃, hJ₃⟩ := exists_dyadic_fixed_power_absorption 6 0 (τ := 0) (ξ := κ)
(by simpa using hκ)
refine ⟨κ / 4, ε, by positivity, hε, hε4, max J₀ (max J₁ (max J₂ J₃)), ?_⟩
intro J hJ A B T hA hB hT hAsize hBsize hAmass hBmass hTmass
have hj₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hj₁ : J₁ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans hJ)
have hj₂ : J₂ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans hJ))
have hj₃ : J₃ ≤ J := (le_max_right _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans hJ))
have h2δ : (2 : ℝ) ≤ (2 : ℝ) ^ ((δ / 2) * (J : ℝ)) := by simpa using hJ₁ J hj₁
have h2γ : (2 : ℝ) ≤ (2 : ℝ) ^ ((γ * ε / 2) * (J : ℝ)) := by simpa using hJ₂ J hj₂
have h64 : (64 : ℝ) ≤ (2 : ℝ) ^ (κ * (J : ℝ)) := by
have hh := hJ₃ J hj₃
norm_num at hh
exact hh
let U := A ∪ B
have hUcard : (U.card : ℝ) ≤ (A.card : ℝ) + (B.card : ℝ) := by
exact_mod_cast Finset.card_union_le A B
have hUsize : (U.card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ / 2) * (J : ℝ)) := by
calc
_ ≤ (A.card : ℝ) + (B.card : ℝ) := hUcard
_ ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) + (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) := add_le_add hAsize hBsize
_ = 2 * (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) := by ring
_ ≤ (2 : ℝ) ^ ((δ / 2) * (J : ℝ)) * (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) := by gcongr
_ = _ := by rw [← Real.rpow_add (by norm_num)]; congr 1; ring
have hUmass : DyadicRingSetNonconcentration (γ / 2) ε U := by
intro L hL hεL r
have hh := finite_fiber_bound_union (fun a : ZMod (2 ^ J) => (a.val : ZMod (2 ^ L)))
(show 0 ≤ (2 : ℝ) ^ (-γ * (L : ℝ)) by positivity) (hAmass L hL hεL) (hBmass L hL hεL) r
apply hh.trans
apply mul_le_mul_of_nonneg_right _ (Nat.cast_nonneg _)
calc
_ ≤ (2 : ℝ) ^ ((γ * ε / 2) * (J : ℝ)) * (2 : ℝ) ^ (-γ * (L : ℝ)) := by gcongr
_ = (2 : ℝ) ^ ((γ * ε / 2) * (J : ℝ) - γ * (L : ℝ)) := by
rw [← Real.rpow_add (by norm_num)]; congr 1; ring
_ ≤ _ := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith only [mul_lt_mul_of_pos_left hεL hγ]
have hTmass' : DyadicUnitSetNonconcentration (γ / 2) ε T := by
intro L hL hεL r
apply (hTmass L hL hεL r).trans
apply mul_le_mul_of_nonneg_right _ (Nat.cast_nonneg _)
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith only [mul_nonneg hγ.le (Nat.cast_nonneg L : (0 : ℝ) ≤ L)]
have hUE := havg J hj₀ U T (hA.mono Finset.subset_union_left) hT hUsize hUmass hTmass'
have hunion : (∑ u ∈ T, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) B) : ℝ)) ≤
(2 : ℝ) ^ (-κ * (J : ℝ)) * (T.card : ℝ) * ((A.card : ℝ) + (B.card : ℝ)) ^ 3 := by
calc
_ ≤ ∑ u ∈ T, (Finset.addEnergy U (ringDilate (u : ZMod (2 ^ J)) U) : ℝ) := by
apply Finset.sum_le_sum
intro u hu
exact_mod_cast Finset.addEnergy_mono Finset.subset_union_left
(ring_dilate_subset (u : ZMod (2 ^ J)) (Finset.subset_union_right : B ⊆ A ∪ B))
_ ≤ (2 : ℝ) ^ (-κ * (J : ℝ)) * (T.card : ℝ) * (U.card : ℝ) ^ 3 := hUE
_ ≤ _ := by gcongr
have hleft : (∑ u ∈ T, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) B) : ℝ)) ≤
(T.card : ℝ) * (A.card : ℝ) ^ 2 * (B.card : ℝ) := by
calc
_ ≤ ∑ _u ∈ T, (A.card : ℝ) ^ 2 * (B.card : ℝ) :=
Finset.sum_le_sum (fun u _ => ring_unit_mixed_energy_upper_left A B u)
_ = _ := by simp; ring
have hright : (∑ u ∈ T, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) B) : ℝ)) ≤
(T.card : ℝ) * (A.card : ℝ) * (B.card : ℝ) ^ 2 := by
calc
_ ≤ ∑ _u ∈ T, (A.card : ℝ) * (B.card : ℝ) ^ 2 :=
Finset.sum_le_sum (fun u _ => ring_unit_mixed_energy_upper_right A B u)
_ = _ := by simp; ring
have hbalance : 64 * ((2 : ℝ) ^ (-κ * (J : ℝ))) ^ 2 *
((2 : ℝ) ^ ((κ / 4) * (J : ℝ))) ^ 3 ≤ (2 : ℝ) ^ (-(κ / 4) * (J : ℝ)) := by
calc
_ ≤ (2 : ℝ) ^ (κ * (J : ℝ)) * ((2 : ℝ) ^ (-κ * (J : ℝ))) ^ 2 *
((2 : ℝ) ^ ((κ / 4) * (J : ℝ))) ^ 3 := by gcongr
_ = _ := by
rw [← Real.rpow_mul_natCast (by norm_num), ← Real.rpow_mul_natCast (by norm_num),
← Real.rpow_add (by norm_num), ← Real.rpow_add (by norm_num)]
congr 1
norm_num
ring
have hinverse : 1 ≤ (2 : ℝ) ^ (-(κ / 4) * (J : ℝ)) * (2 : ℝ) ^ ((κ / 4) * (J : ℝ)) := by
rw [← Real.rpow_add (by norm_num),
show -(κ / 4) * (J : ℝ) + (κ / 4) * (J : ℝ) = 0 by ring, Real.rpow_zero]
exact mixed_energy_square_bound (Finset.sum_nonneg (fun u _ => Nat.cast_nonneg _))
(Nat.cast_nonneg _) (Nat.cast_nonneg _) (Nat.cast_nonneg _)
(by positivity) (by positivity) (by positivity) hbalance hinverse hunion hleft hright
theorem norm_sum_sq_le_card_mul_sum_sq {X : Type*} (I : Finset X) (f : X → ℂ) :
‖∑ i ∈ I, f i‖ ^ 2 ≤ (I.card : ℝ) * ∑ i ∈ I, ‖f i‖ ^ 2 := by
have hc := Finset.sum_mul_sq_le_sq_mul_sq I (fun _ => (1 : ℝ)) (fun i => ‖f i‖)
simp only [one_mul, one_pow, Finset.sum_const, nsmul_eq_mul, mul_one] at hc
exact (pow_le_pow_left₀ (norm_nonneg _) (norm_sum_le I f) 2).trans hc
noncomputable def cyclicUnitDilate {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (u : (ZMod q)ˣ) (x : ZMod q) : ℂ := f ((u⁻¹ : (ZMod q)ˣ) * x)
noncomputable def cyclicSetCombination {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q)) (x : ZMod q) : ℂ :=
∑ i ∈ I, (w i : ℂ) * cyclicSetIndicator (A i) x
theorem mem_ring_unit_dilate {R : Type*} [Ring R] [DecidableEq R]
(u : Rˣ) (A : Finset R) (x : R) :
x ∈ ringDilate (u : R) A ↔ ((u⁻¹ : Rˣ) : R) * x ∈ A := by
constructor
· intro hx
obtain ⟨a, ha, hax⟩ := Finset.mem_image.mp hx
rw [← hax, ← mul_assoc, Units.inv_mul, one_mul]
exact ha
· intro hx
apply Finset.mem_image.mpr
exact ⟨((u⁻¹ : Rˣ) : R) * x, hx, by rw [← mul_assoc, Units.mul_inv, one_mul]⟩
theorem cyclic_unit_dilate_indicator {q : ℕ} [NeZero q]
(A : Finset (ZMod q)) (u : (ZMod q)ˣ) :
cyclicUnitDilate (cyclicSetIndicator A) u = cyclicSetIndicator (ringDilate (u : ZMod q) A) := by
classical
funext x
simp only [cyclicUnitDilate, cyclicSetIndicator, mem_ring_unit_dilate]
theorem cyclic_unit_dilate_set_combination {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q)) (u : (ZMod q)ˣ) :
cyclicUnitDilate (cyclicSetCombination I w A) u =
cyclicSetCombination I w (fun i => ringDilate (u : ZMod q) (A i)) := by
funext x
unfold cyclicSetCombination cyclicUnitDilate
apply Finset.sum_congr rfl
intro i hi
congr 1
exact congrFun (cyclic_unit_dilate_indicator (A i) u) x
theorem cyclic_convolution_scaled {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (a b : ℂ) (x : ZMod q) :
cyclicConvolution (fun y => a * f y) (fun y => b * g y) x = a * b * cyclicConvolution f g x := by
unfold cyclicConvolution
rw [Finset.mul_sum]
apply Finset.sum_congr rfl
intro y hy
ring
theorem cyclic_convolution_sum_left {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (f : X → ZMod q → ℂ) (g : ZMod q → ℂ) (x : ZMod q) :
cyclicConvolution (fun y => ∑ i ∈ I, f i y) g x = ∑ i ∈ I, cyclicConvolution (f i) g x := by
simp only [cyclicConvolution, Finset.sum_mul]
rw [Finset.sum_comm]
theorem cyclic_convolution_sum_right {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (f : ZMod q → ℂ) (g : X → ZMod q → ℂ) (x : ZMod q) :
cyclicConvolution f (fun y => ∑ i ∈ I, g i y) x = ∑ i ∈ I, cyclicConvolution f (g i) x := by
simp only [cyclicConvolution, Finset.mul_sum]
rw [Finset.sum_comm]
theorem cyclic_convolution_set_combinations {X Y : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (K : Finset Y) (w : X → ℝ) (v : Y → ℝ)
(A : X → Finset (ZMod q)) (B : Y → Finset (ZMod q)) (x : ZMod q) :
cyclicConvolution (cyclicSetCombination I w A) (cyclicSetCombination K v B) x =
∑ i ∈ I, ∑ j ∈ K, (w i : ℂ) * (v j : ℂ) *
cyclicConvolution (cyclicSetIndicator (A i)) (cyclicSetIndicator (B j)) x := by
unfold cyclicSetCombination
rw [cyclic_convolution_sum_left]
apply Finset.sum_congr rfl
intro i hi
rw [cyclic_convolution_sum_right]
apply Finset.sum_congr rfl
intro j hj
exact cyclic_convolution_scaled _ _ _ _ _
theorem finite_weighted_card_three_halves_bound {X : Type*}
(I : Finset X) (w a : X → ℝ) (hw : ∀ i ∈ I, 0 ≤ w i) (ha : ∀ i ∈ I, 0 ≤ a i) :
(∑ i ∈ I, w i ^ 2 * (a i * Real.sqrt (a i))) ^ 2 ≤
(∑ i ∈ I, w i ^ 2 * a i) * (∑ i ∈ I, w i * a i) ^ 2 := by
have hc := Finset.sum_mul_sq_le_sq_mul_sq I (fun i => w i * Real.sqrt (a i)) (fun i => w i * a i)
have hfirst : (∑ i ∈ I, (w i * Real.sqrt (a i)) ^ 2) = ∑ i ∈ I, w i ^ 2 * a i := by
apply Finset.sum_congr rfl
intro i hi
rw [mul_pow, Real.sq_sqrt (ha i hi)]
have hprod : (∑ i ∈ I, (w i * Real.sqrt (a i)) * (w i * a i)) =
∑ i ∈ I, w i ^ 2 * (a i * Real.sqrt (a i)) := by
apply Finset.sum_congr rfl
intro i hi
ring
rw [hfirst, hprod] at hc
apply hc.trans
apply mul_le_mul_of_nonneg_left _ (Finset.sum_nonneg (fun i hi => mul_nonneg (sq_nonneg _) (ha i hi)))
exact Finset.sum_sq_le_sq_sum_of_nonneg (fun i hi => mul_nonneg (hw i hi) (ha i hi))
theorem cyclic_set_combination_unit_energy {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q)) (u : (ZMod q)ˣ)
(hw : ∀ i ∈ I, 0 ≤ w i) :
(∑ x : ZMod q, ‖cyclicConvolution (cyclicSetCombination I w A)
(cyclicUnitDilate (cyclicSetCombination I w A) u) x‖ ^ 2) ≤
(I.card : ℝ) ^ 2 * ∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
(Finset.addEnergy (A i) (ringDilate (u : ZMod q) (A j)) : ℝ) := by
have hpoint : ∀ x : ZMod q,
‖cyclicConvolution (cyclicSetCombination I w A)
(cyclicUnitDilate (cyclicSetCombination I w A) u) x‖ ^ 2 ≤
(I.card : ℝ) ^ 2 * ∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
‖cyclicConvolution (cyclicSetIndicator (A i))
(cyclicSetIndicator (ringDilate (u : ZMod q) (A j))) x‖ ^ 2 := by
intro x
rw [cyclic_unit_dilate_set_combination, cyclic_convolution_set_combinations]
have hh := norm_sum_sq_le_card_mul_sum_sq (I ×ˢ I) (fun p =>
(w p.1 : ℂ) * (w p.2 : ℂ) * cyclicConvolution (cyclicSetIndicator (A p.1))
(cyclicSetIndicator (ringDilate (u : ZMod q) (A p.2))) x)
simp only [Finset.sum_product, Finset.card_product, Nat.cast_mul] at hh
apply hh.trans_eq
rw [pow_two]
congr 1
apply Finset.sum_congr rfl
intro i hi
apply Finset.sum_congr rfl
intro j hj
rw [norm_mul, norm_mul, Complex.norm_real, Complex.norm_real,
Real.norm_eq_abs, Real.norm_eq_abs, abs_of_nonneg (hw i hi), abs_of_nonneg (hw j hj),
mul_pow, mul_pow]
calc
_ ≤ ∑ x : ZMod q, (I.card : ℝ) ^ 2 * ∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
‖cyclicConvolution (cyclicSetIndicator (A i))
(cyclicSetIndicator (ringDilate (u : ZMod q) (A j))) x‖ ^ 2 :=
Finset.sum_le_sum (fun x _ => hpoint x)
_ = (I.card : ℝ) ^ 2 * ∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
∑ x : ZMod q, ‖cyclicConvolution (cyclicSetIndicator (A i))
(cyclicSetIndicator (ringDilate (u : ZMod q) (A j))) x‖ ^ 2 := by
rw [← Finset.mul_sum, Finset.sum_comm]
congr 1
apply Finset.sum_congr rfl
intro i hi
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro j hj
rw [← Finset.mul_sum]
_ = _ := by simp_rw [cyclic_set_convolution_energy]
theorem cyclic_set_combination_average_energy {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q)) (T : Finset (ZMod q)ˣ)
{C : ℝ} (hw : ∀ i ∈ I, 0 ≤ w i) (hC : 0 ≤ C)
(hE : ∀ i ∈ I, ∀ j ∈ I,
(∑ u ∈ T, (Finset.addEnergy (A i) (ringDilate (u : ZMod q) (A j)) : ℝ)) ≤
C * ((A i).card : ℝ) * Real.sqrt ((A i).card : ℝ) *
((A j).card : ℝ) * Real.sqrt ((A j).card : ℝ)) :
(∑ u ∈ T, ∑ x : ZMod q, ‖cyclicConvolution (cyclicSetCombination I w A)
(cyclicUnitDilate (cyclicSetCombination I w A) u) x‖ ^ 2) ≤
(I.card : ℝ) ^ 2 * C * (∑ i ∈ I, w i ^ 2 * ((A i).card : ℝ)) *
(∑ i ∈ I, w i * ((A i).card : ℝ)) ^ 2 := by
let a := fun i => ((A i).card : ℝ)
have hfactor : (∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
(C * a i * Real.sqrt (a i) * a j * Real.sqrt (a j))) =
C * (∑ i ∈ I, w i ^ 2 * (a i * Real.sqrt (a i))) ^ 2 := by
rw [pow_two, Finset.sum_mul_sum, Finset.mul_sum]
apply Finset.sum_congr rfl
intro i hi
rw [Finset.mul_sum]
apply Finset.sum_congr rfl
intro j hj
ring
calc
_ ≤ ∑ u ∈ T, (I.card : ℝ) ^ 2 * ∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
(Finset.addEnergy (A i) (ringDilate (u : ZMod q) (A j)) : ℝ) :=
Finset.sum_le_sum (fun u _ => cyclic_set_combination_unit_energy I w A u hw)
_ = (I.card : ℝ) ^ 2 * ∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
∑ u ∈ T, (Finset.addEnergy (A i) (ringDilate (u : ZMod q) (A j)) : ℝ) := by
rw [← Finset.mul_sum, Finset.sum_comm]
congr 1
apply Finset.sum_congr rfl
intro i hi
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro j hj
rw [← Finset.mul_sum]
_ ≤ (I.card : ℝ) ^ 2 * ∑ i ∈ I, ∑ j ∈ I, w i ^ 2 * w j ^ 2 *
(C * a i * Real.sqrt (a i) * a j * Real.sqrt (a j)) := by
apply mul_le_mul_of_nonneg_left _ (sq_nonneg _)
apply Finset.sum_le_sum
intro i hi
apply Finset.sum_le_sum
intro j hj
exact mul_le_mul_of_nonneg_left (hE i hi j hj) (by positivity)
_ = (I.card : ℝ) ^ 2 * C *
(∑ i ∈ I, w i ^ 2 * (a i * Real.sqrt (a i))) ^ 2 := by rw [hfactor]; ring
_ ≤ (I.card : ℝ) ^ 2 * C *
((∑ i ∈ I, w i ^ 2 * a i) * (∑ i ∈ I, w i * a i) ^ 2) :=
mul_le_mul_of_nonneg_left (finite_weighted_card_three_halves_bound I w a hw
(fun i _ => Nat.cast_nonneg _)) (mul_nonneg (sq_nonneg _) hC)
_ = _ := by ring
theorem dyadic_mixed_energy_bound_of_sq {J : ℕ}
{A B : Finset (ZMod (2 ^ J))} {T : Finset (ZMod (2 ^ J))ˣ} {τ : ℝ}
(hE : (∑ u ∈ T, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) B) : ℝ)) ^ 2 ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * (T.card : ℝ) ^ 2 * (A.card : ℝ) ^ 3 * (B.card : ℝ) ^ 3) :
(∑ u ∈ T, (Finset.addEnergy A (ringDilate (u : ZMod (2 ^ J)) B) : ℝ)) ≤
((2 : ℝ) ^ (-(τ / 2) * (J : ℝ)) * (T.card : ℝ)) *
(A.card : ℝ) * Real.sqrt (A.card : ℝ) * (B.card : ℝ) * Real.sqrt (B.card : ℝ) := by
have hscale : ((2 : ℝ) ^ (-(τ / 2) * (J : ℝ))) ^ 2 = (2 : ℝ) ^ (-τ * (J : ℝ)) := by
rw [← Real.rpow_mul_natCast (by norm_num)]
congr 1
norm_num
ring
have hsquare : (((2 : ℝ) ^ (-(τ / 2) * (J : ℝ)) * (T.card : ℝ)) *
(A.card : ℝ) * Real.sqrt (A.card : ℝ) * (B.card : ℝ) * Real.sqrt (B.card : ℝ)) ^ 2 =
(2 : ℝ) ^ (-τ * (J : ℝ)) * (T.card : ℝ) ^ 2 * (A.card : ℝ) ^ 3 * (B.card : ℝ) ^ 3 := by
simp only [mul_pow, Real.sq_sqrt (Nat.cast_nonneg _), hscale]
ring
have hnonneg : 0 ≤ ((2 : ℝ) ^ (-(τ / 2) * (J : ℝ)) * (T.card : ℝ)) *
(A.card : ℝ) * Real.sqrt (A.card : ℝ) * (B.card : ℝ) * Real.sqrt (B.card : ℝ) := by positivity
rw [← hsquare] at hE
exact (sq_le_sq₀ (Finset.sum_nonneg (fun _ _ => Nat.cast_nonneg _)) hnonneg).mp hE
theorem cyclic_set_combination_norm {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q))
(hw : ∀ i ∈ I, 0 ≤ w i) (x : ZMod q) :
‖cyclicSetCombination I w A x‖ = ∑ i ∈ I, w i * ‖cyclicSetIndicator (A i) x‖ := by
classical
have heq : cyclicSetCombination I w A x =
((∑ i ∈ I, w i * ‖cyclicSetIndicator (A i) x‖ : ℝ) : ℂ) := by
rw [Complex.ofReal_sum]
apply Finset.sum_congr rfl
intro i hi
by_cases hx : x ∈ A i <;> simp [cyclicSetIndicator, hx]
rw [heq, Complex.norm_of_nonneg (Finset.sum_nonneg (fun i hi => mul_nonneg (hw i hi) (norm_nonneg _)))]
theorem cyclic_set_combination_sum_norm {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q))
(hw : ∀ i ∈ I, 0 ≤ w i) :
(∑ x : ZMod q, ‖cyclicSetCombination I w A x‖) = ∑ i ∈ I, w i * ((A i).card : ℝ) := by
simp_rw [cyclic_set_combination_norm I w A hw]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro i hi
rw [← Finset.mul_sum, cyclic_set_indicator_norm_sum]
theorem cyclic_set_combination_sq_norm_lower {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q))
(hw : ∀ i ∈ I, 0 ≤ w i) :
(∑ i ∈ I, w i ^ 2 * ((A i).card : ℝ)) ≤ ∑ x : ZMod q, ‖cyclicSetCombination I w A x‖ ^ 2 := by
calc
_ = ∑ i ∈ I, w i ^ 2 * ∑ x : ZMod q, ‖cyclicSetIndicator (A i) x‖ ^ 2 := by
simp_rw [cyclic_set_indicator_sq_norm_sum]
_ = ∑ x : ZMod q, ∑ i ∈ I, (w i * ‖cyclicSetIndicator (A i) x‖) ^ 2 := by
simp_rw [Finset.mul_sum, mul_pow]
rw [Finset.sum_comm]
_ ≤ ∑ x : ZMod q, (∑ i ∈ I, w i * ‖cyclicSetIndicator (A i) x‖) ^ 2 :=
Finset.sum_le_sum (fun x _ => Finset.sum_sq_le_sq_sum_of_nonneg
(fun i hi => mul_nonneg (hw i hi) (norm_nonneg _)))
_ = _ := by simp_rw [cyclic_set_combination_norm I w A hw]
/-- Flattening for a bounded number of nonnegative set levels. The level
sets satisfy the same density and residue bounds, and their total mass is at most one. -/
theorem exists_dyadic_set_combination_flattening {X : Type*} {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ I : Finset X, ∀ w : X → ℝ,
∀ A : X → Finset (ZMod (2 ^ J)), ∀ T : Finset (ZMod (2 ^ J))ˣ,
(∀ i ∈ I, 0 ≤ w i) → T.Nonempty →
(I.card : ℝ) ≤ (2 : ℝ) ^ (τ * (J : ℝ)) →
(∑ i ∈ I, w i * ((A i).card : ℝ)) ≤ 1 →
(∀ i ∈ I, (A i).Nonempty ∧
((A i).card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ) * (J : ℝ)) ∧
DyadicRingSetNonconcentration γ ε (A i)) →
DyadicUnitSetNonconcentration γ ε T →
(∑ u ∈ T, ∑ x : ZMod (2 ^ J), ‖cyclicConvolution (cyclicSetCombination I w A)
(cyclicUnitDilate (cyclicSetCombination I w A) u) x‖ ^ 2) ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * (T.card : ℝ) *
∑ x : ZMod (2 ^ J), ‖cyclicSetCombination I w A x‖ ^ 2 := by
obtain ⟨κ, ε, hκ, hε, hε4, J₀, hmix⟩ := exists_dyadic_average_mixed_energy_decay hγ hδ hδ1
refine ⟨κ / 6, ε, by positivity, hε, hε4, J₀, ?_⟩
intro J hJ I w A T hw hT hI hmass hA hTmass
have hE : ∀ i ∈ I, ∀ j ∈ I,
(∑ u ∈ T, (Finset.addEnergy (A i) (ringDilate (u : ZMod (2 ^ J)) (A j)) : ℝ)) ≤
((2 : ℝ) ^ (-(κ / 2) * (J : ℝ)) * (T.card : ℝ)) *
((A i).card : ℝ) * Real.sqrt ((A i).card : ℝ) *
((A j).card : ℝ) * Real.sqrt ((A j).card : ℝ) := by
intro i hi j hj
exact dyadic_mixed_energy_bound_of_sq (hmix J hJ (A i) (A j) T (hA i hi).1
(hA j hj).1 hT (hA i hi).2.1 (hA j hj).2.1 (hA i hi).2.2 (hA j hj).2.2 hTmass)
have hh := cyclic_set_combination_average_energy I w A T hw (by positivity) hE
have hmass0 : 0 ≤ ∑ i ∈ I, w i * ((A i).card : ℝ) :=
Finset.sum_nonneg (fun i hi => mul_nonneg (hw i hi) (Nat.cast_nonneg _))
have hmass2 : (∑ i ∈ I, w i * ((A i).card : ℝ)) ^ 2 ≤ 1 := by
simpa only [one_pow] using pow_le_pow_left₀ hmass0 hmass 2
have hI2 : (I.card : ℝ) ^ 2 ≤ ((2 : ℝ) ^ ((κ / 6) * (J : ℝ))) ^ 2 :=
pow_le_pow_left₀ (Nat.cast_nonneg _) hI 2
have hcoef : (I.card : ℝ) ^ 2 *
((2 : ℝ) ^ (-(κ / 2) * (J : ℝ)) * (T.card : ℝ)) ≤
(2 : ℝ) ^ (-(κ / 6) * (J : ℝ)) * (T.card : ℝ) := by
calc
_ ≤ ((2 : ℝ) ^ ((κ / 6) * (J : ℝ))) ^ 2 *
((2 : ℝ) ^ (-(κ / 2) * (J : ℝ)) * (T.card : ℝ)) :=
mul_le_mul_of_nonneg_right hI2 (by positivity)
_ = _ := by
rw [← Real.rpow_mul_natCast (by norm_num), ← mul_assoc, ← Real.rpow_add (by norm_num)]
congr 2
norm_num
ring
calc
_ ≤ (I.card : ℝ) ^ 2 * ((2 : ℝ) ^ (-(κ / 2) * (J : ℝ)) * (T.card : ℝ)) *
(∑ i ∈ I, w i ^ 2 * ((A i).card : ℝ)) * (∑ i ∈ I, w i * ((A i).card : ℝ)) ^ 2 := hh
_ ≤ (I.card : ℝ) ^ 2 * ((2 : ℝ) ^ (-(κ / 2) * (J : ℝ)) * (T.card : ℝ)) *
(∑ i ∈ I, w i ^ 2 * ((A i).card : ℝ)) * 1 :=
mul_le_mul_of_nonneg_left hmass2 (by positivity)
_ ≤ ((2 : ℝ) ^ (-(κ / 6) * (J : ℝ)) * (T.card : ℝ)) *
(∑ i ∈ I, w i ^ 2 * ((A i).card : ℝ)) := by
rw [mul_one]
exact mul_le_mul_of_nonneg_right hcoef (by positivity)
_ ≤ _ := mul_le_mul_of_nonneg_left (cyclic_set_combination_sq_norm_lower I w A hw) (by positivity)
theorem weighted_sum_sq_le_mass_mul {X : Type*} (I : Finset X) (w t : X → ℝ)
(hw : ∀ i ∈ I, 0 ≤ w i) :
(∑ i ∈ I, w i * t i) ^ 2 ≤ (∑ i ∈ I, w i) * ∑ i ∈ I, w i * t i ^ 2 := by
have hprod : (∑ i ∈ I, Real.sqrt (w i) * (Real.sqrt (w i) * t i)) = ∑ i ∈ I, w i * t i := by
apply Finset.sum_congr rfl
intro i hi
rw [← mul_assoc, Real.mul_self_sqrt (hw i hi)]
have hfirst : (∑ i ∈ I, Real.sqrt (w i) ^ 2) = ∑ i ∈ I, w i :=
Finset.sum_congr rfl (fun i hi => Real.sq_sqrt (hw i hi))
have hsecond : (∑ i ∈ I, (Real.sqrt (w i) * t i) ^ 2) = ∑ i ∈ I, w i * t i ^ 2 := by
apply Finset.sum_congr rfl
intro i hi
rw [mul_pow, Real.sq_sqrt (hw i hi)]
have hh := Finset.sum_mul_sq_le_sq_mul_sq I (fun i => Real.sqrt (w i)) (fun i => Real.sqrt (w i) * t i)
rwa [hprod, hfirst, hsecond] at hh
theorem cyclic_convolution_young_sq {q : ℕ} [NeZero q] (f g : ZMod q → ℂ) :
(∑ x : ZMod q, ‖cyclicConvolution f g x‖ ^ 2) ≤
(∑ x : ZMod q, ‖f x‖) ^ 2 * ∑ x : ZMod q, ‖g x‖ ^ 2 := by
have hpoint : ∀ x : ZMod q, ‖cyclicConvolution f g x‖ ^ 2 ≤
(∑ y : ZMod q, ‖f y‖) * ∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ ^ 2 := by
intro x
have hh : ‖cyclicConvolution f g x‖ ≤ ∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ := by
simpa only [cyclicConvolution, norm_mul] using norm_sum_le Finset.univ (fun y => f y * g (x - y))
exact (pow_le_pow_left₀ (norm_nonneg _) hh 2).trans
(weighted_sum_sq_le_mass_mul Finset.univ (fun y => ‖f y‖) (fun y => ‖g (x - y)‖)
(fun _ _ => norm_nonneg _))
calc
_ ≤ ∑ x : ZMod q, (∑ y : ZMod q, ‖f y‖) * ∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ ^ 2 :=
Finset.sum_le_sum (fun x _ => hpoint x)
_ = (∑ y : ZMod q, ‖f y‖) * ∑ y : ZMod q, ‖f y‖ * ∑ x : ZMod q, ‖g x‖ ^ 2 := by
rw [← Finset.mul_sum, Finset.sum_comm]
congr 1
apply Finset.sum_congr rfl
intro y hy
rw [← Finset.mul_sum]
congr 1
exact Fintype.sum_equiv (Equiv.subRight y) _ _ (fun _ => rfl)
_ = _ := by rw [← Finset.sum_mul]; ring
theorem cyclic_convolution_comm {q : ℕ} [NeZero q] (f g : ZMod q → ℂ) :
cyclicConvolution f g = cyclicConvolution g f := by
funext x
unfold cyclicConvolution
apply Fintype.sum_equiv (Equiv.subLeft x)
intro y
simp only [Equiv.subLeft_apply, sub_sub_cancel]
ring
theorem cyclic_convolution_young_sq_right {q : ℕ} [NeZero q] (f g : ZMod q → ℂ) :
(∑ x : ZMod q, ‖cyclicConvolution f g x‖ ^ 2) ≤
(∑ x : ZMod q, ‖g x‖) ^ 2 * ∑ x : ZMod q, ‖f x‖ ^ 2 := by
rw [cyclic_convolution_comm]
exact cyclic_convolution_young_sq g f
theorem cyclic_unit_dilate_sum_norm {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (u : (ZMod q)ˣ) :
(∑ x : ZMod q, ‖cyclicUnitDilate f u x‖) = ∑ x : ZMod q, ‖f x‖ := by
exact Fintype.sum_equiv (ringUnitMulAddEquiv u⁻¹).toEquiv _ _ (fun _ => rfl)
theorem cyclic_unit_dilate_sq_norm {q : ℕ} [NeZero q] (f : ZMod q → ℂ) (u : (ZMod q)ˣ) :
(∑ x : ZMod q, ‖cyclicUnitDilate f u x‖ ^ 2) = ∑ x : ZMod q, ‖f x‖ ^ 2 := by
exact Fintype.sum_equiv (ringUnitMulAddEquiv u⁻¹).toEquiv _ _ (fun _ => rfl)
theorem cyclic_convolution_norm_of_nonnegative {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (hf : ∀ x, f x = (‖f x‖ : ℂ)) (hg : ∀ x, g x = (‖g x‖ : ℂ))
(x : ZMod q) : ‖cyclicConvolution f g x‖ = ∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ := by
have heq : cyclicConvolution f g x = ((∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ : ℝ) : ℂ) := by
unfold cyclicConvolution
rw [Complex.ofReal_sum]
apply Finset.sum_congr rfl
intro y hy
rw [Complex.ofReal_mul, ← hf, ← hg]
rw [heq, Complex.norm_of_nonneg (Finset.sum_nonneg (fun _ _ => mul_nonneg (norm_nonneg _) (norm_nonneg _)))]
theorem cyclic_set_combination_nonnegative {X : Type*} {q : ℕ} [NeZero q]
(I : Finset X) (w : X → ℝ) (A : X → Finset (ZMod q)) (hw : ∀ i ∈ I, 0 ≤ w i)
(x : ZMod q) : cyclicSetCombination I w A x = (‖cyclicSetCombination I w A x‖ : ℂ) := by
classical
rw [cyclic_set_combination_norm I w A hw, Complex.ofReal_sum]
apply Finset.sum_congr rfl
intro i hi
by_cases hx : x ∈ A i <;> simp [cyclicSetIndicator, hx]
theorem cyclic_convolution_norm_dominated {q : ℕ} [NeZero q]
(f g F G : ZMod q → ℂ) (hF : ∀ x, F x = (‖F x‖ : ℂ)) (hG : ∀ x, G x = (‖G x‖ : ℂ))
(hf : ∀ x, ‖f x‖ ≤ ‖F x‖) (hg : ∀ x, ‖g x‖ ≤ ‖G x‖) (x : ZMod q) :
‖cyclicConvolution f g x‖ ≤ ‖cyclicConvolution F G x‖ := by
rw [cyclic_convolution_norm_of_nonnegative F G hF hG]
calc
_ ≤ ∑ y : ZMod q, ‖f y‖ * ‖g (x - y)‖ := by
simpa only [cyclicConvolution, norm_mul] using norm_sum_le Finset.univ (fun y => f y * g (x - y))
_ ≤ _ := Finset.sum_le_sum (fun y _ => mul_le_mul (hf y) (hg _) (norm_nonneg _) (norm_nonneg _))
noncomputable def dyadicLevelWeight (n : ℕ) : ℝ := (1 / 2 : ℝ) ^ n
noncomputable def finiteDyadicLevel {X : Type*} [Fintype X] (p : X → ℝ) (n : ℕ) : Finset X := by
classical
exact Finset.univ.filter (fun x => dyadicLevelWeight n ≤ p x ∧ p x < 2 * dyadicLevelWeight n)
theorem dyadic_level_weight_pos (n : ℕ) : 0 < dyadicLevelWeight n := by
unfold dyadicLevelWeight
positivity
theorem dyadic_level_weight_zero : dyadicLevelWeight 0 = 1 := by simp [dyadicLevelWeight]
theorem dyadic_level_weight_succ (n : ℕ) : 2 * dyadicLevelWeight (n + 1) = dyadicLevelWeight n := by
unfold dyadicLevelWeight
rw [pow_succ]
ring
theorem dyadic_level_weight_antitone {m n : ℕ} (hmn : m ≤ n) : dyadicLevelWeight n ≤ dyadicLevelWeight m := by
exact pow_le_pow_of_le_one (by norm_num) (by norm_num) hmn
theorem dyadic_level_weight_rpow (n : ℕ) : dyadicLevelWeight n = (2 : ℝ) ^ (-(n : ℝ)) := by
rw [Real.rpow_neg (by norm_num), Real.rpow_natCast, ← inv_pow]
simp only [dyadicLevelWeight, one_div]
theorem mem_finite_dyadic_level {X : Type*} [Fintype X] (p : X → ℝ) (n : ℕ) (x : X) :
x ∈ finiteDyadicLevel p n ↔ dyadicLevelWeight n ≤ p x ∧ p x < 2 * dyadicLevelWeight n := by
classical
simp only [finiteDyadicLevel, Finset.mem_filter, Finset.mem_univ, true_and]
theorem finite_dyadic_level_disjoint {X : Type*} [Fintype X] (p : X → ℝ) {m n : ℕ}
(hmn : m ≠ n) : Disjoint (finiteDyadicLevel p m) (finiteDyadicLevel p n) := by
classical
rw [Finset.disjoint_left]
intro x hxm hxn
obtain ⟨hmlo, hmhi⟩ := (mem_finite_dyadic_level p m x).mp hxm
obtain ⟨hnlo, hnhi⟩ := (mem_finite_dyadic_level p n x).mp hxn
rcases lt_or_gt_of_ne hmn with hmn | hnm
· have hh := mul_le_mul_of_nonneg_left (dyadic_level_weight_antitone (Nat.succ_le_of_lt hmn)) (by norm_num : (0 : ℝ) ≤ 2)
rw [dyadic_level_weight_succ] at hh
linarith only [hh, hmlo, hnhi]
· have hh := mul_le_mul_of_nonneg_left (dyadic_level_weight_antitone (Nat.succ_le_of_lt hnm)) (by norm_num : (0 : ℝ) ≤ 2)
rw [dyadic_level_weight_succ] at hh
linarith only [hh, hnlo, hmhi]
theorem exists_finite_dyadic_level {X : Type*} [Fintype X] (p : X → ℝ) (N : ℕ) {x : X}
(hxlo : dyadicLevelWeight N ≤ p x) (hxhi : p x ≤ 1) :
∃ n : ℕ, n ≤ N ∧ x ∈ finiteDyadicLevel p n := by
induction N with
| zero =>
refine ⟨0, le_rfl, (mem_finite_dyadic_level p 0 x).mpr ⟨hxlo, ?_⟩⟩
rw [dyadic_level_weight_zero]
linarith only [hxhi]
| succ N ih =>
by_cases hh : dyadicLevelWeight N ≤ p x
· obtain ⟨n, hn, hxn⟩ := ih hh
exact ⟨n, hn.trans (Nat.le_succ _), hxn⟩
· refine ⟨N + 1, le_rfl, (mem_finite_dyadic_level p (N + 1) x).mpr ⟨hxlo, ?_⟩⟩
rw [dyadic_level_weight_succ]
exact lt_of_not_ge hh
theorem finite_level_card_bound {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) {A : Finset X} {w M : ℝ} (hp : ∀ x, 0 ≤ p x)
(hmass : ∑ x : X, p x ≤ M) (hlower : ∀ x ∈ A, w ≤ p x) :
w * (A.card : ℝ) ≤ M := by
calc
_ = ∑ _x ∈ A, w := by simp [mul_comm]
_ ≤ ∑ x ∈ A, p x := Finset.sum_le_sum hlower
_ ≤ ∑ x : X, p x := Finset.sum_le_sum_of_subset_of_nonneg (Finset.subset_univ _) (fun x _ _ => hp x)
_ ≤ _ := hmass
theorem finite_level_fiber_bound {X Y : Type*} [Fintype X] [DecidableEq X] [DecidableEq Y]
(p : X → ℝ) (π : X → Y) {A : Finset X} {w m M : ℝ}
(hp : ∀ x, 0 ≤ p x) (hm : 0 < m)
(hlower : ∀ x ∈ A, w ≤ p x) (hupper : ∀ x ∈ A, p x ≤ 2 * w)
(hmass : m ≤ ∑ x ∈ A, p x)
(hfiber : ∀ r : Y, (∑ x ∈ Finset.univ.filter (fun x => π x = r), p x) ≤ M) :
∀ r : Y, ((A.filter (fun x => π x = r)).card : ℝ) ≤ (2 * M / m) * (A.card : ℝ) := by
intro r
have hsize : m ≤ (2 * w) * (A.card : ℝ) := by
apply hmass.trans
calc
_ ≤ ∑ _x ∈ A, 2 * w := Finset.sum_le_sum hupper
_ = _ := by simp [mul_comm]
have hcount : w * ((A.filter (fun x => π x = r)).card : ℝ) ≤ M := by
calc
_ = ∑ _x ∈ A.filter (fun x => π x = r), w := by simp [mul_comm]
_ ≤ ∑ x ∈ A.filter (fun x => π x = r), p x :=
Finset.sum_le_sum (fun x hx => hlower x (Finset.mem_filter.mp hx).1)
_ ≤ ∑ x ∈ Finset.univ.filter (fun x => π x = r), p x :=
Finset.sum_le_sum_of_subset_of_nonneg (Finset.filter_subset_filter _ (Finset.subset_univ _))
(fun x _ _ => hp x)
_ ≤ _ := hfiber r
apply (mul_le_mul_iff_left₀ hm).mp
calc
_ ≤ ((2 * w) * (A.card : ℝ)) * ((A.filter (fun x => π x = r)).card : ℝ) := by
simpa only [mul_comm] using mul_le_mul_of_nonneg_right hsize
(Nat.cast_nonneg (A.filter (fun x => π x = r)).card : (0 : ℝ) ≤ (A.filter (fun x => π x = r)).card)
_ = (2 * (A.card : ℝ)) * (w * ((A.filter (fun x => π x = r)).card : ℝ)) := by ring
_ ≤ (2 * (A.card : ℝ)) * M := mul_le_mul_of_nonneg_left hcount (by positivity)
_ = _ := by field_simp
theorem finite_dyadic_level_fiber_bound {X Y : Type*} [Fintype X] [DecidableEq X] [DecidableEq Y]
(p : X → ℝ) (π : X → Y) (n : ℕ) {m M : ℝ}
(hp : ∀ x, 0 ≤ p x) (hm : 0 < m) (hmass : m ≤ ∑ x ∈ finiteDyadicLevel p n, p x)
(hfiber : ∀ r : Y, (∑ x ∈ Finset.univ.filter (fun x => π x = r), p x) ≤ M) :
∀ r : Y, (((finiteDyadicLevel p n).filter (fun x => π x = r)).card : ℝ) ≤
(2 * M / m) * ((finiteDyadicLevel p n).card : ℝ) :=
finite_level_fiber_bound p π hp hm
(fun x hx => ((mem_finite_dyadic_level p n x).mp hx).1)
(fun x hx => ((mem_finite_dyadic_level p n x).mp hx).2.le) hmass hfiber
noncomputable def finiteDyadicApprox {X : Type*} [Fintype X]
(p : X → ℝ) (I : Finset ℕ) (x : X) : ℝ := by
classical
exact ∑ n ∈ I, if x ∈ finiteDyadicLevel p n then dyadicLevelWeight n else 0
theorem finite_dyadic_approx_eq_weight {X : Type*} [Fintype X]
(p : X → ℝ) {I : Finset ℕ} {n : ℕ} {x : X}
(hn : n ∈ I) (hx : x ∈ finiteDyadicLevel p n) : finiteDyadicApprox p I x = dyadicLevelWeight n := by
classical
unfold finiteDyadicApprox
rw [Finset.sum_eq_single n]
· simp only [hx, if_true]
· intro k hk hkn
have hnot : x ∉ finiteDyadicLevel p k := by
intro hxk
exact (Finset.disjoint_left.mp (finite_dyadic_level_disjoint p hkn)) hxk hx
simp only [hnot, if_false]
· exact fun h => (h hn).elim
theorem finite_dyadic_approx_nonneg {X : Type*} [Fintype X]
(p : X → ℝ) (I : Finset ℕ) (x : X) : 0 ≤ finiteDyadicApprox p I x := by
classical
unfold finiteDyadicApprox
apply Finset.sum_nonneg
intro n hn
split_ifs
· exact (dyadic_level_weight_pos n).le
· exact le_rfl
theorem finite_dyadic_approx_le {X : Type*} [Fintype X]
(p : X → ℝ) (I : Finset ℕ) (hp : ∀ x, 0 ≤ p x) (x : X) : finiteDyadicApprox p I x ≤ p x := by
classical
by_cases hx : ∃ n ∈ I, x ∈ finiteDyadicLevel p n
· obtain ⟨n, hn, hxn⟩ := hx
rw [finite_dyadic_approx_eq_weight p hn hxn]
exact ((mem_finite_dyadic_level p n x).mp hxn).1
· have hzero : finiteDyadicApprox p I x = 0 := by
apply Finset.sum_eq_zero
intro n hn
have hnot : x ∉ finiteDyadicLevel p n := fun hxn => hx ⟨n, hn, hxn⟩
simp only [hnot, if_false]
rw [hzero]
exact hp x
theorem finite_dyadic_approx_dominates {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) (I : Finset ℕ) {x : X} (hx : x ∈ I.biUnion (finiteDyadicLevel p)) :
p x ≤ 2 * finiteDyadicApprox p I x := by
obtain ⟨n, hn, hxn⟩ := Finset.mem_biUnion.mp hx
rw [finite_dyadic_approx_eq_weight p hn hxn]
exact ((mem_finite_dyadic_level p n x).mp hxn).2.le
theorem finite_dyadic_approx_sum {X : Type*} [Fintype X]
(p : X → ℝ) (I : Finset ℕ) :
(∑ x : X, finiteDyadicApprox p I x) = ∑ n ∈ I, dyadicLevelWeight n * ((finiteDyadicLevel p n).card : ℝ) := by
classical
unfold finiteDyadicApprox
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro n hn
simp [← Finset.sum_filter, mul_comm]
theorem finite_dyadic_union_mass {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) (I : Finset ℕ) :
(∑ x ∈ I.biUnion (finiteDyadicLevel p), p x) = ∑ n ∈ I, ∑ x ∈ finiteDyadicLevel p n, p x := by
apply Finset.sum_biUnion
intro m hm n hn hmn
exact finite_dyadic_level_disjoint p hmn
theorem cyclic_dyadic_combination_norm {q : ℕ} [NeZero q]
(p : ZMod q → ℝ) (I : Finset ℕ) (x : ZMod q) :
‖cyclicSetCombination I dyadicLevelWeight (finiteDyadicLevel p) x‖ = finiteDyadicApprox p I x := by
classical
rw [cyclic_set_combination_norm _ _ _ (fun n _ => (dyadic_level_weight_pos n).le)]
simp only [cyclic_set_indicator_norm, mul_ite, mul_one, mul_zero, finiteDyadicApprox]
apply Finset.sum_congr rfl
intro n hn
split_ifs <;> rfl
/-- Retain high-weight levels with significant mass. The remaining points
split into a part of small total mass and a part of uniformly small weight. -/
theorem exists_finite_dyadic_level_decomposition {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) (N : ℕ) {v m : ℝ} (hp : ∀ x, 0 ≤ p x) (hp1 : ∀ x, p x ≤ 1)
(hm : 0 < m) (hNv : dyadicLevelWeight N ≤ v) :
∃ I : Finset ℕ, ∃ G S : Finset X,
I.card ≤ N + 1 ∧ G = I.biUnion (finiteDyadicLevel p) ∧ Disjoint G S ∧
(∀ n ∈ I, (finiteDyadicLevel p n).Nonempty ∧ v < dyadicLevelWeight n ∧
m ≤ ∑ x ∈ finiteDyadicLevel p n, p x) ∧
(∑ x ∈ S, p x) ≤ (N + 1 : ℕ) * m ∧
(∀ x : X, x ∉ G → x ∉ S → p x ≤ 2 * v) := by
classical
let I := (Finset.range (N + 1)).filter (fun n => v < dyadicLevelWeight n ∧ m ≤ ∑ x ∈ finiteDyadicLevel p n, p x)
let K := (Finset.range (N + 1)).filter (fun n => v < dyadicLevelWeight n ∧ (∑ x ∈ finiteDyadicLevel p n, p x) < m)
let G := I.biUnion (finiteDyadicLevel p)
let S := K.biUnion (finiteDyadicLevel p)
have hI : I.card ≤ N + 1 := (Finset.card_filter_le _ _).trans_eq (Finset.card_range _)
have hK : K.card ≤ N + 1 := (Finset.card_filter_le _ _).trans_eq (Finset.card_range _)
refine ⟨I, G, S, hI, rfl, ?_, ?_, ?_, ?_⟩
· rw [Finset.disjoint_left]
intro x hxG hxS
obtain ⟨i, hi, hxi⟩ := Finset.mem_biUnion.mp hxG
obtain ⟨k, hk, hxk⟩ := Finset.mem_biUnion.mp hxS
have hik : i ≠ k := by
intro heq
subst k
exact (not_lt_of_ge (Finset.mem_filter.mp hi).2.2) (Finset.mem_filter.mp hk).2.2
exact (Finset.disjoint_left.mp (finite_dyadic_level_disjoint p hik)) hxi hxk
· intro n hn
have hgood := (Finset.mem_filter.mp hn).2
refine ⟨?_, hgood⟩
by_contra h
have he : finiteDyadicLevel p n = ∅ := Finset.not_nonempty_iff_eq_empty.mp h
simp only [he, Finset.sum_empty] at hgood
exact (not_le_of_gt hm) hgood.2
· rw [finite_dyadic_union_mass]
calc
_ ≤ ∑ _n ∈ K, m := Finset.sum_le_sum (fun n hn => (Finset.mem_filter.mp hn).2.2.le)
_ = (K.card : ℝ) * m := by simp
_ ≤ _ := mul_le_mul_of_nonneg_right (by exact_mod_cast hK) hm.le
· intro x hxG hxS
by_contra hx
have hxv : 2 * v < p x := lt_of_not_ge hx
have hv : 0 < v := (dyadic_level_weight_pos N).trans_le hNv
have hxN : dyadicLevelWeight N ≤ p x := by linarith only [hNv, hxv, hv]
obtain ⟨n, hn, hxn⟩ := exists_finite_dyadic_level p N hxN (hp1 x)
have hnrange : n ∈ Finset.range (N + 1) := Finset.mem_range.mpr (by omega)
have hnv : v < dyadicLevelWeight n := by
have hh := ((mem_finite_dyadic_level p n x).mp hxn).2
linarith only [hh, hxv]
by_cases hmass : m ≤ ∑ x ∈ finiteDyadicLevel p n, p x
· exact hxG (Finset.mem_biUnion.mpr ⟨n, Finset.mem_filter.mpr ⟨hnrange, hnv, hmass⟩, hxn⟩)
· exact hxS (Finset.mem_biUnion.mpr ⟨n, Finset.mem_filter.mpr ⟨hnrange, hnv, lt_of_not_ge hmass⟩, hxn⟩)
theorem norm_five_sum_sq_le (a b c d e : ℂ) :
‖a + b + c + d + e‖ ^ 2 ≤ 5 * (‖a‖ ^ 2 + ‖b‖ ^ 2 + ‖c‖ ^ 2 + ‖d‖ ^ 2 + ‖e‖ ^ 2) := by
have hh := norm_sum_sq_le_card_mul_sum_sq (Finset.univ : Finset (Fin 5)) ![a, b, c, d, e]
simpa [Fin.sum_univ_succ, add_assoc] using hh
theorem cyclic_unit_convolution_decomposition {q : ℕ} [NeZero q]
(f g l s : ZMod q → ℂ) (u : (ZMod q)ˣ)
(hdecomp : ∀ x, f x = g x + l x + s x) (x : ZMod q) :
cyclicConvolution f (cyclicUnitDilate f u) x =
cyclicConvolution g (cyclicUnitDilate g u) x +
cyclicConvolution l (cyclicUnitDilate f u) x +
cyclicConvolution s (cyclicUnitDilate f u) x +
cyclicConvolution g (cyclicUnitDilate l u) x +
cyclicConvolution g (cyclicUnitDilate s u) x := by
unfold cyclicConvolution cyclicUnitDilate
rw [← Finset.sum_add_distrib, ← Finset.sum_add_distrib, ← Finset.sum_add_distrib,
← Finset.sum_add_distrib]
apply Finset.sum_congr rfl
intro y hy
rw [hdecomp y, hdecomp (((u⁻¹ : (ZMod q)ˣ) : ZMod q) * (x - y))]
ring
theorem cyclic_unit_convolution_error_bound {q : ℕ} [NeZero q]
(f g l s : ZMod q → ℂ) (u : (ZMod q)ˣ) {v m : ℝ}
(hdecomp : ∀ x, f x = g x + l x + s x)
(hfmass : (∑ x : ZMod q, ‖f x‖) ≤ 1) (hgmass : (∑ x : ZMod q, ‖g x‖) ≤ 1)
(hgener : (∑ x : ZMod q, ‖g x‖ ^ 2) ≤ ∑ x : ZMod q, ‖f x‖ ^ 2)
(hlener : (∑ x : ZMod q, ‖l x‖ ^ 2) ≤ v)
(hsmass : (∑ x : ZMod q, ‖s x‖) ≤ m) (hm : 0 ≤ m) :
(∑ x : ZMod q, ‖cyclicConvolution f (cyclicUnitDilate f u) x‖ ^ 2) ≤
5 * (∑ x : ZMod q, ‖cyclicConvolution g (cyclicUnitDilate g u) x‖ ^ 2) +
10 * v + 10 * m ^ 2 * ∑ x : ZMod q, ‖f x‖ ^ 2 := by
have hfmass2 : (∑ x : ZMod q, ‖f x‖) ^ 2 ≤ 1 := by
simpa only [one_pow] using pow_le_pow_left₀ (Finset.sum_nonneg (fun _ _ => norm_nonneg _)) hfmass 2
have hgmass2 : (∑ x : ZMod q, ‖g x‖) ^ 2 ≤ 1 := by
simpa only [one_pow] using pow_le_pow_left₀ (Finset.sum_nonneg (fun _ _ => norm_nonneg _)) hgmass 2
have hsmass2 : (∑ x : ZMod q, ‖s x‖) ^ 2 ≤ m ^ 2 :=
pow_le_pow_left₀ (Finset.sum_nonneg (fun _ _ => norm_nonneg _)) hsmass 2
have hlf : (∑ x : ZMod q, ‖cyclicConvolution l (cyclicUnitDilate f u) x‖ ^ 2) ≤ v := by
calc
_ ≤ (∑ x : ZMod q, ‖cyclicUnitDilate f u x‖) ^ 2 * ∑ x : ZMod q, ‖l x‖ ^ 2 :=
cyclic_convolution_young_sq_right _ _
_ = (∑ x : ZMod q, ‖f x‖) ^ 2 * ∑ x : ZMod q, ‖l x‖ ^ 2 := by rw [cyclic_unit_dilate_sum_norm]
_ ≤ 1 * ∑ x : ZMod q, ‖l x‖ ^ 2 := mul_le_mul_of_nonneg_right hfmass2 (by positivity)
_ ≤ _ := by simpa only [one_mul] using hlener
have hsf : (∑ x : ZMod q, ‖cyclicConvolution s (cyclicUnitDilate f u) x‖ ^ 2) ≤
m ^ 2 * ∑ x : ZMod q, ‖f x‖ ^ 2 := by
calc
_ ≤ (∑ x : ZMod q, ‖s x‖) ^ 2 * ∑ x : ZMod q, ‖cyclicUnitDilate f u x‖ ^ 2 :=
cyclic_convolution_young_sq _ _
_ = (∑ x : ZMod q, ‖s x‖) ^ 2 * ∑ x : ZMod q, ‖f x‖ ^ 2 := by rw [cyclic_unit_dilate_sq_norm]
_ ≤ _ := mul_le_mul_of_nonneg_right hsmass2 (by positivity)
have hgl : (∑ x : ZMod q, ‖cyclicConvolution g (cyclicUnitDilate l u) x‖ ^ 2) ≤ v := by
calc
_ ≤ (∑ x : ZMod q, ‖g x‖) ^ 2 * ∑ x : ZMod q, ‖cyclicUnitDilate l u x‖ ^ 2 :=
cyclic_convolution_young_sq _ _
_ = (∑ x : ZMod q, ‖g x‖) ^ 2 * ∑ x : ZMod q, ‖l x‖ ^ 2 := by rw [cyclic_unit_dilate_sq_norm]
_ ≤ 1 * ∑ x : ZMod q, ‖l x‖ ^ 2 := mul_le_mul_of_nonneg_right hgmass2 (by positivity)
_ ≤ _ := by simpa only [one_mul] using hlener
have hgs : (∑ x : ZMod q, ‖cyclicConvolution g (cyclicUnitDilate s u) x‖ ^ 2) ≤
m ^ 2 * ∑ x : ZMod q, ‖f x‖ ^ 2 := by
calc
_ ≤ (∑ x : ZMod q, ‖cyclicUnitDilate s u x‖) ^ 2 * ∑ x : ZMod q, ‖g x‖ ^ 2 :=
cyclic_convolution_young_sq_right _ _
_ = (∑ x : ZMod q, ‖s x‖) ^ 2 * ∑ x : ZMod q, ‖g x‖ ^ 2 := by rw [cyclic_unit_dilate_sum_norm]
_ ≤ _ := mul_le_mul hsmass2 hgener (by positivity) (sq_nonneg _)
calc
_ ≤ ∑ x : ZMod q, 5 * (
‖cyclicConvolution g (cyclicUnitDilate g u) x‖ ^ 2 +
‖cyclicConvolution l (cyclicUnitDilate f u) x‖ ^ 2 +
‖cyclicConvolution s (cyclicUnitDilate f u) x‖ ^ 2 +
‖cyclicConvolution g (cyclicUnitDilate l u) x‖ ^ 2 +
‖cyclicConvolution g (cyclicUnitDilate s u) x‖ ^ 2) := by
apply Finset.sum_le_sum
intro x hx
rw [cyclic_unit_convolution_decomposition f g l s u hdecomp]
exact norm_five_sum_sq_le _ _ _ _ _
_ = 5 * ((∑ x : ZMod q, ‖cyclicConvolution g (cyclicUnitDilate g u) x‖ ^ 2) +
(∑ x : ZMod q, ‖cyclicConvolution l (cyclicUnitDilate f u) x‖ ^ 2) +
(∑ x : ZMod q, ‖cyclicConvolution s (cyclicUnitDilate f u) x‖ ^ 2) +
(∑ x : ZMod q, ‖cyclicConvolution g (cyclicUnitDilate l u) x‖ ^ 2) +
∑ x : ZMod q, ‖cyclicConvolution g (cyclicUnitDilate s u) x‖ ^ 2) := by
rw [← Finset.mul_sum]
simp only [Finset.sum_add_distrib]
_ ≤ _ := by linarith only [hlf, hsf, hgl, hgs]
theorem cyclic_unit_energy_dominated {q : ℕ} [NeZero q]
(f F : ZMod q → ℂ) (u : (ZMod q)ˣ) {c : ℝ} (hc : 0 ≤ c)
(hF : ∀ x, F x = (‖F x‖ : ℂ)) (hf : ∀ x, ‖f x‖ ≤ c * ‖F x‖) :
(∑ x : ZMod q, ‖cyclicConvolution f (cyclicUnitDilate f u) x‖ ^ 2) ≤
c ^ 4 * ∑ x : ZMod q, ‖cyclicConvolution F (cyclicUnitDilate F u) x‖ ^ 2 := by
have hpoint : ∀ x : ZMod q, ‖cyclicConvolution f (cyclicUnitDilate f u) x‖ ≤
c ^ 2 * ‖cyclicConvolution F (cyclicUnitDilate F u) x‖ := by
intro x
rw [cyclic_convolution_norm_of_nonnegative F (cyclicUnitDilate F u) hF
(fun y => hF (((u⁻¹ : (ZMod q)ˣ) : ZMod q) * y))]
calc
_ ≤ ∑ y : ZMod q, ‖f y‖ * ‖cyclicUnitDilate f u (x - y)‖ := by
simpa only [cyclicConvolution, norm_mul] using
norm_sum_le Finset.univ (fun y => f y * cyclicUnitDilate f u (x - y))
_ ≤ ∑ y : ZMod q, (c * ‖F y‖) * (c * ‖cyclicUnitDilate F u (x - y)‖) :=
Finset.sum_le_sum (fun y _ => mul_le_mul (hf y) (hf _) (norm_nonneg _) (by positivity))
_ = _ := by
rw [Finset.mul_sum]
apply Finset.sum_congr rfl
intro y hy
ring
calc
_ ≤ ∑ x : ZMod q, (c ^ 2 * ‖cyclicConvolution F (cyclicUnitDilate F u) x‖) ^ 2 :=
Finset.sum_le_sum (fun x _ => pow_le_pow_left₀ (norm_nonneg _) (hpoint x) 2)
_ = _ := by simp only [mul_pow, ← pow_mul, show (2 : ℕ) * 2 = 4 from rfl, Finset.mul_sum]
/-- A fixed exponential bound absorbs the number of dyadic levels. -/
theorem exists_dyadic_linear_count_bound {η : ℝ} (hη : 0 < η) :
∃ J₀ : ℕ, ∀ J : ℕ, J₀ ≤ J → ((2 * J + 1 : ℕ) : ℝ) ≤ (2 : ℝ) ^ (η * (J : ℝ)) := by
let b := (2 : ℝ) ^ (η / 2)
have hb : 1 < b := Real.one_lt_rpow (by norm_num) (by positivity)
let d := b - 1
have hd : 0 < d := sub_pos.mpr hb
obtain ⟨J₀, hJ₀⟩ := exists_nat_ge (2 / d ^ 2)
refine ⟨J₀, ?_⟩
intro J hJ
have hJ0 : (0 : ℝ) ≤ J := Nat.cast_nonneg _
have hJr : (J₀ : ℝ) ≤ (J : ℝ) := by exact_mod_cast hJ
have hbound : 2 ≤ (J : ℝ) * d ^ 2 := (div_le_iff₀ (sq_pos_of_pos hd)).mp (hJ₀.trans hJr)
have hquad : 2 * (J : ℝ) ≤ ((J : ℝ) * d) ^ 2 := by
have hh := mul_le_mul_of_nonneg_left hbound hJ0
nlinarith only [hh]
have hbern : 1 + (J : ℝ) * d ≤ b ^ J := by
have hh := one_add_mul_le_pow (show -2 ≤ d by linarith only [hd]) J
simpa only [d, add_sub_cancel] using hh
calc
_ ≤ (1 + (J : ℝ) * d) ^ 2 := by
push_cast
nlinarith only [hquad, mul_nonneg hJ0 hd.le]
_ ≤ (b ^ J) ^ 2 := pow_le_pow_left₀ (by positivity) hbern 2
_ = _ := by
dsimp only [b]
rw [← Real.rpow_mul_natCast (by norm_num), ← Real.rpow_mul_natCast (by norm_num)]
congr 1
norm_num
ring
noncomputable def finiteRealRestriction {X : Type*} [DecidableEq X]
(p : X → ℝ) (A : Finset X) (x : X) : ℂ := if x ∈ A then (p x : ℂ) else 0
theorem finite_real_restriction_norm {X : Type*} [DecidableEq X]
(p : X → ℝ) (A : Finset X) (hp : ∀ x, 0 ≤ p x) (x : X) :
‖finiteRealRestriction p A x‖ = if x ∈ A then p x else 0 := by
by_cases hx : x ∈ A <;>
simp [finiteRealRestriction, hx, Complex.norm_real, Real.norm_eq_abs, abs_of_nonneg (hp x)]
theorem finite_real_restriction_norm_le {X : Type*} [DecidableEq X]
(p : X → ℝ) (A : Finset X) (hp : ∀ x, 0 ≤ p x) (x : X) :
‖finiteRealRestriction p A x‖ ≤ p x := by
rw [finite_real_restriction_norm p A hp]
split_ifs
· exact le_rfl
· exact hp x
theorem finite_real_restriction_mass {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) (A : Finset X) (hp : ∀ x, 0 ≤ p x) :
(∑ x : X, ‖finiteRealRestriction p A x‖) = ∑ x ∈ A, p x := by
simp only [finite_real_restriction_norm p A hp, ← Finset.sum_filter,
Finset.filter_mem_eq_inter, Finset.univ_inter]
theorem finite_real_restriction_mass_le {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) (A : Finset X) (hp : ∀ x, 0 ≤ p x) :
(∑ x : X, ‖finiteRealRestriction p A x‖) ≤ ∑ x : X, p x :=
Finset.sum_le_sum (fun x _ => finite_real_restriction_norm_le p A hp x)
theorem finite_real_restriction_energy_le {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) (A : Finset X) (hp : ∀ x, 0 ≤ p x) :
(∑ x : X, ‖finiteRealRestriction p A x‖ ^ 2) ≤ ∑ x : X, p x ^ 2 :=
Finset.sum_le_sum (fun x _ => pow_le_pow_left₀ (norm_nonneg _) (finite_real_restriction_norm_le p A hp x) 2)
theorem finite_real_restriction_energy_of_peak {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) (A : Finset X) {M : ℝ} (hp : ∀ x, 0 ≤ p x) (hM : 0 ≤ M)
(hmass : (∑ x : X, p x) ≤ 1) (hpeak : ∀ x ∈ A, p x ≤ M) :
(∑ x : X, ‖finiteRealRestriction p A x‖ ^ 2) ≤ M := by
have hh : ∀ x : X, ‖finiteRealRestriction p A x‖ ≤ M := by
intro x
rw [finite_real_restriction_norm p A hp]
split_ifs with hx
· exact hpeak x hx
· exact hM
calc
_ ≤ ∑ x : X, M * ‖finiteRealRestriction p A x‖ := by
apply Finset.sum_le_sum
intro x hx
simpa only [pow_two] using mul_le_mul_of_nonneg_right (hh x) (norm_nonneg _)
_ = M * ∑ x : X, ‖finiteRealRestriction p A x‖ := (Finset.mul_sum _ _ _).symm
_ ≤ M * 1 := mul_le_mul_of_nonneg_left ((finite_real_restriction_mass_le p A hp).trans hmass) hM
_ = _ := mul_one _
theorem finite_real_restriction_three_parts {X : Type*} [Fintype X] [DecidableEq X]
(p : X → ℝ) {G S : Finset X} (hGS : Disjoint G S) (x : X) :
(p x : ℂ) = finiteRealRestriction p G x + finiteRealRestriction p ((G ∪ S)ᶜ) x +
finiteRealRestriction p S x := by
by_cases hxG : x ∈ G
· have hxS : x ∉ S := fun hxS => (Finset.disjoint_left.mp hGS) hxG hxS
simp [finiteRealRestriction, hxG, hxS]
· by_cases hxS : x ∈ S <;> simp [finiteRealRestriction, hxG, hxS]
def DyadicProbabilityNonconcentration {J : ℕ} (γ ε : ℝ) (p : ZMod (2 ^ J) → ℝ) : Prop :=
∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
(∑ x ∈ Finset.univ.filter (fun x : ZMod (2 ^ J) => (x.val : ZMod (2 ^ L)) = r), p x) ≤
(2 : ℝ) ^ (-γ * (L : ℝ))
/-- Averaged additive flattening for an arbitrary nonnegative law whose
squared norm remains above the density threshold. -/
theorem exists_dyadic_probability_flattening {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ p : ZMod (2 ^ J) → ℝ, ∀ T : Finset (ZMod (2 ^ J))ˣ,
(∀ x, 0 ≤ p x) → (∑ x : ZMod (2 ^ J), p x) ≤ 1 →
(2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) ≤ (∑ x : ZMod (2 ^ J), p x ^ 2) →
DyadicProbabilityNonconcentration γ ε p → T.Nonempty → DyadicUnitSetNonconcentration γ ε T →
(∑ u ∈ T, ∑ x : ZMod (2 ^ J),
‖cyclicConvolution (fun y => (p y : ℂ)) (cyclicUnitDilate (fun y => (p y : ℂ)) u) x‖ ^ 2) ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * (T.card : ℝ) * ∑ x : ZMod (2 ^ J), p x ^ 2 := by
classical
obtain ⟨a, ε, ha, hε, hε4, J₀, hflat⟩ := exists_dyadic_set_combination_flattening (X := ℕ)
(show 0 < γ / 2 by positivity) (show 0 < δ / 2 by positivity) (by linarith only [hδ1])
let η := γ * ε / 8
have hη : 0 < η := by dsimp only [η]; positivity
let b := min a (min (δ / 2) η)
have hb : 0 < b := lt_min ha (lt_min (by positivity) hη)
have hba : b ≤ a := min_le_left _ _
have hbδ : b ≤ δ / 2 := (min_le_right _ _).trans (min_le_left _ _)
have hbη : b ≤ η := (min_le_right _ _).trans (min_le_right _ _)
obtain ⟨J₁, hJ₁⟩ := exists_dyadic_linear_count_bound ha
obtain ⟨J₂, hJ₂⟩ := exists_dyadic_linear_count_bound (show 0 < η / 2 by positivity)
obtain ⟨J₃, hJ₃⟩ := exists_dyadic_fixed_power_absorption 1 0 (τ := 0) (ξ := η) (by simpa using hη)
obtain ⟨J₄, hJ₄⟩ := exists_dyadic_fixed_power_absorption 7 0 (τ := 0) (ξ := b / 2)
(by simpa using (show 0 < b / 2 by positivity))
refine ⟨b / 2, ε, by positivity, hε, hε4, max J₀ (max J₁ (max J₂ (max J₃ J₄))), ?_⟩
intro J hJ p T hp hmass hnorm hspread hT hTspread
have hj₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hj₁ : J₁ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans hJ)
have hj₂ : J₂ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans hJ))
have hj₃ : J₃ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans hJ)))
have hj₄ : J₄ ≤ J := (le_max_right _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans hJ)))
have hJ0 : (0 : ℝ) ≤ J := Nat.cast_nonneg _
have hp1 : ∀ x, p x ≤ 1 := fun x =>
(Finset.single_le_sum (fun y _ => hp y) (Finset.mem_univ x)).trans hmass
let v := (2 : ℝ) ^ (-(1 - δ / 2) * (J : ℝ))
let m := (2 : ℝ) ^ (-η * (J : ℝ))
let z := (2 : ℝ) ^ (-(η / 2) * (J : ℝ))
let H := ∑ x : ZMod (2 ^ J), p x ^ 2
have hv : 0 < v := by positivity
have hm : 0 < m := by positivity
have hz : 0 ≤ z := by positivity
have hH : 0 ≤ H := Finset.sum_nonneg (fun _ _ => sq_nonneg _)
have hNv : dyadicLevelWeight (2 * J) ≤ v := by
rw [dyadic_level_weight_rpow]
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
push_cast
nlinarith only [hJ0, mul_nonneg hδ.le hJ0]
obtain ⟨I, G, S, hI, hG, hGS, hlevels, hS, hlow⟩ :=
exists_finite_dyadic_level_decomposition p (2 * J) hp hp1 hm hNv
let A := finiteDyadicLevel p
let F := cyclicSetCombination I dyadicLevelWeight A
let f := fun x => (p x : ℂ)
let g := finiteRealRestriction p G
let l := finiteRealRestriction p ((G ∪ S)ᶜ)
let s := finiteRealRestriction p S
have hfnorm : ∀ x, ‖f x‖ = p x := fun x => Complex.norm_of_nonneg (hp x)
have hfmass : (∑ x : ZMod (2 ^ J), ‖f x‖) ≤ 1 := by simpa only [hfnorm] using hmass
have hfenergy : (∑ x : ZMod (2 ^ J), ‖f x‖ ^ 2) = H := by simp only [hfnorm, H]
have hIcap : (I.card : ℝ) ≤ (2 : ℝ) ^ (a * (J : ℝ)) :=
(show (I.card : ℝ) ≤ ((2 * J + 1 : ℕ) : ℝ) by exact_mod_cast hI).trans (hJ₁ J hj₁)
have hsmass : (∑ x : ZMod (2 ^ J), ‖s x‖) ≤ z := by
rw [finite_real_restriction_mass p S hp]
calc
_ ≤ ((2 * J + 1 : ℕ) : ℝ) * m := hS
_ ≤ (2 : ℝ) ^ ((η / 2) * (J : ℝ)) * (2 : ℝ) ^ (-η * (J : ℝ)) :=
mul_le_mul_of_nonneg_right (hJ₂ J hj₂) hm.le
_ = _ := by
rw [← Real.rpow_add (by norm_num)]
congr 1
ring
have h2η : (2 : ℝ) ≤ (2 : ℝ) ^ (η * (J : ℝ)) := by simpa using hJ₃ J hj₃
have hloss : ∀ L : ℕ, ε * (J : ℝ) < (L : ℝ) →
2 * (2 : ℝ) ^ (-γ * (L : ℝ)) / m ≤ (2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) := by
intro L hL
apply (div_le_iff₀ hm).mpr
calc
_ ≤ (2 : ℝ) ^ (η * (J : ℝ)) * (2 : ℝ) ^ (-γ * (L : ℝ)) := by gcongr
_ = (2 : ℝ) ^ (η * (J : ℝ) - γ * (L : ℝ)) := by
rw [← Real.rpow_add (by norm_num)]; congr 1; ring
_ ≤ (2 : ℝ) ^ (-(γ / 2) * (L : ℝ) - η * (J : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
dsimp only [η]
nlinarith only [mul_lt_mul_of_pos_left hL hγ, mul_nonneg hγ.le (Nat.cast_nonneg L : (0 : ℝ) ≤ L)]
_ = _ := by
dsimp only [m]
rw [← Real.rpow_add (by norm_num)]
congr 1
ring
have hA : ∀ n ∈ I, (A n).Nonempty ∧
((A n).card : ℝ) ≤ (2 : ℝ) ^ ((1 - δ / 2) * (J : ℝ)) ∧
DyadicRingSetNonconcentration (γ / 2) ε (A n) := by
intro n hn
obtain ⟨hnonempty, hnweight, hnmass⟩ := hlevels n hn
refine ⟨hnonempty, ?_, ?_⟩
· have hcard := finite_level_card_bound p hp hmass
(fun x hx => ((mem_finite_dyadic_level p n x).mp hx).1)
have hvc : v * ((A n).card : ℝ) ≤ 1 :=
(mul_le_mul_of_nonneg_right hnweight.le (Nat.cast_nonneg _)).trans hcard
apply (mul_le_mul_iff_of_pos_left hv).mp
calc
_ ≤ 1 := hvc
_ = _ := by
dsimp only [v]
rw [← Real.rpow_add (by norm_num),
show -(1 - δ / 2) * (J : ℝ) + (1 - δ / 2) * (J : ℝ) = 0 by ring, Real.rpow_zero]
· intro L hL hεL r
have hh := finite_dyadic_level_fiber_bound p (fun x => (x.val : ZMod (2 ^ L))) n
hp hm hnmass (hspread L hL hεL) r
exact hh.trans (mul_le_mul_of_nonneg_right (hloss L hεL) (Nat.cast_nonneg _))
have hTspread' : DyadicUnitSetNonconcentration (γ / 2) ε T := by
intro L hL hεL r
apply (hTspread L hL hεL r).trans
apply mul_le_mul_of_nonneg_right _ (Nat.cast_nonneg _)
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith only [mul_nonneg hγ.le (Nat.cast_nonneg L : (0 : ℝ) ≤ L)]
have hFmass : (∑ n ∈ I, dyadicLevelWeight n * ((A n).card : ℝ)) ≤ 1 := by
rw [← finite_dyadic_approx_sum p I]
exact (Finset.sum_le_sum (fun x _ => finite_dyadic_approx_le p I hp x)).trans hmass
have hFenergy : (∑ x : ZMod (2 ^ J), ‖F x‖ ^ 2) ≤ H := by
apply Finset.sum_le_sum
intro x hx
rw [cyclic_dyadic_combination_norm]
exact pow_le_pow_left₀ (finite_dyadic_approx_nonneg p I x) (finite_dyadic_approx_le p I hp x) 2
have hFflat := hflat J hj₀ I dyadicLevelWeight A T (fun n _ => (dyadic_level_weight_pos n).le)
hT hIcap hFmass hA hTspread'
have hFnonneg : ∀ x, F x = (‖F x‖ : ℂ) :=
cyclic_set_combination_nonnegative I dyadicLevelWeight A (fun n _ => (dyadic_level_weight_pos n).le)
have hgdom : ∀ x, ‖g x‖ ≤ 2 * ‖F x‖ := by
intro x
rw [finite_real_restriction_norm p G hp]
by_cases hx : x ∈ G
· rw [if_pos hx, cyclic_dyadic_combination_norm]
exact finite_dyadic_approx_dominates p I (by rwa [← hG])
· rw [if_neg hx]
positivity
have hgavg : (∑ u ∈ T, ∑ x : ZMod (2 ^ J), ‖cyclicConvolution g (cyclicUnitDilate g u) x‖ ^ 2) ≤
16 * (2 : ℝ) ^ (-a * (J : ℝ)) * (T.card : ℝ) * H := by
have hFbound : (∑ u ∈ T, ∑ x : ZMod (2 ^ J), ‖cyclicConvolution F (cyclicUnitDilate F u) x‖ ^ 2) ≤
(2 : ℝ) ^ (-a * (J : ℝ)) * (T.card : ℝ) * H := by
exact hFflat.trans (mul_le_mul_of_nonneg_left hFenergy
(show 0 ≤ (2 : ℝ) ^ (-a * (J : ℝ)) * (T.card : ℝ) from mul_nonneg
(Real.rpow_pos_of_pos (by norm_num) _).le (Nat.cast_nonneg _)))
calc
_ ≤ ∑ u ∈ T, (2 : ℝ) ^ (4 : ℕ) * ∑ x : ZMod (2 ^ J), ‖cyclicConvolution F (cyclicUnitDilate F u) x‖ ^ 2 :=
Finset.sum_le_sum (fun u _ => cyclic_unit_energy_dominated g F u (by norm_num) hFnonneg hgdom)
_ = 16 * ∑ u ∈ T, ∑ x : ZMod (2 ^ J), ‖cyclicConvolution F (cyclicUnitDilate F u) x‖ ^ 2 := by
rw [← Finset.mul_sum, show (2 : ℝ) ^ (4 : ℕ) = 16 by norm_num]
_ ≤ 16 * ((2 : ℝ) ^ (-a * (J : ℝ)) * (T.card : ℝ) * H) :=
mul_le_mul_of_nonneg_left hFbound (by norm_num)
_ = _ := by ring
have hlener : (∑ x : ZMod (2 ^ J), ‖l x‖ ^ 2) ≤ 2 * v := by
apply finite_real_restriction_energy_of_peak p _ hp (by positivity) hmass
intro x hx
have hh : x ∉ G ∧ x ∉ S := by simpa only [Finset.mem_compl, Finset.mem_union, not_or] using hx
exact hlow x hh.1 hh.2
have hzsq : z ^ 2 = (2 : ℝ) ^ (-η * (J : ℝ)) := by
dsimp only [z]
rw [← Real.rpow_mul_natCast (by norm_num)]
congr 1
norm_num
ring
have hvrel : v ≤ (2 : ℝ) ^ (-(δ / 2) * (J : ℝ)) * H := by
calc
_ = (2 : ℝ) ^ (-(δ / 2) * (J : ℝ)) * (2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) := by
dsimp only [v]
rw [← Real.rpow_add (by norm_num)]
congr 1
ring
_ ≤ _ := mul_le_mul_of_nonneg_left hnorm (by positivity)
have herr : (∑ u ∈ T, ∑ x : ZMod (2 ^ J), ‖cyclicConvolution f (cyclicUnitDilate f u) x‖ ^ 2) ≤
(80 * (2 : ℝ) ^ (-a * (J : ℝ)) + 20 * (2 : ℝ) ^ (-(δ / 2) * (J : ℝ)) +
10 * (2 : ℝ) ^ (-η * (J : ℝ))) * (T.card : ℝ) * H := by
have hu : ∀ u ∈ T, (∑ x : ZMod (2 ^ J), ‖cyclicConvolution f (cyclicUnitDilate f u) x‖ ^ 2) ≤
5 * (∑ x : ZMod (2 ^ J), ‖cyclicConvolution g (cyclicUnitDilate g u) x‖ ^ 2) +
20 * v + 10 * (2 : ℝ) ^ (-η * (J : ℝ)) * H := by
intro u hu
have hh := cyclic_unit_convolution_error_bound f g l s u
(finite_real_restriction_three_parts p hGS) hfmass
((finite_real_restriction_mass_le p G hp).trans hmass)
(by simpa only [hfenergy] using finite_real_restriction_energy_le p G hp)
hlener hsmass hz
simpa only [hfenergy, hzsq, show (10 : ℝ) * (2 * v) = 20 * v by ring] using hh
calc
_ ≤ ∑ u ∈ T, (5 * (∑ x : ZMod (2 ^ J), ‖cyclicConvolution g (cyclicUnitDilate g u) x‖ ^ 2) +
20 * v + 10 * (2 : ℝ) ^ (-η * (J : ℝ)) * H) := Finset.sum_le_sum hu
_ = 5 * (∑ u ∈ T, ∑ x : ZMod (2 ^ J), ‖cyclicConvolution g (cyclicUnitDilate g u) x‖ ^ 2) +
(T.card : ℝ) * (20 * v + 10 * (2 : ℝ) ^ (-η * (J : ℝ)) * H) := by
rw [Finset.sum_add_distrib, Finset.sum_add_distrib, ← Finset.mul_sum]
simp only [Finset.sum_const, nsmul_eq_mul]
ring
_ ≤ 5 * (16 * (2 : ℝ) ^ (-a * (J : ℝ)) * (T.card : ℝ) * H) +
(T.card : ℝ) * (20 * ((2 : ℝ) ^ (-(δ / 2) * (J : ℝ)) * H) +
10 * (2 : ℝ) ^ (-η * (J : ℝ)) * H) := by
apply add_le_add (mul_le_mul_of_nonneg_left hgavg (by norm_num : (0 : ℝ) ≤ 5))
apply mul_le_mul_of_nonneg_left _ (Nat.cast_nonneg T.card : (0 : ℝ) ≤ T.card)
exact add_le_add (mul_le_mul_of_nonneg_left hvrel (by norm_num : (0 : ℝ) ≤ 20)) le_rfl
_ = _ := by ring
have h110 : (110 : ℝ) ≤ (2 : ℝ) ^ ((b / 2) * (J : ℝ)) := by
have hh := hJ₄ J hj₄
norm_num at hh
exact (by norm_num : (110 : ℝ) ≤ 128).trans hh
have hcoef : 80 * (2 : ℝ) ^ (-a * (J : ℝ)) + 20 * (2 : ℝ) ^ (-(δ / 2) * (J : ℝ)) +
10 * (2 : ℝ) ^ (-η * (J : ℝ)) ≤ (2 : ℝ) ^ (-(b / 2) * (J : ℝ)) := by
have hpow : ∀ c : ℝ, b ≤ c → (2 : ℝ) ^ (-c * (J : ℝ)) ≤ (2 : ℝ) ^ (-b * (J : ℝ)) := by
intro c hc
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_right hc hJ0
linarith only [hh]
calc
_ ≤ 110 * (2 : ℝ) ^ (-b * (J : ℝ)) := by
linarith only [hpow a hba, hpow (δ / 2) hbδ, hpow η hbη]
_ ≤ (2 : ℝ) ^ ((b / 2) * (J : ℝ)) * (2 : ℝ) ^ (-b * (J : ℝ)) :=
mul_le_mul_of_nonneg_right h110 (by positivity)
_ = _ := by rw [← Real.rpow_add (by norm_num)]; congr 1; ring
exact herr.trans (mul_le_mul_of_nonneg_right
(mul_le_mul_of_nonneg_right hcoef (Nat.cast_nonneg _)) hH)
theorem finite_dyadic_approx_weighted_sum {X : Type*} [Fintype X]
(p : X → ℝ) (I : Finset ℕ) (b : X → ℝ) :
(∑ x : X, finiteDyadicApprox p I x * b x) =
∑ n ∈ I, dyadicLevelWeight n * ∑ x ∈ finiteDyadicLevel p n, b x := by
classical
simp only [finiteDyadicApprox, Finset.sum_mul]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro n hn
rw [Finset.mul_sum]
simp only [ite_mul, zero_mul, ← Finset.sum_filter]
simp
/-- Lift bounds on retained dyadic levels to an average under a nonnegative
law. The two discarded parts are controlled by mass and pointwise size. -/
theorem finite_dyadic_weighted_average {X : Type*} [Fintype X] [DecidableEq X]
(p b : X → ℝ) (I : Finset ℕ) (G S : Finset X) {C D v H : ℝ}
(hp : ∀ x, 0 ≤ p x) (hmass : (∑ x : X, p x) ≤ 1)
(hb : ∀ x, 0 ≤ b x) (hbH : ∀ x, b x ≤ H) (hH : 0 ≤ H)
(hC : 0 ≤ C) (hv : 0 ≤ v) (hG : G = I.biUnion (finiteDyadicLevel p))
(hGS : Disjoint G S) (hS : (∑ x ∈ S, p x) ≤ D)
(hlow : ∀ x, x ∉ G → x ∉ S → p x ≤ v)
(hlevels : ∀ n ∈ I, (∑ x ∈ finiteDyadicLevel p n, b x) ≤
C * ((finiteDyadicLevel p n).card : ℝ)) :
(∑ x : X, p x * b x) ≤ 2 * C + (D + v * Fintype.card X) * H := by
classical
have happrox : (∑ x : X, finiteDyadicApprox p I x * b x) ≤ C := by
rw [finite_dyadic_approx_weighted_sum]
calc
_ ≤ ∑ n ∈ I, dyadicLevelWeight n *
(C * ((finiteDyadicLevel p n).card : ℝ)) :=
Finset.sum_le_sum (fun n hn => mul_le_mul_of_nonneg_left (hlevels n hn)
(dyadic_level_weight_pos n).le)
_ = C * ∑ n ∈ I, dyadicLevelWeight n * ((finiteDyadicLevel p n).card : ℝ) := by
rw [Finset.mul_sum]
apply Finset.sum_congr rfl
intro n hn
ring
_ ≤ C * 1 := by
apply mul_le_mul_of_nonneg_left _ hC
rw [← finite_dyadic_approx_sum]
exact (Finset.sum_le_sum (fun x _ => finite_dyadic_approx_le p I hp x)).trans hmass
_ = C := mul_one _
have hgood : (∑ x ∈ G, p x * b x) ≤ 2 * C := by
calc
_ ≤ ∑ x ∈ G, 2 * (finiteDyadicApprox p I x * b x) := by
apply Finset.sum_le_sum
intro x hx
have hh := mul_le_mul_of_nonneg_right
(finite_dyadic_approx_dominates p I (by rwa [← hG])) (hb x)
simpa only [mul_assoc] using hh
_ = 2 * ∑ x ∈ G, finiteDyadicApprox p I x * b x := (Finset.mul_sum _ _ _).symm
_ ≤ 2 * ∑ x : X, finiteDyadicApprox p I x * b x := by
apply mul_le_mul_of_nonneg_left _ (by norm_num : (0 : ℝ) ≤ 2)
exact Finset.sum_le_sum_of_subset_of_nonneg (Finset.subset_univ _)
(fun x _ _ => mul_nonneg (finite_dyadic_approx_nonneg p I x) (hb x))
_ ≤ 2 * C := mul_le_mul_of_nonneg_left happrox (by norm_num)
have hsmall : (∑ x ∈ S, p x * b x) ≤ D * H := by
calc
_ ≤ ∑ x ∈ S, p x * H := Finset.sum_le_sum (fun x _ =>
mul_le_mul_of_nonneg_left (hbH x) (hp x))
_ = (∑ x ∈ S, p x) * H := (Finset.sum_mul _ _ _).symm
_ ≤ D * H := mul_le_mul_of_nonneg_right hS hH
have htail : (∑ x ∈ (G ∪ S)ᶜ, p x * b x) ≤ v * Fintype.card X * H := by
calc
_ ≤ ∑ _x ∈ (G ∪ S)ᶜ, v * H := by
apply Finset.sum_le_sum
intro x hx
have hnot : x ∉ G ∧ x ∉ S := by
simpa only [Finset.mem_compl, Finset.mem_union, not_or] using hx
exact mul_le_mul (hlow x hnot.1 hnot.2) (hbH x) (hb x) hv
_ = (((G ∪ S)ᶜ).card : ℝ) * (v * H) := by simp
_ ≤ (Fintype.card X : ℝ) * (v * H) := by
apply mul_le_mul_of_nonneg_right _ (mul_nonneg hv hH)
exact_mod_cast Finset.card_le_univ ((G ∪ S)ᶜ)
_ = _ := by ring
have hpartition : (∑ x : X, p x * b x) =
(∑ x ∈ G, p x * b x) + (∑ x ∈ S, p x * b x) +
∑ x ∈ (G ∪ S)ᶜ, p x * b x := by
rw [← Finset.sum_union hGS, Finset.sum_add_sum_compl]
rw [hpartition]
calc
_ ≤ 2 * C + D * H + v * Fintype.card X * H := add_le_add (add_le_add hgood hsmall) htail
_ = _ := by ring
theorem unit_image_fiber_card {R Q : Type*} [Monoid R] [DecidableEq R]
(T : Finset Rˣ) (π : R → Q) (r : Q) [DecidableEq Q] :
((T.image (fun u : Rˣ => (u : R))).filter (fun a => π a = r)).card =
(T.filter (fun u : Rˣ => π (u : R) = r)).card := by
classical
rw [Finset.filter_image, Finset.card_image_of_injective _ Units.val_injective]
def DyadicUnitProbabilityNonconcentration {J : ℕ} (γ ε : ℝ)
(w : (ZMod (2 ^ J))ˣ → ℝ) : Prop :=
∀ L : ℕ, L ≤ J → ε * (J : ℝ) < (L : ℝ) → ∀ r : ZMod (2 ^ L),
(∑ u ∈ Finset.univ.filter
(fun u : (ZMod (2 ^ J))ˣ => (((u : ZMod (2 ^ J)).val : ZMod (2 ^ L))) = r), w u) ≤
(2 : ℝ) ^ (-γ * (L : ℝ))
theorem cyclic_probability_unit_energy_bound {q : ℕ} [NeZero q]
(p : ZMod q → ℝ) (hp : ∀ x, 0 ≤ p x) (hmass : (∑ x : ZMod q, p x) ≤ 1)
(u : (ZMod q)ˣ) :
(∑ x : ZMod q, ‖cyclicConvolution (fun y => (p y : ℂ))
(cyclicUnitDilate (fun y => (p y : ℂ)) u) x‖ ^ 2) ≤ ∑ x : ZMod q, p x ^ 2 := by
have hfnorm : ∀ x : ZMod q, ‖(p x : ℂ)‖ = p x := fun x => Complex.norm_of_nonneg (hp x)
have hh := cyclic_convolution_young_sq (fun y => (p y : ℂ))
(cyclicUnitDilate (fun y => (p y : ℂ)) u)
rw [cyclic_unit_dilate_sq_norm] at hh
simp only [hfnorm] at hh
have hsq : (∑ x : ZMod q, p x) ^ 2 ≤ 1 := by
simpa only [one_pow] using pow_le_pow_left₀ (Finset.sum_nonneg (fun x _ => hp x)) hmass 2
exact hh.trans (by simpa only [one_mul] using
mul_le_mul_of_nonneg_right hsq (Finset.sum_nonneg (fun _ _ => sq_nonneg _)))
/-- Additive flattening with both a nonuniform input law and a nonuniform
law on unit multipliers. All parameters are independent of the two laws. -/
theorem exists_dyadic_weighted_probability_flattening {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ p : ZMod (2 ^ J) → ℝ,
∀ w : (ZMod (2 ^ J))ˣ → ℝ,
(∀ x, 0 ≤ p x) → (∑ x : ZMod (2 ^ J), p x) ≤ 1 →
(2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) ≤ (∑ x : ZMod (2 ^ J), p x ^ 2) →
DyadicProbabilityNonconcentration γ ε p →
(∀ u, 0 ≤ w u) → (∑ u : (ZMod (2 ^ J))ˣ, w u) ≤ 1 →
DyadicUnitProbabilityNonconcentration γ ε w →
(∑ u : (ZMod (2 ^ J))ˣ, w u * ∑ x : ZMod (2 ^ J),
‖cyclicConvolution (fun y => (p y : ℂ))
(cyclicUnitDilate (fun y => (p y : ℂ)) u) x‖ ^ 2) ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * ∑ x : ZMod (2 ^ J), p x ^ 2 := by
classical
obtain ⟨a, ε, ha, hε, hε4, J₀, hflat⟩ := exists_dyadic_probability_flattening
(show 0 < γ / 2 by positivity) hδ hδ1
let η := γ * ε / 8
have hη : 0 < η := by dsimp only [η]; positivity
let b := min a (min (η / 2) 1)
have hb : 0 < b := lt_min ha (lt_min (by positivity) (by norm_num))
have hba : b ≤ a := min_le_left _ _
have hbη : b ≤ η / 2 := (min_le_right _ _).trans (min_le_left _ _)
have hb1 : b ≤ 1 := (min_le_right _ _).trans (min_le_right _ _)
obtain ⟨J₁, hJ₁⟩ := exists_dyadic_linear_count_bound (show 0 < η / 2 by positivity)
obtain ⟨J₂, hJ₂⟩ := exists_dyadic_fixed_power_absorption 1 0
(τ := 0) (ξ := η) (by simpa using hη)
obtain ⟨J₃, hJ₃⟩ := exists_dyadic_fixed_power_absorption 3 0
(τ := 0) (ξ := b / 2) (by simpa using (show 0 < b / 2 by positivity))
refine ⟨b / 2, ε, by positivity, hε, hε4, max J₀ (max J₁ (max J₂ J₃)), ?_⟩
intro J hJ p w hp hmass hnorm hspread hw hwmass hwspread
have hj₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hj₁ : J₁ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans hJ)
have hj₂ : J₂ ≤ J := (le_max_left _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans hJ))
have hj₃ : J₃ ≤ J := (le_max_right _ _).trans ((le_max_right _ _).trans ((le_max_right _ _).trans hJ))
have hJ0 : (0 : ℝ) ≤ J := Nat.cast_nonneg _
have hw1 : ∀ u, w u ≤ 1 := fun u =>
(Finset.single_le_sum (fun v _ => hw v) (Finset.mem_univ u)).trans hwmass
let v := (2 : ℝ) ^ (-2 * (J : ℝ))
let m := (2 : ℝ) ^ (-η * (J : ℝ))
let H := ∑ x : ZMod (2 ^ J), p x ^ 2
let E := fun u : (ZMod (2 ^ J))ˣ => ∑ x : ZMod (2 ^ J),
‖cyclicConvolution (fun y => (p y : ℂ)) (cyclicUnitDilate (fun y => (p y : ℂ)) u) x‖ ^ 2
have hv : 0 < v := by positivity
have hm : 0 < m := by positivity
have hH : 0 ≤ H := Finset.sum_nonneg (fun _ _ => sq_nonneg _)
have hNv : dyadicLevelWeight (2 * J) ≤ v := by
rw [dyadic_level_weight_rpow]
dsimp only [v]
norm_num
obtain ⟨I, G, S, hI, hG, hGS, hlevels, hS, hlow⟩ :=
exists_finite_dyadic_level_decomposition w (2 * J) hw hw1 hm hNv
have h2η : (2 : ℝ) ≤ (2 : ℝ) ^ (η * (J : ℝ)) := by simpa using hJ₂ J hj₂
have hloss : ∀ L : ℕ, ε * (J : ℝ) < (L : ℝ) →
2 * (2 : ℝ) ^ (-γ * (L : ℝ)) / m ≤ (2 : ℝ) ^ (-(γ / 2) * (L : ℝ)) := by
intro L hL
apply (div_le_iff₀ hm).mpr
calc
_ ≤ (2 : ℝ) ^ (η * (J : ℝ)) * (2 : ℝ) ^ (-γ * (L : ℝ)) := by gcongr
_ = (2 : ℝ) ^ (η * (J : ℝ) - γ * (L : ℝ)) := by
rw [← Real.rpow_add (by norm_num)]; congr 1; ring
_ ≤ (2 : ℝ) ^ (-(γ / 2) * (L : ℝ) - η * (J : ℝ)) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
dsimp only [η]
nlinarith only [mul_lt_mul_of_pos_left hL hγ,
mul_nonneg hγ.le (Nat.cast_nonneg L : (0 : ℝ) ≤ L)]
_ = _ := by
dsimp only [m]
rw [← Real.rpow_add (by norm_num)]
congr 1
ring
have hlevelspread : ∀ n ∈ I,
DyadicUnitSetNonconcentration (γ / 2) ε (finiteDyadicLevel w n) := by
intro n hn L hL hεL r
rw [unit_image_fiber_card]
have hh := finite_dyadic_level_fiber_bound w
(fun u : (ZMod (2 ^ J))ˣ => (((u : ZMod (2 ^ J)).val : ZMod (2 ^ L)))) n
hw hm (hlevels n hn).2.2 (hwspread L hL hεL) r
exact hh.trans (mul_le_mul_of_nonneg_right (hloss L hεL) (Nat.cast_nonneg _))
have hspread' : DyadicProbabilityNonconcentration (γ / 2) ε p := by
intro L hL hεL r
apply (hspread L hL hεL r).trans
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith only [mul_nonneg hγ.le (Nat.cast_nonneg L : (0 : ℝ) ≤ L)]
have hsmall : (∑ u ∈ S, w u) ≤ (2 : ℝ) ^ (-(η / 2) * (J : ℝ)) := by
calc
_ ≤ ((2 * J + 1 : ℕ) : ℝ) * m := hS
_ ≤ (2 : ℝ) ^ ((η / 2) * (J : ℝ)) * (2 : ℝ) ^ (-η * (J : ℝ)) :=
mul_le_mul_of_nonneg_right (hJ₁ J hj₁) hm.le
_ = _ := by rw [← Real.rpow_add (by norm_num)]; congr 1; ring
have htail : 2 * v * (Fintype.card (ZMod (2 ^ J))ˣ : ℝ) ≤
2 * (2 : ℝ) ^ (-(J : ℝ)) := by
have hcard : Fintype.card (ZMod (2 ^ J))ˣ ≤ 2 ^ J := by
calc
_ ≤ Fintype.card (ZMod (2 ^ J)) :=
Fintype.card_le_of_injective (fun u : (ZMod (2 ^ J))ˣ => (u : ZMod (2 ^ J))) Units.val_injective
_ = _ := ZMod.card _
calc
_ ≤ 2 * v * ((2 ^ J : ℕ) : ℝ) :=
mul_le_mul_of_nonneg_left (by exact_mod_cast hcard) (by positivity)
_ = _ := by
dsimp only [v]
push_cast
rw [← Real.rpow_natCast, mul_assoc, ← Real.rpow_add (by norm_num)]
congr 2
ring
have hmain : (∑ u : (ZMod (2 ^ J))ˣ, w u * E u) ≤
(2 * (2 : ℝ) ^ (-a * (J : ℝ)) + (2 : ℝ) ^ (-(η / 2) * (J : ℝ)) +
2 * (2 : ℝ) ^ (-(J : ℝ))) * H := by
have hh := finite_dyadic_weighted_average w E I G S hw hwmass
(fun _ => Finset.sum_nonneg (fun _ _ => sq_nonneg _))
(cyclic_probability_unit_energy_bound p hp hmass) hH
(show 0 ≤ (2 : ℝ) ^ (-a * (J : ℝ)) * H by positivity)
(show 0 ≤ 2 * v by positivity) hG hGS hsmall hlow (by
intro n hn
have hflatn := hflat J hj₀ p (finiteDyadicLevel w n) hp hmass hnorm hspread'
(hlevels n hn).1 (hlevelspread n hn)
simpa only [E, H, mul_assoc, mul_left_comm, mul_comm] using hflatn)
calc
_ ≤ 2 * ((2 : ℝ) ^ (-a * (J : ℝ)) * H) +
((2 : ℝ) ^ (-(η / 2) * (J : ℝ)) + 2 * v * Fintype.card (ZMod (2 ^ J))ˣ) * H := hh
_ ≤ 2 * ((2 : ℝ) ^ (-a * (J : ℝ)) * H) +
((2 : ℝ) ^ (-(η / 2) * (J : ℝ)) + 2 * (2 : ℝ) ^ (-(J : ℝ))) * H := by
exact add_le_add le_rfl (mul_le_mul_of_nonneg_right (add_le_add le_rfl htail) hH)
_ = _ := by ring
have h5 : (5 : ℝ) ≤ (2 : ℝ) ^ ((b / 2) * (J : ℝ)) := by
have hh := hJ₃ J hj₃
norm_num at hh
exact (by norm_num : (5 : ℝ) ≤ 8).trans hh
have hcoef : 2 * (2 : ℝ) ^ (-a * (J : ℝ)) + (2 : ℝ) ^ (-(η / 2) * (J : ℝ)) +
2 * (2 : ℝ) ^ (-(J : ℝ)) ≤ (2 : ℝ) ^ (-(b / 2) * (J : ℝ)) := by
have hpow : ∀ c : ℝ, b ≤ c → (2 : ℝ) ^ (-c * (J : ℝ)) ≤ (2 : ℝ) ^ (-b * (J : ℝ)) := by
intro c hc
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hh := mul_le_mul_of_nonneg_right hc hJ0
linarith only [hh]
have hpow1 : (2 : ℝ) ^ (-(J : ℝ)) ≤ (2 : ℝ) ^ (-b * (J : ℝ)) := by
simpa using hpow 1 hb1
calc
_ ≤ 5 * (2 : ℝ) ^ (-b * (J : ℝ)) := by
linarith only [hpow a hba, hpow (η / 2) hbη, hpow1]
_ ≤ (2 : ℝ) ^ ((b / 2) * (J : ℝ)) * (2 : ℝ) ^ (-b * (J : ℝ)) :=
mul_le_mul_of_nonneg_right h5 (by positivity)
_ = _ := by rw [← Real.rpow_add (by norm_num)]; congr 1; ring
exact hmain.trans (mul_le_mul_of_nonneg_right hcoef hH)
theorem finite_pushforward_equivariant {X Y : Type*} [Fintype X] [DecidableEq Y]
(p : X → ℝ) (π : X → Y) (e : X ≃ X) (σ : Y ≃ Y)
(hπ : ∀ x, π (e x) = σ (π x)) (r : Y) :
finitePushforward (fun x => p (e x)) π r = finitePushforward p π (σ r) := by
classical
unfold finitePushforward
simp only [Finset.sum_filter]
apply Fintype.sum_equiv e
intro x
rw [hπ]
simp only [Equiv.apply_eq_iff_eq]
theorem finite_pushforward_unit_dilate {R Q : Type*} [Ring R] [Ring Q]
[Fintype R] [DecidableEq Q] (p : R → ℝ) (π : R →+* Q) (u : Rˣ) (r : Q) :
finitePushforward (fun x => p ((u : R) * x)) π r =
finitePushforward p π (π (u : R) * r) := by
let v : Qˣ := Units.map π.toMonoidHom u
exact finite_pushforward_equivariant p π (ringUnitMulAddEquiv u).toEquiv
(ringUnitMulAddEquiv v).toEquiv (fun x => by simp [ringUnitMulAddEquiv, v]) r
theorem finite_pushforward_unit_translate {R Q : Type*} [Ring R] [Ring Q]
[Fintype Rˣ] [DecidableEq Q] (w : Rˣ → ℝ) (π : R →+* Q) (u : Rˣ) (r : Q) :
finitePushforward (fun v : Rˣ => w (u * v)) (fun v : Rˣ => π (v : R)) r =
finitePushforward w (fun v : Rˣ => π (v : R)) (π (u : R) * r) := by
let v : Qˣ := Units.map π.toMonoidHom u
exact finite_pushforward_equivariant w (fun z : Rˣ => π (z : R)) (Equiv.mulLeft u)
(ringUnitMulAddEquiv v).toEquiv (fun x => by simp [ringUnitMulAddEquiv, v]) r
theorem dyadic_probability_nonconcentration_unit_dilate {J : ℕ} {γ ε : ℝ}
{p : ZMod (2 ^ J) → ℝ} (hp : DyadicProbabilityNonconcentration γ ε p)
(u : (ZMod (2 ^ J))ˣ) :
DyadicProbabilityNonconcentration γ ε (fun x => p ((u : ZMod (2 ^ J)) * x)) := by
intro L hL hεL r
let π : ZMod (2 ^ J) →+* ZMod (2 ^ L) := ZMod.castHom (pow_dvd_pow 2 hL) _
have hπ : ∀ x : ZMod (2 ^ J), π x = (x.val : ZMod (2 ^ L)) := by
intro x
exact ZMod.cast_eq_val _
change finitePushforward _ (fun x : ZMod (2 ^ J) => (x.val : ZMod (2 ^ L))) r ≤ _
simp only [← hπ]
rw [finite_pushforward_unit_dilate]
simpa only [finitePushforward, hπ] using hp L hL hεL (π (u : ZMod (2 ^ J)) * r)
theorem dyadic_unit_probability_nonconcentration_translate {J : ℕ} {γ ε : ℝ}
{w : (ZMod (2 ^ J))ˣ → ℝ} (hw : DyadicUnitProbabilityNonconcentration γ ε w)
(u : (ZMod (2 ^ J))ˣ) :
DyadicUnitProbabilityNonconcentration γ ε (fun v => w (u * v)) := by
intro L hL hεL r
let π : ZMod (2 ^ J) →+* ZMod (2 ^ L) := ZMod.castHom (pow_dvd_pow 2 hL) _
have hπ : ∀ x : ZMod (2 ^ J), π x = (x.val : ZMod (2 ^ L)) := by
intro x
exact ZMod.cast_eq_val _
change finitePushforward _ (fun v : (ZMod (2 ^ J))ˣ => ((v : ZMod (2 ^ J)).val : ZMod (2 ^ L))) r ≤ _
simp only [← hπ]
rw [finite_pushforward_unit_translate]
simpa only [finitePushforward, hπ] using hw L hL hεL (π (u : ZMod (2 ^ J)) * r)
theorem finite_pushforward_linear_combination {X Y I : Type*} [Fintype X] [Fintype I]
[DecidableEq Y] (w : I → ℝ) (F : I → X → ℝ) (π : X → Y) (r : Y) :
finitePushforward (fun x => ∑ i : I, w i * F i x) π r =
∑ i : I, w i * finitePushforward (F i) π r := by
unfold finitePushforward
rw [Finset.sum_comm]
simp only [Finset.mul_sum]
theorem cyclic_mixture_norm_of_nonnegative {I : Type*} [Fintype I] {q : ℕ} [NeZero q]
(w : I → ℝ) (F : I → ZMod q → ℂ) (hw : ∀ i, 0 ≤ w i)
(hF : ∀ i x, F i x = (‖F i x‖ : ℂ)) (x : ZMod q) :
‖cyclicMixture w F x‖ = ∑ i : I, w i * ‖F i x‖ := by
have heq : cyclicMixture w F x = ((∑ i : I, w i * ‖F i x‖ : ℝ) : ℂ) := by
unfold cyclicMixture
rw [Complex.ofReal_sum]
apply Finset.sum_congr rfl
intro i hi
rw [Complex.ofReal_mul]
exact congrArg (fun z : ℂ => (w i : ℂ) * z) (hF i x)
rw [heq]
exact Complex.norm_of_nonneg (Finset.sum_nonneg (fun i _ => mul_nonneg (hw i) (norm_nonneg _)))
theorem dyadic_probability_nonconcentration_mixture {I : Type*} [Fintype I]
{J : ℕ} {γ ε : ℝ} (w : I → ℝ) (F : I → ZMod (2 ^ J) → ℂ)
(hw : ∀ i, 0 ≤ w i) (hmass : ∑ i : I, w i = 1)
(hF : ∀ i x, F i x = (‖F i x‖ : ℂ))
(hspread : ∀ i, DyadicProbabilityNonconcentration γ ε (fun x => ‖F i x‖)) :
DyadicProbabilityNonconcentration γ ε (fun x => ‖cyclicMixture w F x‖) := by
intro L hL hεL r
simp only [cyclic_mixture_norm_of_nonnegative w F hw hF]
change finitePushforward _ (fun x : ZMod (2 ^ J) => (x.val : ZMod (2 ^ L))) r ≤ _
rw [finite_pushforward_linear_combination]
calc
_ ≤ ∑ i : I, w i * (2 : ℝ) ^ (-γ * (L : ℝ)) :=
Finset.sum_le_sum (fun i _ => mul_le_mul_of_nonneg_left (hspread i L hL hεL r) (hw i))
_ = _ := by rw [← Finset.sum_mul, hmass, one_mul]
theorem cyclic_convolution_norm_le_peak {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) {M : ℝ} (hpeak : ∀ x, ‖f x‖ ≤ M) (x : ZMod q) :
‖cyclicConvolution f g x‖ ≤ M * ∑ y : ZMod q, ‖g y‖ := by
rw [cyclic_convolution_comm]
calc
_ ≤ ∑ y : ZMod q, ‖g y * f (x - y)‖ := norm_sum_le _ _
_ ≤ ∑ y : ZMod q, M * ‖g y‖ := by
apply Finset.sum_le_sum
intro y hy
rw [norm_mul, mul_comm]
exact mul_le_mul_of_nonneg_right (hpeak (x - y)) (norm_nonneg _)
_ = _ := (Finset.mul_sum _ _ _).symm
theorem cyclic_probability_convolution_fiber_bound {Q q : ℕ} [NeZero Q] [NeZero q]
{f g : ZMod Q → ℂ} (hf : FiniteComplexProbability f) (hg : FiniteComplexProbability g)
(π : ZMod Q →+ ZMod q) {M : ℝ}
(hpeak : ∀ r : ZMod q, finitePushforward (fun x => ‖f x‖) π r ≤ M) (r : ZMod q) :
finitePushforward (fun x => ‖cyclicConvolution f g x‖) π r ≤ M := by
rw [← norm_cyclicPushforward_of_probability (cyclicConvolution_probability hf hg),
cyclicPushforward_convolution]
have hpeak' : ∀ x, ‖cyclicPushforward f π x‖ ≤ M := by
intro x
rw [norm_cyclicPushforward_of_probability hf]
exact hpeak x
have hh := cyclic_convolution_norm_le_peak (cyclicPushforward f π) (cyclicPushforward g π) hpeak' r
simpa only [finite_complex_probability_sum_norm (cyclicPushforward_probability hg π), mul_one] using hh
theorem dyadic_probability_nonconcentration_convolution {J : ℕ} {γ ε : ℝ}
{f g : ZMod (2 ^ J) → ℂ} (hf : FiniteComplexProbability f) (hg : FiniteComplexProbability g)
(hspread : DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖)) :
DyadicProbabilityNonconcentration γ ε (fun x => ‖cyclicConvolution f g x‖) := by
intro L hL hεL r
let π : ZMod (2 ^ J) →+* ZMod (2 ^ L) := ZMod.castHom (pow_dvd_pow 2 hL) _
have hπ : ∀ x : ZMod (2 ^ J), π x = (x.val : ZMod (2 ^ L)) := by
intro x
exact ZMod.cast_eq_val _
have hπadd : ∀ x : ZMod (2 ^ J), π.toAddMonoidHom x = (x.val : ZMod (2 ^ L)) := hπ
have hh := cyclic_probability_convolution_fiber_bound hf hg π.toAddMonoidHom
(M := (2 : ℝ) ^ (-γ * (L : ℝ))) (by
intro r
simpa only [finitePushforward, hπadd] using hspread L hL hεL r) r
simpa only [finitePushforward, hπadd] using hh
theorem cyclic_unit_dilate_probability {q : ℕ} [NeZero q] {f : ZMod q → ℂ}
(hf : FiniteComplexProbability f) (u : (ZMod q)ˣ) :
FiniteComplexProbability (cyclicUnitDilate f u) := by
refine ⟨fun x => hf.norm_cast _, ?_⟩
calc
_ = ∑ x : ZMod q, f x := Fintype.sum_equiv (ringUnitMulAddEquiv u⁻¹).toEquiv _ _ (fun _ => rfl)
_ = 1 := hf.sum_eq_one
theorem dyadic_probability_nonconcentration_cyclic_unit_dilate {J : ℕ} {γ ε : ℝ}
{f : ZMod (2 ^ J) → ℂ}
(hf : DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖))
(u : (ZMod (2 ^ J))ˣ) :
DyadicProbabilityNonconcentration γ ε (fun x => ‖cyclicUnitDilate f u x‖) :=
dyadic_probability_nonconcentration_unit_dilate hf u⁻¹
theorem cyclic_mixture_energy_le {I : Type*} [Fintype I] {q : ℕ} [NeZero q]
(w : I → ℝ) (F : I → ZMod q → ℂ) (hw : ∀ i, 0 ≤ w i)
(hmass : ∑ i : I, w i = 1) :
(∑ x : ZMod q, ‖cyclicMixture w F x‖ ^ 2) ≤
∑ i : I, w i * ∑ x : ZMod q, ‖F i x‖ ^ 2 := by
have hx : ∀ x : ZMod q, ‖cyclicMixture w F x‖ ^ 2 ≤ ∑ i : I, w i * ‖F i x‖ ^ 2 := by
intro x
have hnorm : ‖cyclicMixture w F x‖ ≤ ∑ i : I, w i * ‖F i x‖ := by
calc
_ ≤ ∑ i : I, ‖(w i : ℂ) * F i x‖ := norm_sum_le _ _
_ = _ := by
apply Finset.sum_congr rfl
intro i hi
rw [norm_mul, Complex.norm_of_nonneg (hw i)]
exact (pow_le_pow_left₀ (norm_nonneg _) hnorm 2).trans
(weighted_sum_sq_le Finset.univ w (fun i => ‖F i x‖) (fun i _ => hw i) hmass)
calc
_ ≤ ∑ x : ZMod q, ∑ i : I, w i * ‖F i x‖ ^ 2 := Finset.sum_le_sum (fun x _ => hx x)
_ = _ := by rw [Finset.sum_comm]; simp only [Finset.mul_sum]
theorem cyclic_convolution_mixture_left {I : Type*} [Fintype I] {q : ℕ} [NeZero q]
(w : I → ℝ) (F : I → ZMod q → ℂ) (g : ZMod q → ℂ) :
cyclicConvolution (cyclicMixture w F) g = cyclicMixture w (fun i => cyclicConvolution (F i) g) := by
funext x
unfold cyclicConvolution cyclicMixture
simp only [Finset.sum_mul, Finset.mul_sum]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro i hi
apply Finset.sum_congr rfl
intro y hy
ring
theorem cyclic_convolution_mixture_right {I : Type*} [Fintype I] {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : I → ℝ) (G : I → ZMod q → ℂ) :
cyclicConvolution f (cyclicMixture w G) = cyclicMixture w (fun i => cyclicConvolution f (G i)) := by
rw [cyclic_convolution_comm, cyclic_convolution_mixture_left]
congr 1
funext i
exact cyclic_convolution_comm _ _
theorem cyclic_convolution_mixture_energy_le {I K : Type*} [Fintype I] [Fintype K]
{q : ℕ} [NeZero q] (w : I → ℝ) (v : K → ℝ)
(F : I → ZMod q → ℂ) (G : K → ZMod q → ℂ)
(hw : ∀ i, 0 ≤ w i) (hwmass : ∑ i : I, w i = 1)
(hv : ∀ k, 0 ≤ v k) (hvmass : ∑ k : K, v k = 1) :
(∑ x : ZMod q, ‖cyclicConvolution (cyclicMixture w F) (cyclicMixture v G) x‖ ^ 2) ≤
∑ i : I, w i * ∑ k : K, v k * ∑ x : ZMod q, ‖cyclicConvolution (F i) (G k) x‖ ^ 2 := by
rw [cyclic_convolution_mixture_left]
apply (cyclic_mixture_energy_le w _ hw hwmass).trans
apply Finset.sum_le_sum
intro i hi
apply mul_le_mul_of_nonneg_left _ (hw i)
rw [cyclic_convolution_mixture_right]
exact cyclic_mixture_energy_le v _ hv hvmass
theorem cyclic_unit_dilate_mul {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (u v : (ZMod q)ˣ) :
cyclicUnitDilate (cyclicUnitDilate f v) u = cyclicUnitDilate f (u * v) := by
funext x
simp only [cyclicUnitDilate, mul_inv_rev, Units.val_mul, mul_assoc]
theorem cyclic_unit_dilate_convolution {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (u : (ZMod q)ˣ) :
cyclicConvolution (cyclicUnitDilate f u) (cyclicUnitDilate g u) =
cyclicUnitDilate (cyclicConvolution f g) u := by
funext x
unfold cyclicConvolution cyclicUnitDilate
apply Fintype.sum_equiv (ringUnitMulAddEquiv u⁻¹).toEquiv
intro y
change f ((u⁻¹ : (ZMod q)ˣ) * y) * g ((u⁻¹ : (ZMod q)ˣ) * (x - y)) =
f ((u⁻¹ : (ZMod q)ˣ) * y) * g ((u⁻¹ : (ZMod q)ˣ) * x - (u⁻¹ : (ZMod q)ˣ) * y)
rw [mul_sub]
theorem cyclic_unit_pair_convolution_energy {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (u v : (ZMod q)ˣ) :
(∑ x : ZMod q, ‖cyclicConvolution (cyclicUnitDilate f u) (cyclicUnitDilate g v) x‖ ^ 2) =
∑ x : ZMod q, ‖cyclicConvolution f (cyclicUnitDilate g (u⁻¹ * v)) x‖ ^ 2 := by
have hrel : cyclicUnitDilate (cyclicUnitDilate g (u⁻¹ * v)) u = cyclicUnitDilate g v := by
rw [cyclic_unit_dilate_mul, mul_inv_cancel_left]
rw [← hrel, cyclic_unit_dilate_convolution, cyclic_unit_dilate_sq_norm]
/-- One probability step: average unit dilations, then add two independent
samples from that averaged law. -/
noncomputable def cyclicUnitAveragingStep {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ) : ZMod q → ℂ :=
cyclicConvolution (cyclicMixture w (cyclicUnitDilate f)) (cyclicMixture w (cyclicUnitDilate f))
theorem cyclic_unit_averaging_step_probability {q : ℕ} [NeZero q] {f : ZMod q → ℂ}
(hf : FiniteComplexProbability f) (w : (ZMod q)ˣ → ℝ)
(hw : ∀ u, 0 ≤ w u) (hmass : ∑ u : (ZMod q)ˣ, w u = 1) :
FiniteComplexProbability (cyclicUnitAveragingStep f w) := by
have hmix := cyclicMixture_probability w (cyclicUnitDilate f) hw hmass
(cyclic_unit_dilate_probability hf)
exact cyclicConvolution_probability hmix hmix
theorem dyadic_probability_nonconcentration_averaging_step {J : ℕ} {γ ε : ℝ}
{f : ZMod (2 ^ J) → ℂ} (hf : FiniteComplexProbability f)
(hspread : DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖))
(w : (ZMod (2 ^ J))ˣ → ℝ) (hw : ∀ u, 0 ≤ w u) (hmass : ∑ u : (ZMod (2 ^ J))ˣ, w u = 1) :
DyadicProbabilityNonconcentration γ ε (fun x => ‖cyclicUnitAveragingStep f w x‖) := by
have hmix := cyclicMixture_probability w (cyclicUnitDilate f) hw hmass
(cyclic_unit_dilate_probability hf)
exact dyadic_probability_nonconcentration_convolution hmix hmix
(dyadic_probability_nonconcentration_mixture w (cyclicUnitDilate f) hw hmass
(fun u => (cyclic_unit_dilate_probability hf u).norm_cast)
(dyadic_probability_nonconcentration_cyclic_unit_dilate hspread))
theorem cyclic_unit_averaging_step_energy_le {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ)
(hw : ∀ u, 0 ≤ w u) (hmass : ∑ u : (ZMod q)ˣ, w u = 1) :
(∑ x : ZMod q, ‖cyclicUnitAveragingStep f w x‖ ^ 2) ≤
∑ u : (ZMod q)ˣ, w u * ∑ v : (ZMod q)ˣ, w v *
∑ x : ZMod q, ‖cyclicConvolution f (cyclicUnitDilate f (u⁻¹ * v)) x‖ ^ 2 := by
have hh := cyclic_convolution_mixture_energy_le w w (cyclicUnitDilate f) (cyclicUnitDilate f)
hw hmass hw hmass
simpa only [cyclicUnitAveragingStep, cyclic_unit_pair_convolution_energy] using hh
theorem cyclic_unit_averaging_step_energy_mono {q : ℕ} [NeZero q]
{f : ZMod q → ℂ} (hf : FiniteComplexProbability f) (w : (ZMod q)ˣ → ℝ)
(hw : ∀ u, 0 ≤ w u) (hmass : ∑ u : (ZMod q)ˣ, w u = 1) :
(∑ x : ZMod q, ‖cyclicUnitAveragingStep f w x‖ ^ 2) ≤ ∑ x : ZMod q, ‖f x‖ ^ 2 := by
let θ := cyclicMixture w (cyclicUnitDilate f)
have hθ := cyclicMixture_probability w (cyclicUnitDilate f) hw hmass
(cyclic_unit_dilate_probability hf)
have hconv := cyclic_convolution_young_sq θ θ
rw [finite_complex_probability_sum_norm hθ, one_pow, one_mul] at hconv
have hmix := cyclic_mixture_energy_le w (cyclicUnitDilate f) hw hmass
simp only [cyclic_unit_dilate_sq_norm, ← Finset.sum_mul, hmass, one_mul] at hmix
exact hconv.trans hmix
theorem exists_dyadic_averaging_step_flattening {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ f : ZMod (2 ^ J) → ℂ,
∀ w : (ZMod (2 ^ J))ˣ → ℝ,
FiniteComplexProbability f →
(2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) ≤ (∑ x : ZMod (2 ^ J), ‖f x‖ ^ 2) →
DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖) →
(∀ u, 0 ≤ w u) → (∑ u : (ZMod (2 ^ J))ˣ, w u) = 1 →
DyadicUnitProbabilityNonconcentration γ ε w →
(∑ x : ZMod (2 ^ J), ‖cyclicUnitAveragingStep f w x‖ ^ 2) ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * ∑ x : ZMod (2 ^ J), ‖f x‖ ^ 2 := by
classical
obtain ⟨τ, ε, hτ, hε, hε4, J₀, hflat⟩ := exists_dyadic_weighted_probability_flattening hγ hδ hδ1
refine ⟨τ, ε, hτ, hε, hε4, J₀, ?_⟩
intro J hJ f w hf hnorm hspread hw hmass hwspread
have hfreal : (fun x : ZMod (2 ^ J) => (‖f x‖ : ℂ)) = f := funext (fun x => (hf.norm_cast x).symm)
have hu : ∀ u : (ZMod (2 ^ J))ˣ,
(∑ v : (ZMod (2 ^ J))ˣ, w v * ∑ x : ZMod (2 ^ J),
‖cyclicConvolution f (cyclicUnitDilate f (u⁻¹ * v)) x‖ ^ 2) ≤
(2 : ℝ) ^ (-τ * (J : ℝ)) * ∑ x : ZMod (2 ^ J), ‖f x‖ ^ 2 := by
intro u
have hmassu : (∑ v : (ZMod (2 ^ J))ˣ, w (u * v)) = 1 := by
calc
_ = ∑ v : (ZMod (2 ^ J))ˣ, w v := Fintype.sum_equiv (Equiv.mulLeft u) _ _ (fun _ => rfl)
_ = 1 := hmass
have hh := hflat J hJ (fun x => ‖f x‖) (fun v => w (u * v)) (fun x => norm_nonneg _)
(finite_complex_probability_sum_norm hf).le hnorm hspread (fun v => hw (u * v)) hmassu.le
(dyadic_unit_probability_nonconcentration_translate hwspread u)
rw [hfreal] at hh
have heq : (∑ v : (ZMod (2 ^ J))ˣ, w (u * v) * ∑ x : ZMod (2 ^ J),
‖cyclicConvolution f (cyclicUnitDilate f v) x‖ ^ 2) =
∑ v : (ZMod (2 ^ J))ˣ, w v * ∑ x : ZMod (2 ^ J),
‖cyclicConvolution f (cyclicUnitDilate f (u⁻¹ * v)) x‖ ^ 2 := by
apply Fintype.sum_equiv (Equiv.mulLeft u)
intro v
change w (u * v) * (∑ x : ZMod (2 ^ J), ‖cyclicConvolution f (cyclicUnitDilate f v) x‖ ^ 2) =
w (u * v) * ∑ x : ZMod (2 ^ J), ‖cyclicConvolution f (cyclicUnitDilate f (u⁻¹ * (u * v))) x‖ ^ 2
rw [inv_mul_cancel_left]
rwa [heq] at hh
calc
_ ≤ ∑ u : (ZMod (2 ^ J))ˣ, w u * ∑ v : (ZMod (2 ^ J))ˣ, w v *
∑ x : ZMod (2 ^ J), ‖cyclicConvolution f (cyclicUnitDilate f (u⁻¹ * v)) x‖ ^ 2 :=
cyclic_unit_averaging_step_energy_le f w hw hmass
_ ≤ ∑ u : (ZMod (2 ^ J))ˣ, w u *
((2 : ℝ) ^ (-τ * (J : ℝ)) * ∑ x : ZMod (2 ^ J), ‖f x‖ ^ 2) :=
Finset.sum_le_sum (fun u _ => mul_le_mul_of_nonneg_left (hu u) (hw u))
_ = _ := by rw [← Finset.sum_mul, hmass, one_mul]
theorem exists_dyadic_averaging_step_energy_bound {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ τ ε : ℝ, 0 < τ ∧ 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ f : ZMod (2 ^ J) → ℂ,
∀ w : (ZMod (2 ^ J))ˣ → ℝ,
FiniteComplexProbability f →
DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖) →
(∀ u, 0 ≤ w u) → (∑ u : (ZMod (2 ^ J))ˣ, w u) = 1 →
DyadicUnitProbabilityNonconcentration γ ε w →
(∑ x : ZMod (2 ^ J), ‖cyclicUnitAveragingStep f w x‖ ^ 2) ≤
max ((2 : ℝ) ^ (-(1 - δ) * (J : ℝ)))
((2 : ℝ) ^ (-τ * (J : ℝ)) * ∑ x : ZMod (2 ^ J), ‖f x‖ ^ 2) := by
obtain ⟨τ, ε, hτ, hε, hε4, J₀, hflat⟩ := exists_dyadic_averaging_step_flattening hγ hδ hδ1
refine ⟨τ, ε, hτ, hε, hε4, J₀, ?_⟩
intro J hJ f w hf hspread hw hmass hwspread
by_cases hnorm : (2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) ≤ ∑ x : ZMod (2 ^ J), ‖f x‖ ^ 2
· exact (hflat J hJ f w hf hnorm hspread hw hmass hwspread).trans (le_max_right _ _)
· exact (cyclic_unit_averaging_step_energy_mono hf w hw hmass).trans
((lt_of_not_ge hnorm).le.trans (le_max_left _ _))
theorem finite_complex_probability_sq_norm_le_one {X : Type*} [Fintype X]
{f : X → ℂ} (hf : FiniteComplexProbability f) : (∑ x : X, ‖f x‖ ^ 2) ≤ 1 := by
have hh := Finset.sum_sq_le_sq_sum_of_nonneg (s := (Finset.univ : Finset X))
(f := fun x => ‖f x‖) (fun _ _ => norm_nonneg _)
simpa only [finite_complex_probability_sum_norm hf, one_pow] using hh
theorem finite_contractive_iteration {R : ℕ} (E : ℕ → ℝ) {M c : ℝ}
(hM : 0 ≤ M) (hc : 0 ≤ c) (hc1 : c ≤ 1) (hbase : E 0 ≤ 1)
(hstep : ∀ n < R, E (n + 1) ≤ max M (c * E n)) :
∀ n ≤ R, E n ≤ max M (c ^ n) := by
intro n
induction n with
| zero =>
intro hn
exact hbase.trans (by simpa using le_max_right M (1 : ℝ))
| succ n ih =>
intro hn
apply (hstep n (by omega)).trans
apply max_le (le_max_left _ _)
calc
c * E n ≤ c * max M (c ^ n) := mul_le_mul_of_nonneg_left (ih (by omega)) hc
_ = max (c * M) (c ^ (n + 1)) := by rw [mul_max_of_nonneg _ _ hc, pow_succ']
_ ≤ max M (c ^ (n + 1)) := max_le_max
(by simpa only [one_mul] using mul_le_mul_of_nonneg_right hc1 hM) le_rfl
noncomputable def cyclicUnitAveragingIter {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : ℕ → (ZMod q)ˣ → ℝ) : ℕ → ZMod q → ℂ
| 0 => f
| n + 1 => cyclicUnitAveragingStep (cyclicUnitAveragingIter f w n) (w n)
theorem cyclic_unit_averaging_iter_probability {q R : ℕ} [NeZero q]
{f : ZMod q → ℂ} (hf : FiniteComplexProbability f) (w : ℕ → (ZMod q)ˣ → ℝ)
(hw : ∀ n < R, ∀ u, 0 ≤ w n u) (hmass : ∀ n < R, ∑ u : (ZMod q)ˣ, w n u = 1) :
∀ n ≤ R, FiniteComplexProbability (cyclicUnitAveragingIter f w n) := by
intro n
induction n with
| zero => intro hn; exact hf
| succ n ih =>
intro hn
exact cyclic_unit_averaging_step_probability (ih (by omega)) (w n) (hw n (by omega)) (hmass n (by omega))
theorem dyadic_probability_nonconcentration_averaging_iter {J R : ℕ} {γ ε : ℝ}
{f : ZMod (2 ^ J) → ℂ} (hf : FiniteComplexProbability f)
(hspread : DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖))
(w : ℕ → (ZMod (2 ^ J))ˣ → ℝ)
(hw : ∀ n < R, ∀ u, 0 ≤ w n u) (hmass : ∀ n < R, ∑ u : (ZMod (2 ^ J))ˣ, w n u = 1) :
∀ n ≤ R, DyadicProbabilityNonconcentration γ ε (fun x => ‖cyclicUnitAveragingIter f w n x‖) := by
intro n
induction n with
| zero => intro hn; exact hspread
| succ n ih =>
intro hn
exact dyadic_probability_nonconcentration_averaging_step
(cyclic_unit_averaging_iter_probability hf w hw hmass n (by omega)) (ih (by omega))
(w n) (hw n (by omega)) (hmass n (by omega))
/-- A fixed number of independent unit-averaging steps reaches the density
threshold. The number of steps and residue cutoff are uniform in the modulus. -/
theorem exists_dyadic_probability_flattening_iteration {γ δ : ℝ}
(hγ : 0 < γ) (hδ : 0 < δ) (hδ1 : δ ≤ 1) :
∃ ε : ℝ, 0 < ε ∧ ε ≤ 1 / 4 ∧ ∃ R : ℕ, 0 < R ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ f : ZMod (2 ^ J) → ℂ,
∀ w : ℕ → (ZMod (2 ^ J))ˣ → ℝ,
FiniteComplexProbability f →
DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖) →
(∀ n < R, ∀ u, 0 ≤ w n u) →
(∀ n < R, (∑ u : (ZMod (2 ^ J))ˣ, w n u) = 1) →
(∀ n < R, DyadicUnitProbabilityNonconcentration γ ε (w n)) →
(∑ x : ZMod (2 ^ J), ‖cyclicUnitAveragingIter f w R x‖ ^ 2) ≤
(2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) := by
obtain ⟨τ, ε, hτ, hε, hε4, J₀, hstep⟩ := exists_dyadic_averaging_step_energy_bound hγ hδ hδ1
obtain ⟨R, hR⟩ := exists_nat_gt (1 / τ)
have hRτ : 1 ≤ (R : ℝ) * τ := ((div_lt_iff₀ hτ).mp hR).le
have hR0 : 0 < R := by
by_contra hn
have heq : R = 0 := by omega
subst R
norm_num at hRτ
refine ⟨ε, hε, hε4, R, hR0, J₀, ?_⟩
intro J hJ f w hf hspread hw hmass hwspread
let M := (2 : ℝ) ^ (-(1 - δ) * (J : ℝ))
let c := (2 : ℝ) ^ (-τ * (J : ℝ))
let E := fun n : ℕ => ∑ x : ZMod (2 ^ J), ‖cyclicUnitAveragingIter f w n x‖ ^ 2
have hc : 0 ≤ c := by positivity
have hc1 : c ≤ 1 := by
calc
_ ≤ (2 : ℝ) ^ (0 : ℝ) := by
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
nlinarith only [mul_nonneg hτ.le (Nat.cast_nonneg J : (0 : ℝ) ≤ J)]
_ = 1 := Real.rpow_zero _
have hE : E R ≤ max M (c ^ R) := by
apply finite_contractive_iteration E (by positivity) hc hc1 (finite_complex_probability_sq_norm_le_one hf)
(fun n hn => hstep J hJ (cyclicUnitAveragingIter f w n) (w n)
(cyclic_unit_averaging_iter_probability hf w hw hmass n hn.le)
(dyadic_probability_nonconcentration_averaging_iter hf hspread w hw hmass n hn.le)
(hw n hn) (hmass n hn) (hwspread n hn)) R le_rfl
have hcR : c ^ R ≤ M := by
dsimp only [c, M]
rw [← Real.rpow_mul_natCast (by norm_num)]
apply Real.rpow_le_rpow_of_exponent_le (by norm_num)
have hJ0 : (0 : ℝ) ≤ J := Nat.cast_nonneg _
have hRτJ := mul_le_mul_of_nonneg_right hRτ hJ0
have hδJ := mul_nonneg hδ.le hJ0
nlinarith only [hRτJ, hδJ]
exact hE.trans (max_le le_rfl hcR)
theorem dft_cyclic_unit_dilate {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (u : (ZMod q)ˣ) (k : ZMod q) :
ZMod.dft (cyclicUnitDilate f u) k = ZMod.dft f ((u : ZMod q) * k) := by
simp only [ZMod.dft_apply, smul_eq_mul, cyclicUnitDilate]
apply Fintype.sum_equiv (ringUnitMulAddEquiv u⁻¹).toEquiv
intro x
change ZMod.stdAddChar (-(x * k)) * f (((u⁻¹ : (ZMod q)ˣ) : ZMod q) * x) =
ZMod.stdAddChar (-((((u⁻¹ : (ZMod q)ˣ) : ZMod q) * x) * ((u : ZMod q) * k))) *
f (((u⁻¹ : (ZMod q)ˣ) : ZMod q) * x)
have heq : (((u⁻¹ : (ZMod q)ˣ) : ZMod q) * x) * ((u : ZMod q) * k) = x * k := by
calc
_ = (((u⁻¹ : (ZMod q)ˣ) : ZMod q) * (u : ZMod q)) * (x * k) := by ring
_ = _ := by rw [Units.inv_mul, one_mul]
rw [heq]
theorem dft_cyclic_mixture {I : Type*} [Fintype I] {q : ℕ} [NeZero q]
(w : I → ℝ) (F : I → ZMod q → ℂ) (k : ZMod q) :
ZMod.dft (cyclicMixture w F) k = ∑ i : I, (w i : ℂ) * ZMod.dft (F i) k := by
simp only [ZMod.dft_apply, smul_eq_mul, cyclicMixture, Finset.mul_sum]
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro i hi
apply Finset.sum_congr rfl
intro x hx
ring
theorem norm_dft_cyclic_unit_mixture_le {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ) (hw : ∀ u, 0 ≤ w u) (k : ZMod q) :
‖ZMod.dft (cyclicMixture w (cyclicUnitDilate f)) k‖ ≤
∑ u : (ZMod q)ˣ, w u * ‖ZMod.dft f ((u : ZMod q) * k)‖ := by
rw [dft_cyclic_mixture]
calc
_ ≤ ∑ u : (ZMod q)ˣ, ‖(w u : ℂ) * ZMod.dft (cyclicUnitDilate f u) k‖ := norm_sum_le _ _
_ = _ := by
apply Finset.sum_congr rfl
intro u hu
rw [norm_mul, Complex.norm_of_nonneg (hw u), dft_cyclic_unit_dilate]
theorem weighted_sum_two_power_le {I : Type*} [Fintype I]
(w t : I → ℝ) (hw : ∀ i, 0 ≤ w i) (ht : ∀ i, 0 ≤ t i)
(hmass : ∑ i : I, w i = 1) (n : ℕ) :
(∑ i : I, w i * t i) ^ (2 ^ n) ≤ ∑ i : I, w i * t i ^ (2 ^ n) := by
induction n with
| zero => simp
| succ n ih =>
rw [pow_succ, pow_mul]
calc
_ ≤ (∑ i : I, w i * t i ^ (2 ^ n)) ^ 2 :=
pow_le_pow_left₀ (pow_nonneg (Finset.sum_nonneg (fun i _ => mul_nonneg (hw i) (ht i))) _) ih 2
_ ≤ ∑ i : I, w i * (t i ^ (2 ^ n)) ^ 2 :=
weighted_sum_sq_le Finset.univ w (fun i => t i ^ (2 ^ n)) (fun i _ => hw i) hmass
_ = _ := by simp only [pow_mul]
theorem norm_dft_unit_mixture_two_power_le {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ)
(hw : ∀ u, 0 ≤ w u) (hmass : ∑ u : (ZMod q)ˣ, w u = 1)
(n : ℕ) (k : ZMod q) :
‖ZMod.dft (cyclicMixture w (cyclicUnitDilate f)) k‖ ^ (2 ^ n) ≤
∑ u : (ZMod q)ˣ, w u * ‖ZMod.dft f ((u : ZMod q) * k)‖ ^ (2 ^ n) := by
exact (pow_le_pow_left₀ (norm_nonneg _) (norm_dft_cyclic_unit_mixture_le f w hw k) _).trans
(weighted_sum_two_power_le w (fun u => ‖ZMod.dft f ((u : ZMod q) * k)‖)
hw (fun _ => norm_nonneg _) hmass n)
theorem dft_neg_of_real {q : ℕ} [NeZero q] (f : ZMod q → ℂ)
(hf : ∀ x, f x = (‖f x‖ : ℂ)) (k : ZMod q) :
ZMod.dft f (-k) = starRingEnd ℂ (ZMod.dft f k) := by
have hconj : (fun x => starRingEnd ℂ (f x)) = f := by
funext x
rw [hf x]
exact Complex.conj_ofReal _
have hh := dft_conjugate f (-k)
rwa [hconj, neg_neg] at hh
noncomputable def cyclicSymmetrize {q : ℕ} [NeZero q] (f : ZMod q → ℂ) : ZMod q → ℂ :=
cyclicConvolution f (cyclicUnitDilate f (-1))
theorem dft_cyclic_symmetrize {q : ℕ} [NeZero q] (f : ZMod q → ℂ)
(hf : ∀ x, f x = (‖f x‖ : ℂ)) (k : ZMod q) :
ZMod.dft (cyclicSymmetrize f) k = (‖ZMod.dft f k‖ ^ 2 : ℝ) := by
rw [cyclicSymmetrize, dft_cyclicConvolution, dft_cyclic_unit_dilate]
simp only [Units.val_neg, Units.val_one, neg_one_mul]
rw [dft_neg_of_real f hf]
simpa only [Complex.ofReal_pow] using Complex.mul_conj' (ZMod.dft f k)
theorem cyclic_symmetrize_probability {q : ℕ} [NeZero q]
{f : ZMod q → ℂ} (hf : FiniteComplexProbability f) :
FiniteComplexProbability (cyclicSymmetrize f) :=
cyclicConvolution_probability hf (cyclic_unit_dilate_probability hf (-1))
theorem dyadic_probability_nonconcentration_symmetrize {J : ℕ} {γ ε : ℝ}
{f : ZMod (2 ^ J) → ℂ} (hf : FiniteComplexProbability f)
(hspread : DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖)) :
DyadicProbabilityNonconcentration γ ε (fun x => ‖cyclicSymmetrize f x‖) :=
dyadic_probability_nonconcentration_convolution hf (cyclic_unit_dilate_probability hf (-1)) hspread
theorem dft_cyclic_symmetrize_nonnegative {q : ℕ} [NeZero q] (f : ZMod q → ℂ)
(hf : ∀ x, f x = (‖f x‖ : ℂ)) (k : ZMod q) :
ZMod.dft (cyclicSymmetrize f) k = (‖ZMod.dft (cyclicSymmetrize f) k‖ : ℂ) := by
rw [dft_cyclic_symmetrize f hf, Complex.norm_of_nonneg (sq_nonneg _)]
theorem dft_unit_mixture_of_nonnegative_fourier {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ)
(hf : ∀ k, ZMod.dft f k = (‖ZMod.dft f k‖ : ℂ)) (k : ZMod q) :
ZMod.dft (cyclicMixture w (cyclicUnitDilate f)) k =
((∑ u : (ZMod q)ˣ, w u * ‖ZMod.dft f ((u : ZMod q) * k)‖ : ℝ) : ℂ) := by
rw [dft_cyclic_mixture, Complex.ofReal_sum]
apply Finset.sum_congr rfl
intro u hu
rw [dft_cyclic_unit_dilate, Complex.ofReal_mul]
exact congrArg (fun z : ℂ => (w u : ℂ) * z) (hf ((u : ZMod q) * k))
theorem norm_dft_unit_mixture_of_nonnegative_fourier {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ) (hw : ∀ u, 0 ≤ w u)
(hf : ∀ k, ZMod.dft f k = (‖ZMod.dft f k‖ : ℂ)) (k : ZMod q) :
‖ZMod.dft (cyclicMixture w (cyclicUnitDilate f)) k‖ =
∑ u : (ZMod q)ˣ, w u * ‖ZMod.dft f ((u : ZMod q) * k)‖ := by
rw [dft_unit_mixture_of_nonnegative_fourier f w hf]
exact Complex.norm_of_nonneg (Finset.sum_nonneg (fun u _ => mul_nonneg (hw u) (norm_nonneg _)))
theorem dft_unit_averaging_step_of_nonnegative_fourier {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ)
(hf : ∀ k, ZMod.dft f k = (‖ZMod.dft f k‖ : ℂ)) (k : ZMod q) :
ZMod.dft (cyclicUnitAveragingStep f w) k =
(((∑ u : (ZMod q)ˣ, w u * ‖ZMod.dft f ((u : ZMod q) * k)‖) ^ 2 : ℝ) : ℂ) := by
rw [cyclicUnitAveragingStep, dft_cyclicConvolution, dft_unit_mixture_of_nonnegative_fourier f w hf]
push_cast
ring
theorem norm_dft_unit_averaging_step_of_nonnegative_fourier {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ)
(hf : ∀ k, ZMod.dft f k = (‖ZMod.dft f k‖ : ℂ)) (k : ZMod q) :
‖ZMod.dft (cyclicUnitAveragingStep f w) k‖ =
(∑ u : (ZMod q)ˣ, w u * ‖ZMod.dft f ((u : ZMod q) * k)‖) ^ 2 := by
rw [dft_unit_averaging_step_of_nonnegative_fourier f w hf, Complex.norm_of_nonneg (sq_nonneg _)]
theorem dft_unit_averaging_step_nonnegative {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ)
(hf : ∀ k, ZMod.dft f k = (‖ZMod.dft f k‖ : ℂ)) (k : ZMod q) :
ZMod.dft (cyclicUnitAveragingStep f w) k = (‖ZMod.dft (cyclicUnitAveragingStep f w) k‖ : ℂ) := by
rw [dft_unit_averaging_step_of_nonnegative_fourier f w hf, Complex.norm_of_nonneg (sq_nonneg _)]
theorem dft_unit_averaging_iter_nonnegative {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : ℕ → (ZMod q)ˣ → ℝ)
(hf : ∀ k, ZMod.dft f k = (‖ZMod.dft f k‖ : ℂ)) (n : ℕ) :
∀ k, ZMod.dft (cyclicUnitAveragingIter f w n) k =
(‖ZMod.dft (cyclicUnitAveragingIter f w n) k‖ : ℂ) := by
induction n with
| zero => exact hf
| succ n ih => exact dft_unit_averaging_step_nonnegative _ _ ih
noncomputable def cyclicUnitProductIter {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : ℕ → (ZMod q)ˣ → ℝ) : ℕ → ZMod q → ℂ
| 0 => f
| n + 1 => cyclicMixture (w n) (cyclicUnitDilate (cyclicUnitProductIter f w n))
theorem norm_dft_unit_product_dominated {q R : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : ℕ → (ZMod q)ˣ → ℝ)
(hf : ∀ x, f x = (‖f x‖ : ℂ))
(hw : ∀ n < R, ∀ u, 0 ≤ w n u) (hmass : ∀ n < R, ∑ u : (ZMod q)ˣ, w n u = 1) :
∀ n ≤ R, ∀ k : ZMod q,
‖ZMod.dft (cyclicUnitProductIter f w n) k‖ ^ (2 ^ (n + 1)) ≤
‖ZMod.dft (cyclicUnitAveragingIter (cyclicSymmetrize f) w n) k‖ := by
intro n
induction n with
| zero =>
intro hn k
simp only [cyclicUnitProductIter, cyclicUnitAveragingIter, zero_add, pow_one,
dft_cyclic_symmetrize f hf, Complex.norm_of_nonneg (sq_nonneg _)]
exact le_rfl
| succ n ih =>
intro hn k
let ν := cyclicUnitAveragingIter (cyclicSymmetrize f) w n
have hν : ∀ k, ZMod.dft ν k = (‖ZMod.dft ν k‖ : ℂ) :=
dft_unit_averaging_iter_nonnegative _ w (dft_cyclic_symmetrize_nonnegative f hf) n
have hh : ‖ZMod.dft (cyclicUnitProductIter f w (n + 1)) k‖ ^ (2 ^ (n + 1)) ≤
∑ u : (ZMod q)ˣ, w n u * ‖ZMod.dft ν ((u : ZMod q) * k)‖ := by
apply (norm_dft_unit_mixture_two_power_le (cyclicUnitProductIter f w n) (w n)
(hw n (by omega)) (hmass n (by omega)) (n + 1) k).trans
exact Finset.sum_le_sum (fun u _ => mul_le_mul_of_nonneg_left (ih (by omega) _) (hw n (by omega) u))
change ‖ZMod.dft (cyclicUnitProductIter f w (n + 1)) k‖ ^ (2 ^ (n + 1 + 1)) ≤
‖ZMod.dft (cyclicUnitAveragingStep ν (w n)) k‖
rw [norm_dft_unit_averaging_step_of_nonnegative_fourier ν (w n) hν, pow_succ, pow_mul]
exact pow_le_pow_left₀ (pow_nonneg (norm_nonneg _) _) hh 2
theorem norm_dft_unit_product_final_power_le {q R : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : ℕ → (ZMod q)ˣ → ℝ)
(hf : ∀ x, f x = (‖f x‖ : ℂ))
(hw : ∀ n < R + 1, ∀ u, 0 ≤ w n u)
(hmass : ∀ n < R + 1, ∑ u : (ZMod q)ˣ, w n u = 1) (k : ZMod q) :
‖ZMod.dft (cyclicUnitProductIter f w (R + 1)) k‖ ^ (2 ^ (R + 1)) ≤
‖ZMod.dft (cyclicMixture (w R)
(cyclicUnitDilate (cyclicUnitAveragingIter (cyclicSymmetrize f) w R))) k‖ := by
have hν := dft_unit_averaging_iter_nonnegative (cyclicSymmetrize f) w
(dft_cyclic_symmetrize_nonnegative f hf) R
rw [norm_dft_unit_mixture_of_nonnegative_fourier _ _ (hw R (by omega)) hν]
apply (norm_dft_unit_mixture_two_power_le (cyclicUnitProductIter f w R) (w R)
(hw R (by omega)) (hmass R (by omega)) (R + 1) k).trans
apply Finset.sum_le_sum
intro u hu
apply mul_le_mul_of_nonneg_left _ (hw R (by omega) u)
exact norm_dft_unit_product_dominated f w hf hw hmass R (by omega) _
theorem finite_sum_comp_le_of_injective {X Y : Type*} [Fintype X] [Fintype Y]
(e : X → Y) (he : Function.Injective e) (F : Y → ℝ) (hF : ∀ y, 0 ≤ F y) :
(∑ x : X, F (e x)) ≤ ∑ y : Y, F y := by
classical
calc
_ = ∑ y ∈ (Finset.univ : Finset X).image e, F y := by
symm
exact Finset.sum_image (fun x _ y _ hxy => he hxy)
_ ≤ _ := Finset.sum_le_sum_of_subset_of_nonneg (Finset.subset_univ _)
(fun y _ _ => hF y)
theorem norm_dft_unit_mixture_sq_le {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (w : (ZMod q)ˣ → ℝ)
(hw : ∀ u, 0 ≤ w u) (hmass : ∑ u : (ZMod q)ˣ, w u = 1)
{M : ℝ} (hpeak : ∀ u, w u ≤ M) {k : ZMod q} (hk : IsUnit k) :
‖ZMod.dft (cyclicMixture w (cyclicUnitDilate f)) k‖ ^ 2 ≤
(q : ℝ) * M * ∑ x : ZMod q, ‖f x‖ ^ 2 := by
have hM : 0 ≤ M := (hw 1).trans (hpeak 1)
have hwsq : (∑ u : (ZMod q)ˣ, w u ^ 2) ≤ M := by
calc
_ ≤ ∑ u : (ZMod q)ˣ, w u * M := Finset.sum_le_sum (fun u _ => by
simpa only [pow_two] using mul_le_mul_of_nonneg_left (hpeak u) (hw u))
_ = M := by rw [← Finset.sum_mul, hmass, one_mul]
have hfsq : (∑ u : (ZMod q)ˣ, ‖ZMod.dft f ((u : ZMod q) * k)‖ ^ 2) ≤
(q : ℝ) * ∑ x : ZMod q, ‖f x‖ ^ 2 := by
obtain ⟨v, rfl⟩ := hk
have hinj : Function.Injective (fun u : (ZMod q)ˣ => (u : ZMod q) * (v : ZMod q)) := by
intro u z huz
exact Units.val_injective (v.mulRight.injective huz)
exact (finite_sum_comp_le_of_injective _ hinj (fun x => ‖ZMod.dft f x‖ ^ 2)
(fun _ => sq_nonneg _)).trans_eq (dft_parseval f)
calc
_ ≤ (∑ u : (ZMod q)ˣ, w u * ‖ZMod.dft f ((u : ZMod q) * k)‖) ^ 2 :=
pow_le_pow_left₀ (norm_nonneg _) (norm_dft_cyclic_unit_mixture_le f w hw k) 2
_ ≤ (∑ u : (ZMod q)ˣ, w u ^ 2) *
∑ u : (ZMod q)ˣ, ‖ZMod.dft f ((u : ZMod q) * k)‖ ^ 2 :=
Finset.sum_mul_sq_le_sq_mul_sq _ _ _
_ ≤ M * ((q : ℝ) * ∑ x : ZMod q, ‖f x‖ ^ 2) :=
mul_le_mul hwsq hfsq (Finset.sum_nonneg (fun _ _ => sq_nonneg _)) hM
_ = _ := by ring
theorem dyadic_unit_probability_point_bound {J : ℕ} {γ ε : ℝ}
{w : (ZMod (2 ^ J))ˣ → ℝ} (hw : ∀ u, 0 ≤ w u)
(hspread : DyadicUnitProbabilityNonconcentration γ ε w)
(hJ : 0 < J) (hε : ε < 1) (u : (ZMod (2 ^ J))ˣ) :
w u ≤ (2 : ℝ) ^ (-γ * (J : ℝ)) := by
have hεJ : ε * (J : ℝ) < (J : ℝ) := by
simpa only [one_mul] using mul_lt_mul_of_pos_right hε (show (0 : ℝ) < J by exact_mod_cast hJ)
apply (Finset.single_le_sum (fun v _ => hw v) (show u ∈ Finset.univ.filter
(fun v : (ZMod (2 ^ J))ˣ => (((v : ZMod (2 ^ J)).val : ZMod (2 ^ J))) = (u : ZMod (2 ^ J))) by simp)).trans
exact hspread J le_rfl hεJ (u : ZMod (2 ^ J))
/-- Power cancellation for an initial nonconcentrated law followed by a
fixed number of independent nonconcentrated unit inputs. -/
theorem exists_dyadic_unit_product_fourier_decay {γ : ℝ} (hγ : 0 < γ) :
∃ ε τ : ℝ, 0 < ε ∧ ε ≤ 1 / 4 ∧ 0 < τ ∧ ∃ r : ℕ, 0 < r ∧ ∃ J₀ : ℕ,
∀ J : ℕ, J₀ ≤ J → ∀ f : ZMod (2 ^ J) → ℂ,
∀ w : ℕ → (ZMod (2 ^ J))ˣ → ℝ,
FiniteComplexProbability f →
DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖) →
(∀ n < r, ∀ u, 0 ≤ w n u) →
(∀ n < r, (∑ u : (ZMod (2 ^ J))ˣ, w n u) = 1) →
(∀ n < r, DyadicUnitProbabilityNonconcentration γ ε (w n)) →
∀ k : ZMod (2 ^ J), IsUnit k →
‖ZMod.dft (cyclicUnitProductIter f w r) k‖ ≤ (2 : ℝ) ^ (-τ * (J : ℝ)) := by
let δ := min (γ / 2) (1 / 2)
have hδ : 0 < δ := lt_min (by positivity) (by norm_num)
have hδ1 : δ ≤ 1 := (min_le_right _ _).trans (by norm_num)
have hκ : 0 < γ - δ := by
have hh : δ ≤ γ / 2 := min_le_left _ _
linarith only [hh, hγ]
obtain ⟨ε, hε, hε4, R, hR, J₀, hflat⟩ := exists_dyadic_probability_flattening_iteration hγ hδ hδ1
let N := 2 ^ (R + 2)
have hN : 0 < N := by dsimp only [N]; positivity
have hNR : (0 : ℝ) < N := by exact_mod_cast hN
let τ := (γ - δ) / (N : ℝ)
have hτ : 0 < τ := div_pos hκ hNR
refine ⟨ε, τ, hε, hε4, hτ, R + 1, by omega, max J₀ 1, ?_⟩
intro J hJ f w hf hspread hw hmass hwspread k hk
have hJ₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hJpos : 0 < J := by have hh := (le_max_right J₀ 1).trans hJ; omega
let ν := cyclicUnitAveragingIter (cyclicSymmetrize f) w R
have henergy : (∑ x : ZMod (2 ^ J), ‖ν x‖ ^ 2) ≤ (2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) :=
hflat J hJ₀ (cyclicSymmetrize f) w (cyclic_symmetrize_probability hf)
(dyadic_probability_nonconcentration_symmetrize hf hspread)
(fun n hn => hw n (by omega)) (fun n hn => hmass n (by omega))
(fun n hn => hwspread n (by omega))
have hlast : ∀ u, w R u ≤ (2 : ℝ) ^ (-γ * (J : ℝ)) :=
dyadic_unit_probability_point_bound (hw R (by omega)) (hwspread R (by omega))
hJpos (by linarith only [hε4])
have hbilinear : ‖ZMod.dft (cyclicMixture (w R) (cyclicUnitDilate ν)) k‖ ^ 2 ≤
(2 : ℝ) ^ (-(γ - δ) * (J : ℝ)) := by
calc
_ ≤ ((2 ^ J : ℕ) : ℝ) * (2 : ℝ) ^ (-γ * (J : ℝ)) * ∑ x : ZMod (2 ^ J), ‖ν x‖ ^ 2 :=
norm_dft_unit_mixture_sq_le ν (w R) (hw R (by omega)) (hmass R (by omega)) hlast hk
_ ≤ ((2 ^ J : ℕ) : ℝ) * (2 : ℝ) ^ (-γ * (J : ℝ)) * (2 : ℝ) ^ (-(1 - δ) * (J : ℝ)) :=
mul_le_mul_of_nonneg_left henergy (by positivity)
_ = _ := by
push_cast
rw [← Real.rpow_natCast, ← Real.rpow_add (by norm_num), ← Real.rpow_add (by norm_num)]
congr 1
ring
have hpower : ‖ZMod.dft (cyclicUnitProductIter f w (R + 1)) k‖ ^ N ≤
(2 : ℝ) ^ (-(γ - δ) * (J : ℝ)) := by
have hh := pow_le_pow_left₀ (pow_nonneg (norm_nonneg _) _)
(norm_dft_unit_product_final_power_le f w hf.norm_cast hw hmass k) 2
have he : N = 2 ^ (R + 1) * 2 := by dsimp only [N]; rw [show R + 2 = R + 1 + 1 by omega, pow_succ]
rw [he, pow_mul]
exact hh.trans hbilinear
apply (pow_le_pow_iff_left₀ (norm_nonneg _) (by positivity) hN.ne').mp
calc
_ ≤ (2 : ℝ) ^ (-(γ - δ) * (J : ℝ)) := hpower
_ = ((2 : ℝ) ^ (-τ * (J : ℝ))) ^ N := by
rw [← Real.rpow_mul_natCast (by norm_num)]
congr 1
dsimp only [τ]
field_simp
theorem finite_sum_units_eq {R M : Type*} [Monoid R] [Fintype R] [Fintype Rˣ]
[AddCommMonoid M] (F : R → M) (hsupport : ∀ x, F x ≠ 0 → IsUnit x) :
(∑ u : Rˣ, F (u : R)) = ∑ x : R, F x := by
classical
calc
_ = ∑ x ∈ (Finset.univ : Finset Rˣ).image (fun u : Rˣ => (u : R)), F x := by
symm
exact Finset.sum_image (fun u _ v _ huv => Units.val_injective huv)
_ = _ := by
apply Finset.sum_subset (Finset.subset_univ _)
intro x hx hxnot
by_contra hzero
obtain ⟨u, rfl⟩ := hsupport x hzero
exact hxnot (Finset.mem_image.mpr ⟨u, Finset.mem_univ _, rfl⟩)
theorem finite_unit_fiber_mass_eq {R Q : Type*} [Monoid R] [Fintype R] [Fintype Rˣ]
[DecidableEq Q] (p : R → ℝ) (π : R → Q)
(hsupport : ∀ x, p x ≠ 0 → IsUnit x) (r : Q) :
(∑ u ∈ Finset.univ.filter (fun u : Rˣ => π (u : R) = r), p (u : R)) =
finitePushforward p π r := by
simp only [finitePushforward, Finset.sum_filter]
apply finite_sum_units_eq (fun x => if π x = r then p x else 0)
intro x hx
by_cases hxr : π x = r
· exact hsupport x (by simpa only [if_pos hxr] using hx)
· simp only [if_neg hxr, ne_eq, not_true_eq_false] at hx
theorem dyadic_unit_probability_nonconcentration_of_supported {J : ℕ} {γ ε : ℝ}
{p : ZMod (2 ^ J) → ℝ} (hsupport : ∀ x, p x ≠ 0 → IsUnit x)
(hspread : DyadicProbabilityNonconcentration γ ε p) :
DyadicUnitProbabilityNonconcentration γ ε (fun u : (ZMod (2 ^ J))ˣ => p (u : ZMod (2 ^ J))) := by
intro L hL hεL r
have heq := finite_unit_fiber_mass_eq p (fun x : ZMod (2 ^ J) => (x.val : ZMod (2 ^ L))) hsupport r
exact heq.trans_le (hspread L hL hεL r)
theorem cyclic_multiplicative_convolution_comm {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) : cyclicMultiplicativeConvolution f g = cyclicMultiplicativeConvolution g f := by
classical
funext x
unfold cyclicMultiplicativeConvolution cyclicPushforward
apply Fintype.sum_equiv (Equiv.prodComm (ZMod q) (ZMod q))
intro p
rcases p with ⟨a, b⟩
simp [mul_comm]
theorem cyclic_product_pow_one {q : ℕ} [NeZero q] (f : ZMod q → ℂ) :
cyclicProductPow f 1 = f := by
apply ZMod.dft.injective
funext k
rw [cyclicProductPow, dft_cyclicMultiplicativeConvolution]
simp [cyclicProductPow, ite_mul]
theorem cyclic_mixture_units_eq_mulconv {q : ℕ} [NeZero q]
(f g : ZMod q → ℂ) (hg : ∀ x, g x = (‖g x‖ : ℂ))
(hsupport : ∀ x, g x ≠ 0 → IsUnit x) :
cyclicMixture (fun u : (ZMod q)ˣ => ‖g (u : ZMod q)‖) (cyclicUnitDilate f) =
cyclicMultiplicativeConvolution f g := by
apply ZMod.dft.injective
funext k
rw [dft_cyclic_mixture, dft_cyclicMultiplicativeConvolution]
calc
_ = ∑ u : (ZMod q)ˣ, g (u : ZMod q) * ZMod.dft f ((u : ZMod q) * k) := by
apply Finset.sum_congr rfl
intro u hu
rw [dft_cyclic_unit_dilate, ← hg (u : ZMod q)]
_ = _ := finite_sum_units_eq (fun x : ZMod q => g x * ZMod.dft f (x * k))
(fun x hx => hsupport x (mul_ne_zero_iff.mp hx).1)
theorem cyclic_unit_product_iter_const {q : ℕ} [NeZero q]
(f : ZMod q → ℂ) (hf : ∀ x, f x = (‖f x‖ : ℂ))
(hsupport : ∀ x, f x ≠ 0 → IsUnit x) (r : ℕ) :
cyclicUnitProductIter f (fun _ u => ‖f (u : ZMod q)‖) r = cyclicProductPow f (r + 1) := by
induction r with
| zero => exact (cyclic_product_pow_one f).symm
| succ r ih =>
rw [cyclicUnitProductIter, ih, cyclic_mixture_units_eq_mulconv _ f hf hsupport]
exact cyclic_multiplicative_convolution_comm _ _
theorem cyclic_uniform_nat_set_complex_probability {q : ℕ} [NeZero q]
{A : Finset ℕ} (hA : A.Nonempty) : FiniteComplexProbability (cyclicUniformNatSet (q := q) A) := by
refine ⟨?_, ?_⟩
· intro x
rw [norm_cyclicUniformNatSet, cyclicUniformNatSet_eq_residue_mass]
· simpa only [ZMod.dft_apply_zero] using dft_cyclicUniformNatSet_at_zero (q := q) hA
theorem dyadic_uniform_nat_set_probability_nonconcentration {J : ℕ} {γ ε : ℝ}
(A : Finset ℕ) (hcutoff : 2 ≤ ε * (J : ℝ))
(hspread : ∀ L : ℕ, 2 ≤ L → L ≤ J → ∀ x : ZMod (2 ^ L),
‖cyclicUniformNatSet A x‖ ≤ (2 : ℝ) ^ (-γ * (L : ℝ))) :
DyadicProbabilityNonconcentration γ ε (fun x : ZMod (2 ^ J) => ‖cyclicUniformNatSet A x‖) := by
intro L hL hεL r
have hL2 : 2 ≤ L := by exact_mod_cast (hcutoff.trans_lt hεL).le
let π : ZMod (2 ^ J) →+* ZMod (2 ^ L) := ZMod.castHom (pow_dvd_pow 2 hL) _
have hπ : ∀ x : ZMod (2 ^ J), π x = (x.val : ZMod (2 ^ L)) := fun x => ZMod.cast_eq_val _
have heq := congrFun (finite_pushforward_norm_cyclicUniformNatSet π A) r
have hh := hspread L hL2 hL r
rw [← heq] at hh
simpa only [finitePushforward, hπ] using hh
theorem weighted_dyadic_mixing : WeightedDyadicMixing := by
intro γ hγ hγhalf
obtain ⟨ε, τ, hε, hε4, hτ, r, hr, J₀, hdecay⟩ := exists_dyadic_unit_product_fourier_decay hγ
refine ⟨r + 1, τ, max J₀ ⌈2 / ε⌉₊, by omega, hτ, ?_⟩
intro J hJ A hA hodd hspread a ha
have hJ₀ : J₀ ≤ J := (le_max_left _ _).trans hJ
have hJceil : ⌈2 / ε⌉₊ ≤ J := (le_max_right _ _).trans hJ
have hcutoff : 2 ≤ ε * (J : ℝ) := by
have hcast : (2 / ε : ℝ) ≤ J := (Nat.le_ceil _).trans (by exact_mod_cast hJceil)
have hh := (div_le_iff₀ hε).mp hcast
simpa only [mul_comm] using hh
let f : ZMod (2 ^ J) → ℂ := cyclicUniformNatSet A
let w : (ZMod (2 ^ J))ˣ → ℝ := fun u => ‖f (u : ZMod (2 ^ J))‖
have hf : FiniteComplexProbability f := cyclic_uniform_nat_set_complex_probability hA
have hsupport : ∀ x, ‖f x‖ ≠ 0 → IsUnit x := cyclicUniformNatSet_support_odd hodd J
have hsupport' : ∀ x, f x ≠ 0 → IsUnit x := fun x hx => hsupport x (norm_ne_zero_iff.mpr hx)
have hnonconcentration : DyadicProbabilityNonconcentration γ ε (fun x => ‖f x‖) :=
dyadic_uniform_nat_set_probability_nonconcentration A hcutoff hspread
have hw : ∀ u, 0 ≤ w u := fun _ => norm_nonneg _
have hmass : ∑ u : (ZMod (2 ^ J))ˣ, w u = 1 := by
rw [finite_sum_units_eq (fun x => ‖f x‖) hsupport]
exact finite_complex_probability_sum_norm hf
have hwspread : DyadicUnitProbabilityNonconcentration γ ε w :=
dyadic_unit_probability_nonconcentration_of_supported hsupport hnonconcentration
have hh := hdecay J hJ₀ f (fun _ => w) hf hnonconcentration (fun _ _ => hw)
(fun _ _ => hmass) (fun _ _ => hwspread) (a : ZMod (2 ^ J)) (odd_natCast_isUnit_dyadic J ha)
rw [cyclic_unit_product_iter_const f hf.norm_cast hsupport'] at hh
exact hh
theorem target : fcTypeOfName% "Erdos18.erdos_18b" := by
exact erdos18b_of_weighted_dyadic_mixing weighted_dyadic_mixing
Provenance
- Proof SHA-256
- sha256:4d6ee89617415288e9f127beb3c0e0211c011f891889fcb43d0e16373bd14088
- Solver
- JenW1N
- Attribution
- conjectures.io