analysis.special_functions.stirling
⟷
Mathlib.Analysis.SpecialFunctions.Stirling
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -134,7 +134,7 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
((1 / (2 * n.succ + 1)) ^ 2 / (1 - (1 / (2 * n.succ + 1)) ^ 2)) :=
by
have := (hasSum_geometric_of_lt_one h_nonneg _).hMul_left ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2)
- · simp_rw [← pow_succ] at this
+ · simp_rw [← pow_succ'] at this
exact this
rw [one_div, inv_pow]
exact inv_lt_one (one_lt_pow ((lt_add_iff_pos_left 1).mpr <| by positivity) two_ne_zero)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -134,7 +134,7 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
((1 / (2 * n.succ + 1)) ^ 2 / (1 - (1 / (2 * n.succ + 1)) ^ 2)) :=
by
have := (hasSum_geometric_of_lt_one h_nonneg _).hMul_left ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2)
- · simp_rw [← pow_succ] at this
+ · simp_rw [← pow_succ] at this
exact this
rw [one_div, inv_pow]
exact inv_lt_one (one_lt_pow ((lt_add_iff_pos_left 1).mpr <| by positivity) two_ne_zero)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -133,7 +133,7 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
HasSum (fun k : ℕ => ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2) ^ k.succ)
((1 / (2 * n.succ + 1)) ^ 2 / (1 - (1 / (2 * n.succ + 1)) ^ 2)) :=
by
- have := (hasSum_geometric_of_lt_1 h_nonneg _).hMul_left ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2)
+ have := (hasSum_geometric_of_lt_one h_nonneg _).hMul_left ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2)
· simp_rw [← pow_succ] at this
exact this
rw [one_div, inv_pow]
@@ -262,7 +262,7 @@ theorem tendsto_self_div_two_mul_self_add_one :
skip
rw [one_div, ← add_zero (2 : ℝ)]
refine'
- (((tendsto_const_div_atTop_nhds_0_nat 1).const_add (2 : ℝ)).inv₀
+ (((tendsto_const_div_atTop_nhds_zero_nat 1).const_add (2 : ℝ)).inv₀
((add_zero (2 : ℝ)).symm ▸ two_ne_zero)).congr'
(eventually_at_top.mpr ⟨1, fun n hn => _⟩)
rw [add_div' (1 : ℝ) 2 n (cast_ne_zero.mpr (one_le_iff_ne_zero.mp hn)), inv_div]
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -229,7 +229,7 @@ theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a
#print Stirling.stirlingSeq'_antitone /-
/-- The sequence `stirling_seq ∘ succ` is monotone decreasing -/
theorem stirlingSeq'_antitone : Antitone (stirlingSeq ∘ succ) := fun n m h =>
- (log_le_log (stirlingSeq'_pos m) (stirlingSeq'_pos n)).mp (log_stirlingSeq'_antitone h)
+ (log_le_log_iff (stirlingSeq'_pos m) (stirlingSeq'_pos n)).mp (log_stirlingSeq'_antitone h)
#align stirling.stirling_seq'_antitone Stirling.stirlingSeq'_antitone
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -220,7 +220,7 @@ theorem stirlingSeq'_pos (n : ℕ) : 0 < stirlingSeq n.succ := by unfold stirlin
theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a ≤ stirlingSeq n.succ :=
by
cases' log_stirling_seq_bounded_by_constant with c h
- refine' ⟨exp c, exp_pos _, fun n => _⟩
+ refine' ⟨NormedSpace.exp c, exp_pos _, fun n => _⟩
rw [← le_log_iff_exp_le (stirling_seq'_pos n)]
exact h n
#align stirling.stirling_seq'_bounded_by_pos_constant Stirling.stirlingSeq'_bounded_by_pos_constant
@@ -281,7 +281,7 @@ theorem stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq (n : ℕ) (hn : n ≠ 0)
rw [sq_sqrt, sq_sqrt]
any_goals positivity
have : (n : ℝ) ≠ 0 := cast_ne_zero.mpr hn
- have : exp 1 ≠ 0 := exp_ne_zero 1
+ have : NormedSpace.exp 1 ≠ 0 := exp_ne_zero 1
have : ((2 * n)! : ℝ) ≠ 0 := cast_ne_zero.mpr (factorial_ne_zero (2 * n))
have : 2 * (n : ℝ) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * n)
field_simp
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,8 +3,8 @@ Copyright (c) 2022. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Moritz Firsching, Fabian Kruse, Nikolas Kuhn
-/
-import Mathbin.Analysis.PSeries
-import Mathbin.Data.Real.Pi.Wallis
+import Analysis.PSeries
+import Data.Real.Pi.Wallis
#align_import analysis.special_functions.stirling from "leanprover-community/mathlib"@"fd4551cfe4b7484b81c2c9ba3405edae27659676"
mathlib commit https://github.com/leanprover-community/mathlib/commit/442a83d738cb208d3600056c489be16900ba701d
@@ -71,7 +71,6 @@ theorem stirlingSeq_one : stirlingSeq 1 = exp 1 / sqrt 2 := by
#align stirling.stirling_seq_one Stirling.stirlingSeq_one
-/
-#print Stirling.log_stirlingSeq_formula /-
/-- We have the expression
`log (stirling_seq (n + 1)) = log(n + 1)! - 1 / 2 * log(2 * n) - n * log ((n + 1) / e)`.
-/
@@ -82,8 +81,7 @@ theorem log_stirlingSeq_formula (n : ℕ) :
rw [stirling_seq, log_div, log_mul, sqrt_eq_rpow, log_rpow, Real.log_pow, tsub_tsub] <;>
try apply ne_of_gt <;>
positivity
-#align stirling.log_stirling_seq_formula Stirling.log_stirlingSeq_formula
--/
+#align stirling.log_stirling_seq_formula Stirling.log_stirlingSeq_formulaₓ
#print Stirling.log_stirlingSeq_diff_hasSum /-
-- TODO: Make `positivity` handle `≠ 0` goals
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -96,7 +96,7 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
by
change HasSum ((fun b : ℕ => 1 / (2 * (b : ℝ) + 1) * ((1 / (2 * m.succ + 1)) ^ 2) ^ b) ∘ succ) _
refine' (hasSum_nat_add_iff 1).mpr _
- convert (has_sum_log_one_add_inv <| cast_pos.mpr (succ_pos m)).mul_left ((m.succ : ℝ) + 1 / 2)
+ convert (has_sum_log_one_add_inv <| cast_pos.mpr (succ_pos m)).hMul_left ((m.succ : ℝ) + 1 / 2)
· ext k
rw [← pow_mul, pow_add]
push_cast
@@ -135,7 +135,7 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
HasSum (fun k : ℕ => ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2) ^ k.succ)
((1 / (2 * n.succ + 1)) ^ 2 / (1 - (1 / (2 * n.succ + 1)) ^ 2)) :=
by
- have := (hasSum_geometric_of_lt_1 h_nonneg _).mul_left ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2)
+ have := (hasSum_geometric_of_lt_1 h_nonneg _).hMul_left ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2)
· simp_rw [← pow_succ] at this
exact this
rw [one_div, inv_pow]
mathlib commit https://github.com/leanprover-community/mathlib/commit/63721b2c3eba6c325ecf8ae8cca27155a4f6306f
@@ -182,7 +182,7 @@ theorem log_stirlingSeq_bounded_aux :
∃ c : ℝ, ∀ n : ℕ, log (stirlingSeq 1) - log (stirlingSeq n.succ) ≤ c :=
by
let d := ∑' k : ℕ, (1 : ℝ) / k.succ ^ 2
- use (1 / 4 * d : ℝ)
+ use(1 / 4 * d : ℝ)
let log_stirling_seq' : ℕ → ℝ := fun k => log (stirling_seq k.succ)
intro n
have h₁ : ∀ k, log_stirling_seq' k - log_stirling_seq' (k + 1) ≤ 1 / 4 * (1 / k.succ ^ 2) := by
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,15 +2,12 @@
Copyright (c) 2022. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Moritz Firsching, Fabian Kruse, Nikolas Kuhn
-
-! This file was ported from Lean 3 source module analysis.special_functions.stirling
-! leanprover-community/mathlib commit fd4551cfe4b7484b81c2c9ba3405edae27659676
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Analysis.PSeries
import Mathbin.Data.Real.Pi.Wallis
+#align_import analysis.special_functions.stirling from "leanprover-community/mathlib"@"fd4551cfe4b7484b81c2c9ba3405edae27659676"
+
/-!
# Stirling's formula
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -59,17 +59,22 @@ noncomputable def stirlingSeq (n : ℕ) : ℝ :=
#align stirling.stirling_seq Stirling.stirlingSeq
-/
+#print Stirling.stirlingSeq_zero /-
@[simp]
theorem stirlingSeq_zero : stirlingSeq 0 = 0 := by
rw [stirling_seq, cast_zero, MulZeroClass.mul_zero, Real.sqrt_zero, MulZeroClass.zero_mul,
div_zero]
#align stirling.stirling_seq_zero Stirling.stirlingSeq_zero
+-/
+#print Stirling.stirlingSeq_one /-
@[simp]
theorem stirlingSeq_one : stirlingSeq 1 = exp 1 / sqrt 2 := by
rw [stirling_seq, pow_one, factorial_one, cast_one, mul_one, mul_one_div, one_div_div]
#align stirling.stirling_seq_one Stirling.stirlingSeq_one
+-/
+#print Stirling.log_stirlingSeq_formula /-
/-- We have the expression
`log (stirling_seq (n + 1)) = log(n + 1)! - 1 / 2 * log(2 * n) - n * log ((n + 1) / e)`.
-/
@@ -81,7 +86,9 @@ theorem log_stirlingSeq_formula (n : ℕ) :
try apply ne_of_gt <;>
positivity
#align stirling.log_stirling_seq_formula Stirling.log_stirlingSeq_formula
+-/
+#print Stirling.log_stirlingSeq_diff_hasSum /-
-- TODO: Make `positivity` handle `≠ 0` goals
/-- The sequence `log (stirling_seq (m + 1)) - log (stirling_seq (m + 2))` has the series expansion
`∑ 1 / (2 * (k + 1) + 1) * (1 / 2 * (m + 1) + 1)^(2 * (k + 1))`
@@ -109,6 +116,7 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
sum_singleton, h]
ring
#align stirling.log_stirling_seq_diff_has_sum Stirling.log_stirlingSeq_diff_hasSum
+-/
#print Stirling.log_stirlingSeq'_antitone /-
/-- The sequence `log ∘ stirling_seq ∘ succ` is monotone decreasing -/
@@ -118,6 +126,7 @@ theorem log_stirlingSeq'_antitone : Antitone (Real.log ∘ stirlingSeq ∘ succ)
#align stirling.log_stirling_seq'_antitone Stirling.log_stirlingSeq'_antitone
-/
+#print Stirling.log_stirlingSeq_diff_le_geo_sum /-
/-- We have a bound for successive elements in the sequence `log (stirling_seq k)`.
-/
theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
@@ -144,7 +153,9 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
exact inv_le_one (le_add_of_nonneg_left <| by positivity)
exact hasSum_le hab (log_stirling_seq_diff_has_sum n) g
#align stirling.log_stirling_seq_diff_le_geo_sum Stirling.log_stirlingSeq_diff_le_geo_sum
+-/
+#print Stirling.log_stirlingSeq_sub_log_stirlingSeq_succ /-
/-- We have the bound `log (stirling_seq n) - log (stirling_seq (n+1))` ≤ 1/(4 n^2)
-/
theorem log_stirlingSeq_sub_log_stirlingSeq_succ (n : ℕ) :
@@ -166,7 +177,9 @@ theorem log_stirlingSeq_sub_log_stirlingSeq_succ (n : ℕ) :
norm_cast
linarith
#align stirling.log_stirling_seq_sub_log_stirling_seq_succ Stirling.log_stirlingSeq_sub_log_stirlingSeq_succ
+-/
+#print Stirling.log_stirlingSeq_bounded_aux /-
/-- For any `n`, we have `log_stirling_seq 1 - log_stirling_seq n ≤ 1/4 * ∑' 1/k^2` -/
theorem log_stirlingSeq_bounded_aux :
∃ c : ℝ, ∀ n : ℕ, log (stirlingSeq 1) - log (stirlingSeq n.succ) ≤ c :=
@@ -189,18 +202,24 @@ theorem log_stirlingSeq_bounded_aux :
_ = 1 / 4 * ∑ k in range n, 1 / k.succ ^ 2 := by rw [mul_sum]
_ ≤ 1 / 4 * d := mul_le_mul_of_nonneg_left h₂ <| by positivity
#align stirling.log_stirling_seq_bounded_aux Stirling.log_stirlingSeq_bounded_aux
+-/
+#print Stirling.log_stirlingSeq_bounded_by_constant /-
/-- The sequence `log_stirling_seq` is bounded below for `n ≥ 1`. -/
theorem log_stirlingSeq_bounded_by_constant : ∃ c, ∀ n : ℕ, c ≤ log (stirlingSeq n.succ) :=
by
obtain ⟨d, h⟩ := log_stirling_seq_bounded_aux
exact ⟨log (stirling_seq 1) - d, fun n => sub_le_comm.mp (h n)⟩
#align stirling.log_stirling_seq_bounded_by_constant Stirling.log_stirlingSeq_bounded_by_constant
+-/
+#print Stirling.stirlingSeq'_pos /-
/-- The sequence `stirling_seq` is positive for `n > 0` -/
theorem stirlingSeq'_pos (n : ℕ) : 0 < stirlingSeq n.succ := by unfold stirling_seq; positivity
#align stirling.stirling_seq'_pos Stirling.stirlingSeq'_pos
+-/
+#print Stirling.stirlingSeq'_bounded_by_pos_constant /-
/-- The sequence `stirling_seq` has a positive lower bound.
-/
theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a ≤ stirlingSeq n.succ :=
@@ -210,6 +229,7 @@ theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a
rw [← le_log_iff_exp_le (stirling_seq'_pos n)]
exact h n
#align stirling.stirling_seq'_bounded_by_pos_constant Stirling.stirlingSeq'_bounded_by_pos_constant
+-/
#print Stirling.stirlingSeq'_antitone /-
/-- The sequence `stirling_seq ∘ succ` is monotone decreasing -/
@@ -218,6 +238,7 @@ theorem stirlingSeq'_antitone : Antitone (stirlingSeq ∘ succ) := fun n m h =>
#align stirling.stirling_seq'_antitone Stirling.stirlingSeq'_antitone
-/
+#print Stirling.stirlingSeq_has_pos_limit_a /-
/-- The limit `a` of the sequence `stirling_seq` satisfies `0 < a` -/
theorem stirlingSeq_has_pos_limit_a : ∃ a : ℝ, 0 < a ∧ Tendsto stirlingSeq atTop (𝓝 a) :=
by
@@ -227,6 +248,7 @@ theorem stirlingSeq_has_pos_limit_a : ∃ a : ℝ, 0 < a ∧ Tendsto stirlingSeq
rw [← Filter.tendsto_add_atTop_iff_nat 1]
exact tendsto_atTop_ciInf stirling_seq'_antitone ⟨x, hx'⟩
#align stirling.stirling_seq_has_pos_limit_a Stirling.stirlingSeq_has_pos_limit_a
+-/
/-!
### Part 2
@@ -234,6 +256,7 @@ theorem stirlingSeq_has_pos_limit_a : ∃ a : ℝ, 0 < a ∧ Tendsto stirlingSeq
-/
+#print Stirling.tendsto_self_div_two_mul_self_add_one /-
/-- The sequence `n / (2 * n + 1)` tends to `1/2` -/
theorem tendsto_self_div_two_mul_self_add_one :
Tendsto (fun n : ℕ => (n : ℝ) / (2 * n + 1)) atTop (𝓝 (1 / 2)) :=
@@ -249,7 +272,9 @@ theorem tendsto_self_div_two_mul_self_add_one :
(eventually_at_top.mpr ⟨1, fun n hn => _⟩)
rw [add_div' (1 : ℝ) 2 n (cast_ne_zero.mpr (one_le_iff_ne_zero.mp hn)), inv_div]
#align stirling.tendsto_self_div_two_mul_self_add_one Stirling.tendsto_self_div_two_mul_self_add_one
+-/
+#print Stirling.stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq /-
/-- For any `n ≠ 0`, we have the identity
`(stirling_seq n)^4 / (stirling_seq (2*n))^2 * (n / (2 * n + 1)) = W n`, where `W n` is the
`n`-th partial product of Wallis' formula for `π / 2`. -/
@@ -268,7 +293,9 @@ theorem stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq (n : ℕ) (hn : n ≠ 0)
simp only [mul_pow, mul_comm 2 n, mul_comm 4 n, pow_mul]
ring
#align stirling.stirling_seq_pow_four_div_stirling_seq_pow_two_eq Stirling.stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq
+-/
+#print Stirling.second_wallis_limit /-
/-- Suppose the sequence `stirling_seq` (defined above) has the limit `a ≠ 0`.
Then the Wallis sequence `W n` has limit `a^2 / 2`.
-/
@@ -291,6 +318,7 @@ theorem second_wallis_limit (a : ℝ) (hane : a ≠ 0) (ha : Tendsto stirlingSeq
(pow_ne_zero 2 hane)).mul
tendsto_self_div_two_mul_self_add_one
#align stirling.second_wallis_limit Stirling.second_wallis_limit
+-/
#print Stirling.tendsto_stirlingSeq_sqrt_pi /-
/-- **Stirling's Formula** -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/c471da714c044131b90c133701e51b877c246677
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Moritz Firsching, Fabian Kruse, Nikolas Kuhn
! This file was ported from Lean 3 source module analysis.special_functions.stirling
-! leanprover-community/mathlib commit 2c1d8ca2812b64f88992a5294ea3dba144755cd1
+! leanprover-community/mathlib commit fd4551cfe4b7484b81c2c9ba3405edae27659676
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -14,6 +14,9 @@ import Mathbin.Data.Real.Pi.Wallis
/-!
# Stirling's formula
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file proves Stirling's formula for the factorial.
It states that $n!$ grows asymptotically like $\sqrt{2\pi n}(\frac{n}{e})^n$.
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -174,13 +174,13 @@ theorem log_stirlingSeq_bounded_aux :
intro n
have h₁ : ∀ k, log_stirling_seq' k - log_stirling_seq' (k + 1) ≤ 1 / 4 * (1 / k.succ ^ 2) := by
intro k; convert log_stirling_seq_sub_log_stirling_seq_succ k using 1; field_simp
- have h₂ : (∑ k : ℕ in range n, (1 : ℝ) / k.succ ^ 2) ≤ d :=
+ have h₂ : ∑ k : ℕ in range n, (1 : ℝ) / k.succ ^ 2 ≤ d :=
sum_le_tsum (range n) (fun k _ => by positivity)
((summable_nat_add_iff 1).mpr <| real.summable_one_div_nat_pow.mpr one_lt_two)
calc
log (stirling_seq 1) - log (stirling_seq n.succ) = log_stirling_seq' 0 - log_stirling_seq' n :=
rfl
- _ = ∑ k in range n, log_stirling_seq' k - log_stirling_seq' (k + 1) := by
+ _ = ∑ k in range n, (log_stirling_seq' k - log_stirling_seq' (k + 1)) := by
rw [← sum_range_sub' log_stirling_seq' n]
_ ≤ ∑ k in range n, 1 / 4 * (1 / k.succ ^ 2) := (sum_le_sum fun k _ => h₁ k)
_ = 1 / 4 * ∑ k in range n, 1 / k.succ ^ 2 := by rw [mul_sum]
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -47,12 +47,14 @@ namespace Stirling
-/
+#print Stirling.stirlingSeq /-
/-- Define `stirling_seq n` as $\frac{n!}{\sqrt{2n}(\frac{n}{e})^n}$.
Stirling's formula states that this sequence has limit $\sqrt(π)$.
-/
noncomputable def stirlingSeq (n : ℕ) : ℝ :=
n ! / (sqrt (2 * n) * (n / exp 1) ^ n)
#align stirling.stirling_seq Stirling.stirlingSeq
+-/
@[simp]
theorem stirlingSeq_zero : stirlingSeq 0 = 0 := by
@@ -105,11 +107,13 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
ring
#align stirling.log_stirling_seq_diff_has_sum Stirling.log_stirlingSeq_diff_hasSum
+#print Stirling.log_stirlingSeq'_antitone /-
/-- The sequence `log ∘ stirling_seq ∘ succ` is monotone decreasing -/
-theorem log_stirling_seq'_antitone : Antitone (Real.log ∘ stirlingSeq ∘ succ) :=
+theorem log_stirlingSeq'_antitone : Antitone (Real.log ∘ stirlingSeq ∘ succ) :=
antitone_nat_of_succ_le fun n =>
sub_nonneg.mp <| (log_stirlingSeq_diff_hasSum n).NonNeg fun m => by positivity
-#align stirling.log_stirling_seq'_antitone Stirling.log_stirling_seq'_antitone
+#align stirling.log_stirling_seq'_antitone Stirling.log_stirlingSeq'_antitone
+-/
/-- We have a bound for successive elements in the sequence `log (stirling_seq k)`.
-/
@@ -191,23 +195,25 @@ theorem log_stirlingSeq_bounded_by_constant : ∃ c, ∀ n : ℕ, c ≤ log (sti
#align stirling.log_stirling_seq_bounded_by_constant Stirling.log_stirlingSeq_bounded_by_constant
/-- The sequence `stirling_seq` is positive for `n > 0` -/
-theorem stirling_seq'_pos (n : ℕ) : 0 < stirlingSeq n.succ := by unfold stirling_seq; positivity
-#align stirling.stirling_seq'_pos Stirling.stirling_seq'_pos
+theorem stirlingSeq'_pos (n : ℕ) : 0 < stirlingSeq n.succ := by unfold stirling_seq; positivity
+#align stirling.stirling_seq'_pos Stirling.stirlingSeq'_pos
/-- The sequence `stirling_seq` has a positive lower bound.
-/
-theorem stirling_seq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a ≤ stirlingSeq n.succ :=
+theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a ≤ stirlingSeq n.succ :=
by
cases' log_stirling_seq_bounded_by_constant with c h
refine' ⟨exp c, exp_pos _, fun n => _⟩
rw [← le_log_iff_exp_le (stirling_seq'_pos n)]
exact h n
-#align stirling.stirling_seq'_bounded_by_pos_constant Stirling.stirling_seq'_bounded_by_pos_constant
+#align stirling.stirling_seq'_bounded_by_pos_constant Stirling.stirlingSeq'_bounded_by_pos_constant
+#print Stirling.stirlingSeq'_antitone /-
/-- The sequence `stirling_seq ∘ succ` is monotone decreasing -/
-theorem stirling_seq'_antitone : Antitone (stirlingSeq ∘ succ) := fun n m h =>
- (log_le_log (stirling_seq'_pos m) (stirling_seq'_pos n)).mp (log_stirling_seq'_antitone h)
-#align stirling.stirling_seq'_antitone Stirling.stirling_seq'_antitone
+theorem stirlingSeq'_antitone : Antitone (stirlingSeq ∘ succ) := fun n m h =>
+ (log_le_log (stirlingSeq'_pos m) (stirlingSeq'_pos n)).mp (log_stirlingSeq'_antitone h)
+#align stirling.stirling_seq'_antitone Stirling.stirlingSeq'_antitone
+-/
/-- The limit `a` of the sequence `stirling_seq` satisfies `0 < a` -/
theorem stirlingSeq_has_pos_limit_a : ∃ a : ℝ, 0 < a ∧ Tendsto stirlingSeq atTop (𝓝 a) :=
@@ -283,6 +289,7 @@ theorem second_wallis_limit (a : ℝ) (hane : a ≠ 0) (ha : Tendsto stirlingSeq
tendsto_self_div_two_mul_self_add_one
#align stirling.second_wallis_limit Stirling.second_wallis_limit
+#print Stirling.tendsto_stirlingSeq_sqrt_pi /-
/-- **Stirling's Formula** -/
theorem tendsto_stirlingSeq_sqrt_pi : Tendsto (fun n : ℕ => stirlingSeq n) atTop (𝓝 (sqrt π)) :=
by
@@ -291,6 +298,7 @@ theorem tendsto_stirlingSeq_sqrt_pi : Tendsto (fun n : ℕ => stirlingSeq n) atT
tendsto_nhds_unique wallis.tendsto_W_nhds_pi_div_two (second_wallis_limit a hapos.ne' halimit)
rwa [(div_left_inj' (two_ne_zero' ℝ)).mp hπ, sqrt_sq hapos.le]
#align stirling.tendsto_stirling_seq_sqrt_pi Stirling.tendsto_stirlingSeq_sqrt_pi
+-/
end Stirling
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -181,7 +181,6 @@ theorem log_stirlingSeq_bounded_aux :
_ ≤ ∑ k in range n, 1 / 4 * (1 / k.succ ^ 2) := (sum_le_sum fun k _ => h₁ k)
_ = 1 / 4 * ∑ k in range n, 1 / k.succ ^ 2 := by rw [mul_sum]
_ ≤ 1 / 4 * d := mul_le_mul_of_nonneg_left h₂ <| by positivity
-
#align stirling.log_stirling_seq_bounded_aux Stirling.log_stirlingSeq_bounded_aux
/-- The sequence `log_stirling_seq` is bounded below for `n ≥ 1`. -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/31c24aa72e7b3e5ed97a8412470e904f82b81004
@@ -246,7 +246,7 @@ theorem tendsto_self_div_two_mul_self_add_one :
`(stirling_seq n)^4 / (stirling_seq (2*n))^2 * (n / (2 * n + 1)) = W n`, where `W n` is the
`n`-th partial product of Wallis' formula for `π / 2`. -/
theorem stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq (n : ℕ) (hn : n ≠ 0) :
- stirlingSeq n ^ 4 / stirlingSeq (2 * n) ^ 2 * (n / (2 * n + 1)) = Wallis.w n :=
+ stirlingSeq n ^ 4 / stirlingSeq (2 * n) ^ 2 * (n / (2 * n + 1)) = Wallis.W n :=
by
rw [bit0_eq_two_mul, stirling_seq, pow_mul, stirling_seq, wallis.W_eq_factorial_ratio]
simp_rw [div_pow, mul_pow]
@@ -265,7 +265,7 @@ theorem stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq (n : ℕ) (hn : n ≠ 0)
Then the Wallis sequence `W n` has limit `a^2 / 2`.
-/
theorem second_wallis_limit (a : ℝ) (hane : a ≠ 0) (ha : Tendsto stirlingSeq atTop (𝓝 a)) :
- Tendsto Wallis.w atTop (𝓝 (a ^ 2 / 2)) :=
+ Tendsto Wallis.W atTop (𝓝 (a ^ 2 / 2)) :=
by
refine'
tendsto.congr'
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -87,7 +87,7 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
by
change HasSum ((fun b : ℕ => 1 / (2 * (b : ℝ) + 1) * ((1 / (2 * m.succ + 1)) ^ 2) ^ b) ∘ succ) _
refine' (hasSum_nat_add_iff 1).mpr _
- convert(has_sum_log_one_add_inv <| cast_pos.mpr (succ_pos m)).mul_left ((m.succ : ℝ) + 1 / 2)
+ convert (has_sum_log_one_add_inv <| cast_pos.mpr (succ_pos m)).mul_left ((m.succ : ℝ) + 1 / 2)
· ext k
rw [← pow_mul, pow_add]
push_cast
@@ -98,8 +98,8 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
· have h : ∀ (x : ℝ) (hx : x ≠ 0), 1 + x⁻¹ = (x + 1) / x := by intros;
rw [_root_.add_div, div_self hx, inv_eq_one_div]
simp (disch := norm_cast;
- apply_rules [mul_ne_zero, succ_ne_zero, factorial_ne_zero, exp_ne_zero]
- ) only [log_stirling_seq_formula,
+ apply_rules [mul_ne_zero, succ_ne_zero, factorial_ne_zero,
+ exp_ne_zero]) only [log_stirling_seq_formula,
log_div, log_mul, log_exp, factorial_succ, cast_mul, cast_succ, cast_zero, range_one,
sum_singleton, h]
ring
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -95,7 +95,7 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
have : 2 * ((m : ℝ) + 1) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * m.succ)
field_simp
ring
- · have h : ∀ (x : ℝ) (hx : x ≠ 0), 1 + x⁻¹ = (x + 1) / x := by intros ;
+ · have h : ∀ (x : ℝ) (hx : x ≠ 0), 1 + x⁻¹ = (x + 1) / x := by intros;
rw [_root_.add_div, div_self hx, inv_eq_one_div]
simp (disch := norm_cast;
apply_rules [mul_ne_zero, succ_ne_zero, factorial_ne_zero, exp_ne_zero]
@@ -123,7 +123,7 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
((1 / (2 * n.succ + 1)) ^ 2 / (1 - (1 / (2 * n.succ + 1)) ^ 2)) :=
by
have := (hasSum_geometric_of_lt_1 h_nonneg _).mul_left ((1 / (2 * (n.succ : ℝ) + 1)) ^ 2)
- · simp_rw [← pow_succ] at this
+ · simp_rw [← pow_succ] at this
exact this
rw [one_div, inv_pow]
exact inv_lt_one (one_lt_pow ((lt_add_iff_pos_left 1).mpr <| by positivity) two_ne_zero)
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -35,7 +35,7 @@ formula for `π`.
-/
-open Topology Real BigOperators Nat
+open scoped Topology Real BigOperators Nat
open Finset Filter Nat Real
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -91,20 +91,13 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
· ext k
rw [← pow_mul, pow_add]
push_cast
- have : 2 * (k : ℝ) + 1 ≠ 0 := by
- norm_cast
- exact succ_ne_zero (2 * k)
- have : 2 * ((m : ℝ) + 1) + 1 ≠ 0 := by
- norm_cast
- exact succ_ne_zero (2 * m.succ)
+ have : 2 * (k : ℝ) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * k)
+ have : 2 * ((m : ℝ) + 1) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * m.succ)
field_simp
ring
- · have h : ∀ (x : ℝ) (hx : x ≠ 0), 1 + x⁻¹ = (x + 1) / x :=
- by
- intros
+ · have h : ∀ (x : ℝ) (hx : x ≠ 0), 1 + x⁻¹ = (x + 1) / x := by intros ;
rw [_root_.add_div, div_self hx, inv_eq_one_div]
- simp (disch :=
- norm_cast
+ simp (disch := norm_cast;
apply_rules [mul_ne_zero, succ_ne_zero, factorial_ne_zero, exp_ne_zero]
) only [log_stirling_seq_formula,
log_div, log_mul, log_exp, factorial_succ, cast_mul, cast_succ, cast_zero, range_one,
@@ -175,11 +168,8 @@ theorem log_stirlingSeq_bounded_aux :
use (1 / 4 * d : ℝ)
let log_stirling_seq' : ℕ → ℝ := fun k => log (stirling_seq k.succ)
intro n
- have h₁ : ∀ k, log_stirling_seq' k - log_stirling_seq' (k + 1) ≤ 1 / 4 * (1 / k.succ ^ 2) :=
- by
- intro k
- convert log_stirling_seq_sub_log_stirling_seq_succ k using 1
- field_simp
+ have h₁ : ∀ k, log_stirling_seq' k - log_stirling_seq' (k + 1) ≤ 1 / 4 * (1 / k.succ ^ 2) := by
+ intro k; convert log_stirling_seq_sub_log_stirling_seq_succ k using 1; field_simp
have h₂ : (∑ k : ℕ in range n, (1 : ℝ) / k.succ ^ 2) ≤ d :=
sum_le_tsum (range n) (fun k _ => by positivity)
((summable_nat_add_iff 1).mpr <| real.summable_one_div_nat_pow.mpr one_lt_two)
@@ -202,10 +192,7 @@ theorem log_stirlingSeq_bounded_by_constant : ∃ c, ∀ n : ℕ, c ≤ log (sti
#align stirling.log_stirling_seq_bounded_by_constant Stirling.log_stirlingSeq_bounded_by_constant
/-- The sequence `stirling_seq` is positive for `n > 0` -/
-theorem stirling_seq'_pos (n : ℕ) : 0 < stirlingSeq n.succ :=
- by
- unfold stirling_seq
- positivity
+theorem stirling_seq'_pos (n : ℕ) : 0 < stirlingSeq n.succ := by unfold stirling_seq; positivity
#align stirling.stirling_seq'_pos Stirling.stirling_seq'_pos
/-- The sequence `stirling_seq` has a positive lower bound.
@@ -268,9 +255,7 @@ theorem stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq (n : ℕ) (hn : n ≠ 0)
have : (n : ℝ) ≠ 0 := cast_ne_zero.mpr hn
have : exp 1 ≠ 0 := exp_ne_zero 1
have : ((2 * n)! : ℝ) ≠ 0 := cast_ne_zero.mpr (factorial_ne_zero (2 * n))
- have : 2 * (n : ℝ) + 1 ≠ 0 := by
- norm_cast
- exact succ_ne_zero (2 * n)
+ have : 2 * (n : ℝ) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * n)
field_simp
simp only [mul_pow, mul_comm 2 n, mul_comm 4 n, pow_mul]
ring
mathlib commit https://github.com/leanprover-community/mathlib/commit/e3fb84046afd187b710170887195d50bada934ee
@@ -228,9 +228,9 @@ theorem stirlingSeq_has_pos_limit_a : ∃ a : ℝ, 0 < a ∧ Tendsto stirlingSeq
by
obtain ⟨x, x_pos, hx⟩ := stirling_seq'_bounded_by_pos_constant
have hx' : x ∈ lowerBounds (Set.range (stirling_seq ∘ succ)) := by simpa [lowerBounds] using hx
- refine' ⟨_, lt_of_lt_of_le x_pos (le_cinfₛ (Set.range_nonempty _) hx'), _⟩
+ refine' ⟨_, lt_of_lt_of_le x_pos (le_csInf (Set.range_nonempty _) hx'), _⟩
rw [← Filter.tendsto_add_atTop_iff_nat 1]
- exact tendsto_atTop_cinfᵢ stirling_seq'_antitone ⟨x, hx'⟩
+ exact tendsto_atTop_ciInf stirling_seq'_antitone ⟨x, hx'⟩
#align stirling.stirling_seq_has_pos_limit_a Stirling.stirlingSeq_has_pos_limit_a
/-!
mathlib commit https://github.com/leanprover-community/mathlib/commit/36b8aa61ea7c05727161f96a0532897bd72aedab
@@ -4,13 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Moritz Firsching, Fabian Kruse, Nikolas Kuhn
! This file was ported from Lean 3 source module analysis.special_functions.stirling
-! leanprover-community/mathlib commit f2ce6086713c78a7f880485f7917ea547a215982
+! leanprover-community/mathlib commit 2c1d8ca2812b64f88992a5294ea3dba144755cd1
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Analysis.PSeries
-import Mathbin.Analysis.SpecialFunctions.Log.Deriv
-import Mathbin.Tactic.Positivity
import Mathbin.Data.Real.Pi.Wallis
/-!
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce7e9d53d4bbc38065db3b595cd5bd73c323bc1d
@@ -89,7 +89,7 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
by
change HasSum ((fun b : ℕ => 1 / (2 * (b : ℝ) + 1) * ((1 / (2 * m.succ + 1)) ^ 2) ^ b) ∘ succ) _
refine' (hasSum_nat_add_iff 1).mpr _
- convert (has_sum_log_one_add_inv <| cast_pos.mpr (succ_pos m)).mul_left ((m.succ : ℝ) + 1 / 2)
+ convert(has_sum_log_one_add_inv <| cast_pos.mpr (succ_pos m)).mul_left ((m.succ : ℝ) + 1 / 2)
· ext k
rw [← pow_mul, pow_add]
push_cast
mathlib commit https://github.com/leanprover-community/mathlib/commit/3180fab693e2cee3bff62675571264cb8778b212
@@ -58,7 +58,8 @@ noncomputable def stirlingSeq (n : ℕ) : ℝ :=
@[simp]
theorem stirlingSeq_zero : stirlingSeq 0 = 0 := by
- rw [stirling_seq, cast_zero, mul_zero, Real.sqrt_zero, zero_mul, div_zero]
+ rw [stirling_seq, cast_zero, MulZeroClass.mul_zero, Real.sqrt_zero, MulZeroClass.zero_mul,
+ div_zero]
#align stirling.stirling_seq_zero Stirling.stirlingSeq_zero
@[simp]
mathlib commit https://github.com/leanprover-community/mathlib/commit/ddec54a71a0dd025c05445d467f1a2b7d586a3ba
@@ -231,7 +231,7 @@ theorem stirlingSeq_has_pos_limit_a : ∃ a : ℝ, 0 < a ∧ Tendsto stirlingSeq
have hx' : x ∈ lowerBounds (Set.range (stirling_seq ∘ succ)) := by simpa [lowerBounds] using hx
refine' ⟨_, lt_of_lt_of_le x_pos (le_cinfₛ (Set.range_nonempty _) hx'), _⟩
rw [← Filter.tendsto_add_atTop_iff_nat 1]
- exact tendsto_atTop_cinfi stirling_seq'_antitone ⟨x, hx'⟩
+ exact tendsto_atTop_cinfᵢ stirling_seq'_antitone ⟨x, hx'⟩
#align stirling.stirling_seq_has_pos_limit_a Stirling.stirlingSeq_has_pos_limit_a
/-!
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -189,7 +189,7 @@ theorem log_stirlingSeq_bounded_aux :
rfl
_ = ∑ k in range n, log_stirling_seq' k - log_stirling_seq' (k + 1) := by
rw [← sum_range_sub' log_stirling_seq' n]
- _ ≤ ∑ k in range n, 1 / 4 * (1 / k.succ ^ 2) := sum_le_sum fun k _ => h₁ k
+ _ ≤ ∑ k in range n, 1 / 4 * (1 / k.succ ^ 2) := (sum_le_sum fun k _ => h₁ k)
_ = 1 / 4 * ∑ k in range n, 1 / k.succ ^ 2 := by rw [mul_sum]
_ ≤ 1 / 4 * d := mul_le_mul_of_nonneg_left h₂ <| by positivity
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
@@ -160,7 +160,7 @@ theorem log_stirlingSeq_bounded_aux :
rfl
_ = ∑ k in range n, (log_stirlingSeq' k - log_stirlingSeq' (k + 1)) := by
rw [← sum_range_sub' log_stirlingSeq' n]
- _ ≤ ∑ k in range n, 1 / 4 * (1 / ↑((k + 1)) ^ 2) := (sum_le_sum fun k _ => h₁ k)
+ _ ≤ ∑ k in range n, 1 / 4 * (1 / ↑((k + 1)) ^ 2) := sum_le_sum fun k _ => h₁ k
_ = 1 / 4 * ∑ k in range n, 1 / ↑((k + 1)) ^ 2 := by rw [mul_sum]
_ ≤ 1 / 4 * d := by gcongr
#align stirling.log_stirling_seq_bounded_aux Stirling.log_stirlingSeq_bounded_aux
This adds the notation √r
for Real.sqrt r
. The precedence is such that √x⁻¹
is parsed as √(x⁻¹)
; not because this is particularly desirable, but because it's the default and the choice doesn't really matter.
This is extracted from #7907, which adds a more general nth root typeclass.
The idea is to perform all the boring substitutions downstream quickly, so that we can play around with custom elaborators with a much slower rate of code-rot.
This PR also won't rot as quickly, as it does not forbid writing x.sqrt
as that PR does.
While perhaps claiming √
for Real.sqrt
is greedy; it:
NNReal.sqrt
and Nat.sqrt
sqrt
on Float
Co-authored-by: Yury G. Kudryashov <urkud@urkud.name>
@@ -48,7 +48,7 @@ namespace Stirling
Stirling's formula states that this sequence has limit $\sqrt(π)$.
-/
noncomputable def stirlingSeq (n : ℕ) : ℝ :=
- n ! / (Real.sqrt (2 * n) * (n / exp 1) ^ n)
+ n ! / (√(2 * n : ℝ) * (n / exp 1) ^ n)
#align stirling.stirling_seq Stirling.stirlingSeq
@[simp]
@@ -57,7 +57,7 @@ theorem stirlingSeq_zero : stirlingSeq 0 = 0 := by
#align stirling.stirling_seq_zero Stirling.stirlingSeq_zero
@[simp]
-theorem stirlingSeq_one : stirlingSeq 1 = exp 1 / Real.sqrt 2 := by
+theorem stirlingSeq_one : stirlingSeq 1 = exp 1 / √2 := by
rw [stirlingSeq, pow_one, factorial_one, cast_one, mul_one, mul_one_div, one_div_div]
#align stirling.stirling_seq_one Stirling.stirlingSeq_one
@@ -247,7 +247,7 @@ theorem second_wallis_limit (a : ℝ) (hane : a ≠ 0) (ha : Tendsto stirlingSeq
#align stirling.second_wallis_limit Stirling.second_wallis_limit
/-- **Stirling's Formula** -/
-theorem tendsto_stirlingSeq_sqrt_pi : Tendsto (fun n : ℕ => stirlingSeq n) atTop (𝓝 (sqrt π)) := by
+theorem tendsto_stirlingSeq_sqrt_pi : Tendsto stirlingSeq atTop (𝓝 (√π)) := by
obtain ⟨a, hapos, halimit⟩ := stirlingSeq_has_pos_limit_a
have hπ : π / 2 = a ^ 2 / 2 :=
tendsto_nhds_unique Wallis.tendsto_W_nhds_pi_div_two (second_wallis_limit a hapos.ne' halimit)
@@ -74,15 +74,14 @@ theorem log_stirlingSeq_formula (n : ℕ) :
`∑ 1 / (2 * (k + 1) + 1) * (1 / 2 * (m + 1) + 1)^(2 * (k + 1))`
-/
theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
- HasSum (fun k : ℕ => ↑1 / (↑2 * ↑(k + 1) + ↑1) * (((1:ℝ)/(↑2 * ↑(m + 1) + ↑1)) ^ 2) ^ ↑(k + 1))
+ HasSum (fun k : ℕ => (1 : ℝ) / (2 * ↑(k + 1) + 1) * ((1 / (2 * ↑(m + 1) + 1)) ^ 2) ^ ↑(k + 1))
(log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))) := by
- change HasSum
- ((fun b : ℕ => (1:ℝ) / ((2:ℝ) * b + (1:ℝ)) * (((1:ℝ) / (2 * (m + 1 :) + 1)) ^ 2) ^ b) ∘ succ) _
- refine' (hasSum_nat_add_iff (g := _ - _) -- Porting note: must give implicit arguments
- (f := (fun b : ℕ => ↑1 / (↑2 * b + ↑1) * (((1:ℝ) / (2 * ↑(m + 1) + 1)) ^ 2) ^ b)) 1).mpr _
- convert (hasSum_log_one_add_inv <|
- cast_pos.mpr (succ_pos m)).mul_left ((↑(m + 1) : ℝ) + 1 / 2) using 1
+ let f (k : ℕ) := (1 : ℝ) / (2 * k + 1) * ((1 / (2 * ↑(m + 1) + 1)) ^ 2) ^ k
+ change HasSum (fun k => f (k + 1)) _
+ rw [hasSum_nat_add_iff]
+ convert (hasSum_log_one_add_inv m.cast_add_one_pos).mul_left ((↑(m + 1) : ℝ) + 1 / 2) using 1
· ext k
+ dsimp only [f]
rw [← pow_mul, pow_add]
push_cast
field_simp
@@ -103,18 +102,18 @@ theorem log_stirlingSeq'_antitone : Antitone (Real.log ∘ stirlingSeq ∘ succ)
-/
theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
log (stirlingSeq (n + 1)) - log (stirlingSeq (n + 2)) ≤
- ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) := by
- have h_nonneg : (0 : ℝ) ≤ ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 := sq_nonneg _
- have g : HasSum (fun k : ℕ => (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1))
- (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)) := by
- have := (hasSum_geometric_of_lt_one h_nonneg ?_).mul_left (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)
+ ((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (1 - ((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) := by
+ have h_nonneg : (0 : ℝ) ≤ ((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 := sq_nonneg _
+ have g : HasSum (fun k : ℕ => (((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1))
+ (((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (1 - ((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)) := by
+ have := (hasSum_geometric_of_lt_one h_nonneg ?_).mul_left (((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)
· simp_rw [← _root_.pow_succ'] at this
exact this
rw [one_div, inv_pow]
exact inv_lt_one (one_lt_pow ((lt_add_iff_pos_left 1).mpr <| by positivity) two_ne_zero)
- have hab : ∀ k : ℕ, (1:ℝ) / (↑2 * ↑(k + 1) + ↑1) * (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1) ≤
- (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1) := by
- refine' fun k => mul_le_of_le_one_left (pow_nonneg h_nonneg ↑(k + 1)) _
+ have hab (k : ℕ) : (1 : ℝ) / (2 * ↑(k + 1) + 1) * ((1 / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1) ≤
+ (((1 : ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1) := by
+ refine' mul_le_of_le_one_left (pow_nonneg h_nonneg ↑(k + 1)) _
rw [one_div]
exact inv_le_one (le_add_of_nonneg_left <| by positivity)
exact hasSum_le hab (log_stirlingSeq_diff_hasSum n) g
@@ -128,11 +127,11 @@ set_option maxHeartbeats 400000 in
-/
theorem log_stirlingSeq_sub_log_stirlingSeq_succ (n : ℕ) :
log (stirlingSeq (n + 1)) - log (stirlingSeq (n + 2)) ≤ 1 / (4 * (↑(n + 1):ℝ) ^ 2) := by
- have h₁ : (0 : ℝ) < ↑4 * ((n:ℝ) + 1) ^ 2 := by positivity
- have h₃ : (0 : ℝ) < (2 * ((n:ℝ) + 1) + 1) ^ 2 := by positivity
- have h₂ : (0 : ℝ) < ↑1 - (1 / (2 * ((n:ℝ) + 1) + 1)) ^ 2 := by
+ have h₁ : (0 : ℝ) < 4 * ((n : ℝ) + 1) ^ 2 := by positivity
+ have h₃ : (0 : ℝ) < (2 * ((n : ℝ) + 1) + 1) ^ 2 := by positivity
+ have h₂ : (0 : ℝ) < 1 - (1 / (2 * ((n : ℝ) + 1) + 1)) ^ 2 := by
rw [← mul_lt_mul_right h₃]
- have H : ↑0 < (2 * ((n:ℝ) + 1) + 1) ^ 2 - 1 := by nlinarith [@cast_nonneg ℝ _ n]
+ have H : 0 < (2 * ((n : ℝ) + 1) + 1) ^ 2 - 1 := by nlinarith [@cast_nonneg ℝ _ n]
convert H using 1 <;> field_simp [h₃.ne']
refine' (log_stirlingSeq_diff_le_geo_sum n).trans _
push_cast
@@ -151,20 +150,18 @@ theorem log_stirlingSeq_bounded_aux :
use 1 / 4 * d
let log_stirlingSeq' : ℕ → ℝ := fun k => log (stirlingSeq (k + 1))
intro n
- have h₁ : ∀ k, log_stirlingSeq' k - log_stirlingSeq' (k + 1) ≤
- ↑1 / ↑4 * (↑1 / (↑(k + 1):ℝ) ^ 2) := by
- intro k; convert log_stirlingSeq_sub_log_stirlingSeq_succ k using 1; field_simp
- have h₂ : (∑ k : ℕ in range n, ↑1 / (↑(k + 1):ℝ) ^ 2) ≤ d := by
+ have h₁ k : log_stirlingSeq' k - log_stirlingSeq' (k + 1) ≤ 1 / 4 * (1 / (↑(k + 1) : ℝ) ^ 2) := by
+ convert log_stirlingSeq_sub_log_stirlingSeq_succ k using 1; field_simp
+ have h₂ : (∑ k : ℕ in range n, 1 / (↑(k + 1) : ℝ) ^ 2) ≤ d := by
have := (summable_nat_add_iff 1).mpr <| Real.summable_one_div_nat_pow.mpr one_lt_two
- simp only [rpow_nat_cast] at this
exact sum_le_tsum (range n) (fun k _ => by positivity) this
calc
log (stirlingSeq 1) - log (stirlingSeq (n + 1)) = log_stirlingSeq' 0 - log_stirlingSeq' n :=
rfl
_ = ∑ k in range n, (log_stirlingSeq' k - log_stirlingSeq' (k + 1)) := by
rw [← sum_range_sub' log_stirlingSeq' n]
- _ ≤ ∑ k in range n, ↑1 / ↑4 * (↑1 / ↑((k + 1)) ^ 2) := (sum_le_sum fun k _ => h₁ k)
- _ = ↑1 / ↑4 * ∑ k in range n, ↑1 / ↑((k + 1)) ^ 2 := by rw [mul_sum]
+ _ ≤ ∑ k in range n, 1 / 4 * (1 / ↑((k + 1)) ^ 2) := (sum_le_sum fun k _ => h₁ k)
+ _ = 1 / 4 * ∑ k in range n, 1 / ↑((k + 1)) ^ 2 := by rw [mul_sum]
_ ≤ 1 / 4 * d := by gcongr
#align stirling.log_stirling_seq_bounded_aux Stirling.log_stirlingSeq_bounded_aux
@@ -241,7 +238,7 @@ theorem second_wallis_limit (a : ℝ) (hane : a ≠ 0) (ha : Tendsto stirlingSeq
Tendsto Wallis.W atTop (𝓝 (a ^ 2 / 2)) := by
refine' Tendsto.congr' (eventually_atTop.mpr ⟨1, fun n hn =>
stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq n (one_le_iff_ne_zero.mp hn)⟩) _
- have h : a ^ 2 / ↑2 = a ^ 4 / a ^ 2 * (1 / 2) := by
+ have h : a ^ 2 / 2 = a ^ 4 / a ^ 2 * (1 / 2) := by
rw [mul_one_div, ← mul_one_div (a ^ 4) (a ^ 2), one_div, ← pow_sub_of_lt a]
norm_num
rw [h]
We change the following field in the definition of an additive commutative monoid:
nsmul_succ : ∀ (n : ℕ) (x : G),
- AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+ AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x
where the latter is more natural
We adjust the definitions of ^
in monoids, groups, etc.
Originally there was a warning comment about why this natural order was preferred
use
x * npowRec n x
and notnpowRec n x * x
in the definition to make sure that definitional unfolding ofnpowRec
is blocked, to avoid deep recursion issues.
but it seems to no longer apply.
Remarks on the PR :
pow_succ
and pow_succ'
have switched their meanings.Ideal.IsPrime.mul_mem_pow
which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul
.@@ -108,7 +108,7 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
have g : HasSum (fun k : ℕ => (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1))
(((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)) := by
have := (hasSum_geometric_of_lt_one h_nonneg ?_).mul_left (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)
- · simp_rw [← _root_.pow_succ] at this
+ · simp_rw [← _root_.pow_succ'] at this
exact this
rw [one_div, inv_pow]
exact inv_lt_one (one_lt_pow ((lt_add_iff_pos_left 1).mpr <| by positivity) two_ne_zero)
This PR combines several results involving topological sums over ℤ
. These results are used in #10011 (Hurwitz zeta functions) where sums over ℤ
feature heavily.
Fill in tsum
and Summable
variants for lemmas proved for HasSum
Rename some lemmas (with deprecated aliases) to impose a consistent naming scheme
Generalise several lemmas to allow the target space to be a topological monoid rather than a group.
Speed up some slow proofs (the old summable_int_of_summable_nat
took about 10s to compile on my machine, its replacement Summable.of_nat_of_neg
is 1000 times faster)
@@ -78,7 +78,7 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
(log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))) := by
change HasSum
((fun b : ℕ => (1:ℝ) / ((2:ℝ) * b + (1:ℝ)) * (((1:ℝ) / (2 * (m + 1 :) + 1)) ^ 2) ^ b) ∘ succ) _
- refine' (hasSum_nat_add_iff (a := _ - _) -- Porting note: must give implicit arguments
+ refine' (hasSum_nat_add_iff (g := _ - _) -- Porting note: must give implicit arguments
(f := (fun b : ℕ => ↑1 / (↑2 * b + ↑1) * (((1:ℝ) / (2 * ↑(m + 1) + 1)) ^ 2) ^ b)) 1).mpr _
convert (hasSum_log_one_add_inv <|
cast_pos.mpr (succ_pos m)).mul_left ((↑(m + 1) : ℝ) + 1 / 2) using 1
This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0
branch as we update to intermediate nightlies.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>
@@ -120,6 +120,10 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
exact hasSum_le hab (log_stirlingSeq_diff_hasSum n) g
#align stirling.log_stirling_seq_diff_le_geo_sum Stirling.log_stirlingSeq_diff_le_geo_sum
+-- Adaptation note: after v4.7.0-rc1, there is a performance problem in `field_simp`.
+-- (Part of the code was ignoring the `maxDischargeDepth` setting: now that we have to increase it,
+-- other paths becomes slow.)
+set_option maxHeartbeats 400000 in
/-- We have the bound `log (stirlingSeq n) - log (stirlingSeq (n+1))` ≤ 1/(4 n^2)
-/
theorem log_stirlingSeq_sub_log_stirlingSeq_succ (n : ℕ) :
Homogenises porting notes via capitalisation and addition of whitespace.
It makes the following changes:
@@ -67,7 +67,7 @@ theorem log_stirlingSeq_formula (n : ℕ) :
· simp
· rw [stirlingSeq, log_div, log_mul, sqrt_eq_rpow, log_rpow, Real.log_pow, tsub_tsub]
<;> positivity
--- porting note: generalized from `n.succ` to `n`
+-- Porting note: generalized from `n.succ` to `n`
#align stirling.log_stirling_seq_formula Stirling.log_stirlingSeq_formulaₓ
/-- The sequence `log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))` has the series expansion
I ran tryAtEachStep on all files under Mathlib
to find all locations where omega
succeeds. For each that was a linarith
without an only
, I tried replacing it with omega
, and I verified that elaboration time got smaller. (In almost all cases, there was a noticeable speedup.) I also replaced some slow aesop
s along the way.
@@ -137,7 +137,7 @@ theorem log_stirlingSeq_sub_log_stirlingSeq_succ (n : ℕ) :
rw [div_le_div_right h₃]
ring_nf
norm_cast
- linarith
+ omega
#align stirling.log_stirling_seq_sub_log_stirling_seq_succ Stirling.log_stirlingSeq_sub_log_stirlingSeq_succ
/-- For any `n`, we have `log_stirlingSeq 1 - log_stirlingSeq n ≤ 1/4 * ∑' 1/k^2` -/
@@ -53,8 +53,7 @@ noncomputable def stirlingSeq (n : ℕ) : ℝ :=
@[simp]
theorem stirlingSeq_zero : stirlingSeq 0 = 0 := by
- rw [stirlingSeq, cast_zero, mul_zero, Real.sqrt_zero, zero_mul,
- div_zero]
+ rw [stirlingSeq, cast_zero, mul_zero, Real.sqrt_zero, zero_mul, div_zero]
#align stirling.stirling_seq_zero Stirling.stirlingSeq_zero
@[simp]
@@ -108,7 +108,7 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
have h_nonneg : (0 : ℝ) ≤ ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 := sq_nonneg _
have g : HasSum (fun k : ℕ => (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1))
(((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)) := by
- have := (hasSum_geometric_of_lt_1 h_nonneg ?_).mul_left (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)
+ have := (hasSum_geometric_of_lt_one h_nonneg ?_).mul_left (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)
· simp_rw [← _root_.pow_succ] at this
exact this
rw [one_div, inv_pow]
@@ -212,7 +212,7 @@ theorem tendsto_self_div_two_mul_self_add_one :
· skip
· skip
rw [one_div, ← add_zero (2 : ℝ)]
- refine' (((tendsto_const_div_atTop_nhds_0_nat 1).const_add (2 : ℝ)).inv₀
+ refine' (((tendsto_const_div_atTop_nhds_zero_nat 1).const_add (2 : ℝ)).inv₀
((add_zero (2 : ℝ)).symm ▸ two_ne_zero)).congr' (eventually_atTop.mpr ⟨1, fun n hn => _⟩)
rw [add_div' (1 : ℝ) 2 n (cast_ne_zero.mpr (one_le_iff_ne_zero.mp hn)), inv_div]
#align stirling.tendsto_self_div_two_mul_self_add_one Stirling.tendsto_self_div_two_mul_self_add_one
@@ -32,7 +32,7 @@ formula for `π`.
-/
-open scoped Topology Real BigOperators Nat
+open scoped Topology Real BigOperators Nat Asymptotics
open Finset Filter Nat Real
@@ -254,4 +254,16 @@ theorem tendsto_stirlingSeq_sqrt_pi : Tendsto (fun n : ℕ => stirlingSeq n) atT
rwa [(div_left_inj' (two_ne_zero' ℝ)).mp hπ, sqrt_sq hapos.le]
#align stirling.tendsto_stirling_seq_sqrt_pi Stirling.tendsto_stirlingSeq_sqrt_pi
+/-- **Stirling's Formula**, formulated in terms of `Asymptotics.IsEquivalent`. -/
+lemma factorial_isEquivalent_stirling :
+ (fun n ↦ n ! : ℕ → ℝ) ~[atTop] fun n ↦ Real.sqrt (2 * n * π) * (n / exp 1) ^ n := by
+ refine Asymptotics.isEquivalent_of_tendsto_one ?_ ?_
+ · filter_upwards [eventually_ne_atTop 0] with n hn h
+ exact absurd h (by positivity)
+ · have : sqrt π ≠ 0 := by positivity
+ nth_rewrite 2 [← div_self this]
+ convert tendsto_stirlingSeq_sqrt_pi.div tendsto_const_nhds this using 1
+ ext n
+ field_simp [stirlingSeq, mul_right_comm]
+
end Stirling
@@ -88,11 +88,9 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
push_cast
field_simp
ring
- · have h : ∀ (x : ℝ) (_ : x ≠ 0), 1 + x⁻¹ = (x + 1) / x := by
- intro x hx; rw [_root_.add_div, div_self hx, inv_eq_one_div]
- simp (disch := norm_cast <;> apply_rules [mul_ne_zero, succ_ne_zero, factorial_ne_zero,
- exp_ne_zero]) only [log_stirlingSeq_formula, log_div, log_mul, log_exp, factorial_succ,
- cast_mul, cast_succ, cast_zero, range_one, sum_singleton, h]
+ · have h : ∀ x ≠ (0 : ℝ), 1 + x⁻¹ = (x + 1) / x := fun x hx ↦ by field_simp [hx]
+ simp (disch := positivity) only [log_stirlingSeq_formula, log_div, log_mul, log_exp,
+ factorial_succ, cast_mul, cast_succ, cast_zero, range_one, sum_singleton, h]
ring
#align stirling.log_stirling_seq_diff_has_sum Stirling.log_stirlingSeq_diff_hasSum
rpow
lemmas (#9108)
A bunch of easy lemmas about Real.pow
and the golf of existing lemmas with them.
Also rename log_le_log
to log_le_log_iff
and log_le_log'
to log_le_log
. Those misnames caused several proofs to bother with side conditions they didn't need.
From LeanAPAP
@@ -188,7 +188,7 @@ theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a
/-- The sequence `stirlingSeq ∘ succ` is monotone decreasing -/
theorem stirlingSeq'_antitone : Antitone (stirlingSeq ∘ succ) := fun n m h =>
- (log_le_log (stirlingSeq'_pos m) (stirlingSeq'_pos n)).mp (log_stirlingSeq'_antitone h)
+ (log_le_log_iff (stirlingSeq'_pos m) (stirlingSeq'_pos n)).mp (log_stirlingSeq'_antitone h)
#align stirling.stirling_seq'_antitone Stirling.stirlingSeq'_antitone
/-- The limit `a` of the sequence `stirlingSeq` satisfies `0 < a` -/
@@ -229,7 +229,8 @@ theorem stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq (n : ℕ) (hn : n ≠ 0)
simp_rw [div_pow, mul_pow]
rw [sq_sqrt, sq_sqrt]
any_goals positivity
- field_simp; ring
+ field_simp [← exp_nsmul]
+ ring_nf
#align stirling.stirling_seq_pow_four_div_stirling_seq_pow_two_eq Stirling.stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq
/-- Suppose the sequence `stirlingSeq` (defined above) has the limit `a ≠ 0`.
Following on from previous gcongr
golfing PRs #4702 and #4784.
This is a replacement for #7901: this round of golfs, first introduced there, there exposed some performance issues in gcongr
, hopefully fixed by #8731, and I am opening a new PR so that the performance can be checked against current master rather than master at the time of #7901.
@@ -164,7 +164,7 @@ theorem log_stirlingSeq_bounded_aux :
rw [← sum_range_sub' log_stirlingSeq' n]
_ ≤ ∑ k in range n, ↑1 / ↑4 * (↑1 / ↑((k + 1)) ^ 2) := (sum_le_sum fun k _ => h₁ k)
_ = ↑1 / ↑4 * ∑ k in range n, ↑1 / ↑((k + 1)) ^ 2 := by rw [mul_sum]
- _ ≤ 1 / 4 * d := mul_le_mul_of_nonneg_left h₂ <| by positivity
+ _ ≤ 1 / 4 * d := by gcongr
#align stirling.log_stirling_seq_bounded_aux Stirling.log_stirlingSeq_bounded_aux
/-- The sequence `log_stirlingSeq` is bounded below for `n ≥ 1`. -/
This is the supremum of
along with some minor fixes from failures on nightly-testing as Mathlib master
is merged into it.
Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.
I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0
branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.
In particular this includes adjustments for the Lean PRs
We can get rid of all the
local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)
macros across Mathlib (and in any projects that want to write natural number powers of reals).
Changes the default behaviour of simp
to (config := {decide := false})
. This makes simp
(and consequentially norm_num
) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp
or norm_num
to decide
or rfl
, or adding (config := {decide := true})
.
This changed the behaviour of simp
so that simp [f]
will only unfold "fully applied" occurrences of f
. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true })
. We may in future add a syntax for this, e.g. simp [!f]
; please provide feedback! In the meantime, we have made the following changes:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[eqns]
to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp
and Function.flip
.This change in Lean may require further changes down the line (e.g. adding the !f
syntax, and/or upstreaming the special treatment for Function.comp
and Function.flip
, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>
@@ -36,8 +36,6 @@ open scoped Topology Real BigOperators Nat
open Finset Filter Nat Real
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
-
namespace Stirling
/-!
@@ -80,7 +78,7 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
HasSum (fun k : ℕ => ↑1 / (↑2 * ↑(k + 1) + ↑1) * (((1:ℝ)/(↑2 * ↑(m + 1) + ↑1)) ^ 2) ^ ↑(k + 1))
(log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))) := by
change HasSum
- ((fun b : ℕ => (1:ℝ) / ((2:ℝ) * b + (1:ℝ)) * (((1:ℝ) / (2 * ↑(m + 1) + 1)) ^ 2) ^ b) ∘ succ) _
+ ((fun b : ℕ => (1:ℝ) / ((2:ℝ) * b + (1:ℝ)) * (((1:ℝ) / (2 * (m + 1 :) + 1)) ^ 2) ^ b) ∘ succ) _
refine' (hasSum_nat_add_iff (a := _ - _) -- Porting note: must give implicit arguments
(f := (fun b : ℕ => ↑1 / (↑2 * b + ↑1) * (((1:ℝ) / (2 * ↑(m + 1) + 1)) ^ 2) ^ b)) 1).mpr _
convert (hasSum_log_one_add_inv <|
The Stirling formula file was full of n.succ
whose only purpose was to steer automatic coercion to a real number. Then formulas became unreadable and had to be restated in docstrings, leading to the error flagged on zulip
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -64,26 +64,27 @@ theorem stirlingSeq_one : stirlingSeq 1 = exp 1 / Real.sqrt 2 := by
rw [stirlingSeq, pow_one, factorial_one, cast_one, mul_one, mul_one_div, one_div_div]
#align stirling.stirling_seq_one Stirling.stirlingSeq_one
-/-- We have the expression
-`log (stirlingSeq (n + 1)) = log(n + 1)! - 1 / 2 * log(2 * n) - n * log ((n + 1) / e)`.
--/
-theorem log_stirlingSeq_formula (n : ℕ) : log (stirlingSeq n.succ) =
- Real.log n.succ ! - 1 / 2 * Real.log (2 * n.succ) - n.succ * log (n.succ / exp 1) := by
- rw [stirlingSeq, log_div, log_mul, sqrt_eq_rpow, log_rpow, Real.log_pow, tsub_tsub] <;> positivity
-#align stirling.log_stirling_seq_formula Stirling.log_stirlingSeq_formula
+theorem log_stirlingSeq_formula (n : ℕ) :
+ log (stirlingSeq n) = Real.log n ! - 1 / 2 * Real.log (2 * n) - n * log (n / exp 1) := by
+ cases n
+ · simp
+ · rw [stirlingSeq, log_div, log_mul, sqrt_eq_rpow, log_rpow, Real.log_pow, tsub_tsub]
+ <;> positivity
+-- porting note: generalized from `n.succ` to `n`
+#align stirling.log_stirling_seq_formula Stirling.log_stirlingSeq_formulaₓ
/-- The sequence `log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))` has the series expansion
`∑ 1 / (2 * (k + 1) + 1) * (1 / 2 * (m + 1) + 1)^(2 * (k + 1))`
-/
theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
- HasSum (fun k : ℕ => ↑1 / (↑2 * k.succ + ↑1) * (((1:ℝ) / (↑2 * m.succ + ↑1)) ^ 2) ^ k.succ)
- (log (stirlingSeq m.succ) - log (stirlingSeq m.succ.succ)) := by
+ HasSum (fun k : ℕ => ↑1 / (↑2 * ↑(k + 1) + ↑1) * (((1:ℝ)/(↑2 * ↑(m + 1) + ↑1)) ^ 2) ^ ↑(k + 1))
+ (log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))) := by
change HasSum
- ((fun b : ℕ => (1:ℝ) / ((2:ℝ) * b + (1:ℝ)) * (((1:ℝ) / (2 * m.succ + 1)) ^ 2) ^ b) ∘ succ) _
+ ((fun b : ℕ => (1:ℝ) / ((2:ℝ) * b + (1:ℝ)) * (((1:ℝ) / (2 * ↑(m + 1) + 1)) ^ 2) ^ b) ∘ succ) _
refine' (hasSum_nat_add_iff (a := _ - _) -- Porting note: must give implicit arguments
- (f := (fun b : ℕ => ↑1 / (↑2 * b + ↑1) * (((1:ℝ) / (2 * m.succ + 1)) ^ 2) ^ b)) 1).mpr _
+ (f := (fun b : ℕ => ↑1 / (↑2 * b + ↑1) * (((1:ℝ) / (2 * ↑(m + 1) + 1)) ^ 2) ^ b)) 1).mpr _
convert (hasSum_log_one_add_inv <|
- cast_pos.mpr (succ_pos m)).mul_left ((m.succ : ℝ) + 1 / 2) using 1
+ cast_pos.mpr (succ_pos m)).mul_left ((↑(m + 1) : ℝ) + 1 / 2) using 1
· ext k
rw [← pow_mul, pow_add]
push_cast
@@ -106,19 +107,19 @@ theorem log_stirlingSeq'_antitone : Antitone (Real.log ∘ stirlingSeq ∘ succ)
/-- We have a bound for successive elements in the sequence `log (stirlingSeq k)`.
-/
theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
- log (stirlingSeq n.succ) - log (stirlingSeq n.succ.succ) ≤
- ((1:ℝ) / (2 * n.succ + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * n.succ + 1)) ^ 2) := by
- have h_nonneg : ↑0 ≤ ((1:ℝ) / (2 * n.succ + 1)) ^ 2 := sq_nonneg _
- have g : HasSum (fun k : ℕ => (((1:ℝ) / (2 * n.succ + 1)) ^ 2) ^ k.succ)
- (((1:ℝ) / (2 * n.succ + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * n.succ + 1)) ^ 2)) := by
- have := (hasSum_geometric_of_lt_1 h_nonneg ?_).mul_left (((1:ℝ) / (2 * n.succ + 1)) ^ 2)
+ log (stirlingSeq (n + 1)) - log (stirlingSeq (n + 2)) ≤
+ ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) := by
+ have h_nonneg : (0 : ℝ) ≤ ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 := sq_nonneg _
+ have g : HasSum (fun k : ℕ => (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1))
+ (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2 / (↑1 - ((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)) := by
+ have := (hasSum_geometric_of_lt_1 h_nonneg ?_).mul_left (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2)
· simp_rw [← _root_.pow_succ] at this
exact this
rw [one_div, inv_pow]
exact inv_lt_one (one_lt_pow ((lt_add_iff_pos_left 1).mpr <| by positivity) two_ne_zero)
- have hab : ∀ k : ℕ, (1:ℝ) / (↑2 * k.succ + ↑1) * (((1:ℝ) / (2 * n.succ + 1)) ^ 2) ^ k.succ ≤
- (((1:ℝ) / (2 * n.succ + 1)) ^ 2) ^ k.succ := by
- refine' fun k => mul_le_of_le_one_left (pow_nonneg h_nonneg k.succ) _
+ have hab : ∀ k : ℕ, (1:ℝ) / (↑2 * ↑(k + 1) + ↑1) * (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1) ≤
+ (((1:ℝ) / (2 * ↑(n + 1) + 1)) ^ 2) ^ ↑(k + 1) := by
+ refine' fun k => mul_le_of_le_one_left (pow_nonneg h_nonneg ↑(k + 1)) _
rw [one_div]
exact inv_le_one (le_add_of_nonneg_left <| by positivity)
exact hasSum_le hab (log_stirlingSeq_diff_hasSum n) g
@@ -127,10 +128,10 @@ theorem log_stirlingSeq_diff_le_geo_sum (n : ℕ) :
/-- We have the bound `log (stirlingSeq n) - log (stirlingSeq (n+1))` ≤ 1/(4 n^2)
-/
theorem log_stirlingSeq_sub_log_stirlingSeq_succ (n : ℕ) :
- log (stirlingSeq n.succ) - log (stirlingSeq n.succ.succ) ≤ ↑1 / (↑4 * (n.succ:ℝ) ^ 2) := by
- have h₁ : ↑0 < ↑4 * ((n:ℝ) + 1) ^ 2 := by positivity
- have h₃ : ↑0 < (2 * ((n:ℝ) + 1) + 1) ^ 2 := by positivity
- have h₂ : ↑0 < ↑1 - (1 / (2 * ((n:ℝ) + 1) + 1)) ^ 2 := by
+ log (stirlingSeq (n + 1)) - log (stirlingSeq (n + 2)) ≤ 1 / (4 * (↑(n + 1):ℝ) ^ 2) := by
+ have h₁ : (0 : ℝ) < ↑4 * ((n:ℝ) + 1) ^ 2 := by positivity
+ have h₃ : (0 : ℝ) < (2 * ((n:ℝ) + 1) + 1) ^ 2 := by positivity
+ have h₂ : (0 : ℝ) < ↑1 - (1 / (2 * ((n:ℝ) + 1) + 1)) ^ 2 := by
rw [← mul_lt_mul_right h₃]
have H : ↑0 < (2 * ((n:ℝ) + 1) + 1) ^ 2 - 1 := by nlinarith [@cast_nonneg ℝ _ n]
convert H using 1 <;> field_simp [h₃.ne']
@@ -146,41 +147,41 @@ theorem log_stirlingSeq_sub_log_stirlingSeq_succ (n : ℕ) :
/-- For any `n`, we have `log_stirlingSeq 1 - log_stirlingSeq n ≤ 1/4 * ∑' 1/k^2` -/
theorem log_stirlingSeq_bounded_aux :
- ∃ c : ℝ, ∀ n : ℕ, log (stirlingSeq 1) - log (stirlingSeq n.succ) ≤ c := by
- let d := ∑' k : ℕ, ↑1 / (k.succ:ℝ) ^ 2
- use (1 / 4 * d : ℝ)
- let log_stirlingSeq' : ℕ → ℝ := fun k => log (stirlingSeq k.succ)
+ ∃ c : ℝ, ∀ n : ℕ, log (stirlingSeq 1) - log (stirlingSeq (n + 1)) ≤ c := by
+ let d : ℝ := ∑' k : ℕ, (1 : ℝ) / (↑(k + 1) : ℝ) ^ 2
+ use 1 / 4 * d
+ let log_stirlingSeq' : ℕ → ℝ := fun k => log (stirlingSeq (k + 1))
intro n
have h₁ : ∀ k, log_stirlingSeq' k - log_stirlingSeq' (k + 1) ≤
- ↑1 / ↑4 * (↑1 / (k.succ:ℝ) ^ 2) := by
+ ↑1 / ↑4 * (↑1 / (↑(k + 1):ℝ) ^ 2) := by
intro k; convert log_stirlingSeq_sub_log_stirlingSeq_succ k using 1; field_simp
- have h₂ : (∑ k : ℕ in range n, ↑1 / (k.succ:ℝ) ^ 2) ≤ d := by
+ have h₂ : (∑ k : ℕ in range n, ↑1 / (↑(k + 1):ℝ) ^ 2) ≤ d := by
have := (summable_nat_add_iff 1).mpr <| Real.summable_one_div_nat_pow.mpr one_lt_two
simp only [rpow_nat_cast] at this
exact sum_le_tsum (range n) (fun k _ => by positivity) this
calc
- log (stirlingSeq 1) - log (stirlingSeq n.succ) = log_stirlingSeq' 0 - log_stirlingSeq' n :=
+ log (stirlingSeq 1) - log (stirlingSeq (n + 1)) = log_stirlingSeq' 0 - log_stirlingSeq' n :=
rfl
_ = ∑ k in range n, (log_stirlingSeq' k - log_stirlingSeq' (k + 1)) := by
rw [← sum_range_sub' log_stirlingSeq' n]
- _ ≤ ∑ k in range n, ↑1 / ↑4 * (↑1 / ↑(k.succ) ^ 2) := (sum_le_sum fun k _ => h₁ k)
- _ = ↑1 / ↑4 * ∑ k in range n, ↑1 / ↑(k.succ) ^ 2 := by rw [mul_sum]
+ _ ≤ ∑ k in range n, ↑1 / ↑4 * (↑1 / ↑((k + 1)) ^ 2) := (sum_le_sum fun k _ => h₁ k)
+ _ = ↑1 / ↑4 * ∑ k in range n, ↑1 / ↑((k + 1)) ^ 2 := by rw [mul_sum]
_ ≤ 1 / 4 * d := mul_le_mul_of_nonneg_left h₂ <| by positivity
#align stirling.log_stirling_seq_bounded_aux Stirling.log_stirlingSeq_bounded_aux
/-- The sequence `log_stirlingSeq` is bounded below for `n ≥ 1`. -/
-theorem log_stirlingSeq_bounded_by_constant : ∃ c, ∀ n : ℕ, c ≤ log (stirlingSeq n.succ) := by
+theorem log_stirlingSeq_bounded_by_constant : ∃ c, ∀ n : ℕ, c ≤ log (stirlingSeq (n + 1)) := by
obtain ⟨d, h⟩ := log_stirlingSeq_bounded_aux
exact ⟨log (stirlingSeq 1) - d, fun n => sub_le_comm.mp (h n)⟩
#align stirling.log_stirling_seq_bounded_by_constant Stirling.log_stirlingSeq_bounded_by_constant
/-- The sequence `stirlingSeq` is positive for `n > 0` -/
-theorem stirlingSeq'_pos (n : ℕ) : 0 < stirlingSeq n.succ := by unfold stirlingSeq; positivity
+theorem stirlingSeq'_pos (n : ℕ) : 0 < stirlingSeq (n + 1) := by unfold stirlingSeq; positivity
#align stirling.stirling_seq'_pos Stirling.stirlingSeq'_pos
/-- The sequence `stirlingSeq` has a positive lower bound.
-/
-theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a ≤ stirlingSeq n.succ := by
+theorem stirlingSeq'_bounded_by_pos_constant : ∃ a, 0 < a ∧ ∀ n : ℕ, a ≤ stirlingSeq (n + 1) := by
cases' log_stirlingSeq_bounded_by_constant with c h
refine' ⟨exp c, exp_pos _, fun n => _⟩
rw [← le_log_iff_exp_le (stirlingSeq'_pos n)]
After https://github.com/leanprover/std4/pull/230, and clear some unused imports
@@ -72,9 +72,6 @@ theorem log_stirlingSeq_formula (n : ℕ) : log (stirlingSeq n.succ) =
rw [stirlingSeq, log_div, log_mul, sqrt_eq_rpow, log_rpow, Real.log_pow, tsub_tsub] <;> positivity
#align stirling.log_stirling_seq_formula Stirling.log_stirlingSeq_formula
--- Porting note: the custom discharger of the simp in the theorem below has
--- unreachable tactics for some of its invocations
-set_option linter.unreachableTactic false in
/-- The sequence `log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))` has the series expansion
`∑ 1 / (2 * (k + 1) + 1) * (1 / 2 * (m + 1) + 1)^(2 * (k + 1))`
-/
The main reasons is that having h : 0 < denom
in the context should suffice for field_simp
to do its job, without the need to manually pass h.ne
or similar.
Quite a few have := … ≠ 0
could be dropped, and some field_simp
calls no longer need explicit arguments; this is promising.
This does break some proofs where field_simp
was not used as a closing tactic, and it now
shuffles terms around a bit different. These were fixed. Using field_simp
in the middle of a proof seems rather fragile anyways.
As a drive-by contribution, positivity
now knows about π > 0
.
fixes: #4835
Co-authored-by: Matthew Ballard <matt@mrb.email>
@@ -90,8 +90,6 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
· ext k
rw [← pow_mul, pow_add]
push_cast
- have : 2 * (k : ℝ) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * k)
- have : 2 * ((m : ℝ) + 1) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * m.succ)
field_simp
ring
· have h : ∀ (x : ℝ) (_ : x ≠ 0), 1 + x⁻¹ = (x + 1) / x := by
@@ -235,13 +233,7 @@ theorem stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq (n : ℕ) (hn : n ≠ 0)
simp_rw [div_pow, mul_pow]
rw [sq_sqrt, sq_sqrt]
any_goals positivity
- have : (n : ℝ) ≠ 0 := cast_ne_zero.mpr hn
- have : exp 1 ≠ 0 := exp_ne_zero 1
- have : ((2 * n)! : ℝ) ≠ 0 := cast_ne_zero.mpr (factorial_ne_zero (2 * n))
- have : 2 * (n : ℝ) + 1 ≠ 0 := by norm_cast; exact succ_ne_zero (2 * n)
- field_simp
- simp only [mul_pow, mul_comm 2 n, mul_comm 4 n, pow_mul]
- ring
+ field_simp; ring
#align stirling.stirling_seq_pow_four_div_stirling_seq_pow_two_eq Stirling.stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq
/-- Suppose the sequence `stirlingSeq` (defined above) has the limit `a ≠ 0`.
MulZeroClass.
in mul_zero
/zero_mul
(#6682)
Search&replace MulZeroClass.mul_zero
-> mul_zero
, MulZeroClass.zero_mul
-> zero_mul
.
These were introduced by Mathport, as the full name of mul_zero
is actually MulZeroClass.mul_zero
(it's exported with the short name).
@@ -55,7 +55,7 @@ noncomputable def stirlingSeq (n : ℕ) : ℝ :=
@[simp]
theorem stirlingSeq_zero : stirlingSeq 0 = 0 := by
- rw [stirlingSeq, cast_zero, MulZeroClass.mul_zero, Real.sqrt_zero, MulZeroClass.zero_mul,
+ rw [stirlingSeq, cast_zero, mul_zero, Real.sqrt_zero, zero_mul,
div_zero]
#align stirling.stirling_seq_zero Stirling.stirlingSeq_zero
@@ -36,7 +36,7 @@ open scoped Topology Real BigOperators Nat
open Finset Filter Nat Real
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue #2220
+local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
namespace Stirling
@@ -74,7 +74,7 @@ theorem log_stirlingSeq_formula (n : ℕ) : log (stirlingSeq n.succ) =
-- Porting note: the custom discharger of the simp in the theorem below has
-- unreachable tactics for some of its invocations
-set_option linter.unreachableTactic false
+set_option linter.unreachableTactic false in
/-- The sequence `log (stirlingSeq (m + 1)) - log (stirlingSeq (m + 2))` has the series expansion
`∑ 1 / (2 * (k + 1) + 1) * (1 / 2 * (m + 1) + 1)^(2 * (k + 1))`
-/
@@ -101,7 +101,6 @@ theorem log_stirlingSeq_diff_hasSum (m : ℕ) :
cast_mul, cast_succ, cast_zero, range_one, sum_singleton, h]
ring
#align stirling.log_stirling_seq_diff_has_sum Stirling.log_stirlingSeq_diff_hasSum
-set_option linter.unreachableTactic true
/-- The sequence `log ∘ stirlingSeq ∘ succ` is monotone decreasing -/
theorem log_stirlingSeq'_antitone : Antitone (Real.log ∘ stirlingSeq ∘ succ) :=
@@ -2,15 +2,12 @@
Copyright (c) 2022 Moritz Firsching. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Moritz Firsching, Fabian Kruse, Nikolas Kuhn
-
-! This file was ported from Lean 3 source module analysis.special_functions.stirling
-! leanprover-community/mathlib commit 2c1d8ca2812b64f88992a5294ea3dba144755cd1
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Analysis.PSeries
import Mathlib.Data.Real.Pi.Wallis
+#align_import analysis.special_functions.stirling from "leanprover-community/mathlib"@"2c1d8ca2812b64f88992a5294ea3dba144755cd1"
+
/-!
# Stirling's formula
@@ -29,7 +29,7 @@ ingredients are
- taking the logarithm of the sequence and
- using the series expansion of $\log(1 + x)$.
-**Part 2**: We use the fact that the series defined in part 1 converges againt a real number $a$
+**Part 2**: We use the fact that the series defined in part 1 converges against a real number $a$
and prove that $a = \sqrt{\pi}$. Here the main ingredient is the convergence of Wallis' product
formula for `π`.
-/
The unported dependencies are
algebra.order.module
init.core
linear_algebra.free_module.finite.rank
algebra.order.monoid.cancel.defs
algebra.abs
algebra.group_power.lemmas
init.data.list.basic
linear_algebra.free_module.rank
algebra.order.monoid.cancel.basic
init.data.list.default
topology.subset_properties
init.logic
The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file