| 1 | //  (C) Copyright John Maddock 2005. | 
|---|
| 2 | //  (C) Copyright Henry S. Warren 2005. | 
|---|
| 3 | //  Use, modification and distribution are subject to the | 
|---|
| 4 | //  Boost Software License, Version 1.0. (See accompanying file | 
|---|
| 5 | //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 
|---|
| 6 |  | 
|---|
| 7 | #ifndef BOOST_TR1_RANDOM_HPP_INCLUDED | 
|---|
| 8 | #  define BOOST_TR1_RANDOM_HPP_INCLUDED | 
|---|
| 9 | #  include <boost/tr1/detail/config.hpp> | 
|---|
| 10 |  | 
|---|
| 11 | #ifdef BOOST_HAS_TR1_RANDOM | 
|---|
| 12 | #  include BOOST_TR1_HEADER(random) | 
|---|
| 13 | #else | 
|---|
| 14 | // Boost.Random: | 
|---|
| 15 | #include <boost/random.hpp> | 
|---|
| 16 | #ifndef __SUNPRO_CC | 
|---|
| 17 |     // Sunpros linker complains if we so much as include this... | 
|---|
| 18 | #   include <boost/nondet_random.hpp> | 
|---|
| 19 | #endif | 
|---|
| 20 | #include <boost/tr1/detail/functor2iterator.hpp> | 
|---|
| 21 | #include <boost/type_traits/is_fundamental.hpp> | 
|---|
| 22 | #include <boost/type_traits/is_same.hpp> | 
|---|
| 23 |  | 
|---|
| 24 | namespace std { namespace tr1{ | 
|---|
| 25 |  | 
|---|
| 26 | using ::boost::variate_generator; | 
|---|
| 27 |  | 
|---|
| 28 | template<class UIntType, UIntType a, UIntType c, UIntType m> | 
|---|
| 29 | class linear_congruential | 
|---|
| 30 | { | 
|---|
| 31 | private: | 
|---|
| 32 |    typedef ::boost::random::linear_congruential<UIntType, a, c, m, 0> impl_type; | 
|---|
| 33 | public: | 
|---|
| 34 |    // types | 
|---|
| 35 |    typedef UIntType result_type; | 
|---|
| 36 |    // parameter values | 
|---|
| 37 |    BOOST_STATIC_CONSTANT(UIntType, multiplier = a); | 
|---|
| 38 |    BOOST_STATIC_CONSTANT(UIntType, increment = c); | 
|---|
| 39 |    BOOST_STATIC_CONSTANT(UIntType, modulus = m); | 
|---|
| 40 |    // constructors and member function | 
|---|
| 41 |    explicit linear_congruential(unsigned long x0 = 1) | 
|---|
| 42 |       : m_gen(x0){} | 
|---|
| 43 |    linear_congruential(const linear_congruential& that) | 
|---|
| 44 |       : m_gen(that.m_gen){} | 
|---|
| 45 |    template<class Gen> linear_congruential(Gen& g) | 
|---|
| 46 |    { | 
|---|
| 47 |       init1(g, ::boost::is_same<Gen,linear_congruential>()); | 
|---|
| 48 |    } | 
|---|
| 49 |    void seed(unsigned long x0 = 1) | 
|---|
| 50 |    { m_gen.seed(x0); } | 
|---|
| 51 |    template<class Gen> void seed(Gen& g) | 
|---|
| 52 |    {  | 
|---|
| 53 |       init2(g, ::boost::is_fundamental<Gen>()); | 
|---|
| 54 |    } | 
|---|
| 55 |    result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 56 |    { return (m_gen.min)(); } | 
|---|
| 57 |    result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 58 |    { return (m_gen.max)(); } | 
|---|
| 59 |    result_type operator()() | 
|---|
| 60 |    { | 
|---|
| 61 |       return m_gen();  | 
|---|
| 62 |    } | 
|---|
| 63 |    bool operator==(const linear_congruential& that)const | 
|---|
| 64 |    { return m_gen == that.m_gen; } | 
|---|
| 65 |    bool operator!=(const linear_congruential& that)const | 
|---|
| 66 |    { return m_gen != that.m_gen; } | 
|---|
| 67 |  | 
|---|
| 68 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | 
|---|
| 69 |   template<class CharT, class Traits> | 
|---|
| 70 |   friend std::basic_ostream<CharT,Traits>& | 
|---|
| 71 |   operator<<(std::basic_ostream<CharT,Traits>& os, | 
|---|
| 72 |              const linear_congruential& lcg) | 
|---|
| 73 |   { | 
|---|
| 74 |     return os << lcg.m_gen;  | 
|---|
| 75 |   } | 
|---|
| 76 |  | 
|---|
| 77 |   template<class CharT, class Traits> | 
|---|
| 78 |   friend std::basic_istream<CharT,Traits>& | 
|---|
| 79 |   operator>>(std::basic_istream<CharT,Traits>& is, | 
|---|
| 80 |              linear_congruential& lcg) | 
|---|
| 81 |   { | 
|---|
| 82 |     return is >> lcg.m_gen; | 
|---|
| 83 |   } | 
|---|
| 84 | #endif | 
|---|
| 85 |  | 
|---|
| 86 | private: | 
|---|
| 87 |    template <class Gen> | 
|---|
| 88 |    void init1(Gen& g, const ::boost::true_type&) | 
|---|
| 89 |    { | 
|---|
| 90 |       m_gen = g.m_gen; | 
|---|
| 91 |    } | 
|---|
| 92 |    template <class Gen> | 
|---|
| 93 |    void init1(Gen& g, const ::boost::false_type&) | 
|---|
| 94 |    { | 
|---|
| 95 |       init2(g, ::boost::is_fundamental<Gen>()); | 
|---|
| 96 |    } | 
|---|
| 97 |    template <class Gen> | 
|---|
| 98 |    void init2(Gen& g, const ::boost::true_type&) | 
|---|
| 99 |    { | 
|---|
| 100 |       m_gen.seed(static_cast<unsigned long>(g)); | 
|---|
| 101 |    } | 
|---|
| 102 |    template <class Gen> | 
|---|
| 103 |    void init2(Gen& g, const ::boost::false_type&) | 
|---|
| 104 |    { | 
|---|
| 105 |       //typedef typename Gen::result_type gen_rt; | 
|---|
| 106 |       boost::tr1_details::functor2iterator<Gen, unsigned long> f1(g), f2; | 
|---|
| 107 |       m_gen.seed(f1, f2); | 
|---|
| 108 |    } | 
|---|
| 109 |    impl_type m_gen; | 
|---|
| 110 | }; | 
|---|
| 111 |  | 
|---|
| 112 | template<class UIntType, int w, int n, int m, int r, | 
|---|
| 113 | UIntType a, int u, int s, UIntType b, int t, UIntType c, int l> | 
|---|
| 114 | class mersenne_twister | 
|---|
| 115 | { | 
|---|
| 116 |    typedef ::boost::random::mersenne_twister | 
|---|
| 117 |       <UIntType, w, n, m, r, a, u, s, b, t, c, l, 0> imp_type; | 
|---|
| 118 | public: | 
|---|
| 119 |    // types | 
|---|
| 120 |    typedef UIntType result_type; | 
|---|
| 121 |    // parameter values | 
|---|
| 122 |    BOOST_STATIC_CONSTANT(int, word_size = w); | 
|---|
| 123 |    BOOST_STATIC_CONSTANT(int, state_size = n); | 
|---|
| 124 |    BOOST_STATIC_CONSTANT(int, shift_size = m); | 
|---|
| 125 |    BOOST_STATIC_CONSTANT(int, mask_bits = r); | 
|---|
| 126 |    BOOST_STATIC_CONSTANT(UIntType, parameter_a = a); | 
|---|
| 127 |    BOOST_STATIC_CONSTANT(int, output_u = u); | 
|---|
| 128 |    BOOST_STATIC_CONSTANT(int, output_s = s); | 
|---|
| 129 |    BOOST_STATIC_CONSTANT(UIntType, output_b = b); | 
|---|
| 130 |    BOOST_STATIC_CONSTANT(int, output_t = t); | 
|---|
| 131 |    BOOST_STATIC_CONSTANT(UIntType, output_c = c); | 
|---|
| 132 |    BOOST_STATIC_CONSTANT(int, output_l = l); | 
|---|
| 133 |    // constructors and member function | 
|---|
| 134 |    mersenne_twister(){} | 
|---|
| 135 |    explicit mersenne_twister(unsigned long value) | 
|---|
| 136 |       : m_gen(value == 0 ? 4357UL : value){} | 
|---|
| 137 |    template<class Gen> mersenne_twister(Gen& g) | 
|---|
| 138 |    { | 
|---|
| 139 |       init1(g, ::boost::is_same<mersenne_twister,Gen>()); | 
|---|
| 140 |    } | 
|---|
| 141 |    void seed() | 
|---|
| 142 |    { m_gen.seed(); } | 
|---|
| 143 |    void seed(unsigned long value) | 
|---|
| 144 |    { m_gen.seed(value == 0 ? 5489UL : value); } | 
|---|
| 145 |    template<class Gen> void seed(Gen& g) | 
|---|
| 146 |    { init2(g, ::boost::is_fundamental<Gen>()); } | 
|---|
| 147 |    result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 148 |    { return (m_gen.min)(); } | 
|---|
| 149 |    result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 150 |    { return (m_gen.max)(); } | 
|---|
| 151 |    result_type operator()() | 
|---|
| 152 |    { return m_gen(); } | 
|---|
| 153 |    bool operator==(const mersenne_twister& that)const | 
|---|
| 154 |    { return m_gen == that.m_gen; } | 
|---|
| 155 |    bool operator!=(const mersenne_twister& that)const | 
|---|
| 156 |    { return m_gen != that.m_gen; } | 
|---|
| 157 |  | 
|---|
| 158 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | 
|---|
| 159 |    template<class CharT, class Traits> | 
|---|
| 160 |    friend std::basic_ostream<CharT,Traits>& | 
|---|
| 161 |    operator<<(std::basic_ostream<CharT,Traits>& os, | 
|---|
| 162 |             const mersenne_twister& lcg) | 
|---|
| 163 |    { | 
|---|
| 164 |       return os << lcg.m_gen; | 
|---|
| 165 |    } | 
|---|
| 166 |  | 
|---|
| 167 |    template<class CharT, class Traits> | 
|---|
| 168 |    friend std::basic_istream<CharT,Traits>& | 
|---|
| 169 |    operator>>(std::basic_istream<CharT,Traits>& is, | 
|---|
| 170 |             mersenne_twister& lcg) | 
|---|
| 171 |    { | 
|---|
| 172 |       return is >> lcg.m_gen; | 
|---|
| 173 |    } | 
|---|
| 174 | #endif | 
|---|
| 175 | private: | 
|---|
| 176 |    template <class Gen> | 
|---|
| 177 |    void init1(Gen& g, const ::boost::true_type&) | 
|---|
| 178 |    { | 
|---|
| 179 |       m_gen = g.m_gen; | 
|---|
| 180 |    } | 
|---|
| 181 |    template <class Gen> | 
|---|
| 182 |    void init1(Gen& g, const ::boost::false_type&) | 
|---|
| 183 |    { | 
|---|
| 184 |       init2(g, ::boost::is_fundamental<Gen>()); | 
|---|
| 185 |    } | 
|---|
| 186 |    template <class Gen> | 
|---|
| 187 |    void init2(Gen& g, const ::boost::true_type&) | 
|---|
| 188 |    { | 
|---|
| 189 |       m_gen.seed(static_cast<unsigned long>(g == 0 ? 4357UL : g)); | 
|---|
| 190 |    } | 
|---|
| 191 |    template <class Gen> | 
|---|
| 192 |    void init2(Gen& g, const ::boost::false_type&) | 
|---|
| 193 |    { | 
|---|
| 194 |       m_gen.seed(g); | 
|---|
| 195 |    } | 
|---|
| 196 |    imp_type m_gen; | 
|---|
| 197 | }; | 
|---|
| 198 |  | 
|---|
| 199 | template<class IntType, IntType m, int s, int r> | 
|---|
| 200 | class subtract_with_carry | 
|---|
| 201 | { | 
|---|
| 202 | public: | 
|---|
| 203 |    // types | 
|---|
| 204 |    typedef IntType result_type; | 
|---|
| 205 |    // parameter values | 
|---|
| 206 |    BOOST_STATIC_CONSTANT(IntType, modulus = m); | 
|---|
| 207 |    BOOST_STATIC_CONSTANT(int, long_lag = r); | 
|---|
| 208 |    BOOST_STATIC_CONSTANT(int, short_lag = s); | 
|---|
| 209 |  | 
|---|
| 210 |    // constructors and member function | 
|---|
| 211 |    subtract_with_carry(){} | 
|---|
| 212 |    explicit subtract_with_carry(unsigned long value) | 
|---|
| 213 |       : m_gen(value == 0 ? 19780503UL : value){} | 
|---|
| 214 |    template<class Gen> subtract_with_carry(Gen& g) | 
|---|
| 215 |    { init1(g, ::boost::is_same<Gen, subtract_with_carry<IntType, m, s, r> >()); } | 
|---|
| 216 |    void seed(unsigned long value = 19780503ul) | 
|---|
| 217 |    { m_gen.seed(value == 0 ? 19780503UL : value); } | 
|---|
| 218 |    template<class Gen> void seed(Gen& g) | 
|---|
| 219 |    { init2(g, ::boost::is_fundamental<Gen>()); } | 
|---|
| 220 |    result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 221 |    { return (m_gen.min)(); } | 
|---|
| 222 |    result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 223 |    { return (m_gen.max)(); } | 
|---|
| 224 |    result_type operator()() | 
|---|
| 225 |    { return m_gen(); } | 
|---|
| 226 |    bool operator==(const subtract_with_carry& that)const | 
|---|
| 227 |    { return m_gen == that.m_gen; } | 
|---|
| 228 |    bool operator!=(const subtract_with_carry& that)const | 
|---|
| 229 |    { return m_gen != that.m_gen; } | 
|---|
| 230 |  | 
|---|
| 231 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | 
|---|
| 232 |    template<class CharT, class Traits> | 
|---|
| 233 |    friend std::basic_ostream<CharT,Traits>& | 
|---|
| 234 |    operator<<(std::basic_ostream<CharT,Traits>& os, | 
|---|
| 235 |             const subtract_with_carry& lcg) | 
|---|
| 236 |    { | 
|---|
| 237 |       return os << lcg.m_gen; | 
|---|
| 238 |    } | 
|---|
| 239 |  | 
|---|
| 240 |    template<class CharT, class Traits> | 
|---|
| 241 |    friend std::basic_istream<CharT,Traits>& | 
|---|
| 242 |    operator>>(std::basic_istream<CharT,Traits>& is, | 
|---|
| 243 |             subtract_with_carry& lcg) | 
|---|
| 244 |    { | 
|---|
| 245 |       return is >> lcg.m_gen; | 
|---|
| 246 |    } | 
|---|
| 247 | #endif | 
|---|
| 248 | private: | 
|---|
| 249 |    template <class Gen> | 
|---|
| 250 |    void init1(Gen& g, const ::boost::true_type&) | 
|---|
| 251 |    { | 
|---|
| 252 |       m_gen = g.m_gen; | 
|---|
| 253 |    } | 
|---|
| 254 |    template <class Gen> | 
|---|
| 255 |    void init1(Gen& g, const ::boost::false_type&) | 
|---|
| 256 |    { | 
|---|
| 257 |       init2(g, ::boost::is_fundamental<Gen>()); | 
|---|
| 258 |    } | 
|---|
| 259 |    template <class Gen> | 
|---|
| 260 |    void init2(Gen& g, const ::boost::true_type&) | 
|---|
| 261 |    { | 
|---|
| 262 |       m_gen.seed(static_cast<unsigned long>(g == 0 ? 19780503UL : g)); | 
|---|
| 263 |    } | 
|---|
| 264 |    template <class Gen> | 
|---|
| 265 |    void init2(Gen& g, const ::boost::false_type&) | 
|---|
| 266 |    { | 
|---|
| 267 |       m_gen.seed(g); | 
|---|
| 268 |    } | 
|---|
| 269 |    ::boost::random::subtract_with_carry<IntType, m, s, r, 0> m_gen; | 
|---|
| 270 | }; | 
|---|
| 271 |  | 
|---|
| 272 | template<class RealType, int w, int s, int r> | 
|---|
| 273 | class subtract_with_carry_01 | 
|---|
| 274 | { | 
|---|
| 275 | public: | 
|---|
| 276 |    // types | 
|---|
| 277 |    typedef RealType result_type; | 
|---|
| 278 |    // parameter values | 
|---|
| 279 |    BOOST_STATIC_CONSTANT(int, word_size = w); | 
|---|
| 280 |    BOOST_STATIC_CONSTANT(int, long_lag = r); | 
|---|
| 281 |    BOOST_STATIC_CONSTANT(int, short_lag = s); | 
|---|
| 282 |  | 
|---|
| 283 |    // constructors and member function | 
|---|
| 284 |    subtract_with_carry_01(){} | 
|---|
| 285 |    explicit subtract_with_carry_01(unsigned long value) | 
|---|
| 286 |       : m_gen(value == 0 ? 19780503UL : value){} | 
|---|
| 287 |    template<class Gen> subtract_with_carry_01(Gen& g) | 
|---|
| 288 |    { init1(g, ::boost::is_same<Gen, subtract_with_carry_01<RealType, w, s, r> >()); } | 
|---|
| 289 |    void seed(unsigned long value = 19780503UL) | 
|---|
| 290 |    { m_gen.seed(value == 0 ? 19780503UL : value); } | 
|---|
| 291 |    template<class Gen> void seed(Gen& g) | 
|---|
| 292 |    { init2(g, ::boost::is_fundamental<Gen>()); } | 
|---|
| 293 |    result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 294 |    { return (m_gen.min)(); } | 
|---|
| 295 |    result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 296 |    { return (m_gen.max)(); } | 
|---|
| 297 |    result_type operator()() | 
|---|
| 298 |    { return m_gen(); } | 
|---|
| 299 |    bool operator==(const subtract_with_carry_01& that)const | 
|---|
| 300 |    { return m_gen == that.m_gen; } | 
|---|
| 301 |    bool operator!=(const subtract_with_carry_01& that)const | 
|---|
| 302 |    { return m_gen != that.m_gen; } | 
|---|
| 303 |  | 
|---|
| 304 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | 
|---|
| 305 |    template<class CharT, class Traits> | 
|---|
| 306 |    friend std::basic_ostream<CharT,Traits>& | 
|---|
| 307 |    operator<<(std::basic_ostream<CharT,Traits>& os, | 
|---|
| 308 |             const subtract_with_carry_01& lcg) | 
|---|
| 309 |    { | 
|---|
| 310 |       return os << lcg.m_gen; | 
|---|
| 311 |    } | 
|---|
| 312 |  | 
|---|
| 313 |    template<class CharT, class Traits> | 
|---|
| 314 |    friend std::basic_istream<CharT,Traits>& | 
|---|
| 315 |    operator>>(std::basic_istream<CharT,Traits>& is, | 
|---|
| 316 |             subtract_with_carry_01& lcg) | 
|---|
| 317 |    { | 
|---|
| 318 |       return is >> lcg.m_gen; | 
|---|
| 319 |    } | 
|---|
| 320 | #endif | 
|---|
| 321 | private: | 
|---|
| 322 |    template <class Gen> | 
|---|
| 323 |    void init1(Gen& g, const ::boost::true_type&) | 
|---|
| 324 |    { | 
|---|
| 325 |       m_gen = g.m_gen; | 
|---|
| 326 |    } | 
|---|
| 327 |    template <class Gen> | 
|---|
| 328 |    void init1(Gen& g, const ::boost::false_type&) | 
|---|
| 329 |    { | 
|---|
| 330 |       init2(g, ::boost::is_fundamental<Gen>()); | 
|---|
| 331 |    } | 
|---|
| 332 |    template <class Gen> | 
|---|
| 333 |    void init2(Gen& g, const ::boost::true_type&) | 
|---|
| 334 |    { | 
|---|
| 335 |       m_gen.seed(static_cast<unsigned long>(g == 0 ? 19780503UL : g)); | 
|---|
| 336 |    } | 
|---|
| 337 |    template <class Gen> | 
|---|
| 338 |    void init2(Gen& g, const ::boost::false_type&) | 
|---|
| 339 |    { | 
|---|
| 340 |       //typedef typename Gen::result_type gen_rt; | 
|---|
| 341 |       boost::tr1_details::functor2iterator<Gen, unsigned long> f1(g), f2; | 
|---|
| 342 |       m_gen.seed(f1, f2); | 
|---|
| 343 |    } | 
|---|
| 344 |    ::boost::random::subtract_with_carry_01<RealType, w, s, r, 0> m_gen; | 
|---|
| 345 | }; | 
|---|
| 346 |  | 
|---|
| 347 | using ::boost::random::discard_block; | 
|---|
| 348 |  | 
|---|
| 349 | template<class UniformRandomNumberGenerator1, int s1, class UniformRandomNumberGenerator2, int s2> | 
|---|
| 350 | class xor_combine | 
|---|
| 351 | { | 
|---|
| 352 | public: | 
|---|
| 353 |    // types | 
|---|
| 354 |    typedef UniformRandomNumberGenerator1 base1_type; | 
|---|
| 355 |    typedef UniformRandomNumberGenerator2 base2_type; | 
|---|
| 356 |    typedef unsigned long result_type; | 
|---|
| 357 |    // parameter values | 
|---|
| 358 |    BOOST_STATIC_CONSTANT(int, shift1 = s1); | 
|---|
| 359 |    BOOST_STATIC_CONSTANT(int, shift2 = s2); | 
|---|
| 360 |    // constructors and member function | 
|---|
| 361 |    xor_combine(){ init_minmax(); } | 
|---|
| 362 |    xor_combine(const base1_type & rng1, const base2_type & rng2) | 
|---|
| 363 |       : m_b1(rng1), m_b2(rng2) { init_minmax(); } | 
|---|
| 364 |    xor_combine(unsigned long s) | 
|---|
| 365 |       : m_b1(s), m_b2(s+1) { init_minmax(); } | 
|---|
| 366 |    template<class Gen> xor_combine(Gen& g) | 
|---|
| 367 |    {  | 
|---|
| 368 |       init_minmax();  | 
|---|
| 369 |       init1(g, ::boost::is_same<Gen, xor_combine<UniformRandomNumberGenerator1, s1, UniformRandomNumberGenerator2, s2> >()); | 
|---|
| 370 |    } | 
|---|
| 371 |    void seed() | 
|---|
| 372 |    { | 
|---|
| 373 |       m_b1.seed(); | 
|---|
| 374 |       m_b2.seed(); | 
|---|
| 375 |    } | 
|---|
| 376 |    void seed(unsigned long s) | 
|---|
| 377 |    { | 
|---|
| 378 |       m_b1.seed(s); | 
|---|
| 379 |       m_b2.seed(s+1); | 
|---|
| 380 |    } | 
|---|
| 381 |    template<class Gen> void seed(Gen& g) | 
|---|
| 382 |    { | 
|---|
| 383 |       init2(g, ::boost::is_fundamental<Gen>()); | 
|---|
| 384 |    } | 
|---|
| 385 |  | 
|---|
| 386 |    const base1_type& base1() const | 
|---|
| 387 |    { return m_b1; } | 
|---|
| 388 |    const base2_type& base2() const | 
|---|
| 389 |    { return m_b2; } | 
|---|
| 390 |    result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 391 |    { return m_min; } | 
|---|
| 392 |    result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() const | 
|---|
| 393 |    { return m_max; } | 
|---|
| 394 |    result_type operator()() | 
|---|
| 395 |    { return (m_b1() << s1) ^ (m_b2() << s2); } | 
|---|
| 396 |  | 
|---|
| 397 |    bool operator == (const xor_combine& that)const | 
|---|
| 398 |    { return (m_b1 == that.m_b1) && (m_b2 == that.m_b2); } | 
|---|
| 399 |    bool operator != (const xor_combine& that)const | 
|---|
| 400 |    { return !(*this == that); } | 
|---|
| 401 |  | 
|---|
| 402 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | 
|---|
| 403 |    template<class CharT, class Traits> | 
|---|
| 404 |    friend std::basic_ostream<CharT,Traits>& | 
|---|
| 405 |    operator<<(std::basic_ostream<CharT,Traits>& os, | 
|---|
| 406 |             const xor_combine& lcg) | 
|---|
| 407 |    { | 
|---|
| 408 |       return os << lcg.m_b1 << " " << lcg.m_b2; | 
|---|
| 409 |    } | 
|---|
| 410 |  | 
|---|
| 411 |    template<class CharT, class Traits> | 
|---|
| 412 |    friend std::basic_istream<CharT,Traits>& | 
|---|
| 413 |    operator>>(std::basic_istream<CharT,Traits>& is, | 
|---|
| 414 |             xor_combine& lcg) | 
|---|
| 415 |    { | 
|---|
| 416 |       return is >> lcg.m_b1 >> lcg.m_b2; | 
|---|
| 417 |    } | 
|---|
| 418 | #endif | 
|---|
| 419 |  | 
|---|
| 420 | private: | 
|---|
| 421 |    void init_minmax(); | 
|---|
| 422 |    base1_type m_b1; | 
|---|
| 423 |    base2_type m_b2; | 
|---|
| 424 |    result_type m_min; | 
|---|
| 425 |    result_type m_max; | 
|---|
| 426 |  | 
|---|
| 427 |    template <class Gen> | 
|---|
| 428 |    void init1(Gen& g, const ::boost::true_type&) | 
|---|
| 429 |    { | 
|---|
| 430 |       m_b1 = g.m_b1; | 
|---|
| 431 |       m_b2 = g.m_b2; | 
|---|
| 432 |    } | 
|---|
| 433 |    template <class Gen> | 
|---|
| 434 |    void init1(Gen& g, const ::boost::false_type&) | 
|---|
| 435 |    { | 
|---|
| 436 |       init2(g, ::boost::is_fundamental<Gen>()); | 
|---|
| 437 |    } | 
|---|
| 438 |    template <class Gen> | 
|---|
| 439 |    void init2(Gen& g, const ::boost::true_type&) | 
|---|
| 440 |    { | 
|---|
| 441 |       m_b1.seed(static_cast<unsigned long>(g)); | 
|---|
| 442 |       m_b2.seed(static_cast<unsigned long>(g)); | 
|---|
| 443 |    } | 
|---|
| 444 |    template <class Gen> | 
|---|
| 445 |    void init2(Gen& g, const ::boost::false_type&) | 
|---|
| 446 |    { | 
|---|
| 447 |       m_b1.seed(g); | 
|---|
| 448 |       m_b2.seed(g); | 
|---|
| 449 |    } | 
|---|
| 450 | }; | 
|---|
| 451 |  | 
|---|
| 452 | template<class UniformRandomNumberGenerator1, int s1, class UniformRandomNumberGenerator2, int s2> | 
|---|
| 453 | void xor_combine<UniformRandomNumberGenerator1, s1, UniformRandomNumberGenerator2, s2>::init_minmax() | 
|---|
| 454 | { | 
|---|
| 455 |    // | 
|---|
| 456 |    // The following code is based on that given in "Hacker's Delight" | 
|---|
| 457 |    // by Henry S. Warren, (Addison-Wesley, 2003), and at  | 
|---|
| 458 |    // http://www.hackersdelight.org/index.htm. | 
|---|
| 459 |    // Used here by permission. | 
|---|
| 460 |    // | 
|---|
| 461 |    // calculation of minimum value: | 
|---|
| 462 |    // | 
|---|
| 463 |    result_type a = (m_b1.min)() << s1; | 
|---|
| 464 |    result_type b = (m_b1.max)() << s1; | 
|---|
| 465 |    result_type c = (m_b2.min)() << s2; | 
|---|
| 466 |    result_type d = (m_b2.max)() << s2; | 
|---|
| 467 |    result_type m, temp; | 
|---|
| 468 |  | 
|---|
| 469 |    m = 0x1uL << ((sizeof(result_type) * CHAR_BIT) - 1); | 
|---|
| 470 |    while (m != 0) { | 
|---|
| 471 |       if (~a & c & m) { | 
|---|
| 472 |          temp = (a | m) & (static_cast<result_type>(0u) - m); | 
|---|
| 473 |          if (temp <= b) a = temp; | 
|---|
| 474 |       } | 
|---|
| 475 |       else if (a & ~c & m) { | 
|---|
| 476 |          temp = (c | m) & (static_cast<result_type>(0u) - m); | 
|---|
| 477 |          if (temp <= d) c = temp; | 
|---|
| 478 |       } | 
|---|
| 479 |       m >>= 1; | 
|---|
| 480 |    } | 
|---|
| 481 |    m_min = a ^ c; | 
|---|
| 482 |  | 
|---|
| 483 |    // | 
|---|
| 484 |    // calculation of maximum value: | 
|---|
| 485 |    // | 
|---|
| 486 |    if((((std::numeric_limits<result_type>::max)() >> s1) < (m_b1.max)()) | 
|---|
| 487 |       || ((((std::numeric_limits<result_type>::max)()) >> s2) < (m_b2.max)())) | 
|---|
| 488 |    { | 
|---|
| 489 |       m_max = (std::numeric_limits<result_type>::max)(); | 
|---|
| 490 |       return; | 
|---|
| 491 |    } | 
|---|
| 492 |    a = (m_b1.min)() << s1; | 
|---|
| 493 |    b = (m_b1.max)() << s1; | 
|---|
| 494 |    c = (m_b2.min)() << s2; | 
|---|
| 495 |    d = (m_b2.max)() << s2; | 
|---|
| 496 |  | 
|---|
| 497 |    m = 0x1uL << ((sizeof(result_type) * CHAR_BIT) - 1); | 
|---|
| 498 |  | 
|---|
| 499 |    while (m != 0) { | 
|---|
| 500 |       if (b & d & m) { | 
|---|
| 501 |          temp = (b - m) | (m - 1); | 
|---|
| 502 |          if (temp >= a) b = temp; | 
|---|
| 503 |          else { | 
|---|
| 504 |             temp = (d - m) | (m - 1); | 
|---|
| 505 |             if (temp >= c) d = temp; | 
|---|
| 506 |          } | 
|---|
| 507 |       } | 
|---|
| 508 |       m = m >> 1; | 
|---|
| 509 |    } | 
|---|
| 510 |    m_max = b ^ d; | 
|---|
| 511 | } | 
|---|
| 512 |  | 
|---|
| 513 | typedef linear_congruential< ::boost::int32_t, 16807, 0, 2147483647> minstd_rand0; | 
|---|
| 514 | typedef linear_congruential< ::boost::int32_t, 48271, 0, 2147483647> minstd_rand; | 
|---|
| 515 | typedef mersenne_twister< ::boost::uint32_t, 32,624,397,31,0x9908b0df,11,7,0x9d2c5680,15,0xefc60000,18> mt19937; | 
|---|
| 516 | typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01; | 
|---|
| 517 | typedef subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01; | 
|---|
| 518 | typedef discard_block<subtract_with_carry< ::boost::int32_t, (1<<24), 10, 24>, 223, 24> ranlux3; | 
|---|
| 519 | typedef discard_block<subtract_with_carry< ::boost::int32_t, (1<<24), 10, 24>, 389, 24> ranlux4; | 
|---|
| 520 | typedef discard_block<subtract_with_carry_01<float, 24, 10, 24>, 223, 24> ranlux3_01; | 
|---|
| 521 | typedef discard_block<subtract_with_carry_01<float, 24, 10, 24>, 389, 24> ranlux4_01; | 
|---|
| 522 |  | 
|---|
| 523 | #ifndef __SUNPRO_CC | 
|---|
| 524 | using ::boost::random_device; | 
|---|
| 525 | #endif | 
|---|
| 526 | using ::boost::uniform_int; | 
|---|
| 527 |  | 
|---|
| 528 | class bernoulli_distribution | 
|---|
| 529 | { | 
|---|
| 530 | public: | 
|---|
| 531 |    // types | 
|---|
| 532 |    typedef int input_type; | 
|---|
| 533 |    typedef bool result_type; | 
|---|
| 534 |    // constructors and member function | 
|---|
| 535 |    explicit bernoulli_distribution(double p = 0.5) | 
|---|
| 536 |       : m_dist(p){} | 
|---|
| 537 |    double p() const | 
|---|
| 538 |    { return m_dist.p(); } | 
|---|
| 539 |    void reset() | 
|---|
| 540 |    { m_dist.reset(); } | 
|---|
| 541 |    template<class UniformRandomNumberGenerator> | 
|---|
| 542 |    result_type operator()(UniformRandomNumberGenerator& urng) | 
|---|
| 543 |    { | 
|---|
| 544 |       return m_dist(urng); | 
|---|
| 545 |    } | 
|---|
| 546 | #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | 
|---|
| 547 |    template<class CharT, class Traits> | 
|---|
| 548 |    friend std::basic_ostream<CharT,Traits>& | 
|---|
| 549 |    operator<<(std::basic_ostream<CharT,Traits>& os, | 
|---|
| 550 |             const bernoulli_distribution& lcg) | 
|---|
| 551 |    { | 
|---|
| 552 |       return os << lcg.m_dist; | 
|---|
| 553 |    } | 
|---|
| 554 |  | 
|---|
| 555 |    template<class CharT, class Traits> | 
|---|
| 556 |    friend std::basic_istream<CharT,Traits>& | 
|---|
| 557 |    operator>>(std::basic_istream<CharT,Traits>& is, | 
|---|
| 558 |             bernoulli_distribution& lcg) | 
|---|
| 559 |    { | 
|---|
| 560 |       return is >> lcg.m_dist; | 
|---|
| 561 |    } | 
|---|
| 562 | #endif | 
|---|
| 563 |  | 
|---|
| 564 | private: | 
|---|
| 565 |    ::boost::bernoulli_distribution<double> m_dist; | 
|---|
| 566 | }; | 
|---|
| 567 | //using ::boost::bernoulli_distribution; | 
|---|
| 568 | using ::boost::geometric_distribution; | 
|---|
| 569 | using ::boost::poisson_distribution; | 
|---|
| 570 | using ::boost::binomial_distribution; | 
|---|
| 571 | using ::boost::uniform_real; | 
|---|
| 572 | using ::boost::exponential_distribution; | 
|---|
| 573 | using ::boost::normal_distribution; | 
|---|
| 574 | using ::boost::gamma_distribution; | 
|---|
| 575 |  | 
|---|
| 576 | } } | 
|---|
| 577 |  | 
|---|
| 578 | #endif | 
|---|
| 579 |  | 
|---|
| 580 | #endif | 
|---|
| 581 |  | 
|---|