Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef _GLIBCXX_PARALLEL_RANDOM_NUMBER_H
00033 #define _GLIBCXX_PARALLEL_RANDOM_NUMBER_H 1
00034
00035 #include <parallel/types.h>
00036 #include <tr1/random>
00037 #include <limits>
00038
00039 namespace __gnu_parallel
00040 {
00041
00042 class _RandomNumber
00043 {
00044 private:
00045 std::tr1::mt19937 _M_mt;
00046 uint64_t _M_supremum;
00047 uint64_t _M_rand_sup;
00048 double _M_supremum_reciprocal;
00049 double _M_rand_sup_reciprocal;
00050
00051
00052 uint64_t __cache;
00053
00054
00055 int __bits_left;
00056
00057 static uint32_t
00058 __scale_down(uint64_t __x,
00059 #if _GLIBCXX_SCALE_DOWN_FPU
00060 uint64_t , double _M_supremum_reciprocal)
00061 #else
00062 uint64_t _M_supremum, double )
00063 #endif
00064 {
00065 #if _GLIBCXX_SCALE_DOWN_FPU
00066 return uint32_t(__x * _M_supremum_reciprocal);
00067 #else
00068 return static_cast<uint32_t>(__x % _M_supremum);
00069 #endif
00070 }
00071
00072 public:
00073
00074 _RandomNumber()
00075 : _M_mt(0), _M_supremum(0x100000000ULL),
00076 _M_rand_sup(1ULL << std::numeric_limits<uint32_t>::digits),
00077 _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)),
00078 _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)),
00079 __cache(0), __bits_left(0) { }
00080
00081
00082
00083
00084
00085 _RandomNumber(uint32_t __seed, uint64_t _M_supremum = 0x100000000ULL)
00086 : _M_mt(__seed), _M_supremum(_M_supremum),
00087 _M_rand_sup(1ULL << std::numeric_limits<uint32_t>::digits),
00088 _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)),
00089 _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)),
00090 __cache(0), __bits_left(0) { }
00091
00092
00093 uint32_t
00094 operator()()
00095 { return __scale_down(_M_mt(), _M_supremum, _M_supremum_reciprocal); }
00096
00097
00098
00099 uint32_t
00100 operator()(uint64_t local_supremum)
00101 {
00102 return __scale_down(_M_mt(), local_supremum,
00103 double(local_supremum * _M_rand_sup_reciprocal));
00104 }
00105
00106
00107
00108 unsigned long
00109 __genrand_bits(int __bits)
00110 {
00111 unsigned long __res = __cache & ((1 << __bits) - 1);
00112 __cache = __cache >> __bits;
00113 __bits_left -= __bits;
00114 if (__bits_left < 32)
00115 {
00116 __cache |= ((uint64_t(_M_mt())) << __bits_left);
00117 __bits_left += 32;
00118 }
00119 return __res;
00120 }
00121 };
00122
00123 }
00124
00125 #endif