Imports
import CLRSLean.Chapter_03.Section_03_1_Asymptotic_Notation import Mathlib import Mathlib.NumberTheory.Harmonic.EulerMascheroni
open Filteropen Asymptoticsopen scoped Topology

3.2. Standard Notations and Common Functions

Concrete asymptotic comparisons for algorithm analysis.

  • nᵃ = o(nᵇ) when a < b

  • nᵃ = o(cⁿ) when 1 < c

  • log n = o(nʳ) when 0 < r

  • (log n)ᵃ = o(nʳ) when 0 < r

  • aⁿ = o(bⁿ) when 0 ≤ a < b

  • the harmonic numbers satisfy Hₙ ~ log n and Hₙ = Θ(log n)

  • ⌊n⌋ = Θ(n) and ⌈n⌉ = Θ(n) on ℕ

  • ⌊n/2⌋ = Θ(n) and ⌈n/2⌉ = Θ(n) on ℕ

  • lower and upper factorial bounds

  • aⁿ = o(n!) and n! = o(nⁿ)

namespace CLRSnamespace Chapter03

Polynomial comparisons

nᵃ = o(nᵇ) when a < b.

theorem isLittleO_pow_pow {a b : } (h : a < b) : isLittleO (fun n : => (n : ) ^ a) (fun n : => (n : ) ^ b) := exact (h_ℝ.comp_tendsto tendsto_natCast_atTop_atTop).congr ( ) ( )

nᵃ = O(nᵇ) when a ≤ b.

theorem isBigO_pow_pow {a b : } (h : a b) : isBigO (fun n : => (n : ) ^ a) (fun n : => (n : ) ^ b) :=

Polynomial, logarithmic, and exponential comparisons

For any natural exponent a and real base c > 1, nᵃ = o(cⁿ).

theorem isLittleO_pow_const_exp {a : } {c : } (hc : 1 < c) : isLittleO (fun n : => (n : ) ^ a) (fun n : => c ^ n) :=

For every positive real exponent r, log n = o(nʳ).

theorem isLittleO_log_rpow {r : } (hr : 0 < r) : isLittleO (fun n : => Real.log (n : )) (fun n : => (n : ) ^ r) :=

For every fixed natural exponent a and positive real exponent r, (log n)ᵃ = o(nʳ).

theorem isLittleO_log_pow_rpow {a : } {r : } (hr : 0 < r) : isLittleO (fun n : => Real.log (n : ) ^ a) (fun n : => (n : ) ^ r) :=

Weak O form of isLittleO_log_pow_rpow.

theorem isBigO_log_pow_rpow {a : } {r : } (hr : 0 < r) : isBigO (fun n : => Real.log (n : ) ^ a) (fun n : => (n : ) ^ r) := (isLittleO_log_pow_rpow (a := a) hr).isBigO

If 0 ≤ a < b, then aⁿ = o(bⁿ).

theorem isLittleO_exp_exp_of_lt {a b : } (ha : 0 a) (hab : a < b) : isLittleO (fun n : => a ^ n) (fun n : => b ^ n) :=

Harmonic numbers

The harmonic numbers are asymptotic to log n.

The harmonic numbers have logarithmic growth, Hₙ = Θ(log n).

theorem isBigTheta_harmonic_log : isBigTheta (fun n : => (harmonic n : )) (fun n : => Real.log (n : )) := exact ; , ;

Floor and ceiling are Θ(id) on ℕ

exact ; , ; exact ; , ; private theorem ceil_half_le_self_nat {n : } (hn : 1 n) : (n + 1) / 2 n :=

Natural-number floor half-scale: ⌊n/2⌋ = Θ(n).

Natural-number ceiling half-scale, represented as (n+1)/2: ⌈n/2⌉ = Θ(n).

Factorial bound

n! ≤ nⁿ for all n. Proof on : each factor 1..n ≤ n.

theorem factorial_upper_bound_nat (n : ) : Nat.factorial n n ^ n :=

n! ≤ nⁿ for all n, real version.

theorem factorial_upper_bound (n : ) : (Nat.factorial n : ) (n : ) ^ n :=

For any offset m, the last k factors in (m+k)! are each at least m+1, so (m+1)^k ≤ (m+k)!.

theorem factorial_lower_bound_offset_nat (m k : ) : (m + 1) ^ k Nat.factorial (m + k) :=

Real-valued version of factorial_lower_bound_offset_nat.

theorem factorial_lower_bound_offset (m k : ) : ((m + 1 : ) : ) ^ k (Nat.factorial (m + k) : ) :=

A CLRS-style half-scale lower bound: the upper half of the factors in n! contributes at least (⌊n/2⌋+1)^(n-⌊n/2⌋).

theorem factorial_lower_bound_half_pow_nat (n : ) : (n / 2 + 1) ^ (n - n / 2) Nat.factorial n :=

Real-valued version of factorial_lower_bound_half_pow_nat.

theorem factorial_lower_bound_half_pow (n : ) : (((n / 2 + 1 : ) : ) ^ (n - n / 2)) (Nat.factorial n : ) :=

Exponential vs factorial

aⁿ = o(n!) as n → ∞. Follows from FloorSemiring.tendsto_pow_div_factorial_atTop, the standard lemma that cⁿ / n! → 0 for any real c.

CLRS standard growth-table fact: n! = o(nⁿ).

end Chapter03end CLRS