Skip to content

How to construct a valid seed for l'Ecuyer's method with given .Random.seed?

5 messages · Marius Hofert, Hana Sevcikova, Daniel Nordlund

#
I updated to the latest CRAN versions of 'rlecuyer', 'Rmpi', and 'snow':
    
,----[ sessionInfo() ]
| ...
| other attached packages:
| [1] rlecuyer_0.3-3 Rmpi_0.6-1     snow_0.3-10   
| ...
`----

But I still obtain:

,----
| Error in .lec.SetPackageSeed(seed) : 
|   Seed[1] >= -1065242851, Seed is not set.
`----

when executing

,----
| library(snow)
| RNGkind("L'Ecuyer-CMRG")
| cl <- makeCluster(parallel::detectCores(), type="MPI")
| .t <- snow::clusterSetupRNG(cl, seed=.Random.seed[2:7])
| stopCluster(cl)
`----
#
Since clusterSetupRNG() calls clusterSetupRNGstream() and this calls .lec.SetPackageSeed(), I could further minimalize the problem:

set.seed(1)
RNGkind("L'Ecuyer-CMRG") # => .Random.seed is of length 7 (first number encodes the rng kind)
(seed <- .Random.seed[2:7]) # should give a valid seed for l'Ecuyer's RNG
require(rlecuyer) # latest version 0.3-3
.lec.SetPackageSeed(seed)

The last line fails with:

,----
| Error in .lec.SetPackageSeed(seed) :
|   Seed[0] >= -767742437, Seed is not set.
`----

Looking at .lec.SetPackageSeed, "seed" seems to pass .lec.CheckSeed() [the check
could probably be improved here (but further checking is done in the C code; see
below)]:

,----
| > .lec.SetPackageSeed
| function (seed = rep(12345, 6))
| {
|     if (!exists(".lec.Random.seed.table", envir = .GlobalEnv))
|         .lec.init()
|     seed <- .lec.CheckSeed(seed) # => bad check since it's passed
|     .Call("r_set_package_seed", as.double(seed), PACKAGE = "rlecuyer") # => this fails!
|     return(seed)
| }
| <environment: namespace:rlecuyer>
`----

Going into the C code, r_set_package_seed calls RngStream_SetPackageSeed which in turn calls CheckSeed(seed). The relevant part of CheckSeed is this:

,----
| for (i = 0; i < 3; ++i) {
|     if (seed[i] >= m1) {
|     	/* HS 01-25-2012 */
|     	error("Seed[%1d] >= %d, Seed is not set.\n", i,m1);
|        /* original code
|          fprintf (stderr, "****************************************\n"
|       	 "ERROR: Seed[%1d] >= m1, Seed is not set.\n"
|       	 "****************************************\n\n", i);
|           return (-1);
|        */
|      }
| }
`----

Note that seed[0] in this (C-)code corresponds to the first element of my
variable "seed", which is -1535484873. This should definitely be smaller than m1
since m1 is defined as 4294967087.0 on line 34 in ./src/RngStream.c of the package 'rlecuyer'.

Why is seed[i] then >= m1??? This is strange. Indeed, as you can see from the
error message above, m1 is taken as -767742437 in my case (why?). Still (and even more
confusing), -1535484873 >= -767742437 is FALSE (!) but the if(){} is entered
anyways...


Cheers,

Marius
#
Marius,

I looked it up in the original L'Ecuyer's paper: The seed must be larger 
than 0. Thus, the function defines the seed variable as unsigned long 
integer. You're passing a negative number, so I think there is some 
overflow going on.

The internal L'Ecuyer RNG is a modification of the original one (and I'm 
not familiar with it), but they seem to relax that restriction.

Hana
On 1/23/13 1:01 AM, Marius Hofert wrote:
#
Dear Hana,

Thanks for helping.

I am still wondering, why m1 (which should be 2^32-209 [see line 34 in
./src/RngStream.c]) is -767742437 in my case and why the minimal example you
gave was working for you but isn't for me.

Apart from that, ?.Random.seed -> "L'Ecuyer-CMRG" says:

,----
| The 6 elements of the seed are internally regarded as 32-bit
| unsigned integers.  Neither the first three nor the last
| three should be all zero, and they are limited to less than
| ?4294967087? and ?4294944443? respectively.
`----

=> .Random.seed provides a *signed* integer. I tried to convert it to an
unsigned integer:

RNGkind()
set.seed(1)
.Random.seed[-1]
RNGkind("L'Ecuyer-CMRG")
.Random.seed[-1] # => unsigned

seed <- .Random.seed[-1] + 2^32 # => shifting
require(rlecuyer)
.lec.SetPackageSeed(seed)

... but it fails with

,----
| Error in .lec.SetPackageSeed(seed) : Seed[1] >= 14, Seed is not set.
`----

=> so there seem to be the requirement that the second element of the seed is <
14 (???). 

I might have done the conversion to a signed integer incorrectly, though.

It would be great if the seed was checked *precisely* (not just basic length
checks) in R, maybe in .lec.CheckSeed(). That would rule out further problems
and strange error messages from C, which are harder to debug. 

What are the precise conditions for the seed in 'rlecuyer'? Judging from the
above error, the second element must be < 14. But, additionally,... ?

I hope there is a solution to the problem of "how to convert .Random.seed to get
a valid seed for 'rlecuyer'"... we need that in a package. 

Cheers,

Marius




Hana Sevcikova <hanas at uw.edu> writes:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20130123/c79c5366/attachment.bin>
#
I apologize if this message is posted twice.  I am having email problems.

I think the confusion about negative numbers is that R represents the seed values as signed integers, but the underlying C code interprets those values as unsigned integers.  At least that is how I read the documentation on .Random.seed 


Hope this is helpful,

Dan

Daniel Nordlund
Bothell, WA USA