Title: | Utility Functions for Working with Random Number Generators |
---|---|
Description: | Provides a set of functions for working with Random Number Generators (RNGs). In particular, a generic S4 framework is defined for getting/setting the current RNG, or RNG data that are embedded into objects for reproducibility. Notably, convenient default methods greatly facilitate the way current RNG settings can be changed. |
Authors: | Renaud Gaujoux [aut, cre], Max Kuhn [ctb] |
Maintainer: | Renaud Gaujoux <[email protected]> |
License: | GPL (>= 3) |
Version: | 1.5.3 |
Built: | 2024-11-03 04:50:43 UTC |
Source: | https://github.com/renozao/rngtools |
.getRNG
is an S4 generic that extract RNG settings from a variety of
object types.
Its methods define the workhorse functions that are called by getRNG
.
.getRNG(object, ...) ## S4 method for signature 'ANY' .getRNG(object, ...) ## S4 method for signature 'missing' .getRNG(object) ## S4 method for signature 'list' .getRNG(object) ## S4 method for signature 'numeric' .getRNG(object, ...)
.getRNG(object, ...) ## S4 method for signature 'ANY' .getRNG(object, ...) ## S4 method for signature 'missing' .getRNG(object) ## S4 method for signature 'list' .getRNG(object) ## S4 method for signature 'numeric' .getRNG(object, ...)
object |
an R object from which RNG settings can be extracted, e.g. an
integer vector containing a suitable value for |
... |
extra arguments to allow extension and passed to a suitable S4 method
|
"ANY": Default method that tries to extract RNG information from object
, by
looking sequentially to a slot named 'rng'
, a slot named 'rng.seed'
or an attribute names 'rng'
.
It returns NULL
if no RNG data was found.
"missing": Returns the current RNG settings.
"list": Method for S3 objects, that aims at reproducing the behaviour of the function
getRNG
of the package getRNG
.
It sequentially looks for RNG data in elements 'rng'
, noise$rng
if element 'noise'
exists and is a list
, or in attribute 'rng'
.
"numeric": Method for numeric vectors, which returns the object itself, coerced into an integer
vector if necessary, as it is assumed to already represent a value for
.Random.seed
.
.setRNG
is an S4 generic that sets the current RNG settings, from a
variety of specifications.
Its methods define the workhorse functions that are called by setRNG
.
.setRNG(object, ...) ## S4 method for signature 'character' .setRNG(object, ...) ## S4 method for signature 'numeric' .setRNG(object, ...)
.setRNG(object, ...) ## S4 method for signature 'character' .setRNG(object, ...) ## S4 method for signature 'numeric' .setRNG(object, ...)
object |
an R object from which RNG settings can be extracted, e.g. an
integer vector containing a suitable value for |
... |
extra arguments to allow extension and passed to a suitable S4 method
|
"character": Sets the RNG to kind object
, assuming is a valid RNG kind:
it is equivalent to RNGkind(object, ...
.
All arguments in ...
are passed to RNGkind
.
"numeric": Sets the RNG settings using object
directly the new value for
.Random.seed
or to initialise it with set.seed
.
# set RNG kind old <- setRNG('Marsaglia') # restore setRNG(old) # directly set .Random.seed rng <- getRNG() r <- runif(10) setRNG(rng) rng.equal(rng) # initialise from a single number (<=> set.seed) setRNG(123) rng <- getRNG() runif(10) set.seed(123) rng.equal(rng)
# set RNG kind old <- setRNG('Marsaglia') # restore setRNG(old) # directly set .Random.seed rng <- getRNG() r <- runif(10) setRNG(rng) rng.equal(rng) # initialise from a single number (<=> set.seed) setRNG(123) rng <- getRNG() runif(10) set.seed(123) rng.equal(rng)
checkRNG
checks if two objects have the same RNG
settings and should be used in unit tests, e.g., with the RUnit
package.
checkRNG(x, y = getRNG(), ...)
checkRNG(x, y = getRNG(), ...)
x , y
|
objects from which RNG settings are extracted. |
... |
extra arguments passed to |
#--- checkRNG --- # check for differences in RNG set.seed(123) checkRNG(123) try( checkRNG(123, 123) ) try( checkRNG(123, 1:3) )
#--- checkRNG --- # check for differences in RNG set.seed(123) checkRNG(123) try( checkRNG(123, 123) ) try( checkRNG(123, 1:3) )
getRNG
returns the Random Number Generator (RNG) settings used for
computing an object, using a suitable .getRNG
S4 method to extract
these settings.
For example, in the case of objects that result from multiple model fits,
it would return the RNG settings used to compute the best fit.
getRNG(object, ..., num.ok = FALSE, extract = TRUE, recursive = TRUE) hasRNG(object) nextRNG(object, ..., ndraw = 0L) setRNG(object, ..., verbose = FALSE, check = TRUE)
getRNG(object, ..., num.ok = FALSE, extract = TRUE, recursive = TRUE) hasRNG(object) nextRNG(object, ..., ndraw = 0L) setRNG(object, ..., verbose = FALSE, check = TRUE)
object |
an R object from which RNG settings can be extracted, e.g. an
integer vector containing a suitable value for |
... |
extra arguments to allow extension and passed to a suitable S4 method
|
num.ok |
logical that indicates if single numeric (not integer) RNG data should be
considered as a valid RNG seed ( |
extract |
logical that indicates if embedded RNG data should be looked for and
extracted ( |
recursive |
logical that indicates if embedded RNG data should be extracted
recursively ( |
ndraw |
number of draws to perform before returning the RNG seed. |
verbose |
a logical that indicates if the new RNG settings should be displayed. |
check |
logical that indicates if only valid RNG kinds should be accepted, or if invalid values should just throw a warning. Note that this argument is used only on R >= 3.0.2. |
This function handles single number RNG specifications in the following way:
Return them unchanged, considering them as encoded RNG kind
specification (see RNG
). No validity check is performed.
If num.ok=TRUE
return them unchanged.
Otherwise, consider them as (pre-)seeds and pass them to set.seed
to get a proper RNG seed.
Hence calling getRNG(1234)
is equivalent to set.seed(1234); getRNG()
(See examples).
getRNG
, getRNG1
, nextRNG
and setRNG
usually return an integer vector of length > 2L, like .Random.seed
.
getRNG
and getRNG1
return NULL
if no RNG data was found.
setRNG
invisibly returns the old RNG settings as
they were before changing them.
#--- getRNG --- # get current RNG settings s <- getRNG() head(s) showRNG(s) # get RNG from a given single numeric seed s1234 <- getRNG(1234) head(s1234) showRNG(s1234) # this is identical to the RNG seed as after set.seed() set.seed(1234) identical(s1234, .Random.seed) # but if num.ok=TRUE the object is returned unchanged getRNG(1234, num.ok=TRUE) # single integer RNG data = encoded kind head(getRNG(1L)) # embedded RNG data s <- getRNG(list(1L, rng=1234)) identical(s, s1234) #--- hasRNG --- # test for embedded RNG data hasRNG(1) hasRNG( structure(1, rng=1:3) ) hasRNG( list(1, 2, 3) ) hasRNG( list(1, 2, 3, rng=1:3) ) hasRNG( list(1, 2, 3, noise=list(1:3, rng=1)) ) #--- nextRNG --- head(nextRNG()) head(nextRNG(1234)) head(nextRNG(1234, ndraw=10)) #--- setRNG --- obj <- list(x=1000, rng=123) setRNG(obj) rng <- getRNG() runif(10) set.seed(123) rng.equal(rng)
#--- getRNG --- # get current RNG settings s <- getRNG() head(s) showRNG(s) # get RNG from a given single numeric seed s1234 <- getRNG(1234) head(s1234) showRNG(s1234) # this is identical to the RNG seed as after set.seed() set.seed(1234) identical(s1234, .Random.seed) # but if num.ok=TRUE the object is returned unchanged getRNG(1234, num.ok=TRUE) # single integer RNG data = encoded kind head(getRNG(1L)) # embedded RNG data s <- getRNG(list(1L, rng=1234)) identical(s, s1234) #--- hasRNG --- # test for embedded RNG data hasRNG(1) hasRNG( structure(1, rng=1:3) ) hasRNG( list(1, 2, 3) ) hasRNG( list(1, 2, 3, rng=1:3) ) hasRNG( list(1, 2, 3, noise=list(1:3, rng=1)) ) #--- nextRNG --- head(nextRNG()) head(nextRNG(1234)) head(nextRNG(1234, ndraw=10)) #--- setRNG --- obj <- list(x=1000, rng=123) setRNG(obj) rng <- getRNG() runif(10) set.seed(123) rng.equal(rng)
getRNG1
is an S4 generic that returns the initial RNG settings
used for computing an object.
For example, in the case of results from multiple model fits, it would
return the RNG settings used to compute the first fit.
getRNG1(object, ...) ## S4 method for signature 'ANY' getRNG1(object, ...)
getRNG1(object, ...) ## S4 method for signature 'ANY' getRNG1(object, ...)
object |
an R object. |
... |
extra arguments to allow extension. |
getRNG1
is defined to provide separate access to the RNG settings as
they were at the very beginning of a whole computation, which might differ
from the RNG settings returned by getRNG
, that allows to reproduce the
result only.
Think of a sequence of separate computations, from which only one result is
used for the result (e.g. the one that maximizes a likelihood):
getRNG1
would return the RNG settings to reproduce the complete sequence
of computations, while getRNG
would return the RNG settings necessary to
reproduce only the computation whose result has maximum likelihood.
ANY
: Default method that is identical to getRNG(object, ...)
.
rng.equal
compares the RNG settings associated with two objects.
rng.equal(x, y) rng1.equal(x, y)
rng.equal(x, y) rng1.equal(x, y)
x |
objects from which RNG settings are extracted |
y |
object from which RNG settings are extracted |
These functions return TRUE
if the RNG settings are identical,
and FALSE
otherwise.
The comparison is made between the hashes returned by RNGdigest
.
rng.equal
and rng.equal1
return a TRUE
or
FALSE
.
These functions provide a direct access to the RNG seed object .Random.seed
.
RNGseed(seed) RNGrecovery()
RNGseed(seed) RNGrecovery()
seed |
an RNG seed, i.e. an integer vector. No validity check is performed, so it must be a valid seed. |
invisibly the current RNG seed when called with no arguments,
or the – old – value of the seed before changing it to
seed
.
RNGseed
: directly gets/sets the current RNG seed .Random.seed
.
It can typically be used to backup and restore the RNG state on exit of
functions, enabling local RNG changes.
RNGrecovery
: recovers from a broken state of .Random.seed
,
and reset the RNG settings to defaults.
#--- RNGseed --- # get current seed RNGseed() # directly set seed old <- RNGseed(c(401L, 1L, 1L)) # show old/new seed description showRNG(old) showRNG() # set bad seed RNGseed(2:3) try( showRNG() ) # recover from bad state RNGrecovery() showRNG() # example of backup/restore of RNG in functions f <- function(){ orng <- RNGseed() on.exit(RNGseed(orng)) RNGkind('Marsaglia') runif(10) } sample(NA) s <- .Random.seed f() identical(s, .Random.seed)
#--- RNGseed --- # get current seed RNGseed() # directly set seed old <- RNGseed(c(401L, 1L, 1L)) # show old/new seed description showRNG(old) showRNG() # set bad seed RNGseed(2:3) try( showRNG() ) # recover from bad state RNGrecovery() showRNG() # example of backup/restore of RNG in functions f <- function(){ orng <- RNGseed() on.exit(RNGseed(orng)) RNGkind('Marsaglia') runif(10) } sample(NA) s <- .Random.seed f() identical(s, .Random.seed)
These functions are used to generate independent streams of random numbers.
RNGseq(n, seed = NULL, ..., simplify = TRUE, version = 2) RNGseq_seed(seed = NULL, normal.kind = NULL, sample.kind = NULL, verbose = FALSE, version = 2)
RNGseq(n, seed = NULL, ..., simplify = TRUE, version = 2) RNGseq_seed(seed = NULL, normal.kind = NULL, sample.kind = NULL, verbose = FALSE, version = 2)
n |
Number of streams to be created |
seed |
seed specification used to initialise the set of streams
using |
... |
extra arguments passed to |
simplify |
a logical that specifies if sequences of length 1 should be unlisted and returned as a single vector. |
version |
version of the function to use, to reproduce old behaviours.
Version 1 had a bug which made the generated stream sequences share most of their
seeds (!), as well as being not equivalent to calling |
normal.kind |
Type of Normal random generator passed to base::RNGkind. See |
sample.kind |
Type of Discrete Uniform random generator passed to base::RNGkind. See |
verbose |
logical to toggle verbose messages |
a list of integer vectors (or a single integer vector if
n=1
and unlist=TRUE
).
a 7-length numeric vector.
RNGseq
: Creates a given number of seeds for L'Ecuyer's RNG, that can be used to seed
parallel computation, making them fully reproducible.
This ensures complete reproducibility of the set of run.
The streams are created using L'Ecuyer's RNG, implemented in R core since
version 2.14.0 under the name "L'Ecuyer-CMRG"
(see RNG
).
Generating a sequence without specifying a seed uses a single draw of the current RNG. The generation of a sequence using seed (a single or 6-length numeric) a should not affect the current RNG state.
RNGseq_seed
: generates the – next – random seed used as the first seed in
the sequence generated by RNGseq
.
RNGseq(3) RNGseq(3) RNGseq(3, seed=123) # or identically set.seed(123) identical(RNGseq(3), RNGseq(3, seed=123)) RNGseq(3, seed=1:6, verbose=TRUE) # select Normal kind RNGseq(3, seed=123, normal.kind="Ahrens") ## generate a seed for RNGseq # random RNGseq_seed() RNGseq_seed() RNGseq_seed(NULL) # fixed RNGseq_seed(1) RNGseq_seed(1:6) # `RNGseq_seed(1)` is identical to set.seed(1) s <- RNGseq_seed() identical(s, RNGseq_seed(1))
RNGseq(3) RNGseq(3) RNGseq(3, seed=123) # or identically set.seed(123) identical(RNGseq(3), RNGseq(3, seed=123)) RNGseq(3, seed=1:6, verbose=TRUE) # select Normal kind RNGseq(3, seed=123, normal.kind="Ahrens") ## generate a seed for RNGseq # random RNGseq_seed() RNGseq_seed() RNGseq_seed(NULL) # fixed RNGseq_seed(1) RNGseq_seed(1:6) # `RNGseq_seed(1)` is identical to set.seed(1) s <- RNGseq_seed() identical(s, RNGseq_seed(1))
These functions retrieve/prints formated information about RNGs.
RNGstr(object, n = 7L, ...) RNGtype(object, ..., provider = FALSE) showRNG(object = getRNG(), indent = "#", ...) RNGinfo(object = getRNG(), ...) RNGdigest(object = getRNG())
RNGstr(object, n = 7L, ...) RNGtype(object, ..., provider = FALSE) showRNG(object = getRNG(), indent = "#", ...) RNGinfo(object = getRNG(), ...) RNGdigest(object = getRNG())
object |
RNG seed (i.e. an integer vector), or an object that contains
embedded RNG data.
For |
n |
maximum length for a seed to be showed in full.
If the seed has length greater than |
... |
extra arguments passed to |
provider |
logical that indicates if the library that provides the RNG should also be returned as an extra element. |
indent |
character string to use as indentation prefix in the output
from |
All functions can be called with objects that are – valid –
RNG seeds or contain embedded RNG data, but none of them change the current
RNG setting.
To effectively change the current settings on should use setRNG
.
a single character string
RNGtype
returns a named character vector containing the types of the random number generator, which correspond
to the arguments accepted by base::RNGkind.
Note that starting with R 3.6, the vector has length 3, while in previous R versions it has length 2 (no sample.kind element).
RNGstr
: returns a description of an RNG seed as a single character string.
It formats seeds by collapsing them in a comma separated string. By default, seeds that contain more than 7L integers, have their 3 first values collapsed plus a digest hash of the complete seed.
RNGtype
: extract the kinds of RNG and Normal RNG.
It returns the same type of values as RNGkind()
(character strings),
except that it can extract the RNG settings from an object.
If object
is missing it returns the kinds of the current RNG settings,
i.e. it is identical to RNGkind()
.
showRNG
: displays human readable information about RNG settings.
If object
is missing it displays information about the current RNG.
RNGinfo
: is equivalent to RNGtype
but returns a named
list instead of an unnamed character vector.
# default is a 626-long integer RNGstr() # what would be the seed after seeding with set.seed(1234) RNGstr(1234) # another RNG (short seed) RNGstr(c(401L, 1L, 1L)) # no validity check is performed RNGstr(2:3) # get RNG type RNGtype() RNGtype(provider=TRUE) RNGtype(1:3) # type from encoded RNG kind RNGtype(107L) # this is different from the following which treats 107 as a seed for set.seed RNGtype(107) showRNG() # as after set.seed(1234) showRNG(1234) showRNG() set.seed(1234) showRNG() # direct seeding showRNG(1:3) # this does not change the current RNG showRNG() showRNG(provider=TRUE) # get info as a list RNGinfo() RNGinfo(provider=TRUE) # from encoded RNG kind RNGinfo(107) # compute digest hash from RNG settings RNGdigest() RNGdigest(1234) # no validity check is performed RNGdigest(2:3)
# default is a 626-long integer RNGstr() # what would be the seed after seeding with set.seed(1234) RNGstr(1234) # another RNG (short seed) RNGstr(c(401L, 1L, 1L)) # no validity check is performed RNGstr(2:3) # get RNG type RNGtype() RNGtype(provider=TRUE) RNGtype(1:3) # type from encoded RNG kind RNGtype(107L) # this is different from the following which treats 107 as a seed for set.seed RNGtype(107) showRNG() # as after set.seed(1234) showRNG(1234) showRNG() set.seed(1234) showRNG() # direct seeding showRNG(1:3) # this does not change the current RNG showRNG() showRNG(provider=TRUE) # get info as a list RNGinfo() RNGinfo(provider=TRUE) # from encoded RNG kind RNGinfo(107) # compute digest hash from RNG settings RNGdigest() RNGdigest(1234) # no validity check is performed RNGdigest(2:3)
This package contains a set of functions for working with Random Number Generators (RNGs). In particular, it defines a generic S4 framework for getting/setting the current RNG, or RNG data that are embedded into objects for reproducibility.
Notably, convenient default methods greatly facilitate the way current RNG settings can be changed.
showRNG() s <- getRNG() RNGstr(s) RNGtype(s) # get what would be the RNG seed after set.seed s <- nextRNG(1234) showRNG(s) showRNG( nextRNG(1234, ndraw=10) ) # change of RNG kind showRNG() k <- RNGkind() k[2L] <- 'Ahrens' try( RNGkind(k) ) setRNG(k) showRNG() # set encoded kind setRNG(501L) showRNG() # use as set seed setRNG(1234) showRNG() r <- getRNG() # extract embedded RNG specifications runif(10) setRNG(list(1, rng=1234)) rng.equal(r) # restore default RNG (e.g., after errors) RNGrecovery() showRNG()
showRNG() s <- getRNG() RNGstr(s) RNGtype(s) # get what would be the RNG seed after set.seed s <- nextRNG(1234) showRNG(s) showRNG( nextRNG(1234, ndraw=10) ) # change of RNG kind showRNG() k <- RNGkind() k[2L] <- 'Ahrens' try( RNGkind(k) ) setRNG(k) showRNG() # set encoded kind setRNG(501L) showRNG() # use as set seed setRNG(1234) showRNG() r <- getRNG() # extract embedded RNG specifications runif(10) setRNG(list(1, rng=1234)) rng.equal(r) # restore default RNG (e.g., after errors) RNGrecovery() showRNG()