Coverage Report

Created: 2026-09-14 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/r-source/src/main/RNG.c
Line
Count
Source
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1997--2026  The R Core Team
4
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, a copy is available at
18
 *  https://www.R-project.org/Licenses/
19
 */
20
21
22
#ifdef HAVE_CONFIG_H
23
#include <config.h>
24
#endif
25
26
#include <Defn.h>
27
#include <Internal.h>
28
#include <R_ext/Random.h>
29
30
/* Normal generator is not actually set here but in ../nmath/snorm.c */
31
0
#define RNG_DEFAULT MERSENNE_TWISTER
32
0
#define N01_DEFAULT INVERSION
33
0
#define Sample_DEFAULT REJECTION
34
0
#define Binom_DEFAULT BTPE
35
36
37
#include <R_ext/Rdynload.h>
38
39
static DL_FUNC User_unif_fun, User_unif_nseed,
40
  User_unif_seedloc;
41
typedef void (*UnifInitFun)(Int32);
42
43
UnifInitFun User_unif_init = NULL; /* some picky compilers */
44
45
DL_FUNC  User_norm_fun = NULL; /* also in ../nmath/snorm.c */
46
47
static RNGtype RNG_kind = RNG_DEFAULT;
48
#include "nmath2.h" /* ../nmath/nmath2.h : */
49
// extern N01type N01_kind; /* from ../nmath/snorm.c */
50
// extern double BM_norm_keep;   /* ../nmath/snorm.c */
51
// extern Binomtype Binom_kind ; /* ../nmath/rbinom.c */
52
static Sampletype Sample_kind = Sample_DEFAULT;
53
54
55
56
/* typedef unsigned int Int32; in Random.h */
57
58
/* .Random.seed == (RNGkind, i_seed[0],i_seed[1],..,i_seed[n_seed-1])
59
 * or           == (RNGkind) or missing  [--> Randomize]
60
 * where  RNGkind :=  RNG_kind  +  100 * N01_kind  +  10000 * Sample_kind  + 100'000 * Binom_kind
61
 * currently in  outer(outer(outer(0:7, 100*(0:5), "+"), 10000*(0:1), "+"), 100000*(0:1), "+")
62
 */
