Documentation

Mathlib.Data.Nat.Log

Natural number logarithms #

This file defines two -valued analogs of the logarithm of n with base b:

These are interesting because, for 1 < b, Nat.log b and Nat.clog b are respectively right and left adjoints of Nat.pow b. See pow_le_iff_le_log and le_pow_iff_clog_le.

Floor logarithm #

@[irreducible]
def Nat.log (b : ) :

log b n, is the logarithm of natural number n in base b. It returns the largest k : ℕ such that b^k ≤ n, so if b^k = n, it returns exactly k.

Equations
Instances For
    @[simp]
    theorem Nat.log_eq_zero_iff {b n : } :
    log b n = 0 n < b b 1
    theorem Nat.log_of_lt {b n : } (hb : n < b) :
    log b n = 0
    theorem Nat.log_of_left_le_one {b : } (hb : b 1) (n : ) :
    log b n = 0
    @[simp]
    theorem Nat.log_pos_iff {b n : } :
    0 < log b n b n 1 < b
    theorem Nat.log_pos {b n : } (hb : 1 < b) (hbn : b n) :
    0 < log b n
    theorem Nat.log_of_one_lt_of_le {b n : } (h : 1 < b) (hn : b n) :
    log b n = log b (n / b) + 1
    @[simp]
    theorem Nat.log_zero_left (n : ) :
    log 0 n = 0
    @[simp]
    theorem Nat.log_zero_right (b : ) :
    log b 0 = 0
    @[simp]
    theorem Nat.log_one_left (n : ) :
    log 1 n = 0
    @[simp]
    theorem Nat.log_one_right (b : ) :
    log b 1 = 0
    theorem Nat.pow_le_iff_le_log {b : } (hb : 1 < b) {x y : } (hy : y 0) :
    b ^ x y x log b y

    pow 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.

    theorem Nat.lt_pow_iff_log_lt {b : } (hb : 1 < b) {x y : } (hy : y 0) :
    y < b ^ x log b y < x
    theorem Nat.pow_le_of_le_log {b x y : } (hy : y 0) (h : x log b y) :
    b ^ x y
    theorem Nat.le_log_of_pow_le {b x y : } (hb : 1 < b) (h : b ^ x y) :
    x log b y
    theorem Nat.pow_log_le_self (b : ) {x : } (hx : x 0) :
    b ^ log b x x
    theorem Nat.log_lt_of_lt_pow {b x y : } (hy : y 0) :
    y < b ^ xlog b y < x
    theorem Nat.lt_pow_of_log_lt {b x y : } (hb : 1 < b) :
    log b y < xy < b ^ x
    theorem Nat.log_lt_self (b : ) {x : } (hx : x 0) :
    log b x < x
    theorem Nat.log_le_self (b x : ) :
    log b x x
    theorem Nat.lt_pow_succ_log_self {b : } (hb : 1 < b) (x : ) :
    x < b ^ (log b x).succ
    theorem Nat.log_eq_iff {b m n : } (h : m 0 1 < b n 0) :
    log b n = m b ^ m n n < b ^ (m + 1)
    theorem Nat.log_eq_of_pow_le_of_lt_pow {b m n : } (h₁ : b ^ m n) (h₂ : n < b ^ (m + 1)) :
    log b n = m
    theorem Nat.log_pow {b : } (hb : 1 < b) (x : ) :
    log b (b ^ x) = x
    theorem Nat.log_eq_one_iff' {b n : } :
    log b n = 1 b n n < b * b
    theorem Nat.log_eq_one_iff {b n : } :
    log b n = 1 n < b * b 1 < b b n
    theorem Nat.log_mul_base {b n : } (hb : 1 < b) (hn : n 0) :
    log b (n * b) = log b n + 1
    theorem Nat.pow_log_le_add_one (b x : ) :
    b ^ log b x x + 1
    theorem Nat.log_mono_right {b n m : } (h : n m) :
    log b n log b m
    theorem Nat.log_anti_left {b c n : } (hc : 1 < c) (hb : c b) :
    log b n log c n
    theorem Nat.log_antitone_left {n : } :
    AntitoneOn (fun (b : ) => log b n) (Set.Ioi 1)
    @[simp]
    theorem Nat.log_div_base (b n : ) :
    log b (n / b) = log b n - 1
    @[simp]
    theorem Nat.log_div_mul_self (b n : ) :
    log b (n / b * b) = log b n
    theorem Nat.add_pred_div_lt {b n : } (hb : 1 < b) (hn : 2 n) :
    (n + b - 1) / b < n
    theorem Nat.log2_eq_log_two {n : } :
    n.log2 = log 2 n

    Ceil logarithm #

    @[irreducible]
    def Nat.clog (b : ) :

    clog b n, is the upper logarithm of natural number n in base b. It returns the smallest k : ℕ such that n ≤ b^k, so if b^k = n, it returns exactly k.

    Equations
    Instances For
      theorem Nat.clog_of_left_le_one {b : } (hb : b 1) (n : ) :
      clog b n = 0
      theorem Nat.clog_of_right_le_one {n : } (hn : n 1) (b : ) :
      clog b n = 0
      @[simp]
      theorem Nat.clog_zero_left (n : ) :
      clog 0 n = 0
      @[simp]
      theorem Nat.clog_zero_right (b : ) :
      clog b 0 = 0
      @[simp]
      theorem Nat.clog_one_left (n : ) :
      clog 1 n = 0
      @[simp]
      theorem Nat.clog_one_right (b : ) :
      clog b 1 = 0
      theorem Nat.clog_of_two_le {b n : } (hb : 1 < b) (hn : 2 n) :
      clog b n = clog b ((n + b - 1) / b) + 1
      theorem Nat.clog_pos {b n : } (hb : 1 < b) (hn : 2 n) :
      0 < clog b n
      theorem Nat.clog_eq_one {b n : } (hn : 2 n) (h : n b) :
      clog b n = 1
      theorem Nat.le_pow_iff_clog_le {b : } (hb : 1 < b) {x y : } :
      x b ^ y clog b x y

      clog b and pow b form a Galois connection.

      theorem Nat.pow_lt_iff_lt_clog {b : } (hb : 1 < b) {x y : } :
      b ^ y < x y < clog b x
      theorem Nat.clog_pow (b x : ) (hb : 1 < b) :
      clog b (b ^ x) = x
      theorem Nat.pow_pred_clog_lt_self {b : } (hb : 1 < b) {x : } (hx : 1 < x) :
      b ^ (clog b x).pred < x
      theorem Nat.le_pow_clog {b : } (hb : 1 < b) (x : ) :
      x b ^ clog b x
      theorem Nat.clog_mono_right (b : ) {n m : } (h : n m) :
      clog b n clog b m
      theorem Nat.clog_anti_left {b c n : } (hc : 1 < c) (hb : c b) :
      clog b n clog c n
      theorem Nat.clog_antitone_left {n : } :
      AntitoneOn (fun (b : ) => clog b n) (Set.Ioi 1)
      theorem Nat.log_le_clog (b n : ) :
      log b n clog b n

      Computating the logarithm efficiently #

      def Nat.logC (b m : ) :

      An alternate definition for Nat.log which computes more efficiently. For mathematical purposes, use Nat.log instead, and see Nat.log_eq_logC.

      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.logC:

      #eval Nat.logTR 2 (2 ^ 1000000)
      #eval Nat.logC 2 (2 ^ 1000000)
      

      The definition Nat.logC is not tail-recursive, however, but the stack limit will only be reached if the output size is around 2^10000, meaning the input will be around 2^(2^10000), which will take far too long to compute in the first place.

      Adapted from https://downloads.haskell.org/~ghc/9.0.1/docs/html/libraries/ghc-bignum-1.0/GHC-Num-BigNat.html#v:bigNatLogBase-35-

      Equations
      Instances For
        @[irreducible]
        def Nat.logC.step (m pw : ) (hpw : 1 < pw) :

        An auxiliary definition for Nat.logC, where the base of the logarithm is squared in each loop. This allows significantly faster computation of the logarithm: it takes logarithmic time in the size of the output, rather than linear time.

        Equations
        Instances For
          @[csimp]

          The result of Nat.log agrees with the result of Nat.logC. The latter will be computed more efficiently, but the former is easier to prove things about and has more lemmas. This lemma is tagged @[csimp] so that the code generated for Nat.log uses Nat.logC instead.