00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00027
00028
00029
00030
00031
00032
00033
00034 __STXXL_BEGIN_NAMESPACE
00035
00036 extern unsigned ran32State;
00037
00041 struct random_number32
00042 {
00043 typedef unsigned value_type;
00044
00046 inline value_type operator () () const
00047 {
00048 return (ran32State = 1664525 * ran32State + 1013904223);
00049 }
00050 };
00051
00053 inline void srandom_number32(unsigned seed = 0)
00054 {
00055 if (!seed)
00056 seed = get_next_seed();
00057 ran32State = seed;
00058 }
00059
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
00076 inline value_type operator () () const
00077 {
00078 return (state = 1664525 * state + 1013904223);
00079 }
00080 };
00081
00084 struct random_uniform_fast
00085 {
00086 typedef double value_type;
00087 random_number32 rnd32;
00088
00089 random_uniform_fast(unsigned = 0)
00090 { }
00091
00093 inline value_type operator () () const
00094 {
00095 return (double(rnd32()) * (0.5 / 0x80000000));
00096 }
00097 };
00098
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
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
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
00154 inline value_type operator () (value_type N) const
00155 {
00156 return static_cast<value_type>(uniform() * double(N));
00157 }
00158 };
00159
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
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