|  | /* | 
|  | * Copyright (c) 2003-2005 The Regents of The University of Michigan | 
|  | * All rights reserved. | 
|  | * | 
|  | * Redistribution and use in source and binary forms, with or without | 
|  | * modification, are permitted provided that the following conditions are | 
|  | * met: redistributions of source code must retain the above copyright | 
|  | * notice, this list of conditions and the following disclaimer; | 
|  | * redistributions in binary form must reproduce the above copyright | 
|  | * notice, this list of conditions and the following disclaimer in the | 
|  | * documentation and/or other materials provided with the distribution; | 
|  | * neither the name of the copyright holders nor the names of its | 
|  | * contributors may be used to endorse or promote products derived from | 
|  | * this software without specific prior written permission. | 
|  | * | 
|  | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | * | 
|  | * Authors: Nathan Binkert | 
|  | *          Ali Saidi | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * Mersenne Twister random number generator has a period of | 
|  | * 2^19937-1. | 
|  | * | 
|  | * The actual math is in its own file to keep the license clear. | 
|  | */ | 
|  |  | 
|  | #ifndef __BASE_RANDOM_HH__ | 
|  | #define __BASE_RANDOM_HH__ | 
|  |  | 
|  | #include <ios> | 
|  | #include <string> | 
|  |  | 
|  | #include "base/types.hh" | 
|  |  | 
|  | class Checkpoint; | 
|  |  | 
|  | class Random | 
|  | { | 
|  | protected: | 
|  | static const int N = 624; | 
|  | static const int M = 397; | 
|  | static const uint32_t MATRIX_A = (uint32_t)0x9908b0df; | 
|  | static const uint32_t UPPER_MASK = (uint32_t)0x80000000; | 
|  | static const uint32_t LOWER_MASK = (uint32_t)0x7fffffff; | 
|  |  | 
|  | uint32_t mt[N]; | 
|  | int mti; | 
|  |  | 
|  | uint32_t genrand(); | 
|  | uint32_t genrand(uint32_t max); | 
|  | uint64_t genrand(uint64_t max); | 
|  |  | 
|  | void | 
|  | _random(int8_t &value) | 
|  | { | 
|  | value = genrand() & (int8_t)-1; | 
|  | } | 
|  |  | 
|  | void | 
|  | _random(int16_t &value) | 
|  | { | 
|  | value = genrand() & (int16_t)-1; | 
|  | } | 
|  |  | 
|  | void | 
|  | _random(int32_t &value) | 
|  | { | 
|  | value = (int32_t)genrand(); | 
|  | } | 
|  |  | 
|  | void | 
|  | _random(int64_t &value) | 
|  | { | 
|  | value = (int64_t)genrand() << 32 | (int64_t)genrand(); | 
|  | } | 
|  |  | 
|  | void | 
|  | _random(uint8_t &value) | 
|  | { | 
|  | value = genrand() & (uint8_t)-1; | 
|  | } | 
|  |  | 
|  | void | 
|  | _random(uint16_t &value) | 
|  | { | 
|  | value = genrand() & (uint16_t)-1; | 
|  | } | 
|  |  | 
|  | void | 
|  | _random(uint32_t &value) | 
|  | { | 
|  | value = genrand(); | 
|  | } | 
|  |  | 
|  | void | 
|  | _random(uint64_t &value) | 
|  | { | 
|  | value = (uint64_t)genrand() << 32 | (uint64_t)genrand(); | 
|  | } | 
|  |  | 
|  | // [0,1] | 
|  | void | 
|  | _random(float &value) | 
|  | { | 
|  | // ieee floats have 23 bits of mantissa | 
|  | value = (genrand() >> 9) / 8388608.0; | 
|  | } | 
|  |  | 
|  | // [0,1] | 
|  | void | 
|  | _random(double &value) | 
|  | { | 
|  | double number = genrand() * 2097152.0 + (genrand() >> 11); | 
|  | value = number / 9007199254740992.0; | 
|  | } | 
|  |  | 
|  |  | 
|  | // Range based versions of the random number generator | 
|  | int8_t | 
|  | _random(int8_t min, int8_t max) | 
|  | { | 
|  | uint32_t diff = max - min; | 
|  | return static_cast<int8_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | int16_t | 
|  | _random(int16_t min, int16_t max) | 
|  | { | 
|  | uint32_t diff = max - min; | 
|  | return static_cast<int16_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | int32_t | 
|  | _random(int32_t min, int32_t max) | 
|  | { | 
|  | uint32_t diff = max - min; | 
|  | return static_cast<int32_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | int64_t | 
|  | _random(int64_t min, int64_t max) | 
|  | { | 
|  | uint64_t diff = max - min; | 
|  | return static_cast<int64_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | uint8_t | 
|  | _random(uint8_t min, uint8_t max) | 
|  | { | 
|  | uint32_t diff = max - min; | 
|  | return static_cast<uint8_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | uint16_t | 
|  | _random(uint16_t min, uint16_t max) | 
|  | { | 
|  | uint32_t diff = max - min; | 
|  | return static_cast<uint16_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | _random(uint32_t min, uint32_t max) | 
|  | { | 
|  | uint32_t diff = max - min; | 
|  | return static_cast<uint32_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | uint64_t | 
|  | _random(uint64_t min, uint64_t max) | 
|  | { | 
|  | uint64_t diff = max - min; | 
|  | return static_cast<uint64_t>(min + genrand(diff)); | 
|  | } | 
|  |  | 
|  | public: | 
|  | Random(); | 
|  | Random(uint32_t s); | 
|  | Random(uint32_t init_key[], int key_length); | 
|  | ~Random(); | 
|  |  | 
|  | void init(uint32_t s); | 
|  | void init(uint32_t init_key[], int key_length); | 
|  |  | 
|  | template <typename T> | 
|  | T | 
|  | random() | 
|  | { | 
|  | T value; | 
|  | _random(value); | 
|  | return value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | T | 
|  | random(T min, T max) | 
|  | { | 
|  | return _random(min, max); | 
|  | } | 
|  |  | 
|  | // [0,1] | 
|  | double | 
|  | gen_real1() | 
|  | { | 
|  | return genrand() / 4294967296.0; | 
|  | } | 
|  |  | 
|  | // [0,1) | 
|  | double | 
|  | gen_real2() | 
|  | { | 
|  | return genrand() / 4294967295.0; | 
|  | } | 
|  |  | 
|  | // (0,1) | 
|  | double | 
|  | gen_real3() | 
|  | { | 
|  | return ((double)genrand() + 0.5) / 4294967296.0; | 
|  | } | 
|  |  | 
|  | public: | 
|  | void serialize(const std::string &base, std::ostream &os); | 
|  | void unserialize(const std::string &base, Checkpoint *cp, | 
|  | const std::string §ion); | 
|  | }; | 
|  |  | 
|  | extern Random random_mt; | 
|  |  | 
|  | #endif // __BASE_RANDOM_HH__ |