63
64
typedef struct {
65
    RNGtype kind;
66
    N01type Nkind;
67
    char *name; /* print name */
68
    int n_seed; /* length of seed vector */
69
    Int32 *i_seed;
70
} RNGTAB;
71
72
73
static Int32 dummy[628]; // allow for optimizing compilers to read over bound
74
static
75
RNGTAB RNG_Table[] =
76
{
77
/* kind Nkind   name             n_seed      i_seed */
78
    { WICHMANN_HILL,        BUGGY_KINDERMAN_RAMAGE, "Wichmann-Hill",       3, dummy},
79
    { MARSAGLIA_MULTICARRY, BUGGY_KINDERMAN_RAMAGE, "Marsaglia-MultiCarry",  2, dummy},
80
    { SUPER_DUPER,          BUGGY_KINDERMAN_RAMAGE, "Super-Duper",       2, dummy},
81
    { MERSENNE_TWISTER,     BUGGY_KINDERMAN_RAMAGE, "Mersenne-Twister",  1+624, dummy},
82
    { KNUTH_TAOCP,          BUGGY_KINDERMAN_RAMAGE, "Knuth-TAOCP",       1+100, dummy},
83
    { USER_UNIF,            BUGGY_KINDERMAN_RAMAGE, "User-supplied",         0, dummy},
84
    { KNUTH_TAOCP2,         BUGGY_KINDERMAN_RAMAGE, "Knuth-TAOCP-2002",  1+100, dummy},
85
    { LECUYER_CMRG,         BUGGY_KINDERMAN_RAMAGE, "L'Ecuyer-CMRG",         6, dummy},
86
};
87
88
89
#define d2_32 4294967296./* = (double) */
90
0
#define i2_32m1 2.328306437080797e-10/* = 1/(2^32 - 1) */
91
0
#define KT      9.31322574615479e-10 /* = 2^-30 */
92
93
0
#define I1 (RNG_Table[RNG_kind].i_seed[0])
94
0
#define I2 (RNG_Table[RNG_kind].i_seed[1])
95
0
#define I3 (RNG_Table[RNG_kind].i_seed[2])
96
97
static void Randomize(RNGtype kind);
98
static double MT_genrand(void);
99
static Int32 KT_next(void);
100
static void RNG_Init_R_KT(Int32);
101
static void RNG_Init_KT2(Int32);
102
0
#define KT_pos (RNG_Table[KNUTH_TAOCP].i_seed[100])
103
104
static double fixup(double x)
105
0
{
106
    /* ensure 0 and 1 are never returned */
107
0
    if(x <= 0.0) return 0.5*i2_32m1;
108
0
    if((1.0 - x) <= 0.0) return 1.0 - 0.5*i2_32m1;
109
0
    return x;
110
0
}
111
112
113
double unif_rand(void)
114
0
{
115
0
    double value;
116
117
0
    switch(RNG_kind) {
118
119
0
    case WICHMANN_HILL:
120
0
  I1 = I1 * 171 % 30269;
121
0
  I2 = I2 * 172 % 30307;
122
0
  I3 = I3 * 170 % 30323;
123
0
  value = I1 / 30269.0 + I2 / 30307.0 + I3 / 30323.0;
124
0
  return fixup(value - (int) value);/* in [0,1) */
125
126
0
    case MARSAGLIA_MULTICARRY:/* 0177777(octal) == 65535(decimal)*/
127
0
  I1= 36969*(I1 & 0177777) + (I1>>16);
128
0
  I2= 18000*(I2 & 0177777) + (I2>>16);
129
0
  return fixup(((I1 << 16)^(I2 & 0177777)) * i2_32m1); /* in [0,1) */
130
131
0
    case SUPER_DUPER:
132
  /* This is Reeds et al (1984) implementation;
133
   * modified using __unsigned__  seeds instead of signed ones
134
   */
135
0
  I1 ^= ((I1 >> 15) & 0377777); /* Tausworthe */
136
0
  I1 ^= I1 << 17;
137
0
  I2 *= 69069;    /* Congruential */
138
0
  return fixup((I1^I2) * i2_32m1); /* in [0,1) */
139
140
0
    case MERSENNE_TWISTER:
141
0
  return fixup(MT_genrand());
142
143
0
    case KNUTH_TAOCP:
144
0
    case KNUTH_TAOCP2:
145
0
  return fixup(KT_next() * KT);
146
147
0
    case USER_UNIF:
148
0
  return *((double *) User_unif_fun());
149
150
0
    case LECUYER_CMRG:
151
0
    {
152
  /* Based loosely on the GPL-ed version of
153
     http://www.iro.umontreal.ca/~lecuyer/myftp/streams00/c2010/RngStream.c
154
     but using int_least64_t, which C99 guarantees.
155
  */
156
0
  int k;
157
0
  int_least64_t p1, p2;
158
159
0
#define II(i) (RNG_Table[RNG_kind].i_seed[i])
160
0
#define m1    4294967087
161
0
#define m2    4294944443
162
0
#define normc  2.328306549295727688e-10
163
0
#define a12     (int_least64_t)1403580
164
0
#define a13n    (int_least64_t)810728
165
0
#define a21     (int_least64_t)527612
166
0
#define a23n    (int_least64_t)1370589
167
168
0
  p1 = a12 * (unsigned int)II(1) - a13n * (unsigned int)II(0);
169
  /* p1 % m1 would surely do */
170
0
  k = (int) (p1 / m1);
171
0
  p1 -= k * m1;
172
0
  if (p1 < 0) p1 += m1;
173
0
  II(0) = II(1); II(1) = II(2); II(2) = (int) p1;
174
175
0
  p2 = a21 * (unsigned int)II(5) - a23n * (unsigned int)II(3);
176
0
  k = (int) (p2 / m2);
177
0
  p2 -= k * m2;
178
0
  if (p2 < 0) p2 += m2;
179
0
  II(3) = II(4); II(4) = II(5); II(5) = (int) p2;
180
181
0
  return (double)((p1 > p2) ? (p1 - p2) : (p1 - p2 + m1)) * normc;
182
0
    }
183
0
    default:
184
0
  error(_("unif_rand: unimplemented RNG kind %d"), RNG_kind);
185
0
  return -1.;
186
0
    }
187
0
}
188
189
/* we must mask global variable here, as I1-I3 hide RNG_kind
190
   and we want the argument */
