zigg: Lightweight interface to Ziggurat

CI License CRAN r-universe Dependencies Downloads Last Commit

Motivation

Random-numbers are widely used for simulation, estimation and exploration. Many excellent pseudo-random number generators are available, and the literature keeps evolving. George Marsaglia had introduced a number of these, as well as the test battery diehard (later extended by Robert Brown in dieharder, see also the github repo).

A particular generator, Ziggurat, was introduced in a JSS paper in 2000 by Marsaglia and Tsang. A small correction appeared in a JSS paper in 2005 by Leong et al. This version, along with improvements due to Burkhardt and Voss, is provided in our R package RcppZiggurat, along with other implementations allowing for detailed comparison.

However, this existing R package provides a heavier build, and imposes run-time limits as it also links to the GNU GSL (for the method by Voss) as well as implementation from gretl and quantlib. The new package assembled here offers a lighter-weight alternative. It can be called directly from R, and also offers a C(++)-callable interface other packages can use in their native code as we demonstrate via four different sample client packages each connecting in a slightly different way.

Example

The following chart is generated by the example script example/timings.R

It shows that the speed gains from zigg relative to base R are (for this example, on our machine) on the order of 7.4, 5.2, and 4.7 for the normal, exponential, and uniform RRNGs.

That said, the actual time drawing random numbers will likely only affect a fraction of the run-time of study so one may well consider sticking with either the high-quality, well-tested, and widely-deployed default generators available in R, or in other CRAN package. This package provides a useful illustration of how and older and simpler generator can be lighter and faster (at possibly a lesser total period etc).

Usage

Direct R Use

The preceding demo/timings.R shows the basic usage from R. This works as usual:

library(zigg) # load package
zrnorm(5)     # draw five N(0,1) distributed variate

Source Use In Packages

The package can also be used in compiled codeā€”even in four different ways. All are demonstrated in included demo packages and perform similarly but offer different approaches.

  • zigguserDirectC declares the (remote) functions and instantiates function pointers in src/init.c using a standard R mechanism for as exported object code that can be called directly (and consult the Writing R Extensions manual for details);
  • zigguserDirectCpp is similar but assigns the functions pointers inside an included header file in a somewhat more idiomatic C++ way;
  • zigguserHeaderCpp may be the easier way for C++ programmers familiar with header-only libraries as this package provides access to Ziggurat via one such header; the remainder is then standard use of compiled functions in an R package.
  • zigguserHeaderRcpp gets to use additional Rcpp machinery to make package building simpler, it also adds a layer parameter testing adding to a small performance penalty relative to the other three (more bare-bones) approaches.

Installation

The code is provided as an R package so a standard installation from the repository via

remotes::install_packages("zigg")

work. The package has no dependencies.

Moreover, the package can be installed (as binary, where available, or source) from its r-universe repository via

urls <- c("https://eddelbuettel.r-universe.dev", "https://cloud.r-project.org")
install.packages('zigg', repos = urls)

and is also available as an Ubuntu binary, see the docs for that).

Author

Dirk Eddelbuettel

License

GPL (>= 2)

Initially created: Fri Jan 31 08:20:49 AM CST 2025
Last modified: Fri Jan 31 13:43:50 CST 2025