Fast Random Numbers for R with dqrng
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
If you need only a few truly random numbers you might use dice or atmospheric noise. However, if you need many random numbers you will have to use a pseudo random number generator (RNG). R includes support for different RNGs (c.f. ?Random
) and a wide variety of distributions (c.f. ?distributions
). The underlying methods have been well tested, but faster methods are available. The dqrng package provides fast random number generators with good statistical properties for usage with R. It combines these RNGs with fast distribution functions to sample from uniform, normal or exponential distributions.
Installation
At the moment dqrng is not on CRAN, but you can install the current version via drat:
if (!requireNamespace("drat", quietly = TRUE)) install.packages("drat") drat::addRepo("RInstitute") install.packages("dqrng")
Usage
Using the provided RNGs from R is deliberately similar to using R’s build-in RNGs:
library(dqrng) dqRNGkind("Xoroshiro128+") dqset.seed(42) dqrunif(5, min = 2, max = 10) ## [1] 8.480202 6.582408 8.869840 5.062206 8.828782 dqrnorm(5, mean = 3, sd = 5) ## [1] -4.0116902 0.9337035 5.6500975 -6.4582090 5.1763009 dqrexp(5, rate = 4) ## [1] 0.4428268 0.1011437 0.3526118 0.3793630 0.6327636
They are quite a bit faster, though, as we can see by comparing 10 million random draws from different distributions:
N <- 1e7 tm <- microbenchmark( runif = runif(N), dqrunif = dqrunif(N), rnorm = rnorm(N), dqrnorm = dqrnorm(N), rexp = rexp(N), dqrexp = dqrexp(N))
expr | min | lq | mean | median | uq | max | neval | cld |
---|---|---|---|---|---|---|---|---|
runif | 248.16730 | 251.83371 | 262.20559 | 260.33073 | 265.69415 | 322.15771 | 100 | d |
dqrunif | 34.77413 | 35.44569 | 39.40738 | 36.82459 | 38.42524 | 109.96758 | 100 | a |
rnorm | 587.40975 | 596.92850 | 618.79356 | 613.08345 | 624.31043 | 706.79528 | 100 | f |
dqrnorm | 63.17649 | 64.43796 | 68.77696 | 66.80184 | 68.39577 | 141.97466 | 100 | c |
rexp | 392.79228 | 397.48715 | 413.66996 | 411.14180 | 420.42473 | 494.49631 | 100 | e |
dqrexp | 52.75875 | 53.64510 | 57.15006 | 55.80021 | 58.65553 | 79.11577 | 100 | b |
For r*
the default Mersenne-Twister was used, while dqr*
used Xoroshiro128+ in this comparison. For rnorm
the default inversion method was used, while dqrnorm
(and dqrexp
) used the Ziggurat algorithm from Boost.Random with additional tuning.
Both the RNGs and the distribution functions are distributed as C++ header-only library. See the included vignette for possible usage from C++.
Supported Random Number Generators
Support for the following 64 bit RNGs is currently included:
- Mersenne-Twister
The 64 bit variant of the well-known Mersenne-Twister, which is also used as default. This is a conservative default that allows you to take advantage of the fast distribution functions provided by dqrng while staying close to R’s default RNG (32 bit Mersenne-Twister). - pcg64
The default 64 bit variant from the PCG family developed by Melissa O’Neill. See http://www.pcg-random.org for more details. - Xoroshiro128+, Xorshift128+, and Xorshift1024*
RNGs mainly developed by Sebastiano Vigna. They are used as default RNGs in Erlang and different JavaScript engines. See http://xoroshiro.di.unimi.it/ for more details.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.