NEURON
isaac64.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #if HAVE_SYS_TYPES_H
3 #include <sys/types.h>
4 #endif
5 
6 /*
7 ------------------------------------------------------------------------------
8 isaac64.cpp: A Fast cryptographic random number generator
9  for 32-bit and 64-bit machines.
10 By Bob Jenkins, 1996. Public Domain.
11 
12 Modified for modularity by Tom Bartol and Rex Kerr
13 ------------------------------------------------------------------------------
14 */
15 #include "isaac64.h"
16 
17 
18 #define ind(mm, x) (*(ub8*) ((ub1*) (mm) + ((x) & ((RANDSIZ - 1) << 3))))
19 
20 #define rngstep(mix, a, b, mm, m, m2, r, x) \
21  { \
22  x = *m; \
23  a = (mix) + *(m2++); \
24  *(m++) = y = ind(mm, x) + a + b; \
25  *(r++) = b = ind(mm, y >> RANDSIZL) + x; \
26  }
27 
28 #define mix(a, b, c, d, e, f, g, h) \
29  { \
30  a -= e; \
31  f ^= h >> 9; \
32  h += a; \
33  b -= f; \
34  g ^= a << 9; \
35  a += b; \
36  c -= g; \
37  h ^= b >> 23; \
38  b += c; \
39  d -= h; \
40  a ^= c << 15; \
41  c += d; \
42  e -= a; \
43  b ^= d >> 14; \
44  d += e; \
45  f -= b; \
46  c ^= e << 20; \
47  e += f; \
48  g -= c; \
49  d ^= f >> 17; \
50  f += g; \
51  h -= d; \
52  e ^= g << 14; \
53  g += h; \
54  }
55 
56 
57 void isaac64_generate(struct isaac64_state* rng) {
58  ub8 a, b, x, y, *m, *m2, *r, *mend;
59 
60  m = rng->mm;
61  r = rng->randrsl;
62  a = rng->aa;
63  b = rng->bb + (++rng->cc);
64  for (m = rng->mm, mend = m2 = m + (RANDSIZ / 2); m < mend;) {
65  rngstep(~(a ^ (a << 21)), a, b, rng->mm, m, m2, r, x);
66  rngstep(a ^ (a >> 5), a, b, rng->mm, m, m2, r, x);
67  rngstep(a ^ (a << 12), a, b, rng->mm, m, m2, r, x);
68  rngstep(a ^ (a >> 33), a, b, rng->mm, m, m2, r, x);
69  }
70  for (m2 = rng->mm; m2 < mend;) {
71  rngstep(~(a ^ (a << 21)), a, b, rng->mm, m, m2, r, x);
72  rngstep(a ^ (a >> 5), a, b, rng->mm, m, m2, r, x);
73  rngstep(a ^ (a << 12), a, b, rng->mm, m, m2, r, x);
74  rngstep(a ^ (a >> 33), a, b, rng->mm, m, m2, r, x);
75  }
76  rng->bb = b;
77  rng->aa = a;
78 }
79 
80 
81 void isaac64_init(struct isaac64_state* rng, ub4 seed) {
82  ub8 *r, *m;
83  ub8 a, b, c, d, e, f, g, h;
84  ub4 i;
85 
86  rng->aa = (ub8) 0;
87  rng->bb = (ub8) 0;
88  rng->cc = (ub8) 0;
89 
90  a = b = c = d = e = f = g = h = 0x9e3779b97f4a7c13LL; /* the golden ratio */
91 
92  r = rng->randrsl;
93  m = rng->mm;
94 
95  for (i = 0; i < RANDSIZ; ++i)
96  r[i] = (ub8) 0;
97 
98  r[0] = seed;
99 
100  for (i = 0; i < 4; ++i) /* scramble it */
101  {
102  mix(a, b, c, d, e, f, g, h);
103  }
104 
105  for (i = 0; i < RANDSIZ; i += 8) /* fill in m[] with messy stuff */
106  {
107  /* use all the information in the seed */
108  a += r[i];
109  b += r[i + 1];
110  c += r[i + 2];
111  d += r[i + 3];
112  e += r[i + 4];
113  f += r[i + 5];
114  g += r[i + 6];
115  h += r[i + 7];
116  mix(a, b, c, d, e, f, g, h);
117  m[i] = a;
118  m[i + 1] = b;
119  m[i + 2] = c;
120  m[i + 3] = d;
121  m[i + 4] = e;
122  m[i + 5] = f;
123  m[i + 6] = g;
124  m[i + 7] = h;
125  }
126 
127  /* do a second pass to make all of the seed affect all of m[] */
128  for (i = 0; i < RANDSIZ; i += 8) {
129  a += m[i];
130  b += m[i + 1];
131  c += m[i + 2];
132  d += m[i + 3];
133  e += m[i + 4];
134  f += m[i + 5];
135  g += m[i + 6];
136  h += m[i + 7];
137  mix(a, b, c, d, e, f, g, h);
138  m[i] = a;
139  m[i + 1] = b;
140  m[i + 2] = c;
141  m[i + 3] = d;
142  m[i + 4] = e;
143  m[i + 5] = f;
144  m[i + 6] = g;
145  m[i + 7] = h;
146  }
147 
148  isaac64_generate(rng); /* fill in the first set of results */
149  rng->randcnt = RANDMAX; /* prepare to use the first set of results */
150 }
#define c
void isaac64_generate(struct isaac64_state *rng)
Definition: isaac64.cpp:57
void isaac64_init(struct isaac64_state *rng, ub4 seed)
Definition: isaac64.cpp:81
#define rngstep(mix, a, b, mm, m, m2, r, x)
Definition: isaac64.cpp:20
#define mix(a, b, c, d, e, f, g, h)
Definition: isaac64.cpp:28
#define RANDMAX
Definition: isaac64.h:25
#define RANDSIZ
Definition: isaac64.h:24
unsigned int ub4
Definition: isaac64.h:31
unsigned long long ub8
Definition: isaac64.h:27
#define i
Definition: md1redef.h:12
#define g
Definition: passive0.cpp:21
#define e
Definition: passive0.cpp:22
ub8 mm[RANDSIZ]
Definition: isaac64.h:47
int randcnt
Definition: isaac64.h:42
ub8 randrsl[RANDSIZ]
Definition: isaac64.h:46