/*---------------------------------------------------------------------------* * IT++ * *---------------------------------------------------------------------------* * Copyright (c) 1995-2004 by Tony Ottosson, Thomas Eriksson, Pål Frenger, * * Tobias Ringström, and Jonas Samuelsson. * * * * Permission to use, copy, modify, and distribute this software and its * * documentation under the terms of the GNU General Public License is hereby * * granted. No representations are made about the suitability of this * * software for any purpose. It is provided "as is" without expressed or * * implied warranty. See the GNU General Public License for more details. * *---------------------------------------------------------------------------*/ /*! \file \brief Implementation of classes for random number generators. \author Tony Ottosson 1.14 2004/09/23 14:26:13 */ #include #ifdef _MSC_VER # include # define getpid _getpid #else # include #endif #include "base/binary.h" #include "base/matfunc.h" #include "base/scalfunc.h" #include "base/random.h" namespace itpp { int Random_Generator::left = 0; const unsigned int Random_Generator::MAXINT = 0xffffffff; // largest value from randInt() const unsigned int Random_Generator::MAGIC = 0x9908b0dfU; // magic constant unsigned int Random_Generator::state[624]; unsigned int *Random_Generator::pNext; //! Variable used to ensure proper seed initialization static bool __Random_Generator_seed_is_initialized = false; /////////////////////////////////////////////// // Random_Generator /////////////////////////////////////////////// Random_Generator::Random_Generator() { if (!__Random_Generator_seed_is_initialized){ lastSeed = 4357U; reset(); __Random_Generator_seed_is_initialized = true; } } void Random_Generator::randomize() { lastSeed = time(0) * getpid(); // not good enough if randomize is used within a short time-interval reset(); } void Random_Generator::get_state(ivec &out_state) { out_state.set_size(625, false); for (int i=0; i<624; i++) out_state(i) = state[i]; out_state(624) = left; // the number of elements left in state before reload //saved_pNext = pNext; } void Random_Generator::set_state(ivec &new_state) { it_assert(new_state.size()==625, "Random_Generator::set_state(): Not a valid state vector"); for (int i=0; i<624; i++) state[i] = new_state(i); left = new_state(624); pNext = &state[624-left]; } // Set the seed of the Global Random Number Generator void RNG_reset(unsigned long seed) { Random_Generator RNG; RNG.reset(seed); } // Set the seed of the Global Random Number Generator to the same as last time void RNG_reset() { Random_Generator RNG; RNG.reset(); } // Set a random seed for the Global Random Number Generator void RNG_randomize() { Random_Generator RNG; RNG.randomize(); } // Save current full state of generator in memory void RNG_get_state(ivec &state) { Random_Generator RNG; RNG.get_state(state); } // Resume the state saved in memory void RNG_set_state(ivec &state) { Random_Generator RNG; RNG.set_state(state); } /////////////////////////////////////////////// // I_Uniform_RNG /////////////////////////////////////////////// I_Uniform_RNG::I_Uniform_RNG(int min, int max) { setup(min, max); } void I_Uniform_RNG::setup(int min, int max) { if (min <= max) { lo = min; hi = max; } else { lo = max; hi = min; } } void I_Uniform_RNG::get_setup(int &min, int &max) const { min = lo; max = hi; } ivec I_Uniform_RNG::operator()(int n) { ivec vv(n); for (int i=0; i