Skip to content

Instantly share code, notes, and snippets.

@hadley
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hadley/10371417 to your computer and use it in GitHub Desktop.
Save hadley/10371417 to your computer and use it in GitHub Desktop.
Manage multiple independent streams of random numbers
get_seed <- function() {
if (!exists(".Random.seed", envir = globalenv())) return(NULL)
get(".Random.seed", envir = globalenv())
}
set_seed <- function(x) {
old <- cur_seed()
if (!is.null(x)) {
assign(".Random.seed", x, envir = globalenv())
}
invisible(old)
}
new_seed <- function(seed) {
old <- cur_seed()
on.exit(set_seed(old))
set.seed(seed)
cur_seed()
}
Stream <- setRefClass("Stream",
fields = list(seed = "integer"),
methods = list(
initialize = function(seed = 1014) {
seed <<- new_seed(seed)
},
use = function(code) {
old <- cur_seed()
on.exit(set_seed(old))
set_seed(seed)
res <- code
seed <<- get_seed()
res
},
random_bytes = function(bytes) {
use(paste(as.hexmode(sample(255, bytes, replace = TRUE)), collapse = ""))
}
)
)
A1 <- Stream()
A2 <- Stream()
B <- Stream(1015)
# A1 and A2 share the same starting seed so produce
# the same stream of values
A1$use(runif(1))
A1$use(runif(1))
A2$use(runif(1))
A2$use(runif(1))
# B shares a different stream of values, so produce a
# different stream
B$use(runif(1))
B$use(runif(1))
# No stream interfers with the global stream
cur <- .Random.seed
A1$use(runif(5))
stopifnot(identical(cur, .Random.seed))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment