savicky at cs.cas.cz
2007-Oct-22 12:50 UTC
[Rd] bug in detection of zero state for Mersenne Twister (PR#10362)
Full_Name: Petr Savicky Version: all versions starting from 1.7.0 OS: observed on Linux, but is platform independent Submission from: (NULL) (62.24.91.47) The function runif(n) contains a protection against the zero state of Mersenne Twister stored in .Random.seed. If the state is zero, it is regenerated using current time, since a zero state is a fixed point of the recurrence and, hence, produces a constant sequence. The detection of zero state contains a bug, due to which a zero state may not be recognized. This happens if there are nonzero bits in .Random.seed[3] at positions, which are not used by Mersenne Twister (only the most significant bit of .Random.seed[3] is used and the remaining 31 are discarded). An example of such a situation is RNGkind("default") .Random.seed[3] <- as.integer(1) .Random.seed[4:626] <- as.integer(0) x <- runif(10000) all(x==x[1]) # TRUE all(.Random.seed[3:626]==0) # TRUE The output shows that the initial state was indeed effectively zero, since the final state is all zeros. The following patch to FixupSeeds corrects the detection of zero state: --- R-devel_2007-10-21-orig/src/main/RNG.c 2007-09-02 07:49:35.000000000 +0200 +++ R-devel_2007-10-21-FixupSeeds/src/main/RNG.c 2007-10-21 21:47:02.455450224 +0200 @@ -181,7 +181,9 @@ /* No action unless user has corrupted .Random.seed */ if(I1 <= 0) I1 = 624; /* check for all zeroes */ - for (j = 1; j <= 624; j++) + notallzero = ((RNG_Table[RNG_kind].i_seed[1] & 0x80000000) != 0); + if(!notallzero) + for (j = 2; j <= 624; j++) if(RNG_Table[RNG_kind].i_seed[j] != 0) { notallzero = 1; break;