analysis.special_functions.gamma.basic
⟷
Mathlib.Analysis.SpecialFunctions.Gamma.Basic
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)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -605,8 +605,8 @@ theorem Complex.Gamma_ofReal (s : ℝ) : Complex.Gamma (s : ℂ) = Gamma s := by
#print Real.Gamma_nat_eq_factorial /-
theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
- rw [Gamma, Complex.ofReal_add, Complex.ofReal_nat_cast, Complex.ofReal_one,
- Complex.Gamma_nat_eq_factorial, ← Complex.ofReal_nat_cast, Complex.ofReal_re]
+ rw [Gamma, Complex.ofReal_add, Complex.ofReal_natCast, Complex.ofReal_one,
+ Complex.Gamma_nat_eq_factorial, ← Complex.ofReal_natCast, Complex.ofReal_re]
#align real.Gamma_nat_eq_factorial Real.Gamma_nat_eq_factorial
-/
@@ -622,7 +622,7 @@ theorem Gamma_zero : Gamma 0 = 0 := by
/-- At `-n` for `n ∈ ℕ`, the Gamma function is undefined; by convention we assign it the value `0`.
-/
theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 := by
- simpa only [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Complex.Gamma_ofReal,
+ simpa only [← Complex.ofReal_natCast, ← Complex.ofReal_neg, Complex.Gamma_ofReal,
Complex.ofReal_eq_zero] using Complex.Gamma_neg_nat_eq_zero n
#align real.Gamma_neg_nat_eq_zero Real.Gamma_neg_nat_eq_zero
-/
@@ -690,7 +690,7 @@ theorem Gamma_eq_zero_iff (s : ℝ) : Gamma s = 0 ↔ ∃ m : ℕ, s = -m :=
theorem differentiableAt_Gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ Gamma s :=
by
refine' (Complex.differentiableAt_Gamma _ _).HasDerivAt.real_of_complex.DifferentiableAt
- simp_rw [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Ne.def, Complex.ofReal_inj]
+ simp_rw [← Complex.ofReal_natCast, ← Complex.ofReal_neg, Ne.def, Complex.ofReal_inj]
exact hs
#align real.differentiable_at_Gamma Real.differentiableAt_Gamma
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -199,7 +199,7 @@ private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X
IntervalIntegrable (fun x => -((-x).exp * x ^ s) : ℝ → ℂ) volume 0 X :=
by
convert (Gamma_integrand_interval_integrable (s + 1) _ hX).neg
- · ext1; simp only [add_sub_cancel, Pi.neg_apply]
+ · ext1; simp only [add_sub_cancel_right, Pi.neg_apply]
· simp only [add_re, one_re]; linarith
private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y : ℝ} (hY : 0 ≤ Y) :
@@ -234,7 +234,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
partialGamma (s + 1) X = s * partialGamma s X - (-X).exp * X ^ s :=
by
- rw [partial_Gamma, partial_Gamma, add_sub_cancel]
+ rw [partial_Gamma, partial_Gamma, add_sub_cancel_right]
have F_der_I :
∀ x : ℝ,
x ∈ Ioo 0 X →
@@ -325,7 +325,7 @@ theorem GammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
induction' n with n hn generalizing s
· simp only [Nat.cast_zero, neg_lt_zero] at h1
dsimp only [Gamma_aux]; rw [Gamma_integral_add_one h1]
- rw [mul_comm, mul_div_cancel]; contrapose! h1; rw [h1]
+ rw [mul_comm, mul_div_cancel_right₀]; contrapose! h1; rw [h1]
simp
· dsimp only [Gamma_aux]
have hh1 : -(s + 1).re < n :=
@@ -342,7 +342,7 @@ theorem GammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
cases n
· simp only [Nat.cast_zero, neg_lt_zero] at h1
dsimp only [Gamma_aux]
- rw [Gamma_integral_add_one h1, mul_div_cancel_left]
+ rw [Gamma_integral_add_one h1, mul_div_cancel_left₀]
rintro rfl
rw [zero_re] at h1
exact h1.false
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -256,10 +256,10 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
(Gamma_integrand_deriv_integrable_A hs hX).add (Gamma_integrand_deriv_integrable_B hs hX)
have int_eval := integral_eq_sub_of_has_deriv_at_of_le hX cont.continuous_on F_der_I der_ible
-- We are basically done here but manipulating the output into the right form is fiddly.
- apply_fun fun x : ℂ => -x at int_eval
+ apply_fun fun x : ℂ => -x at int_eval
rw [intervalIntegral.integral_add (Gamma_integrand_deriv_integrable_A hs hX)
(Gamma_integrand_deriv_integrable_B hs hX),
- intervalIntegral.integral_neg, neg_add, neg_neg] at int_eval
+ intervalIntegral.integral_neg, neg_add, neg_neg] at int_eval
rw [eq_sub_of_add_eq int_eval, sub_neg_eq_add, neg_sub, add_comm, add_sub]
simp only [sub_left_inj, add_left_inj]
have :
@@ -268,7 +268,7 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
by ext1; ring
rw [this]
have t := @integral_const_mul 0 X volume _ _ s fun x : ℝ => (-x).exp * x ^ (s - 1)
- dsimp at t ; rw [← t, of_real_zero, zero_cpow]
+ dsimp at t; rw [← t, of_real_zero, zero_cpow]
· rw [MulZeroClass.mul_zero, add_zero]; congr; ext1; ring
· contrapose! hs; rw [hs, zero_re]
#align complex.partial_Gamma_add_one Complex.partialGamma_add_one
@@ -323,14 +323,14 @@ theorem GammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
GammaAux n s = GammaAux n (s + 1) / s :=
by
induction' n with n hn generalizing s
- · simp only [Nat.cast_zero, neg_lt_zero] at h1
+ · simp only [Nat.cast_zero, neg_lt_zero] at h1
dsimp only [Gamma_aux]; rw [Gamma_integral_add_one h1]
rw [mul_comm, mul_div_cancel]; contrapose! h1; rw [h1]
simp
· dsimp only [Gamma_aux]
have hh1 : -(s + 1).re < n :=
by
- rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
+ rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
rw [add_re, one_re]; linarith
rw [← hn (s + 1) hh1]
#align complex.Gamma_aux_recurrence1 Complex.GammaAux_recurrence1
@@ -340,18 +340,18 @@ theorem GammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
theorem GammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
GammaAux n s = GammaAux (n + 1) s := by
cases n
- · simp only [Nat.cast_zero, neg_lt_zero] at h1
+ · simp only [Nat.cast_zero, neg_lt_zero] at h1
dsimp only [Gamma_aux]
rw [Gamma_integral_add_one h1, mul_div_cancel_left]
rintro rfl
- rw [zero_re] at h1
+ rw [zero_re] at h1
exact h1.false
· dsimp only [Gamma_aux]
have : Gamma_aux n (s + 1 + 1) / (s + 1) = Gamma_aux n (s + 1) :=
by
have hh1 : -(s + 1).re < n :=
by
- rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
+ rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
rw [add_re, one_re]; linarith
rw [Gamma_aux_recurrence1 (s + 1) n hh1]
rw [this]
@@ -377,7 +377,7 @@ theorem Gamma_eq_GammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : Gamma s = Ga
refine' (Gamma_aux_recurrence2 s (⌊1 - s.re⌋₊ + k) _).symm
rw [Nat.cast_add]
have i0 := Nat.sub_one_lt_floor (1 - s.re)
- simp only [sub_sub_cancel_left] at i0
+ simp only [sub_sub_cancel_left] at i0
refine' lt_add_of_lt_of_nonneg i0 _
rw [← Nat.cast_zero, Nat.cast_le]; exact Nat.zero_le k
convert (u <| n - ⌊1 - s.re⌋₊).symm; rw [Nat.add_sub_of_le]
@@ -438,7 +438,7 @@ theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 :=
rw [neg_ne_zero, Nat.cast_ne_zero]
apply Nat.succ_ne_zero
have : -(n : ℂ) = -↑n.succ + 1 := by simp
- rw [this, Gamma_add_one _ A] at IH
+ rw [this, Gamma_add_one _ A] at IH
contrapose! IH
exact mul_ne_zero A IH
#align complex.Gamma_neg_nat_eq_zero Complex.Gamma_neg_nat_eq_zero
@@ -500,15 +500,15 @@ theorem differentiableAt_GammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 :
by
induction' n with n hn generalizing s
· refine' (has_deriv_at_Gamma_integral _).DifferentiableAt
- rw [Nat.cast_zero] at h1 ; linarith
+ rw [Nat.cast_zero] at h1; linarith
· dsimp only [Gamma_aux]
specialize hn (s + 1)
- have a : 1 - (s + 1).re < ↑n := by rw [Nat.cast_succ] at h1 ;
+ have a : 1 - (s + 1).re < ↑n := by rw [Nat.cast_succ] at h1;
rw [Complex.add_re, Complex.one_re]; linarith
have b : ∀ m : ℕ, s + 1 ≠ -m := by
intro m; have := h2 (1 + m)
contrapose! this
- rw [← eq_sub_iff_add_eq] at this
+ rw [← eq_sub_iff_add_eq] at this
simpa using this
refine' DifferentiableAt.div (DifferentiableAt.comp _ (hn a b) _) _ _
simp; simp; simpa using h2 0
@@ -530,7 +530,7 @@ theorem differentiableAt_Gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
rw [this]
refine' Continuous.isOpen_preimage continuous_re _ isOpen_Ioi
apply eventually_eq_of_mem this
- intro t ht; rw [mem_set_of_eq] at ht
+ intro t ht; rw [mem_set_of_eq] at ht
apply Gamma_eq_Gamma_aux; linarith
#align complex.differentiable_at_Gamma Complex.differentiableAt_Gamma
-/
@@ -661,20 +661,20 @@ theorem Gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : Gamma s ≠ 0 :=
induction n generalizing s
· intro hs
refine' (Gamma_pos_of_pos _).ne'
- rwa [Nat.cast_zero, neg_zero] at hs
+ rwa [Nat.cast_zero, neg_zero] at hs
· intro hs'
have : Gamma (s + 1) ≠ 0 := by
apply n_ih
· intro m
specialize hs (1 + m)
contrapose! hs
- rw [← eq_sub_iff_add_eq] at hs
+ rw [← eq_sub_iff_add_eq] at hs
rw [hs]
push_cast
ring
- · rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one, neg_add] at hs'
+ · rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one, neg_add] at hs'
linarith
- rw [Gamma_add_one, mul_ne_zero_iff] at this
+ rw [Gamma_add_one, mul_ne_zero_iff] at this
· exact this.2
· simpa using hs 0
#align real.Gamma_ne_zero Real.Gamma_ne_zero
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -299,7 +299,7 @@ theorem GammaIntegral_add_one {s : ℂ} (hs : 0 < s.re) :
intro x hx; dsimp only
rw [norm_eq_abs, map_mul, abs.map_neg, abs_cpow_eq_rpow_re_of_pos hx,
abs_of_nonneg (exp_pos (-x)).le, neg_mul, one_mul]
- exact (tendsto_congr' this).mpr (tendsto_rpow_mul_exp_neg_mul_atTop_nhds_0 _ _ zero_lt_one)
+ exact (tendsto_congr' this).mpr (tendsto_rpow_mul_exp_neg_mul_atTop_nhds_zero _ _ zero_lt_one)
#align complex.Gamma_integral_add_one Complex.GammaIntegral_add_one
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -586,7 +586,7 @@ theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) : Gamma s = ∫ x in Ioi 0, exp
theorem Gamma_add_one {s : ℝ} (hs : s ≠ 0) : Gamma (s + 1) = s * Gamma s :=
by
simp_rw [Gamma]
- rw [Complex.ofReal_add, Complex.ofReal_one, Complex.Gamma_add_one, Complex.ofReal_mul_re]
+ rw [Complex.ofReal_add, Complex.ofReal_one, Complex.Gamma_add_one, Complex.re_ofReal_mul]
rwa [Complex.ofReal_ne_zero]
#align real.Gamma_add_one Real.Gamma_add_one
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -83,7 +83,7 @@ theorem GammaIntegral_convergent {s : ℝ} (h : 0 < s) :
constructor
· rw [← integrableOn_Icc_iff_integrableOn_Ioc]
refine' integrable_on.continuous_on_mul continuous_on_id.neg.exp _ is_compact_Icc
- refine' (intervalIntegrable_iff_integrable_Icc_of_le zero_le_one).mp _
+ refine' (intervalIntegrable_iff_integrableOn_Icc_of_le zero_le_one).mp _
exact interval_integrable_rpow' (by linarith)
· refine' integrable_of_isBigO_exp_neg one_half_pos _ (Gamma_integrand_is_o _).IsBigO
refine' continuous_on_id.neg.exp.mul (continuous_on_id.rpow_const _)
@@ -192,7 +192,7 @@ theorem tendsto_partialGamma {s : ℂ} (hs : 0 < s.re) :
private theorem Gamma_integrand_interval_integrable (s : ℂ) {X : ℝ} (hs : 0 < s.re) (hX : 0 ≤ X) :
IntervalIntegrable (fun x => (-x).exp * x ^ (s - 1) : ℝ → ℂ) volume 0 X :=
by
- rw [intervalIntegrable_iff_integrable_Ioc_of_le hX]
+ rw [intervalIntegrable_iff_integrableOn_Ioc_of_le hX]
exact integrable_on.mono_set (Gamma_integral_convergent hs) Ioc_subset_Ioi_self
private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
@@ -209,7 +209,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
(fun x => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) =
(fun x => s * ((-x).exp * x ^ (s - 1)) : ℝ → ℂ) :=
by ext1; ring
- rw [this, intervalIntegrable_iff_integrable_Ioc_of_le hY]
+ rw [this, intervalIntegrable_iff_integrableOn_Ioc_of_le hY]
constructor
· refine' (continuous_on_const.mul _).AEStronglyMeasurable measurableSet_Ioc
apply (continuous_of_real.comp continuous_neg.exp).ContinuousOn.mul
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -62,11 +62,11 @@ theorem Gamma_integrand_isLittleO (s : ℝ) :
refine' is_o_of_tendsto (fun x hx => _) _
· exfalso; exact (exp_pos (-(1 / 2) * x)).ne' hx
have :
- (fun x : ℝ => exp (-x) * x ^ s / exp (-(1 / 2) * x)) =
- (fun x : ℝ => exp (1 / 2 * x) / x ^ s)⁻¹ :=
+ (fun x : ℝ => NormedSpace.exp (-x) * x ^ s / NormedSpace.exp (-(1 / 2) * x)) =
+ (fun x : ℝ => NormedSpace.exp (1 / 2 * x) / x ^ s)⁻¹ :=
by
ext1 x
- field_simp [exp_ne_zero, exp_neg, ← Real.exp_add]
+ field_simp [exp_ne_zero, NormedSpace.exp_neg, ← Real.exp_add]
left
ring
rw [this]
@@ -142,8 +142,8 @@ theorem GammaIntegral_conj (s : ℂ) : GammaIntegral (conj s) = conj (GammaInteg
refine' set_integral_congr measurableSet_Ioi fun x hx => _
dsimp only
rw [RingHom.map_mul, conj_of_real, cpow_def_of_ne_zero (of_real_ne_zero.mpr (ne_of_gt hx)),
- cpow_def_of_ne_zero (of_real_ne_zero.mpr (ne_of_gt hx)), ← exp_conj, RingHom.map_mul, ←
- of_real_log (le_of_lt hx), conj_of_real, RingHom.map_sub, RingHom.map_one]
+ cpow_def_of_ne_zero (of_real_ne_zero.mpr (ne_of_gt hx)), ← NormedSpace.exp_conj,
+ RingHom.map_mul, ← of_real_log (le_of_lt hx), conj_of_real, RingHom.map_sub, RingHom.map_one]
#align complex.Gamma_integral_conj Complex.GammaIntegral_conj
-/
@@ -572,8 +572,8 @@ theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) : Gamma s = ∫ x in Ioi 0, exp
dsimp only [Complex.GammaIntegral]
simp_rw [← Complex.ofReal_one, ← Complex.ofReal_sub]
suffices
- ∫ x : ℝ in Ioi 0, ↑(exp (-x)) * (x : ℂ) ^ ((s - 1 : ℝ) : ℂ) =
- ∫ x : ℝ in Ioi 0, ((exp (-x) * x ^ (s - 1) : ℝ) : ℂ)
+ ∫ x : ℝ in Ioi 0, ↑(NormedSpace.exp (-x)) * (x : ℂ) ^ ((s - 1 : ℝ) : ℂ) =
+ ∫ x : ℝ in Ioi 0, ((NormedSpace.exp (-x) * x ^ (s - 1) : ℝ) : ℂ)
by rw [this, _root_.integral_of_real, Complex.ofReal_re]
refine' set_integral_congr measurableSet_Ioi fun x hx => _
push_cast
@@ -631,7 +631,7 @@ theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 := by
theorem Gamma_pos_of_pos {s : ℝ} (hs : 0 < s) : 0 < Gamma s :=
by
rw [Gamma_eq_integral hs]
- have : (Function.support fun x : ℝ => exp (-x) * x ^ (s - 1)) ∩ Ioi 0 = Ioi 0 :=
+ have : (Function.support fun x : ℝ => NormedSpace.exp (-x) * x ^ (s - 1)) ∩ Ioi 0 = Ioi 0 :=
by
rw [inter_eq_right_iff_subset]
intro x hx
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,9 +3,9 @@ Copyright (c) 2022 David Loeffler. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
-/
-import Mathbin.MeasureTheory.Integral.ExpDecay
-import Mathbin.Analysis.SpecialFunctions.ImproperIntegrals
-import Mathbin.Analysis.MellinTransform
+import MeasureTheory.Integral.ExpDecay
+import Analysis.SpecialFunctions.ImproperIntegrals
+import Analysis.MellinTransform
#align_import analysis.special_functions.gamma.basic from "leanprover-community/mathlib"@"8af7091a43227e179939ba132e54e54e9f3b089a"
mathlib commit https://github.com/leanprover-community/mathlib/commit/63721b2c3eba6c325ecf8ae8cca27155a4f6306f
@@ -654,7 +654,7 @@ theorem Gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : Gamma s ≠ 0 :=
suffices ∀ {n : ℕ}, -(n : ℝ) < s → Gamma s ≠ 0
by
apply this
- swap; use ⌊-s⌋₊ + 1
+ swap; use⌊-s⌋₊ + 1
rw [neg_lt, Nat.cast_add, Nat.cast_one]
exact Nat.lt_floor_add_one _
intro n
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,16 +2,13 @@
Copyright (c) 2022 David Loeffler. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
-
-! This file was ported from Lean 3 source module analysis.special_functions.gamma.basic
-! leanprover-community/mathlib commit 8af7091a43227e179939ba132e54e54e9f3b089a
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.MeasureTheory.Integral.ExpDecay
import Mathbin.Analysis.SpecialFunctions.ImproperIntegrals
import Mathbin.Analysis.MellinTransform
+#align_import analysis.special_functions.gamma.basic from "leanprover-community/mathlib"@"8af7091a43227e179939ba132e54e54e9f3b089a"
+
/-!
# The Gamma function
mathlib commit https://github.com/leanprover-community/mathlib/commit/2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
@@ -57,6 +57,7 @@ open scoped Nat Topology ComplexConjugate
namespace Real
+#print Real.Gamma_integrand_isLittleO /-
/-- Asymptotic bound for the `Γ` function integrand. -/
theorem Gamma_integrand_isLittleO (s : ℝ) :
(fun x : ℝ => exp (-x) * x ^ s) =o[atTop] fun x : ℝ => exp (-(1 / 2) * x) :=
@@ -74,9 +75,11 @@ theorem Gamma_integrand_isLittleO (s : ℝ) :
rw [this]
exact (tendsto_exp_mul_div_rpow_atTop s (1 / 2) one_half_pos).inv_tendsto_atTop
#align real.Gamma_integrand_is_o Real.Gamma_integrand_isLittleO
+-/
+#print Real.GammaIntegral_convergent /-
/-- The Euler integral for the `Γ` function converges for positive real `s`. -/
-theorem Gamma_integral_convergent {s : ℝ} (h : 0 < s) :
+theorem GammaIntegral_convergent {s : ℝ} (h : 0 < s) :
IntegrableOn (fun x : ℝ => exp (-x) * x ^ (s - 1)) (Ioi 0) :=
by
rw [← Ioc_union_Ioi_eq_Ioi (@zero_le_one ℝ _ _ _ _), integrable_on_union]
@@ -89,19 +92,21 @@ theorem Gamma_integral_convergent {s : ℝ} (h : 0 < s) :
refine' continuous_on_id.neg.exp.mul (continuous_on_id.rpow_const _)
intro x hx
exact Or.inl ((zero_lt_one : (0 : ℝ) < 1).trans_le hx).ne'
-#align real.Gamma_integral_convergent Real.Gamma_integral_convergent
+#align real.Gamma_integral_convergent Real.GammaIntegral_convergent
+-/
end Real
namespace Complex
+#print Complex.GammaIntegral_convergent /-
/- Technical note: In defining the Gamma integrand exp (-x) * x ^ (s - 1) for s complex, we have to
make a choice between ↑(real.exp (-x)), complex.exp (↑(-x)), and complex.exp (-↑x), all of which are
equal but not definitionally so. We use the first of these throughout. -/
/-- The integral defining the `Γ` function converges for complex `s` with `0 < re s`.
This is proved by reduction to the real case. -/
-theorem Gamma_integral_convergent {s : ℂ} (hs : 0 < s.re) :
+theorem GammaIntegral_convergent {s : ℂ} (hs : 0 < s.re) :
IntegrableOn (fun x => (-x).exp * x ^ (s - 1) : ℝ → ℂ) (Ioi 0) :=
by
constructor
@@ -113,24 +118,28 @@ theorem Gamma_integral_convergent {s : ℂ} (hs : 0 < s.re) :
rw [of_real_re]; exact Or.inl hx
exact ContinuousAt.comp this continuous_of_real.continuous_at
· rw [← has_finite_integral_norm_iff]
- refine' has_finite_integral.congr (Real.Gamma_integral_convergent hs).2 _
+ refine' has_finite_integral.congr (Real.GammaIntegral_convergent hs).2 _
refine' (ae_restrict_iff' measurableSet_Ioi).mpr (ae_of_all _ fun x hx => _)
dsimp only
rw [norm_eq_abs, map_mul, abs_of_nonneg <| le_of_lt <| exp_pos <| -x,
abs_cpow_eq_rpow_re_of_pos hx _]
simp
-#align complex.Gamma_integral_convergent Complex.Gamma_integral_convergent
+#align complex.Gamma_integral_convergent Complex.GammaIntegral_convergent
+-/
+#print Complex.GammaIntegral /-
/-- Euler's integral for the `Γ` function (of a complex variable `s`), defined as
`∫ x in Ioi 0, exp (-x) * x ^ (s - 1)`.
See `complex.Gamma_integral_convergent` for a proof of the convergence of the integral for
`0 < re s`. -/
-def gammaIntegral (s : ℂ) : ℂ :=
+def GammaIntegral (s : ℂ) : ℂ :=
∫ x in Ioi (0 : ℝ), ↑(-x).exp * ↑x ^ (s - 1)
-#align complex.Gamma_integral Complex.gammaIntegral
+#align complex.Gamma_integral Complex.GammaIntegral
+-/
-theorem gammaIntegral_conj (s : ℂ) : gammaIntegral (conj s) = conj (gammaIntegral s) :=
+#print Complex.GammaIntegral_conj /-
+theorem GammaIntegral_conj (s : ℂ) : GammaIntegral (conj s) = conj (GammaIntegral s) :=
by
rw [Gamma_integral, Gamma_integral, ← integral_conj]
refine' set_integral_congr measurableSet_Ioi fun x hx => _
@@ -138,22 +147,27 @@ theorem gammaIntegral_conj (s : ℂ) : gammaIntegral (conj s) = conj (gammaInteg
rw [RingHom.map_mul, conj_of_real, cpow_def_of_ne_zero (of_real_ne_zero.mpr (ne_of_gt hx)),
cpow_def_of_ne_zero (of_real_ne_zero.mpr (ne_of_gt hx)), ← exp_conj, RingHom.map_mul, ←
of_real_log (le_of_lt hx), conj_of_real, RingHom.map_sub, RingHom.map_one]
-#align complex.Gamma_integral_conj Complex.gammaIntegral_conj
+#align complex.Gamma_integral_conj Complex.GammaIntegral_conj
+-/
-theorem gammaIntegral_of_real (s : ℝ) :
- gammaIntegral ↑s = ↑(∫ x : ℝ in Ioi 0, Real.exp (-x) * x ^ (s - 1)) :=
+#print Complex.GammaIntegral_ofReal /-
+theorem GammaIntegral_ofReal (s : ℝ) :
+ GammaIntegral ↑s = ↑(∫ x : ℝ in Ioi 0, Real.exp (-x) * x ^ (s - 1)) :=
by
rw [Gamma_integral, ← _root_.integral_of_real]
refine' set_integral_congr measurableSet_Ioi _
intro x hx; dsimp only
rw [of_real_mul, of_real_cpow (mem_Ioi.mp hx).le]
simp
-#align complex.Gamma_integral_of_real Complex.gammaIntegral_of_real
+#align complex.Gamma_integral_of_real Complex.GammaIntegral_ofReal
+-/
-theorem gammaIntegral_one : gammaIntegral 1 = 1 := by
+#print Complex.GammaIntegral_one /-
+theorem GammaIntegral_one : GammaIntegral 1 = 1 := by
simpa only [← of_real_one, Gamma_integral_of_real, of_real_inj, sub_self, rpow_zero,
mul_one] using integral_exp_neg_Ioi_zero
-#align complex.Gamma_integral_one Complex.gammaIntegral_one
+#align complex.Gamma_integral_one Complex.GammaIntegral_one
+-/
end Complex
@@ -164,15 +178,19 @@ namespace Complex
section GammaRecurrence
+#print Complex.partialGamma /-
/-- The indefinite version of the `Γ` function, `Γ(s, X) = ∫ x ∈ 0..X, exp(-x) x ^ (s - 1)`. -/
def partialGamma (s : ℂ) (X : ℝ) : ℂ :=
∫ x in 0 ..X, (-x).exp * x ^ (s - 1)
#align complex.partial_Gamma Complex.partialGamma
+-/
+#print Complex.tendsto_partialGamma /-
theorem tendsto_partialGamma {s : ℂ} (hs : 0 < s.re) :
- Tendsto (fun X : ℝ => partialGamma s X) atTop (𝓝 <| gammaIntegral s) :=
- intervalIntegral_tendsto_integral_Ioi 0 (Gamma_integral_convergent hs) tendsto_id
+ Tendsto (fun X : ℝ => partialGamma s X) atTop (𝓝 <| GammaIntegral s) :=
+ intervalIntegral_tendsto_integral_Ioi 0 (GammaIntegral_convergent hs) tendsto_id
#align complex.tendsto_partial_Gamma Complex.tendsto_partialGamma
+-/
private theorem Gamma_integrand_interval_integrable (s : ℂ) {X : ℝ} (hs : 0 < s.re) (hX : 0 ≤ X) :
IntervalIntegrable (fun x => (-x).exp * x ^ (s - 1) : ℝ → ℂ) volume 0 X :=
@@ -205,7 +223,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
rw [← has_finite_integral_norm_iff]
simp_rw [norm_eq_abs, map_mul]
refine'
- (((Real.Gamma_integral_convergent hs).mono_set Ioc_subset_Ioi_self).HasFiniteIntegral.congr
+ (((Real.GammaIntegral_convergent hs).mono_set Ioc_subset_Ioi_self).HasFiniteIntegral.congr
_).const_mul
_
rw [eventually_eq, ae_restrict_iff']
@@ -214,6 +232,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
simp
· exact measurableSet_Ioc
+#print Complex.partialGamma_add_one /-
/-- The recurrence relation for the indefinite version of the `Γ` function. -/
theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
partialGamma (s + 1) X = s * partialGamma s X - (-X).exp * X ^ s :=
@@ -256,10 +275,12 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
· rw [MulZeroClass.mul_zero, add_zero]; congr; ext1; ring
· contrapose! hs; rw [hs, zero_re]
#align complex.partial_Gamma_add_one Complex.partialGamma_add_one
+-/
+#print Complex.GammaIntegral_add_one /-
/-- The recurrence relation for the `Γ` integral. -/
-theorem gammaIntegral_add_one {s : ℂ} (hs : 0 < s.re) :
- gammaIntegral (s + 1) = s * gammaIntegral s :=
+theorem GammaIntegral_add_one {s : ℂ} (hs : 0 < s.re) :
+ GammaIntegral (s + 1) = s * GammaIntegral s :=
by
suffices tendsto (s + 1).partialGamma at_top (𝓝 <| s * Gamma_integral s)
by
@@ -282,7 +303,8 @@ theorem gammaIntegral_add_one {s : ℂ} (hs : 0 < s.re) :
rw [norm_eq_abs, map_mul, abs.map_neg, abs_cpow_eq_rpow_re_of_pos hx,
abs_of_nonneg (exp_pos (-x)).le, neg_mul, one_mul]
exact (tendsto_congr' this).mpr (tendsto_rpow_mul_exp_neg_mul_atTop_nhds_0 _ _ zero_lt_one)
-#align complex.Gamma_integral_add_one Complex.gammaIntegral_add_one
+#align complex.Gamma_integral_add_one Complex.GammaIntegral_add_one
+-/
end GammaRecurrence
@@ -291,14 +313,17 @@ end GammaRecurrence
section GammaDef
+#print Complex.GammaAux /-
/-- The `n`th function in this family is `Γ(s)` if `-n < s.re`, and junk otherwise. -/
-noncomputable def gammaAux : ℕ → ℂ → ℂ
- | 0 => gammaIntegral
+noncomputable def GammaAux : ℕ → ℂ → ℂ
+ | 0 => GammaIntegral
| n + 1 => fun s : ℂ => Gamma_aux n (s + 1) / s
-#align complex.Gamma_aux Complex.gammaAux
+#align complex.Gamma_aux Complex.GammaAux
+-/
-theorem gammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
- gammaAux n s = gammaAux n (s + 1) / s :=
+#print Complex.GammaAux_recurrence1 /-
+theorem GammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
+ GammaAux n s = GammaAux n (s + 1) / s :=
by
induction' n with n hn generalizing s
· simp only [Nat.cast_zero, neg_lt_zero] at h1
@@ -311,10 +336,12 @@ theorem gammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
rw [add_re, one_re]; linarith
rw [← hn (s + 1) hh1]
-#align complex.Gamma_aux_recurrence1 Complex.gammaAux_recurrence1
+#align complex.Gamma_aux_recurrence1 Complex.GammaAux_recurrence1
+-/
-theorem gammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
- gammaAux n s = gammaAux (n + 1) s := by
+#print Complex.GammaAux_recurrence2 /-
+theorem GammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
+ GammaAux n s = GammaAux (n + 1) s := by
cases n
· simp only [Nat.cast_zero, neg_lt_zero] at h1
dsimp only [Gamma_aux]
@@ -331,15 +358,19 @@ theorem gammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
rw [add_re, one_re]; linarith
rw [Gamma_aux_recurrence1 (s + 1) n hh1]
rw [this]
-#align complex.Gamma_aux_recurrence2 Complex.gammaAux_recurrence2
+#align complex.Gamma_aux_recurrence2 Complex.GammaAux_recurrence2
+-/
+#print Complex.Gamma /-
/-- The `Γ` function (of a complex variable `s`). -/
@[pp_nodot]
-def gamma (s : ℂ) : ℂ :=
- gammaAux ⌊1 - s.re⌋₊ s
-#align complex.Gamma Complex.gamma
+def Gamma (s : ℂ) : ℂ :=
+ GammaAux ⌊1 - s.re⌋₊ s
+#align complex.Gamma Complex.Gamma
+-/
-theorem gamma_eq_gammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : gamma s = gammaAux n s :=
+#print Complex.Gamma_eq_GammaAux /-
+theorem Gamma_eq_GammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : Gamma s = GammaAux n s :=
by
have u : ∀ k : ℕ, Gamma_aux (⌊1 - s.re⌋₊ + k) s = Gamma s :=
by
@@ -357,40 +388,52 @@ theorem gamma_eq_gammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : gamma s = ga
· apply Nat.le_of_lt_succ
exact_mod_cast lt_of_le_of_lt (Nat.floor_le h) (by linarith : 1 - s.re < n + 1)
· rw [Nat.floor_of_nonpos]; linarith; linarith
-#align complex.Gamma_eq_Gamma_aux Complex.gamma_eq_gammaAux
+#align complex.Gamma_eq_Gamma_aux Complex.Gamma_eq_GammaAux
+-/
+#print Complex.Gamma_add_one /-
/-- The recurrence relation for the `Γ` function. -/
-theorem gamma_add_one (s : ℂ) (h2 : s ≠ 0) : gamma (s + 1) = s * gamma s :=
+theorem Gamma_add_one (s : ℂ) (h2 : s ≠ 0) : Gamma (s + 1) = s * Gamma s :=
by
let n := ⌊1 - s.re⌋₊
have t1 : -s.re < n := by simpa only [sub_sub_cancel_left] using Nat.sub_one_lt_floor (1 - s.re)
have t2 : -(s + 1).re < n := by rw [add_re, one_re]; linarith
rw [Gamma_eq_Gamma_aux s n t1, Gamma_eq_Gamma_aux (s + 1) n t2, Gamma_aux_recurrence1 s n t1]
field_simp; ring
-#align complex.Gamma_add_one Complex.gamma_add_one
+#align complex.Gamma_add_one Complex.Gamma_add_one
+-/
-theorem gamma_eq_integral {s : ℂ} (hs : 0 < s.re) : gamma s = gammaIntegral s :=
- gamma_eq_gammaAux s 0 (by norm_cast; linarith)
-#align complex.Gamma_eq_integral Complex.gamma_eq_integral
+#print Complex.Gamma_eq_integral /-
+theorem Gamma_eq_integral {s : ℂ} (hs : 0 < s.re) : Gamma s = GammaIntegral s :=
+ Gamma_eq_GammaAux s 0 (by norm_cast; linarith)
+#align complex.Gamma_eq_integral Complex.Gamma_eq_integral
+-/
-theorem gamma_one : gamma 1 = 1 := by rw [Gamma_eq_integral]; simpa using Gamma_integral_one; simp
-#align complex.Gamma_one Complex.gamma_one
+#print Complex.Gamma_one /-
+theorem Gamma_one : Gamma 1 = 1 := by rw [Gamma_eq_integral]; simpa using Gamma_integral_one; simp
+#align complex.Gamma_one Complex.Gamma_one
+-/
-theorem gamma_nat_eq_factorial (n : ℕ) : gamma (n + 1) = n ! :=
+#print Complex.Gamma_nat_eq_factorial /-
+theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! :=
by
induction' n with n hn
· simpa using Gamma_one
· rw [Gamma_add_one n.succ <| nat.cast_ne_zero.mpr <| Nat.succ_ne_zero n]
simp only [Nat.cast_succ, Nat.factorial_succ, Nat.cast_mul]; congr; exact hn
-#align complex.Gamma_nat_eq_factorial Complex.gamma_nat_eq_factorial
+#align complex.Gamma_nat_eq_factorial Complex.Gamma_nat_eq_factorial
+-/
+#print Complex.Gamma_zero /-
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
-theorem gamma_zero : gamma 0 = 0 := by
+theorem Gamma_zero : Gamma 0 = 0 := by
simp_rw [Gamma, zero_re, sub_zero, Nat.floor_one, Gamma_aux, div_zero]
-#align complex.Gamma_zero Complex.gamma_zero
+#align complex.Gamma_zero Complex.Gamma_zero
+-/
+#print Complex.Gamma_neg_nat_eq_zero /-
/-- At `-n` for `n ∈ ℕ`, the Gamma function is undefined; by convention we assign it the value 0. -/
-theorem gamma_neg_nat_eq_zero (n : ℕ) : gamma (-n) = 0 :=
+theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 :=
by
induction' n with n IH
· rw [Nat.cast_zero, neg_zero, Gamma_zero]
@@ -401,9 +444,11 @@ theorem gamma_neg_nat_eq_zero (n : ℕ) : gamma (-n) = 0 :=
rw [this, Gamma_add_one _ A] at IH
contrapose! IH
exact mul_ne_zero A IH
-#align complex.Gamma_neg_nat_eq_zero Complex.gamma_neg_nat_eq_zero
+#align complex.Gamma_neg_nat_eq_zero Complex.Gamma_neg_nat_eq_zero
+-/
-theorem gamma_conj (s : ℂ) : gamma (conj s) = conj (gamma s) :=
+#print Complex.Gamma_conj /-
+theorem Gamma_conj (s : ℂ) : Gamma (conj s) = conj (Gamma s) :=
by
suffices : ∀ (n : ℕ) (s : ℂ), Gamma_aux n (conj s) = conj (Gamma_aux n s); exact this _ _
intro n
@@ -415,7 +460,8 @@ theorem gamma_conj (s : ℂ) : gamma (conj s) = conj (gamma s) :=
rw [div_eq_mul_inv _ s, RingHom.map_mul, conj_inv, ← div_eq_mul_inv]
suffices conj s + 1 = conj (s + 1) by rw [this, IH]
rw [RingHom.map_add, RingHom.map_one]
-#align complex.Gamma_conj Complex.gamma_conj
+#align complex.Gamma_conj Complex.Gamma_conj
+-/
end GammaDef
@@ -424,15 +470,18 @@ end GammaDef
section GammaHasDeriv
+#print Complex.GammaIntegral_eq_mellin /-
/-- Rewrite the Gamma integral as an example of a Mellin transform. -/
-theorem gammaIntegral_eq_mellin : gammaIntegral = mellin fun x => Real.exp (-x) :=
+theorem GammaIntegral_eq_mellin : GammaIntegral = mellin fun x => Real.exp (-x) :=
funext fun s => by simp only [mellin, Gamma_integral, smul_eq_mul, mul_comm]
-#align complex.Gamma_integral_eq_mellin Complex.gammaIntegral_eq_mellin
+#align complex.Gamma_integral_eq_mellin Complex.GammaIntegral_eq_mellin
+-/
+#print Complex.hasDerivAt_GammaIntegral /-
/-- The derivative of the `Γ` integral, at any `s ∈ ℂ` with `1 < re s`, is given by the Melllin
transform of `log t * exp (-t)`. -/
-theorem hasDerivAt_gammaIntegral {s : ℂ} (hs : 0 < s.re) :
- HasDerivAt gammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s :=
+theorem hasDerivAt_GammaIntegral {s : ℂ} (hs : 0 < s.re) :
+ HasDerivAt GammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s :=
by
rw [Gamma_integral_eq_mellin]
convert (mellin_hasDerivAt_of_isBigO_rpow _ _ (lt_add_one _) _ hs).2
@@ -445,10 +494,12 @@ theorem hasDerivAt_gammaIntegral {s : ℂ} (hs : 0 < s.re) :
refine' is_O_const_of_tendsto (_ : tendsto _ _ (𝓝 1)) one_ne_zero
rw [(by simp : (1 : ℂ) = Real.exp (-0))]
exact (continuous_of_real.comp (real.continuous_exp.comp continuous_neg)).ContinuousWithinAt
-#align complex.has_deriv_at_Gamma_integral Complex.hasDerivAt_gammaIntegral
+#align complex.has_deriv_at_Gamma_integral Complex.hasDerivAt_GammaIntegral
+-/
-theorem differentiableAt_gammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 : ∀ m : ℕ, s ≠ -m) :
- DifferentiableAt ℂ (gammaAux n) s :=
+#print Complex.differentiableAt_GammaAux /-
+theorem differentiableAt_GammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 : ∀ m : ℕ, s ≠ -m) :
+ DifferentiableAt ℂ (GammaAux n) s :=
by
induction' n with n hn generalizing s
· refine' (has_deriv_at_Gamma_integral _).DifferentiableAt
@@ -464,9 +515,11 @@ theorem differentiableAt_gammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 :
simpa using this
refine' DifferentiableAt.div (DifferentiableAt.comp _ (hn a b) _) _ _
simp; simp; simpa using h2 0
-#align complex.differentiable_at_Gamma_aux Complex.differentiableAt_gammaAux
+#align complex.differentiable_at_Gamma_aux Complex.differentiableAt_GammaAux
+-/
-theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℂ gamma s :=
+#print Complex.differentiableAt_Gamma /-
+theorem differentiableAt_Gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℂ Gamma s :=
by
let n := ⌊1 - s.re⌋₊ + 1
have hn : 1 - s.re < n := by exact_mod_cast Nat.lt_floor_add_one (1 - s.re)
@@ -482,38 +535,44 @@ theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
apply eventually_eq_of_mem this
intro t ht; rw [mem_set_of_eq] at ht
apply Gamma_eq_Gamma_aux; linarith
-#align complex.differentiable_at_Gamma Complex.differentiableAt_gamma
+#align complex.differentiable_at_Gamma Complex.differentiableAt_Gamma
+-/
end GammaHasDeriv
+#print Complex.tendsto_self_mul_Gamma_nhds_zero /-
/-- At `s = 0`, the Gamma function has a simple pole with residue 1. -/
-theorem tendsto_self_mul_gamma_nhds_zero : Tendsto (fun z : ℂ => z * gamma z) (𝓝[≠] 0) (𝓝 1) :=
+theorem tendsto_self_mul_Gamma_nhds_zero : Tendsto (fun z : ℂ => z * Gamma z) (𝓝[≠] 0) (𝓝 1) :=
by
- rw [show 𝓝 (1 : ℂ) = 𝓝 (Gamma (0 + 1)) by simp only [zero_add, Complex.gamma_one]]
+ rw [show 𝓝 (1 : ℂ) = 𝓝 (Gamma (0 + 1)) by simp only [zero_add, Complex.Gamma_one]]
convert
(tendsto.mono_left _ nhdsWithin_le_nhds).congr'
- (eventually_eq_of_mem self_mem_nhdsWithin Complex.gamma_add_one)
+ (eventually_eq_of_mem self_mem_nhdsWithin Complex.Gamma_add_one)
refine' ContinuousAt.comp _ (continuous_id.add continuous_const).ContinuousAt
- refine' (Complex.differentiableAt_gamma _ fun m => _).ContinuousAt
+ refine' (Complex.differentiableAt_Gamma _ fun m => _).ContinuousAt
rw [zero_add, ← of_real_nat_cast, ← of_real_neg, ← of_real_one, Ne.def, of_real_inj]
refine' (lt_of_le_of_lt _ zero_lt_one).ne'
exact neg_nonpos.mpr (Nat.cast_nonneg _)
-#align complex.tendsto_self_mul_Gamma_nhds_zero Complex.tendsto_self_mul_gamma_nhds_zero
+#align complex.tendsto_self_mul_Gamma_nhds_zero Complex.tendsto_self_mul_Gamma_nhds_zero
+-/
end Complex
namespace Real
+#print Real.Gamma /-
/-- The `Γ` function (of a real variable `s`). -/
@[pp_nodot]
-def gamma (s : ℝ) : ℝ :=
- (Complex.gamma s).re
-#align real.Gamma Real.gamma
+def Gamma (s : ℝ) : ℝ :=
+ (Complex.Gamma s).re
+#align real.Gamma Real.Gamma
+-/
-theorem gamma_eq_integral {s : ℝ} (hs : 0 < s) : gamma s = ∫ x in Ioi 0, exp (-x) * x ^ (s - 1) :=
+#print Real.Gamma_eq_integral /-
+theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) : Gamma s = ∫ x in Ioi 0, exp (-x) * x ^ (s - 1) :=
by
- rw [Gamma, Complex.gamma_eq_integral (by rwa [Complex.ofReal_re] : 0 < Complex.re s)]
- dsimp only [Complex.gammaIntegral]
+ rw [Gamma, Complex.Gamma_eq_integral (by rwa [Complex.ofReal_re] : 0 < Complex.re s)]
+ dsimp only [Complex.GammaIntegral]
simp_rw [← Complex.ofReal_one, ← Complex.ofReal_sub]
suffices
∫ x : ℝ in Ioi 0, ↑(exp (-x)) * (x : ℂ) ^ ((s - 1 : ℝ) : ℂ) =
@@ -523,42 +582,56 @@ theorem gamma_eq_integral {s : ℝ} (hs : 0 < s) : gamma s = ∫ x in Ioi 0, exp
push_cast
rw [Complex.ofReal_cpow (le_of_lt hx)]
push_cast
-#align real.Gamma_eq_integral Real.gamma_eq_integral
+#align real.Gamma_eq_integral Real.Gamma_eq_integral
+-/
-theorem gamma_add_one {s : ℝ} (hs : s ≠ 0) : gamma (s + 1) = s * gamma s :=
+#print Real.Gamma_add_one /-
+theorem Gamma_add_one {s : ℝ} (hs : s ≠ 0) : Gamma (s + 1) = s * Gamma s :=
by
simp_rw [Gamma]
- rw [Complex.ofReal_add, Complex.ofReal_one, Complex.gamma_add_one, Complex.ofReal_mul_re]
+ rw [Complex.ofReal_add, Complex.ofReal_one, Complex.Gamma_add_one, Complex.ofReal_mul_re]
rwa [Complex.ofReal_ne_zero]
-#align real.Gamma_add_one Real.gamma_add_one
+#align real.Gamma_add_one Real.Gamma_add_one
+-/
-theorem gamma_one : gamma 1 = 1 := by
- rw [Gamma, Complex.ofReal_one, Complex.gamma_one, Complex.one_re]
-#align real.Gamma_one Real.gamma_one
+#print Real.Gamma_one /-
+theorem Gamma_one : Gamma 1 = 1 := by
+ rw [Gamma, Complex.ofReal_one, Complex.Gamma_one, Complex.one_re]
+#align real.Gamma_one Real.Gamma_one
+-/
-theorem Complex.gamma_of_real (s : ℝ) : Complex.gamma (s : ℂ) = gamma s := by
- rw [Gamma, eq_comm, ← Complex.conj_eq_iff_re, ← Complex.gamma_conj, Complex.conj_ofReal]
-#align complex.Gamma_of_real Complex.gamma_of_real
+#print Complex.Gamma_ofReal /-
+theorem Complex.Gamma_ofReal (s : ℝ) : Complex.Gamma (s : ℂ) = Gamma s := by
+ rw [Gamma, eq_comm, ← Complex.conj_eq_iff_re, ← Complex.Gamma_conj, Complex.conj_ofReal]
+#align complex.Gamma_of_real Complex.Gamma_ofReal
+-/
-theorem gamma_nat_eq_factorial (n : ℕ) : gamma (n + 1) = n ! := by
+#print Real.Gamma_nat_eq_factorial /-
+theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
rw [Gamma, Complex.ofReal_add, Complex.ofReal_nat_cast, Complex.ofReal_one,
- Complex.gamma_nat_eq_factorial, ← Complex.ofReal_nat_cast, Complex.ofReal_re]
-#align real.Gamma_nat_eq_factorial Real.gamma_nat_eq_factorial
+ Complex.Gamma_nat_eq_factorial, ← Complex.ofReal_nat_cast, Complex.ofReal_re]
+#align real.Gamma_nat_eq_factorial Real.Gamma_nat_eq_factorial
+-/
+#print Real.Gamma_zero /-
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
-theorem gamma_zero : gamma 0 = 0 := by
- simpa only [← Complex.ofReal_zero, Complex.gamma_of_real, Complex.ofReal_inj] using
- Complex.gamma_zero
-#align real.Gamma_zero Real.gamma_zero
+theorem Gamma_zero : Gamma 0 = 0 := by
+ simpa only [← Complex.ofReal_zero, Complex.Gamma_ofReal, Complex.ofReal_inj] using
+ Complex.Gamma_zero
+#align real.Gamma_zero Real.Gamma_zero
+-/
+#print Real.Gamma_neg_nat_eq_zero /-
/-- At `-n` for `n ∈ ℕ`, the Gamma function is undefined; by convention we assign it the value `0`.
-/
-theorem gamma_neg_nat_eq_zero (n : ℕ) : gamma (-n) = 0 := by
- simpa only [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Complex.gamma_of_real,
- Complex.ofReal_eq_zero] using Complex.gamma_neg_nat_eq_zero n
-#align real.Gamma_neg_nat_eq_zero Real.gamma_neg_nat_eq_zero
+theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 := by
+ simpa only [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Complex.Gamma_ofReal,
+ Complex.ofReal_eq_zero] using Complex.Gamma_neg_nat_eq_zero n
+#align real.Gamma_neg_nat_eq_zero Real.Gamma_neg_nat_eq_zero
+-/
-theorem gamma_pos_of_pos {s : ℝ} (hs : 0 < s) : 0 < gamma s :=
+#print Real.Gamma_pos_of_pos /-
+theorem Gamma_pos_of_pos {s : ℝ} (hs : 0 < s) : 0 < Gamma s :=
by
rw [Gamma_eq_integral hs]
have : (Function.support fun x : ℝ => exp (-x) * x ^ (s - 1)) ∩ Ioi 0 = Ioi 0 :=
@@ -573,11 +646,13 @@ theorem gamma_pos_of_pos {s : ℝ} (hs : 0 < s) : 0 < gamma s :=
· refine' eventually_of_mem (self_mem_ae_restrict measurableSet_Ioi) _
exact fun x hx => (mul_pos (exp_pos _) (rpow_pos_of_pos hx _)).le
· exact Gamma_integral_convergent hs
-#align real.Gamma_pos_of_pos Real.gamma_pos_of_pos
+#align real.Gamma_pos_of_pos Real.Gamma_pos_of_pos
+-/
+#print Real.Gamma_ne_zero /-
/-- The Gamma function does not vanish on `ℝ` (except at non-positive integers, where the function
is mathematically undefined and we set it to `0` by convention). -/
-theorem gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : gamma s ≠ 0 :=
+theorem Gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : Gamma s ≠ 0 :=
by
suffices ∀ {n : ℕ}, -(n : ℝ) < s → Gamma s ≠ 0
by
@@ -605,18 +680,23 @@ theorem gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : gamma s ≠ 0 :=
rw [Gamma_add_one, mul_ne_zero_iff] at this
· exact this.2
· simpa using hs 0
-#align real.Gamma_ne_zero Real.gamma_ne_zero
+#align real.Gamma_ne_zero Real.Gamma_ne_zero
+-/
-theorem gamma_eq_zero_iff (s : ℝ) : gamma s = 0 ↔ ∃ m : ℕ, s = -m :=
+#print Real.Gamma_eq_zero_iff /-
+theorem Gamma_eq_zero_iff (s : ℝ) : Gamma s = 0 ↔ ∃ m : ℕ, s = -m :=
⟨by contrapose!; exact Gamma_ne_zero, by rintro ⟨m, rfl⟩; exact Gamma_neg_nat_eq_zero m⟩
-#align real.Gamma_eq_zero_iff Real.gamma_eq_zero_iff
+#align real.Gamma_eq_zero_iff Real.Gamma_eq_zero_iff
+-/
-theorem differentiableAt_gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ gamma s :=
+#print Real.differentiableAt_Gamma /-
+theorem differentiableAt_Gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ Gamma s :=
by
- refine' (Complex.differentiableAt_gamma _ _).HasDerivAt.real_of_complex.DifferentiableAt
+ refine' (Complex.differentiableAt_Gamma _ _).HasDerivAt.real_of_complex.DifferentiableAt
simp_rw [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Ne.def, Complex.ofReal_inj]
exact hs
-#align real.differentiable_at_Gamma Real.differentiableAt_gamma
+#align real.differentiable_at_Gamma Real.differentiableAt_Gamma
+-/
end Real
mathlib commit https://github.com/leanprover-community/mathlib/commit/bf9bbbcf0c1c1ead18280b0d010e417b10abb1b6
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
! This file was ported from Lean 3 source module analysis.special_functions.gamma.basic
-! leanprover-community/mathlib commit cca40788df1b8755d5baf17ab2f27dacc2e17acb
+! leanprover-community/mathlib commit 8af7091a43227e179939ba132e54e54e9f3b089a
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -15,6 +15,9 @@ import Mathbin.Analysis.MellinTransform
/-!
# The Gamma function
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file defines the `Γ` function (of a real or complex variable `s`). We define this by Euler's
integral `Γ(s) = ∫ x in Ioi 0, exp (-x) * x ^ (s - 1)` in the range where this integral converges
(i.e., for `0 < s` in the real case, and `0 < re s` in the complex case).
mathlib commit https://github.com/leanprover-community/mathlib/commit/8efcf8022aac8e01df8d302dcebdbc25d6a886c8
@@ -432,7 +432,7 @@ theorem hasDerivAt_gammaIntegral {s : ℂ} (hs : 0 < s.re) :
HasDerivAt gammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s :=
by
rw [Gamma_integral_eq_mellin]
- convert (mellin_has_deriv_of_isBigO_rpow _ _ (lt_add_one _) _ hs).2
+ convert (mellin_hasDerivAt_of_isBigO_rpow _ _ (lt_add_one _) _ hs).2
· refine' (Continuous.continuousOn _).LocallyIntegrableOn measurableSet_Ioi
exact continuous_of_real.comp (real.continuous_exp.comp continuous_neg)
· rw [← is_O_norm_left]
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -513,7 +513,7 @@ theorem gamma_eq_integral {s : ℝ} (hs : 0 < s) : gamma s = ∫ x in Ioi 0, exp
dsimp only [Complex.gammaIntegral]
simp_rw [← Complex.ofReal_one, ← Complex.ofReal_sub]
suffices
- (∫ x : ℝ in Ioi 0, ↑(exp (-x)) * (x : ℂ) ^ ((s - 1 : ℝ) : ℂ)) =
+ ∫ x : ℝ in Ioi 0, ↑(exp (-x)) * (x : ℂ) ^ ((s - 1 : ℝ) : ℂ) =
∫ x : ℝ in Ioi 0, ((exp (-x) * x ^ (s - 1) : ℝ) : ℂ)
by rw [this, _root_.integral_of_real, Complex.ofReal_re]
refine' set_integral_congr measurableSet_Ioi fun x hx => _
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -518,7 +518,7 @@ theorem gamma_eq_integral {s : ℝ} (hs : 0 < s) : gamma s = ∫ x in Ioi 0, exp
by rw [this, _root_.integral_of_real, Complex.ofReal_re]
refine' set_integral_congr measurableSet_Ioi fun x hx => _
push_cast
- rw [Complex.of_real_cpow (le_of_lt hx)]
+ rw [Complex.ofReal_cpow (le_of_lt hx)]
push_cast
#align real.Gamma_eq_integral Real.gamma_eq_integral
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -180,7 +180,7 @@ private theorem Gamma_integrand_interval_integrable (s : ℂ) {X : ℝ} (hs : 0
private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
IntervalIntegrable (fun x => -((-x).exp * x ^ s) : ℝ → ℂ) volume 0 X :=
by
- convert(Gamma_integrand_interval_integrable (s + 1) _ hX).neg
+ convert (Gamma_integrand_interval_integrable (s + 1) _ hX).neg
· ext1; simp only [add_sub_cancel, Pi.neg_apply]
· simp only [add_re, one_re]; linarith
@@ -237,7 +237,7 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
(Gamma_integrand_deriv_integrable_A hs hX).add (Gamma_integrand_deriv_integrable_B hs hX)
have int_eval := integral_eq_sub_of_has_deriv_at_of_le hX cont.continuous_on F_der_I der_ible
-- We are basically done here but manipulating the output into the right form is fiddly.
- apply_fun fun x : ℂ => -x at int_eval
+ apply_fun fun x : ℂ => -x at int_eval
rw [intervalIntegral.integral_add (Gamma_integrand_deriv_integrable_A hs hX)
(Gamma_integrand_deriv_integrable_B hs hX),
intervalIntegral.integral_neg, neg_add, neg_neg] at int_eval
@@ -349,7 +349,7 @@ theorem gamma_eq_gammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : gamma s = ga
simp only [sub_sub_cancel_left] at i0
refine' lt_add_of_lt_of_nonneg i0 _
rw [← Nat.cast_zero, Nat.cast_le]; exact Nat.zero_le k
- convert(u <| n - ⌊1 - s.re⌋₊).symm; rw [Nat.add_sub_of_le]
+ convert (u <| n - ⌊1 - s.re⌋₊).symm; rw [Nat.add_sub_of_le]
by_cases 0 ≤ 1 - s.re
· apply Nat.le_of_lt_succ
exact_mod_cast lt_of_le_of_lt (Nat.floor_le h) (by linarith : 1 - s.re < n + 1)
@@ -432,7 +432,7 @@ theorem hasDerivAt_gammaIntegral {s : ℂ} (hs : 0 < s.re) :
HasDerivAt gammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s :=
by
rw [Gamma_integral_eq_mellin]
- convert(mellin_has_deriv_of_isBigO_rpow _ _ (lt_add_one _) _ hs).2
+ convert (mellin_has_deriv_of_isBigO_rpow _ _ (lt_add_one _) _ hs).2
· refine' (Continuous.continuousOn _).LocallyIntegrableOn measurableSet_Ioi
exact continuous_of_real.comp (real.continuous_exp.comp continuous_neg)
· rw [← is_O_norm_left]
@@ -468,7 +468,7 @@ theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
let n := ⌊1 - s.re⌋₊ + 1
have hn : 1 - s.re < n := by exact_mod_cast Nat.lt_floor_add_one (1 - s.re)
apply (differentiable_at_Gamma_aux s n hn hs).congr_of_eventuallyEq
- let S := { t : ℂ | 1 - t.re < n }
+ let S := {t : ℂ | 1 - t.re < n}
have : S ∈ 𝓝 s := by
rw [mem_nhds_iff]; use S
refine' ⟨subset.rfl, _, hn⟩
@@ -487,7 +487,8 @@ end GammaHasDeriv
theorem tendsto_self_mul_gamma_nhds_zero : Tendsto (fun z : ℂ => z * gamma z) (𝓝[≠] 0) (𝓝 1) :=
by
rw [show 𝓝 (1 : ℂ) = 𝓝 (Gamma (0 + 1)) by simp only [zero_add, Complex.gamma_one]]
- convert(tendsto.mono_left _ nhdsWithin_le_nhds).congr'
+ convert
+ (tendsto.mono_left _ nhdsWithin_le_nhds).congr'
(eventually_eq_of_mem self_mem_nhdsWithin Complex.gamma_add_one)
refine' ContinuousAt.comp _ (continuous_id.add continuous_const).ContinuousAt
refine' (Complex.differentiableAt_gamma _ fun m => _).ContinuousAt
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -237,10 +237,10 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
(Gamma_integrand_deriv_integrable_A hs hX).add (Gamma_integrand_deriv_integrable_B hs hX)
have int_eval := integral_eq_sub_of_has_deriv_at_of_le hX cont.continuous_on F_der_I der_ible
-- We are basically done here but manipulating the output into the right form is fiddly.
- apply_fun fun x : ℂ => -x at int_eval
+ apply_fun fun x : ℂ => -x at int_eval
rw [intervalIntegral.integral_add (Gamma_integrand_deriv_integrable_A hs hX)
(Gamma_integrand_deriv_integrable_B hs hX),
- intervalIntegral.integral_neg, neg_add, neg_neg] at int_eval
+ intervalIntegral.integral_neg, neg_add, neg_neg] at int_eval
rw [eq_sub_of_add_eq int_eval, sub_neg_eq_add, neg_sub, add_comm, add_sub]
simp only [sub_left_inj, add_left_inj]
have :
@@ -249,8 +249,8 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
by ext1; ring
rw [this]
have t := @integral_const_mul 0 X volume _ _ s fun x : ℝ => (-x).exp * x ^ (s - 1)
- dsimp at t; rw [← t, of_real_zero, zero_cpow]
- · rw [MulZeroClass.mul_zero, add_zero]; congr ; ext1; ring
+ dsimp at t ; rw [← t, of_real_zero, zero_cpow]
+ · rw [MulZeroClass.mul_zero, add_zero]; congr; ext1; ring
· contrapose! hs; rw [hs, zero_re]
#align complex.partial_Gamma_add_one Complex.partialGamma_add_one
@@ -298,14 +298,14 @@ theorem gammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
gammaAux n s = gammaAux n (s + 1) / s :=
by
induction' n with n hn generalizing s
- · simp only [Nat.cast_zero, neg_lt_zero] at h1
+ · simp only [Nat.cast_zero, neg_lt_zero] at h1
dsimp only [Gamma_aux]; rw [Gamma_integral_add_one h1]
rw [mul_comm, mul_div_cancel]; contrapose! h1; rw [h1]
simp
· dsimp only [Gamma_aux]
have hh1 : -(s + 1).re < n :=
by
- rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
+ rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
rw [add_re, one_re]; linarith
rw [← hn (s + 1) hh1]
#align complex.Gamma_aux_recurrence1 Complex.gammaAux_recurrence1
@@ -313,18 +313,18 @@ theorem gammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
theorem gammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
gammaAux n s = gammaAux (n + 1) s := by
cases n
- · simp only [Nat.cast_zero, neg_lt_zero] at h1
+ · simp only [Nat.cast_zero, neg_lt_zero] at h1
dsimp only [Gamma_aux]
rw [Gamma_integral_add_one h1, mul_div_cancel_left]
rintro rfl
- rw [zero_re] at h1
+ rw [zero_re] at h1
exact h1.false
· dsimp only [Gamma_aux]
have : Gamma_aux n (s + 1 + 1) / (s + 1) = Gamma_aux n (s + 1) :=
by
have hh1 : -(s + 1).re < n :=
by
- rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
+ rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
rw [add_re, one_re]; linarith
rw [Gamma_aux_recurrence1 (s + 1) n hh1]
rw [this]
@@ -346,7 +346,7 @@ theorem gamma_eq_gammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : gamma s = ga
refine' (Gamma_aux_recurrence2 s (⌊1 - s.re⌋₊ + k) _).symm
rw [Nat.cast_add]
have i0 := Nat.sub_one_lt_floor (1 - s.re)
- simp only [sub_sub_cancel_left] at i0
+ simp only [sub_sub_cancel_left] at i0
refine' lt_add_of_lt_of_nonneg i0 _
rw [← Nat.cast_zero, Nat.cast_le]; exact Nat.zero_le k
convert(u <| n - ⌊1 - s.re⌋₊).symm; rw [Nat.add_sub_of_le]
@@ -378,7 +378,7 @@ theorem gamma_nat_eq_factorial (n : ℕ) : gamma (n + 1) = n ! :=
induction' n with n hn
· simpa using Gamma_one
· rw [Gamma_add_one n.succ <| nat.cast_ne_zero.mpr <| Nat.succ_ne_zero n]
- simp only [Nat.cast_succ, Nat.factorial_succ, Nat.cast_mul]; congr ; exact hn
+ simp only [Nat.cast_succ, Nat.factorial_succ, Nat.cast_mul]; congr; exact hn
#align complex.Gamma_nat_eq_factorial Complex.gamma_nat_eq_factorial
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
@@ -395,7 +395,7 @@ theorem gamma_neg_nat_eq_zero (n : ℕ) : gamma (-n) = 0 :=
rw [neg_ne_zero, Nat.cast_ne_zero]
apply Nat.succ_ne_zero
have : -(n : ℂ) = -↑n.succ + 1 := by simp
- rw [this, Gamma_add_one _ A] at IH
+ rw [this, Gamma_add_one _ A] at IH
contrapose! IH
exact mul_ne_zero A IH
#align complex.Gamma_neg_nat_eq_zero Complex.gamma_neg_nat_eq_zero
@@ -449,15 +449,15 @@ theorem differentiableAt_gammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 :
by
induction' n with n hn generalizing s
· refine' (has_deriv_at_Gamma_integral _).DifferentiableAt
- rw [Nat.cast_zero] at h1; linarith
+ rw [Nat.cast_zero] at h1 ; linarith
· dsimp only [Gamma_aux]
specialize hn (s + 1)
- have a : 1 - (s + 1).re < ↑n := by rw [Nat.cast_succ] at h1;
+ have a : 1 - (s + 1).re < ↑n := by rw [Nat.cast_succ] at h1 ;
rw [Complex.add_re, Complex.one_re]; linarith
have b : ∀ m : ℕ, s + 1 ≠ -m := by
intro m; have := h2 (1 + m)
contrapose! this
- rw [← eq_sub_iff_add_eq] at this
+ rw [← eq_sub_iff_add_eq] at this
simpa using this
refine' DifferentiableAt.div (DifferentiableAt.comp _ (hn a b) _) _ _
simp; simp; simpa using h2 0
@@ -477,7 +477,7 @@ theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
rw [this]
refine' Continuous.isOpen_preimage continuous_re _ isOpen_Ioi
apply eventually_eq_of_mem this
- intro t ht; rw [mem_set_of_eq] at ht
+ intro t ht; rw [mem_set_of_eq] at ht
apply Gamma_eq_Gamma_aux; linarith
#align complex.differentiable_at_Gamma Complex.differentiableAt_gamma
@@ -585,20 +585,20 @@ theorem gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : gamma s ≠ 0 :=
induction n generalizing s
· intro hs
refine' (Gamma_pos_of_pos _).ne'
- rwa [Nat.cast_zero, neg_zero] at hs
+ rwa [Nat.cast_zero, neg_zero] at hs
· intro hs'
have : Gamma (s + 1) ≠ 0 := by
apply n_ih
· intro m
specialize hs (1 + m)
contrapose! hs
- rw [← eq_sub_iff_add_eq] at hs
+ rw [← eq_sub_iff_add_eq] at hs
rw [hs]
push_cast
ring
- · rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one, neg_add] at hs'
+ · rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one, neg_add] at hs'
linarith
- rw [Gamma_add_one, mul_ne_zero_iff] at this
+ rw [Gamma_add_one, mul_ne_zero_iff] at this
· exact this.2
· simpa using hs 0
#align real.Gamma_ne_zero Real.gamma_ne_zero
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
! This file was ported from Lean 3 source module analysis.special_functions.gamma.basic
-! leanprover-community/mathlib commit 917c3c072e487b3cccdbfeff17e75b40e45f66cb
+! leanprover-community/mathlib commit cca40788df1b8755d5baf17ab2f27dacc2e17acb
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -102,7 +102,7 @@ theorem Gamma_integral_convergent {s : ℂ} (hs : 0 < s.re) :
IntegrableOn (fun x => (-x).exp * x ^ (s - 1) : ℝ → ℂ) (Ioi 0) :=
by
constructor
- · refine' ContinuousOn.aEStronglyMeasurable _ measurableSet_Ioi
+ · refine' ContinuousOn.aestronglyMeasurable _ measurableSet_Ioi
apply (continuous_of_real.comp continuous_neg.exp).ContinuousOn.mul
apply ContinuousAt.continuousOn
intro x hx
@@ -483,6 +483,19 @@ theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
end GammaHasDeriv
+/-- At `s = 0`, the Gamma function has a simple pole with residue 1. -/
+theorem tendsto_self_mul_gamma_nhds_zero : Tendsto (fun z : ℂ => z * gamma z) (𝓝[≠] 0) (𝓝 1) :=
+ by
+ rw [show 𝓝 (1 : ℂ) = 𝓝 (Gamma (0 + 1)) by simp only [zero_add, Complex.gamma_one]]
+ convert(tendsto.mono_left _ nhdsWithin_le_nhds).congr'
+ (eventually_eq_of_mem self_mem_nhdsWithin Complex.gamma_add_one)
+ refine' ContinuousAt.comp _ (continuous_id.add continuous_const).ContinuousAt
+ refine' (Complex.differentiableAt_gamma _ fun m => _).ContinuousAt
+ rw [zero_add, ← of_real_nat_cast, ← of_real_neg, ← of_real_one, Ne.def, of_real_inj]
+ refine' (lt_of_le_of_lt _ zero_lt_one).ne'
+ exact neg_nonpos.mpr (Nat.cast_nonneg _)
+#align complex.tendsto_self_mul_Gamma_nhds_zero Complex.tendsto_self_mul_gamma_nhds_zero
+
end Complex
namespace Real
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -50,7 +50,7 @@ noncomputable section
open Filter intervalIntegral Set Real MeasureTheory Asymptotics
-open Nat Topology ComplexConjugate
+open scoped Nat Topology ComplexConjugate
namespace Real
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -59,8 +59,7 @@ theorem Gamma_integrand_isLittleO (s : ℝ) :
(fun x : ℝ => exp (-x) * x ^ s) =o[atTop] fun x : ℝ => exp (-(1 / 2) * x) :=
by
refine' is_o_of_tendsto (fun x hx => _) _
- · exfalso
- exact (exp_pos (-(1 / 2) * x)).ne' hx
+ · exfalso; exact (exp_pos (-(1 / 2) * x)).ne' hx
have :
(fun x : ℝ => exp (-x) * x ^ s / exp (-(1 / 2) * x)) =
(fun x : ℝ => exp (1 / 2 * x) / x ^ s)⁻¹ :=
@@ -107,11 +106,8 @@ theorem Gamma_integral_convergent {s : ℂ} (hs : 0 < s.re) :
apply (continuous_of_real.comp continuous_neg.exp).ContinuousOn.mul
apply ContinuousAt.continuousOn
intro x hx
- have : ContinuousAt (fun x : ℂ => x ^ (s - 1)) ↑x :=
- by
- apply continuousAt_cpow_const
- rw [of_real_re]
- exact Or.inl hx
+ have : ContinuousAt (fun x : ℂ => x ^ (s - 1)) ↑x := by apply continuousAt_cpow_const;
+ rw [of_real_re]; exact Or.inl hx
exact ContinuousAt.comp this continuous_of_real.continuous_at
· rw [← has_finite_integral_norm_iff]
refine' has_finite_integral.congr (Real.Gamma_integral_convergent hs).2 _
@@ -185,10 +181,8 @@ private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X
IntervalIntegrable (fun x => -((-x).exp * x ^ s) : ℝ → ℂ) volume 0 X :=
by
convert(Gamma_integrand_interval_integrable (s + 1) _ hX).neg
- · ext1
- simp only [add_sub_cancel, Pi.neg_apply]
- · simp only [add_re, one_re]
- linarith
+ · ext1; simp only [add_sub_cancel, Pi.neg_apply]
+ · simp only [add_re, one_re]; linarith
private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y : ℝ} (hY : 0 ≤ Y) :
IntervalIntegrable (fun x : ℝ => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) volume 0 Y :=
@@ -196,9 +190,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
have :
(fun x => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) =
(fun x => s * ((-x).exp * x ^ (s - 1)) : ℝ → ℂ) :=
- by
- ext1
- ring
+ by ext1; ring
rw [this, intervalIntegrable_iff_integrable_Ioc_of_le hY]
constructor
· refine' (continuous_on_const.mul _).AEStronglyMeasurable measurableSet_Ioc
@@ -206,9 +198,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
apply ContinuousAt.continuousOn
intro x hx
refine' (_ : ContinuousAt (fun x : ℂ => x ^ (s - 1)) _).comp continuous_of_real.continuous_at
- apply continuousAt_cpow_const
- rw [of_real_re]
- exact Or.inl hx.1
+ apply continuousAt_cpow_const; rw [of_real_re]; exact Or.inl hx.1
rw [← has_finite_integral_norm_iff]
simp_rw [norm_eq_abs, map_mul]
refine'
@@ -216,8 +206,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
_).const_mul
_
rw [eventually_eq, ae_restrict_iff']
- · apply ae_of_all
- intro x hx
+ · apply ae_of_all; intro x hx
rw [abs_of_nonneg (exp_pos _).le, abs_cpow_eq_rpow_re_of_pos hx.1]
simp
· exact measurableSet_Ioc
@@ -257,19 +246,12 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
have :
(fun x => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) =
(fun x => s * (-x).exp * x ^ (s - 1) : ℝ → ℂ) :=
- by
- ext1
- ring
+ by ext1; ring
rw [this]
have t := @integral_const_mul 0 X volume _ _ s fun x : ℝ => (-x).exp * x ^ (s - 1)
- dsimp at t
- rw [← t, of_real_zero, zero_cpow]
- · rw [MulZeroClass.mul_zero, add_zero]
- congr
- ext1
- ring
- · contrapose! hs
- rw [hs, zero_re]
+ dsimp at t; rw [← t, of_real_zero, zero_cpow]
+ · rw [MulZeroClass.mul_zero, add_zero]; congr ; ext1; ring
+ · contrapose! hs; rw [hs, zero_re]
#align complex.partial_Gamma_add_one Complex.partialGamma_add_one
/-- The recurrence relation for the `Γ` integral. -/
@@ -279,9 +261,7 @@ theorem gammaIntegral_add_one {s : ℂ} (hs : 0 < s.re) :
suffices tendsto (s + 1).partialGamma at_top (𝓝 <| s * Gamma_integral s)
by
refine' tendsto_nhds_unique _ this
- apply tendsto_partial_Gamma
- rw [add_re, one_re]
- linarith
+ apply tendsto_partial_Gamma; rw [add_re, one_re]; linarith
have : (fun X : ℝ => s * partial_Gamma s X - X ^ s * (-X).exp) =ᶠ[at_top] (s + 1).partialGamma :=
by
apply eventually_eq_of_mem (Ici_mem_at_top (0 : ℝ))
@@ -295,8 +275,7 @@ theorem gammaIntegral_add_one {s : ℂ} (hs : 0 < s.re) :
have : (fun e : ℝ => ‖-(e : ℂ) ^ s * (-e).exp‖) =ᶠ[at_top] fun e : ℝ => e ^ s.re * (-1 * e).exp :=
by
refine' eventually_eq_of_mem (Ioi_mem_at_top 0) _
- intro x hx
- dsimp only
+ intro x hx; dsimp only
rw [norm_eq_abs, map_mul, abs.map_neg, abs_cpow_eq_rpow_re_of_pos hx,
abs_of_nonneg (exp_pos (-x)).le, neg_mul, one_mul]
exact (tendsto_congr' this).mpr (tendsto_rpow_mul_exp_neg_mul_atTop_nhds_0 _ _ zero_lt_one)
@@ -320,18 +299,14 @@ theorem gammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
by
induction' n with n hn generalizing s
· simp only [Nat.cast_zero, neg_lt_zero] at h1
- dsimp only [Gamma_aux]
- rw [Gamma_integral_add_one h1]
- rw [mul_comm, mul_div_cancel]
- contrapose! h1
- rw [h1]
+ dsimp only [Gamma_aux]; rw [Gamma_integral_add_one h1]
+ rw [mul_comm, mul_div_cancel]; contrapose! h1; rw [h1]
simp
· dsimp only [Gamma_aux]
have hh1 : -(s + 1).re < n :=
by
rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
- rw [add_re, one_re]
- linarith
+ rw [add_re, one_re]; linarith
rw [← hn (s + 1) hh1]
#align complex.Gamma_aux_recurrence1 Complex.gammaAux_recurrence1
@@ -350,8 +325,7 @@ theorem gammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
have hh1 : -(s + 1).re < n :=
by
rw [Nat.succ_eq_add_one, Nat.cast_add, Nat.cast_one] at h1
- rw [add_re, one_re]
- linarith
+ rw [add_re, one_re]; linarith
rw [Gamma_aux_recurrence1 (s + 1) n hh1]
rw [this]
#align complex.Gamma_aux_recurrence2 Complex.gammaAux_recurrence2
@@ -366,8 +340,7 @@ theorem gamma_eq_gammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : gamma s = ga
by
have u : ∀ k : ℕ, Gamma_aux (⌊1 - s.re⌋₊ + k) s = Gamma s :=
by
- intro k
- induction' k with k hk
+ intro k; induction' k with k hk
· simp [Gamma]
· rw [← hk, Nat.succ_eq_add_one, ← add_assoc]
refine' (Gamma_aux_recurrence2 s (⌊1 - s.re⌋₊ + k) _).symm
@@ -375,16 +348,12 @@ theorem gamma_eq_gammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : gamma s = ga
have i0 := Nat.sub_one_lt_floor (1 - s.re)
simp only [sub_sub_cancel_left] at i0
refine' lt_add_of_lt_of_nonneg i0 _
- rw [← Nat.cast_zero, Nat.cast_le]
- exact Nat.zero_le k
- convert(u <| n - ⌊1 - s.re⌋₊).symm
- rw [Nat.add_sub_of_le]
+ rw [← Nat.cast_zero, Nat.cast_le]; exact Nat.zero_le k
+ convert(u <| n - ⌊1 - s.re⌋₊).symm; rw [Nat.add_sub_of_le]
by_cases 0 ≤ 1 - s.re
· apply Nat.le_of_lt_succ
exact_mod_cast lt_of_le_of_lt (Nat.floor_le h) (by linarith : 1 - s.re < n + 1)
- · rw [Nat.floor_of_nonpos]
- linarith
- linarith
+ · rw [Nat.floor_of_nonpos]; linarith; linarith
#align complex.Gamma_eq_Gamma_aux Complex.gamma_eq_gammaAux
/-- The recurrence relation for the `Γ` function. -/
@@ -392,25 +361,16 @@ theorem gamma_add_one (s : ℂ) (h2 : s ≠ 0) : gamma (s + 1) = s * gamma s :=
by
let n := ⌊1 - s.re⌋₊
have t1 : -s.re < n := by simpa only [sub_sub_cancel_left] using Nat.sub_one_lt_floor (1 - s.re)
- have t2 : -(s + 1).re < n := by
- rw [add_re, one_re]
- linarith
+ have t2 : -(s + 1).re < n := by rw [add_re, one_re]; linarith
rw [Gamma_eq_Gamma_aux s n t1, Gamma_eq_Gamma_aux (s + 1) n t2, Gamma_aux_recurrence1 s n t1]
- field_simp
- ring
+ field_simp; ring
#align complex.Gamma_add_one Complex.gamma_add_one
theorem gamma_eq_integral {s : ℂ} (hs : 0 < s.re) : gamma s = gammaIntegral s :=
- gamma_eq_gammaAux s 0
- (by
- norm_cast
- linarith)
+ gamma_eq_gammaAux s 0 (by norm_cast; linarith)
#align complex.Gamma_eq_integral Complex.gamma_eq_integral
-theorem gamma_one : gamma 1 = 1 := by
- rw [Gamma_eq_integral]
- simpa using Gamma_integral_one
- simp
+theorem gamma_one : gamma 1 = 1 := by rw [Gamma_eq_integral]; simpa using Gamma_integral_one; simp
#align complex.Gamma_one Complex.gamma_one
theorem gamma_nat_eq_factorial (n : ℕ) : gamma (n + 1) = n ! :=
@@ -418,9 +378,7 @@ theorem gamma_nat_eq_factorial (n : ℕ) : gamma (n + 1) = n ! :=
induction' n with n hn
· simpa using Gamma_one
· rw [Gamma_add_one n.succ <| nat.cast_ne_zero.mpr <| Nat.succ_ne_zero n]
- simp only [Nat.cast_succ, Nat.factorial_succ, Nat.cast_mul]
- congr
- exact hn
+ simp only [Nat.cast_succ, Nat.factorial_succ, Nat.cast_mul]; congr ; exact hn
#align complex.Gamma_nat_eq_factorial Complex.gamma_nat_eq_factorial
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
@@ -447,8 +405,7 @@ theorem gamma_conj (s : ℂ) : gamma (conj s) = conj (gamma s) :=
suffices : ∀ (n : ℕ) (s : ℂ), Gamma_aux n (conj s) = conj (Gamma_aux n s); exact this _ _
intro n
induction' n with n IH
- · rw [Gamma_aux]
- exact Gamma_integral_conj
+ · rw [Gamma_aux]; exact Gamma_integral_conj
· intro s
rw [Gamma_aux]
dsimp only
@@ -492,24 +449,18 @@ theorem differentiableAt_gammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 :
by
induction' n with n hn generalizing s
· refine' (has_deriv_at_Gamma_integral _).DifferentiableAt
- rw [Nat.cast_zero] at h1
- linarith
+ rw [Nat.cast_zero] at h1; linarith
· dsimp only [Gamma_aux]
specialize hn (s + 1)
- have a : 1 - (s + 1).re < ↑n := by
- rw [Nat.cast_succ] at h1
- rw [Complex.add_re, Complex.one_re]
- linarith
+ have a : 1 - (s + 1).re < ↑n := by rw [Nat.cast_succ] at h1;
+ rw [Complex.add_re, Complex.one_re]; linarith
have b : ∀ m : ℕ, s + 1 ≠ -m := by
- intro m
- have := h2 (1 + m)
+ intro m; have := h2 (1 + m)
contrapose! this
rw [← eq_sub_iff_add_eq] at this
simpa using this
refine' DifferentiableAt.div (DifferentiableAt.comp _ (hn a b) _) _ _
- simp
- simp
- simpa using h2 0
+ simp; simp; simpa using h2 0
#align complex.differentiable_at_Gamma_aux Complex.differentiableAt_gammaAux
theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℂ gamma s :=
@@ -519,20 +470,15 @@ theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
apply (differentiable_at_Gamma_aux s n hn hs).congr_of_eventuallyEq
let S := { t : ℂ | 1 - t.re < n }
have : S ∈ 𝓝 s := by
- rw [mem_nhds_iff]
- use S
+ rw [mem_nhds_iff]; use S
refine' ⟨subset.rfl, _, hn⟩
- have : S = re ⁻¹' Ioi (1 - n : ℝ) := by
- ext
- rw [preimage, Ioi, mem_set_of_eq, mem_set_of_eq, mem_set_of_eq]
- exact sub_lt_comm
+ have : S = re ⁻¹' Ioi (1 - n : ℝ) := by ext;
+ rw [preimage, Ioi, mem_set_of_eq, mem_set_of_eq, mem_set_of_eq]; exact sub_lt_comm
rw [this]
refine' Continuous.isOpen_preimage continuous_re _ isOpen_Ioi
apply eventually_eq_of_mem this
- intro t ht
- rw [mem_set_of_eq] at ht
- apply Gamma_eq_Gamma_aux
- linarith
+ intro t ht; rw [mem_set_of_eq] at ht
+ apply Gamma_eq_Gamma_aux; linarith
#align complex.differentiable_at_Gamma Complex.differentiableAt_gamma
end GammaHasDeriv
@@ -619,8 +565,7 @@ theorem gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : gamma s ≠ 0 :=
suffices ∀ {n : ℕ}, -(n : ℝ) < s → Gamma s ≠ 0
by
apply this
- swap
- use ⌊-s⌋₊ + 1
+ swap; use ⌊-s⌋₊ + 1
rw [neg_lt, Nat.cast_add, Nat.cast_one]
exact Nat.lt_floor_add_one _
intro n
@@ -646,11 +591,7 @@ theorem gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : gamma s ≠ 0 :=
#align real.Gamma_ne_zero Real.gamma_ne_zero
theorem gamma_eq_zero_iff (s : ℝ) : gamma s = 0 ↔ ∃ m : ℕ, s = -m :=
- ⟨by
- contrapose!
- exact Gamma_ne_zero, by
- rintro ⟨m, rfl⟩
- exact Gamma_neg_nat_eq_zero m⟩
+ ⟨by contrapose!; exact Gamma_ne_zero, by rintro ⟨m, rfl⟩; exact Gamma_neg_nat_eq_zero m⟩
#align real.Gamma_eq_zero_iff Real.gamma_eq_zero_iff
theorem differentiableAt_gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ gamma s :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
! This file was ported from Lean 3 source module analysis.special_functions.gamma.basic
-! leanprover-community/mathlib commit b76e9f654df09f8a832aeee712511fe5f3e57869
+! leanprover-community/mathlib commit 917c3c072e487b3cccdbfeff17e75b40e45f66cb
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -180,7 +180,6 @@ private theorem Gamma_integrand_interval_integrable (s : ℂ) {X : ℝ} (hs : 0
by
rw [intervalIntegrable_iff_integrable_Ioc_of_le hX]
exact integrable_on.mono_set (Gamma_integral_convergent hs) Ioc_subset_Ioi_self
-#align complex.Gamma_integrand_interval_integrable complex.Gamma_integrand_interval_integrable
private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
IntervalIntegrable (fun x => -((-x).exp * x ^ s) : ℝ → ℂ) volume 0 X :=
@@ -190,7 +189,6 @@ private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X
simp only [add_sub_cancel, Pi.neg_apply]
· simp only [add_re, one_re]
linarith
-#align complex.Gamma_integrand_deriv_integrable_A complex.Gamma_integrand_deriv_integrable_A
private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y : ℝ} (hY : 0 ≤ Y) :
IntervalIntegrable (fun x : ℝ => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) volume 0 Y :=
@@ -223,7 +221,6 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
rw [abs_of_nonneg (exp_pos _).le, abs_cpow_eq_rpow_re_of_pos hx.1]
simp
· exact measurableSet_Ioc
-#align complex.Gamma_integrand_deriv_integrable_B complex.Gamma_integrand_deriv_integrable_B
/-- The recurrence relation for the indefinite version of the `Γ` function. -/
theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
@@ -478,7 +475,7 @@ theorem hasDerivAt_gammaIntegral {s : ℂ} (hs : 0 < s.re) :
HasDerivAt gammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s :=
by
rw [Gamma_integral_eq_mellin]
- convert mellin_has_deriv_of_isBigO_rpow _ _ (lt_add_one _) _ hs
+ convert(mellin_has_deriv_of_isBigO_rpow _ _ (lt_add_one _) _ hs).2
· refine' (Continuous.continuousOn _).LocallyIntegrableOn measurableSet_Ioi
exact continuous_of_real.comp (real.continuous_exp.comp continuous_neg)
· rw [← is_O_norm_left]
mathlib commit https://github.com/leanprover-community/mathlib/commit/75e7fca56381d056096ce5d05e938f63a6567828
@@ -103,7 +103,7 @@ theorem Gamma_integral_convergent {s : ℂ} (hs : 0 < s.re) :
IntegrableOn (fun x => (-x).exp * x ^ (s - 1) : ℝ → ℂ) (Ioi 0) :=
by
constructor
- · refine' ContinuousOn.aeStronglyMeasurable _ measurableSet_Ioi
+ · refine' ContinuousOn.aEStronglyMeasurable _ measurableSet_Ioi
apply (continuous_of_real.comp continuous_neg.exp).ContinuousOn.mul
apply ContinuousAt.continuousOn
intro x hx
@@ -203,7 +203,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
ring
rw [this, intervalIntegrable_iff_integrable_Ioc_of_le hY]
constructor
- · refine' (continuous_on_const.mul _).AeStronglyMeasurable measurableSet_Ioc
+ · refine' (continuous_on_const.mul _).AEStronglyMeasurable measurableSet_Ioc
apply (continuous_of_real.comp continuous_neg.exp).ContinuousOn.mul
apply ContinuousAt.continuousOn
intro x hx
mathlib commit https://github.com/leanprover-community/mathlib/commit/f8c79b0a623404854a2902b836eac32156fd7712
@@ -4,13 +4,13 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
! This file was ported from Lean 3 source module analysis.special_functions.gamma.basic
-! leanprover-community/mathlib commit 7982767093ae38cba236487f9c9dd9cd99f63c16
+! leanprover-community/mathlib commit b76e9f654df09f8a832aeee712511fe5f3e57869
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.MeasureTheory.Integral.ExpDecay
import Mathbin.Analysis.SpecialFunctions.ImproperIntegrals
-import Mathbin.Analysis.Calculus.ParametricIntegral
+import Mathbin.Analysis.MellinTransform
/-!
# The Gamma function
@@ -462,191 +462,39 @@ theorem gamma_conj (s : ℂ) : gamma (conj s) = conj (gamma s) :=
end GammaDef
-end Complex
-
/-! Now check that the `Γ` function is differentiable, wherever this makes sense. -/
section GammaHasDeriv
-/-- Integrand for the derivative of the `Γ` function -/
-def dGammaIntegrand (s : ℂ) (x : ℝ) : ℂ :=
- exp (-x) * log x * x ^ (s - 1)
-#align dGamma_integrand dGammaIntegrand
-
-/-- Integrand for the absolute value of the derivative of the `Γ` function -/
-def dGammaIntegrandReal (s x : ℝ) : ℝ :=
- |exp (-x) * log x * x ^ (s - 1)|
-#align dGamma_integrand_real dGammaIntegrandReal
+/-- Rewrite the Gamma integral as an example of a Mellin transform. -/
+theorem gammaIntegral_eq_mellin : gammaIntegral = mellin fun x => Real.exp (-x) :=
+ funext fun s => by simp only [mellin, Gamma_integral, smul_eq_mul, mul_comm]
+#align complex.Gamma_integral_eq_mellin Complex.gammaIntegral_eq_mellin
-theorem dGamma_integrand_isLittleO_atTop (s : ℝ) :
- (fun x : ℝ => exp (-x) * log x * x ^ (s - 1)) =o[atTop] fun x => exp (-(1 / 2) * x) :=
- by
- refine' is_o_of_tendsto (fun x hx => _) _
- · exfalso
- exact (-(1 / 2) * x).exp_pos.ne' hx
- have :
- eventually_eq at_top (fun x : ℝ => exp (-x) * log x * x ^ (s - 1) / exp (-(1 / 2) * x))
- (fun x : ℝ => (fun z : ℝ => exp (1 / 2 * z) / z ^ s) x * (fun z : ℝ => z / log z) x)⁻¹ :=
- by
- refine' eventually_of_mem (Ioi_mem_at_top 1) _
- intro x hx
- dsimp
- replace hx := lt_trans zero_lt_one (mem_Ioi.mp hx)
- rw [Real.exp_neg, neg_mul, Real.exp_neg, rpow_sub hx]
- have : exp x = exp (x / 2) * exp (x / 2) := by rw [← Real.exp_add, add_halves]
- rw [this]
- field_simp [hx.ne', exp_ne_zero (x / 2)]
- ring
- refine' tendsto.congr' this.symm (tendsto.inv_tendsto_at_top _)
- apply tendsto.at_top_mul_at_top (tendsto_exp_mul_div_rpow_atTop s (1 / 2) one_half_pos)
- refine' tendsto.congr' _ ((tendsto_exp_div_pow_at_top 1).comp tendsto_log_at_top)
- apply eventually_eq_of_mem (Ioi_mem_at_top (0 : ℝ))
- intro x hx
- simp [exp_log hx]
-#align dGamma_integrand_is_o_at_top dGamma_integrand_isLittleO_atTop
-
-/-- Absolute convergence of the integral which will give the derivative of the `Γ` function on
-`1 < re s`. -/
-theorem dGamma_integral_abs_convergent (s : ℝ) (hs : 1 < s) :
- IntegrableOn (fun x : ℝ => ‖exp (-x) * log x * x ^ (s - 1)‖) (Ioi 0) :=
+/-- The derivative of the `Γ` integral, at any `s ∈ ℂ` with `1 < re s`, is given by the Melllin
+transform of `log t * exp (-t)`. -/
+theorem hasDerivAt_gammaIntegral {s : ℂ} (hs : 0 < s.re) :
+ HasDerivAt gammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s :=
by
- rw [← Ioc_union_Ioi_eq_Ioi (@zero_le_one ℝ _ _ _ _), integrable_on_union]
- refine' ⟨⟨_, _⟩, _⟩
- · refine' ContinuousOn.aeStronglyMeasurable (ContinuousOn.mul _ _).norm measurableSet_Ioc
- · refine' (continuous_exp.comp continuous_neg).ContinuousOn.mul (continuous_on_log.mono _)
- simp
- · apply continuous_on_id.rpow_const
- intro x hx
- right
- linarith
- · apply has_finite_integral_of_bounded
- swap
- · exact 1 / (s - 1)
- refine' (ae_restrict_iff' measurableSet_Ioc).mpr (ae_of_all _ fun x hx => _)
- rw [norm_norm, norm_eq_abs, mul_assoc, abs_mul, ← one_mul (1 / (s - 1))]
- refine' mul_le_mul _ _ (abs_nonneg _) zero_le_one
- · rw [abs_of_pos (exp_pos (-x)), exp_le_one_iff, neg_le, neg_zero]
- exact hx.1.le
- · exact (abs_log_mul_self_rpow_lt x (s - 1) hx.1 hx.2 (sub_pos.mpr hs)).le
- · have := (dGamma_integrand_isLittleO_atTop s).IsBigO.norm_left
- refine' integrable_of_isBigO_exp_neg one_half_pos (ContinuousOn.mul _ _).norm this
- · refine' (continuous_exp.comp continuous_neg).ContinuousOn.mul (continuous_on_log.mono _)
- simp
- · apply ContinuousAt.continuousOn fun x hx => _
- apply continuous_at_id.rpow continuousAt_const
- dsimp
- right
- linarith
-#align dGamma_integral_abs_convergent dGamma_integral_abs_convergent
-
-/-- A uniform bound for the `s`-derivative of the `Γ` integrand for `s` in vertical strips. -/
-theorem loc_unif_bound_dGammaIntegrand {t : ℂ} {s1 s2 x : ℝ} (ht1 : s1 ≤ t.re) (ht2 : t.re ≤ s2)
- (hx : 0 < x) : ‖dGammaIntegrand t x‖ ≤ dGammaIntegrandReal s1 x + dGammaIntegrandReal s2 x :=
- by
- rcases le_or_lt 1 x with (h | h)
- · -- case 1 ≤ x
- refine' le_add_of_nonneg_of_le (abs_nonneg _) _
- rw [dGammaIntegrand, dGammaIntegrandReal, Complex.norm_eq_abs, map_mul, abs_mul, ←
- Complex.ofReal_mul, Complex.abs_ofReal]
- refine' mul_le_mul_of_nonneg_left _ (abs_nonneg _)
- rw [Complex.abs_cpow_eq_rpow_re_of_pos hx]
- refine' le_trans _ (le_abs_self _)
- apply rpow_le_rpow_of_exponent_le h
- rw [Complex.sub_re, Complex.one_re]
- linarith
- · refine' le_add_of_le_of_nonneg _ (abs_nonneg _)
- rw [dGammaIntegrand, dGammaIntegrandReal, Complex.norm_eq_abs, map_mul, abs_mul, ←
- Complex.ofReal_mul, Complex.abs_ofReal]
- refine' mul_le_mul_of_nonneg_left _ (abs_nonneg _)
- rw [Complex.abs_cpow_eq_rpow_re_of_pos hx]
- refine' le_trans _ (le_abs_self _)
- apply rpow_le_rpow_of_exponent_ge hx h.le
- rw [Complex.sub_re, Complex.one_re]
- linarith
-#align loc_unif_bound_dGamma_integrand loc_unif_bound_dGammaIntegrand
-
-namespace Complex
-
-/-- The derivative of the `Γ` integral, at any `s ∈ ℂ` with `1 < re s`, is given by the integral
-of `exp (-x) * log x * x ^ (s - 1)` over `[0, ∞)`. -/
-theorem hasDerivAt_gammaIntegral {s : ℂ} (hs : 1 < s.re) :
- IntegrableOn (fun x => Real.exp (-x) * Real.log x * x ^ (s - 1) : ℝ → ℂ) (Ioi 0) volume ∧
- HasDerivAt gammaIntegral (∫ x : ℝ in Ioi 0, Real.exp (-x) * Real.log x * x ^ (s - 1)) s :=
- by
- let ε := (s.re - 1) / 2
- let μ := volume.restrict (Ioi (0 : ℝ))
- let bound := fun x : ℝ => dGammaIntegrandReal (s.re - ε) x + dGammaIntegrandReal (s.re + ε) x
- have cont : ∀ t : ℂ, ContinuousOn (fun x => Real.exp (-x) * x ^ (t - 1) : ℝ → ℂ) (Ioi 0) :=
- by
- intro t
- apply (continuous_of_real.comp continuous_neg.exp).ContinuousOn.mul
- apply ContinuousAt.continuousOn
- intro x hx
- refine' (continuousAt_cpow_const _).comp continuous_of_real.continuous_at
- exact Or.inl hx
- have eps_pos : 0 < ε := div_pos (sub_pos.mpr hs) zero_lt_two
- have hF_meas :
- ∀ᶠ t : ℂ in 𝓝 s, ae_strongly_measurable (fun x => Real.exp (-x) * x ^ (t - 1) : ℝ → ℂ) μ :=
- by
- apply eventually_of_forall
- intro t
- exact (cont t).AeStronglyMeasurable measurableSet_Ioi
- have hF'_meas : ae_strongly_measurable (dGammaIntegrand s) μ :=
- by
- refine' ContinuousOn.aeStronglyMeasurable _ measurableSet_Ioi
- have : dGammaIntegrand s = (fun x => Real.exp (-x) * x ^ (s - 1) * Real.log x : ℝ → ℂ) :=
- by
- ext1
- simp only [dGammaIntegrand]
- ring
- rw [this]
- refine' ContinuousOn.mul (cont s) (ContinuousAt.continuousOn _)
- exact fun x hx => continuous_of_real.continuous_at.comp (continuous_at_log (mem_Ioi.mp hx).ne')
- have h_bound : ∀ᵐ x : ℝ ∂μ, ∀ t : ℂ, t ∈ Metric.ball s ε → ‖dGammaIntegrand t x‖ ≤ bound x :=
- by
- refine' (ae_restrict_iff' measurableSet_Ioi).mpr (ae_of_all _ fun x hx => _)
- intro t ht
- rw [Metric.mem_ball, Complex.dist_eq] at ht
- replace ht := lt_of_le_of_lt (Complex.abs_re_le_abs <| t - s) ht
- rw [Complex.sub_re, @abs_sub_lt_iff ℝ _ t.re s.re ((s.re - 1) / 2)] at ht
- refine' loc_unif_bound_dGammaIntegrand _ _ hx
- all_goals simp only [ε]; linarith
- have bound_integrable : integrable bound μ :=
- by
- apply integrable.add
- · refine' dGamma_integral_abs_convergent (s.re - ε) _
- field_simp
- rw [one_lt_div]
- · linarith
- · exact zero_lt_two
- · refine' dGamma_integral_abs_convergent (s.re + ε) _
- linarith
- have h_diff :
- ∀ᵐ x : ℝ ∂μ,
- ∀ t : ℂ,
- t ∈ Metric.ball s ε →
- HasDerivAt (fun u => Real.exp (-x) * x ^ (u - 1) : ℂ → ℂ) (dGammaIntegrand t x) t :=
- by
- refine' (ae_restrict_iff' measurableSet_Ioi).mpr (ae_of_all _ fun x hx => _)
- intro t ht
- rw [mem_Ioi] at hx
- simp only [dGammaIntegrand]
- rw [mul_assoc]
- apply HasDerivAt.const_mul
- rw [of_real_log hx.le, mul_comm]
- have := ((hasDerivAt_id t).sub_const 1).const_cpow (Or.inl (of_real_ne_zero.mpr hx.ne'))
- rwa [mul_one] at this
- exact
- hasDerivAt_integral_of_dominated_loc_of_deriv_le eps_pos hF_meas
- (Gamma_integral_convergent (zero_lt_one.trans hs)) hF'_meas h_bound bound_integrable h_diff
+ rw [Gamma_integral_eq_mellin]
+ convert mellin_has_deriv_of_isBigO_rpow _ _ (lt_add_one _) _ hs
+ · refine' (Continuous.continuousOn _).LocallyIntegrableOn measurableSet_Ioi
+ exact continuous_of_real.comp (real.continuous_exp.comp continuous_neg)
+ · rw [← is_O_norm_left]
+ simp_rw [Complex.norm_eq_abs, abs_of_real, ← Real.norm_eq_abs, is_O_norm_left]
+ simpa only [neg_one_mul] using (isLittleO_exp_neg_mul_rpow_atTop zero_lt_one _).IsBigO
+ · simp_rw [neg_zero, rpow_zero]
+ refine' is_O_const_of_tendsto (_ : tendsto _ _ (𝓝 1)) one_ne_zero
+ rw [(by simp : (1 : ℂ) = Real.exp (-0))]
+ exact (continuous_of_real.comp (real.continuous_exp.comp continuous_neg)).ContinuousWithinAt
#align complex.has_deriv_at_Gamma_integral Complex.hasDerivAt_gammaIntegral
theorem differentiableAt_gammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 : ∀ m : ℕ, s ≠ -m) :
DifferentiableAt ℂ (gammaAux n) s :=
by
induction' n with n hn generalizing s
- · refine' (has_deriv_at_Gamma_integral _).2.DifferentiableAt
+ · refine' (has_deriv_at_Gamma_integral _).DifferentiableAt
rw [Nat.cast_zero] at h1
linarith
· dsimp only [Gamma_aux]
@@ -690,10 +538,10 @@ theorem differentiableAt_gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
linarith
#align complex.differentiable_at_Gamma Complex.differentiableAt_gamma
-end Complex
-
end GammaHasDeriv
+end Complex
+
namespace Real
/-- The `Γ` function (of a real variable `s`). -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/7ad820c4997738e2f542f8a20f32911f52020e26
@@ -323,7 +323,9 @@ theorem Gamma_eq_GammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : Gamma s = Ga
by_cases h : 0 ≤ 1 - s.re
· apply Nat.le_of_lt_succ
exact_mod_cast lt_of_le_of_lt (Nat.floor_le h) (by linarith : 1 - s.re < n + 1)
- · rw [Nat.floor_of_nonpos]; omega; linarith
+ · rw [Nat.floor_of_nonpos]
+ · omega
+ · linarith
#align complex.Gamma_eq_Gamma_aux Complex.Gamma_eq_GammaAux
/-- The recurrence relation for the `Γ` function. -/
@@ -611,7 +613,8 @@ is mathematically undefined and we set it to `0` by convention). -/
theorem Gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : Gamma s ≠ 0 := by
suffices ∀ {n : ℕ}, -(n : ℝ) < s → Gamma s ≠ 0 by
apply this
- swap; exact ⌊-s⌋₊ + 1
+ swap
+ · exact ⌊-s⌋₊ + 1
rw [neg_lt, Nat.cast_add, Nat.cast_one]
exact Nat.lt_floor_add_one _
intro n
b ≠ 0 → a * b / b = a
(#12424)
This lets us unify a few lemmas between GroupWithZero
and EuclideanDomain
and two lemmas that were previously proved separately for Nat
, Int
, Polynomial
.
@@ -332,7 +332,7 @@ theorem Gamma_add_one (s : ℂ) (h2 : s ≠ 0) : Gamma (s + 1) = s * Gamma s :=
have t1 : -s.re < n := by simpa only [sub_sub_cancel_left] using Nat.sub_one_lt_floor (1 - s.re)
have t2 : -(s + 1).re < n := by rw [add_re, one_re]; linarith
rw [Gamma_eq_GammaAux s n t1, Gamma_eq_GammaAux (s + 1) n t2, GammaAux_recurrence1 s n t1]
- field_simp; ring
+ field_simp
#align complex.Gamma_add_one Complex.Gamma_add_one
theorem Gamma_eq_integral {s : ℂ} (hs : 0 < s.re) : Gamma s = GammaIntegral s :=
set_integral
with setIntegral
(#12215)
Done with a global search and replace, and then (to fix the #align
lines), replace (#align \S*)setIntegral
with $1set_integral
.
@@ -122,7 +122,7 @@ def GammaIntegral (s : ℂ) : ℂ :=
theorem GammaIntegral_conj (s : ℂ) : GammaIntegral (conj s) = conj (GammaIntegral s) := by
rw [GammaIntegral, GammaIntegral, ← integral_conj]
- refine' set_integral_congr measurableSet_Ioi fun x hx => _
+ refine' setIntegral_congr measurableSet_Ioi fun x hx => _
dsimp only
rw [RingHom.map_mul, conj_ofReal, cpow_def_of_ne_zero (ofReal_ne_zero.mpr (ne_of_gt hx)),
cpow_def_of_ne_zero (ofReal_ne_zero.mpr (ne_of_gt hx)), ← exp_conj, RingHom.map_mul, ←
@@ -134,7 +134,7 @@ theorem GammaIntegral_ofReal (s : ℝ) :
have : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl
rw [GammaIntegral]
conv_rhs => rw [this, ← _root_.integral_ofReal]
- refine' set_integral_congr measurableSet_Ioi _
+ refine' setIntegral_congr measurableSet_Ioi _
intro x hx; dsimp only
conv_rhs => rw [← this]
rw [ofReal_mul, ofReal_cpow (mem_Ioi.mp hx).le]
@@ -397,7 +397,7 @@ lemma integral_cpow_mul_exp_neg_mul_Ioi {a : ℂ} {r : ℝ} (ha : 0 < a.re) (hr
rw [← cpow_add _ _ (one_div_ne_zero <| ofReal_ne_zero.mpr hr.ne'), add_sub_cancel]
calc
_ = ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * (r * t) ^ (a - 1) * exp (-(r * t)) := by
- refine MeasureTheory.set_integral_congr measurableSet_Ioi (fun x hx ↦ ?_)
+ refine MeasureTheory.setIntegral_congr measurableSet_Ioi (fun x hx ↦ ?_)
rw [mem_Ioi] at hx
rw [mul_cpow_ofReal_nonneg hr.le hx.le, ← mul_assoc, one_div, ← ofReal_inv,
← mul_cpow_ofReal_nonneg (inv_pos.mpr hr).le hr.le, ← ofReal_mul r⁻¹, inv_mul_cancel hr.ne',
@@ -513,7 +513,7 @@ theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) :
have cc : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl
conv_lhs => rw [this]; enter [1, 2, x]; rw [cc]
rw [_root_.integral_ofReal, ← cc, Complex.ofReal_re]
- refine' set_integral_congr measurableSet_Ioi fun x hx => _
+ refine' setIntegral_congr measurableSet_Ioi fun x hx => _
push_cast
rw [Complex.ofReal_cpow (le_of_lt hx)]
push_cast; rfl
@@ -565,7 +565,7 @@ theorem Gamma_pos_of_pos {s : ℝ} (hs : 0 < s) : 0 < Gamma s := by
intro x hx
rw [Function.mem_support]
exact mul_ne_zero (exp_pos _).ne' (rpow_pos_of_pos hx _).ne'
- rw [set_integral_pos_iff_support_of_nonneg_ae]
+ rw [setIntegral_pos_iff_support_of_nonneg_ae]
· rw [this, volume_Ioi, ← ENNReal.ofReal_zero]
exact ENNReal.ofReal_lt_top
· refine' eventually_of_mem (self_mem_ae_restrict measurableSet_Ioi) _
@@ -585,7 +585,7 @@ lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) :
∫ t : ℝ in Ioi 0, t ^ (a - 1) * exp (-(r * t)) = (1 / r) ^ a * Gamma a := by
rw [← ofReal_inj, ofReal_mul, ← Gamma_ofReal, ofReal_cpow (by positivity), ofReal_div]
convert integral_cpow_mul_exp_neg_mul_Ioi (by rwa [ofReal_re] : 0 < (a : ℂ).re) hr
- refine _root_.integral_ofReal.symm.trans <| set_integral_congr measurableSet_Ioi (fun t ht ↦ ?_)
+ refine _root_.integral_ofReal.symm.trans <| setIntegral_congr measurableSet_Ioi (fun t ht ↦ ?_)
norm_cast
rw [← ofReal_cpow (le_of_lt ht), RCLike.ofReal_mul]
rfl
nat_cast
/int_cast
/rat_cast
to natCast
/intCast
/ratCast
(#11486)
Now that I am defining NNRat.cast
, I want a definitive answer to this naming issue. Plenty of lemmas in mathlib already use natCast
/intCast
/ratCast
over nat_cast
/int_cast
/rat_cast
, and this matches with the general expectation that underscore-separated name parts correspond to a single declaration.
@@ -488,7 +488,7 @@ theorem tendsto_self_mul_Gamma_nhds_zero : Tendsto (fun z : ℂ => z * Gamma z)
(eventuallyEq_of_mem self_mem_nhdsWithin Complex.Gamma_add_one)
refine' ContinuousAt.comp (g := Gamma) _ (continuous_id.add continuous_const).continuousAt
refine' (Complex.differentiableAt_Gamma _ fun m => _).continuousAt
- rw [zero_add, ← ofReal_nat_cast, ← ofReal_neg, ← ofReal_one, Ne, ofReal_inj]
+ rw [zero_add, ← ofReal_natCast, ← ofReal_neg, ← ofReal_one, Ne, ofReal_inj]
refine' (lt_of_le_of_lt _ zero_lt_one).ne'
exact neg_nonpos.mpr (Nat.cast_nonneg _)
#align complex.tendsto_self_mul_Gamma_nhds_zero Complex.tendsto_self_mul_Gamma_nhds_zero
@@ -535,8 +535,8 @@ theorem _root_.Complex.Gamma_ofReal (s : ℝ) : Complex.Gamma (s : ℂ) = Gamma
#align complex.Gamma_of_real Complex.Gamma_ofReal
theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
- rw [Gamma, Complex.ofReal_add, Complex.ofReal_nat_cast, Complex.ofReal_one,
- Complex.Gamma_nat_eq_factorial, ← Complex.ofReal_nat_cast, Complex.ofReal_re]
+ rw [Gamma, Complex.ofReal_add, Complex.ofReal_natCast, Complex.ofReal_one,
+ Complex.Gamma_nat_eq_factorial, ← Complex.ofReal_natCast, Complex.ofReal_re]
#align real.Gamma_nat_eq_factorial Real.Gamma_nat_eq_factorial
@[simp]
@@ -554,7 +554,7 @@ theorem Gamma_zero : Gamma 0 = 0 := by
/-- At `-n` for `n ∈ ℕ`, the Gamma function is undefined; by convention we assign it the value `0`.
-/
theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 := by
- simpa only [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Complex.Gamma_ofReal,
+ simpa only [← Complex.ofReal_natCast, ← Complex.ofReal_neg, Complex.Gamma_ofReal,
Complex.ofReal_eq_zero] using Complex.Gamma_neg_nat_eq_zero n
#align real.Gamma_neg_nat_eq_zero Real.Gamma_neg_nat_eq_zero
@@ -642,7 +642,7 @@ theorem Gamma_eq_zero_iff (s : ℝ) : Gamma s = 0 ↔ ∃ m : ℕ, s = -m :=
theorem differentiableAt_Gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ Gamma s := by
refine' (Complex.differentiableAt_Gamma _ _).hasDerivAt.real_of_complex.differentiableAt
- simp_rw [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Ne, Complex.ofReal_inj]
+ simp_rw [← Complex.ofReal_natCast, ← Complex.ofReal_neg, Ne, Complex.ofReal_inj]
exact hs
#align real.differentiable_at_Gamma Real.differentiableAt_Gamma
This splits up Analysis/SpecialFunctions/Gaussian.lean
into three pieces, with the heaviest imports only needed in the later chunks. As only the first chunk is needed for many applications, including those on the critical path towards NumberTheory/Cyclotomic/PID.lean
, this should improve overall build parallelism and shorten mathlib's overall compilation time.
@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
-/
import Mathlib.MeasureTheory.Integral.ExpDecay
-import Mathlib.Analysis.SpecialFunctions.ImproperIntegrals
import Mathlib.Analysis.MellinTransform
#align_import analysis.special_functions.gamma.basic from "leanprover-community/mathlib"@"cca40788df1b8755d5baf17ab2f27dacc2e17acb"
@@ -489,7 +489,7 @@ theorem tendsto_self_mul_Gamma_nhds_zero : Tendsto (fun z : ℂ => z * Gamma z)
(eventuallyEq_of_mem self_mem_nhdsWithin Complex.Gamma_add_one)
refine' ContinuousAt.comp (g := Gamma) _ (continuous_id.add continuous_const).continuousAt
refine' (Complex.differentiableAt_Gamma _ fun m => _).continuousAt
- rw [zero_add, ← ofReal_nat_cast, ← ofReal_neg, ← ofReal_one, Ne.def, ofReal_inj]
+ rw [zero_add, ← ofReal_nat_cast, ← ofReal_neg, ← ofReal_one, Ne, ofReal_inj]
refine' (lt_of_le_of_lt _ zero_lt_one).ne'
exact neg_nonpos.mpr (Nat.cast_nonneg _)
#align complex.tendsto_self_mul_Gamma_nhds_zero Complex.tendsto_self_mul_Gamma_nhds_zero
@@ -643,7 +643,7 @@ theorem Gamma_eq_zero_iff (s : ℝ) : Gamma s = 0 ↔ ∃ m : ℕ, s = -m :=
theorem differentiableAt_Gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ Gamma s := by
refine' (Complex.differentiableAt_Gamma _ _).hasDerivAt.real_of_complex.differentiableAt
- simp_rw [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Ne.def, Complex.ofReal_inj]
+ simp_rw [← Complex.ofReal_nat_cast, ← Complex.ofReal_neg, Ne, Complex.ofReal_inj]
exact hs
#align real.differentiable_at_Gamma Real.differentiableAt_Gamma
IsROrC
to RCLike
(#10819)
IsROrC
contains data, which goes against the expectation that classes prefixed with Is
are prop-valued. People have been complaining about this on and off, so this PR renames IsROrC
to RCLike
.
@@ -132,7 +132,7 @@ theorem GammaIntegral_conj (s : ℂ) : GammaIntegral (conj s) = conj (GammaInteg
theorem GammaIntegral_ofReal (s : ℝ) :
GammaIntegral ↑s = ↑(∫ x : ℝ in Ioi 0, Real.exp (-x) * x ^ (s - 1)) := by
- have : ∀ r : ℝ, Complex.ofReal' r = @IsROrC.ofReal ℂ _ r := fun r => rfl
+ have : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl
rw [GammaIntegral]
conv_rhs => rw [this, ← _root_.integral_ofReal]
refine' set_integral_congr measurableSet_Ioi _
@@ -511,7 +511,7 @@ theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) :
simp_rw [← Complex.ofReal_one, ← Complex.ofReal_sub]
suffices ∫ x : ℝ in Ioi 0, ↑(exp (-x)) * (x : ℂ) ^ ((s - 1 : ℝ) : ℂ) =
∫ x : ℝ in Ioi 0, ((exp (-x) * x ^ (s - 1) : ℝ) : ℂ) by
- have cc : ∀ r : ℝ, Complex.ofReal' r = @IsROrC.ofReal ℂ _ r := fun r => rfl
+ have cc : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl
conv_lhs => rw [this]; enter [1, 2, x]; rw [cc]
rw [_root_.integral_ofReal, ← cc, Complex.ofReal_re]
refine' set_integral_congr measurableSet_Ioi fun x hx => _
@@ -588,7 +588,7 @@ lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) :
convert integral_cpow_mul_exp_neg_mul_Ioi (by rwa [ofReal_re] : 0 < (a : ℂ).re) hr
refine _root_.integral_ofReal.symm.trans <| set_integral_congr measurableSet_Ioi (fun t ht ↦ ?_)
norm_cast
- rw [← ofReal_cpow (le_of_lt ht), IsROrC.ofReal_mul]
+ rw [← ofReal_cpow (le_of_lt ht), RCLike.ofReal_mul]
rfl
open Lean.Meta Qq Mathlib.Meta.Positivity in
mul
-div
cancellation lemmas (#11530)
Lemma names around cancellation of multiplication and division are a mess.
This PR renames a handful of them according to the following table (each big row contains the multiplicative statement, then the three rows contain the GroupWithZero
lemma name, the Group
lemma, the AddGroup
lemma name).
| Statement | New name | Old name | |
@@ -175,7 +175,7 @@ private theorem Gamma_integrand_interval_integrable (s : ℂ) {X : ℝ} (hs : 0
private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
IntervalIntegrable (fun x => -((-x).exp * x ^ s) : ℝ → ℂ) volume 0 X := by
convert (Gamma_integrand_interval_integrable (s + 1) _ hX).neg
- · simp only [ofReal_exp, ofReal_neg, add_sub_cancel]; rfl
+ · simp only [ofReal_exp, ofReal_neg, add_sub_cancel_right]; rfl
· simp only [add_re, one_re]; linarith
private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y : ℝ} (hY : 0 ≤ Y) :
@@ -203,7 +203,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
/-- The recurrence relation for the indefinite version of the `Γ` function. -/
theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
partialGamma (s + 1) X = s * partialGamma s X - (-X).exp * X ^ s := by
- rw [partialGamma, partialGamma, add_sub_cancel]
+ rw [partialGamma, partialGamma, add_sub_cancel_right]
have F_der_I : ∀ x : ℝ, x ∈ Ioo 0 X → HasDerivAt (fun x => (-x).exp * x ^ s : ℝ → ℂ)
(-((-x).exp * x ^ s) + (-x).exp * (s * x ^ (s - 1))) x := by
intro x hx
@@ -276,7 +276,7 @@ theorem GammaAux_recurrence1 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
induction' n with n hn generalizing s
· simp only [Nat.zero_eq, CharP.cast_eq_zero, Left.neg_neg_iff] at h1
dsimp only [GammaAux]; rw [GammaIntegral_add_one h1]
- rw [mul_comm, mul_div_cancel]; contrapose! h1; rw [h1]
+ rw [mul_comm, mul_div_cancel_right₀]; contrapose! h1; rw [h1]
simp
· dsimp only [GammaAux]
have hh1 : -(s + 1).re < n := by
@@ -290,7 +290,7 @@ theorem GammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
cases' n with n n
· simp only [Nat.zero_eq, CharP.cast_eq_zero, Left.neg_neg_iff] at h1
dsimp only [GammaAux]
- rw [GammaIntegral_add_one h1, mul_div_cancel_left]
+ rw [GammaIntegral_add_one h1, mul_div_cancel_left₀]
rintro rfl
rw [zero_re] at h1
exact h1.false
@@ -395,7 +395,7 @@ lemma integral_cpow_mul_exp_neg_mul_Ioi {a : ℂ} {r : ℝ} (ha : 0 < a.re) (hr
∫ (t : ℝ) in Ioi 0, t ^ (a - 1) * exp (-(r * t)) = (1 / r) ^ a * Gamma a := by
have aux : (1 / r : ℂ) ^ a = 1 / r * (1 / r) ^ (a - 1) := by
nth_rewrite 2 [← cpow_one (1 / r : ℂ)]
- rw [← cpow_add _ _ (one_div_ne_zero <| ofReal_ne_zero.mpr hr.ne'), add_sub_cancel'_right]
+ rw [← cpow_add _ _ (one_div_ne_zero <| ofReal_ne_zero.mpr hr.ne'), add_sub_cancel]
calc
_ = ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * (r * t) ^ (a - 1) * exp (-(r * t)) := by
refine MeasureTheory.set_integral_congr measurableSet_Ioi (fun x hx ↦ ?_)
filter_upwards
(#11208)
This is presumably not exhaustive, but covers about a hundred instances.
Style opinions (e.g., why a particular change is great/not a good idea) are very welcome; I'm still forming my own.
@@ -105,8 +105,8 @@ theorem GammaIntegral_convergent {s : ℂ} (hs : 0 < s.re) :
exact ContinuousAt.comp this continuous_ofReal.continuousAt
· rw [← hasFiniteIntegral_norm_iff]
refine' HasFiniteIntegral.congr (Real.GammaIntegral_convergent hs).2 _
- refine' (ae_restrict_iff' measurableSet_Ioi).mpr (ae_of_all _ fun x hx => _)
- dsimp only
+ apply (ae_restrict_iff' measurableSet_Ioi).mpr
+ filter_upwards with x hx
rw [norm_eq_abs, map_mul, abs_of_nonneg <| le_of_lt <| exp_pos <| -x,
abs_cpow_eq_rpow_re_of_pos hx _]
simp
@@ -195,7 +195,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
refine' (((Real.GammaIntegral_convergent hs).mono_set
Ioc_subset_Ioi_self).hasFiniteIntegral.congr _).const_mul _
rw [EventuallyEq, ae_restrict_iff']
- · apply ae_of_all; intro x hx
+ · filter_upwards with x hx
rw [abs_of_nonneg (exp_pos _).le, abs_cpow_eq_rpow_re_of_pos hx.1]
simp
· exact measurableSet_Ioc
@@ -403,13 +403,10 @@ lemma integral_cpow_mul_exp_neg_mul_Ioi {a : ℂ} {r : ℝ} (ha : 0 < a.re) (hr
rw [mul_cpow_ofReal_nonneg hr.le hx.le, ← mul_assoc, one_div, ← ofReal_inv,
← mul_cpow_ofReal_nonneg (inv_pos.mpr hr).le hr.le, ← ofReal_mul r⁻¹, inv_mul_cancel hr.ne',
ofReal_one, one_cpow, one_mul]
- _ = |1 / r| * ∫ (t : ℝ) in Ioi (r * 0), (1 / r) ^ (a - 1) * t ^ (a - 1) * exp (-t) := by
+ _ = 1 / r * ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * t ^ (a - 1) * exp (-t) := by
simp_rw [← ofReal_mul]
rw [integral_comp_mul_left_Ioi (fun x ↦ _ * x ^ (a - 1) * exp (-x)) _ hr, mul_zero,
- real_smul, ← one_div]
- _ = 1 / r * ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * t ^ (a - 1) * exp (-t) := by
- rw [congr_arg Ioi (mul_zero r), _root_.abs_of_nonneg (one_div_pos.mpr hr).le, ofReal_div,
- ofReal_one]
+ real_smul, ← one_div, ofReal_div, ofReal_one]
_ = 1 / r * (1 / r : ℂ) ^ (a - 1) * (∫ (t : ℝ) in Ioi 0, t ^ (a - 1) * exp (-t)) := by
simp_rw [← integral_mul_left, mul_assoc]
_ = (1 / r) ^ a * Gamma a := by
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.
@@ -324,7 +324,7 @@ theorem Gamma_eq_GammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : Gamma s = Ga
by_cases h : 0 ≤ 1 - s.re
· apply Nat.le_of_lt_succ
exact_mod_cast lt_of_le_of_lt (Nat.floor_le h) (by linarith : 1 - s.re < n + 1)
- · rw [Nat.floor_of_nonpos]; linarith; linarith
+ · rw [Nat.floor_of_nonpos]; omega; linarith
#align complex.Gamma_eq_Gamma_aux Complex.Gamma_eq_GammaAux
/-- The recurrence relation for the `Γ` function. -/
refine
s (#10762)
I replaced a few "terminal" refine/refine'
s with exact
.
The strategy was very simple-minded: essentially any refine
whose following line had smaller indentation got replaced by exact
and then I cleaned up the mess.
This PR certainly leaves some further terminal refine
s, but maybe the current change is beneficial.
@@ -477,7 +477,7 @@ theorem differentiableAt_Gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : Differen
have : S = re ⁻¹' Ioi (1 - n : ℝ) := by
ext; rw [preimage, Ioi, mem_setOf_eq, mem_setOf_eq, mem_setOf_eq]; exact sub_lt_comm
rw [this]
- refine' Continuous.isOpen_preimage continuous_re _ isOpen_Ioi
+ exact Continuous.isOpen_preimage continuous_re _ isOpen_Ioi
apply eventuallyEq_of_mem this
intro t ht; rw [mem_setOf_eq] at ht
apply Gamma_eq_GammaAux; linarith
The previous code often discarded the safety features of Qq by casting quoted terms to Expr
and back. This is far from an exhaustive replacement.
This makes use of a bug fix in Lean 4.6.0rc1 that allows us to write things like
match u, α, e with
| 0, ~q(ℤ), ~q([@Int](https://github.com/Int).floor $α' $i $j $a) =>
Previously these match
es did not generalize u
correctly.
To make Qq happy, we introduce a few more assertInstancesCommute
that were not previously here.
Without them, there is a higher risk that positivity
produces an ill-typed proof in weird situations.
Like every assertInstancesCommute
, this comes at a small performance cost that could be eliminated by using the unsafe assumeInstancesCommute
instead.
Another very small performance hit here is from the (possibly unnecessary) defeq check of the types before checking defeq of the values. On the other hand, this might actually increase performance when the match fails due to a type mismatch.
There is probably some boilerplate that can be extracted from the repetition here; but I am declaring that out of scope for this PR: the goal is to establish a canonical spelling for this sort of matching, so that future extensions copy-pasted from these extensions inherit the spelling automatically.
@@ -597,15 +597,18 @@ lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) :
open Lean.Meta Qq Mathlib.Meta.Positivity in
/-- The `positivity` extension which identifies expressions of the form `Gamma a`. -/
@[positivity Gamma (_ : ℝ)]
-def _root_.Mathlib.Meta.Positivity.evalGamma :
- PositivityExt where eval {_ _α} zα pα (e : Q(ℝ)) := do
- let ~q(Gamma $a) := e | throwError "failed to match on Gamma application"
- match ← core zα pα a with
- | .positive (pa : Q(0 < $a)) =>
- pure (.positive (q(Gamma_pos_of_pos $pa) : Q(0 < $e)))
- | .nonnegative (pa : Q(0 ≤ $a)) =>
- pure (.nonnegative (q(Gamma_nonneg_of_nonneg $pa) : Q(0 ≤ $e)))
- | _ => pure .none
+def _root_.Mathlib.Meta.Positivity.evalGamma : PositivityExt where eval {u α} _zα _pα e := do
+ match u, α, e with
+ | 0, ~q(ℝ), ~q(Gamma $a) =>
+ match ← core q(inferInstance) q(inferInstance) a with
+ | .positive pa =>
+ assertInstancesCommute
+ pure (.positive q(Gamma_pos_of_pos $pa))
+ | .nonnegative pa =>
+ assertInstancesCommute
+ pure (.nonnegative q(Gamma_nonneg_of_nonneg $pa))
+ | _ => pure .none
+ | _, _, _ => throwError "failed to match on Gamma application"
/-- The Gamma function does not vanish on `ℝ` (except at non-positive integers, where the function
is mathematically undefined and we set it to `0` by convention). -/
@@ -594,13 +594,13 @@ lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) :
rw [← ofReal_cpow (le_of_lt ht), IsROrC.ofReal_mul]
rfl
-open Lean.Meta Qq in
+open Lean.Meta Qq Mathlib.Meta.Positivity in
/-- The `positivity` extension which identifies expressions of the form `Gamma a`. -/
@[positivity Gamma (_ : ℝ)]
def _root_.Mathlib.Meta.Positivity.evalGamma :
- Mathlib.Meta.Positivity.PositivityExt where eval {_ _α} zα pα (e : Q(ℝ)) := do
+ PositivityExt where eval {_ _α} zα pα (e : Q(ℝ)) := do
let ~q(Gamma $a) := e | throwError "failed to match on Gamma application"
- match ← Mathlib.Meta.Positivity.core zα pα a with
+ match ← core zα pα a with
| .positive (pa : Q(0 < $a)) =>
pure (.positive (q(Gamma_pos_of_pos $pa) : Q(0 < $e)))
| .nonnegative (pa : Q(0 ≤ $a)) =>
@@ -255,7 +255,7 @@ theorem GammaIntegral_add_one {s : ℂ} (hs : 0 < s.re) :
intro x hx; dsimp only
rw [norm_eq_abs, map_mul, abs.map_neg, abs_cpow_eq_rpow_re_of_pos hx,
abs_of_nonneg (exp_pos (-x)).le, neg_mul, one_mul]
- exact (tendsto_congr' this).mpr (tendsto_rpow_mul_exp_neg_mul_atTop_nhds_0 _ _ zero_lt_one)
+ exact (tendsto_congr' this).mpr (tendsto_rpow_mul_exp_neg_mul_atTop_nhds_zero _ _ zero_lt_one)
#align complex.Gamma_integral_add_one Complex.GammaIntegral_add_one
end GammaRecurrence
@@ -398,7 +398,8 @@ lemma integral_cpow_mul_exp_neg_mul_Ioi {a : ℂ} {r : ℝ} (ha : 0 < a.re) (hr
rw [← cpow_add _ _ (one_div_ne_zero <| ofReal_ne_zero.mpr hr.ne'), add_sub_cancel'_right]
calc
_ = ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * (r * t) ^ (a - 1) * exp (-(r * t)) := by
- refine MeasureTheory.set_integral_congr measurableSet_Ioi (fun x (hx : 0 < x) ↦ ?_)
+ refine MeasureTheory.set_integral_congr measurableSet_Ioi (fun x hx ↦ ?_)
+ rw [mem_Ioi] at hx
rw [mul_cpow_ofReal_nonneg hr.le hx.le, ← mul_assoc, one_div, ← ofReal_inv,
← mul_cpow_ofReal_nonneg (inv_pos.mpr hr).le hr.le, ← ofReal_mul r⁻¹, inv_mul_cancel hr.ne',
ofReal_one, one_cpow, one_mul]
Complex
lemmas (#9527)
and rename ofReal_mul_re → re_mul_ofReal
, ofReal_mul_im → im_mul_ofReal
.
From LeanAPAP
@@ -524,7 +524,7 @@ theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) :
theorem Gamma_add_one {s : ℝ} (hs : s ≠ 0) : Gamma (s + 1) = s * Gamma s := by
simp_rw [Gamma]
- rw [Complex.ofReal_add, Complex.ofReal_one, Complex.Gamma_add_one, Complex.ofReal_mul_re]
+ rw [Complex.ofReal_add, Complex.ofReal_one, Complex.Gamma_add_one, Complex.re_ofReal_mul]
rwa [Complex.ofReal_ne_zero]
#align real.Gamma_add_one Real.Gamma_add_one
Add pdf, CDF and measure of Gamma distribution. Add proof that this is indeed a probability distribution. Add proofs that relate the various definitions.
TODO: Refactor Probability/Distributions/Exponential.lean using calls to the results in this file.
Co-authored-by: David Loeffler <d.loeffler.01@cantab.net>
@@ -389,6 +389,33 @@ theorem Gamma_conj (s : ℂ) : Gamma (conj s) = conj (Gamma s) := by
rw [RingHom.map_add, RingHom.map_one]
#align complex.Gamma_conj Complex.Gamma_conj
+/-- Expresses the integral over `Ioi 0` of `t ^ (a - 1) * exp (-(r * t))` in terms of the Gamma
+function, for complex `a`. -/
+lemma integral_cpow_mul_exp_neg_mul_Ioi {a : ℂ} {r : ℝ} (ha : 0 < a.re) (hr : 0 < r) :
+ ∫ (t : ℝ) in Ioi 0, t ^ (a - 1) * exp (-(r * t)) = (1 / r) ^ a * Gamma a := by
+ have aux : (1 / r : ℂ) ^ a = 1 / r * (1 / r) ^ (a - 1) := by
+ nth_rewrite 2 [← cpow_one (1 / r : ℂ)]
+ rw [← cpow_add _ _ (one_div_ne_zero <| ofReal_ne_zero.mpr hr.ne'), add_sub_cancel'_right]
+ calc
+ _ = ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * (r * t) ^ (a - 1) * exp (-(r * t)) := by
+ refine MeasureTheory.set_integral_congr measurableSet_Ioi (fun x (hx : 0 < x) ↦ ?_)
+ rw [mul_cpow_ofReal_nonneg hr.le hx.le, ← mul_assoc, one_div, ← ofReal_inv,
+ ← mul_cpow_ofReal_nonneg (inv_pos.mpr hr).le hr.le, ← ofReal_mul r⁻¹, inv_mul_cancel hr.ne',
+ ofReal_one, one_cpow, one_mul]
+ _ = |1 / r| * ∫ (t : ℝ) in Ioi (r * 0), (1 / r) ^ (a - 1) * t ^ (a - 1) * exp (-t) := by
+ simp_rw [← ofReal_mul]
+ rw [integral_comp_mul_left_Ioi (fun x ↦ _ * x ^ (a - 1) * exp (-x)) _ hr, mul_zero,
+ real_smul, ← one_div]
+ _ = 1 / r * ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * t ^ (a - 1) * exp (-t) := by
+ rw [congr_arg Ioi (mul_zero r), _root_.abs_of_nonneg (one_div_pos.mpr hr).le, ofReal_div,
+ ofReal_one]
+ _ = 1 / r * (1 / r : ℂ) ^ (a - 1) * (∫ (t : ℝ) in Ioi 0, t ^ (a - 1) * exp (-t)) := by
+ simp_rw [← integral_mul_left, mul_assoc]
+ _ = (1 / r) ^ a * Gamma a := by
+ rw [aux, Gamma_eq_integral ha]
+ congr 2 with x
+ rw [ofReal_exp, ofReal_neg, mul_comm]
+
end GammaDef
/-! Now check that the `Γ` function is differentiable, wherever this makes sense. -/
@@ -554,6 +581,18 @@ theorem Gamma_nonneg_of_nonneg {s : ℝ} (hs : 0 ≤ s) : 0 ≤ Gamma s := by
· rw [Gamma_zero]
· exact (Gamma_pos_of_pos h).le
+open Complex in
+/-- Expresses the integral over `Ioi 0` of `t ^ (a - 1) * exp (-(r * t))`, for positive real `r`,
+in terms of the Gamma function. -/
+lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) :
+ ∫ t : ℝ in Ioi 0, t ^ (a - 1) * exp (-(r * t)) = (1 / r) ^ a * Gamma a := by
+ rw [← ofReal_inj, ofReal_mul, ← Gamma_ofReal, ofReal_cpow (by positivity), ofReal_div]
+ convert integral_cpow_mul_exp_neg_mul_Ioi (by rwa [ofReal_re] : 0 < (a : ℂ).re) hr
+ refine _root_.integral_ofReal.symm.trans <| set_integral_congr measurableSet_Ioi (fun t ht ↦ ?_)
+ norm_cast
+ rw [← ofReal_cpow (le_of_lt ht), IsROrC.ofReal_mul]
+ rfl
+
open Lean.Meta Qq in
/-- The `positivity` extension which identifies expressions of the form `Gamma a`. -/
@[positivity Gamma (_ : ℝ)]
In preparation of future PRs dealing with estimates of the complex logarithm and its Taylor series, this introduces Complex.slitPlane
for the set of complex numbers not on the closed negative real axis (in Analysis.SpecialFunctions.Complex.Arg
), adds a bunch of API lemmas, and replaces hypotheses of the form 0 < x.re ∨ x.im ≠ 0
by x ∈ slitPlane
in several other files.
(We do not introduce a new file for that to avoid circular imports with Analysis.SpecialFunctions.Complex.Arg
.)
Co-authored-by: Yury G. Kudryashov <urkud@urkud.name>
@@ -100,8 +100,8 @@ theorem GammaIntegral_convergent {s : ℂ} (hs : 0 < s.re) :
apply (continuous_ofReal.comp continuous_neg.exp).continuousOn.mul
apply ContinuousAt.continuousOn
intro x hx
- have : ContinuousAt (fun x : ℂ => x ^ (s - 1)) ↑x := by
- apply continuousAt_cpow_const; rw [ofReal_re]; exact Or.inl hx
+ have : ContinuousAt (fun x : ℂ => x ^ (s - 1)) ↑x :=
+ continuousAt_cpow_const <| ofReal_mem_slitPlane.2 hx
exact ContinuousAt.comp this continuous_ofReal.continuousAt
· rw [← hasFiniteIntegral_norm_iff]
refine' HasFiniteIntegral.congr (Real.GammaIntegral_convergent hs).2 _
@@ -189,7 +189,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
apply ContinuousAt.continuousOn
intro x hx
refine' (_ : ContinuousAt (fun x : ℂ => x ^ (s - 1)) _).comp continuous_ofReal.continuousAt
- apply continuousAt_cpow_const; rw [ofReal_re]; exact Or.inl hx.1
+ exact continuousAt_cpow_const <| ofReal_mem_slitPlane.2 hx.1
rw [← hasFiniteIntegral_norm_iff]
simp_rw [norm_eq_abs, map_mul]
refine' (((Real.GammaIntegral_convergent hs).mono_set
@@ -211,9 +211,8 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
simpa using (hasDerivAt_neg x).exp
have d2 : HasDerivAt (fun y : ℝ => (y : ℂ) ^ s) (s * x ^ (s - 1)) x := by
have t := @HasDerivAt.cpow_const _ _ _ s (hasDerivAt_id ↑x) ?_
- simpa only [mul_one] using t.comp_ofReal
- simpa only [id.def, ofReal_re, ofReal_im, Ne.def, eq_self_iff_true, not_true, or_false_iff,
- mul_one] using hx.1
+ · simpa only [mul_one] using t.comp_ofReal
+ · exact ofReal_mem_slitPlane.2 hx.1
simpa only [ofReal_neg, neg_mul] using d1.ofReal_comp.mul d2
have cont := (continuous_ofReal.comp continuous_neg.exp).mul (continuous_ofReal_cpow_const hs)
have der_ible :=
[a, +oo)
(#8712)
We have in the library the lemma not_intervalIntegrable_of_tendsto_norm_atTop_of_deriv_isBigO_filter
, saying that if a function tends to infinity at a point in an interval [a, b]
, then its derivative is not interval-integrable on [a, b]
. We generalize this result to allow for any set instead of [a, b]
, and apply it to half-infinite intervals.
In particular, we characterize integrability of x^s
on [a, +oo)
, and deduce that x^s
is never integrable on [0, +oo)
. This makes it possible to remove one assumption in Lemma mellin_comp_rpow
on the Mellin transform.
@@ -75,7 +75,7 @@ theorem GammaIntegral_convergent {s : ℝ} (h : 0 < s) :
constructor
· rw [← integrableOn_Icc_iff_integrableOn_Ioc]
refine' IntegrableOn.continuousOn_mul continuousOn_id.neg.exp _ isCompact_Icc
- refine' (intervalIntegrable_iff_integrable_Icc_of_le zero_le_one).mp _
+ refine' (intervalIntegrable_iff_integrableOn_Icc_of_le zero_le_one).mp _
exact intervalIntegrable_rpow' (by linarith)
· refine' integrable_of_isBigO_exp_neg one_half_pos _ (Gamma_integrand_isLittleO _).isBigO
refine' continuousOn_id.neg.exp.mul (continuousOn_id.rpow_const _)
@@ -169,7 +169,7 @@ theorem tendsto_partialGamma {s : ℂ} (hs : 0 < s.re) :
private theorem Gamma_integrand_interval_integrable (s : ℂ) {X : ℝ} (hs : 0 < s.re) (hX : 0 ≤ X) :
IntervalIntegrable (fun x => (-x).exp * x ^ (s - 1) : ℝ → ℂ) volume 0 X := by
- rw [intervalIntegrable_iff_integrable_Ioc_of_le hX]
+ rw [intervalIntegrable_iff_integrableOn_Ioc_of_le hX]
exact IntegrableOn.mono_set (GammaIntegral_convergent hs) Ioc_subset_Ioi_self
private theorem Gamma_integrand_deriv_integrable_A {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X) :
@@ -182,7 +182,7 @@ private theorem Gamma_integrand_deriv_integrable_B {s : ℂ} (hs : 0 < s.re) {Y
IntervalIntegrable (fun x : ℝ => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) volume 0 Y := by
have : (fun x => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) =
(fun x => s * ((-x).exp * x ^ (s - 1)) : ℝ → ℂ) := by ext1; ring
- rw [this, intervalIntegrable_iff_integrable_Ioc_of_le hY]
+ rw [this, intervalIntegrable_iff_integrableOn_Ioc_of_le hY]
constructor
· refine' (continuousOn_const.mul _).aestronglyMeasurable measurableSet_Ioc
apply (continuous_ofReal.comp continuous_neg.exp).continuousOn.mul
@@ -306,7 +306,7 @@ theorem GammaAux_recurrence2 (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) :
/-- The `Γ` function (of a complex variable `s`). -/
-- @[pp_nodot] -- Porting note: removed
-def Gamma (s : ℂ) : ℂ :=
+irreducible_def Gamma (s : ℂ) : ℂ :=
GammaAux ⌊1 - s.re⌋₊ s
#align complex.Gamma Complex.Gamma
@@ -377,7 +377,8 @@ theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 := by
#align complex.Gamma_neg_nat_eq_zero Complex.Gamma_neg_nat_eq_zero
theorem Gamma_conj (s : ℂ) : Gamma (conj s) = conj (Gamma s) := by
- suffices : ∀ (n : ℕ) (s : ℂ), GammaAux n (conj s) = conj (GammaAux n s); exact this _ _
+ suffices ∀ (n : ℕ) (s : ℂ), GammaAux n (conj s) = conj (GammaAux n s) by
+ simp [Gamma, this]
intro n
induction' n with n IH
· rw [GammaAux]; exact GammaIntegral_conj
@@ -342,7 +342,7 @@ theorem Gamma_eq_integral {s : ℂ} (hs : 0 < s.re) : Gamma s = GammaIntegral s
#align complex.Gamma_eq_integral Complex.Gamma_eq_integral
@[simp]
-theorem Gamma_one : Gamma 1 = 1 := by rw [Gamma_eq_integral]; simp; simp
+theorem Gamma_one : Gamma 1 = 1 := by rw [Gamma_eq_integral] <;> simp
#align complex.Gamma_one Complex.Gamma_one
theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
I've also got a change to make this required, but I'd like to land this first.
@@ -322,7 +322,7 @@ theorem Gamma_eq_GammaAux (s : ℂ) (n : ℕ) (h1 : -s.re < ↑n) : Gamma s = Ga
refine' lt_add_of_lt_of_nonneg i0 _
rw [← Nat.cast_zero, Nat.cast_le]; exact Nat.zero_le k
convert (u <| n - ⌊1 - s.re⌋₊).symm; rw [Nat.add_sub_of_le]
- by_cases 0 ≤ 1 - s.re
+ by_cases h : 0 ≤ 1 - s.re
· apply Nat.le_of_lt_succ
exact_mod_cast lt_of_le_of_lt (Nat.floor_le h) (by linarith : 1 - s.re < n + 1)
· rw [Nat.floor_of_nonpos]; linarith; linarith
exact_mod_cast
tactic with mod_cast
elaborator where possible (#8404)
We still have the exact_mod_cast
tactic, used in a few places, which somehow (?) works a little bit harder to prevent the expected type influencing the elaboration of the term. I would like to get to the bottom of this, and it will be easier once the only usages of exact_mod_cast
are the ones that don't work using the term elaborator by itself.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -354,8 +354,8 @@ theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
@[simp]
theorem Gamma_ofNat_eq_factorial (n : ℕ) [(n + 1).AtLeastTwo] :
- Gamma (no_index (OfNat.ofNat (n + 1) : ℂ)) = n ! := by
- exact_mod_cast Gamma_nat_eq_factorial (n : ℕ)
+ Gamma (no_index (OfNat.ofNat (n + 1) : ℂ)) = n ! :=
+ mod_cast Gamma_nat_eq_factorial (n : ℕ)
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
@[simp]
@@ -440,7 +440,7 @@ theorem differentiableAt_GammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 :
theorem differentiableAt_Gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℂ Gamma s := by
let n := ⌊1 - s.re⌋₊ + 1
- have hn : 1 - s.re < n := by exact_mod_cast Nat.lt_floor_add_one (1 - s.re)
+ have hn : 1 - s.re < n := mod_cast Nat.lt_floor_add_one (1 - s.re)
apply (differentiableAt_GammaAux s n hn hs).congr_of_eventuallyEq
let S := {t : ℂ | 1 - t.re < n}
have : S ∈ 𝓝 s := by
@@ -517,8 +517,8 @@ theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
@[simp]
theorem Gamma_ofNat_eq_factorial (n : ℕ) [(n + 1).AtLeastTwo] :
- Gamma (no_index (OfNat.ofNat (n + 1) : ℝ)) = n ! := by
- exact_mod_cast Gamma_nat_eq_factorial (n : ℕ)
+ Gamma (no_index (OfNat.ofNat (n + 1) : ℝ)) = n ! :=
+ mod_cast Gamma_nat_eq_factorial (n : ℕ)
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
@[simp]
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>
@@ -209,7 +209,7 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
intro x hx
have d1 : HasDerivAt (fun y : ℝ => (-y).exp) (-(-x).exp) x := by
simpa using (hasDerivAt_neg x).exp
- have d2 : HasDerivAt (fun y : ℝ => ↑y ^ s) (s * x ^ (s - 1)) x := by
+ have d2 : HasDerivAt (fun y : ℝ => (y : ℂ) ^ s) (s * x ^ (s - 1)) x := by
have t := @HasDerivAt.cpow_const _ _ _ s (hasDerivAt_id ↑x) ?_
simpa only [mul_one] using t.comp_ofReal
simpa only [id.def, ofReal_re, ofReal_im, Ne.def, eq_self_iff_true, not_true, or_false_iff,
Gamma
(#7977)
I don't personally have any need for these. It just seemed like these would make the API more complete.
@@ -142,6 +142,7 @@ theorem GammaIntegral_ofReal (s : ℝ) :
simp
#align complex.Gamma_integral_of_real Complex.GammaIntegral_ofReal
+@[simp]
theorem GammaIntegral_one : GammaIntegral 1 = 1 := by
simpa only [← ofReal_one, GammaIntegral_ofReal, ofReal_inj, sub_self, rpow_zero,
mul_one] using integral_exp_neg_Ioi_zero
@@ -340,17 +341,24 @@ theorem Gamma_eq_integral {s : ℂ} (hs : 0 < s.re) : Gamma s = GammaIntegral s
Gamma_eq_GammaAux s 0 (by norm_cast; linarith)
#align complex.Gamma_eq_integral Complex.Gamma_eq_integral
-theorem Gamma_one : Gamma 1 = 1 := by rw [Gamma_eq_integral]; simpa using GammaIntegral_one; simp
+@[simp]
+theorem Gamma_one : Gamma 1 = 1 := by rw [Gamma_eq_integral]; simp; simp
#align complex.Gamma_one Complex.Gamma_one
theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
induction' n with n hn
- · simpa using Gamma_one
+ · simp
· rw [Gamma_add_one n.succ <| Nat.cast_ne_zero.mpr <| Nat.succ_ne_zero n]
simp only [Nat.cast_succ, Nat.factorial_succ, Nat.cast_mul]; congr
#align complex.Gamma_nat_eq_factorial Complex.Gamma_nat_eq_factorial
+@[simp]
+theorem Gamma_ofNat_eq_factorial (n : ℕ) [(n + 1).AtLeastTwo] :
+ Gamma (no_index (OfNat.ofNat (n + 1) : ℂ)) = n ! := by
+ exact_mod_cast Gamma_nat_eq_factorial (n : ℕ)
+
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
+@[simp]
theorem Gamma_zero : Gamma 0 = 0 := by
simp_rw [Gamma, zero_re, sub_zero, Nat.floor_one, GammaAux, div_zero]
#align complex.Gamma_zero Complex.Gamma_zero
@@ -493,6 +501,7 @@ theorem Gamma_add_one {s : ℝ} (hs : s ≠ 0) : Gamma (s + 1) = s * Gamma s :=
rwa [Complex.ofReal_ne_zero]
#align real.Gamma_add_one Real.Gamma_add_one
+@[simp]
theorem Gamma_one : Gamma 1 = 1 := by
rw [Gamma, Complex.ofReal_one, Complex.Gamma_one, Complex.one_re]
#align real.Gamma_one Real.Gamma_one
@@ -506,7 +515,13 @@ theorem Gamma_nat_eq_factorial (n : ℕ) : Gamma (n + 1) = n ! := by
Complex.Gamma_nat_eq_factorial, ← Complex.ofReal_nat_cast, Complex.ofReal_re]
#align real.Gamma_nat_eq_factorial Real.Gamma_nat_eq_factorial
+@[simp]
+theorem Gamma_ofNat_eq_factorial (n : ℕ) [(n + 1).AtLeastTwo] :
+ Gamma (no_index (OfNat.ofNat (n + 1) : ℝ)) = n ! := by
+ exact_mod_cast Gamma_nat_eq_factorial (n : ℕ)
+
/-- At `0` the Gamma function is undefined; by convention we assign it the value `0`. -/
+@[simp]
theorem Gamma_zero : Gamma 0 = 0 := by
simpa only [← Complex.ofReal_zero, Complex.Gamma_ofReal, Complex.ofReal_inj] using
Complex.Gamma_zero
Adds Qq static checking, as requested in this comment: https://github.com/leanprover-community/mathlib4/pull/7888#issuecomment-1777483059
The have pa' : Q(..) := pa
lines are necessary to sort out typeclass instances of LE
and LT
.
@@ -543,15 +543,13 @@ open Lean.Meta Qq in
/-- The `positivity` extension which identifies expressions of the form `Gamma a`. -/
@[positivity Gamma (_ : ℝ)]
def _root_.Mathlib.Meta.Positivity.evalGamma :
- Mathlib.Meta.Positivity.PositivityExt where eval {_ _α} zα pα e := do
- let (.app _ (a : Q($_α))) ← withReducible (whnf e) | throwError "not Gamma ·"
+ Mathlib.Meta.Positivity.PositivityExt where eval {_ _α} zα pα (e : Q(ℝ)) := do
+ let ~q(Gamma $a) := e | throwError "failed to match on Gamma application"
match ← Mathlib.Meta.Positivity.core zα pα a with
- | .positive pa =>
- let pa' ← mkAppM ``Gamma_pos_of_pos #[pa]
- pure (.positive pa')
- | .nonnegative pa =>
- let pa' ← mkAppM ``Gamma_nonneg_of_nonneg #[pa]
- pure (.nonnegative pa')
+ | .positive (pa : Q(0 < $a)) =>
+ pure (.positive (q(Gamma_pos_of_pos $pa) : Q(0 < $e)))
+ | .nonnegative (pa : Q(0 ≤ $a)) =>
+ pure (.nonnegative (q(Gamma_nonneg_of_nonneg $pa) : Q(0 ≤ $e)))
| _ => pure .none
/-- The Gamma function does not vanish on `ℝ` (except at non-positive integers, where the function
@@ -534,6 +534,26 @@ theorem Gamma_pos_of_pos {s : ℝ} (hs : 0 < s) : 0 < Gamma s := by
· exact GammaIntegral_convergent hs
#align real.Gamma_pos_of_pos Real.Gamma_pos_of_pos
+theorem Gamma_nonneg_of_nonneg {s : ℝ} (hs : 0 ≤ s) : 0 ≤ Gamma s := by
+ obtain rfl | h := eq_or_lt_of_le hs
+ · rw [Gamma_zero]
+ · exact (Gamma_pos_of_pos h).le
+
+open Lean.Meta Qq in
+/-- The `positivity` extension which identifies expressions of the form `Gamma a`. -/
+@[positivity Gamma (_ : ℝ)]
+def _root_.Mathlib.Meta.Positivity.evalGamma :
+ Mathlib.Meta.Positivity.PositivityExt where eval {_ _α} zα pα e := do
+ let (.app _ (a : Q($_α))) ← withReducible (whnf e) | throwError "not Gamma ·"
+ match ← Mathlib.Meta.Positivity.core zα pα a with
+ | .positive pa =>
+ let pa' ← mkAppM ``Gamma_pos_of_pos #[pa]
+ pure (.positive pa')
+ | .nonnegative pa =>
+ let pa' ← mkAppM ``Gamma_nonneg_of_nonneg #[pa]
+ pure (.nonnegative pa')
+ | _ => pure .none
+
/-- The Gamma function does not vanish on `ℝ` (except at non-positive integers, where the function
is mathematically undefined and we set it to `0` by convention). -/
theorem Gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : Gamma s ≠ 0 := by
Set
/Finset
lemmas match lattice lemma names (#7378)
Rename union_eq_left_iff_subset
to union_eq_left
to match sup_eq_left
. Similarly for the right
and inter
versions.
@@ -522,7 +522,7 @@ theorem Gamma_neg_nat_eq_zero (n : ℕ) : Gamma (-n) = 0 := by
theorem Gamma_pos_of_pos {s : ℝ} (hs : 0 < s) : 0 < Gamma s := by
rw [Gamma_eq_integral hs]
have : (Function.support fun x : ℝ => exp (-x) * x ^ (s - 1)) ∩ Ioi 0 = Ioi 0 := by
- rw [inter_eq_right_iff_subset]
+ rw [inter_eq_right]
intro x hx
rw [Function.mem_support]
exact mul_ne_zero (exp_pos _).ne' (rpow_pos_of_pos hx _).ne'
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).
@@ -229,7 +229,7 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
rw [this]
have t := @integral_const_mul 0 X volume _ _ s fun x : ℝ => (-x).exp * x ^ (s - 1)
rw [← t, ofReal_zero, zero_cpow]
- · rw [MulZeroClass.mul_zero, add_zero]; congr 2; ext1; ring
+ · rw [mul_zero, add_zero]; congr 2; ext1; ring
· contrapose! hs; rw [hs, zero_re]
#align complex.partial_Gamma_add_one Complex.partialGamma_add_one
@@ -224,12 +224,11 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
(Gamma_integrand_deriv_integrable_B hs hX),
intervalIntegral.integral_neg, neg_add, neg_neg] at int_eval
rw [eq_sub_of_add_eq int_eval, sub_neg_eq_add, neg_sub, add_comm, add_sub]
- simp only [sub_left_inj, add_left_inj]
have : (fun x => (-x).exp * (s * x ^ (s - 1)) : ℝ → ℂ) =
(fun x => s * (-x).exp * x ^ (s - 1) : ℝ → ℂ) := by ext1; ring
rw [this]
have t := @integral_const_mul 0 X volume _ _ s fun x : ℝ => (-x).exp * x ^ (s - 1)
- dsimp at t; rw [← t, ofReal_zero, zero_cpow]
+ rw [← t, ofReal_zero, zero_cpow]
· rw [MulZeroClass.mul_zero, add_zero]; congr 2; ext1; ring
· contrapose! hs; rw [hs, zero_re]
#align complex.partial_Gamma_add_one Complex.partialGamma_add_one
@@ -2,16 +2,13 @@
Copyright (c) 2022 David Loeffler. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Loeffler
-
-! This file was ported from Lean 3 source module analysis.special_functions.gamma.basic
-! leanprover-community/mathlib commit cca40788df1b8755d5baf17ab2f27dacc2e17acb
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.MeasureTheory.Integral.ExpDecay
import Mathlib.Analysis.SpecialFunctions.ImproperIntegrals
import Mathlib.Analysis.MellinTransform
+#align_import analysis.special_functions.gamma.basic from "leanprover-community/mathlib"@"cca40788df1b8755d5baf17ab2f27dacc2e17acb"
+
/-!
# The Gamma function
This is the second half of the changes originally in #5699, removing all occurrences of ;
after a space and implementing a linter rule to enforce it.
In most cases this 2-character substring has a space after it, so the following command was run first:
find . -type f -name "*.lean" -exec sed -i -E 's/ ; /; /g' {} \;
The remaining cases were few enough in number that they were done manually.
@@ -232,7 +232,7 @@ theorem partialGamma_add_one {s : ℂ} (hs : 0 < s.re) {X : ℝ} (hX : 0 ≤ X)
(fun x => s * (-x).exp * x ^ (s - 1) : ℝ → ℂ) := by ext1; ring
rw [this]
have t := @integral_const_mul 0 X volume _ _ s fun x : ℝ => (-x).exp * x ^ (s - 1)
- dsimp at t ; rw [← t, ofReal_zero, zero_cpow]
+ dsimp at t; rw [← t, ofReal_zero, zero_cpow]
· rw [MulZeroClass.mul_zero, add_zero]; congr 2; ext1; ring
· contrapose! hs; rw [hs, zero_re]
#align complex.partial_Gamma_add_one Complex.partialGamma_add_one
@@ -418,7 +418,7 @@ theorem differentiableAt_GammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 :
DifferentiableAt ℂ (GammaAux n) s := by
induction' n with n hn generalizing s
· refine' (hasDerivAt_GammaIntegral _).differentiableAt
- rw [Nat.cast_zero] at h1 ; linarith
+ rw [Nat.cast_zero] at h1; linarith
· dsimp only [GammaAux]
specialize hn (s + 1)
have a : 1 - (s + 1).re < ↑n := by
@@ -426,7 +426,6 @@ theorem differentiableAt_GammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 :
have b : ∀ m : ℕ, s + 1 ≠ -m := by
intro m; have := h2 (1 + m)
contrapose! this
- push_neg at this
rw [← eq_sub_iff_add_eq] at this
simpa using this
refine' DifferentiableAt.div (DifferentiableAt.comp _ (hn a b) _) _ _
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