Convexity properties of the Gamma function #

In this file, we prove that Gamma and log ∘ Gamma are convex functions on the positive real line. We then prove the Bohr-Mollerup theorem, which characterises Gamma as the unique positive-real-valued, log-convex function on the positive reals satisfying f (x + 1) = x f x and f 1 = 1.

The proof of the Bohr-Mollerup theorem is bound up with the proof of (a weak form of) the Euler limit formula, Real.BohrMollerup.tendsto_logGammaSeq, stating that for positive real x the sequence x * log n + log n! - ∑ (m : ℕ) ∈ Finset.range (n + 1), log (x + m) tends to log Γ(x) as n → ∞. We prove that any function satisfying the hypotheses of the Bohr-Mollerup theorem must agree with the limit in the Euler limit formula, so there is at most one such function; then we show that Γ satisfies these conditions.

Since most of the auxiliary lemmas for the Bohr-Mollerup theorem are of no relevance outside the context of this proof, we place them in a separate namespace Real.BohrMollerup to avoid clutter. (This includes the logarithmic form of the Euler limit formula, since later we will prove a more general form of the Euler limit formula valid for any real or complex x; see Real.Gamma_seq_tendsto_Gamma and Complex.Gamma_seq_tendsto_Gamma in the file Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean.)

As an application of the Bohr-Mollerup theorem we prove the Legendre doubling formula for the Gamma function for real positive s (which will be upgraded to a proof for all complex s in a later file).

TODO: This argument can be extended to prove the general k-multiplication formula (at least up to a constant, and it should be possible to deduce the value of this constant using Stirling's formula).

theorem ConvexOn.congr {𝕜 : Type u_1} {E : Type u_2} {β : Type u_3} {s : Set E} {f : Eβ} {g : Eβ} [] [SMul 𝕜 E] [] [SMul 𝕜 β] (hf : ConvexOn 𝕜 s f) (hfg : Set.EqOn f g s) :
ConvexOn 𝕜 s g
theorem ConcaveOn.congr {𝕜 : Type u_1} {E : Type u_2} {β : Type u_3} {s : Set E} {f : Eβ} {g : Eβ} [] [SMul 𝕜 E] [] [SMul 𝕜 β] (hf : ConcaveOn 𝕜 s f) (hfg : Set.EqOn f g s) :
ConcaveOn 𝕜 s g
theorem StrictConvexOn.congr {𝕜 : Type u_1} {E : Type u_2} {β : Type u_3} {s : Set E} {f : Eβ} {g : Eβ} [] [SMul 𝕜 E] [] [SMul 𝕜 β] (hf : ) (hfg : Set.EqOn f g s) :
theorem StrictConcaveOn.congr {𝕜 : Type u_1} {E : Type u_2} {β : Type u_3} {s : Set E} {f : Eβ} {g : Eβ} [] [SMul 𝕜 E] [] [SMul 𝕜 β] (hf : ) (hfg : Set.EqOn f g s) :
theorem ConvexOn.add_const {𝕜 : Type u_1} {E : Type u_2} {β : Type u_3} {s : Set E} {f : Eβ} [] [SMul 𝕜 E] [] [Module 𝕜 β] (hf : ConvexOn 𝕜 s f) (b : β) :
ConvexOn 𝕜 s (f + fun (x : E) => b)
theorem ConcaveOn.add_const {𝕜 : Type u_1} {E : Type u_2} {β : Type u_3} {s : Set E} {f : Eβ} [] [SMul 𝕜 E] [] [Module 𝕜 β] (hf : ConcaveOn 𝕜 s f) (b : β) :
ConcaveOn 𝕜 s (f + fun (x : E) => b)
theorem StrictConvexOn.add_const {𝕜 : Type u_1} {E : Type u_2} {s : Set E} [] [SMul 𝕜 E] [] {γ : Type u_4} {f : Eγ} [Module 𝕜 γ] (hf : ) (b : γ) :
StrictConvexOn 𝕜 s (f + fun (x : E) => b)
theorem StrictConcaveOn.add_const {𝕜 : Type u_1} {E : Type u_2} {s : Set E} [] [SMul 𝕜 E] [] {γ : Type u_4} {f : Eγ} [Module 𝕜 γ] (hf : ) (b : γ) :
StrictConcaveOn 𝕜 s (f + fun (x : E) => b)
theorem Real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s : } {t : } {a : } {b : } (hs : 0 < s) (ht : 0 < t) (ha : 0 < a) (hb : 0 < b) (hab : a + b = 1) :
Real.Gamma (a * s + b * t) ^ a * ^ b

