|
| 1 | +/- |
| 2 | +Copyright (c) 2024 Arend Mellendijk. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Arend Mellendijk |
| 5 | +-/ |
| 6 | +import Mathlib.Analysis.Normed.Ring.Basic |
| 7 | +import Mathlib.NumberTheory.ArithmeticFunction |
| 8 | + |
| 9 | +/-! |
| 10 | +# The Selberg Sieve |
| 11 | +
|
| 12 | +We set up the working assumptions of the Selberg sieve, define the notion of an upper bound sieve |
| 13 | +and show that every upper bound sieve yields an upper bound on the size of the sifted set. We also |
| 14 | +define the Λ² sieve and prove that Λ² sieves are upper bound sieves. We then diagonalise the main |
| 15 | +term of the Λ² sieve. |
| 16 | +
|
| 17 | +We mostly follow the treatment outlined by Heath-Brown in the notes to an old graduate course. One |
| 18 | +minor notational difference is that we write $\nu(n)$ in place of $\frac{\omega(n)}{n}$. |
| 19 | +
|
| 20 | +## Results |
| 21 | + * `siftedSum_le_mainSum_errSum_of_UpperBoundSieve` - Every upper bound sieve gives an upper bound |
| 22 | + on the size of the sifted set in terms of `mainSum` and `errSum` |
| 23 | +
|
| 24 | +## Notation |
| 25 | +The `SelbergSieve.Notation` namespace includes common shorthand for the variables included in the |
| 26 | +`SelbergSieve` structure. |
| 27 | + * `A` for `support` |
| 28 | + * `𝒜 d` for `multSum d` - the combined weight of the elements of `A` that are divisible by `d` |
| 29 | + * `P` for `prodPrimes` |
| 30 | + * `a` for `weights` |
| 31 | + * `X` for `totalMass` |
| 32 | + * `ν` for `nu` |
| 33 | + * `y` for `level` |
| 34 | + * `R d` for `rem d` |
| 35 | + * `g d` for `selbergTerms d` |
| 36 | +
|
| 37 | +## References |
| 38 | +
|
| 39 | + * [Heath-Brown, *Lectures on sieves*][heathbrown2002lecturessieves] |
| 40 | + * [Koukoulopoulos, *The Distribution of Prime Numbers*][MR3971232] |
| 41 | +
|
| 42 | +-/ |
| 43 | + |
| 44 | +noncomputable section |
| 45 | + |
| 46 | +open scoped BigOperators ArithmeticFunction |
| 47 | + |
| 48 | +open Finset Real Nat |
| 49 | + |
| 50 | +/-- We set up a sieve problem as follows. Take a finite set of natural numbers `A`, whose elements |
| 51 | +are weighted by a sequence `a n`. Also take a finite set of primes `P`, represented by a squarefree |
| 52 | +natural number. These are the primes that we will sift from our set `A`. Suppose we can approximate |
| 53 | +`∑ n ∈ {k ∈ A | d ∣ k}, a n = ν d * X + R d`, where `X` is an approximation to the total size of `A` |
| 54 | +and `ν` is a multiplicative arithmetic function such that `0 < ν p < 1` for all primes `p ∣ P`. |
| 55 | +
|
| 56 | +Then a sieve-type theorem will give us an upper (or lower) bound on the size of the sifted sum |
| 57 | +`∑ n ∈ {k ∈ support | k.Coprime P}, a n`, obtained by removing any elements of `A` that are a |
| 58 | +multiple of a prime in `P`. -/ |
| 59 | +class BoundingSieve where |
| 60 | + /-- The set of natural numbers that is to be sifted. The fundamental lemma yields an upper bound |
| 61 | + on the size of this set after the multiples of small primes have been removed. -/ |
| 62 | + support : Finset ℕ |
| 63 | + /-- The finite set of prime numbers whose multiples are to be sifted from `support`. We work with |
| 64 | + their product because it lets us treat `nu` as a multiplicative arithmetic function. It also |
| 65 | + plays well with Moebius inversion. -/ |
| 66 | + prodPrimes : ℕ |
| 67 | + prodPrimes_squarefree : Squarefree prodPrimes |
| 68 | + /-- A sequence representing how much each element of `support` should be weighted. -/ |
| 69 | + weights : ℕ → ℝ |
| 70 | + weights_nonneg : ∀ n : ℕ, 0 ≤ weights n |
| 71 | + /-- An approximation to `∑ i in support, weights i`, i.e. the size of the unsifted set. A bad |
| 72 | + approximation will yield a weak statement in the final theorem. -/ |
| 73 | + totalMass : ℝ |
| 74 | + /-- `nu d` is an approximation to the proportion of elements of `support` that are a multiple of |
| 75 | + `d` -/ |
| 76 | + nu : ArithmeticFunction ℝ |
| 77 | + nu_mult : nu.IsMultiplicative |
| 78 | + nu_pos_of_prime : ∀ p : ℕ, p.Prime → p ∣ prodPrimes → 0 < nu p |
| 79 | + nu_lt_one_of_prime : ∀ p : ℕ, p.Prime → p ∣ prodPrimes → nu p < 1 |
| 80 | + |
| 81 | +/-- The Selberg upper bound sieve in particular introduces a parameter called the `level` which |
| 82 | + gives the user control over the size of the error term. -/ |
| 83 | +class SelbergSieve extends BoundingSieve where |
| 84 | + /-- The `level` of the sieve controls how many terms we include in the inclusion-exclusion type |
| 85 | + sum. A higher level will yield a tighter bound for the main term, but will also increase the |
| 86 | + size of the error term. -/ |
| 87 | + level : ℝ |
| 88 | + one_le_level : 1 ≤ level |
| 89 | + |
| 90 | +attribute [arith_mult] BoundingSieve.nu_mult |
| 91 | + |
| 92 | +namespace SelbergSieve |
| 93 | +open BoundingSieve |
| 94 | + |
| 95 | +namespace Notation |
| 96 | + |
| 97 | +@[inherit_doc nu] |
| 98 | +scoped notation3 "ν" => nu |
| 99 | +@[inherit_doc prodPrimes] |
| 100 | +scoped notation3 "P" => prodPrimes |
| 101 | +@[inherit_doc weights] |
| 102 | +scoped notation3 "a" => weights |
| 103 | +@[inherit_doc totalMass] |
| 104 | +scoped notation3 "X" => totalMass |
| 105 | +@[inherit_doc support] |
| 106 | +scoped notation3 "A" => support |
| 107 | +@[inherit_doc level] |
| 108 | +scoped notation3 "y" => level |
| 109 | + |
| 110 | +theorem one_le_y [s : SelbergSieve] : 1 ≤ y := one_le_level |
| 111 | + |
| 112 | +end Notation |
| 113 | + |
| 114 | +open Notation |
| 115 | + |
| 116 | +variable [s : BoundingSieve] |
| 117 | + |
| 118 | +/-! Lemmas about $P$. -/ |
| 119 | + |
| 120 | +theorem prodPrimes_ne_zero : P ≠ 0 := |
| 121 | + Squarefree.ne_zero prodPrimes_squarefree |
| 122 | + |
| 123 | +theorem squarefree_of_dvd_prodPrimes {d : ℕ} (hd : d ∣ P) : Squarefree d := |
| 124 | + Squarefree.squarefree_of_dvd hd prodPrimes_squarefree |
| 125 | + |
| 126 | +theorem squarefree_of_mem_divisors_prodPrimes {d : ℕ} (hd : d ∈ divisors P) : Squarefree d := by |
| 127 | + simp only [Nat.mem_divisors] at hd |
| 128 | + exact Squarefree.squarefree_of_dvd hd.left prodPrimes_squarefree |
| 129 | + |
| 130 | +/-! Lemmas about $\nu$. -/ |
| 131 | + |
| 132 | +theorem prod_primeFactors_nu {d : ℕ} (hd : d ∣ P) : ∏ p ∈ d.primeFactors, ν p = ν d := by |
| 133 | + rw [← nu_mult.map_prod_of_subset_primeFactors _ _ subset_rfl, |
| 134 | + Nat.prod_primeFactors_of_squarefree <| Squarefree.squarefree_of_dvd hd prodPrimes_squarefree] |
| 135 | + |
| 136 | +theorem nu_pos_of_dvd_prodPrimes {d : ℕ} (hd : d ∣ P) : 0 < ν d := by |
| 137 | + calc |
| 138 | + 0 < ∏ p ∈ d.primeFactors, ν p := by |
| 139 | + apply prod_pos |
| 140 | + intro p hpd |
| 141 | + have hp_prime : p.Prime := prime_of_mem_primeFactors hpd |
| 142 | + have hp_dvd : p ∣ P := (dvd_of_mem_primeFactors hpd).trans hd |
| 143 | + exact nu_pos_of_prime p hp_prime hp_dvd |
| 144 | + _ = ν d := prod_primeFactors_nu hd |
| 145 | + |
| 146 | +theorem nu_ne_zero {d : ℕ} (hd : d ∣ P) : ν d ≠ 0 := by |
| 147 | + apply _root_.ne_of_gt |
| 148 | + exact nu_pos_of_dvd_prodPrimes hd |
| 149 | + |
| 150 | +theorem nu_lt_one_of_dvd_prodPrimes {d : ℕ} (hdP : d ∣ P) (hd_ne_one : d ≠ 1) : ν d < 1 := by |
| 151 | + have hd_sq : Squarefree d := Squarefree.squarefree_of_dvd hdP prodPrimes_squarefree |
| 152 | + have := hd_sq.ne_zero |
| 153 | + calc |
| 154 | + ν d = ∏ p ∈ d.primeFactors, ν p := (prod_primeFactors_nu hdP).symm |
| 155 | + _ < ∏ p ∈ d.primeFactors, 1 := by |
| 156 | + apply prod_lt_prod_of_nonempty |
| 157 | + · intro p hp |
| 158 | + simp only [mem_primeFactors] at hp |
| 159 | + apply nu_pos_of_prime p hp.1 (hp.2.1.trans hdP) |
| 160 | + · intro p hpd; rw [mem_primeFactors_of_ne_zero hd_sq.ne_zero] at hpd |
| 161 | + apply nu_lt_one_of_prime p hpd.left (hpd.2.trans hdP) |
| 162 | + · simp only [nonempty_primeFactors, show 1 < d by omega] |
| 163 | + _ = 1 := by |
| 164 | + simp |
| 165 | + |
| 166 | +/-- The weight of all the elements that are a multiple of `d`. -/ |
| 167 | +@[simp] |
| 168 | +def multSum (d : ℕ) : ℝ := ∑ n ∈ A, if d ∣ n then a n else 0 |
| 169 | + |
| 170 | +@[inherit_doc multSum] |
| 171 | +scoped [SelbergSieve.Notation] notation3 "𝒜" => multSum |
| 172 | + |
| 173 | +/-- The remainder term in the approximation A_d = ν (d) X + R_d. This is the degree to which `nu` |
| 174 | + fails to approximate the proportion of the weight that is a multiple of `d`. -/ |
| 175 | +@[simp] |
| 176 | +def rem (d : ℕ) : ℝ := 𝒜 d - ν d * X |
| 177 | + |
| 178 | +@[inherit_doc rem] |
| 179 | +scoped [SelbergSieve.Notation] notation3 "R" => rem |
| 180 | + |
| 181 | +/-- The weight of all the elements that are not a multiple of any of our finite set of primes. -/ |
| 182 | +def siftedSum : ℝ := ∑ d ∈ A, if Coprime P d then a d else 0 |
| 183 | + |
| 184 | +/-- `X * mainSum μ⁺` is the main term in the upper bound on `sifted_sum`. -/ |
| 185 | +def mainSum (muPlus : ℕ → ℝ) : ℝ := ∑ d ∈ divisors P, muPlus d * ν d |
| 186 | + |
| 187 | +/-- `errSum μ⁺` is the error term in the upper bound on `sifted_sum`. -/ |
| 188 | +def errSum (muPlus : ℕ → ℝ) : ℝ := ∑ d ∈ divisors P, |muPlus d| * |R d| |
| 189 | + |
| 190 | +theorem multSum_eq_main_err (d : ℕ) : multSum d = ν d * X + R d := by |
| 191 | + dsimp [rem] |
| 192 | + ring |
| 193 | + |
| 194 | +theorem siftedsum_eq_sum_support_mul_ite : |
| 195 | + siftedSum = ∑ d ∈ support, a d * if Nat.gcd P d = 1 then 1 else 0 := by |
| 196 | + dsimp only [siftedSum] |
| 197 | + simp_rw [mul_ite, mul_one, mul_zero] |
| 198 | + |
| 199 | +omit s in |
| 200 | +/-- A sequence of coefficients $\mu^{+}$ is upper Moebius if $\mu * \zeta ≤ \mu^{+} * \zeta$. These |
| 201 | + coefficients then yield an upper bound on the sifted sum. -/ |
| 202 | +def IsUpperMoebius (muPlus : ℕ → ℝ) : Prop := |
| 203 | + ∀ n : ℕ, (if n=1 then 1 else 0) ≤ ∑ d ∈ n.divisors, muPlus d |
| 204 | + |
| 205 | +theorem siftedSum_le_sum_of_upperMoebius (muPlus : ℕ → ℝ) (h : IsUpperMoebius muPlus) : |
| 206 | + siftedSum ≤ ∑ d ∈ divisors P, muPlus d * multSum d := by |
| 207 | + have hμ : ∀ n, (if n = 1 then 1 else 0) ≤ ∑ d ∈ n.divisors, muPlus d := h |
| 208 | + calc siftedSum ≤ |
| 209 | + ∑ n ∈ support, a n * ∑ d ∈ (Nat.gcd P n).divisors, muPlus d := ?caseA |
| 210 | + _ = ∑ n ∈ support, ∑ d ∈ divisors P, if d ∣ n then a n * muPlus d else 0 := ?caseB |
| 211 | + _ = ∑ d ∈ divisors P, muPlus d * multSum d := ?caseC |
| 212 | + case caseA => |
| 213 | + rw [siftedsum_eq_sum_support_mul_ite] |
| 214 | + apply Finset.sum_le_sum; intro n _ |
| 215 | + exact mul_le_mul_of_nonneg_left (hμ (Nat.gcd P n)) (weights_nonneg n) |
| 216 | + case caseB => |
| 217 | + simp_rw [mul_sum, ← sum_filter] |
| 218 | + congr with n |
| 219 | + congr |
| 220 | + · rw [← divisors_filter_dvd_of_dvd prodPrimes_ne_zero (Nat.gcd_dvd_left _ _)] |
| 221 | + ext x; simp +contextual [dvd_gcd_iff] |
| 222 | + case caseC => |
| 223 | + rw [sum_comm] |
| 224 | + simp_rw [multSum, ← sum_filter, mul_sum, mul_comm] |
| 225 | + |
| 226 | +theorem siftedSum_le_mainSum_errSum_of_upperMoebius (muPlus : ℕ → ℝ) (h : IsUpperMoebius muPlus) : |
| 227 | + siftedSum ≤ X * mainSum muPlus + errSum muPlus := by |
| 228 | + calc siftedSum ≤ ∑ d ∈ divisors P, muPlus d * multSum d := siftedSum_le_sum_of_upperMoebius _ h |
| 229 | + _ ≤ X * ∑ d ∈ divisors P, muPlus d * ν d + ∑ d ∈ divisors P, muPlus d * R d := ?caseA |
| 230 | + _ ≤ _ := ?caseB |
| 231 | + case caseA => |
| 232 | + apply le_of_eq |
| 233 | + rw [mul_sum, ←sum_add_distrib] |
| 234 | + congr with d |
| 235 | + dsimp only [rem]; ring |
| 236 | + case caseB => |
| 237 | + apply _root_.add_le_add (le_rfl) |
| 238 | + apply sum_le_sum; intro d _ |
| 239 | + rw [←abs_mul] |
| 240 | + exact le_abs_self (muPlus d * R d) |
| 241 | + |
| 242 | +end SelbergSieve |
0 commit comments