Create an object that can be used to generate random numbers with the same RNG as monty uses internally. This is primarily meant for debugging and testing the underlying C++ rather than a source of random numbers from R.
Running multiple streams, perhaps in parallel
The underlying random number generators are designed to work in
parallel, and with random access to parameters (see
vignette("rng")
for more details). However, this is usually
done within the context of running a model where each particle
sees its own stream of numbers. We provide some support for
running random number generators in parallel, but any speed
gains from parallelisation are likely to be somewhat eroded by
the overhead of copying around a large number of random numbers.
All the random distribution functions support an argument
n_threads
which controls the number of threads used. This
argument will silently have no effect if your installation
does not support OpenMP.
Parallelisation will be performed at the level of the stream,
where we draw n
numbers from each stream for a total of n * n_streams
random numbers using n_threads
threads to do this.
Setting n_threads
to be higher than n_streams
will therefore
have no effect. If running on somebody else's system (e.g., an
HPC, CRAN) you must respect the various environment variables
that control the maximum allowable number of threads.
With the exception of random_real
, each random number
distribution accepts parameters; the interpretations of these
will depend on n
, n_streams
and their rank.
If a scalar then we will use the same parameter value for every draw from every stream
If a vector with length
n
then we will drawn
random numbers per stream, and every stream will use the same parameter value for every stream for each draw (but a different, shared, parameter value for subsequent draws).If a matrix is provided with one row and
n_streams
columns then we use different parameters for each stream, but the same parameter for each draw.If a matrix is provided with
n
rows andn_streams
columns then we use a parameter value[i, j]
for thei
th draw on thej
th stream.
The rules are slightly different for the prob
argument to
multinomial
as for that prob
is a vector of values. As such
we shift all dimensions by one:
If a vector we use same
prob
every draw from every stream and there arelength(prob)
possible outcomes.If a matrix with
n
columns then vary over each draw (thei
th draw using vectorprob[, i]
but shared across all streams. There arenrow(prob)
possible outcomes.If a 3d array is provided with 1 column and
n_streams
"layers" (the third dimension) then we use then we use different parameters for each stream, but the same parameter for each draw.If a 3d array is provided with
n
columns andn_streams
"layers" then we vary over both draws and streams so that with use vectorprob[, i, j]
for thei
th draw on thej
th stream.
The output will not differ based on the number of threads used, only on the number of streams.
Methods
Method new()
Create a monty_rng
object
Usage
monty_rng$new(
seed = NULL,
n_streams = 1L,
real_type = "double",
deterministic = FALSE
)
Arguments
seed
The seed, as an integer, a raw vector or
NULL
. If an integer we will create a suitable seed via the "splitmix64" algorithm, if a raw vector it must the correct length (a multiple of either 32 or 16 forfloat = FALSE
orfloat = TRUE
respectively). IfNULL
then we create a seed using R's random number generator.n_streams
The number of streams to use (see Details)
real_type
The type of floating point number to use. Currently only
float
anddouble
are supported (withdouble
being the default). This will have no (or negligible) impact on speed, but exists to test the low-precision generators.deterministic
Logical, indicating if we should use "deterministic" mode where distributions return their expectations and the state is never changed.
Method jump()
The jump function updates the random number state for each stream by advancing it to a state equivalent to 2^128 numbers drawn from each stream.
Method long_jump()
Longer than $jump
, the $long_jump
method is
equivalent to 2^192 numbers drawn from each stream.
Method normal()
Generate n
numbers from a normal distribution
Arguments
n
Number of samples to draw (per stream)
mean
The mean of the distribution (length 1 or n)
sd
The standard deviation of the distribution (length 1 or n)
n_threads
Number of threads to use; see Details
algorithm
Name of the algorithm to use; currently
box_muller
andziggurat
are supported, with the latter being considerably faster.
Method binomial()
Generate n
numbers from a binomial distribution
Method poisson()
Generate n
numbers from a Poisson distribution
Method multinomial()
Generate n
draws from a multinomial distribution.
In contrast with most of the distributions here, each draw is a
vector with the same length as prob
.
Arguments
n
The number of samples to draw (per stream)
size
The number of trials (zero or more, length 1 or n)
prob
A vector of probabilities for the success of each trial. This does not need to sum to 1 (though all elements must be non-negative), in which case we interpret
prob
as weights and normalise so that they equal 1 before sampling.n_threads
Number of threads to use; see Details
Method beta()
Generate n
numbers from a beta distribution
Examples
rng <- monty::monty_rng$new(42)
# Shorthand for Uniform(0, 1)
rng$random_real(5)
#> [1] 0.4969537 0.6896184 0.3669609 0.3620384 0.9299854
# Shorthand for Normal(0, 1)
rng$random_normal(5)
#> [1] -1.53271190 -1.41913805 0.02345789 -0.73297710 -1.23072552
# Uniform random numbers between min and max
rng$uniform(5, -2, 6)
#> [1] -0.07182473 4.28030151 -1.86883075 1.79198057 2.40249777
# Normally distributed random numbers with mean and sd
rng$normal(5, 4, 2)
#> [1] 5.100104 3.489436 4.315190 2.868816 4.235165
# Binomially distributed random numbers with size and prob
rng$binomial(5, 10, 0.3)
#> [1] 5 3 2 5 2
# Negative binomially distributed random numbers with size and prob
rng$negative_binomial_prob(5, 10, 0.3)
#> [1] 18 12 10 28 41
# Negative binomially distributed random numbers with size and mean mu
rng$negative_binomial_mu(5, 10, 25)
#> [1] 20 36 29 24 21
# Hypergeometric distributed random numbers with parameters n1, n2 and k
rng$hypergeometric(5, 6, 10, 4)
#> [1] 3 3 1 2 2
# Gamma distributed random numbers with parameters shape and scale
rng$gamma_scale(5, 0.5, 2)
#> [1] 0.09581271 3.72714174 0.03425020 0.11572308 0.02588573
# Gamma distributed random numbers with parameters shape and rate
rng$gamma_rate(5, 0.5, 2)
#> [1] 0.028520416 0.200465364 0.062696319 0.004992461 1.176618107
# Poisson distributed random numbers with mean lambda
rng$poisson(5, 2)
#> [1] 5 0 1 2 1
# Exponentially distributed random numbers with rate
rng$exponential_rate(5, 2)
#> [1] 0.1079527 0.1088540 0.4230433 0.2343017 0.1581192
# Exponentially distributed random numbers with mean
rng$exponential_mean(5, 0.5)
#> [1] 0.29369690 1.25656006 0.38397460 0.61159501 0.06725495
# Multinomial distributed random numbers with size and vector of
# probabiltiies prob
rng$multinomial(5, 10, c(0.1, 0.3, 0.5, 0.1))
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 3 1 0 1
#> [2,] 5 0 2 5 4
#> [3,] 2 6 6 4 4
#> [4,] 2 1 1 1 1