@@ -21,19 +21,6 @@ minor notational difference is that we write $\nu(n)$ in place of $\frac{\omega(
21
21
* `siftedSum_le_mainSum_errSum_of_UpperBoundSieve` - Every upper bound sieve gives an upper bound
22
22
on the size of the sifted set in terms of `mainSum` and `errSum`
23
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
24
## References
38
25
39
26
* [ Heath-Brown, *Lectures on sieves* ] [heathbrown2002lecturessieves ]
@@ -56,7 +43,7 @@ and `ν` is a multiplicative arithmetic function such that `0 < ν p < 1` for al
56
43
Then a sieve-type theorem will give us an upper (or lower) bound on the size of the sifted sum
57
44
`∑ n ∈ {k ∈ support | k.Coprime P}, a n`, obtained by removing any elements of `A` that are a
58
45
multiple of a prime in `P`. -/
59
- class BoundingSieve where
46
+ structure BoundingSieve where
60
47
/-- The set of natural numbers that is to be sifted. The fundamental lemma yields an upper bound
61
48
on the size of this set after the multiples of small primes have been removed. -/
62
49
support : Finset ℕ
@@ -80,7 +67,7 @@ class BoundingSieve where
80
67
81
68
/-- The Selberg upper bound sieve in particular introduces a parameter called the `level` which
82
69
gives the user control over the size of the error term. -/
83
- class SelbergSieve extends BoundingSieve where
70
+ structure SelbergSieve extends BoundingSieve where
84
71
/-- The `level` of the sieve controls how many terms we include in the inclusion-exclusion type
85
72
sum. A higher level will yield a tighter bound for the main term, but will also increase the
86
73
size of the error term. -/
@@ -94,120 +81,99 @@ namespace Mathlib.Meta.Positivity
94
81
open Lean Meta Qq
95
82
96
83
/-- Extension for the `positivity` tactic: `BoundingSieve.weights`. -/
97
- @[positivity BoundingSieve.weights _]
84
+ @[positivity BoundingSieve.weights _ _ ]
98
85
def evalBoundingSieveWeights : PositivityExt where eval {u α} _zα _pα e := do
99
86
match u, α, e with
100
- | 0 , ~q(ℝ), ~q(@BoundingSieve.weights $i $n) =>
87
+ | 0 , ~q(ℝ), ~q(@BoundingSieve.weights $s $n) =>
101
88
assertInstancesCommute
102
- pure (.nonnegative q(BoundingSieve.weights_nonneg $n))
89
+ pure (.nonnegative q(BoundingSieve.weights_nonneg $s $ n))
103
90
| _, _, _ => throwError "not BoundingSieve.weights"
104
91
105
92
end Mathlib.Meta.Positivity
106
93
107
- namespace SelbergSieve
108
- open BoundingSieve
109
-
110
- namespace Notation
111
-
112
- @[inherit_doc nu]
113
- scoped notation3 "ν" => nu
114
- @[inherit_doc prodPrimes]
115
- scoped notation3 "P" => prodPrimes
116
- @[inherit_doc weights]
117
- scoped notation3 "a" => weights
118
- @[inherit_doc totalMass]
119
- scoped notation3 "X" => totalMass
120
- @[inherit_doc support]
121
- scoped notation3 "A" => support
122
- @[inherit_doc level]
123
- scoped notation3 "y" => level
94
+ namespace BoundingSieve
95
+ open SelbergSieve
124
96
125
- theorem one_le_y [ s : SelbergSieve] : 1 ≤ y := one_le_level
97
+ theorem one_le_y { s : SelbergSieve} : 1 ≤ s.level := s. one_le_level
126
98
127
- end Notation
128
-
129
- open Notation
130
-
131
- variable [s : BoundingSieve]
99
+ variable {s : BoundingSieve}
132
100
133
101
/-! Lemmas about $P$. -/
134
102
135
- theorem prodPrimes_ne_zero : P ≠ 0 :=
136
- Squarefree.ne_zero prodPrimes_squarefree
103
+ theorem prodPrimes_ne_zero : s.prodPrimes ≠ 0 :=
104
+ Squarefree.ne_zero s. prodPrimes_squarefree
137
105
138
- theorem squarefree_of_dvd_prodPrimes {d : ℕ} (hd : d ∣ P ) : Squarefree d :=
139
- Squarefree.squarefree_of_dvd hd prodPrimes_squarefree
106
+ theorem squarefree_of_dvd_prodPrimes {d : ℕ} (hd : d ∣ s.prodPrimes ) : Squarefree d :=
107
+ Squarefree.squarefree_of_dvd hd s. prodPrimes_squarefree
140
108
141
- theorem squarefree_of_mem_divisors_prodPrimes {d : ℕ} (hd : d ∈ divisors P) : Squarefree d := by
109
+ theorem squarefree_of_mem_divisors_prodPrimes {d : ℕ} (hd : d ∈ divisors s.prodPrimes) :
110
+ Squarefree d := by
142
111
simp only [Nat.mem_divisors] at hd
143
- exact Squarefree.squarefree_of_dvd hd.left prodPrimes_squarefree
112
+ exact Squarefree.squarefree_of_dvd hd.left s. prodPrimes_squarefree
144
113
145
114
/-! Lemmas about $\nu$. -/
146
115
147
- theorem prod_primeFactors_nu {d : ℕ} (hd : d ∣ P) : ∏ p ∈ d.primeFactors, ν p = ν d := by
148
- rw [← nu_mult.map_prod_of_subset_primeFactors _ _ subset_rfl,
149
- Nat.prod_primeFactors_of_squarefree <| Squarefree.squarefree_of_dvd hd prodPrimes_squarefree]
116
+ theorem prod_primeFactors_nu {d : ℕ} (hd : d ∣ s.prodPrimes) :
117
+ ∏ p ∈ d.primeFactors, s.nu p = s.nu d := by
118
+ rw [← s.nu_mult.map_prod_of_subset_primeFactors _ _ subset_rfl,
119
+ Nat.prod_primeFactors_of_squarefree <| Squarefree.squarefree_of_dvd hd s.prodPrimes_squarefree]
150
120
151
- theorem nu_pos_of_dvd_prodPrimes {d : ℕ} (hd : d ∣ P ) : 0 < ν d := by
121
+ theorem nu_pos_of_dvd_prodPrimes {d : ℕ} (hd : d ∣ s.prodPrimes ) : 0 < s.nu d := by
152
122
calc
153
- 0 < ∏ p ∈ d.primeFactors, ν p := by
123
+ 0 < ∏ p ∈ d.primeFactors, s.nu p := by
154
124
apply prod_pos
155
125
intro p hpd
156
126
have hp_prime : p.Prime := prime_of_mem_primeFactors hpd
157
- have hp_dvd : p ∣ P := (dvd_of_mem_primeFactors hpd).trans hd
158
- exact nu_pos_of_prime p hp_prime hp_dvd
159
- _ = ν d := prod_primeFactors_nu hd
127
+ have hp_dvd : p ∣ s.prodPrimes := (dvd_of_mem_primeFactors hpd).trans hd
128
+ exact s. nu_pos_of_prime p hp_prime hp_dvd
129
+ _ = s.nu d := prod_primeFactors_nu hd
160
130
161
- theorem nu_ne_zero {d : ℕ} (hd : d ∣ P ) : ν d ≠ 0 := by
131
+ theorem nu_ne_zero {d : ℕ} (hd : d ∣ s.prodPrimes ) : s.nu d ≠ 0 := by
162
132
apply _root_.ne_of_gt
163
133
exact nu_pos_of_dvd_prodPrimes hd
164
134
165
- theorem nu_lt_one_of_dvd_prodPrimes {d : ℕ} (hdP : d ∣ P) (hd_ne_one : d ≠ 1 ) : ν d < 1 := by
166
- have hd_sq : Squarefree d := Squarefree.squarefree_of_dvd hdP prodPrimes_squarefree
135
+ theorem nu_lt_one_of_dvd_prodPrimes {d : ℕ} (hdP : d ∣ s.prodPrimes) (hd_ne_one : d ≠ 1 ) :
136
+ s.nu d < 1 := by
137
+ have hd_sq : Squarefree d := Squarefree.squarefree_of_dvd hdP s.prodPrimes_squarefree
167
138
have := hd_sq.ne_zero
168
139
calc
169
- ν d = ∏ p ∈ d.primeFactors, ν p := (prod_primeFactors_nu hdP).symm
140
+ s.nu d = ∏ p ∈ d.primeFactors, s.nu p := (prod_primeFactors_nu hdP).symm
170
141
_ < ∏ p ∈ d.primeFactors, 1 := by
171
142
apply prod_lt_prod_of_nonempty
172
143
· intro p hp
173
144
simp only [mem_primeFactors] at hp
174
- apply nu_pos_of_prime p hp.1 (hp.2 .1 .trans hdP)
145
+ apply s. nu_pos_of_prime p hp.1 (hp.2 .1 .trans hdP)
175
146
· intro p hpd; rw [mem_primeFactors_of_ne_zero hd_sq.ne_zero] at hpd
176
- apply nu_lt_one_of_prime p hpd.left (hpd.2 .trans hdP)
147
+ apply s. nu_lt_one_of_prime p hpd.left (hpd.2 .trans hdP)
177
148
· simp only [nonempty_primeFactors, show 1 < d by omega]
178
149
_ = 1 := by
179
150
simp
180
151
181
152
/-- The weight of all the elements that are a multiple of `d`. -/
182
153
@[simp]
183
- def multSum (d : ℕ) : ℝ := ∑ n ∈ A , if d ∣ n then a n else 0
154
+ def multSum (d : ℕ) : ℝ := ∑ n ∈ s.support , if d ∣ n then s.weights n else 0
184
155
185
- @[inherit_doc multSum]
186
- scoped [SelbergSieve.Notation] notation3 "𝒜" => multSum
187
156
188
157
/-- The remainder term in the approximation A_d = ν (d) X + R_d. This is the degree to which `nu`
189
158
fails to approximate the proportion of the weight that is a multiple of `d`. -/
190
159
@[simp]
191
- def rem (d : ℕ) : ℝ := 𝒜 d - ν d * X
192
-
193
- @[inherit_doc rem]
194
- scoped [SelbergSieve.Notation] notation3 "R" => rem
160
+ def rem (d : ℕ) : ℝ := s.multSum d - s.nu d * s.totalMass
195
161
196
162
/-- The weight of all the elements that are not a multiple of any of our finite set of primes. -/
197
- def siftedSum : ℝ := ∑ d ∈ A , if Coprime P d then a d else 0
163
+ def siftedSum : ℝ := ∑ d ∈ s.support , if Coprime s.prodPrimes d then s.weights d else 0
198
164
199
165
/-- `X * mainSum μ⁺` is the main term in the upper bound on `sifted_sum`. -/
200
- def mainSum (muPlus : ℕ → ℝ) : ℝ := ∑ d ∈ divisors P , muPlus d * ν d
166
+ def mainSum (muPlus : ℕ → ℝ) : ℝ := ∑ d ∈ divisors s.prodPrimes , muPlus d * s.nu d
201
167
202
168
/-- `errSum μ⁺` is the error term in the upper bound on `sifted_sum`. -/
203
- def errSum (muPlus : ℕ → ℝ) : ℝ := ∑ d ∈ divisors P , |muPlus d| * |R d|
169
+ def errSum (muPlus : ℕ → ℝ) : ℝ := ∑ d ∈ divisors s.prodPrimes , |muPlus d| * |s.rem d|
204
170
205
- theorem multSum_eq_main_err (d : ℕ) : multSum d = ν d * X + R d := by
171
+ theorem multSum_eq_main_err (d : ℕ) : s. multSum d = s.nu d * s.totalMass + s.rem d := by
206
172
dsimp [rem]
207
173
ring
208
174
209
175
theorem siftedSum_eq_sum_support_mul_ite :
210
- siftedSum = ∑ d ∈ support, a d * if Nat.gcd P d = 1 then 1 else 0 := by
176
+ s. siftedSum = ∑ d ∈ s. support, s.weights d * if Nat.gcd s.prodPrimes d = 1 then 1 else 0 := by
211
177
dsimp only [siftedSum]
212
178
simp_rw [mul_ite, mul_one, mul_zero]
213
179
@@ -221,16 +187,17 @@ def IsUpperMoebius (muPlus : ℕ → ℝ) : Prop :=
221
187
∀ n : ℕ, (if n = 1 then 1 else 0 ) ≤ ∑ d ∈ n.divisors, muPlus d
222
188
223
189
theorem siftedSum_le_sum_of_upperMoebius (muPlus : ℕ → ℝ) (h : IsUpperMoebius muPlus) :
224
- siftedSum ≤ ∑ d ∈ divisors P , muPlus d * multSum d := by
190
+ s. siftedSum ≤ ∑ d ∈ divisors s.prodPrimes , muPlus d * s. multSum d := by
225
191
have hμ : ∀ n, (if n = 1 then 1 else 0 ) ≤ ∑ d ∈ n.divisors, muPlus d := h
226
192
calc siftedSum ≤
227
- ∑ n ∈ support, a n * ∑ d ∈ (Nat.gcd P n).divisors, muPlus d := ?caseA
228
- _ = ∑ n ∈ support, ∑ d ∈ divisors P, if d ∣ n then a n * muPlus d else 0 := ?caseB
229
- _ = ∑ d ∈ divisors P, muPlus d * multSum d := ?caseC
193
+ ∑ n ∈ s.support, s.weights n * ∑ d ∈ (Nat.gcd s.prodPrimes n).divisors, muPlus d := ?caseA
194
+ _ = ∑ n ∈ s.support, ∑ d ∈ divisors s.prodPrimes,
195
+ if d ∣ n then s.weights n * muPlus d else 0 := ?caseB
196
+ _ = ∑ d ∈ divisors s.prodPrimes, muPlus d * multSum d := ?caseC
230
197
case caseA =>
231
198
rw [siftedSum_eq_sum_support_mul_ite]
232
199
gcongr with n
233
- exact hμ (Nat.gcd P n)
200
+ exact hμ (Nat.gcd s.prodPrimes n)
234
201
case caseB =>
235
202
simp_rw [mul_sum, ← sum_filter]
236
203
congr with n
@@ -242,17 +209,17 @@ theorem siftedSum_le_sum_of_upperMoebius (muPlus : ℕ → ℝ) (h : IsUpperMoeb
242
209
simp_rw [multSum, ← sum_filter, mul_sum, mul_comm]
243
210
244
211
theorem siftedSum_le_mainSum_errSum_of_upperMoebius (muPlus : ℕ → ℝ) (h : IsUpperMoebius muPlus) :
245
- siftedSum ≤ X * mainSum muPlus + errSum muPlus := calc
246
- siftedSum ≤ ∑ d ∈ divisors P , muPlus d * multSum d :=
212
+ s. siftedSum ≤ s.totalMass * s. mainSum muPlus + s. errSum muPlus := calc
213
+ s. siftedSum ≤ ∑ d ∈ divisors s.prodPrimes , muPlus d * multSum d :=
247
214
siftedSum_le_sum_of_upperMoebius _ h
248
- _ = X * mainSum muPlus + ∑ d ∈ divisors P , muPlus d * R d := by
215
+ _ = s.totalMass * mainSum muPlus + ∑ d ∈ divisors s.prodPrimes , muPlus d * s.rem d := by
249
216
rw [mainSum, mul_sum, ← sum_add_distrib]
250
217
congr with d
251
218
dsimp only [rem]; ring
252
- _ ≤ X * mainSum muPlus + errSum muPlus := by
219
+ _ ≤ s.totalMass * mainSum muPlus + errSum muPlus := by
253
220
rw [errSum]
254
221
gcongr _ + ∑ d ∈ _, ?_ with d
255
222
rw [← abs_mul]
256
- exact le_abs_self (muPlus d * R d)
223
+ exact le_abs_self (muPlus d * s.rem d)
257
224
258
- end SelbergSieve
225
+ end BoundingSieve
0 commit comments