Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
MersenneTwister.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MersenneTwister.h (C) 2000-2025 */
9/* */
10/* This file defines the MersenneTwister class pattern as well as two */
11/* associated classes mt19937 and mt11213b. It is a version adapted for */
12/* TROLL of the MersenneTwister.hpp file from the BOOST library */
13/*---------------------------------------------------------------------------*/
14/*---------------------------------------------------------------------------*/
15#ifndef ARCANE_CORE_RANDOM_MERSENNETWISTER_H
16#define ARCANE_CORE_RANDOM_MERSENNETWISTER_H
17/*---------------------------------------------------------------------------*/
18/*---------------------------------------------------------------------------*/
19
20#include "arcane/utils/FatalErrorException.h"
21
22#include "arcane/core/random/RandomGlobal.h"
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane::random
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
45template <class UIntType, Integer w, Integer n, Integer m, Integer r, UIntType a, Integer u,
46 Integer s, UIntType b, Integer t, UIntType c, Integer l, UIntType val>
48{
49 public:
50
51 typedef UIntType result_type;
52 static const Integer word_size = w;
53 static const Integer state_size = n;
54 static const Integer shift_size = m;
55 static const Integer mask_bits = r;
56 static const UIntType parameter_a = a;
57 static const Integer output_u = u;
58 static const Integer output_s = s;
59 static const UIntType output_b = b;
60 static const Integer output_t = t;
61 static const UIntType output_c = c;
62 static const Integer output_l = l;
63
64 static const bool has_fixed_range = false;
65
66 /*---------------------------------------------------------------------------*/
67 /*---------------------------------------------------------------------------*/
68
76
77 /*---------------------------------------------------------------------------*/
78 /*---------------------------------------------------------------------------*/
79
86 explicit MersenneTwister(UIntType value)
87 {
88 seed(value);
89 }
90
91 /*---------------------------------------------------------------------------*/
92 /*---------------------------------------------------------------------------*/
93
100 template <class It> MersenneTwister(It& first, It last) { seed(first, last); }
101
102 /*---------------------------------------------------------------------------*/
103 /*---------------------------------------------------------------------------*/
104
112 template <class Generator>
113 explicit MersenneTwister(Generator& gen) { seed(gen); }
114
115 /*---------------------------------------------------------------------------*/
116 /*---------------------------------------------------------------------------*/
117
124 void seed() { seed(UIntType(5489)); }
125
126 /*---------------------------------------------------------------------------*/
127 /*---------------------------------------------------------------------------*/
128
135 void seed(UIntType value)
136 {
137 // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
138 const UIntType mask = ~0u;
139 x[0] = value & mask;
140 for (i = 1; i < n; i++) {
141 // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
142 x[i] = (1812433253UL * (x[i - 1] ^ (x[i - 1] >> (w - 2))) + i) & mask;
143 }
144 }
145
146 /*---------------------------------------------------------------------------*/
147 /*---------------------------------------------------------------------------*/
148
155 void seed(UIntType* state)
156 {
157 for (Integer i = 0; i < n; i++)
158 x[i] = state[i];
159 }
160
161 /*---------------------------------------------------------------------------*/
162 /*---------------------------------------------------------------------------*/
163
171 template <class Generator>
172 void seed(Generator& gen)
173 {
174 // For GCC, moving this function out-of-line prevents inlining, which may
175 // reduce overall object code size. However, MSVC does not grok
176 // out-of-line definitions of member function templates.
177 for (Integer j = 0; j < n; j++)
178 x[j] = gen();
179 i = n;
180 }
181
182 /*---------------------------------------------------------------------------*/
183 /*---------------------------------------------------------------------------*/
184
192 UIntType getState(Integer j)
193 {
194 return x[j];
195 }
196
197 /*---------------------------------------------------------------------------*/
198 /*---------------------------------------------------------------------------*/
199
205 result_type min() const { return 0; }
206
207 /*---------------------------------------------------------------------------*/
208 /*---------------------------------------------------------------------------*/
209
215 result_type max() const
216 {
217 // avoid "left shift count >= with of type" warning
218 result_type res = 0;
219 for (Integer i = 0; i < w; ++i)
220 res |= (1u << i);
221 return res;
222 }
223
224 /*---------------------------------------------------------------------------*/
225 /*---------------------------------------------------------------------------*/
226
227 /* declaration of the () operator */
228 result_type operator()();
229
230 /*---------------------------------------------------------------------------*/
231 /*---------------------------------------------------------------------------*/
232
238 static bool validation(result_type v) { return val == v; }
239
240 /*---------------------------------------------------------------------------*/
241 /*---------------------------------------------------------------------------*/
242
248 bool operator==(const MersenneTwister& rhs) const
249 {
250 // Use a member function; Streamable concept not supported.
251 for (Integer j = 0; j < state_size; ++j)
252 if (compute(j) != rhs.compute(j))
253 return false;
254 return true;
255 }
256
257 /*---------------------------------------------------------------------------*/
258 /*---------------------------------------------------------------------------*/
259
265 bool operator!=(const MersenneTwister& rhs) const
266 {
267 return !(*this == rhs);
268 }
269
270 private:
271
272 /*---------------------------------------------------------------------------*/
273 /*---------------------------------------------------------------------------*/
274
281 // returns x(i-n+index), where index is in 0..n-1
282 UIntType compute(UIntType index) const
283 {
284 // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
285 return x[(i + n + index) % (2 * n)];
286 }
287 void twist(Integer block);
288
289 /*---------------------------------------------------------------------------*/
290 /*---------------------------------------------------------------------------*/
291
292 /* Class pattern members */
293 // state representation: next output is o(x(i))
294 // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
295 // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
296 // The goal is to always have x(i-n) ... x(i-1) available for
297 // operator== and save/restore.
298 UIntType x[2 * n];
299 Integer i;
300};
301
302/*---------------------------------------------------------------------------*/
303/*---------------------------------------------------------------------------*/
304
311template <class UIntType, Integer w, Integer n, Integer m, Integer r, UIntType a, Integer u,
312 Integer s, UIntType b, Integer t, UIntType c, Integer l, UIntType val>
314{
315 const UIntType upper_mask = (~0u) << r;
316 const UIntType lower_mask = ~upper_mask;
317
318 if (block == 0) {
319 for (Integer j = n; j < 2 * n; j++) {
320 UIntType y = (x[j - n] & upper_mask) | (x[j - (n - 1)] & lower_mask);
321 x[j] = x[j - (n - m)] ^ (y >> 1) ^ (y & 1 ? a : 0);
322 }
323 }
324 else if (block == 1) {
325 // split loop to avoid costly modulo operations
326 { // extra scope for MSVC brokenness w.r.t. for scope
327 for (Integer j = 0; j < n - m; j++) {
328 UIntType y = (x[j + n] & upper_mask) | (x[j + n + 1] & lower_mask);
329 x[j] = x[j + n + m] ^ (y >> 1) ^ (y & 1 ? a : 0);
330 }
331 }
332
333 for (Integer j = n - m; j < n - 1; j++) {
334 UIntType y = (x[j + n] & upper_mask) | (x[j + n + 1] & lower_mask);
335 x[j] = x[j - (n - m)] ^ (y >> 1) ^ (y & 1 ? a : 0);
336 }
337 // last iteration
338 UIntType y = (x[2 * n - 1] & upper_mask) | (x[0] & lower_mask);
339 x[n - 1] = x[m - 1] ^ (y >> 1) ^ (y & 1 ? a : 0);
340 i = 0;
341 }
342}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
353template <class UIntType, Integer w, Integer n, Integer m, Integer r, UIntType a, Integer u,
354 Integer s, UIntType b, Integer t, UIntType c, Integer l, UIntType val>
355inline typename MersenneTwister<UIntType, w, n, m, r, a, u, s, b, t, c, l, val>::result_type
357{
358 if (i == n)
359 twist(0);
360 else if (i >= 2 * n)
361 twist(1);
362 // Step 4
363 UIntType z = x[i];
364 ++i;
365 z ^= (z >> u);
366 z ^= ((z << s) & b);
367 z ^= ((z << t) & c);
368 z ^= (z >> l);
369 return z;
370}
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374
375/* Definition of the mt11213b class*/
376typedef MersenneTwister<UInt32, 32, 351, 175, 19, 0xccab8ee7, 11,
377 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92>
378Mt11213b;
379
380/*---------------------------------------------------------------------------*/
381/*---------------------------------------------------------------------------*/
382
383/* Definition of the Mt19937 class*/
384typedef MersenneTwister<UInt32, 32, 624, 397, 31, 0x9908b0df, 11,
385 7, 0x9d2c5680, 15, 0xefc60000, 18, 3346425566U>
386Mt19937;
387
388} // namespace Arcane::random
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
393#endif
MersenneTwister class pattern.
static bool validation(result_type v)
Validation function (I don't really know what it is for!).
MersenneTwister()
Constructor with seed initialization from the seed() method.
MersenneTwister(UIntType value)
Constructor with initialization of the seed array from the value value. The call to the seed(value) m...
bool operator!=(const MersenneTwister &rhs) const
Overriding the != operator.
void seed(UIntType *state)
Initialization of the seed array from the array state. state must be an array of n elements.
void seed(UIntType value)
Initialization of the seed array from the value value. The seed array of this generator consists of n...
MersenneTwister(Generator &gen)
Constructor with initialization of the seed array from the generator gen. gen must contain the () ope...
result_type max() const
max() returns the maximum possible value of a sequence.
void seed(Generator &gen)
Initialization of the seed array from the generator gen. gen is a class that must contain the () oper...
UIntType getState(Integer j)
Method that returns the generator state for index j. The complete state of the generator is given by ...
bool operator==(const MersenneTwister &rhs) const
Overriding the == operator.
void twist(Integer block)
Implementation of the "twist" operation associated with the Mersenne Twister. The generator state is ...
UIntType compute(UIntType index) const
Private method that returns the generator state for index index.
MersenneTwister(It &first, It last)
Constructor with initialization of the seed array from the seed(first,last) method.
void seed()
Initialization of the seed array. The call to the seed(5489) method is performed.
result_type operator()()
Overriding the () operator which returns the pseudo random value of the generator....
result_type min() const
min() returns the minimum possible value of a sequence.
std::uint32_t UInt32
Unsigned integer type of 32 bits.
Int32 Integer
Type representing an integer.