Log-convexity of the Gamma function on the positive reals (stated in multiplicative form), proved using the Hölder inequality applied to Euler's integral.

The function n ↦ x log n + log n! - (log x + ... + log (x + n)), which we will show tends to log (Gamma x) as n → ∞.

Equations
Instances For
theorem Real.BohrMollerup.f_nat_eq {f : } {n : } (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hn : n 0) :
f n = f 1 + Real.log (n - 1).factorial
theorem Real.BohrMollerup.f_add_nat_eq {f : } {x : } (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hx : 0 < x) (n : ) :
f (x + n) = f x + m, Real.log (x + m)
theorem Real.BohrMollerup.f_add_nat_le {f : } {x : } {n : } (hf_conv : ConvexOn () f) (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hn : n 0) (hx : 0 < x) (hx' : x 1) :
f (n + x) f n + x * Real.log n

Linear upper bound for f (x + n) on unit interval

theorem Real.BohrMollerup.f_add_nat_ge {f : } {x : } {n : } (hf_conv : ConvexOn () f) (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hn : 2 n) (hx : 0 < x) :
f n + x * Real.log (n - 1) f (n + x)

Linear lower bound for f (x + n) on unit interval

theorem Real.BohrMollerup.logGammaSeq_add_one (x : ) (n : ) :
= + - (x + 1) * (Real.log (n + 1) - Real.log n)
theorem Real.BohrMollerup.le_logGammaSeq {f : } {x : } (hf_conv : ConvexOn () f) (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hx : 0 < x) (hx' : x 1) (n : ) :
f x f 1 + x * Real.log (n + 1) - x * Real.log n +
theorem Real.BohrMollerup.ge_logGammaSeq {f : } {x : } {n : } (hf_conv : ConvexOn () f) (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hx : 0 < x) (hn : n 0) :
f x
theorem Real.BohrMollerup.tendsto_logGammaSeq_of_le_one {f : } {x : } (hf_conv : ConvexOn () f) (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hx : 0 < x) (hx' : x 1) :
Filter.Tendsto Filter.atTop (nhds (f x - f 1))
theorem Real.BohrMollerup.tendsto_logGammaSeq {f : } {x : } (hf_conv : ConvexOn () f) (hf_feq : ∀ {y : }, 0 < yf (y + 1) = f y + ) (hx : 0 < x) :
Filter.Tendsto Filter.atTop (nhds (f x - f 1))
theorem Real.BohrMollerup.tendsto_log_gamma {x : } (hx : 0 < x) :
Filter.Tendsto Filter.atTop (nhds ())
theorem Real.eq_Gamma_of_log_convex {f : } (hf_conv : ConvexOn () ()) (hf_feq : ∀ {y : }, 0 < yf (y + 1) = y * f y) (hf_pos : ∀ {y : }, 0 < y0 < f y) (hf_one : f 1 = 1) :

The Bohr-Mollerup theorem: the Gamma function is the unique log-convex, positive-valued function on the positive reals which satisfies f 1 = 1 and f (x + 1) = x * f x for all x.

The Gamma doubling formula #

As a fun application of the Bohr-Mollerup theorem, we prove the Gamma-function doubling formula (for positive real s). The idea is that 2 ^ s * Gamma (s / 2) * Gamma (s / 2 + 1 / 2) is log-convex and satisfies the Gamma functional equation, so it must actually be a constant multiple of Gamma, and we can compute the constant by specialising at s = 1.

Auxiliary definition for the doubling formula (we'll show this is equal to Gamma s)

Equations
Instances For
theorem Real.doublingGamma_add_one (s : ) (hs : s 0) :
(s + 1).doublingGamma = s * s.doublingGamma
theorem Real.log_doublingGamma_eq :
Set.EqOn (fun (s : ) => Real.log (Real.Gamma (s / 2)) + Real.log (Real.Gamma (s / 2 + 1 / 2)) + s * - Real.log ()) ()
theorem Real.doublingGamma_eq_Gamma {s : } (hs : 0 < s) :
s.doublingGamma =
theorem Real.Gamma_mul_Gamma_add_half_of_pos {s : } (hs : 0 < s) :
* Real.Gamma (s + 1 / 2) = Real.Gamma (2 * s) * 2 ^ (1 - 2 * s) *

Legendre's doubling formula for the Gamma function, for positive real arguments. Note that we shall later prove this for all s as Real.Gamma_mul_Gamma_add_half (superseding this result) but this result is needed as an intermediate step.