## Random Number Generation

## Usage

    .Random.seed <- c(rng.kind, n1, n2, ...)
    save.seed <- .Random.seed

    RNGkind(kind=NULL)

## Arguments

`kind` | character or `NULL`. If `kind` is a character string, set R's RNG to the kind desired, if it's `NULL`, return the currently used RNG.
`rng.kind` | integer code in `0:k` for the above `kind`.
`n1,n2,...` | integers. See the details for how many are required (which depends on `rng.kind`).

## Description

`.Random.seed` is an integer vector, containing the random number generator (RNG) state for random number generation in R.

`RNGkind` is a more friendly interface to query or set the kind of RNG in use.

## Details

Currently available RNG kinds

- "Wichmann-Hill": `.Random.seed[1] == 0`

  The seed, `.Random.seed[-1] == r[1:3]` is an integer vector of length 3, where each `r[i]` is in `1:(p[i] - 1)`, where `p` is the length 3 vector of primes, `p = (30269, 30307, 30323)`. The Wichmann-Hill generator has a cycle length of 6.9536e12 (= `prod(p-1)/4` ), see p.123 of Applied Statistics (1984) vol.33 which corrects the original article.

- "Marsaglia-Multicarry": `.Random.seed[1] == 1`

  A multiply-with-carry RNG is used, as recommended by George Marsaglia in his post to the mailing list `sci.stat.math' on September 29, 1997. It has a period of > 2^60 and has passed all tests (according to Marsaglia). The seed is two integers (all values allowed).

- "Super-Duper": `.Random.seed[1] == 2`

  Marsaglia's famous Super-Duper from the 70's. This is the original version which does not pass the MTUPLE test of the Diehard battery. It has a period of about 4.6*10^18 for most initial seeds. The seed is two integers (all values allowed for the first seed: the second must be odd).

  We use the implementation as by Reeds et al. (1982-'83), with the additional non-0 seed measure (see note below).

  The two seeds are the Tausworthe and Congruence long integers, respectively. A one-to-one mapping to S's `.Random.seed[1:12]` is possible but we will not publish one, not least as this generator is not exactly the same as that in recent versions of S-PLUS.

— — to be expanded — —

((Planned additions are "Mersenne-Twister", "Knuth-TAOCP" (from TAOCP, Vol.2, 3rd ed.,1997), "Ecuyer-...", "Eichenauer-..."))

Note: If any of `.Random.seed[i]` (i>1) is set to `0`, it will be substituted with `1` in the next call to a random number generator, such as `runif`.

## Value

`.Random.seed` is an `integer` vector whose first element codes the kind of RNG and therefore is in `0:k` where {k+1} is the number of available RNGs.
In the underlying C, `.Random.seed[-1]` is used as `unsigned long` (32 bits at least); in R, whose `integer`s are C's `long`, `.Random.seed[i]` can therefore be negative for i > 1.

`RNGkind` returns the RNG in use before the call, invisibly if `kind` is not `NULL`.

## Note

Initially, there is no seed; a new one is created, using ``Randomize''. Hence, student exercises will each have different simulation results, by default.

## Author(s)

of RNGkind: Martin Maechler

## References

B. A. Wichmann and I. D. Hill (1982). Algorithm AS 183: An Efficient and Portable Pseudo-random Number Generator, Applied Statistics, 31, 188-190; Remarks: 34, 198 and 35, 89.

A. De Matteis and S. Pagnutti (1993). Long-range Correlation Analysis of the Wichmann-Hill Random Number Generator, Statist. Comput., 3, 67-70.

Marsaglia, G. (1997). A random number generator for C. Discussion paper, posting on usenet newsgroup `sci.stat.math`.

Marsaglia, G. and Zaman, A. (1994). Some portable very-long-period random number generators. Computers in Physics, 8, 117-121.

## See Also

`runif`, `rnorm`, ....

## Examples

    runif(1); .Random.seed; runif(1); .Random.seed
    ## If there is no seed,  a ``random'' new one is created:
    rm(.Random.seed); runif(1); .Random.seed

    RNGkind("Wich")# (partial string matching on 'kind')
    p.WH <- c(30269, 30307, 30323)
    a.WH <- c(  171,   172,   170)
    next.WHseed <- function(i.seed = .Random.seed[-1]) (a.WH * i.seed) %% p.WH
    my.runif1 <- function(i.seed = .Random.seed)
      { ns <- next.WHseed(i.seed[-1]); sum(ns / p.WH) %% 1 }

    ## This shows how `runif(.)' works for Wichmann-Hill, using only R functions:
    rs <- .Random.seed
    (WHs <- next.WHseed(rs[-1]))
    u <- runif(1)
    all(next.WHseed(rs[-1]) == .Random.seed[-1])
    u == my.runif1(rs)

    ## ----
    .Random.seed
    ok <- RNGkind()
    RNGkind("Super")#matches  "Super-Duper"
    RNGkind()
    .Random.seed # new, corresponding to  Super-Duper

    ## Reset:
    RNGkind(ok)

[Package Contents]