Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MersenneTwister.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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-2006 */
9/* */
10/* Ce fichier definit le patron de classe MersenneTwister ainsi que deux */
11/* classes associees mt19937 et mt11213b. Il est une version adapte a TROLL */
12/* du fichier MersenneTwister.hpp provenant de la bibliotheque BOOST */
13/*---------------------------------------------------------------------------*/
14/*---------------------------------------------------------------------------*/
15#ifndef ARCANE_RANDOM_MERSENNE_TWISTER_H
16#define ARCANE_RANDOM_MERSENNE_TWISTER_H
17/*---------------------------------------------------------------------------*/
18/*---------------------------------------------------------------------------*/
19
20#include "arcane/utils/FatalErrorException.h"
21
22#include "arcane/random/RandomGlobal.h"
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27ARCANE_BEGIN_NAMESPACE
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32RANDOM_BEGIN_NAMESPACE
33
43template<class UIntType, Integer w, Integer n, Integer m, Integer r, UIntType a, Integer u,
44 Integer s, UIntType b, Integer t, UIntType c, Integer l, UIntType val>
46{
47public:
48 typedef UIntType result_type;
49 static const Integer word_size = w;
50 static const Integer state_size = n;
51 static const Integer shift_size = m;
52 static const Integer mask_bits = r;
53 static const UIntType parameter_a = a;
54 static const Integer output_u = u;
55 static const Integer output_s = s;
56 static const UIntType output_b = b;
57 static const Integer output_t = t;
58 static const UIntType output_c = c;
59 static const Integer output_l = l;
60
61 static const bool has_fixed_range = false;
62 /*---------------------------------------------------------------------------*/
63 /*---------------------------------------------------------------------------*/
70 MersenneTwister() { seed(); }
71 /*---------------------------------------------------------------------------*/
72 /*---------------------------------------------------------------------------*/
79 explicit MersenneTwister(UIntType value)
80 { seed(value); }
81 /*---------------------------------------------------------------------------*/
82 /*---------------------------------------------------------------------------*/
89 template<class It> MersenneTwister(It& first, It last) { seed(first,last); }
90 /*---------------------------------------------------------------------------*/
91 /*---------------------------------------------------------------------------*/
99 template<class Generator>
100 explicit MersenneTwister(Generator & gen) { seed(gen); }
101
102 /*---------------------------------------------------------------------------*/
103 /*---------------------------------------------------------------------------*/
110 void seed() { seed(UIntType(5489)); }
111 /*---------------------------------------------------------------------------*/
112 /*---------------------------------------------------------------------------*/
119 void seed(UIntType value)
120 {
121 // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
122 const UIntType mask = ~0u;
123 x[0] = value & mask;
124 for (i = 1; i < n; i++) {
125 // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
126 x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
127 }
128 }
129 /*---------------------------------------------------------------------------*/
130 /*---------------------------------------------------------------------------*/
137 void seed(UIntType * state)
138 { for (Integer i=0;i<n;i++) x[i] = state[i];}
139 /*---------------------------------------------------------------------------*/
140 /*---------------------------------------------------------------------------*/
148 template<class Generator>
150 {
151 // For GCC, moving this function out-of-line prevents inlining, which may
152 // reduce overall object code size. However, MSVC does not grok
153 // out-of-line definitions of member function templates.
154 for(Integer j = 0; j < n; j++)
155 x[j] = gen();
156 i = n;
157 }
158 /*---------------------------------------------------------------------------*/
159 /*---------------------------------------------------------------------------*/
168 {
169 return x[j];
170 }
171 /*---------------------------------------------------------------------------*/
172 /*---------------------------------------------------------------------------*/
178 result_type min() const { return 0; }
179 /*---------------------------------------------------------------------------*/
180 /*---------------------------------------------------------------------------*/
187 {
188 // avoid "left shift count >= with of type" warning
189 result_type res = 0;
190 for(Integer i = 0; i < w; ++i)
191 res |= (1u << i);
192 return res;
193 }
194 /*---------------------------------------------------------------------------*/
195 /*---------------------------------------------------------------------------*/
196 /* déclaration de l'opérateur () */
197 result_type operator()();
198 /*---------------------------------------------------------------------------*/
199 /*---------------------------------------------------------------------------*/
205 static bool validation(result_type v) { return val == v; }
206 /*---------------------------------------------------------------------------*/
207 /*---------------------------------------------------------------------------*/
213 bool operator==(const MersenneTwister& rhs) const
214 {
215 // Use a member function; Streamable concept not supported.
216 for(Integer j = 0; j < state_size; ++j)
217 if(compute(j) != rhs.compute(j))
218 return false;
219 return true;
220 }
221 /*---------------------------------------------------------------------------*/
222 /*---------------------------------------------------------------------------*/
228 bool operator!=(const MersenneTwister& rhs) const
229 { return !(*this == rhs); }
230
231private:
232 /*---------------------------------------------------------------------------*/
233 /*---------------------------------------------------------------------------*/
240 // returns x(i-n+index), where index is in 0..n-1
242 {
243 // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
244 return x[ (i + n + index) % (2*n) ];
245 }
246 void twist(Integer block);
247 /*---------------------------------------------------------------------------*/
248 /*---------------------------------------------------------------------------*/
249 /* Membres du patron de classe */
250 // state representation: next output is o(x(i))
251 // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
252 // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
253 // The goal is to always have x(i-n) ... x(i-1) available for
254 // operator== and save/restore.
255 UIntType x[2*n];
256 Integer i;
257};
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
267template<class UIntType, Integer w, Integer n, Integer m, Integer r, UIntType a, Integer u,
268 Integer s, UIntType b, Integer t, UIntType c, Integer l, UIntType val>
270{
271 const UIntType upper_mask = (~0u) << r;
273
274 if(block == 0) {
275 for(Integer j = n; j < 2*n; j++) {
276 UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
277 x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
278 }
279 } else if (block == 1) {
280 // split loop to avoid costly modulo operations
281 { // extra scope for MSVC brokenness w.r.t. for scope
282 for(Integer j = 0; j < n-m; j++) {
283 UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
284 x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
285 }
286 }
287
288 for(Integer j = n-m; j < n-1; j++) {
289 UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
290 x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
291 }
292 // last iteration
293 UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
294 x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
295 i = 0;
296 }
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
307template<class UIntType, Integer w, Integer n, Integer m, Integer r, UIntType a, Integer u,
308 Integer s, UIntType b, Integer t, UIntType c, Integer l, UIntType val>
311{
312 if(i == n)
313 twist(0);
314 else if(i >= 2*n)
315 twist(1);
316 // Step 4
317 UIntType z = x[i];
318 ++i;
319 z ^= (z >> u);
320 z ^= ((z << s) & b);
321 z ^= ((z << t) & c);
322 z ^= (z >> l);
323 return z;
324}
325
326/*---------------------------------------------------------------------------*/
327/*---------------------------------------------------------------------------*/
328/* Définition de la classe mt11213b*/
329typedef MersenneTwister<UInt32,32,351,175,19,0xccab8ee7,11,
330 7,0x31b6ab00,15,0xffe50000,17, 0xa37d3c92> Mt11213b;
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
333/* Définition de la classe Mt19937*/
334typedef MersenneTwister<UInt32,32,624,397,31,0x9908b0df,11,
335 7,0x9d2c5680,15,0xefc60000,18, 3346425566U> Mt19937;
336
337RANDOM_END_NAMESPACE
338ARCANE_END_NAMESPACE
339
340
341#endif // ARCANE_RANDOM_MERSENNE_TWISTER_H
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
MersenneTwister(UIntType value)
Constructeur avec initialisation du tableau de graines à partir de la valeur value....
UIntType compute(UIntType index) const
Méthode privée qui retourne l'état du générateur pour l'index index.
MersenneTwister(It &first, It last)
Constructeur avec initialisation du tableau de graines à partir de la méthode seed(first,...
result_type min() const
min() retourne la valeur minimum possible d'une séquence.
MersenneTwister()
Constructeur avec initialisation de la graine à partir de la méthode seed()
bool operator!=(const MersenneTwister &rhs) const
Surdéfinition de l'opérateur !=.
bool operator==(const MersenneTwister &rhs) const
Surdéfinition de l'opérateur ==.
result_type max() const
max() retourne la valeur maximum possible d'une séquence.
void seed()
Initialisation du tableau de graines. L'appel à la méthode seed(5489) est réalisé.
MersenneTwister(Generator &gen)
Constructeur avec initialisation du tableau de graines à partir du générateur gen....
UIntType getState(Integer j)
Méthode qui retourne l'état du générateur pour l'index j. L'état complet du générateur est donnée par...
void seed(UIntType *state)
Initialisation du tableau de graines à partir du tableau state. state doit être un tableau de n éléme...
void seed(Generator &gen)
Initialisation du tableau de graines à partir du générateur gen. gen est une classe qui doit contenir...
static bool validation(result_type v)
Fonction de validation (je ne sais pas trop a quoi elle sert!)
void seed(UIntType value)
Initialisation du tableau de graines à partir de la valeur value. Le tableau de graines de ce générat...
Int32 Integer
Type représentant un entier.