numo-narray 0.9.0.1-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }