gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 1 0
merge default
0 files changed with 1 insertions and 1 deletions:
↑ Collapse diff ↑
Show white space 384 line context
... ...
@@ -65,385 +65,385 @@
65 65
#include <algorithm>
66 66
#include <iterator>
67 67
#include <vector>
68 68

	
69 69
#include <ctime>
70 70
#include <cmath>
71 71

	
72 72
#include <lemon/dim2.h>
73 73
///\ingroup misc
74 74
///\file
75 75
///\brief Mersenne Twister random number generator
76 76

	
77 77
namespace lemon {
78 78

	
79 79
  namespace _random_bits {
80 80
    
81 81
    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
82 82
    struct RandomTraits {};
83 83

	
84 84
    template <typename _Word>
85 85
    struct RandomTraits<_Word, 32> {
86 86

	
87 87
      typedef _Word Word;
88 88
      static const int bits = 32;
89 89

	
90 90
      static const int length = 624;
91 91
      static const int shift = 397;
92 92
      
93 93
      static const Word mul = 0x6c078965u;
94 94
      static const Word arrayInit = 0x012BD6AAu;
95 95
      static const Word arrayMul1 = 0x0019660Du;
96 96
      static const Word arrayMul2 = 0x5D588B65u;
97 97

	
98 98
      static const Word mask = 0x9908B0DFu;
99 99
      static const Word loMask = (1u << 31) - 1;
100 100
      static const Word hiMask = ~loMask;
101 101

	
102 102

	
103 103
      static Word tempering(Word rnd) {
104 104
        rnd ^= (rnd >> 11);
105 105
        rnd ^= (rnd << 7) & 0x9D2C5680u;
106 106
        rnd ^= (rnd << 15) & 0xEFC60000u;
107 107
        rnd ^= (rnd >> 18);
108 108
        return rnd;
109 109
      }
110 110

	
111 111
    };
112 112

	
113 113
    template <typename _Word>
114 114
    struct RandomTraits<_Word, 64> {
115 115

	
116 116
      typedef _Word Word;
117 117
      static const int bits = 64;
118 118

	
119 119
      static const int length = 312;
120 120
      static const int shift = 156;
121 121

	
122 122
      static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
123 123
      static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
124 124
      static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
125 125
      static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
126 126

	
127 127
      static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
128 128
      static const Word loMask = (Word(1u) << 31) - 1;
129 129
      static const Word hiMask = ~loMask;
130 130

	
131 131
      static Word tempering(Word rnd) {
132 132
        rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
133 133
        rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
134 134
        rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
135 135
        rnd ^= (rnd >> 43);
136 136
        return rnd;
137 137
      }
138 138

	
139 139
    };
140 140

	
141 141
    template <typename _Word>
142 142
    class RandomCore {
143 143
    public:
144 144

	
145 145
      typedef _Word Word;
146 146

	
147 147
    private:
148 148

	
149 149
      static const int bits = RandomTraits<Word>::bits;
150 150

	
151 151
      static const int length = RandomTraits<Word>::length;
152 152
      static const int shift = RandomTraits<Word>::shift;
153 153

	
154 154
    public:
155 155

	
156 156
      void initState() {
157 157
        static const Word seedArray[4] = {
158 158
          0x12345u, 0x23456u, 0x34567u, 0x45678u
159 159
        };
160 160
    
161 161
        initState(seedArray, seedArray + 4);
162 162
      }
163 163

	
164 164
      void initState(Word seed) {
165 165

	
166 166
        static const Word mul = RandomTraits<Word>::mul;
167 167

	
168 168
        current = state; 
169 169

	
170 170
        Word *curr = state + length - 1;
171 171
        curr[0] = seed; --curr;
172 172
        for (int i = 1; i < length; ++i) {
173 173
          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
174 174
          --curr;
175 175
        }
176 176
      }
177 177

	
178 178
      template <typename Iterator>
179 179
      void initState(Iterator begin, Iterator end) {
180 180

	
181 181
        static const Word init = RandomTraits<Word>::arrayInit;
182 182
        static const Word mul1 = RandomTraits<Word>::arrayMul1;
183 183
        static const Word mul2 = RandomTraits<Word>::arrayMul2;
184 184

	
185 185

	
186 186
        Word *curr = state + length - 1; --curr;
187 187
        Iterator it = begin; int cnt = 0;
188 188
        int num;
189 189

	
190 190
        initState(init);
191 191

	
192 192
        num = length > end - begin ? length : end - begin;
193 193
        while (num--) {
194 194
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1)) 
195 195
            + *it + cnt;
196 196
          ++it; ++cnt;
197 197
          if (it == end) {
198 198
            it = begin; cnt = 0;
199 199
          }
200 200
          if (curr == state) {
201 201
            curr = state + length - 1; curr[0] = state[0];
202 202
          }
203 203
          --curr;
204 204
        }
205 205

	
206 206
        num = length - 1; cnt = length - (curr - state) - 1;
207 207
        while (num--) {
208 208
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
209 209
            - cnt;
210 210
          --curr; ++cnt;
211 211
          if (curr == state) {
212 212
            curr = state + length - 1; curr[0] = state[0]; --curr;
213 213
            cnt = 1;
214 214
          }
215 215
        }
216 216
        
217 217
        state[length - 1] = Word(1) << (bits - 1);
218 218
      }
219 219
      
220 220
      void copyState(const RandomCore& other) {
221 221
        std::copy(other.state, other.state + length, state);
222 222
        current = state + (other.current - other.state);
223 223
      }
224 224

	
225 225
      Word operator()() {
226 226
        if (current == state) fillState();
227 227
        --current;
228 228
        Word rnd = *current;
229 229
        return RandomTraits<Word>::tempering(rnd);
230 230
      }
231 231

	
232 232
    private:
233 233

	
234 234
  
235 235
      void fillState() {
236 236
        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
237 237
        static const Word loMask = RandomTraits<Word>::loMask;
238 238
        static const Word hiMask = RandomTraits<Word>::hiMask;
239 239

	
240 240
        current = state + length; 
241 241

	
242 242
        register Word *curr = state + length - 1;
243 243
        register long num;
244 244
      
245 245
        num = length - shift;
246 246
        while (num--) {
247 247
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
248 248
            curr[- shift] ^ mask[curr[-1] & 1ul];
249 249
          --curr;
250 250
        }
251 251
        num = shift - 1;
252 252
        while (num--) {
253 253
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
254 254
            curr[length - shift] ^ mask[curr[-1] & 1ul];
255 255
          --curr;
256 256
        }
257
        curr[0] = (((curr[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
257
        state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
258 258
          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
259 259

	
260 260
      }
261 261

	
262 262
  
263 263
      Word *current;
264 264
      Word state[length];
265 265
      
266 266
    };
267 267

	
268 268

	
269 269
    template <typename Result, 
270 270
              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
271 271
    struct Masker {
272 272
      static Result mask(const Result& result) {
273 273
        return Masker<Result, (shift + 1) / 2>::
274 274
          mask(static_cast<Result>(result | (result >> shift)));
275 275
      }
276 276
    };
277 277
    
278 278
    template <typename Result>
279 279
    struct Masker<Result, 1> {
280 280
      static Result mask(const Result& result) {
281 281
        return static_cast<Result>(result | (result >> 1));
282 282
      }
283 283
    };
284 284

	
285 285
    template <typename Result, typename Word, 
286 286
              int rest = std::numeric_limits<Result>::digits, int shift = 0, 
287 287
              bool last = rest <= std::numeric_limits<Word>::digits>
288 288
    struct IntConversion {
289 289
      static const int bits = std::numeric_limits<Word>::digits;
290 290
    
291 291
      static Result convert(RandomCore<Word>& rnd) {
292 292
        return static_cast<Result>(rnd() >> (bits - rest)) << shift;
293 293
      }
294 294
      
295 295
    }; 
296 296

	
297 297
    template <typename Result, typename Word, int rest, int shift> 
298 298
    struct IntConversion<Result, Word, rest, shift, false> {
299 299
      static const int bits = std::numeric_limits<Word>::digits;
300 300

	
301 301
      static Result convert(RandomCore<Word>& rnd) {
302 302
        return (static_cast<Result>(rnd()) << shift) | 
303 303
          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
304 304
      }
305 305
    };
306 306

	
307 307

	
308 308
    template <typename Result, typename Word,
309 309
              bool one_word = (std::numeric_limits<Word>::digits < 
310 310
			       std::numeric_limits<Result>::digits) >
311 311
    struct Mapping {
312 312
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
313 313
        Word max = Word(bound - 1);
314 314
        Result mask = Masker<Result>::mask(bound - 1);
315 315
        Result num;
316 316
        do {
317 317
          num = IntConversion<Result, Word>::convert(rnd) & mask; 
318 318
        } while (num > max);
319 319
        return num;
320 320
      }
321 321
    };
322 322

	
323 323
    template <typename Result, typename Word>
324 324
    struct Mapping<Result, Word, false> {
325 325
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
326 326
        Word max = Word(bound - 1);
327 327
        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
328 328
          ::mask(max);
329 329
        Word num;
330 330
        do {
331 331
          num = rnd() & mask;
332 332
        } while (num > max);
333 333
        return num;
334 334
      }
335 335
    };
336 336

	
337 337
    template <typename Result, int exp, bool pos = (exp >= 0)>
338 338
    struct ShiftMultiplier {
339 339
      static const Result multiplier() {
340 340
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
341 341
        res *= res;
342 342
        if ((exp & 1) == 1) res *= static_cast<Result>(2.0);
343 343
        return res; 
344 344
      }
345 345
    };
346 346

	
347 347
    template <typename Result, int exp>
348 348
    struct ShiftMultiplier<Result, exp, false> {
349 349
      static const Result multiplier() {
350 350
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
351 351
        res *= res;
352 352
        if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
353 353
        return res; 
354 354
      }
355 355
    };
356 356

	
357 357
    template <typename Result>
358 358
    struct ShiftMultiplier<Result, 0, true> {
359 359
      static const Result multiplier() {
360 360
        return static_cast<Result>(1.0); 
361 361
      }
362 362
    };
363 363

	
364 364
    template <typename Result>
365 365
    struct ShiftMultiplier<Result, -20, true> {
366 366
      static const Result multiplier() {
367 367
        return static_cast<Result>(1.0/1048576.0); 
368 368
      }
369 369
    };
370 370
    
371 371
    template <typename Result>
372 372
    struct ShiftMultiplier<Result, -32, true> {
373 373
      static const Result multiplier() {
374 374
        return static_cast<Result>(1.0/424967296.0); 
375 375
      }
376 376
    };
377 377

	
378 378
    template <typename Result>
379 379
    struct ShiftMultiplier<Result, -53, true> {
380 380
      static const Result multiplier() {
381 381
        return static_cast<Result>(1.0/9007199254740992.0); 
382 382
      }
383 383
    };
384 384

	
385 385
    template <typename Result>
386 386
    struct ShiftMultiplier<Result, -64, true> {
387 387
      static const Result multiplier() {
388 388
        return static_cast<Result>(1.0/18446744073709551616.0); 
389 389
      }
390 390
    };
391 391

	
392 392
    template <typename Result, int exp>
393 393
    struct Shifting {
394 394
      static Result shift(const Result& result) {
395 395
        return result * ShiftMultiplier<Result, exp>::multiplier();
396 396
      }
397 397
    };
398 398

	
399 399
    template <typename Result, typename Word,
400 400
              int rest = std::numeric_limits<Result>::digits, int shift = 0, 
401 401
              bool last = rest <= std::numeric_limits<Word>::digits>
402 402
    struct RealConversion{ 
403 403
      static const int bits = std::numeric_limits<Word>::digits;
404 404

	
405 405
      static Result convert(RandomCore<Word>& rnd) {
406 406
        return Shifting<Result, - shift - rest>::
407 407
          shift(static_cast<Result>(rnd() >> (bits - rest)));
408 408
      }
409 409
    };
410 410

	
411 411
    template <typename Result, typename Word, int rest, int shift>
412 412
    struct RealConversion<Result, Word, rest, shift, false> { 
413 413
      static const int bits = std::numeric_limits<Word>::digits;
414 414

	
415 415
      static Result convert(RandomCore<Word>& rnd) {
416 416
        return Shifting<Result, - shift - bits>::
417 417
          shift(static_cast<Result>(rnd())) +
418 418
          RealConversion<Result, Word, rest-bits, shift + bits>::
419 419
          convert(rnd);
420 420
      }
421 421
    };
422 422

	
423 423
    template <typename Result, typename Word>
424 424
    struct Initializer {
425 425

	
426 426
      template <typename Iterator>
427 427
      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
428 428
        std::vector<Word> ws;
429 429
        for (Iterator it = begin; it != end; ++it) {
430 430
          ws.push_back(Word(*it));
431 431
        }
432 432
        rnd.initState(ws.begin(), ws.end());
433 433
      }
434 434

	
435 435
      static void init(RandomCore<Word>& rnd, Result seed) {
436 436
        rnd.initState(seed);
437 437
      }
438 438
    };
439 439

	
440 440
    template <typename Word>
441 441
    struct BoolConversion {
442 442
      static bool convert(RandomCore<Word>& rnd) {
443 443
        return (rnd() & 1) == 1;
444 444
      }
445 445
    };
446 446

	
447 447
    template <typename Word>
448 448
    struct BoolProducer {
449 449
      Word buffer;
0 comments (0 inline)