191
static void FixupSeeds(RNGtype RNG_kind, int initial)
192
0
{
193
/* Depending on RNG, set 0 values to non-0, etc. */
194
195
0
    int j, notallzero = 0;
196
197
    /* Set 0 to 1 :
198
       for(j = 0; j <= RNG_Table[RNG_kind].n_seed - 1; j++)
199
       if(!RNG_Table[RNG_kind].i_seed[j]) RNG_Table[RNG_kind].i_seed[j]++; */
200
201
0
    switch(RNG_kind) {
202
0
    case WICHMANN_HILL:
203
0
  I1 = I1 % 30269; I2 = I2 % 30307; I3 = I3 % 30323;
204
205
  /* map values equal to 0 mod modulus to 1. */
206
0
  if(I1 == 0) I1 = 1;
207
0
  if(I2 == 0) I2 = 1;
208
0
  if(I3 == 0) I3 = 1;
209
0
  return;
210
211
0
    case SUPER_DUPER:
212
0
  if(I1 == 0) I1 = 1;
213
  /* I2 = Congruential: must be ODD */
214
0
  I2 |= 1;
215
0
  break;
216
217
0
    case MARSAGLIA_MULTICARRY:
218
0
  if(I1 == 0) I1 = 1;
219
0
  if(I2 == 0) I2 = 1;
220
0
  break;
221
222
0
    case MERSENNE_TWISTER:
223
0
  if(initial) I1 = 624;
224
   /* No action unless user has corrupted .Random.seed */
225
0
  if(I1 <= 0) I1 = 624;
226
  /* check for all zeroes */
227
0
  for (j = 1; j <= 624; j++)
228
0
      if(RNG_Table[RNG_kind].i_seed[j] != 0) {
229
0
    notallzero = 1;
230
0
    break;
231
0
      }
232
0
  if(!notallzero) Randomize(RNG_kind);
233
0
  break;
234
235
0
    case KNUTH_TAOCP:
236
0
    case KNUTH_TAOCP2:
237
0
  if(KT_pos <= 0) KT_pos = 100;
238
  /* check for all zeroes */
239
0
  for (j = 0; j < 100; j++)
240
0
      if(RNG_Table[RNG_kind].i_seed[j] != 0) {
241
0
    notallzero = 1;
242
0
    break;
243
0
      }
244
0
  if(!notallzero) Randomize(RNG_kind);
245
0
  break;
246
0
    case USER_UNIF:
247
0
  break;
248
0
    case LECUYER_CMRG:
249
  /* first set: not all zero, in [0, m1)
250
     second set: not all zero, in [0, m2) */
251
0
    {
252
0
  unsigned int tmp;
253
0
  int allOK = 1;
254
0
  for (j = 0; j < 3; j++) {
255
0
      tmp = RNG_Table[RNG_kind].i_seed[j];
256
0
      if(tmp != 0) notallzero = 1;
257
0
      if (tmp >= m1) allOK = 0;
258
0
  }
259
0
  if(!notallzero || !allOK) Randomize(RNG_kind);
260
0
  for (j = 3; j < 6; j++) {
261
0
      tmp = RNG_Table[RNG_kind].i_seed[j];
262
0
      if(tmp != 0) notallzero = 1;
263
0
      if (tmp >= m2) allOK = 0;
264
0
  }
265
0
  if(!notallzero || !allOK) Randomize(RNG_kind);
266
0
    }
267
0
    break;
268
0
    default:
269
0
  error(_("FixupSeeds: unimplemented RNG kind %d"), RNG_kind);
270
0
    }
271
0
}
272
273
static void RNG_Init(RNGtype kind, Int32 seed)
274
0
{
275
0
    int j;
276
277
0
    BM_norm_keep = 0.0; /* zap Box-Muller history */
278
279
    /* Initial scrambling */
280
0
    for(j = 0; j < 50; j++)
281
0
  seed = (69069 * seed + 1);
282
0
    switch(kind) {
283
0
    case WICHMANN_HILL:
284
0
    case MARSAGLIA_MULTICARRY:
285
0
    case SUPER_DUPER:
286
0
    case MERSENNE_TWISTER:
287
  /* i_seed[0] is mti, *but* this is needed for historical consistency */
288
0
  for(j = 0; j < RNG_Table[kind].n_seed; j++) {
289
0
      seed = (69069 * seed + 1);
290
0
      RNG_Table[kind].i_seed[j] = seed;
291
0
  }
292
0
  FixupSeeds(kind, 1);
293
0
  break;
294
0
    case KNUTH_TAOCP:
295
0
  RNG_Init_R_KT(seed);
296
0
  break;
297
0
    case KNUTH_TAOCP2:
298
0
  RNG_Init_KT2(seed);
299
0
  break;
300
0
    case LECUYER_CMRG:
301
0
  for(j = 0; j < RNG_Table[kind].n_seed; j++) {
302
0
      seed = (69069 * seed + 1);
303
0
      while(seed >= m2) seed = (69069 * seed + 1);
304
0
      RNG_Table[kind].i_seed[j] = seed;
305
0
  }
306
0
  break;
307
0
    case USER_UNIF:
308
0
  User_unif_fun = R_FindSymbol("user_unif_rand", "", NULL);
309
0
  if (!User_unif_fun) error(_("'user_unif_rand' not in load table"));
310
0
  User_unif_init = (UnifInitFun) R_FindSymbol("user_unif_init", "", NULL);
311
0
  if (User_unif_init) (void) User_unif_init(seed);
312
0
  User_unif_nseed = R_FindSymbol("user_unif_nseed", "", NULL);
313
0
  User_unif_seedloc = R_FindSymbol("user_unif_seedloc", "",  NULL);
314
0
  if (User_unif_seedloc) {
315
0
      int ns = 0;
316
0
      if (!User_unif_nseed) {
317
0
    warning(_("cannot read seeds unless 'user_unif_nseed' is supplied"));
318
0
    break;
319
0
      }
320
0
      ns = *((int *) User_unif_nseed());
321
0
      if (ns < 0 || ns > 625) {
322
0
    warning(_("seed length must be in 0...625; ignored"));
323
0
    break;
324
0
      }
325
0
      RNG_Table[kind].n_seed = ns;
326
0
      RNG_Table[kind].i_seed = (Int32 *) User_unif_seedloc();
327
0
  }
328
0
  break;
329
0
    default:
330
0
  error(_("RNG_Init: unimplemented RNG kind %d"), kind);
331
0
    }
332
0
}
333
334
static SEXP GetSeedsFromVar(void)
335
0
{
336
0
    SEXP seeds = R_findVarInFrame(R_GlobalEnv, R_SeedsSymbol);
337
0
    if (TYPEOF(seeds) == PROMSXP)
338
0
  seeds = eval(R_SeedsSymbol, R_GlobalEnv);
339
0
    return seeds;
340
0
}
341
342
static void Randomize(RNGtype kind)
343
0
{
344
/* called by  GetRNGstate() when there is no .Random.seed, also from FixupSeeds()  */
345
0
    RNG_Init(kind, TimeToSeed());
346
0
}
347
348
static bool GetRNGkind(SEXP seeds)
349
0
{
350
    /* Load RNG_kind, N01_kind, Sample_kind, Binom_kind from .Random.seed if present */
351
352
0
    if (isNull(seeds))
353
0
  seeds = GetSeedsFromVar();
354
0
    if (seeds == R_UnboundValue) return TRUE;
355
0
    if (!isInteger(seeds)) {
356
0
  if (seeds == R_MissingArg) /* How can this happen? */
357
0
      R_MissingArgError(R_SeedsSymbol, R_CurrentExpression,
358
0
            "getRNGError");
359
0
  warning(_("'.Random.seed' is not an integer vector but of type '%s', so ignored"),
360
0
    R_typeToChar(seeds));
361
0
  goto invalid;
362
0
    }
363
0
    int *is = INTEGER(seeds),
364
0
  tmp = is[0];
365
    /* avoid overflow here: max current value is 110507 */
366
0
    if (tmp == NA_INTEGER || tmp < 0 || tmp > 111000) {
367
0
  warning(_("'.Random.seed[1]' is not a valid integer, so ignored"));
368
0
  goto invalid;
369
0
    }
370
0
    RNGtype newRNG = (RNGtype) (tmp % 100);
371
0
    N01type newN01 = (N01type) (tmp % 10000 / 100);
372
0
    Sampletype newSample = (Sampletype) (tmp % 100000 / 10000);
373
0
    Binomtype  newBinom  =  (Binomtype) (tmp / 100000);
374
0
    if (newN01 > KINDERMAN_RAMAGE || newSample > REJECTION || newBinom > BTPE) {
375
0
  warning(_("'.Random.seed[1]' is not a valid Normal | Sample | Binom type, so ignored"));
376
0
  goto invalid;
377
0
    }
378
0
    switch(newRNG) {
379
0
    case WICHMANN_HILL:
380
0
    case MARSAGLIA_MULTICARRY:
381
0
    case SUPER_DUPER:
382
0
    case MERSENNE_TWISTER:
383
0
    case KNUTH_TAOCP:
384
0
    case KNUTH_TAOCP2:
385
0
    case LECUYER_CMRG:
386
0
  break;
387
0
    case USER_UNIF:
388
0
  if(!User_unif_fun) {
389
0
      warning(_("'.Random.seed[1] %% 100 = 5' but no user-supplied generator, so ignored"));
390
0
      goto invalid;
391
0
  }
392
0
  break;
393
0
    default:
394
0
  warning(_("'.Random.seed[1] %% 100' is not a valid RNG kind so ignored"));
395
0
  goto invalid;
396
0
    }
397
0
    RNG_kind = newRNG; N01_kind = newN01; Sample_kind = newSample; Binom_kind = newBinom;
398
0
    return false;
399
0
invalid:
400
0
    RNG_kind = RNG_DEFAULT; N01_kind = N01_DEFAULT; Sample_kind = Sample_DEFAULT; Binom_kind = Binom_DEFAULT;
401
402
0
    Randomize(RNG_kind);
403
0
    PutRNGstate(); // write out to .Random.seed
404
0
    return true;
405
0
}
406
407
static void copy_seeds_in(Int32 *i_seed, SEXP seeds, int len_seed)
408
0
{
409
0
    int *p = INTEGER(seeds); // will warn if R INTEGER type changes
410
0
    memcpy(i_seed, p + 1, sizeof(Int32) * len_seed);
411
0
}
412
413
void GetRNGstate(void)
414
0
{
415
    /* Get  .Random.seed  into proper variables */
416
417
0
    SEXP seeds = GetSeedsFromVar();
418
0
    if (seeds == R_UnboundValue)
419
0
  Randomize(RNG_kind);
420
0
    else {
421
  /* this might re-set the generator */
422
0
  if(GetRNGkind(seeds)) return;
423
0
  int len_seed = RNG_Table[RNG_kind].n_seed;
424
  /* Not sure whether this test is needed: wrong for USER_UNIF */
425
0
  if(LENGTH(seeds) > 1 && LENGTH(seeds) < len_seed + 1)
426
0
      error(_("'.Random.seed' has wrong length"));
427
0
  if(LENGTH(seeds) == 1 && RNG_kind != USER_UNIF)
428
0
      Randomize(RNG_kind);
429
0
  else {
430
0
      copy_seeds_in(RNG_Table[RNG_kind].i_seed, seeds, len_seed);
431
0
      FixupSeeds(RNG_kind, 0);
432
0
  }
433
0
    }
434
0
}
435
436
static R_INLINE void copy_seeds_out(SEXP seeds, Int32 *i_seed, int len_seed)
437
0
{
438
0
    int *p = INTEGER(seeds) + 1; // will warn if R INTEGER type changes
439
0
    memcpy(p, i_seed, sizeof(Int32) * len_seed);
440
0
}
441
442
void PutRNGstate(void)
443
0
{
444
0
    if (RNG_kind > LECUYER_CMRG || N01_kind > KINDERMAN_RAMAGE ||
445
0
  Sample_kind > REJECTION || Binom_kind > BTPE) {
446
0
  warning("Internal .Random.seed is corrupt: not saving");
447
0
  return;
448
0
    }
449
450
    /* Copy out seeds to  .Random.seed  */
451
0
    int len_seed = RNG_Table[RNG_kind].n_seed;
452
0
    int kinds = RNG_kind + 100 * N01_kind + 10000 * Sample_kind + 100000 * Binom_kind;
453
454
0
    SEXP seeds = R_findVarInFrame(R_GlobalEnv, R_SeedsSymbol);
455
0
    if (NOT_SHARED(seeds) && ATTRIB(seeds) == R_NilValue &&
456
0
  TYPEOF(seeds) == INTSXP && XLENGTH(seeds) == len_seed + 1) {
457
  /* it is safe to reuse the existing .Random.seed vector */
458
0
  INTEGER(seeds)[0] = kinds;
459
0
  copy_seeds_out(seeds, RNG_Table[RNG_kind].i_seed, len_seed);
460
0
    }
461
0
    else {
462
  /* need to allocate a fresh .Random.seed vector */
463
0
  seeds = PROTECT(allocVector(INTSXP, len_seed + 1));
464
0
  INTEGER(seeds)[0] = kinds;
465
0
  copy_seeds_out(seeds, RNG_Table[RNG_kind].i_seed, len_seed);
466
467
  /* assign only in the workspace */
468
0
  defineVar(R_SeedsSymbol, seeds, R_GlobalEnv);
469
0
  INCREMENT_NAMED(seeds);
470
0
  UNPROTECT(1);
471
0
    }
472
0
}
473
474
static void RNGkind(RNGtype newkind)
475
0
{
476
/* Choose a new kind of RNG.
477
 * Initialize its seed by calling the old RNG's unif_rand()
478
 */
479
0
    if (newkind == (RNGtype)-1) newkind = RNG_DEFAULT;
480
0
    switch(newkind) {
481
0
    case MARSAGLIA_MULTICARRY:
482
0
  warning(_("RNGkind: Marsaglia-Multicarry has poor statistical properties"));
483
0
    case WICHMANN_HILL:
484
0
    case SUPER_DUPER:
485
0
    case MERSENNE_TWISTER:
486
0
    case KNUTH_TAOCP:
487
0
    case USER_UNIF:
488
0
    case KNUTH_TAOCP2:
489
0
    case LECUYER_CMRG:
490
0
  break;
491
0
    default:
492
0
  error(_("RNGkind: unimplemented RNG kind %d"), newkind);
493
0
    }
494
0
    GetRNGstate();
495
    // precaution against corruption as per package randtoolbox
496
0
    double u = unif_rand();
497
0
    if (u < 0.0 || u > 1.0) {
498
0
  warning("someone corrupted the random-number generator: re-initializing");
499
0
  RNG_Init(newkind, TimeToSeed());
500
0
    } else
501
0
  RNG_Init(newkind, (Int32) (u * UINT_MAX));
502
0
    RNG_kind = newkind;
503
0
    PutRNGstate();
504
0
}
505
506
static void Norm_kind(N01type kind)
507
0
{
508
    /* N01type is an enumeration type, so this will probably get
509
       mapped to an unsigned integer type. */
510
0
    if (kind == KINDERMAN_RAMAGE && RNG_kind == MARSAGLIA_MULTICARRY) {
511
0
  warning(_("RNGkind: severe deviations from normality for Kinderman-Ramage + Marsaglia-Multicarry"));
512
0
    }
513
0
    if (kind == AHRENS_DIETER && RNG_kind == MARSAGLIA_MULTICARRY) {
514
0
  warning(_("RNGkind: deviations from normality for Ahrens-Dieter + Marsaglia-Multicarry"));
515
0
    }
516
0
    if (kind == (N01type)-1) kind = N01_DEFAULT;
517
0
    if (kind > KINDERMAN_RAMAGE)
518
0
  error(_("invalid Normal type in 'RNGkind'"));
519
0
    if (kind == USER_NORM) {
520
0
  User_norm_fun = R_FindSymbol("user_norm_rand", "", NULL);
521
0
  if (!User_norm_fun) error(_("'user_norm_rand' not in load table"));
522
0
    }
523
0
    GetRNGstate(); /* might not be initialized */
524
0
    if (kind == BOX_MULLER)
525
0
  BM_norm_keep = 0.0; /* zap Box-Muller history */
526
0
    N01_kind = kind;
527
0
    PutRNGstate();
528
0
}
529
530
static void Samp_kind(Sampletype kind)
531
0
{
532
    /* Sampletype is an enumeration type, so this will probably get
533
       mapped to an unsigned integer type. */
534
0
    if (kind == (Sampletype)-1) kind = Sample_DEFAULT;
535
0
    if (kind > REJECTION)
536
0
        error(_("invalid sample type in 'RNGkind'"));
537
0
    GetRNGstate(); /* might not be initialized */
538
0
    Sample_kind = kind;
539
0
    PutRNGstate();
540
0
}
541
542
static void Bin_kind(Binomtype kind)
543
0
{
544
    /* Binomtype is an enumeration type, so this will probably get
545
       mapped to an unsigned integer type. */
546
0
    if (kind == (Binomtype)-1) kind = Binom_DEFAULT;
547
0
    if (kind > BTPE)
548
0
        error(_("invalid binom type in 'RNGkind'"));
549
0
    GetRNGstate(); /* might not be initialized */
550
0
    Binom_kind = kind;
551
0
    PutRNGstate();
552
0
}
553
554
555
/*------ .Internal interface ------------------------*/
556
557
attribute_hidden SEXP do_RNGkind (SEXP call, SEXP op, SEXP args, SEXP env)
558
0
{
559
0
    checkArity(op,args);
560
0
    GetRNGstate(); /* might not be initialized */
561
0
    SEXP ans = PROTECT(allocVector(INTSXP, 4));
562
0
    INTEGER(ans)[0] = RNG_kind;
563
0
    INTEGER(ans)[1] = N01_kind;
564
0
    INTEGER(ans)[2] = Sample_kind;
565
0
    INTEGER(ans)[3] = Binom_kind;
566
0
    SEXP rng   = CAR(args),
567
0
  norm   = CADR(args),
568
0
  sample = CADDR(args),
569
0
  binom  = CADDDR(args);
570
0
    GetRNGkind(R_NilValue); /* pull from .Random.seed if present */
571
0
    if(!isNull(rng)) { /* set a new RNG kind */
572
0
  RNGkind((RNGtype) asInteger(rng));
573
0
    }
574
0
    if(!isNull(norm)) { /* set a new normal kind */
575
0
  Norm_kind((N01type) asInteger(norm));
576
0
    }
577
0
    if(!isNull(sample)) { /* set a new sample kind */
578
0
  Samp_kind((Sampletype) asInteger(sample));
579
0
    }
580
0
    if(!isNull(binom)) { /* set a new binom kind */
581
0
  Bin_kind((Binomtype) asInteger(binom));
582
0
    }
583
0
    UNPROTECT(1);
584
0
    return ans;
585
0
}
586
587
588
attribute_hidden SEXP do_setseed (SEXP call, SEXP op, SEXP args, SEXP env)
589
0
{
590
0
    checkArity(op, args);
591
0
    int seed;
592
0
    if(!isNull(CAR(args))) {
593
0
  seed = asInteger(CAR(args));
594
0
  if (seed == NA_INTEGER)
595
0
      error(_("supplied seed is not a valid integer"));
596
0
    } else seed = TimeToSeed();
597
0
    SEXP skind   = CADR(args),
598
0
   nkind   = CADDR(args),
599
0
  sampkind = CADDDR(args),
600
0
  binomkind= CAD4R(args);
601
    /* pull RNG_kind, N01_kind, ... from .Random.seed if present: */
602
0
    GetRNGkind(R_NilValue);
603
0
    if (!isNull(skind)) RNGkind((RNGtype) asInteger(skind));
604
0
    if (!isNull(nkind)) Norm_kind((N01type) asInteger(nkind));
605
0
    if(!isNull(sampkind)) Samp_kind((Sampletype) asInteger(sampkind));
606
0
    if(!isNull(binomkind)) Bin_kind((Binomtype) asInteger(binomkind));
607
0
    RNG_Init(RNG_kind, (Int32) seed); /* zaps BM history */
608
0
    PutRNGstate();
609
0
    return R_NilValue;
610
0
}
611
612
613
/* S COMPATIBILITY */
614
615
/* The following entry points provide compatibility with S. */
616
/* These entry points should not be used by new R code. */
617
/* These entry points are now hidden */
618
619
attribute_hidden
620
void seed_in(long *ignored)
621
0
{
622
0
    GetRNGstate();
623
0
}
624
625
attribute_hidden
626
void seed_out(long *ignored)
627
0
{
628
0
    PutRNGstate();
629
0
}
630
631
/* ===================  Mersenne Twister ========================== */
632
/* From http://www.math.keio.ac.jp/~matumoto/emt.html */
633
/* New URL (accessed 2018-11-08):
634
   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/eindex.html
635
636
   The initialization method in the 1998 code and paper had a minor
637
   issue that was addressed with new initialization approaches in an
638
   update in 2002.  R has always used a different initialization
639
   approach and is not affected by that issue.
640
*/
641
642
/* A C-program for MT19937: Real number version([0,1)-interval)
643
   (1999/10/28)
644
     genrand() generates one pseudorandom real number (double)
645
   which is uniformly distributed on [0,1)-interval, for each
646
   call. sgenrand(seed) sets initial values to the working area
647
   of 624 words. Before genrand(), sgenrand(seed) must be
648
   called once. (seed is any 32-bit integer.)
649
   Integer generator is obtained by modifying two lines.
650
     Coded by Takuji Nishimura, considering the suggestions by
651
   Topher Cooper and Marc Rieffel in July-Aug. 1997.
652
653
   Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura.
654
   When you use this, send an email to: matumoto@math.keio.ac.jp
655
   with an appropriate reference to your work.
656
657
   REFERENCE
658
   M. Matsumoto and T. Nishimura,
659
   "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform
660
   Pseudo-Random Number Generator",
661
   ACM Transactions on Modeling and Computer Simulation,
662
   Vol. 8, No. 1, January 1998, pp 3--30.
663
*/
664
665
/* Period parameters */
666
0
#define N 624
667
0
#define M 397
668
0
#define MATRIX_A 0x9908b0df   /* constant vector a */
669
0
#define UPPER_MASK 0x80000000 /* most significant w-r bits */
670
0
#define LOWER_MASK 0x7fffffff /* least significant r bits */
671
672
/* Tempering parameters */
673
0
#define TEMPERING_MASK_B 0x9d2c5680
674
0
#define TEMPERING_MASK_C 0xefc60000
675
0
#define TEMPERING_SHIFT_U(y)  (y >> 11)
676
0
#define TEMPERING_SHIFT_S(y)  (y << 7)
677
0
#define TEMPERING_SHIFT_T(y)  (y << 15)
678
0
#define TEMPERING_SHIFT_L(y)  (y >> 18)
679
680
static Int32 *mt = dummy+1; /* the array for the state vector  */
681
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
682
683
/* Initializing the array with a seed */
684
static void
685
MT_sgenrand(Int32 seed)
686
0
{
687
0
    int i;
688
689
0
    for (i = 0; i < N; i++) {
690
0
  mt[i] = seed & 0xffff0000;
691
0
  seed = 69069 * seed + 1;
692
0
  mt[i] |= (seed & 0xffff0000) >> 16;
693
0
  seed = 69069 * seed + 1;
694
0
    }
695
0
    mti = N;
696
0
}
697
698
/* Initialization by "sgenrand()" is an example. Theoretically,
699
   there are 2^19937-1 possible states as an initial state.
700
   Essential bits in "seed_array[]" is following 19937 bits:
701
    (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1].
702
   (seed_array[0]&LOWER_MASK) is discarded.
703
   Theoretically,
704
    (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1]
705
   can take any values except all zeros.                             */
