Natural number logarithms #
This file defines two ℕ-valued analogs of the logarithm of n with base b:
log b n: Lower logarithm, or floor log. Greatestksuch thatb^k ≤ n.clog b n: Upper logarithm, or ceil log. Leastksuch thatn ≤ b^k.
These are interesting because, for 1 < b, Nat.log b and Nat.clog b are respectively right and
left adjoints of (b ^ ·). See le_log_iff_pow_le and clog_le_iff_le_pow.
Implementation notes #
We define both functions using recursion on b.
In order to compute, e.g., Nat.log b n, we compute e = Nat.log (b * b) n first,
then figure out whether the answer is 2 * e or 2 * e + 1.
The actual implementations use fuel recursion so that (by decide : Nat.log 2 20 = 4) works.
Adapted from https://downloads.haskell.org/~ghc/9.0.1/docs/html/libraries/ghc-bignum-1.0/GHC-Num-BigNat.html#v:bigNatLogBase-35-
Note a tail-recursive version of Nat.log is also possible:
def logTR (b n : ℕ) : ℕ :=
let rec go : ℕ → ℕ → ℕ | n, acc => if h : b ≤ n ∧ 1 < b then go (n / b) (acc + 1) else acc
decreasing_by
have : n / b < n := Nat.div_lt_self (by omega) h.2
decreasing_trivial
go n 0
but performs worse for large numbers than Nat.log:
#eval Nat.logTR 2 (2 ^ 1000000)
#eval Nat.log 2 (2 ^ 1000000)
Floor logarithm #
An auxiliary definition for Nat.log.
For b > 1, n ≠ 0, n < b ^ fuel, Nat.log.go n b fuel = (n / b ^ b.log n, b.log n).
Equations
Instances For
(b ^ ·) and log b (almost) form a Galois connection. See also Nat.pow_le_of_le_log and
Nat.le_log_of_pow_le for individual implications under weaker assumptions.
See also log_lt_of_lt_pow' for a version that assumes x ≠ 0 instead of y ≠ 0.
A version of log_lt_of_lt_pow that assumes x ≠ 0 instead of y ≠ 0.
Ceil logarithm #
This lemma says that `⌈log (b ^ k) n⌉ = ⌈(⌈log b n⌉ / k)⌉, using operations on natural numbers to express this equality.
Since Lean has no dedicated function for the ceiling division,
we use (a + (b - 1)) / b for ⌈a / b⌉.