gsl_rng__knuthran2002.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* rng/knuthran2002.c
  2. *
  3. * Copyright (C) 2007 Brian Gough
  4. * Copyright (C) 2001, 2007 Brian Gough, Carlo Perassi
  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 3 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * 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, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. /*
  21. * This generator is taken from
  22. *
  23. * Donald E. Knuth, The Art of Computer Programming, Volume 2, Section 3.6
  24. * Third Edition, Addison-Wesley,
  25. *
  26. * The modifications introduced in the 9th printing (2002) are
  27. * included here; there's no backwards compatibility with the
  28. * original. [ see http://www-cs-faculty.stanford.edu/~knuth/taocp.html ]
  29. *
  30. */
  31. #include "gsl__config.h"
  32. #include <stdlib.h>
  33. #include "gsl_rng.h"
  34. #define BUFLEN 1009 /* length of the buffer aa[] */
  35. #define KK 100 /* the long lag */
  36. #define LL 37 /* the short lag */
  37. #define MM (1L << 30) /* the modulus */
  38. #define TT 70 /* guaranteed separation between streams */
  39. #define is_odd(x) ((x) & 1) /* the units bit of x */
  40. #define mod_diff(x, y) (((x) - (y)) & (MM - 1)) /* (x - y) mod MM */
  41. static inline void ran_array (long int aa[], unsigned int n,
  42. long int ran_x[]);
  43. static inline unsigned long int ran_get (void *vstate);
  44. static double ran_get_double (void *vstate);
  45. static void ran_set (void *state, unsigned long int s);
  46. typedef struct
  47. {
  48. unsigned int i;
  49. long int aa[BUFLEN];
  50. long int ran_x[KK]; /* the generator state */
  51. }
  52. ran_state_t;
  53. static inline void
  54. ran_array (long int aa[], unsigned int n, long int ran_x[])
  55. {
  56. unsigned int i;
  57. unsigned int j;
  58. for (j = 0; j < KK; j++)
  59. aa[j] = ran_x[j];
  60. for (; j < n; j++)
  61. aa[j] = mod_diff (aa[j - KK], aa[j - LL]);
  62. for (i = 0; i < LL; i++, j++)
  63. ran_x[i] = mod_diff (aa[j - KK], aa[j - LL]);
  64. for (; i < KK; i++, j++)
  65. ran_x[i] = mod_diff (aa[j - KK], ran_x[i - LL]);
  66. }
  67. static inline unsigned long int
  68. ran_get (void *vstate)
  69. {
  70. ran_state_t *state = (ran_state_t *) vstate;
  71. unsigned int i = state->i;
  72. unsigned long int v;
  73. if (i == 0)
  74. {
  75. /* fill buffer with new random numbers */
  76. ran_array (state->aa, BUFLEN, state->ran_x);
  77. }
  78. v = state->aa[i];
  79. state->i = (i + 1) % KK;
  80. return v;
  81. }
  82. static double
  83. ran_get_double (void *vstate)
  84. {
  85. ran_state_t *state = (ran_state_t *) vstate;
  86. return ran_get (state) / 1073741824.0; /* RAND_MAX + 1 */
  87. }
  88. static void
  89. ran_set (void *vstate, unsigned long int s)
  90. {
  91. ran_state_t *state = (ran_state_t *) vstate;
  92. long x[KK + KK - 1]; /* the preparation buffer */
  93. register int j;
  94. register int t;
  95. register long ss;
  96. if (s == 0 )
  97. s = 314159; /* default seed used by Knuth */
  98. ss = (s + 2)&(MM-2);
  99. for (j = 0; j < KK; j++)
  100. {
  101. x[j] = ss; /* bootstrap the buffer */
  102. ss <<= 1;
  103. if (ss >= MM) /* cyclic shift 29 bits */
  104. ss -= MM - 2;
  105. }
  106. x[1]++; /* make x[1] (and only x[1]) odd */
  107. ss = s & (MM - 1);
  108. t = TT - 1;
  109. while (t)
  110. {
  111. for (j = KK - 1; j > 0; j--) /* square */
  112. {
  113. x[j + j] = x[j];
  114. x[j + j - 1] = 0;
  115. }
  116. for (j = KK + KK - 2; j >= KK; j--)
  117. {
  118. x[j - (KK - LL)] = mod_diff (x[j - (KK - LL)], x[j]);
  119. x[j - KK] = mod_diff (x[j - KK], x[j]);
  120. }
  121. if (is_odd (ss))
  122. { /* multiply by "z" */
  123. for (j = KK; j > 0; j--)
  124. {
  125. x[j] = x[j - 1];
  126. }
  127. x[0] = x[KK]; /* shift the buffer cyclically */
  128. x[LL] = mod_diff (x[LL], x[KK]);
  129. }
  130. if (ss)
  131. ss >>= 1;
  132. else
  133. t--;
  134. }
  135. for (j = 0; j < LL; j++)
  136. state->ran_x[j + KK - LL] = x[j];
  137. for (; j < KK; j++)
  138. state->ran_x[j - LL] = x[j];
  139. for (j = 0; j< 10; j++)
  140. ran_array(x, KK+KK-1, state->ran_x); /* warm things up */
  141. state->i = 0;
  142. return;
  143. }
  144. static const gsl_rng_type ran_type = {
  145. "knuthran2002", /* name */
  146. 0x3fffffffUL, /* RAND_MAX = (2 ^ 30) - 1 */
  147. 0, /* RAND_MIN */
  148. sizeof (ran_state_t),
  149. &ran_set,
  150. &ran_get,
  151. &ran_get_double
  152. };
  153. const gsl_rng_type *gsl_rng_knuthran2002 = &ran_type;