source: Sophya/trunk/SophyaLib/BaseTools/tinymt64.h@ 4057

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

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

File size: 6.0 KB
Line 
1#ifndef TINYMT64_H
2#define TINYMT64_H
3/**
4 * @file tinymt64.h
5 *
6 * @brief Tiny Mersenne Twister only 127 bit internal state
7 *
8 * @author Mutsuo Saito (Hiroshima University)
9 * @author Makoto Matsumoto (The University of Tokyo)
10 *
11 * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
12 * Hiroshima University and The University of Tokyo.
13 * All rights reserved.
14 *
15 * The 3-clause BSD License is applied to this software, see
16 * LICENSE.txt
17 */
18
19#include <stdint.h>
20#include <inttypes.h>
21
22#define TINYMT64_MEXP 127
23#define TINYMT64_SH0 12
24#define TINYMT64_SH1 11
25#define TINYMT64_SH8 8
26#define TINYMT64_MASK UINT64_C(0x7fffffffffffffff)
27#define TINYMT64_MUL (1.0 / 18446744073709551616.0)
28
29/*
30 * tinymt64 internal state vector and parameters
31 */
32struct TINYMT64_T {
33 uint64_t status[2];
34 uint32_t mat1;
35 uint32_t mat2;
36 uint64_t tmat;
37};
38
39typedef struct TINYMT64_T tinymt64_t;
40
41/* --- Ajout par cmv / Compilation C++ --- */
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46void tinymt64_init(tinymt64_t * random, uint64_t seed);
47void tinymt64_init_by_array(tinymt64_t * random, const uint64_t init_key[],
48 int key_length);
49
50/* --- Ajout par cmv / Compilation C++ --- */
51#ifdef __cplusplus
52}
53#endif
54
55#if defined(__GNUC__)
56/**
57 * This function always returns 127
58 * @param random not used
59 * @return always 127
60 */
61inline static int tinymt64_get_mexp(
62 tinymt64_t * random __attribute__((unused))) {
63 return TINYMT64_MEXP;
64}
65#else
66inline static int tinymt64_get_mexp(tinymt64_t * random) {
67 return TINYMT64_MEXP;
68}
69#endif
70
71/**
72 * This function changes internal state of tinymt64.
73 * Users should not call this function directly.
74 * @param random tinymt internal status
75 */
76inline static void tinymt64_next_state(tinymt64_t * random) {
77 uint64_t x;
78
79 random->status[0] &= TINYMT64_MASK;
80 x = random->status[0] ^ random->status[1];
81 x ^= x << TINYMT64_SH0;
82 x ^= x >> 32;
83 x ^= x << 32;
84 x ^= x << TINYMT64_SH1;
85 random->status[0] = random->status[1];
86 random->status[1] = x;
87 random->status[0] ^= -((int64_t)(x & 1)) & random->mat1;
88 random->status[1] ^= -((int64_t)(x & 1)) & (((uint64_t)random->mat2) << 32);
89}
90
91/**
92 * This function outputs 64-bit unsigned integer from internal state.
93 * Users should not call this function directly.
94 * @param random tinymt internal status
95 * @return 64-bit unsigned pseudorandom number
96 */
97inline static uint64_t tinymt64_temper(tinymt64_t * random) {
98 uint64_t x;
99#if defined(LINEARITY_CHECK)
100 x = random->status[0] ^ random->status[1];
101#else
102 x = random->status[0] + random->status[1];
103#endif
104 x ^= random->status[0] >> TINYMT64_SH8;
105 x ^= -((int64_t)(x & 1)) & random->tmat;
106 return x;
107}
108
109/**
110 * This function outputs floating point number from internal state.
111 * Users should not call this function directly.
112 * @param random tinymt internal status
113 * @return floating point number r (1.0 <= r < 2.0)
114 */
115inline static double tinymt64_temper_conv(tinymt64_t * random) {
116 uint64_t x;
117 union {
118 uint64_t u;
119 double d;
120 } conv;
121#if defined(LINEARITY_CHECK)
122 x = random->status[0] ^ random->status[1];
123#else
124 x = random->status[0] + random->status[1];
125#endif
126 x ^= random->status[0] >> TINYMT64_SH8;
127 conv.u = ((x ^ (-((int64_t)(x & 1)) & random->tmat)) >> 12)
128 | UINT64_C(0x3ff0000000000000);
129 return conv.d;
130}
131
132/**
133 * This function outputs floating point number from internal state.
134 * Users should not call this function directly.
135 * @param random tinymt internal status
136 * @return floating point number r (1.0 < r < 2.0)
137 */
138inline static double tinymt64_temper_conv_open(tinymt64_t * random) {
139 uint64_t x;
140 union {
141 uint64_t u;
142 double d;
143 } conv;
144#if defined(LINEARITY_CHECK)
145 x = random->status[0] ^ random->status[1];
146#else
147 x = random->status[0] + random->status[1];
148#endif
149 x ^= random->status[0] >> TINYMT64_SH8;
150 conv.u = ((x ^ (-((int64_t)(x & 1)) & random->tmat)) >> 12)
151 | UINT64_C(0x3ff0000000000001);
152 return conv.d;
153}
154
155/**
156 * This function outputs 64-bit unsigned integer from internal state.
157 * @param random tinymt internal status
158 * @return 64-bit unsigned integer r (0 <= r < 2^64)
159 */
160inline static uint64_t tinymt64_generate_uint64(tinymt64_t * random) {
161 tinymt64_next_state(random);
162 return tinymt64_temper(random);
163}
164
165/**
166 * This function outputs floating point number from internal state.
167 * This function is implemented using multiplying by 1 / 2^64.
168 * @param random tinymt internal status
169 * @return floating point number r (0.0 <= r < 1.0)
170 */
171inline static double tinymt64_generate_double(tinymt64_t * random) {
172 tinymt64_next_state(random);
173 return tinymt64_temper(random) * TINYMT64_MUL;
174}
175
176/**
177 * This function outputs floating point number from internal state.
178 * This function is implemented using union trick.
179 * @param random tinymt internal status
180 * @return floating point number r (0.0 <= r < 1.0)
181 */
182inline static double tinymt64_generate_double01(tinymt64_t * random) {
183 tinymt64_next_state(random);
184 return tinymt64_temper_conv(random) - 1.0;
185}
186
187/**
188 * This function outputs floating point number from internal state.
189 * This function is implemented using union trick.
190 * @param random tinymt internal status
191 * @return floating point number r (1.0 <= r < 2.0)
192 */
193inline static double tinymt64_generate_double12(tinymt64_t * random) {
194 tinymt64_next_state(random);
195 return tinymt64_temper_conv(random);
196}
197
198/**
199 * This function outputs floating point number from internal state.
200 * This function is implemented using union trick.
201 * @param random tinymt internal status
202 * @return floating point number r (0.0 < r <= 1.0)
203 */
204inline static double tinymt64_generate_doubleOC(tinymt64_t * random) {
205 tinymt64_next_state(random);
206 return 2.0 - tinymt64_temper_conv(random);
207}
208
209/**
210 * This function outputs floating point number from internal state.
211 * This function is implemented using union trick.
212 * @param random tinymt internal status
213 * @return floating point number r (0.0 < r < 1.0)
214 */
215inline static double tinymt64_generate_doubleOO(tinymt64_t * random) {
216 tinymt64_next_state(random);
217 return tinymt64_temper_conv_open(random) - 1.0;
218}
219
220#endif
Note: See TracBrowser for help on using the repository browser.