[R] bitwise addition
Charles C. Berry
cberry at tajo.ucsd.edu
Mon May 15 00:57:23 CEST 2006
On Sat, 13 May 2006, jim holtman wrote:
> Using the algorithm in the reference
> www.everything2.com/index.pl?node_id=449702 and the 'bitops' package, here
> is some code that will select the numeric values with a specified number of
> bits. It takes less than 12 seconds to select from 21-bit numbers. If I had
> more memory, I would expect that for 25-bit numbers it would take about 200
> seconds to compute the indices.
>
The approach on the 'everything2' page is decidely cool.
Since a fixed number of bits is sought one can operate on the indices of
the bits, rather than the words and bits per se.
For example, selecting 2 bits from 4 bit words:
res <- rep(as.double(0),choose(4,2))
k <- 0
for ( index.1 in (1):(3) )
for ( index.2 in (index.1+1):(4) ){
index <- c( index.1,index.2 )
k <- k + 1
res[k] <- sum( 2^(index-1) ) }
gives
> res
[1] 3 5 9 6 10 12
Of course, one could turn 'index' into a character representation of the
bits instead of a decimal representation, if that was desired.
To generalize this a little computing on the language helps. For 25 bit
words choosing those with 9 bits turned on:
##-----
hi.index <- 25
n.index <- 9
for.template <- "for ( index.#X# in (#FROM#):(#TO#) )"
for.text <- function(x)
{ from.text <- if (x==1) "1" else paste("index.",x-1,"+1",sep="")
to.text <- as.character(hi.index-n.index+x)
sub("#X#",x,sub("#TO#",to.text,sub("#FROM#",from.text,for.template)))
}
all.text <- paste( "k <- 0;",
paste( sapply(1:n.index,for.text),collapse=" "),
"{index <- c(",
paste(sapply(1:n.index,function(x)
paste("index",x,sep='.')),collapse=","),
");k <- k + 1; res[k] <- sum( 2^(index-1) ) }")
res <- rep(as.double(0),choose(hi.index,n.index))
system.time(eval( parse(text=all.text ) ))
##-----
On my 2GHz AMD 64 running on Windows XP, I get
> system.time(eval( parse(text=all.text ) ))
[1] 35.17 0.08 35.41 NA NA
> res[1:10]
[1] 511 767 1279 2303 4351 8447 16639 33023 65791 131327
Note that if ordered binary numbers are needed, an additional sort()
is required - adding about 1/10 seconds:
> system.time(print(sort(res)[1:10]))
[1] 511 767 895 959 991 1007 1015 1019 1021 1022
[1] 0.11 0.00 0.11 NA NA
>
The memory needed is modest, as you would expect:
> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 178596 4.8 407500 10.9 407500 10.9
Vcells 2115922 16.2 5621217 42.9 4397614 33.6
>
Running this using
text.bits <- function(x) {
tmp <- rep("0",hi.index)
tmp[hi.index+1-x] <- "1";paste(tmp,collapse="")}
res <- rep("0000000000000000111111111",choose(hi.index,n.index))
and substituting
res[k] <- text.bits(index)
in place of "res[k] <- sum( 2^(index-1) )" gives:
> system.time(eval( parse(text=all.text ) ))
[1] 201.31 0.12 204.44 NA NA
> res[1:10]
[1] "0000000000000000111111111" "0000000000000001011111111"
[3] "0000000000000010011111111" "0000000000000100011111111"
[5] "0000000000001000011111111" "0000000000010000011111111"
[7] "0000000000100000011111111" "0000000001000000011111111"
[9] "0000000010000000011111111" "0000000100000000011111111"
>
> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 2221730 59.4 3307833 88.4 3307833 88.4
Vcells 9266414 70.7 11894938 90.8 12374438 94.5
>
And running this with the decimal representation for 'res' for 25 bit
words choosing those with 12 bits turned on:
> hi.index <- 25
> n.index <- 12
.
.
.
> system.time(eval( parse(text=all.text ) ))
[1] 101.78 0.08 104.14 NA NA
Chuck
[rest deleted]
Charles C. Berry (858) 534-2098
Dept of Family/Preventive Medicine
E mailto:cberry at tajo.ucsd.edu UC San Diego
http://biostat.ucsd.edu/~cberry/ La Jolla, San Diego 92093-0717
More information about the R-help
mailing list