Random Number Seed
The use of random number seeds in secr is explained.
A seed suitable for any kind of RNG is held in a vector of 626 integers named .Random.seed
. The vector is not to be modified directly by users. Instead, to start a reproducible stream of random numbers, the user calls set.seed
with a single non-null integer argument. This has the effect of initialising .Random.seed
. The value of .Random.seed
may nevertheless be stored and restored to reset the RNG state.
set.seed
with a NULL argument initialises .Random.seed
to an indeterminate (time- and process-dependent) value. The same happens if a random number function is called before .Random.seed
has been set.
The ‘official’ approach to setting and storing the RNG seed is shown in code and documentation for the generic function simulate
in the stats package.
The generic has argument ‘seed’ with default NULL.
If ‘seed’ is non-null then set.seed
is called.
The returned value has an attribute “seed” whose value is either (i) if specified, the integer value of the ‘seed’ argument (with its own attribute “kind” from RNGkind), or (ii) the original vector .Random.seed
.
On exit the RNG state in .Random.seed
is reset to the value that applied when the function was called.
For NULL seed input, the saved RNGstate may be used to reset .Random.seed (see Examples).
Many functions in secr call on random numbers, sometimes in unexpected places. For example autoini
selects a random sample to thin points and speed computation. In most functions there is no provision for direct control of the random number state: users won't usually care, and if they do then set.seed
may be called for the particular R session. Exceptions are ip.secr
and par.secr.fit
; both allow control of the seed, but do not save it.
However, control of the RNG seed is required for reproducible data generation in simulation functions. These functions typically have a ‘seed’ argument that is used internally in a call to set.seed
. Handling of seeds in the simulation functions of secr largely follows stats::simulate
as described in the preceding section.
The relevant functions are –
Function | Default | Saved attribute | Note |
randomHabitat |
NULL | seed or RNGstate | |
secr.test |
NULL | seed or RNGstate | calls and retains seed from simulate.secr |
sim.capthist |
NULL | seed or RNGstate | |
sim.resight |
NULL | seed or RNGstate | Seed may be passed in ... argument |
sim.popn |
NULL | seed or RNGstate | |
sim.secr |
NULL | seed or RNGstate | |
simulate.secr |
NULL | seed or RNGstate | S3 method called by sim.secr
|
Setting seed = NULL
in any of these functions has the effect of continuing the existing random number stream; it is not the same as calling set.seed(NULL)
. Two functions at present do not follow this model: ip.secr
and par.secr.fit
.
In the parallel model the L'Ecuyer pseudorandom generator is used to provide a separate random number stream for each core (see clusterSetRNGStream
).
When using Rcpp the state of the random number generator is set in C++ with the call
RNGScope scope;
that automatically resets the state of the generator on exit (Eddelbuettel 2013 p. 115).
Random number streams in separate RcppParallel threads are (probably) not independent. Thus there are potential issues with RNG calls in multi-threaded code. However, in secr 4.0 all RNG calls in C++ code are outside multi-threaded contexts, with the exception of simulations allowing for overdispersion in mark–resight estimates (Rcpp exported function sightingchatcpp). The implications for mark-resight estimates have not been explored, and it is unclear whether more elaborate solutions are needed.
Eddelbuettel, D. 2013. Seamless R and C++ integration with Rcpp. Springer.
## Not run: lmfit <- lm(speed ~ dist, data = cars) ## 1. NULL seed r1 <- simulate(lmfit, seed = NULL) r2 <- simulate(lmfit, seed = NULL) ## restore RNGstate, assuming RNGkind unchanged .Random.seed <- attr(r1, "seed") r3 <- simulate(lmfit, seed = NULL) r1[1:6,1] r2[1:6,1] r3[1:6,1] ## 2. explicit seed r4 <- simulate(lmfit, seed = 123) r5 <- simulate(lmfit, seed = attr(r4, "seed")) r4[1:6,1] r5[1:6,1] ## End(Not run)
Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.