706
707
static double MT_genrand(void)
708
0
{
709
0
    Int32 y;
710
0
    static Int32 mag01[2]={0x0, MATRIX_A};
711
    /* mag01[x] = x * MATRIX_A  for x=0,1 */
712
713
0
    mti = dummy[0];
714
715
0
    if (mti >= N) { /* generate N words at one time */
716
0
  int kk;
717
718
0
  if (mti == N+1)   /* if sgenrand() has not been called, */
719
0
      MT_sgenrand(4357); /* a default initial seed is used   */
720
721
0
  for (kk = 0; kk < N - M; kk++) {
722
0
      y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
723
0
      mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
724
0
  }
725
0
  for (; kk < N - 1; kk++) {
726
0
      y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
727
0
      mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
728
0
  }
729
0
  y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
730
0
  mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
731
732
0
  mti = 0;
733
0
    }
734
735
0
    y = mt[mti++];
736
0
    y ^= TEMPERING_SHIFT_U(y);
737
0
    y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
738
0
    y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
739
0
    y ^= TEMPERING_SHIFT_L(y);
740
0
    dummy[0] = mti;
741
742
0
    return ( (double)y * 2.3283064365386963e-10 ); /* reals: [0,1)-interval */
743
0
}
744
745
/*
746
   The following code was taken from earlier versions of
747
   http://www-cs-faculty.stanford.edu/~knuth/programs/rng.c-old
748
   http://www-cs-faculty.stanford.edu/~knuth/programs/rng.c
749
*/
750
751
752
/* This define may give a warning with clang, but is needed to comply
753
   with the prohibition on changing the code. */
