Stxxl  1.4.0
include/stxxl/bits/common/rand.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  include/stxxl/bits/common/rand.h
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2002, 2003, 2005 Roman Dementiev <dementiev@mpi-sb.mpg.de>
00007  *  Copyright (C) 2007 Andreas Beckmann <beckmann@mpi-inf.mpg.de>
00008  *
00009  *  Distributed under the Boost Software License, Version 1.0.
00010  *  (See accompanying file LICENSE_1_0.txt or copy at
00011  *  http://www.boost.org/LICENSE_1_0.txt)
00012  **************************************************************************/
00013 
00014 #ifndef STXXL_RAND_HEADER
00015 #define STXXL_RAND_HEADER
00016 
00017 #include <cstdlib>
00018 
00019 #ifdef STXXL_BOOST_RANDOM
00020  #include <boost/random.hpp>
00021 #endif
00022 
00023 #include <stxxl/bits/common/types.h>
00024 #include <stxxl/bits/common/seed.h>
00025 
00026 // Recommended seeding procedure:
00027 // by default, the global seed is initialized from a high resolution timer and the process id
00028 // 1. stxxl::set_seed(seed); // optionally, do this if you wan't to us a specific seed to replay a certain program run
00029 // 2. seed = stxxl::get_next_seed(); // store/print/... this value can be used for step 1 to replay the program with a specific seed
00030 // 3. stxxl::srandom_number32(); // seed the global state of stxxl::random_number32
00031 // 4. create all the other prngs used.
00032 
00033 
00034 __STXXL_BEGIN_NAMESPACE
00035 
00036 extern unsigned ran32State;
00037 
00038 //! \brief Fast uniform [0, 2^32) pseudo-random generator
00039 //!        with period 2^32, random bits: 32.
00040 //! \warning Uses a global state and is not reentrant or thread-safe!
00041 struct random_number32
00042 {
00043     typedef unsigned value_type;
00044 
00045     //! \brief Returns a random number from [0, 2^32)
00046     inline value_type operator () () const
00047     {
00048         return (ran32State = 1664525 * ran32State + 1013904223);
00049     }
00050 };
00051 
00052 //! \brief Set a seed value for \c random_number32.
00053 inline void srandom_number32(unsigned seed = 0)
00054 {
00055     if (!seed)
00056         seed = get_next_seed();
00057     ran32State = seed;
00058 }
00059 
00060 //! \brief Fast uniform [0, 2^32) pseudo-random generator
00061 //!        with period 2^32, random bits: 32.
00062 //! Reentrant variant of random_number32 that keeps it's private state.
00063 struct random_number32_r
00064 {
00065     typedef unsigned value_type;
00066     mutable unsigned state;
00067 
00068     random_number32_r(unsigned seed = 0)
00069     {
00070         if (!seed)
00071             seed = get_next_seed();
00072         state = seed;
00073     }
00074 
00075     //! \brief Returns a random number from [0, 2^32)
00076     inline value_type operator () () const
00077     {
00078         return (state = 1664525 * state + 1013904223);
00079     }
00080 };
00081 
00082 //! \brief Fast uniform [0.0, 1.0) pseudo-random generator
00083 //! \warning Uses a global state and is not reentrant or thread-safe!
00084 struct random_uniform_fast
00085 {
00086     typedef double value_type;
00087     random_number32 rnd32;
00088 
00089     random_uniform_fast(unsigned /*seed*/ = 0)
00090     { }
00091 
00092     //! \brief Returns a random number from [0.0, 1.0)
00093     inline value_type operator () () const
00094     {
00095         return (double(rnd32()) * (0.5 / 0x80000000));
00096     }
00097 };
00098 
00099 //! \brief Slow and precise uniform [0.0, 1.0) pseudo-random generator
00100 //!        period: at least 2^48, random bits: at least 31
00101 //!
00102 //! \warning Seed is not the same as in the fast generator \c random_uniform_fast
00103 struct random_uniform_slow
00104 {
00105     typedef double value_type;
00106 #ifdef STXXL_BOOST_RANDOM
00107     typedef boost::minstd_rand base_generator_type;
00108     base_generator_type generator;
00109     boost::uniform_real<> uni_dist;
00110     mutable boost::variate_generator<base_generator_type &, boost::uniform_real<> > uni;
00111 
00112     random_uniform_slow(unsigned seed = 0) : uni(generator, uni_dist)
00113     {
00114         if (!seed)
00115             seed = get_next_seed();
00116         uni.engine().seed(seed);
00117     }
00118 #else
00119     mutable unsigned short state48[3];
00120 
00121     random_uniform_slow(unsigned seed = 0)
00122     {
00123         if (!seed)
00124             seed = get_next_seed();
00125         state48[0] = seed & 0xffff;
00126         state48[1] = seed >> 16;
00127         state48[2] = 42;
00128         erand48(state48);
00129     }
00130 #endif
00131 
00132     //! \brief Returns a random number from [0.0, 1.0)
00133     inline value_type operator () () const
00134     {
00135 #ifdef STXXL_BOOST_RANDOM
00136         return uni();
00137 #else
00138         return erand48(state48);
00139 #endif
00140     }
00141 };
00142 
00143 //! \brief Uniform [0, N) pseudo-random generator
00144 template <class UniformRGen_ = random_uniform_fast>
00145 struct random_number
00146 {
00147     typedef unsigned value_type;
00148     UniformRGen_ uniform;
00149 
00150     random_number(unsigned seed = 0) : uniform(seed)
00151     { }
00152 
00153     //! \brief Returns a random number from [0, N)
00154     inline value_type operator () (value_type N) const
00155     {
00156         return static_cast<value_type>(uniform() * double(N));
00157     }
00158 };
00159 
00160 //! \brief Slow and precise uniform [0, 2^64) pseudo-random generator
00161 struct random_number64
00162 {
00163     typedef stxxl::uint64 value_type;
00164     random_uniform_slow uniform;
00165 
00166     random_number64(unsigned seed = 0) : uniform(seed)
00167     { }
00168 
00169     //! \brief Returns a random number from [0, 2^64)
00170     inline value_type operator () () const
00171     {
00172         return static_cast<value_type>(uniform() * (18446744073709551616.));
00173     }
00174 };
00175 
00176 __STXXL_END_NAMESPACE
00177 
00178 #endif // !STXXL_RAND_HEADER
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines