source: Sophya/trunk/SophyaLib/BaseTools/tinymt32.c@ 4040

Last change on this file since 4040 was 4019, checked in by cmv, 14 years ago

ajout generateurs tinymt32+64, cmv 24/09/2011

File size: 3.7 KB
RevLine 
[4019]1/**
2 * @file tinymt32.c
3 *
4 * @brief Tiny Mersenne Twister only 127 bit internal state
5 *
6 * @author Mutsuo Saito (Hiroshima University)
7 * @author Makoto Matsumoto (The University of Tokyo)
8 *
9 * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
10 * Hiroshima University and The University of Tokyo.
11 * All rights reserved.
12 *
13 * The 3-clause BSD License is applied to this software, see
14 * LICENSE.txt
15 */
16#include "tinymt32.h"
17#define MIN_LOOP 8
18#define PRE_LOOP 8
19
20/**
21 * This function represents a function used in the initialization
22 * by init_by_array
23 * @param x 32-bit integer
24 * @return 32-bit integer
25 */
26static uint32_t ini_func1(uint32_t x) {
27 return (x ^ (x >> 27)) * (uint32_t)1664525UL;
28}
29
30/**
31 * This function represents a function used in the initialization
32 * by init_by_array
33 * @param x 32-bit integer
34 * @return 32-bit integer
35 */
36static uint32_t ini_func2(uint32_t x) {
37 return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
38}
39
40/**
41 * This function certificate the period of 2^127-1.
42 * @param random tinymt state vector.
43 */
44static void period_certification(tinymt32_t * random) {
45 if ((random->status[0] & TINYMT32_MASK) == 0 &&
46 random->status[1] == 0 &&
47 random->status[2] == 0 &&
48 random->status[3] == 0) {
49 random->status[0] = 'T';
50 random->status[1] = 'I';
51 random->status[2] = 'N';
52 random->status[3] = 'Y';
53 }
54}
55
56/**
57 * This function initializes the internal state array with a 32-bit
58 * unsigned integer seed.
59 * @param random tinymt state vector.
60 * @param seed a 32-bit unsigned integer used as a seed.
61 */
62void tinymt32_init(tinymt32_t * random, uint32_t seed) {
63 int i;
64 random->status[0] = seed;
65 random->status[1] = random->mat1;
66 random->status[2] = random->mat2;
67 random->status[3] = random->tmat;
68 for (i = 1; i < MIN_LOOP; i++) {
69 random->status[i & 3] ^= i + UINT32_C(1812433253)
70 * (random->status[(i - 1) & 3]
71 ^ (random->status[(i - 1) & 3] >> 30));
72 }
73 period_certification(random);
74 for (i = 0; i < PRE_LOOP; i++) {
75 tinymt32_next_state(random);
76 }
77}
78
79/**
80 * This function initializes the internal state array,
81 * with an array of 32-bit unsigned integers used as seeds
82 * @param random tinymt state vector.
83 * @param init_key the array of 32-bit integers, used as a seed.
84 * @param key_length the length of init_key.
85 */
86void tinymt32_init_by_array(tinymt32_t * random, uint32_t init_key[],
87 int key_length) {
88 const int lag = 1;
89 const int mid = 1;
90 const int size = 4;
91 int i, j;
92 int count;
93 uint32_t r;
94 uint32_t * st = &random->status[0];
95
96 st[0] = 0;
97 st[1] = random->mat1;
98 st[2] = random->mat2;
99 st[3] = random->tmat;
100 if (key_length + 1 > MIN_LOOP) {
101 count = key_length + 1;
102 } else {
103 count = MIN_LOOP;
104 }
105 r = ini_func1(st[0] ^ st[mid % size]
106 ^ st[(size - 1) % size]);
107 st[mid % size] += r;
108 r += key_length;
109 st[(mid + lag) % size] += r;
110 st[0] = r;
111 count--;
112 for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
113 r = ini_func1(st[i] ^ st[(i + mid) % size] ^ st[(i + size - 1) % size]);
114 st[(i + mid) % size] += r;
115 r += init_key[j] + i;
116 st[(i + mid + lag) % size] += r;
117 st[i] = r;
118 i = (i + 1) % size;
119 }
120 for (; j < count; j++) {
121 r = ini_func1(st[i] ^ st[(i + mid) % size] ^ st[(i + size - 1) % size]);
122 st[(i + mid) % size] += r;
123 r += i;
124 st[(i + mid + lag) % size] += r;
125 st[i] = r;
126 i = (i + 1) % size;
127 }
128 for (j = 0; j < size; j++) {
129 r = ini_func2(st[i] + st[(i + mid) % size] + st[(i + size - 1) % size]);
130 st[(i + mid) % size] ^= r;
131 r -= i;
132 st[(i + mid + lag) % size] ^= r;
133 st[i] = r;
134 i = (i + 1) % size;
135 }
136 period_certification(random);
137 for (i = 0; i < PRE_LOOP; i++) {
138 tinymt32_next_state(random);
139 }
140}
Note: See TracBrowser for help on using the repository browser.