3 * @brief double precision SIMD-oriented Fast Mersenne Twister (dSFMT)
4 * based on IEEE 754 format.
6 * @author Mutsuo Saito (Hiroshima University)
7 * @author Makoto Matsumoto (Hiroshima University)
9 * Copyright (C) 2007,2008 Mutsuo Saito, Makoto Matsumoto and Hiroshima
10 * University. All rights reserved.
12 * The new BSD License is applied to this software, see LICENSE.txt
17 #include "dSFMT-params.h"
19 /** dsfmt internal state vector */
20 dsfmt_t dsfmt_global_data;
21 /** dsfmt mexp for check */
22 static const int dsfmt_mexp = DSFMT_MEXP;
27 inline static uint32_t ini_func1(uint32_t x);
28 inline static uint32_t ini_func2(uint32_t x);
29 inline static void gen_rand_array_c1o2(dsfmt_t *dsfmt, w128_t array[],
31 inline static void gen_rand_array_c0o1(dsfmt_t *dsfmt, w128_t array[],
33 inline static void gen_rand_array_o0c1(dsfmt_t *dsfmt, w128_t array[],
35 inline static void gen_rand_array_o0o1(dsfmt_t *dsfmt, w128_t array[],
37 inline static int idxof(int i);
38 static void initial_mask(dsfmt_t *dsfmt);
39 static void period_certification(dsfmt_t *dsfmt);
41 #if defined(HAVE_SSE2)
42 # include <emmintrin.h>
43 /** mask data for sse2 */
44 static __m128i sse2_param_mask;
45 /** 1 in 64bit for sse2 */
46 static __m128i sse2_int_one;
47 /** 2.0 double for sse2 */
48 static __m128d sse2_double_two;
49 /** -1.0 double for sse2 */
50 static __m128d sse2_double_m_one;
52 static void setup_const(void);
56 * This function simulate a 32-bit array index overlapped to 64-bit
57 * array of LITTLE ENDIAN in BIG ENDIAN machine.
59 #if defined(DSFMT_BIG_ENDIAN)
60 inline static int idxof(int i) {
64 inline static int idxof(int i) {
70 * This function represents the recursion formula.
72 * @param a a 128-bit part of the internal state array
73 * @param b a 128-bit part of the internal state array
74 * @param lung a 128-bit part of the internal state array
76 #if defined(HAVE_ALTIVEC)
77 inline static void do_recursion(w128_t *r, w128_t *a, w128_t * b,
79 const vector unsigned char sl1 = ALTI_SL1;
80 const vector unsigned char sl1_perm = ALTI_SL1_PERM;
81 const vector unsigned int sl1_msk = ALTI_SL1_MSK;
82 const vector unsigned char sr1 = ALTI_SR;
83 const vector unsigned char sr1_perm = ALTI_SR_PERM;
84 const vector unsigned int sr1_msk = ALTI_SR_MSK;
85 const vector unsigned char perm = ALTI_PERM;
86 const vector unsigned int msk1 = ALTI_MSK;
87 vector unsigned int w, x, y, z;
91 x = vec_perm(w, (vector unsigned int)perm, perm);
92 y = vec_perm(z, sl1_perm, sl1_perm);
94 y = vec_and(y, sl1_msk);
97 x = vec_perm(w, (vector unsigned int)sr1_perm, sr1_perm);
99 x = vec_and(x, sr1_msk);
100 y = vec_and(w, msk1);
102 r->s = vec_xor(z, x);
105 #elif defined(HAVE_SSE2)
107 * This function setup some constant variables for SSE2.
109 static void setup_const(void) {
110 static int first = 1;
114 sse2_param_mask = _mm_set_epi32(DSFMT_MSK32_3, DSFMT_MSK32_4,
115 DSFMT_MSK32_1, DSFMT_MSK32_2);
116 sse2_int_one = _mm_set_epi32(0, 1, 0, 1);
117 sse2_double_two = _mm_set_pd(2.0, 2.0);
118 sse2_double_m_one = _mm_set_pd(-1.0, -1.0);
123 * This function represents the recursion formula.
124 * @param r output 128-bit
125 * @param a a 128-bit part of the internal state array
126 * @param b a 128-bit part of the internal state array
127 * @param d a 128-bit part of the internal state array (I/O)
129 inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *u) {
130 __m128i v, w, x, y, z;
133 z = _mm_slli_epi64(x, DSFMT_SL1);
134 y = _mm_shuffle_epi32(u->si, SSE2_SHUFF);
135 z = _mm_xor_si128(z, b->si);
136 y = _mm_xor_si128(y, z);
138 v = _mm_srli_epi64(y, DSFMT_SR);
139 w = _mm_and_si128(y, sse2_param_mask);
140 v = _mm_xor_si128(v, x);
141 v = _mm_xor_si128(v, w);
145 #else /* standard C */
147 * This function represents the recursion formula.
148 * @param r output 128-bit
149 * @param a a 128-bit part of the internal state array
150 * @param b a 128-bit part of the internal state array
151 * @param lung a 128-bit part of the internal state array (I/O)
153 inline static void do_recursion(w128_t *r, w128_t *a, w128_t * b,
155 uint64_t t0, t1, L0, L1;
161 lung->u[0] = (t0 << DSFMT_SL1) ^ (L1 >> 32) ^ (L1 << 32) ^ b->u[0];
162 lung->u[1] = (t1 << DSFMT_SL1) ^ (L0 >> 32) ^ (L0 << 32) ^ b->u[1];
163 r->u[0] = (lung->u[0] >> DSFMT_SR) ^ (lung->u[0] & DSFMT_MSK1) ^ t0;
164 r->u[1] = (lung->u[1] >> DSFMT_SR) ^ (lung->u[1] & DSFMT_MSK2) ^ t1;
168 #if defined(HAVE_SSE2)
170 * This function converts the double precision floating point numbers which
171 * distribute uniformly in the range [1, 2) to those which distribute uniformly
172 * in the range [0, 1).
173 * @param w 128bit stracture of double precision floating point numbers (I/O)
175 inline static void convert_c0o1(w128_t *w) {
176 w->sd = _mm_add_pd(w->sd, sse2_double_m_one);
180 * This function converts the double precision floating point numbers which
181 * distribute uniformly in the range [1, 2) to those which distribute uniformly
182 * in the range (0, 1].
183 * @param w 128bit stracture of double precision floating point numbers (I/O)
185 inline static void convert_o0c1(w128_t *w) {
186 w->sd = _mm_sub_pd(sse2_double_two, w->sd);
190 * This function converts the double precision floating point numbers which
191 * distribute uniformly in the range [1, 2) to those which distribute uniformly
192 * in the range (0, 1).
193 * @param w 128bit stracture of double precision floating point numbers (I/O)
195 inline static void convert_o0o1(w128_t *w) {
196 w->si = _mm_or_si128(w->si, sse2_int_one);
197 w->sd = _mm_add_pd(w->sd, sse2_double_m_one);
199 #else /* standard C and altivec */
201 * This function converts the double precision floating point numbers which
202 * distribute uniformly in the range [1, 2) to those which distribute uniformly
203 * in the range [0, 1).
204 * @param w 128bit stracture of double precision floating point numbers (I/O)
206 inline static void convert_c0o1(w128_t *w) {
212 * This function converts the double precision floating point numbers which
213 * distribute uniformly in the range [1, 2) to those which distribute uniformly
214 * in the range (0, 1].
215 * @param w 128bit stracture of double precision floating point numbers (I/O)
217 inline static void convert_o0c1(w128_t *w) {
218 w->d[0] = 2.0 - w->d[0];
219 w->d[1] = 2.0 - w->d[1];
223 * This function converts the double precision floating point numbers which
224 * distribute uniformly in the range [1, 2) to those which distribute uniformly
225 * in the range (0, 1).
226 * @param w 128bit stracture of double precision floating point numbers (I/O)
228 inline static void convert_o0o1(w128_t *w) {
237 * This function fills the user-specified array with double precision
238 * floating point pseudorandom numbers of the IEEE 754 format.
239 * @param dsfmt dsfmt state vector.
240 * @param array an 128-bit array to be filled by pseudorandom numbers.
241 * @param size number of 128-bit pseudorandom numbers to be generated.
243 inline static void gen_rand_array_c1o2(dsfmt_t *dsfmt, w128_t array[],
248 lung = dsfmt->status[DSFMT_N];
249 do_recursion(&array[0], &dsfmt->status[0], &dsfmt->status[DSFMT_POS1],
251 for (i = 1; i < DSFMT_N - DSFMT_POS1; i++) {
252 do_recursion(&array[i], &dsfmt->status[i],
253 &dsfmt->status[i + DSFMT_POS1], &lung);
255 for (; i < DSFMT_N; i++) {
256 do_recursion(&array[i], &dsfmt->status[i],
257 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
259 for (; i < size - DSFMT_N; i++) {
260 do_recursion(&array[i], &array[i - DSFMT_N],
261 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
263 for (j = 0; j < 2 * DSFMT_N - size; j++) {
264 dsfmt->status[j] = array[j + size - DSFMT_N];
266 for (; i < size; i++, j++) {
267 do_recursion(&array[i], &array[i - DSFMT_N],
268 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
269 dsfmt->status[j] = array[i];
271 dsfmt->status[DSFMT_N] = lung;
275 * This function fills the user-specified array with double precision
276 * floating point pseudorandom numbers of the IEEE 754 format.
277 * @param dsfmt dsfmt state vector.
278 * @param array an 128-bit array to be filled by pseudorandom numbers.
279 * @param size number of 128-bit pseudorandom numbers to be generated.
281 inline static void gen_rand_array_c0o1(dsfmt_t *dsfmt, w128_t array[],
286 lung = dsfmt->status[DSFMT_N];
287 do_recursion(&array[0], &dsfmt->status[0], &dsfmt->status[DSFMT_POS1],
289 for (i = 1; i < DSFMT_N - DSFMT_POS1; i++) {
290 do_recursion(&array[i], &dsfmt->status[i],
291 &dsfmt->status[i + DSFMT_POS1], &lung);
293 for (; i < DSFMT_N; i++) {
294 do_recursion(&array[i], &dsfmt->status[i],
295 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
297 for (; i < size - DSFMT_N; i++) {
298 do_recursion(&array[i], &array[i - DSFMT_N],
299 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
300 convert_c0o1(&array[i - DSFMT_N]);
302 for (j = 0; j < 2 * DSFMT_N - size; j++) {
303 dsfmt->status[j] = array[j + size - DSFMT_N];
305 for (; i < size; i++, j++) {
306 do_recursion(&array[i], &array[i - DSFMT_N],
307 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
308 dsfmt->status[j] = array[i];
309 convert_c0o1(&array[i - DSFMT_N]);
311 for (i = size - DSFMT_N; i < size; i++) {
312 convert_c0o1(&array[i]);
314 dsfmt->status[DSFMT_N] = lung;
318 * This function fills the user-specified array with double precision
319 * floating point pseudorandom numbers of the IEEE 754 format.
320 * @param dsfmt dsfmt state vector.
321 * @param array an 128-bit array to be filled by pseudorandom numbers.
322 * @param size number of 128-bit pseudorandom numbers to be generated.
324 inline static void gen_rand_array_o0o1(dsfmt_t *dsfmt, w128_t array[],
329 lung = dsfmt->status[DSFMT_N];
330 do_recursion(&array[0], &dsfmt->status[0], &dsfmt->status[DSFMT_POS1],
332 for (i = 1; i < DSFMT_N - DSFMT_POS1; i++) {
333 do_recursion(&array[i], &dsfmt->status[i],
334 &dsfmt->status[i + DSFMT_POS1], &lung);
336 for (; i < DSFMT_N; i++) {
337 do_recursion(&array[i], &dsfmt->status[i],
338 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
340 for (; i < size - DSFMT_N; i++) {
341 do_recursion(&array[i], &array[i - DSFMT_N],
342 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
343 convert_o0o1(&array[i - DSFMT_N]);
345 for (j = 0; j < 2 * DSFMT_N - size; j++) {
346 dsfmt->status[j] = array[j + size - DSFMT_N];
348 for (; i < size; i++, j++) {
349 do_recursion(&array[i], &array[i - DSFMT_N],
350 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
351 dsfmt->status[j] = array[i];
352 convert_o0o1(&array[i - DSFMT_N]);
354 for (i = size - DSFMT_N; i < size; i++) {
355 convert_o0o1(&array[i]);
357 dsfmt->status[DSFMT_N] = lung;
361 * This function fills the user-specified array with double precision
362 * floating point pseudorandom numbers of the IEEE 754 format.
363 * @param dsfmt dsfmt state vector.
364 * @param array an 128-bit array to be filled by pseudorandom numbers.
365 * @param size number of 128-bit pseudorandom numbers to be generated.
367 inline static void gen_rand_array_o0c1(dsfmt_t *dsfmt, w128_t array[],
372 lung = dsfmt->status[DSFMT_N];
373 do_recursion(&array[0], &dsfmt->status[0], &dsfmt->status[DSFMT_POS1],
375 for (i = 1; i < DSFMT_N - DSFMT_POS1; i++) {
376 do_recursion(&array[i], &dsfmt->status[i],
377 &dsfmt->status[i + DSFMT_POS1], &lung);
379 for (; i < DSFMT_N; i++) {
380 do_recursion(&array[i], &dsfmt->status[i],
381 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
383 for (; i < size - DSFMT_N; i++) {
384 do_recursion(&array[i], &array[i - DSFMT_N],
385 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
386 convert_o0c1(&array[i - DSFMT_N]);
388 for (j = 0; j < 2 * DSFMT_N - size; j++) {
389 dsfmt->status[j] = array[j + size - DSFMT_N];
391 for (; i < size; i++, j++) {
392 do_recursion(&array[i], &array[i - DSFMT_N],
393 &array[i + DSFMT_POS1 - DSFMT_N], &lung);
394 dsfmt->status[j] = array[i];
395 convert_o0c1(&array[i - DSFMT_N]);
397 for (i = size - DSFMT_N; i < size; i++) {
398 convert_o0c1(&array[i]);
400 dsfmt->status[DSFMT_N] = lung;
404 * This function represents a function used in the initialization
406 * @param x 32-bit integer
407 * @return 32-bit integer
409 static uint32_t ini_func1(uint32_t x) {
410 return (x ^ (x >> 27)) * (uint32_t)1664525UL;
414 * This function represents a function used in the initialization
416 * @param x 32-bit integer
417 * @return 32-bit integer
419 static uint32_t ini_func2(uint32_t x) {
420 return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
424 * This function initializes the internal state array to fit the IEEE
426 * @param dsfmt dsfmt state vector.
428 static void initial_mask(dsfmt_t *dsfmt) {
432 psfmt = &dsfmt->status[0].u[0];
433 for (i = 0; i < DSFMT_N * 2; i++) {
434 psfmt[i] = (psfmt[i] & DSFMT_LOW_MASK) | DSFMT_HIGH_CONST;
439 * This function certificate the period of 2^{SFMT_MEXP}-1.
440 * @param dsfmt dsfmt state vector.
442 static void period_certification(dsfmt_t *dsfmt) {
444 uint64_t pcv[2] = {DSFMT_PCV1, DSFMT_PCV2};
448 tmp[0] = (dsfmt->status[DSFMT_N].u[0] ^ DSFMT_FIX1);
449 tmp[1] = (dsfmt->status[DSFMT_N].u[1] ^ DSFMT_FIX2);
451 inner = tmp[0] & pcv[0];
452 inner ^= tmp[1] & pcv[1];
453 for (i = 32; i > 0; i >>= 1) {
461 /* check NG, and modification */
462 #if (DSFMT_PCV2 & 1) == 1
463 dsfmt->status[DSFMT_N].u[1] ^= 1;
466 for (i = 1; i >= 0; i--) {
468 for (j = 0; j < 64; j++) {
469 if ((work & pcv[i]) != 0) {
470 dsfmt->status[DSFMT_N].u[i] ^= work;
484 * This function returns the identification string. The string shows
485 * the Mersenne exponent, and all parameters of this generator.
488 const char *dsfmt_get_idstring(void) {
493 * This function returns the minimum size of array used for \b
494 * fill_array functions.
495 * @return minimum size of array used for fill_array functions.
497 int dsfmt_get_min_array_size(void) {
502 * This function fills the internal state array with double precision
503 * floating point pseudorandom numbers of the IEEE 754 format.
504 * @param dsfmt dsfmt state vector.
506 void dsfmt_gen_rand_all(dsfmt_t *dsfmt) {
510 lung = dsfmt->status[DSFMT_N];
511 do_recursion(&dsfmt->status[0], &dsfmt->status[0],
512 &dsfmt->status[DSFMT_POS1], &lung);
513 for (i = 1; i < DSFMT_N - DSFMT_POS1; i++) {
514 do_recursion(&dsfmt->status[i], &dsfmt->status[i],
515 &dsfmt->status[i + DSFMT_POS1], &lung);
517 for (; i < DSFMT_N; i++) {
518 do_recursion(&dsfmt->status[i], &dsfmt->status[i],
519 &dsfmt->status[i + DSFMT_POS1 - DSFMT_N], &lung);
521 dsfmt->status[DSFMT_N] = lung;
525 * This function generates double precision floating point
526 * pseudorandom numbers which distribute in the range [1, 2) to the
527 * specified array[] by one call. The number of pseudorandom numbers
528 * is specified by the argument \b size, which must be at least (SFMT_MEXP
529 * / 128) * 2 and a multiple of two. The function
530 * get_min_array_size() returns this minimum size. The generation by
531 * this function is much faster than the following fill_array_xxx functions.
533 * For initialization, init_gen_rand() or init_by_array() must be called
534 * before the first call of this function. This function can not be
535 * used after calling genrand_xxx functions, without initialization.
537 * @param dsfmt dsfmt state vector.
538 * @param array an array where pseudorandom numbers are filled
539 * by this function. The pointer to the array must be "aligned"
540 * (namely, must be a multiple of 16) in the SIMD version, since it
541 * refers to the address of a 128-bit integer. In the standard C
542 * version, the pointer is arbitrary.
544 * @param size the number of 64-bit pseudorandom integers to be
545 * generated. size must be a multiple of 2, and greater than or equal
546 * to (SFMT_MEXP / 128) * 2.
548 * @note \b memalign or \b posix_memalign is available to get aligned
549 * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
550 * returns the pointer to the aligned memory block.
552 void dsfmt_fill_array_close1_open2(dsfmt_t *dsfmt, double array[], int size) {
553 assert(size % 2 == 0);
554 assert(size >= DSFMT_N64);
555 gen_rand_array_c1o2(dsfmt, (w128_t *)array, size / 2);
559 * This function generates double precision floating point
560 * pseudorandom numbers which distribute in the range (0, 1] to the
561 * specified array[] by one call. This function is the same as
562 * fill_array_close1_open2() except the distribution range.
564 * @param dsfmt dsfmt state vector.
565 * @param array an array where pseudorandom numbers are filled
567 * @param size the number of pseudorandom numbers to be generated.
568 * see also \sa fill_array_close1_open2()
570 void dsfmt_fill_array_open_close(dsfmt_t *dsfmt, double array[], int size) {
571 assert(size % 2 == 0);
572 assert(size >= DSFMT_N64);
573 gen_rand_array_o0c1(dsfmt, (w128_t *)array, size / 2);
577 * This function generates double precision floating point
578 * pseudorandom numbers which distribute in the range [0, 1) to the
579 * specified array[] by one call. This function is the same as
580 * fill_array_close1_open2() except the distribution range.
582 * @param array an array where pseudorandom numbers are filled
584 * @param dsfmt dsfmt state vector.
585 * @param size the number of pseudorandom numbers to be generated.
586 * see also \sa fill_array_close1_open2()
588 void dsfmt_fill_array_close_open(dsfmt_t *dsfmt, double array[], int size) {
589 assert(size % 2 == 0);
590 assert(size >= DSFMT_N64);
591 gen_rand_array_c0o1(dsfmt, (w128_t *)array, size / 2);
595 * This function generates double precision floating point
596 * pseudorandom numbers which distribute in the range (0, 1) to the
597 * specified array[] by one call. This function is the same as
598 * fill_array_close1_open2() except the distribution range.
600 * @param dsfmt dsfmt state vector.
601 * @param array an array where pseudorandom numbers are filled
603 * @param size the number of pseudorandom numbers to be generated.
604 * see also \sa fill_array_close1_open2()
606 void dsfmt_fill_array_open_open(dsfmt_t *dsfmt, double array[], int size) {
607 assert(size % 2 == 0);
608 assert(size >= DSFMT_N64);
609 gen_rand_array_o0o1(dsfmt, (w128_t *)array, size / 2);
612 #if defined(__INTEL_COMPILER)
613 # pragma warning(disable:981)
616 * This function initializes the internal state array with a 32-bit
618 * @param dsfmt dsfmt state vector.
619 * @param seed a 32-bit integer used as the seed.
620 * @param mexp caller's mersenne expornent
622 void dsfmt_chk_init_gen_rand(dsfmt_t *dsfmt, uint32_t seed, int mexp) {
626 /* make sure caller program is compiled with the same MEXP */
627 if (mexp != dsfmt_mexp) {
628 fprintf(stderr, "DSFMT_MEXP doesn't match with dSFMT.c\n");
631 psfmt = &dsfmt->status[0].u32[0];
632 psfmt[idxof(0)] = seed;
633 for (i = 1; i < (DSFMT_N + 1) * 4; i++) {
634 psfmt[idxof(i)] = 1812433253UL
635 * (psfmt[idxof(i - 1)] ^ (psfmt[idxof(i - 1)] >> 30)) + i;
638 period_certification(dsfmt);
639 dsfmt->idx = DSFMT_N64;
640 #if defined(HAVE_SSE2)
646 * This function initializes the internal state array,
647 * with an array of 32-bit integers used as the seeds
648 * @param dsfmt dsfmt state vector.
649 * @param init_key the array of 32-bit integers, used as a seed.
650 * @param key_length the length of init_key.
651 * @param mexp caller's mersenne expornent
653 void dsfmt_chk_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[],
654 int key_length, int mexp) {
660 int size = (DSFMT_N + 1) * 4; /* pulmonary */
662 /* make sure caller program is compiled with the same MEXP */
663 if (mexp != dsfmt_mexp) {
664 fprintf(stderr, "DSFMT_MEXP doesn't match with dSFMT.c\n");
669 } else if (size >= 68) {
671 } else if (size >= 39) {
676 mid = (size - lag) / 2;
678 psfmt32 = &dsfmt->status[0].u32[0];
679 memset(dsfmt->status, 0x8b, sizeof(dsfmt->status));
680 if (key_length + 1 > size) {
681 count = key_length + 1;
685 r = ini_func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid % size)]
686 ^ psfmt32[idxof((size - 1) % size)]);
687 psfmt32[idxof(mid % size)] += r;
689 psfmt32[idxof((mid + lag) % size)] += r;
690 psfmt32[idxof(0)] = r;
693 for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
694 r = ini_func1(psfmt32[idxof(i)]
695 ^ psfmt32[idxof((i + mid) % size)]
696 ^ psfmt32[idxof((i + size - 1) % size)]);
697 psfmt32[idxof((i + mid) % size)] += r;
698 r += init_key[j] + i;
699 psfmt32[idxof((i + mid + lag) % size)] += r;
700 psfmt32[idxof(i)] = r;
703 for (; j < count; j++) {
704 r = ini_func1(psfmt32[idxof(i)]
705 ^ psfmt32[idxof((i + mid) % size)]
706 ^ psfmt32[idxof((i + size - 1) % size)]);
707 psfmt32[idxof((i + mid) % size)] += r;
709 psfmt32[idxof((i + mid + lag) % size)] += r;
710 psfmt32[idxof(i)] = r;
713 for (j = 0; j < size; j++) {
714 r = ini_func2(psfmt32[idxof(i)]
715 + psfmt32[idxof((i + mid) % size)]
716 + psfmt32[idxof((i + size - 1) % size)]);
717 psfmt32[idxof((i + mid) % size)] ^= r;
719 psfmt32[idxof((i + mid + lag) % size)] ^= r;
720 psfmt32[idxof(i)] = r;
724 period_certification(dsfmt);
725 dsfmt->idx = DSFMT_N64;
726 #if defined(HAVE_SSE2)
730 #if defined(__INTEL_COMPILER)
731 # pragma warning(default:981)