754
#ifdef __clang__
755
#pragma clang diagnostic push
756
#pragma clang diagnostic ignored "-Wkeyword-macro"
757
#endif
758
0
#define long Int32
759
#ifdef __clang__
760
#pragma clang diagnostic pop
761
#endif
762
763
0
#define ran_arr_buf       R_KT_ran_arr_buf
764
0
#define ran_arr_cycle     R_KT_ran_arr_cycle
765
0
#define ran_arr_ptr       R_KT_ran_arr_ptr
766
0
#define ran_arr_sentinel  R_KT_ran_arr_sentinel
767
0
#define ran_x             dummy
768
769
0
#define KK 100                     /* the long lag */
770
0
#define LL  37                     /* the short lag */
771
0
#define MM (1L<<30)                 /* the modulus */
772
0
#define TT  70   /* guaranteed separation between streams */
773
0
#define mod_diff(x,y) (((x)-(y))&(MM-1)) /* subtraction mod MM */
774
0
#define is_odd(x)  ((x)&1)          /* units bit of x */
775
static void ran_array(long aa[],int n)    /* put n new random numbers in aa */
776
0
{
777
0
  register int i,j;
778
0
  for (j=0;j<KK;j++) aa[j]=ran_x[j];
779
0
  for (;j<n;j++) aa[j]=mod_diff(aa[j-KK],aa[j-LL]);
780
0
  for (i=0;i<LL;i++,j++) ran_x[i]=mod_diff(aa[j-KK],aa[j-LL]);
781
0
  for (;i<KK;i++,j++) ran_x[i]=mod_diff(aa[j-KK],ran_x[i-LL]);
782
0
}
783
0
#define QUALITY 1009 /* recommended quality level for high-res use */
784
static long ran_arr_buf[QUALITY];
785
static long ran_arr_sentinel=(long)-1;
786
static long *ran_arr_ptr=&ran_arr_sentinel; /* the next random number, or -1 */
787
788
static long ran_arr_cycle(void)
789
0
{
790
0
  ran_array(ran_arr_buf,QUALITY);
791
0
  ran_arr_buf[KK]=(long)(-1);
792
0
  ran_arr_ptr=ran_arr_buf+1;
793
0
  return ran_arr_buf[0];
794
0
}
795
796
/* ===================  Knuth TAOCP  2002 ========================== */
797
798
/*    This program by D E Knuth is in the public domain and freely copyable.
799
 *    It is explained in Seminumerical Algorithms, 3rd edition, Section 3.6
800
 *    (or in the errata to the 2nd edition --- see
801
 *        http://www-cs-faculty.stanford.edu/~knuth/taocp.html
802
 *    in the changes to Volume 2 on pages 171 and following).              */
