Skip to content

Commit b86fd5c

Browse files
ajirvingpre-commit-ci-lite[bot]jcommelin
committed
feat(NumberTheory.Chebyshev): prove connection between prime counting and theta (leanprover-community#32281)
Uses Abel summation to express the prime counting function in terms of the Chebyshev theta function. This upstreams some results from PrimeNumberTheoremAnd. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Johan Commelin <johan@commelin.net>
1 parent d7ea567 commit b86fd5c

5 files changed

Lines changed: 275 additions & 11 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,6 +2135,7 @@ public import Mathlib.Analysis.SpecialFunctions.Log.Deriv
21352135
public import Mathlib.Analysis.SpecialFunctions.Log.ENNRealLog
21362136
public import Mathlib.Analysis.SpecialFunctions.Log.ENNRealLogExp
21372137
public import Mathlib.Analysis.SpecialFunctions.Log.ERealExp
2138+
public import Mathlib.Analysis.SpecialFunctions.Log.InvLog
21382139
public import Mathlib.Analysis.SpecialFunctions.Log.Monotone
21392140
public import Mathlib.Analysis.SpecialFunctions.Log.NegMulLog
21402141
public import Mathlib.Analysis.SpecialFunctions.Log.PosLog
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/-
2+
Copyright (c) 2025 Alastair Irving. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Alastair Irving, Michael Stoll
5+
-/
6+
7+
module
8+
9+
public import Mathlib.Analysis.SpecialFunctions.Log.Deriv
10+
public import Mathlib.Analysis.SpecialFunctions.Pow.Asymptotics
11+
12+
/-!
13+
# Multiplicative inverse of real logarithm
14+
15+
We prove properties of the function `x ↦ (log x)⁻¹`.
16+
17+
## Main results
18+
19+
- `deriv_inv_log` gives a formula for the derivative which holds for all values.
20+
-/
21+
22+
@[expose] public section
23+
24+
namespace Real
25+
26+
open Filter
27+
28+
lemma not_differentiableAt_inv_log_zero : ¬ DifferentiableAt ℝ (fun x ↦ (log x)⁻¹) 0 := by
29+
simp only [← hasDerivAt_deriv_iff, hasDerivAt_iff_tendsto_slope_zero, zero_add, log_zero,
30+
inv_zero, sub_zero, smul_eq_mul, ← mul_inv, mul_comm _ (log _)]
31+
have H' : Tendsto (fun x ↦ log x * x) (nhdsWithin 0 (Set.Iio 0)) (nhdsWithin 0 (Set.Ioi 0)) := by
32+
refine tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within _
33+
tendsto_log_mul_self_nhdsLT_zero ?_
34+
simp only [← nhdsWithin_Ioo_eq_nhdsLT neg_one_lt_zero, Set.mem_Ioi]
35+
refine eventually_nhdsWithin_of_forall fun x ⟨hx₁, hx₂⟩ ↦ mul_pos_of_neg_of_neg ?_ hx₂
36+
refine log_neg_eq_log x ▸ log_neg ?_ ?_ <;> grind
37+
exact fun H ↦ (tendsto_nhdsWithin_mono_left (show Set.Iio (0 : ℝ) ⊆ _ by grind) H).not_tendsto
38+
(by simp) (tendsto_inv_nhdsGT_zero.comp H')
39+
40+
lemma not_continuousAt_inv_log_one : ¬ ContinuousAt (fun x ↦ (log x)⁻¹) 1 := by
41+
suffices Tendsto (fun x ↦ (log x)⁻¹) (nhdsWithin 1 {1}ᶜ) (Bornology.cobounded ℝ) from
42+
not_continuousAt_of_tendsto this nhdsWithin_le_nhds (Metric.disjoint_nhds_cobounded _)
43+
have H := HasDerivAt.tendsto_nhdsNE (by simpa using hasDerivAt_log one_ne_zero) one_ne_zero
44+
exact tendsto_inv₀_nhdsNE_zero.comp <| log_one ▸ H
45+
46+
lemma not_continuousAt_inv_log_neg_one : ¬ ContinuousAt (fun x ↦ (log x)⁻¹) (-1) := by
47+
refine fun H ↦ not_continuousAt_inv_log_one ?_
48+
simpa only [log_neg_eq_log] using ContinuousAt.comp' H continuousAt_neg
49+
50+
theorem deriv_inv_log {x : ℝ} :
51+
deriv (fun x ↦ (log x)⁻¹) x = -x⁻¹ / (log x ^ 2) := by
52+
rcases eq_or_ne x 0 with rfl | h0
53+
· simpa using deriv_zero_of_not_differentiableAt not_differentiableAt_inv_log_zero
54+
rcases eq_or_ne x 1 with rfl | h1
55+
· simpa using deriv_zero_of_not_differentiableAt <|
56+
mt DifferentiableAt.continuousAt not_continuousAt_inv_log_one
57+
rcases eq_or_ne x (-1) with rfl | h2
58+
· simpa using deriv_zero_of_not_differentiableAt <|
59+
mt DifferentiableAt.continuousAt not_continuousAt_inv_log_neg_one
60+
simp_all
61+
62+
end Real

Mathlib/Computability/AkraBazzi/SumTransform.lean

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ public import Mathlib.Analysis.Calculus.Deriv.Inv
1010
public import Mathlib.Analysis.SpecialFunctions.Pow.Continuity
1111
public import Mathlib.Analysis.SpecialFunctions.Log.Deriv
1212

13+
import Mathlib.Analysis.SpecialFunctions.Log.InvLog
14+
1315
/-!
1416
# Akra-Bazzi theorem: the sum transform
1517
@@ -353,16 +355,16 @@ lemma differentiableAt_one_add_smoothingFn {x : ℝ} (hx : 1 < x) :
353355
lemma differentiableOn_one_add_smoothingFn : DifferentiableOn ℝ (fun z => 1 + ε z) (Set.Ioi 1) :=
354356
fun _ hx => (differentiableAt_one_add_smoothingFn hx).differentiableWithinAt
355357

356-
lemma deriv_smoothingFn {x : ℝ} (hx : 1 < x) : deriv ε x = -x⁻¹ / (log x ^ 2) := by
357-
have : log x ≠ 0 := Real.log_ne_zero_of_pos_of_ne_one (by positivity) (ne_of_gt hx)
358-
change deriv (fun z => 1 / log z) x = -x⁻¹ / (log x ^ 2)
359-
rw [deriv_fun_div] <;> aesop
358+
lemma deriv_smoothingFn {x : ℝ} : deriv ε x = -x⁻¹ / (log x ^ 2) := by
359+
unfold smoothingFn
360+
simp_rw [one_div]
361+
apply deriv_inv_log
360362

361363
lemma isLittleO_deriv_smoothingFn : deriv ε =o[atTop] fun x => x⁻¹ :=
362364
calc deriv ε
363365
_ =ᶠ[atTop] fun x => -x⁻¹ / (log x ^ 2) := by
364-
filter_upwards [eventually_gt_atTop 1] with x hx
365-
rw [deriv_smoothingFn hx]
366+
filter_upwards with x
367+
rw [deriv_smoothingFn]
366368
_ = fun x => (-x * log x ^ 2)⁻¹ := by
367369
simp_rw [neg_div, div_eq_mul_inv, ← mul_inv, neg_inv, neg_mul]
368370
_ =o[atTop] fun x => (x * 1)⁻¹ := by
@@ -381,17 +383,17 @@ lemma eventually_deriv_one_sub_smoothingFn :
381383
_ =ᶠ[atTop] -(deriv ε) := by
382384
filter_upwards [eventually_gt_atTop 1] with x hx; rw [deriv_fun_sub] <;> aesop
383385
_ =ᶠ[atTop] fun x => x⁻¹ / (log x ^ 2) := by
384-
filter_upwards [eventually_gt_atTop 1] with x hx
385-
simp [deriv_smoothingFn hx, neg_div]
386+
filter_upwards with x
387+
simp [deriv_smoothingFn, neg_div]
386388

387389
lemma eventually_deriv_one_add_smoothingFn :
388390
deriv (fun x => 1 + ε x) =ᶠ[atTop] fun x => -x⁻¹ / (log x ^ 2) :=
389391
calc deriv (fun x => 1 + ε x)
390392
_ =ᶠ[atTop] deriv ε := by
391393
filter_upwards [eventually_gt_atTop 1] with x hx; rw [deriv_fun_add] <;> aesop
392394
_ =ᶠ[atTop] fun x => -x⁻¹ / (log x ^ 2) := by
393-
filter_upwards [eventually_gt_atTop 1] with x hx
394-
simp [deriv_smoothingFn hx]
395+
filter_upwards with x
396+
simp [deriv_smoothingFn]
395397

396398
lemma isLittleO_deriv_one_sub_smoothingFn :
397399
deriv (fun x => 1 - ε x) =o[atTop] fun (x : ℝ) => x⁻¹ :=

Mathlib/NumberTheory/AbelSummation.lean

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,30 @@ theorem sum_mul_eq_sub_integral_mul₀' (hc : c 0 = 0) (m : ℕ)
235235
convert sum_mul_eq_sub_integral_mul₀ c hc m hf_diff hf_int
236236
all_goals rw [Nat.floor_natCast]
237237

238+
/-- Specialized version of `sum_mul_eq_sub_integral_mul` when `c 0 = c 1 = 0`. -/
239+
theorem sum_mul_eq_sub_integral_mul₁ (hc : c 0 = 0) (hc1 : c 1 = 0) (b : ℝ)
240+
(hf_diff : ∀ t ∈ Set.Icc 2 b, DifferentiableAt ℝ f t)
241+
(hf_int : IntegrableOn (deriv f) (Set.Icc 2 b)) :
242+
∑ k ∈ Icc 0 ⌊b⌋₊, f k * c k =
243+
f b * (∑ k ∈ Icc 0 ⌊b⌋₊, c k) - ∫ t in Set.Ioc 2 b, deriv f t * ∑ k ∈ Icc 0 ⌊t⌋₊, c k := by
244+
by_cases! hb : b < 2
245+
· -- Easy case, everything is 0
246+
have H₁ : ∀ n ∈ Icc 0 ⌊b⌋₊, c n = 0 := by grind [(Nat.floor_lt' two_ne_zero).mpr hb]
247+
have H₂ : ∀ n ∈ Icc 0 ⌊b⌋₊, f n * c n = 0 := by grind
248+
simp [sum_eq_zero H₁, sum_eq_zero H₂, Set.Ioc_eq_empty_of_le hb.le]
249+
-- Split off the first two terms of the sum
250+
have : 2 ≤ ⌊b⌋₊ := Nat.le_floor hb
251+
have H : ∑ k ∈ Icc 0 ⌊b⌋₊, f ↑k * c k = f (2 :) * c 2 + ∑ k ∈ Ioc 2 ⌊b⌋₊, f ↑k * c k := by
252+
rw [add_sum_Ioc_eq_sum_Icc (f := fun (k : ℕ) ↦ f k * c k) this,
253+
show Icc 0 ⌊b⌋₊ = {0, 1} ∪ Icc 2 ⌊b⌋₊ by grind]
254+
exact sum_union_eq_right fun k hk hk' ↦ by grind
255+
rw [H]
256+
-- Apply Abel summation to the remainder
257+
nth_rewrite 3 [show 2 = ⌊(2 : ℝ)⌋₊ by simp]
258+
rw [sum_mul_eq_sub_sub_integral_mul c zero_le_two hb hf_diff hf_int]
259+
simp [show Icc 0 2 = {0, 1, 2} by rfl, hc, hc1]
260+
grind
261+
238262
end specialversions
239263

240264
section limit

Mathlib/NumberTheory/Chebyshev.lean

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ Authors: Alastair Irving, Terry Tao, Ruben Van de Velde
55
-/
66
module
77

8+
public import Mathlib.Algebra.Order.Floor.Semifield
89
public import Mathlib.Analysis.SpecialFunctions.Pow.Real
10+
public import Mathlib.MeasureTheory.Integral.IntervalIntegral.Basic
11+
public import Mathlib.NumberTheory.AbelSummation
12+
public import Mathlib.NumberTheory.PrimeCounting
913
public import Mathlib.NumberTheory.Primorial
1014
public import Mathlib.NumberTheory.ArithmeticFunction.VonMangoldt
1115

16+
import Mathlib.Analysis.SpecialFunctions.Log.InvLog
1217
import Mathlib.Data.Nat.Prime.Int
1318

1419
/-!
@@ -28,6 +33,8 @@ These give logarithmically weighted sums of primes and prime powers.
2833
- `Chebyshev.theta_le_log4_mul_x` gives Chebyshev's upper bound on `θ`
2934
- `Chebyshev.psi_eq_sum_theta` and `Chebyshev.psi_eq_theta_add_sum_theta` relate `psi` to `theta`.
3035
- `Chebyshev.psi_le_const_mul_self` gives Chebyshev's upper bound on `ψ`.
36+
- `Chebyshev.primeCounting_eq_theta_div_log_add_integral` relates the prime counting function to `θ`
37+
- `Chebyshev.eventually_primeCounting_le` gives an upper bound on the prime counting function.
3138
3239
## Notation
3340
@@ -40,14 +47,14 @@ Parts of this file were upstreamed from the PrimeNumberTheoremAnd project by Kon
4047
4148
## TODOS
4249
43-
- Upstream the results relating `theta` and `psi` to the prime counting function.
4450
- Prove Chebyshev's lower bound.
4551
-/
4652
@[expose] public section
4753

4854
open Nat hiding log
4955
open Finset Real
5056
open ArithmeticFunction hiding log
57+
open scoped Nat.Prime
5158

5259
namespace Chebyshev
5360

@@ -269,4 +276,172 @@ theorem psi_sub_theta_eq_sum_not_prime (x : ℝ) :
269276
· simp [h, vonMangoldt_apply_prime]
270277
· simp
271278

279+
section PrimeCounting
280+
281+
/-! ## Relation to prime counting
282+
283+
We relate `θ` to the prime counting function `π`.-/
284+
285+
open Asymptotics Filter MeasureTheory
286+
287+
/-- Integrability for the integral in `Chebyshev.primeCounting_eq_theta_div_log_add_integral`. -/
288+
theorem integrableOn_theta_div_id_mul_log_sq (x : ℝ) :
289+
IntegrableOn (fun t ↦ θ t / (t * log t ^ 2)) (Set.Icc 2 x) volume := by
290+
conv => arg 1; ext; rw [theta, div_eq_mul_one_div, mul_comm, sum_filter]
291+
refine integrableOn_mul_sum_Icc _ (by norm_num) <| ContinuousOn.integrableOn_Icc fun x hx ↦
292+
ContinuousAt.continuousWithinAt ?_
293+
have : x ≠ 0 := by linarith [hx.1]
294+
have : x * log x ^ 20 := mul_ne_zero this <| by simp; grind
295+
fun_prop (disch := assumption)
296+
297+
/-- Expresses the prime counting function `π` in terms of `θ` by using Abel summation. -/
298+
theorem primeCounting_eq_theta_div_log_add_integral {x : ℝ} (hx : 2 ≤ x) :
299+
π ⌊x⌋₊ = θ x / log x + ∫ t in 2..x, θ t / (t * log t ^ 2) := by
300+
-- Rewrite in a form to which Abel summation can be applied
301+
simp only [primeCounting, primeCounting', count_eq_card_filter_range]
302+
rw [card_eq_sum_ones, range_succ_eq_Icc_zero, sum_filter]
303+
push_cast
304+
let a : ℕ → ℝ := Set.indicator (setOf Nat.Prime) (fun n ↦ log n)
305+
trans ∑ n ∈ Icc 0 ⌊x⌋₊, (log n)⁻¹ * a n
306+
· refine sum_congr rfl fun n hn ↦ ?_
307+
split_ifs with h
308+
· have : log n ≠ 0 := log_ne_zero_of_pos_of_ne_one (mod_cast h.pos) (mod_cast h.ne_one)
309+
simp [a, h, field]
310+
· simp [a, h]
311+
rw [sum_mul_eq_sub_integral_mul₁ a (f := fun n ↦ (log n)⁻¹) (by simp [a]) (by simp [a]),
312+
← intervalIntegral.integral_of_le hx]
313+
· -- Rewrite the derivative inside the intigral
314+
have int_deriv (f : ℝ → ℝ) :
315+
∫ u in 2..x, deriv (fun x ↦ (log x)⁻¹) u * f u =
316+
∫ u in 2..x, f u * -(u * log u ^ 2)⁻¹ :=
317+
intervalIntegral.integral_congr fun u _ ↦ by simp [deriv_inv_log, field]
318+
simp [int_deriv, a, Set.indicator_apply, sum_filter, theta_eq_sum_Icc]
319+
grind
320+
· -- Differentiability
321+
intro z ⟨hz, _⟩
322+
have : z ≠ 0 := by linarith
323+
have : log z ≠ 0 := by apply log_ne_zero_of_pos_of_ne_one <;> linarith
324+
fun_prop (disch := assumption)
325+
· -- Integrability of the derivative
326+
refine ContinuousOn.integrableOn_Icc fun z ⟨hz, _⟩ ↦ ContinuousWithinAt.congr ?_
327+
(fun _ _ ↦ deriv_inv_log) deriv_inv_log
328+
have hz₀ : z ≠ 0 := by linarith
329+
have : log z ^ 20 := by
330+
refine pow_ne_zero 2 <| log_ne_zero_of_pos_of_ne_one ?_ ?_ <;> linarith
331+
exact ContinuousAt.continuousWithinAt <| by fun_prop (disch := assumption)
332+
333+
theorem intervalIntegrable_one_div_log_sq {a b : ℝ} (one_lt_a : 1 < a) (one_lt_b : 1 < b) :
334+
IntervalIntegrable (fun x ↦ 1 / log x ^ 2) MeasureTheory.volume a b := by
335+
refine ContinuousOn.intervalIntegrable fun x hx ↦ ContinuousAt.continuousWithinAt ?_
336+
rw [Set.mem_uIcc] at hx
337+
have : x ≠ 0 := by grind
338+
have : log x ^ 20 := pow_ne_zero _ (log_ne_zero.mpr (by grind))
339+
fun_prop (disch := assumption)
340+
341+
/- Simple bound on the integral from monotonicity.
342+
We will bound the integral on 2..x by splitting into two intervals and using this result on both. -/
343+
private theorem integral_1_div_log_sq_le {a b : ℝ} (hab : a ≤ b) (one_lt : 1 < a) :
344+
∫ x in a..b, 1 / log x ^ 2 ≤ (b - a) / log a ^ 2 := by
345+
calc
346+
_ ≤ ∫ x in a..b, 1 / log a ^ 2 := by
347+
refine intervalIntegral.integral_mono_on hab ?_ (by simp) fun x ⟨hx, _⟩ ↦ by gcongr <;> bound
348+
apply intervalIntegrable_one_div_log_sq <;> linarith
349+
_ ≤ _ := by simp [field]
350+
351+
/- Explicit integral bound, we expose a BigO version below since the constants and lower order term
352+
aren't very convenient. -/
353+
private theorem integral_one_div_log_sq_le_explicit {x : ℝ} (hx : 4 ≤ x) :
354+
∫ t in 2..x, 1 / log t ^ 24 * x / (log x) ^ 2 + x.sqrt / log 2 ^ 2 := by
355+
have two_le_sqrt : 2 ≤ x.sqrt := Real.le_sqrt_of_sq_le <| by norm_num [hx]
356+
have sqrt_le_x : x.sqrt ≤ x := sqrt_le_left (by linarith) |>.mpr (by bound)
357+
rw [← intervalIntegral.integral_add_adjacent_intervals (b := x.sqrt)]
358+
· grw [integral_1_div_log_sq_le two_le_sqrt (by linarith),
359+
integral_1_div_log_sq_le sqrt_le_x (by linarith)]
360+
rw [log_sqrt (by linarith), add_comm, div_pow, ← div_mul, mul_comm, mul_div_assoc]
361+
norm_num
362+
gcongr <;> linarith
363+
all_goals apply intervalIntegrable_one_div_log_sq <;> linarith
364+
365+
-- Somewhat arbitrary bound which we use to estimate the second term.
366+
private theorem sqrt_isLittleO :
367+
Real.sqrt =o[atTop] (fun x ↦ x / log x ^ 2) := by
368+
apply isLittleO_mul_iff_isLittleO_div _|>.mp
369+
· conv => arg 2; ext; rw [mul_comm]
370+
apply isLittleO_mul_iff_isLittleO_div _|>.mpr
371+
· simp_rw [div_sqrt, sqrt_eq_rpow, ← rpow_two]
372+
apply isLittleO_log_rpow_rpow_atTop _ (by norm_num)
373+
filter_upwards [eventually_gt_atTop 0] with x hx using sqrt_ne_zero'.mpr hx
374+
filter_upwards [eventually_gt_atTop 1] with x hx
375+
apply pow_ne_zero _ <| log_ne_zero.mpr ⟨_, _, _⟩ <;> linarith
376+
377+
theorem integral_one_div_log_sq_isBigO :
378+
(fun x ↦ ∫ t in 2..x, 1 / log t ^ 2) =O[atTop] (fun x ↦ x / log x ^ 2) := by
379+
trans (fun x ↦ 4 * x / log x ^ 2 + √x / log 2 ^ 2)
380+
· apply IsBigO.of_bound'
381+
filter_upwards [eventually_ge_atTop 4] with x hx
382+
apply le_trans <| intervalIntegral.abs_integral_le_integral_abs (by linarith)
383+
rw [intervalIntegral.integral_congr (g := (fun t ↦ 1 / log t ^ 2))]
384+
· grw [integral_one_div_log_sq_le_explicit hx, norm_of_nonneg]
385+
positivity
386+
intro t ht
387+
simp
388+
refine IsBigO.add ?_ ?_
389+
· simp_rw [mul_div_assoc]
390+
apply isBigO_const_mul_self
391+
conv => arg 2; ext; rw [← mul_one_div, mul_comm]
392+
apply IsBigO.const_mul_left sqrt_isLittleO.isBigO
393+
394+
/-- Bound on the integral in `Chebyshev.primeCounting_eq_theta_div_log_add_integral`. -/
395+
theorem integral_theta_div_log_sq_isBigO :
396+
(fun x ↦ ∫ t in 2..x, θ t / (t * log t ^ 2)) =O[atTop] (fun x ↦ x / log x ^ 2) := by
397+
refine (IsBigO.of_bound (log 4) ?_).trans integral_one_div_log_sq_isBigO
398+
filter_upwards [eventually_ge_atTop 4] with x hx
399+
simp_rw [norm_eq_abs]
400+
calc |∫ (t : ℝ) in 2..x, θ t / (t * log t ^ 2)|
401+
_ ≤ ∫ (x : ℝ) in 2..x, |θ x / (x * log x ^ 2)| :=
402+
intervalIntegral.abs_integral_le_integral_abs (by linarith)
403+
_ ≤ ∫ (x : ℝ) in 2..x, log 4 * (1 / log x ^ 2) :=
404+
intervalIntegral.integral_mono_on (by linarith) ?hf ?hg fun t ⟨ht, _⟩ ↦ ?hh
405+
_ = log 4 * |∫ (t : ℝ) in 2..x, 1 / log t ^ 2| := by
406+
rw [intervalIntegral.integral_const_mul, abs_of_nonneg]
407+
exact intervalIntegral.integral_nonneg (by linarith) fun u _ ↦ by positivity
408+
case hf =>
409+
refine (intervalIntegrable_iff.mpr ?_).abs
410+
rw [Set.uIoc_of_le (by linarith), ← integrableOn_Icc_iff_integrableOn_Ioc]
411+
exact integrableOn_theta_div_id_mul_log_sq x
412+
case hg =>
413+
refine (intervalIntegrable_one_div_log_sq ?_ ?_).const_mul _ <;> linarith
414+
case hh =>
415+
calc |θ t / (t * log t ^ 2)|
416+
_ = θ t / (t * log t ^ 2) := abs_of_nonneg (by positivity [theta_nonneg t])
417+
_ ≤ log 4 * t / (t * log t ^ 2) := by grw [theta_le_log4_mul_x (by linarith)]
418+
_ = log 4 * (1 / log t ^ 2) := by field
419+
420+
theorem integral_theta_div_log_sq_isLittleO :
421+
(fun x ↦ ∫ t in 2..x, θ t / (t * log t ^ 2)) =o[atTop] (fun x ↦ x / log x) := by
422+
refine integral_theta_div_log_sq_isBigO.trans_isLittleO ?_
423+
refine isLittleO_iff_tendsto' (by simp) |>.mpr ?_
424+
refine Tendsto.congr' (f₁ := fun x ↦ (log x)⁻¹) ?_ tendsto_log_atTop.inv_tendsto_atTop
425+
filter_upwards [eventually_gt_atTop 0] with x hx
426+
field
427+
428+
theorem primeCounting_sub_theta_div_log_isBigO :
429+
(fun x ↦ π ⌊x⌋₊ - θ x / log x) =O[atTop] (fun x ↦ x / log x ^ 2) := by
430+
apply integral_theta_div_log_sq_isBigO.congr' _ (by rfl)
431+
filter_upwards [eventually_ge_atTop 2] with x hx
432+
rw [primeCounting_eq_theta_div_log_add_integral hx]
433+
simp
434+
435+
/-- Chebyshev's upper bound on the prime counting function -/
436+
theorem eventually_primeCounting_le {ε : ℝ} (εpos : 0 < ε) :
437+
∀ᶠ x in atTop, π ⌊x⌋₊ ≤ (log 4 + ε) * x / log x := by
438+
have := integral_theta_div_log_sq_isLittleO.bound εpos
439+
filter_upwards [eventually_ge_atTop 2, this] with x hx hx2
440+
rw [primeCounting_eq_theta_div_log_add_integral hx, add_mul, add_div]
441+
have hl : 0 ≤ log x := by bound
442+
rw [norm_of_nonneg (show 0 ≤ x / log x by bound), ← mul_div_assoc] at hx2
443+
grw [theta_le_log4_mul_x (by linarith), ← hx2]
444+
grind [le_norm_self]
445+
446+
end PrimeCounting
272447
end Chebyshev

0 commit comments

Comments
 (0)