# rxRngNewStream: Parallel Random Number Generation

## Description

R interface to Parallel Random Number Generators (RNGs) in MKL.

## Usage

```
rxRngNewStream(kind = "MT2203", subStream = 0, seed = NULL, normalKind = NULL)
rxRngGetStream()
rxRngSetStream(streamState)
rxRngDelStream(kind = "default", normalKind = "default")
```

## Arguments

`kind`

a character string specifying the desired kind of random number generator. The available kinds are "MCG31", "R250", "MRG32K3A", "MCG59", "MT19937", "MT2203", "SFMT19937", "SOBOL". While "MT2203" allows creating up to 6024 independent random streams, the other kinds allow only 1.

`subStream`

an integer value identifying the index of the independent random stream. The valid value is from 0 to 6023 for "MT2203", and 0 for the other kinds.

`seed`

an integer that will be used to initialize the random number generator.

`normalKind`

a character string specifying the method of Normal generation. The default `NULL`

means no change, and generally will allow random normals to be generated by means of inverting the cumulative distribution function. Other allowable values are `"BOXMULLER"`

, `"BOXMULLER2"`

, (both similar to the standard R `"Box-Muller"`

option described in Random), and `"ICDF"`

, an alternate implementation of the standard R `"Inversion"`

.

`streamState`

an integer vector containing the state of the random number generator.

## Details

`rxRngNewStream`

allocates memory for storing the RNG state and
`rxRngDelStream`

needs to be called to release the memory. These functions
set or modify the current random number state and are implemented as
`"user-defined"`

random number generators. See Random
and Random.user for more details.

Most of the basic random number generators are *pseudo*-random number
generators; random number streams are deterministically generated from a given
seed, but give the appearance of randomness. The `"SOBOL"`

random number generator is a *quasi*-random number
generator; it is simply a sequence that cover a given hypercube in
roughly the same way as would truly random points from a uniform
distribution. The quasi-random number generators always return the
same sequences of numbers and are thus perfectly correlated. They can
be useful, however, in fields such as Monte Carlo integration.

## Value

`rxRngNewStream`

returns invisibly a two-element character vector of the RNG and normal kinds used *before* the call. This is the same as the object returned by `RNGkind`

; see Random for details. If the previous random number state was generated by a call to `rxRngNewStream`

, the first element will be `"user-defined"`

, otherwise one of the strings listed in Random.

`rxRngGetStream`

returns an integer vector containing the current RNG state.

`rxRngSetStream`

returns invisibly an integer vector containing the current RNG state and replaces the current active RNG state with the new one.

`rxRngDelStream`

returns invisibly an integer vector containing the current RNG state and delete the current active RNG.

## Note

In addition to the independent streams provided by "MT2203", independent streams can also be obtained from some of the other kinds using block-splitting and/or leapfrogging methods.

## Author(s)

Microsoft Corporation `Microsoft Technical Support`

## References

*Intel Math Kernel Library, Reference Manual*.

*Intel Math Kernel Library, Vector Statistical Library Notes*.
`http://software.intel.com/sites/products/documentation/doclib/mkl_sa/11/vslnotes/vslnotes.pdf`

*Vector Statistical Library (VSL) Performance Data*.
`http://software.intel.com/sites/products/documentation/doclib/mkl_sa/11/vsl/vsl_performance_data.htm`

.

## See Also

Random, Random.user.

## Examples

```
## Not run:
## initialize, save, load, and delete
num <- 5
kinds <- c("MCG31", "R250", "MRG32K3A", "MCG59",
"MT19937", "MT2203", "SFMT19937", "SOBOL")
for (kind in kinds) {
kind.old <- rxRngNewStream (kind = kind)
a <- runif (num)
saved <- rxRngGetStream ()
a1 <- runif (num)
rxRngSetStream (saved)
a2 <- runif (num)
rxRngDelStream(kind.old[1], kind.old[2])
stopifnot( all (a1 == a2) )
}
## parallel random number generation
rxOptions(numCoresToUse=4)
oldcc <- rxSetComputeContext("localpar")
"ParallelRNG" <- function( RngKind = "MT2203", subStream = 0, seed = NULL, RnGenerator = "runif", length = 1 )
{
rxRngNewStream( kind = RngKind, subStream = subStream, seed = seed )
do.call( RnGenerator, list( length ) )
}
# generates 5 uniform random numbers on each of 4 workers, giving the same streams on workers
# 1 and 3 and on 2 and 4, respectively
rxExec( ParallelRNG, RngKind = "MT2203", subStream = rxElemArg( c( 0, 1, 0, 1 ) ),
seed = 17, RnGenerator = "runif", length = 5 )
rxSetComputeContext(oldcc)
## End(Not run)
```