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