Integer logarithms in a field with respect to a natural base #
This file defines two ℤ
-valued analogs of the logarithm of r : R
with base b : ℕ
:
Int.log b r
: Lower logarithm, or floor log. Greatestk
such that↑b^k ≤ r
.Int.clog b r
: Upper logarithm, or ceil log. Leastk
such thatr ≤ ↑b^k
.
Note that Int.log
gives the position of the left-most non-zero digit:
#eval (Int.log 10 (0.09 : ℚ), Int.log 10 (0.10 : ℚ), Int.log 10 (0.11 : ℚ))
-- (-2, -1, -1)
#eval (Int.log 10 (9 : ℚ), Int.log 10 (10 : ℚ), Int.log 10 (11 : ℚ))
-- (0, 1, 1)
which means it can be used for computing digit expansions
import Data.Fin.VecNotation
import Mathlib.Data.Rat.Floor
def digits (b : ℕ) (q : ℚ) (n : ℕ) : ℕ :=
⌊q * ((b : ℚ) ^ (n - Int.log b q))⌋₊ % b
#eval digits 10 (1/7) ∘ ((↑) : Fin 8 → ℕ)
-- ![1, 4, 2, 8, 5, 7, 1, 4]
Main results #
- For
Int.log
:Int.zpow_log_le_self
,Int.lt_zpow_succ_log_self
: the bounds formed byInt.log
,(b : R) ^ log b r ≤ r < (b : R) ^ (log b r + 1)
.Int.zpow_log_gi
: the galois coinsertion betweenzpow
andInt.log
.
- For
Int.clog
:Int.zpow_pred_clog_lt_self
,Int.self_le_zpow_clog
: the bounds formed byInt.clog
,(b : R) ^ (clog b r - 1) < r ≤ (b : R) ^ clog b r
.Int.clog_zpow_gi
: the galois insertion betweenInt.clog
andzpow
.
Int.neg_log_inv_eq_clog
,Int.neg_clog_inv_eq_log
: the link between the two definitions.
theorem
Int.log_of_one_le_right
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
{r : R}
(hr : 1 ≤ r)
:
theorem
Int.log_of_right_le_one
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
{r : R}
(hr : r ≤ 1)
:
@[simp]
@[simp]
theorem
Int.log_ofNat
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b n : ℕ)
[n.AtLeastTwo]
:
Int.log b (OfNat.ofNat n) = ↑(Nat.log b (OfNat.ofNat n))
theorem
Int.log_of_left_le_one
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : b ≤ 1)
(r : R)
:
theorem
Int.log_of_right_le_zero
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
{r : R}
(hr : r ≤ 0)
:
theorem
Int.zpow_log_le_self
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
{r : R}
(hb : 1 < b)
(hr : 0 < r)
:
theorem
Int.lt_zpow_succ_log_self
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
(r : R)
:
@[simp]
@[simp]
@[simp]
@[simp]
theorem
Int.log_zpow
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
(z : ℤ)
:
theorem
Int.log_mono_right
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
{r₁ r₂ : R}
(h₀ : 0 < r₁)
(h : r₁ ≤ r₂)
:
def
Int.zpowLogGi
(R : Type u_1)
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
:
GaloisCoinsertion (fun (z : ℤ) => ⟨↑b ^ z, ⋯⟩) fun (r : ↑(Set.Ioi 0)) => Int.log b ↑r
Over suitable subtypes, zpow
and Int.log
form a galois coinsertion
Equations
- Int.zpowLogGi R hb = GaloisCoinsertion.monotoneIntro ⋯ ⋯ ⋯ ⋯
Instances For
theorem
Int.lt_zpow_iff_log_lt
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
{x : ℤ}
{r : R}
(hr : 0 < r)
:
zpow b
and Int.log b
(almost) form a Galois connection.
theorem
Int.zpow_le_iff_le_log
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
{x : ℤ}
{r : R}
(hr : 0 < r)
:
zpow b
and Int.log b
(almost) form a Galois connection.
theorem
Int.clog_of_one_le_right
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
{r : R}
(hr : 1 ≤ r)
:
theorem
Int.clog_of_right_le_one
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
{r : R}
(hr : r ≤ 1)
:
theorem
Int.clog_of_right_le_zero
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
{r : R}
(hr : r ≤ 0)
:
@[simp]
@[simp]
theorem
Int.neg_log_inv_eq_clog
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
(r : R)
:
theorem
Int.neg_clog_inv_eq_log
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b : ℕ)
(r : R)
:
@[simp]
@[simp]
theorem
Int.clog_ofNat
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
(b n : ℕ)
[n.AtLeastTwo]
:
Int.clog b (OfNat.ofNat n) = ↑(Nat.clog b (OfNat.ofNat n))
theorem
Int.clog_of_left_le_one
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : b ≤ 1)
(r : R)
:
theorem
Int.self_le_zpow_clog
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
(r : R)
:
theorem
Int.zpow_pred_clog_lt_self
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
{r : R}
(hb : 1 < b)
(hr : 0 < r)
:
@[simp]
@[simp]
@[simp]
@[simp]
theorem
Int.clog_zpow
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
(z : ℤ)
:
theorem
Int.clog_mono_right
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
{r₁ r₂ : R}
(h₀ : 0 < r₁)
(h : r₁ ≤ r₂)
:
def
Int.clogZPowGi
(R : Type u_1)
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
:
GaloisInsertion (fun (r : ↑(Set.Ioi 0)) => Int.clog b ↑r) fun (z : ℤ) => ⟨↑b ^ z, ⋯⟩
Over suitable subtypes, Int.clog
and zpow
form a galois insertion
Equations
- Int.clogZPowGi R hb = GaloisInsertion.monotoneIntro ⋯ ⋯ ⋯ ⋯
Instances For
theorem
Int.zpow_lt_iff_lt_clog
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
{x : ℤ}
{r : R}
(hr : 0 < r)
:
Int.clog b
and zpow b
(almost) form a Galois connection.
theorem
Int.le_zpow_iff_clog_le
{R : Type u_1}
[LinearOrderedSemifield R]
[FloorSemiring R]
{b : ℕ}
(hb : 1 < b)
{x : ℤ}
{r : R}
(hr : 0 < r)
:
Int.clog b
and zpow b
(almost) form a Galois connection.