numo-narray 0.9.0.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +47 -0
  4. data/Rakefile +41 -0
  5. data/ext/numo/narray/SFMT-params.h +97 -0
  6. data/ext/numo/narray/SFMT-params19937.h +46 -0
  7. data/ext/numo/narray/SFMT.c +620 -0
  8. data/ext/numo/narray/SFMT.h +157 -0
  9. data/ext/numo/narray/array.c +525 -0
  10. data/ext/numo/narray/data.c +901 -0
  11. data/ext/numo/narray/depend.erb +33 -0
  12. data/ext/numo/narray/extconf.rb +117 -0
  13. data/ext/numo/narray/gen/bit.erb.c +811 -0
  14. data/ext/numo/narray/gen/cogen.rb +18 -0
  15. data/ext/numo/narray/gen/def/dcomplex.rb +32 -0
  16. data/ext/numo/narray/gen/def/dfloat.rb +30 -0
  17. data/ext/numo/narray/gen/def/int16.rb +29 -0
  18. data/ext/numo/narray/gen/def/int32.rb +29 -0
  19. data/ext/numo/narray/gen/def/int64.rb +29 -0
  20. data/ext/numo/narray/gen/def/int8.rb +29 -0
  21. data/ext/numo/narray/gen/def/robject.rb +30 -0
  22. data/ext/numo/narray/gen/def/scomplex.rb +32 -0
  23. data/ext/numo/narray/gen/def/sfloat.rb +30 -0
  24. data/ext/numo/narray/gen/def/uint16.rb +29 -0
  25. data/ext/numo/narray/gen/def/uint32.rb +29 -0
  26. data/ext/numo/narray/gen/def/uint64.rb +29 -0
  27. data/ext/numo/narray/gen/def/uint8.rb +29 -0
  28. data/ext/numo/narray/gen/dtype.erb.c +328 -0
  29. data/ext/numo/narray/gen/tmpl/accum.c +36 -0
  30. data/ext/numo/narray/gen/tmpl/accum_binary.c +75 -0
  31. data/ext/numo/narray/gen/tmpl/accum_index.c +58 -0
  32. data/ext/numo/narray/gen/tmpl/allocate.c +35 -0
  33. data/ext/numo/narray/gen/tmpl/aref.c +51 -0
  34. data/ext/numo/narray/gen/tmpl/aset.c +61 -0
  35. data/ext/numo/narray/gen/tmpl/binary.c +53 -0
  36. data/ext/numo/narray/gen/tmpl/binary2.c +55 -0
  37. data/ext/numo/narray/gen/tmpl/binary_s.c +34 -0
  38. data/ext/numo/narray/gen/tmpl/bit_binary.c +94 -0
  39. data/ext/numo/narray/gen/tmpl/bit_count.c +82 -0
  40. data/ext/numo/narray/gen/tmpl/bit_unary.c +77 -0
  41. data/ext/numo/narray/gen/tmpl/cast.c +37 -0
  42. data/ext/numo/narray/gen/tmpl/cast_array.c +79 -0
  43. data/ext/numo/narray/gen/tmpl/cast_numeric.c +22 -0
  44. data/ext/numo/narray/gen/tmpl/coerce_cast.c +8 -0
  45. data/ext/numo/narray/gen/tmpl/cond_binary.c +51 -0
  46. data/ext/numo/narray/gen/tmpl/cond_unary.c +45 -0
  47. data/ext/numo/narray/gen/tmpl/cum.c +42 -0
  48. data/ext/numo/narray/gen/tmpl/each.c +43 -0
  49. data/ext/numo/narray/gen/tmpl/each_with_index.c +64 -0
  50. data/ext/numo/narray/gen/tmpl/extract.c +23 -0
  51. data/ext/numo/narray/gen/tmpl/eye.c +91 -0
  52. data/ext/numo/narray/gen/tmpl/fill.c +38 -0
  53. data/ext/numo/narray/gen/tmpl/format.c +60 -0
  54. data/ext/numo/narray/gen/tmpl/format_to_a.c +47 -0
  55. data/ext/numo/narray/gen/tmpl/head.c +25 -0
  56. data/ext/numo/narray/gen/tmpl/inspect.c +16 -0
  57. data/ext/numo/narray/gen/tmpl/map_with_index.c +94 -0
  58. data/ext/numo/narray/gen/tmpl/median.c +44 -0
  59. data/ext/numo/narray/gen/tmpl/minmax.c +47 -0
  60. data/ext/numo/narray/gen/tmpl/poly.c +49 -0
  61. data/ext/numo/narray/gen/tmpl/pow.c +74 -0
  62. data/ext/numo/narray/gen/tmpl/powint.c +17 -0
  63. data/ext/numo/narray/gen/tmpl/qsort.c +149 -0
  64. data/ext/numo/narray/gen/tmpl/rand.c +33 -0
  65. data/ext/numo/narray/gen/tmpl/rand_norm.c +46 -0
  66. data/ext/numo/narray/gen/tmpl/robj_allocate.c +32 -0
  67. data/ext/numo/narray/gen/tmpl/seq.c +61 -0
  68. data/ext/numo/narray/gen/tmpl/set2.c +56 -0
  69. data/ext/numo/narray/gen/tmpl/sort.c +36 -0
  70. data/ext/numo/narray/gen/tmpl/sort_index.c +86 -0
  71. data/ext/numo/narray/gen/tmpl/store.c +31 -0
  72. data/ext/numo/narray/gen/tmpl/store_array.c +5 -0
  73. data/ext/numo/narray/gen/tmpl/store_from.c +53 -0
  74. data/ext/numo/narray/gen/tmpl/store_numeric.c +22 -0
  75. data/ext/numo/narray/gen/tmpl/to_a.c +41 -0
  76. data/ext/numo/narray/gen/tmpl/unary.c +58 -0
  77. data/ext/numo/narray/gen/tmpl/unary2.c +58 -0
  78. data/ext/numo/narray/gen/tmpl/unary_s.c +57 -0
  79. data/ext/numo/narray/index.c +822 -0
  80. data/ext/numo/narray/kwarg.c +79 -0
  81. data/ext/numo/narray/math.c +140 -0
  82. data/ext/numo/narray/narray.c +1539 -0
  83. data/ext/numo/narray/ndloop.c +1928 -0
  84. data/ext/numo/narray/numo/compat.h +23 -0
  85. data/ext/numo/narray/numo/intern.h +112 -0
  86. data/ext/numo/narray/numo/narray.h +411 -0
  87. data/ext/numo/narray/numo/ndloop.h +99 -0
  88. data/ext/numo/narray/numo/template.h +140 -0
  89. data/ext/numo/narray/numo/types/bit.h +19 -0
  90. data/ext/numo/narray/numo/types/complex.h +410 -0
  91. data/ext/numo/narray/numo/types/complex_macro.h +205 -0
  92. data/ext/numo/narray/numo/types/dcomplex.h +11 -0
  93. data/ext/numo/narray/numo/types/dfloat.h +12 -0
  94. data/ext/numo/narray/numo/types/float_def.h +34 -0
  95. data/ext/numo/narray/numo/types/float_macro.h +277 -0
  96. data/ext/numo/narray/numo/types/int16.h +12 -0
  97. data/ext/numo/narray/numo/types/int32.h +12 -0
  98. data/ext/numo/narray/numo/types/int64.h +12 -0
  99. data/ext/numo/narray/numo/types/int8.h +12 -0
  100. data/ext/numo/narray/numo/types/int_macro.h +34 -0
  101. data/ext/numo/narray/numo/types/robj_macro.h +218 -0
  102. data/ext/numo/narray/numo/types/robject.h +21 -0
  103. data/ext/numo/narray/numo/types/scomplex.h +11 -0
  104. data/ext/numo/narray/numo/types/sfloat.h +13 -0
  105. data/ext/numo/narray/numo/types/uint16.h +12 -0
  106. data/ext/numo/narray/numo/types/uint32.h +12 -0
  107. data/ext/numo/narray/numo/types/uint64.h +12 -0
  108. data/ext/numo/narray/numo/types/uint8.h +12 -0
  109. data/ext/numo/narray/numo/types/uint_macro.h +31 -0
  110. data/ext/numo/narray/numo/types/xint_macro.h +133 -0
  111. data/ext/numo/narray/rand.c +87 -0
  112. data/ext/numo/narray/step.c +506 -0
  113. data/ext/numo/narray/struct.c +872 -0
  114. data/lib/2.1/numo/narray.so +0 -0
  115. data/lib/2.2/numo/narray.so +0 -0
  116. data/lib/2.3/numo/narray.so +0 -0
  117. data/lib/erbpp/line_number.rb +126 -0
  118. data/lib/erbpp/narray_def.rb +338 -0
  119. data/lib/erbpp.rb +286 -0
  120. data/lib/numo/narray.rb +6 -0
  121. data/numo-narray.gemspec +35 -0
  122. data/spec/bit_spec.rb +93 -0
  123. data/spec/narray_spec.rb +249 -0
  124. metadata +238 -0
