[Rd] initial scrambling of seed in do_setseed / RNG_Init
Petr Savicky
savicky at cs.cas.cz
Sun Sep 23 12:43:48 CEST 2007
I would like to suggest a modification of initial scrambling of the
seed in RNG_Init (called from do_setseed). The modified code is
equivalent, but faster. Patch against R-devel_2007-09-22 follows
--- R-devel-orig/src/main/RNG.c 2007-09-02 07:49:35.000000000 +0200
+++ R-devel-modif/src/main/RNG.c 2007-09-23 10:51:59.234566440 +0200
@@ -216,8 +216,8 @@
BM_norm_keep = 0.0; /* zap Box-Muller history */
/* Initial scrambling */
- for(j = 0; j < 50; j++)
- seed = (69069 * seed + 1);
+ /* Equivalent to 50 iterations of seed = (69069 * seed + 1) */
+ seed = (1100682473U * seed + 2358491998U);
switch(kind) {
case WICHMANN_HILL:
case MARSAGLIA_MULTICARRY:
Let me add also the following remark. The help(Random.user) page says
Optionally, the user can supply the entry point 'user_unif_init',
which is called with an 'unsigned int' argument when 'RNGkind' (or
'set.seed') is called, and is intended to be used to initialize
the user's RNG code. The argument is intended to be used to set
the "seeds"; it is the 'seed' argument to 'set.seed' or an
essentially random seed if 'RNGkind' is called.
I want to comment on the sentence
The argument is intended to be used to set
the "seeds"; it is the 'seed' argument to 'set.seed' or ....
This is not correct. If user_unif_init is called from set.seed, then
it receives the argument of set.seed after the initial scrambling.
If someone writes a user defined generator and wishes to get the original
seed specified in set.seed (which is my situation), then it may be useful
for him to know that the transformation
seed = 3602842457U * (seed - 2358491998U);
is the inverse to the initial scrambling. Hence, if it is applied to the
value received by user_unif_init, it provides the original value specified
by the user in set.seed.
Let me point out that the initial scrambling does not eliminate seed 0.
It only decreases the probability that this seed is sent to the generator.
Due to scrambling, the entry point user_unif_init receives 0 not as a
consequence of set.seed(0), but as a consequence of set.seed(105890386).
This is less likely, but still possible.
I suggest to clarify the page help(Random.user) concerning the transformation
of the seed. For example, the sentence
it is the 'seed' argument to 'set.seed'
may be extended to
it is the 'seed' argument to 'set.seed' after a transformation described
in function RNG_Init in src/main/RNG.c
Also, a remark concerning the inverse transformation may be add. In my opinion,
the best way to do this could be to add a comment to RNG_Init in src/main/RNG.c,
saying, for example:
If you need to undo the initial scrambling in user_unif_init, use
seed = 3602842457U * (seed - 2358491998U);
Petr Savicky.
More information about the R-devel
mailing list