From savicky at cs.cas.cz  Mon Oct 22 14:50:26 2007
From: savicky at cs.cas.cz (savicky at cs.cas.cz)
Date: Mon, 22 Oct 2007 14:50:26 +0200 (CEST)
Subject: [Rd] bug in detection of zero state for Mersenne Twister (PR#10362)
Message-ID: <20071022125026.D577D283416B@mail.pubhealth.ku.dk>

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;



[Rd] bug in detection of zero state for Mersenne Twister (PR#10362)
savicky at cs.cas.cz