803
804
/*    N.B. The MODIFICATIONS introduced in the 9th printing (2002) are
805
      included here; there's no backwards compatibility with the original. */
806
807
808
static void ran_start(long seed)
809
0
{
810
0
  register int t,j;
811
0
  long x[KK+KK-1];              /* the preparation buffer */
812
0
  register long ss=(seed+2)&(MM-2);
813
0
  for (j=0;j<KK;j++) {
814
0
    x[j]=ss;                      /* bootstrap the buffer */
815
0
    ss<<=1; if (ss>=MM) ss-=MM-2; /* cyclic shift 29 bits */
816
0
  }
817
0
  x[1]++;              /* make x[1] (and only x[1]) odd */
818
0
  for (ss=seed&(MM-1),t=TT-1; t; ) {
819
0
    for (j=KK-1;j>0;j--) x[j+j]=x[j], x[j+j-1]=0; /* "square" */
820
0
    for (j=KK+KK-2;j>=KK;j--)
821
0
      x[j-(KK-LL)]=mod_diff(x[j-(KK-LL)],x[j]),
822
0
      x[j-KK]=mod_diff(x[j-KK],x[j]);
823
0
    if (is_odd(ss)) {              /* "multiply by z" */
824
0
      for (j=KK;j>0;j--)  x[j]=x[j-1];
825
0
      x[0]=x[KK];            /* shift the buffer cyclically */
826
0
      x[LL]=mod_diff(x[LL],x[KK]);
827
0
    }
828
0
    if (ss) ss>>=1; else t--;
829
0
  }
830
0
  for (j=0;j<LL;j++) ran_x[j+KK-LL]=x[j];
831
0
  for (;j<KK;j++) ran_x[j-LL]=x[j];
832
0
  for (j=0;j<10;j++) ran_array(x,KK+KK-1); /* warm things up */
833
0
  ran_arr_ptr=&ran_arr_sentinel;
834
0
}
835
/* ===================== end of Knuth's code ====================== */
836
837
static void RNG_Init_KT2(Int32 seed)
838
0
{
839
0
    ran_start(seed % 1073741821);
840
0
    KT_pos = 100;
841
0
}
842
843
static Int32 KT_next(void)
844
0
{
845
0
    if(KT_pos >= 100) {
846
0
  ran_arr_cycle();
847
0
  KT_pos = 0;
848
0
    }
849
0
    return ran_x[(KT_pos)++];
850
0
}
851
852
static void RNG_Init_R_KT(Int32 seed)
853
0
{
854
0
    SEXP fun, sseed, call, ans;
855
0
    PROTECT(fun = findVar1(install(".TAOCP1997init"), R_BaseEnv, CLOSXP, FALSE));
856
0
    if(fun == R_UnboundValue)
857
0
  error("function '.TAOCP1997init' is missing");
858
0
    PROTECT(sseed = ScalarInteger((int)(seed % 1073741821)));
859
0
    PROTECT(call = lang2(fun, sseed));
860
0
    ans = eval(call, R_GlobalEnv);
861
0
    memcpy(dummy, INTEGER(ans), 100*sizeof(int));
862
0
    UNPROTECT(3);
863
0
    KT_pos = 100;
864
0
}
865
866
/* Our PRNGs have at most 32 bit of precision. All generators except
867
   Knuth-TAOCP, Knuth-TAOCP-2002, and possibly the user-supplied ones
868
   have 31 or 32 bits of precision; the others are assumed to
869
   have at least 25. */
