-
The expansions package: integer and float expansions, and odometers
2016-08-13
SourceI released the
expansions
package for R. To install it, follow the instructions given on my repo.Expansions of integer and real numbers
Conversion of decimal integers to integer base
This is the role of the
intAtBase
function:intAtBase(14, base=3) ## [1] 2 1 1 2*1 + 1*3 + 1*3^2 ## [1] 14
The
intAtBasePower
function returns the expansion of the integer \(m^p\) where \(m\) and \(p\) are supplied by the user:intAtBasePower(2, 5, base=3) == intAtBase(2^5, base=3) ## [1] TRUE TRUE TRUE TRUE
The advantage is the possibility to convert huge numbers \(m^p\):
intAtBase(2^100, base=3) ## Error in intAtBase(2^100, base = 3): n is too big intAtBasePower(2, 100, base=3) ## [1] 1 2 2 0 1 1 1 1 2 2 0 2 2 0 1 1 0 0 2 1 0 2 0 2 1 0 0 2 2 1 0 1 1 0 0 ## [36] 0 0 1 1 1 2 2 1 0 0 0 0 2 2 2 1 2 0 2 1 0 1 0 2 2 2 0 0 1
The
intAtBaseFib
function returns the expansion of a Fibonacci number given by its index:intAtBaseFib(6, base=3) == intAtBase(8, base=3) ## [1] TRUE TRUE intAtBaseFib(100, base=3) ## [1] 0 1 2 0 1 2 2 0 0 2 2 0 0 1 0 2 0 2 0 0 1 1 1 1 2 1 2 2 2 0 1 2 0 0 0 ## [36] 0 2 0 1 0 2 0 0 1
Cantor expansions, or “ary” expansions
The
intToAry
function performs the Cantor expansion of an integer. I explained the Cantor expansion in a previous article.# (3,4,7)-expansion of 77: intToAry(77, c(3,4,7)) ## [1] 2 1 6 2*1 + 1*3 + 6*(3*4) ## [1] 77
# Cartesian product {0,1}x{0,1}: sapply(0:3, function(x) intToAry(x, sizes=c(2,2))) ## [,1] [,2] [,3] [,4] ## [1,] 0 1 0 1 ## [2,] 0 0 1 1
It is implemented with
Rcpp
(source code), and it is fast.Float expansions
The
floatExpand01
function returns the expansion of a real number between \(0\) and \(1\) to its expansion in a given integer base. For example:floatExpand01(0.625, base=2) ## [1] 1 0 1
It means that \(0.625 = 1\times \frac{1}{2} + 0 \times \frac{1}{2^2} + 1 \times \frac{1}{2^2}\).
The
floatExpand
function returns a list representing the expansion of a positive number in scientific notation: \[ x = 0.d_1d_2\ldots d_n \times \text{base}^e. \] The digits \(d_1\), \(\ldots\), \(d_n\) are given in the first component of the list and the exponent \(e\) is given in the second one. For example:floatExpand(1.125, base=2) ## $digits ## [1] 1 0 0 1 ## ## $exponent ## [1] 1 (1*1/2 + 0*1/2^2 + 0*1/2^3 + 1*1/2^4) * 2^1 ## [1] 1.125
Odometers and addition of adic integers
The odometer is the action \(x \mapsto x+1\) on the group of \(b\)-adic integers. In other words, \(x\) is the expansion in an integer base \(b\) of a real number between \(0\) and \(1\), and the odometer maps \(x\) to \(x + (1, 0, 0, \ldots)\) where “\(+\)” is the addition modulo \(b\) with carry to the right.
odometer(c(1,0,1), base=2) ## [1] 0 1 1
By transporting the \(3\)-adic integers to \([0,1)\) with the float expansion in base \(3\), let’s have a look at the graph of the \(3\)-adic odometer:
ternary2num <- function(t) sum(t/3^seq_along(t)) num2ternary <- function(u) floatExpand01(u, base=3) par(mar=c(4,4,2,2)) u <- seq(0, 0.995, by=0.0025) Ou <- sapply(u, function(u) ternary2num(odometer(num2ternary(u), base=3))) plot(u, Ou, xlab="u", ylab="O(u)", xlim=c(0,1), ylim=c(0,1), pch=19, cex=.25, pty="s", xaxs="i", yaxs="i") grid(nx=9)
The
expansions
package also provides the functionsumadic
to perform the sum of two adic integers:sumadic(c(0,1), c(1,1,1), base=2) ## [1] 1 0 0 1 identical(sumadic(c(0,1), 1, base=2), odometer(c(0,1), base=2)) ## [1] TRUE