RngStreams is an object-oriented random-number package with many long streams and substreams, based on the MRG32k3a RNG from reference [fn:1] below and proposed in [fn:2].
It has implementations in C, C++, Java, R, and some other languages. The main description and documentation is in the c++ directory, in the paper streams.pdf. Directories c and java gives a short description of the interfaces in C and Java, respectively.
The package is copyrighted by Pierre L’Écuyer and the University of Montreal. It can be used freely for any purpose.
E-mail: mailto:lecuyer@iro.umontreal.ca
http://www.iro.umontreal.ca/~lecuyer/
If you use it for your research, please cite the relevant publications in which MRG32k3a and the package with multiple streams were proposed.
This code is adapted from the Java implementation. The implementation:
- Inherits from System.Random
- Constructors:
RngStream()
- initially use the seed
{12345u,12345u,12345u,12345u,12345u,12345u}
and then subsequently advances to the next stream RngStream(string name)
- to set the stream name
RngStream(int seed)
- with equivalent seed behaviour as R’s
set.seed(seed)
.
- Standard
RngStream
methods:void SetPackageSeed(uint[])
- to set the package seed
void ResetStartStream()
- to reset to the start of the stream
void ResetNextSubstream()
- to reset to the start of the sub-stream
void SetAntithetic(bool)
- to determine whether to use antithetic sampling (default=false)
void IncreasedPrecis(bool)
- to determine whether to use increased precision (default=false)
void SetSeed(uint[])
- set the stream seeds (note: does not change the package seed)
double[] GetState()
- returns the current seed
void WriteState()
- write a brief description to the console
void WriteStateFull()
- write a full description to the console
- New methods
void AdvanceState(int e,int c)
- increment the current seed by \(2^e+c\)
void AdvanceSubstream(int e,int c)
- increment the substream seed by \(2^e+c\) using substream steps and change the current seed to the same value
void AdvanceStream(int e,int c)
- increment the current stream by \(2^e+c\) using stream steps and change the current seed and substream to the same value
Using C# and the RngStream.cs
file:
using System;
class HelloWorld {
public static void Main()
{
RngStream rng1 = new RngStream(); // defaults to {12345u,12345u,12345u,12345u,12345u,12345u}
Console.WriteLine(rng1.NextDouble()+" "+rng1.NextDouble());
RngStream rng2 = new RngStream(12345);
Console.WriteLine(rng2.NextDouble()+" "+rng2.NextDouble());
rng2.ResetNextSubstream();
Console.WriteLine(rng2.NextDouble()+" "+rng2.NextDouble());
rng2.ResetNextStream();
Console.WriteLine(rng2.NextDouble()+" "+rng2.NextDouble());
}
}
0.127011122046577 0.318527565396794 0.0724408950348632 0.769887841571279 0.698103786494021 0.186421477183622 0.485965335294788 0.15088750221408
Equivalent code in R:
library(parallel)
RNGkind("L'Ecuyer-CMRG")
## Note that 407 is the index for this type of random number generator
.Random.seed <- c(407L,12345L,12345L,12345L,12345L,12345L,12345L)
print(runif(2))
set.seed(12345)
Ig <- Bg <- .Random.seed
print(runif(2))
.Random.seed <- Bg <- parallel::nextRNGSubStream(Bg)
print(runif(2))
.Random.seed <- Ig <- Bg <- parallel::nextRNGStream(Ig)
print(runif(2))
[1] 0.1270111 0.3185276 [1] 0.0724409 0.7698878 [1] 0.6981038 0.1864215 [1] 0.4859653 0.1508875
[fn:1] P. L’Ecuyer, “Good Parameter Sets for Combined Multiple Recursive Random Number Generators”, Operations Research, 47, 1 (1999), 159–164.
[fn:2] P. L’Ecuyer, R. Simard, E. J. Chen, and W. D. Kelton, “An Objected-Oriented Random-Number Package with Many Long Streams and Substreams”, Operations Research, 50, 6 (2002), 1073–1075