
## zigg: lightweight interface to Ziggurat

[![CI](https://github.com/eddelbuettel/zigg/workflows/ci/badge.svg)](https://github.com/eddelbuettel/zigg/actions?query=workflow%3Aci)
[![License](https://eddelbuettel.github.io/badges/GPL2+.svg)](https://www.gnu.org/licenses/gpl-2.0.html)
[![CRAN](https://www.r-pkg.org/badges/version/zigg)](https://cran.r-project.org/package=zigg)
[![r-universe](https://eddelbuettel.r-universe.dev/badges/zigg)](https://eddelbuettel.r-universe.dev/zigg)
[![Dependencies](https://tinyverse.netlify.app/badge/zigg)](https://cran.r-project.org/package=zigg)
[![Downloads](https://cranlogs.r-pkg.org/badges/zigg?color=brightgreen)](https://www.r-pkg.org:443/pkg/zigg)
[![Last Commit](https://img.shields.io/github/last-commit/eddelbuettel/zigg)](https://github.com/eddelbuettel/zigg)

### 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][marsaglia] had introduced a number of these, as well as the test battery [diehard][diehard]
(later extended by [Robert Brown][rgb] in [dieharder][dieharder], see also the [github
repo][dieharder gh]).

A particular generator, [Ziggurat][ziggurat], was introduced in a [JSS paper in 2000][jss2000] by
[Marsaglia] and Tsang. A small correction appeared in a [JSS paper in 2005][jss2005] by Leong et al.
This version, along with improvements due to [Burkhardt][burkardt] and [Voss][voss], is provided in
our R package [RcppZiggurat][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][voss]) as well as implementation from [gretl][gretl]
and [quantlib][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][timings]

![](https://eddelbuettel.github.io/images/2025-01-05/ziggurat_base_R_comparison.png)

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][timings] shows the basic usage from R.  This works as usual:

```r
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][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][wre] manual for details);
- [zigguserDirectCpp][zigguserdirectCpp] is similar but assigns the functions
  pointers inside an included header file in a somewhat more idiomatic C++
  way;
- [zigguserHeaderCpp][zigguserheaderCpp] may be the easier way for C++
  programmers familiar with header-only libraries as this package provides
  access to [Ziggurat][ziggurat] via one such header; the remainder is then
  standard use of compiled functions in an R package.
- [zigguserHeaderRcpp][zigguserheaderRcpp] gets to use additional
  [Rcpp][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

```r
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][runiverse] repository via

```r
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][runiverseubuntu]).

### Author

Dirk Eddelbuettel

### License

GPL (>= 2)

[marsaglia]: https://en.wikipedia.org/wiki/George_Marsaglia
[diehard]: https://en.wikipedia.org/wiki/Diehard_tests
[rgb]: http://webhome.phy.duke.edu/~rgb/
[dieharder]: http://webhome.phy.duke.edu/~rgb/General/dieharder.php
[dieharder gh]: https://github.com/eddelbuettel/dieharder
[ziggurat]: https://en.wikipedia.org/wiki/Ziggurat_algorithm
[jss2000]: https://doi.org/10.18637/jss.v005.i08
[jss2005]: https://doi.org/10.18637/jss.v012.i07
[burkardt]: https://people.sc.fsu.edu/~jburkardt/
[voss]: https://www.seehuhn.de/pages/ziggurat
[rcppziggurat]: https://cran.r-project.org/package=RcppZiggurat
[runiverse]: https://eddelbuettel.r-universe.dev/zigg
[runiverseubuntu]: https://docs.r-universe.dev/install/binaries.html#does-r-universe-have-linux-binaries
[gretl]: https://gretl.sourceforge.net/
[quantlib]: https://www.quantlib.org
[timings]: https://github.com/eddelbuettel/zigg/blob/master/inst/example/timings.R
[zigguserdirectC]: https://github.com/eddelbuettel/zigg/tree/master/inst/examplePackages/directC
[zigguserdirectCpp]: https://github.com/eddelbuettel/zigg/tree/master/inst/examplePackages/directCpp
[zigguserheaderCpp]: https://github.com/eddelbuettel/zigg/tree/master/inst/examplePackages/headerCpp
[zigguserheaderRcpp]: https://github.com/eddelbuettel/zigg/tree/master/inst/examplePackages/headerRcpp
[wre]: https://rstudio.github.io/r-manuals/r-exts/System-and-foreign-language-interfaces.html#linking-to-native-routines-in-other-packages
[rcpp]: https://www.rcpp.org
