Skip to content

Commit b268456

Browse files
committed
feat(NumberTheory): define the Selberg Sieve (#21880)
This will be the first in a series of PRs proving the fundamental lemma of the Selberg sieve. This PR sets up the running assumptions for the Selberg sieve and writes the upper bound in terms of a main term and an error term.
1 parent 4aa8b04 commit b268456

File tree

2 files changed

+243
-0
lines changed

2 files changed

+243
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4359,6 +4359,7 @@ import Mathlib.NumberTheory.PythagoreanTriples
43594359
import Mathlib.NumberTheory.RamificationInertia.Basic
43604360
import Mathlib.NumberTheory.RamificationInertia.Galois
43614361
import Mathlib.NumberTheory.Rayleigh
4362+
import Mathlib.NumberTheory.SelbergSieve
43624363
import Mathlib.NumberTheory.SiegelsLemma
43634364
import Mathlib.NumberTheory.SmoothNumbers
43644365
import Mathlib.NumberTheory.SumFourSquares
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
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

Comments
 (0)