Create an object that can be used to generate random numbers with the same RNG as dust uses internally. This is primarily meant for debugging and testing the underlying C++ rather than a source of random numbers from R.
A dust_rng
object, which can be used to drawn random
numbers from dust's distributions.
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 (see dust_openmp_support).
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; consider
using dust_openmp_threads to select a safe number.
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 draw n
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 and n_streams
columns then we use a parameter value [i, j]
for the i
th
draw on the j
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 are length(prob)
possible outcomes.
If a matrix with n
columns then vary over each draw (the
i
th draw using vector prob[, i]
but shared across all
streams. There are nrow(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 and n_streams
"layers" then we vary over both draws and streams so that with
use vector prob[, i, j]
for the i
th draw on the j
th
stream.
The output will not differ based on the number of threads used, only on the number of streams.
info
Information about the generator (read-only)
new()
Create a dust_rng
object
dust_rng$new(
seed = NULL,
n_streams = 1L,
real_type = "double",
deterministic = FALSE
)
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 for float = FALSE
or float = TRUE
respectively). If NULL
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
and double
are supported (with double
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.
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.
long_jump()
Longer than $jump
, the $long_jump
method is
equivalent to 2^192 numbers drawn from each stream.
normal()
Generate n
numbers from a normal distribution
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
and ziggurat
are supported, with the latter being considerably
faster.
binomial()
Generate n
numbers from a binomial distribution
gamma()
Generate n
numbers from a gamma distribution
poisson()
Generate n
numbers from a Poisson distribution
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
.
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
rng <- dust::dust_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$nbinomial(5, 10, 0.3)
#> [1] 18 12 10 28 41
# Hypergeometric distributed random numbers with parameters n1, n2 and k
rng$hypergeometric(5, 6, 10, 4)
#> [1] 2 2 2 0 2
# Gamma distributed random numbers with parameters a and b
rng$gamma(5, 0.5, 2)
#> [1] 0.1440913 0.5461841 0.8933152 2.0532643 0.2496346
# Poisson distributed random numbers with mean lambda
rng$poisson(5, 2)
#> [1] 6 2 2 2 1
# Exponentially distributed random numbers with rate
rng$exponential(5, 2)
#> [1] 0.19990637 0.02665489 0.14149562 0.60697382 0.31936759
# 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,] 0 2 0 0 0
#> [2,] 3 2 3 3 4
#> [3,] 7 6 7 6 6
#> [4,] 0 0 0 1 0