Making functions that set the random seed independent

josliber

Sometimes I want to write a randomized function that always returns the same output for a particular input. I've always implemented this by setting the random seed at the top of the function and then proceeding. Consider two functions defined in this way:

sample.12 <- function(size) {
  set.seed(144)
  sample(1:2, size, replace=TRUE)
}
rand.prod <- function(x) {
  set.seed(144)
  runif(length(x)) * x
}

sample.12 returns a vector of the specified size randomly sampled from the set {1, 2} and rand.prod multiplies each element of a specified vector by a random value uniformly selected from [0, 1]. Normally I would expect x <- sample.12(10000) ; rand.prod(x) to have a "step" distribution with pdf 3/4 in the range [0, 1] and 1/4 in the range [1, 2], but due to my unfortunate choice of identical random seeds above I see a different result:

x <- sample.12(10000)
hist(rand.prod(x))

enter image description here

I can fix this issue in this case by changing the random seed in one of the functions to some other value. For instance, with set.seed(10000) in rand.prod I get the expected distribution:

enter image description here

Previously on SO this solution of using different seeds has been accepted as the best approach to generate independent random number streams. However, I find the solution to be unsatisfying because streams with different seeds could be related to one another (possibly even highly related to one another); in fact, they might even yield identical streams according to ?set.seed:

There is no guarantee that different values of seed will seed the RNG differently, although any exceptions would be extremely rare.

Is there a way to implement a pair of randomized functions in R that:

  1. Always return the same output for a particular input, and
  2. Enforce independence between their sources of randomness by more than just using different random seeds?
josliber

I've dug into this some more and it looks like the rlecuyer package provides independent random streams:

Provides an interface to the C implementation of the random number generator with multiple independent streams developed by L'Ecuyer et al (2002). The main purpose of this package is to enable the use of this random number generator in parallel R applications.

The first step is global initialization of the independent streams:

library(rlecuyer)
.lec.CreateStream(c("stream.12", "stream.prod"))

Then each function needs to be modified to reset the appropriate stream to its beginning state (.lec.RestartStartStream), set the R random number generator to the appropriate stream (.lec.CurrentStream), and afterward set the R random number generator back to its state before the function was called (.lec.CurrentStreamEnd).

sample.12 <- function(size) {
  .lec.ResetStartStream("stream.12")
  .lec.CurrentStream("stream.12")
  x <- sample(1:2, size, replace=TRUE)
  .lec.CurrentStreamEnd()
  x
}
rand.prod <- function(x) {
  .lec.ResetStartStream("stream.prod")
  .lec.CurrentStream("stream.prod")
  y <- runif(length(x)) * x
  .lec.CurrentStreamEnd()
  y
}

This satisfies the "always returns the same output given the same input" requirement:

all.equal(rand.prod(sample.12(10000)), rand.prod(sample.12(10000)))
# [1] TRUE

The streams also appears to operate independently in our example:

x <- sample.12(10000)
hist(rand.prod(x))

enter image description here

Note that this would not give consistent values across runs of our script because each call to .lec.CreateStream would give a different initial state. To address this, we could note the initial state for each stream:

.lec.GetState("stream.12")
# [1] 3161578179 1307260052 2724279262 1101690876 1009565594  836476762
.lec.GetState("stream.prod")
# [1]  596094074 2279636413 3050913596 1739649456 2368706608 3058697049

We can then change the stream initialization at the beginning of the script to:

library(rlecuyer)
.lec.CreateStream(c("stream.12", "stream.prod"))
.lec.SetSeed("stream.12", c(3161578179, 1307260052, 2724279262, 1101690876, 1009565594, 836476762))
.lec.SetSeed("stream.prod", c(596094074, 2279636413, 3050913596, 1739649456, 2368706608, 3058697049))

Now calls to sample.12 and rand.prod will match across calls to the script.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

set the random seed in julia generator of random numbers

From Dev

set.seed() function influence into random in R

From Dev

Set the same seed in random-normal NetLogo

From Dev

Tensorflow `set_random_seed` not working

From Dev

Set the same seed in random-normal NetLogo

From Dev

JavaScript Making independent functions work without defining new

From Dev

Set random negative number with Random Functions in Jmeter?

From Dev

How to set random seed in Galsim, the modular galaxy image simulation toolkit

From Dev

C++11: How to set seed using <random>

From Dev

How to set the same initial seed random numbers in Matlab?

From Dev

How to set random seed in Galsim, the modular galaxy image simulation toolkit

From Dev

Generating random vector that's linearly independent of a set of vectors

From Dev

How to get seed of current state of random generator in goal to place it in set.seed() function

From Dev

set has no order but random.choice( list(set) ) is unstable given random seed

From Dev

Making an independent List<T>

From Dev

How to set random seed in sqlalchemy.sql.expression.func.random() in python?

From Dev

Does setting the seed in tf.random.set_seed also set the seed used by the glorot_uniform kernel_initializer when using a conv2D layer in keras?

From Dev

How to create random seed

From Dev

Random number Generation with Seed

From Dev

ORDER BY random() with seed in SQLITE

From Dev

Choose random seed and save it

From Dev

Python: Random seed issues

From Dev

Remember location(?) in Random seed?

From Dev

Choose random seed and save it

From Dev

Bash RANDOM with seed?

From Dev

Using a random seed in Rmallet

From Dev

Get seed of Random object without passing in the seed?

From Dev

Get seed of Random object without passing in the seed?

From Dev

Width independent functions

Related Related

  1. 1

    set the random seed in julia generator of random numbers

  2. 2

    set.seed() function influence into random in R

  3. 3

    Set the same seed in random-normal NetLogo

  4. 4

    Tensorflow `set_random_seed` not working

  5. 5

    Set the same seed in random-normal NetLogo

  6. 6

    JavaScript Making independent functions work without defining new

  7. 7

    Set random negative number with Random Functions in Jmeter?

  8. 8

    How to set random seed in Galsim, the modular galaxy image simulation toolkit

  9. 9

    C++11: How to set seed using <random>

  10. 10

    How to set the same initial seed random numbers in Matlab?

  11. 11

    How to set random seed in Galsim, the modular galaxy image simulation toolkit

  12. 12

    Generating random vector that's linearly independent of a set of vectors

  13. 13

    How to get seed of current state of random generator in goal to place it in set.seed() function

  14. 14

    set has no order but random.choice( list(set) ) is unstable given random seed

  15. 15

    Making an independent List<T>

  16. 16

    How to set random seed in sqlalchemy.sql.expression.func.random() in python?

  17. 17

    Does setting the seed in tf.random.set_seed also set the seed used by the glorot_uniform kernel_initializer when using a conv2D layer in keras?

  18. 18

    How to create random seed

  19. 19

    Random number Generation with Seed

  20. 20

    ORDER BY random() with seed in SQLITE

  21. 21

    Choose random seed and save it

  22. 22

    Python: Random seed issues

  23. 23

    Remember location(?) in Random seed?

  24. 24

    Choose random seed and save it

  25. 25

    Bash RANDOM with seed?

  26. 26

    Using a random seed in Rmallet

  27. 27

    Get seed of Random object without passing in the seed?

  28. 28

    Get seed of Random object without passing in the seed?

  29. 29

    Width independent functions

HotTag

Archive