123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /**
- * @file tinymt32.c
- *
- * @brief Tiny Mersenne Twister only 127 bit internal state
- *
- * @author Mutsuo Saito (Hiroshima University)
- * @author Makoto Matsumoto (The University of Tokyo)
- *
- * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
- * Hiroshima University and The University of Tokyo.
- * All rights reserved.
- *
- * The 3-clause BSD License is applied to this software, see
- * LICENSE.txt
- */
- #include "tinymt32.h"
- #define MIN_LOOP 8
- #define PRE_LOOP 8
- /**
- * This function represents a function used in the initialization
- * by init_by_array
- * @param x 32-bit integer
- * @return 32-bit integer
- */
- static uint32_t ini_func1(uint32_t x) {
- return (x ^ (x >> 27)) * UINT32_C(1664525);
- }
- /**
- * This function represents a function used in the initialization
- * by init_by_array
- * @param x 32-bit integer
- * @return 32-bit integer
- */
- static uint32_t ini_func2(uint32_t x) {
- return (x ^ (x >> 27)) * UINT32_C(1566083941);
- }
- /**
- * This function certificate the period of 2^127-1.
- * @param random tinymt state vector.
- */
- static void period_certification(tinymt32_t * random) {
- if ((random->status[0] & TINYMT32_MASK) == 0 &&
- random->status[1] == 0 &&
- random->status[2] == 0 &&
- random->status[3] == 0) {
- random->status[0] = 'T';
- random->status[1] = 'I';
- random->status[2] = 'N';
- random->status[3] = 'Y';
- }
- }
- /**
- * This function initializes the internal state array with a 32-bit
- * unsigned integer seed.
- * @param random tinymt state vector.
- * @param seed a 32-bit unsigned integer used as a seed.
- */
- void tinymt32_init(tinymt32_t * random, uint32_t seed) {
- random->status[0] = seed;
- random->status[1] = random->mat1;
- random->status[2] = random->mat2;
- random->status[3] = random->tmat;
- for (int i = 1; i < MIN_LOOP; i++) {
- random->status[i & 3] ^= i + UINT32_C(1812433253)
- * (random->status[(i - 1) & 3]
- ^ (random->status[(i - 1) & 3] >> 30));
- }
- period_certification(random);
- for (int i = 0; i < PRE_LOOP; i++) {
- tinymt32_next_state(random);
- }
- }
- /**
- * This function initializes the internal state array,
- * with an array of 32-bit unsigned integers used as seeds
- * @param random tinymt state vector.
- * @param init_key the array of 32-bit integers, used as a seed.
- * @param key_length the length of init_key.
- */
- void tinymt32_init_by_array(tinymt32_t * random, uint32_t init_key[],
- int key_length) {
- const int lag = 1;
- const int mid = 1;
- const int size = 4;
- int i, j;
- int count;
- uint32_t r;
- uint32_t * st = &random->status[0];
- st[0] = 0;
- st[1] = random->mat1;
- st[2] = random->mat2;
- st[3] = random->tmat;
- if (key_length + 1 > MIN_LOOP) {
- count = key_length + 1;
- } else {
- count = MIN_LOOP;
- }
- r = ini_func1(st[0] ^ st[mid % size]
- ^ st[(size - 1) % size]);
- st[mid % size] += r;
- r += key_length;
- st[(mid + lag) % size] += r;
- st[0] = r;
- count--;
- for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
- r = ini_func1(st[i % size]
- ^ st[(i + mid) % size]
- ^ st[(i + size - 1) % size]);
- st[(i + mid) % size] += r;
- r += init_key[j] + i;
- st[(i + mid + lag) % size] += r;
- st[i % size] = r;
- i = (i + 1) % size;
- }
- for (; j < count; j++) {
- r = ini_func1(st[i % size]
- ^ st[(i + mid) % size]
- ^ st[(i + size - 1) % size]);
- st[(i + mid) % size] += r;
- r += i;
- st[(i + mid + lag) % size] += r;
- st[i % size] = r;
- i = (i + 1) % size;
- }
- for (j = 0; j < size; j++) {
- r = ini_func2(st[i % size]
- + st[(i + mid) % size]
- + st[(i + size - 1) % size]);
- st[(i + mid) % size] ^= r;
- r -= i;
- st[(i + mid + lag) % size] ^= r;
- st[i % size] = r;
- i = (i + 1) % size;
- }
- period_certification(random);
- for (i = 0; i < PRE_LOOP; i++) {
- tinymt32_next_state(random);
- }
- }
|