3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <gsl/gsl_rng.h>
24 /* This file provides support for random() generators. There are three
25 versions in widespread use today,
27 - The original BSD version, e.g. on SunOS 4.1 and FreeBSD.
29 - The Linux libc5 version, which is differs from the BSD version in
30 its seeding procedure, possibly due to the introduction of a typo
33 - The GNU glibc2 version, which has a new (and better) seeding
36 They all produce different numbers, due to the different seeding
37 algorithms, but the algorithm for the generator is the same in each
42 static inline long int random_get (int * i, int * j, int n, long int * x);
44 static inline unsigned long int random8_get (void *vstate);
45 static inline unsigned long int random32_get (void *vstate);
46 static inline unsigned long int random64_get (void *vstate);
47 static inline unsigned long int random128_get (void *vstate);
48 static inline unsigned long int random256_get (void *vstate);
50 static double random8_get_double (void *vstate);
51 static double random32_get_double (void *vstate);
52 static double random64_get_double (void *vstate);
53 static double random128_get_double (void *vstate);
54 static double random256_get_double (void *vstate);
56 static void random8_glibc2_set (void *state, unsigned long int s);
57 static void random32_glibc2_set (void *state, unsigned long int s);
58 static void random64_glibc2_set (void *state, unsigned long int s);
59 static void random128_glibc2_set (void *state, unsigned long int s);
60 static void random256_glibc2_set (void *state, unsigned long int s);
62 static void random8_libc5_set (void *state, unsigned long int s);
63 static void random32_libc5_set (void *state, unsigned long int s);
64 static void random64_libc5_set (void *state, unsigned long int s);
65 static void random128_libc5_set (void *state, unsigned long int s);
66 static void random256_libc5_set (void *state, unsigned long int s);
68 static void random8_bsd_set (void *state, unsigned long int s);
69 static void random32_bsd_set (void *state, unsigned long int s);
70 static void random64_bsd_set (void *state, unsigned long int s);
71 static void random128_bsd_set (void *state, unsigned long int s);
72 static void random256_bsd_set (void *state, unsigned long int s);
74 static void bsd_initialize (long int * x, int n, unsigned long int s);
75 static void libc5_initialize (long int * x, int n, unsigned long int s);
76 static void glibc2_initialize (long int * x, int n, unsigned long int s);
112 static inline unsigned long int
113 random8_get (void *vstate)
115 random8_state_t *state = (random8_state_t *) vstate;
117 state->x = (1103515245 * state->x + 12345) & 0x7fffffffUL;
121 static inline long int
122 random_get (int * i, int * j, int n, long int * x)
127 k = (x[*i] >> 1) & 0x7FFFFFFF ;
140 static inline unsigned long int
141 random32_get (void *vstate)
143 random32_state_t *state = (random32_state_t *) vstate;
144 unsigned long int k = random_get (&state->i, &state->j, 7, state->x) ;
148 static inline unsigned long int
149 random64_get (void *vstate)
151 random64_state_t *state = (random64_state_t *) vstate;
152 long int k = random_get (&state->i, &state->j, 15, state->x) ;
156 static inline unsigned long int
157 random128_get (void *vstate)
159 random128_state_t *state = (random128_state_t *) vstate;
160 unsigned long int k = random_get (&state->i, &state->j, 31, state->x) ;
164 static inline unsigned long int
165 random256_get (void *vstate)
167 random256_state_t *state = (random256_state_t *) vstate;
168 long int k = random_get (&state->i, &state->j, 63, state->x) ;
173 random8_get_double (void *vstate)
175 return random8_get (vstate) / 2147483648.0 ;
179 random32_get_double (void *vstate)
181 return random32_get (vstate) / 2147483648.0 ;
185 random64_get_double (void *vstate)
187 return random64_get (vstate) / 2147483648.0 ;
191 random128_get_double (void *vstate)
193 return random128_get (vstate) / 2147483648.0 ;
197 random256_get_double (void *vstate)
199 return random256_get (vstate) / 2147483648.0 ;
203 random8_bsd_set (void *vstate, unsigned long int s)
205 random8_state_t *state = (random8_state_t *) vstate;
214 random32_bsd_set (void *vstate, unsigned long int s)
216 random32_state_t *state = (random32_state_t *) vstate;
219 bsd_initialize (state->x, 7, s) ;
224 for (i = 0 ; i < 10 * 7 ; i++)
225 random32_get (state) ;
229 random64_bsd_set (void *vstate, unsigned long int s)
231 random64_state_t *state = (random64_state_t *) vstate;
234 bsd_initialize (state->x, 15, s) ;
239 for (i = 0 ; i < 10 * 15 ; i++)
240 random64_get (state) ;
244 random128_bsd_set (void *vstate, unsigned long int s)
246 random128_state_t *state = (random128_state_t *) vstate;
249 bsd_initialize (state->x, 31, s) ;
254 for (i = 0 ; i < 10 * 31 ; i++)
255 random128_get (state) ;
259 random256_bsd_set (void *vstate, unsigned long int s)
261 random256_state_t *state = (random256_state_t *) vstate;
264 bsd_initialize (state->x, 63, s) ;
269 for (i = 0 ; i < 10 * 63 ; i++)
270 random256_get (state) ;
274 bsd_initialize (long int * x, int n, unsigned long int s)
283 for (i = 1 ; i < n ; i++)
284 x[i] = 1103515245 * x[i-1] + 12345 ;
288 libc5_initialize (long int * x, int n, unsigned long int s)
297 for (i = 1 ; i < n ; i++)
298 x[i] = 1103515145 * x[i-1] + 12345 ;
302 glibc2_initialize (long int * x, int n, unsigned long int s)
311 for (i = 1 ; i < n ; i++)
313 const long int h = s / 127773;
314 const long int t = 16807 * (s - h * 127773) - h * 2836;
329 random8_glibc2_set (void *vstate, unsigned long int s)
331 random8_state_t *state = (random8_state_t *) vstate;
340 random32_glibc2_set (void *vstate, unsigned long int s)
342 random32_state_t *state = (random32_state_t *) vstate;
345 glibc2_initialize (state->x, 7, s) ;
350 for (i = 0 ; i < 10 * 7 ; i++)
351 random32_get (state) ;
355 random64_glibc2_set (void *vstate, unsigned long int s)
357 random64_state_t *state = (random64_state_t *) vstate;
360 glibc2_initialize (state->x, 15, s) ;
365 for (i = 0 ; i < 10 * 15 ; i++)
366 random64_get (state) ;
370 random128_glibc2_set (void *vstate, unsigned long int s)
372 random128_state_t *state = (random128_state_t *) vstate;
375 glibc2_initialize (state->x, 31, s) ;
380 for (i = 0 ; i < 10 * 31 ; i++)
381 random128_get (state) ;
385 random256_glibc2_set (void *vstate, unsigned long int s)
387 random256_state_t *state = (random256_state_t *) vstate;
390 glibc2_initialize (state->x, 63, s) ;
395 for (i = 0 ; i < 10 * 63 ; i++)
396 random256_get (state) ;
401 random8_libc5_set (void *vstate, unsigned long int s)
403 random8_state_t *state = (random8_state_t *) vstate;
412 random32_libc5_set (void *vstate, unsigned long int s)
414 random32_state_t *state = (random32_state_t *) vstate;
417 libc5_initialize (state->x, 7, s) ;
422 for (i = 0 ; i < 10 * 7 ; i++)
423 random32_get (state) ;
427 random64_libc5_set (void *vstate, unsigned long int s)
429 random64_state_t *state = (random64_state_t *) vstate;
432 libc5_initialize (state->x, 15, s) ;
437 for (i = 0 ; i < 10 * 15 ; i++)
438 random64_get (state) ;
442 random128_libc5_set (void *vstate, unsigned long int s)
444 random128_state_t *state = (random128_state_t *) vstate;
447 libc5_initialize (state->x, 31, s) ;
452 for (i = 0 ; i < 10 * 31 ; i++)
453 random128_get (state) ;
457 random256_libc5_set (void *vstate, unsigned long int s)
459 random256_state_t *state = (random256_state_t *) vstate;
462 libc5_initialize (state->x, 63, s) ;
467 for (i = 0 ; i < 10 * 63 ; i++)
468 random256_get (state) ;
471 static const gsl_rng_type random_glibc2_type =
472 {"random-glibc2", /* name */
473 0x7fffffffUL, /* RAND_MAX */
475 sizeof (random128_state_t),
476 &random128_glibc2_set,
478 &random128_get_double};
480 static const gsl_rng_type random8_glibc2_type =
481 {"random8-glibc2", /* name */
482 0x7fffffffUL, /* RAND_MAX */
484 sizeof (random8_state_t),
487 &random8_get_double};
489 static const gsl_rng_type random32_glibc2_type =
490 {"random32-glibc2", /* name */
491 0x7fffffffUL, /* RAND_MAX */
493 sizeof (random32_state_t),
494 &random32_glibc2_set,
496 &random32_get_double};
498 static const gsl_rng_type random64_glibc2_type =
499 {"random64-glibc2", /* name */
500 0x7fffffffUL, /* RAND_MAX */
502 sizeof (random64_state_t),
503 &random64_glibc2_set,
505 &random64_get_double};
507 static const gsl_rng_type random128_glibc2_type =
508 {"random128-glibc2", /* name */
509 0x7fffffffUL, /* RAND_MAX */
511 sizeof (random128_state_t),
512 &random128_glibc2_set,
514 &random128_get_double};
516 static const gsl_rng_type random256_glibc2_type =
517 {"random256-glibc2", /* name */
518 0x7fffffffUL, /* RAND_MAX */
520 sizeof (random256_state_t),
521 &random256_glibc2_set,
523 &random256_get_double};
525 static const gsl_rng_type random_libc5_type =
526 {"random-libc5", /* name */
527 0x7fffffffUL, /* RAND_MAX */
529 sizeof (random128_state_t),
530 &random128_libc5_set,
532 &random128_get_double};
534 static const gsl_rng_type random8_libc5_type =
535 {"random8-libc5", /* name */
536 0x7fffffffUL, /* RAND_MAX */
538 sizeof (random8_state_t),
541 &random8_get_double};
543 static const gsl_rng_type random32_libc5_type =
544 {"random32-libc5", /* name */
545 0x7fffffffUL, /* RAND_MAX */
547 sizeof (random32_state_t),
550 &random32_get_double};
552 static const gsl_rng_type random64_libc5_type =
553 {"random64-libc5", /* name */
554 0x7fffffffUL, /* RAND_MAX */
556 sizeof (random64_state_t),
559 &random64_get_double};
561 static const gsl_rng_type random128_libc5_type =
562 {"random128-libc5", /* name */
563 0x7fffffffUL, /* RAND_MAX */
565 sizeof (random128_state_t),
566 &random128_libc5_set,
568 &random128_get_double};
570 static const gsl_rng_type random256_libc5_type =
571 {"random256-libc5", /* name */
572 0x7fffffffUL, /* RAND_MAX */
574 sizeof (random256_state_t),
575 &random256_libc5_set,
577 &random256_get_double};
579 static const gsl_rng_type random_bsd_type =
580 {"random-bsd", /* name */
581 0x7fffffffUL, /* RAND_MAX */
583 sizeof (random128_state_t),
586 &random128_get_double};
588 static const gsl_rng_type random8_bsd_type =
589 {"random8-bsd", /* name */
590 0x7fffffffUL, /* RAND_MAX */
592 sizeof (random8_state_t),
595 &random8_get_double};
597 static const gsl_rng_type random32_bsd_type =
598 {"random32-bsd", /* name */
599 0x7fffffffUL, /* RAND_MAX */
601 sizeof (random32_state_t),
604 &random32_get_double};
606 static const gsl_rng_type random64_bsd_type =
607 {"random64-bsd", /* name */
608 0x7fffffffUL, /* RAND_MAX */
610 sizeof (random64_state_t),
613 &random64_get_double};
615 static const gsl_rng_type random128_bsd_type =
616 {"random128-bsd", /* name */
617 0x7fffffffUL, /* RAND_MAX */
619 sizeof (random128_state_t),
622 &random128_get_double};
624 static const gsl_rng_type random256_bsd_type =
625 {"random256-bsd", /* name */
626 0x7fffffffUL, /* RAND_MAX */
628 sizeof (random256_state_t),
631 &random256_get_double};
633 const gsl_rng_type *gsl_rng_random_libc5 = &random_libc5_type;
634 const gsl_rng_type *gsl_rng_random8_libc5 = &random8_libc5_type;
635 const gsl_rng_type *gsl_rng_random32_libc5 = &random32_libc5_type;
636 const gsl_rng_type *gsl_rng_random64_libc5 = &random64_libc5_type;
637 const gsl_rng_type *gsl_rng_random128_libc5 = &random128_libc5_type;
638 const gsl_rng_type *gsl_rng_random256_libc5 = &random256_libc5_type;
640 const gsl_rng_type *gsl_rng_random_glibc2 = &random_glibc2_type;
641 const gsl_rng_type *gsl_rng_random8_glibc2 = &random8_glibc2_type;
642 const gsl_rng_type *gsl_rng_random32_glibc2 = &random32_glibc2_type;
643 const gsl_rng_type *gsl_rng_random64_glibc2 = &random64_glibc2_type;
644 const gsl_rng_type *gsl_rng_random128_glibc2 = &random128_glibc2_type;
645 const gsl_rng_type *gsl_rng_random256_glibc2 = &random256_glibc2_type;
647 const gsl_rng_type *gsl_rng_random_bsd = &random_bsd_type;
648 const gsl_rng_type *gsl_rng_random8_bsd = &random8_bsd_type;
649 const gsl_rng_type *gsl_rng_random32_bsd = &random32_bsd_type;
650 const gsl_rng_type *gsl_rng_random64_bsd = &random64_bsd_type;
651 const gsl_rng_type *gsl_rng_random128_bsd = &random128_bsd_type;
652 const gsl_rng_type *gsl_rng_random256_bsd = &random256_bsd_type;