@@ -0,0 +1,620 @@
1
+ /**
2
+ * @file SFMT.c
3
+ * @brief SIMD oriented Fast Mersenne Twister(SFMT)
4
+ *
5
+ * @author Mutsuo Saito (Hiroshima University)
6
+ * @author Makoto Matsumoto (Hiroshima University)
7
+ *
8
+ * Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
9
+ * University. All rights reserved.
10
+ *
11
+ * The new BSD License is applied to this software, see LICENSE.txt
12
+ */
13
+ #include <string.h>
14
+ #include <assert.h>
15
+ #include "SFMT.h"
16
+ #include "SFMT-params.h"
17
+
18
+ #if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
19
+ #define BIG_ENDIAN64 1
20
+ #endif
21
+ #if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
22
+ #define BIG_ENDIAN64 1
23
+ #endif
24
+ #if defined(ONLY64) && !defined(BIG_ENDIAN64)
25
+ #if defined(__GNUC__)
26
+ #error "-DONLY64 must be specified with -DBIG_ENDIAN64"
27
+ #endif
28
+ #undef ONLY64
29
+ #endif
30
+ /*------------------------------------------------------
31
+ 128-bit SIMD data type for Altivec, SSE2 or standard C
32
+ ------------------------------------------------------*/
33
+ #if defined(HAVE_ALTIVEC)
34
+ #if !defined(__APPLE__)
35
+ #include <altivec.h>
36
+ #endif
37
+ /** 128-bit data structure */
38
+ union W128_T {
39
+ vector unsigned int s;
40
+ uint32_t u[4];
41
+ };
42
+ /** 128-bit data type */
43
+ typedef union W128_T w128_t;
44
+
45
+ #elif defined(HAVE_SSE2)
46
+ #include <emmintrin.h>
47
+
48
+ /** 128-bit data structure */
49
+ union W128_T {
50
+ __m128i si;
51
+ uint32_t u[4];
52
+ };
53
+ /** 128-bit data type */
54
+ typedef union W128_T w128_t;
55
+
56
+ #else
57
+
58
+ /** 128-bit data structure */
59
+ struct W128_T {
60
+ uint32_t u[4];
61
+ };
62
+ /** 128-bit data type */
63
+ typedef struct W128_T w128_t;
64
+
65
+ #endif
66
+
67
+ /*--------------------------------------
68
+ FILE GLOBAL VARIABLES
69
+ internal state, index counter and flag
70
+ --------------------------------------*/
71
+ /** the 128-bit internal state array */
72
+ static w128_t sfmt[N];
73
+ /** the 32bit integer pointer to the 128-bit internal state array */
74
+ static uint32_t *psfmt32 = &sfmt[0].u[0];
75
+ #if !defined(BIG_ENDIAN64) || defined(ONLY64)
76
+ /** the 64bit integer pointer to the 128-bit internal state array */
77
+ static uint64_t *psfmt64 = (uint64_t *)&sfmt[0].u[0];
78
+ #endif
79
+ /** index counter to the 32-bit internal state array */
80
+ static int idx;
81
+ /** a flag: it is 0 if and only if the internal state is not yet
82
+ * initialized. */
83
+ static int initialized = 0;
84
+ /** a parity check vector which certificate the period of 2^{MEXP} */
85
+ static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
86
+
87
+ /*----------------
88
+ STATIC FUNCTIONS
89
+ ----------------*/
90
+ inline static int idxof(int i);
91
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift);
92
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift);
93
+ inline static void gen_rand_all(void);
94
+ inline static void gen_rand_array(w128_t *array, int size);
95
+ inline static uint32_t func1(uint32_t x);
96
+ inline static uint32_t func2(uint32_t x);
97
+ static void period_certification(void);
98
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
99
+ inline static void swap(w128_t *array, int size);
100
+ #endif
101
+
102
+ #if defined(HAVE_ALTIVEC)
103
+ #include "SFMT-alti.h"
104
+ #elif defined(HAVE_SSE2)
105
+ #include "SFMT-sse2.h"
106
+ #endif
107
+
108
+ /**
109
+ * This function simulate a 64-bit index of LITTLE ENDIAN
110
+ * in BIG ENDIAN machine.
111
+ */
112
+ #ifdef ONLY64
113
+ inline static int idxof(int i) {
114
+ return i ^ 1;
115
+ }
116
+ #else
117
+ inline static int idxof(int i) {
118
+ return i;
119
+ }
120
+ #endif
121
+ /**
122
+ * This function simulates SIMD 128-bit right shift by the standard C.
123
+ * The 128-bit integer given in in is shifted by (shift * 8) bits.
124
+ * This function simulates the LITTLE ENDIAN SIMD.
125
+ * @param out the output of this function
126
+ * @param in the 128-bit data to be shifted
127
+ * @param shift the shift value
128
+ */
129
+ #ifdef ONLY64
130
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
131
+ uint64_t th, tl, oh, ol;
132
+
133
+ th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
134
+ tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
135
+
136
+ oh = th >> (shift * 8);
137
+ ol = tl >> (shift * 8);
138
+ ol |= th << (64 - shift * 8);
139
+ out->u[0] = (uint32_t)(ol >> 32);
140
+ out->u[1] = (uint32_t)ol;
141
+ out->u[2] = (uint32_t)(oh >> 32);
142
+ out->u[3] = (uint32_t)oh;
143
+ }
144
+ #else
145
+ inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
146
+ uint64_t th, tl, oh, ol;
147
+
148
+ th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
149
+ tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
150
+
151
+ oh = th >> (shift * 8);
152
+ ol = tl >> (shift * 8);
153
+ ol |= th << (64 - shift * 8);
154
+ out->u[1] = (uint32_t)(ol >> 32);
155
+ out->u[0] = (uint32_t)ol;
156
+ out->u[3] = (uint32_t)(oh >> 32);
157
+ out->u[2] = (uint32_t)oh;
158
+ }
159
+ #endif
160
+ /**
161
+ * This function simulates SIMD 128-bit left shift by the standard C.
162
+ * The 128-bit integer given in in is shifted by (shift * 8) bits.
163
+ * This function simulates the LITTLE ENDIAN SIMD.
164
+ * @param out the output of this function
165
+ * @param in the 128-bit data to be shifted
166
+ * @param shift the shift value
167
+ */
168
+ #ifdef ONLY64
169
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
170
+ uint64_t th, tl, oh, ol;
171
+
172
+ th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
173
+ tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
174
+
175
+ oh = th << (shift * 8);
176
+ ol = tl << (shift * 8);
177
+ oh |= tl >> (64 - shift * 8);
178
+ out->u[0] = (uint32_t)(ol >> 32);
179
+ out->u[1] = (uint32_t)ol;
180
+ out->u[2] = (uint32_t)(oh >> 32);
181
+ out->u[3] = (uint32_t)oh;
182
+ }
183
+ #else
184
+ inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
185
+ uint64_t th, tl, oh, ol;
186
+
187
+ th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
188
+ tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
189
+
190
+ oh = th << (shift * 8);
191
+ ol = tl << (shift * 8);
192
+ oh |= tl >> (64 - shift * 8);
193
+ out->u[1] = (uint32_t)(ol >> 32);
194
+ out->u[0] = (uint32_t)ol;
195
+ out->u[3] = (uint32_t)(oh >> 32);
196
+ out->u[2] = (uint32_t)oh;
197
+ }
198
+ #endif
199
+
200
+ /**
201
+ * This function represents the recursion formula.
202
+ * @param r output
203
+ * @param a a 128-bit part of the internal state array
204
+ * @param b a 128-bit part of the internal state array
205
+ * @param c a 128-bit part of the internal state array
206
+ * @param d a 128-bit part of the internal state array
207
+ */
208
+ #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
209
+ #ifdef ONLY64
210
+ inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
211
+ w128_t *d) {
212
+ w128_t x;
213
+ w128_t y;
214
+
215
+ lshift128(&x, a, SL2);
216
+ rshift128(&y, c, SR2);
217
+ r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
218
+ ^ (d->u[0] << SL1);
219
+ r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
220
+ ^ (d->u[1] << SL1);
221
+ r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
222
+ ^ (d->u[2] << SL1);
223
+ r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
224
+ ^ (d->u[3] << SL1);
225
+ }
226
+ #else
227
+ inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
228
+ w128_t *d) {
229
+ w128_t x;
230
+ w128_t y;
231
+
232
+ lshift128(&x, a, SL2);
233
+ rshift128(&y, c, SR2);
234
+ r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
235
+ ^ (d->u[0] << SL1);
236
+ r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
237
+ ^ (d->u[1] << SL1);
238
+ r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
239
+ ^ (d->u[2] << SL1);
240
+ r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
241
+ ^ (d->u[3] << SL1);
242
+ }
243
+ #endif
244
+ #endif
245
+
246
+ #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
247
+ /**
248
+ * This function fills the internal state array with pseudorandom
249
+ * integers.
250
+ */
251
+ inline static void gen_rand_all(void) {
252
+ int i;
253
+ w128_t *r1, *r2;
254
+
255
+ r1 = &sfmt[N - 2];
256
+ r2 = &sfmt[N - 1];
257
+ for (i = 0; i < N - POS1; i++) {
258
+ do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
259
+ r1 = r2;
260
+ r2 = &sfmt[i];
261
+ }
262
+ for (; i < N; i++) {
263
+ do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1 - N], r1, r2);
264
+ r1 = r2;
265
+ r2 = &sfmt[i];
266
+ }
267
+ }
268
+
269
+ /**
270
+ * This function fills the user-specified array with pseudorandom
271
+ * integers.
272
+ *
273
+ * @param array an 128-bit array to be filled by pseudorandom numbers.
274
+ * @param size number of 128-bit pseudorandom numbers to be generated.
275
+ */
276
+ inline static void gen_rand_array(w128_t *array, int size) {
277
+ int i, j;
278
+ w128_t *r1, *r2;
279
+
280
+ r1 = &sfmt[N - 2];
281
+ r2 = &sfmt[N - 1];
282
+ for (i = 0; i < N - POS1; i++) {
283
+ do_recursion(&array[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
284
+ r1 = r2;
285
+ r2 = &array[i];
286
+ }
287
+ for (; i < N; i++) {
288
+ do_recursion(&array[i], &sfmt[i], &array[i + POS1 - N], r1, r2);
289
+ r1 = r2;
290
+ r2 = &array[i];
291
+ }
292
+ for (; i < size - N; i++) {
293
+ do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
294
+ r1 = r2;
295
+ r2 = &array[i];
296
+ }
297
+ for (j = 0; j < 2 * N - size; j++) {
298
+ sfmt[j] = array[j + size - N];
299
+ }
300
+ for (; i < size; i++, j++) {
301
+ do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
302
+ r1 = r2;
303
+ r2 = &array[i];
304
+ sfmt[j] = array[i];
305
+ }
306
+ }
307
+ #endif
308
+
309
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
310
+ inline static void swap(w128_t *array, int size) {
311
+ int i;
312
+ uint32_t x, y;
313
+
314
+ for (i = 0; i < size; i++) {
315
+ x = array[i].u[0];
316
+ y = array[i].u[2];
317
+ array[i].u[0] = array[i].u[1];
318
+ array[i].u[2] = array[i].u[3];
319
+ array[i].u[1] = x;
320
+ array[i].u[3] = y;
321
+ }
322
+ }
323
+ #endif
324
+ /**
325
+ * This function represents a function used in the initialization
326
+ * by init_by_array
327
+ * @param x 32-bit integer
328
+ * @return 32-bit integer
329
+ */
330
+ static uint32_t func1(uint32_t x) {
331
+ return (x ^ (x >> 27)) * (uint32_t)1664525UL;
332
+ }
333
+
334
+ /**
335
+ * This function represents a function used in the initialization
336
+ * by init_by_array
337
+ * @param x 32-bit integer
338
+ * @return 32-bit integer
339
+ */
340
+ static uint32_t func2(uint32_t x) {
341
+ return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
342
+ }
343
+
344
+ /**
345
+ * This function certificate the period of 2^{MEXP}
346
+ */
347
+ static void period_certification(void) {
348
+ int inner = 0;
349
+ int i, j;
350
+ uint32_t work;
351
+
352
+ for (i = 0; i < 4; i++)
353
+ inner ^= psfmt32[idxof(i)] & parity[i];
354
+ for (i = 16; i > 0; i >>= 1)
355
+ inner ^= inner >> i;
356
+ inner &= 1;
357
+ /* check OK */
358
+ if (inner == 1) {
359
+ return;
360
+ }
361
+ /* check NG, and modification */
362
+ for (i = 0; i < 4; i++) {
363
+ work = 1;
364
+ for (j = 0; j < 32; j++) {
365
+ if ((work & parity[i]) != 0) {
366
+ psfmt32[idxof(i)] ^= work;
367
+ return;
368
+ }
369
+ work = work << 1;
370
+ }
371
+ }
372
+ }
373
+
374
+ /*----------------
375
+ PUBLIC FUNCTIONS
376
+ ----------------*/
377
+ /**
378
+ * This function returns the identification string.
379
+ * The string shows the word size, the Mersenne exponent,
380
+ * and all parameters of this generator.
381
+ */
382
+ const char *get_idstring(void) {
383
+ return IDSTR;
384
+ }
385
+
386
+ /**
387
+ * This function returns the minimum size of array used for \b
388
+ * fill_array32() function.
389
+ * @return minimum size of array used for fill_array32() function.
390
+ */
391
+ int get_min_array_size32(void) {
392
+ return N32;
393
+ }
394
+
395
+ /**
396
+ * This function returns the minimum size of array used for \b
397
+ * fill_array64() function.
398
+ * @return minimum size of array used for fill_array64() function.
399
+ */
400
+ int get_min_array_size64(void) {
401
+ return N64;
402
+ }
403
+
404
+ #ifndef ONLY64
405
+ /**
406
+ * This function generates and returns 32-bit pseudorandom number.
407
+ * init_gen_rand or init_by_array must be called before this function.
408
+ * @return 32-bit pseudorandom number
409
+ */
410
+ uint32_t gen_rand32(void) {
411
+ uint32_t r;
412
+
413
+ assert(initialized);
414
+ if (idx >= N32) {
415
+ gen_rand_all();
416
+ idx = 0;
417
+ }
418
+ r = psfmt32[idx++];
419
+ return r;
420
+ }
421
+ #endif
422
+ /**
423
+ * This function generates and returns 64-bit pseudorandom number.
424
+ * init_gen_rand or init_by_array must be called before this function.
425
+ * The function gen_rand64 should not be called after gen_rand32,
426
+ * unless an initialization is again executed.
427
+ * @return 64-bit pseudorandom number
428
+ */
429
+ uint64_t gen_rand64(void) {
430
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
431
+ uint32_t r1, r2;
432
+ #else
433
+ uint64_t r;
434
+ #endif
435
+
436
+ assert(initialized);
437
+ assert(idx % 2 == 0);
438
+
439
+ if (idx >= N32) {
440
+ gen_rand_all();
441
+ idx = 0;
442
+ }
443
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
444
+ r1 = psfmt32[idx];
445
+ r2 = psfmt32[idx + 1];
446
+ idx += 2;
447
+ return ((uint64_t)r2 << 32) | r1;
448
+ #else
449
+ r = psfmt64[idx / 2];
450
+ idx += 2;
451
+ return r;
452
+ #endif
453
+ }
454
+
455
+ #ifndef ONLY64
456
+ /**
457
+ * This function generates pseudorandom 32-bit integers in the
458
+ * specified array[] by one call. The number of pseudorandom integers
459
+ * is specified by the argument size, which must be at least 624 and a
460
+ * multiple of four. The generation by this function is much faster
461
+ * than the following gen_rand function.
462
+ *
463
+ * For initialization, init_gen_rand or init_by_array must be called
464
+ * before the first call of this function. This function can not be
465
+ * used after calling gen_rand function, without initialization.
466
+ *
467
+ * @param array an array where pseudorandom 32-bit integers are filled
468
+ * by this function. The pointer to the array must be \b "aligned"
469
+ * (namely, must be a multiple of 16) in the SIMD version, since it
470
+ * refers to the address of a 128-bit integer. In the standard C
471
+ * version, the pointer is arbitrary.
472
+ *
473
+ * @param size the number of 32-bit pseudorandom integers to be
474
+ * generated. size must be a multiple of 4, and greater than or equal
475
+ * to (MEXP / 128 + 1) * 4.
476
+ *
477
+ * @note \b memalign or \b posix_memalign is available to get aligned
478
+ * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
479
+ * returns the pointer to the aligned memory block.
480
+ */
481
+ void fill_array32(uint32_t *array, int size) {
482
+ assert(initialized);
483
+ assert(idx == N32);
484
+ assert(size % 4 == 0);
485
+ assert(size >= N32);
486
+
487
+ gen_rand_array((w128_t *)array, size / 4);
488
+ idx = N32;
489
+ }
490
+ #endif
491
+
492
+ /**
493
+ * This function generates pseudorandom 64-bit integers in the
494
+ * specified array[] by one call. The number of pseudorandom integers
495
+ * is specified by the argument size, which must be at least 312 and a
496
+ * multiple of two. The generation by this function is much faster
497
+ * than the following gen_rand function.
498
+ *
499
+ * For initialization, init_gen_rand or init_by_array must be called
500
+ * before the first call of this function. This function can not be
501
+ * used after calling gen_rand function, without initialization.
502
+ *
503
+ * @param array an array where pseudorandom 64-bit integers are filled
504
+ * by this function. The pointer to the array must be "aligned"
505
+ * (namely, must be a multiple of 16) in the SIMD version, since it
506
+ * refers to the address of a 128-bit integer. In the standard C
507
+ * version, the pointer is arbitrary.
508
+ *
509
+ * @param size the number of 64-bit pseudorandom integers to be
510
+ * generated. size must be a multiple of 2, and greater than or equal
511
+ * to (MEXP / 128 + 1) * 2
512
+ *
513
+ * @note \b memalign or \b posix_memalign is available to get aligned
514
+ * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
515
+ * returns the pointer to the aligned memory block.
516
+ */
517
+ void fill_array64(uint64_t *array, int size) {
518
+ assert(initialized);
519
+ assert(idx == N32);
520
+ assert(size % 2 == 0);
521
+ assert(size >= N64);
522
+
523
+ gen_rand_array((w128_t *)array, size / 2);
524
+ idx = N32;
525
+
526
+ #if defined(BIG_ENDIAN64) && !defined(ONLY64)
527
+ swap((w128_t *)array, size /2);
528
+ #endif
529
+ }
530
+
531
+ /**
532
+ * This function initializes the internal state array with a 32-bit
533
+ * integer seed.
534
+ *
535
+ * @param seed a 32-bit integer used as the seed.
536
+ */
537
+ void init_gen_rand(uint32_t seed) {
538
+ int i;
539
+
540
+ psfmt32[idxof(0)] = seed;
541
+ for (i = 1; i < N32; i++) {
542
+ psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
543
+ ^ (psfmt32[idxof(i - 1)] >> 30))
544
+ + i;
545
+ }
546
+ idx = N32;
547
+ period_certification();
548
+ initialized = 1;
549
+ }
550
+
551
+ /**
552
+ * This function initializes the internal state array,
553
+ * with an array of 32-bit integers used as the seeds
554
+ * @param init_key the array of 32-bit integers, used as a seed.
555
+ * @param key_length the length of init_key.
556
+ */
557
+ void init_by_array(uint32_t *init_key, int key_length) {
558
+ int i, j, count;
559
+ uint32_t r;
560
+ int lag;
561
+ int mid;
562
+ int size = N * 4;
563
+
564
+ if (size >= 623) {
565
+ lag = 11;
566
+ } else if (size >= 68) {
567
+ lag = 7;
568
+ } else if (size >= 39) {
569
+ lag = 5;
570
+ } else {
571
+ lag = 3;
572
+ }
573
+ mid = (size - lag) / 2;
574
+
575
+ memset(sfmt, 0x8b, sizeof(sfmt));
576
+ if (key_length + 1 > N32) {
577
+ count = key_length + 1;
578
+ } else {
579
+ count = N32;
580
+ }
581
+ r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
582
+ ^ psfmt32[idxof(N32 - 1)]);
583
+ psfmt32[idxof(mid)] += r;
584
+ r += key_length;
585
+ psfmt32[idxof(mid + lag)] += r;
586
+ psfmt32[idxof(0)] = r;
587
+
588
+ count--;
589
+ for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
590
+ r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
591
+ ^ psfmt32[idxof((i + N32 - 1) % N32)]);
592
+ psfmt32[idxof((i + mid) % N32)] += r;
593
+ r += init_key[j] + i;
594
+ psfmt32[idxof((i + mid + lag) % N32)] += r;
595
+ psfmt32[idxof(i)] = r;
596
+ i = (i + 1) % N32;
597
+ }
598
+ for (; j < count; j++) {
599
+ r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
600
+ ^ psfmt32[idxof((i + N32 - 1) % N32)]);
601
+ psfmt32[idxof((i + mid) % N32)] += r;
602
+ r += i;
603
+ psfmt32[idxof((i + mid + lag) % N32)] += r;
604
+ psfmt32[idxof(i)] = r;
605
+ i = (i + 1) % N32;
606
+ }
607
+ for (j = 0; j < N32; j++) {
608
+ r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)]
609
+ + psfmt32[idxof((i + N32 - 1) % N32)]);
610
+ psfmt32[idxof((i + mid) % N32)] ^= r;
611
+ r -= i;
612
+ psfmt32[idxof((i + mid + lag) % N32)] ^= r;
613
+ psfmt32[idxof(i)] = r;
614
+ i = (i + 1) % N32;
615
+ }
616
+
617
+ idx = N32;
618
+ period_certification();
619
+ initialized = 1;
620
+ }