870
static R_INLINE double ru(void)
871
0
{
872
0
    double U = 33554432.0;
873
0
    return (floor(U*unif_rand()) + unif_rand())/U;
874
0
}
875
876
static double R_unif_index_0(double dn)
877
0
{
878
0
    double cut = INT_MAX;
879
880
0
    switch(RNG_kind) {
881
0
    case KNUTH_TAOCP:
882
0
    case USER_UNIF:
883
0
    case KNUTH_TAOCP2:
884
0
  cut = 33554431.0; /* 2^25 - 1 */
885
0
  break;
886
0
    default:
887
0
  break;
888
0
    }
889
890
0
    double u = dn > cut ? ru() : unif_rand();
891
0
    return floor(dn * u);
892
0
}
893
894
//generate a random non-negative integer < 2 ^ bits in 16 bit chunks
895
static double rbits(int bits)
896
0
{
897
0
    uint_least64_t v = 0;
898
0
    for (int n = 0; n <= bits; n += 16) {
899
0
  int v1 = (int) floor(unif_rand() * 65536);
900
0
  v = 65536 * v + v1;
901
0
    }
902
0
    const uint_least64_t one64 = 1L;
903
    // mask out the bits in the result that are not needed
904
0
    return (double) (v & ((one64 << bits) - 1));
905
0
}
906
907
double R_unif_index(double dn)
908
0
{
909
0
    if (Sample_kind == ROUNDING)
910
0
  return R_unif_index_0(dn);
911
912
    // rejection sampling from integers below the next larger power of two
913
0
    if (dn <= 0)
914
0
  return 0.0;
915
0
    int bits = (int) ceil(log2(dn));
916
0
    double dv;
917
0
    do { dv = rbits(bits); } while (dn <= dv);
918
0
    return dv;
919
0
}
920
921
0
Sampletype R_sample_kind(void) { return Sample_kind; }