1 // random number generation (out of line) -*- C++ -*- 2 3 // Copyright (C) 2007, 2009 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file tr1_impl/random.tcc 26 * This is an internal header file, included by other library headers. 27 * You should not attempt to use it directly. 28 */ 29 30 namespace std 31 { 32 _GLIBCXX_BEGIN_NAMESPACE_TR1 33 34 /* 35 * (Further) implementation-space details. 36 */ 37 namespace __detail 38 { 39 // General case for x = (ax + c) mod m -- use Schrage's algorithm to avoid 40 // integer overflow. 41 // 42 // Because a and c are compile-time integral constants the compiler kindly 43 // elides any unreachable paths. 44 // 45 // Preconditions: a > 0, m > 0. 46 // 47 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool> 48 struct _Mod 49 { 50 static _Tp 51 __calc(_Tp __x) 52 { 53 if (__a == 1) 54 __x %= __m; 55 else 56 { 57 static const _Tp __q = __m / __a; 58 static const _Tp __r = __m % __a; 59 60 _Tp __t1 = __a * (__x % __q); 61 _Tp __t2 = __r * (__x / __q); 62 if (__t1 >= __t2) 63 __x = __t1 - __t2; 64 else 65 __x = __m - __t2 + __t1; 66 } 67 68 if (__c != 0) 69 { 70 const _Tp __d = __m - __x; 71 if (__d > __c) 72 __x += __c; 73 else 74 __x = __c - __d; 75 } 76 return __x; 77 } 78 }; 79 80 // Special case for m == 0 -- use unsigned integer overflow as modulo 81 // operator. 82 template<typename _Tp, _Tp __a, _Tp __c, _Tp __m> 83 struct _Mod<_Tp, __a, __c, __m, true> 84 { 85 static _Tp 86 __calc(_Tp __x) 87 { return __a * __x + __c; } 88 }; 89 } // namespace __detail 90 91 /** 92 * Seeds the LCR with integral value @p __x0, adjusted so that the 93 * ring identity is never a member of the convergence set. 94 */ 95 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 96 void 97 linear_congruential<_UIntType, __a, __c, __m>:: 98 seed(unsigned long __x0) 99 { 100 if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) 101 && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0)) 102 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1); 103 else 104 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0); 105 } 106 107 /** 108 * Seeds the LCR engine with a value generated by @p __g. 109 */ 110 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 111 template<class _Gen> 112 void 113 linear_congruential<_UIntType, __a, __c, __m>:: 114 seed(_Gen& __g, false_type) 115 { 116 _UIntType __x0 = __g(); 117 if ((__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) 118 && (__detail::__mod<_UIntType, 1, 0, __m>(__x0) == 0)) 119 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(1); 120 else 121 _M_x = __detail::__mod<_UIntType, 1, 0, __m>(__x0); 122 } 123 124 /** 125 * Gets the next generated value in sequence. 126 */ 127 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 128 typename linear_congruential<_UIntType, __a, __c, __m>::result_type 129 linear_congruential<_UIntType, __a, __c, __m>:: 130 operator()() 131 { 132 _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x); 133 return _M_x; 134 } 135 136 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 137 typename _CharT, typename _Traits> 138 std::basic_ostream<_CharT, _Traits>& 139 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 140 const linear_congruential<_UIntType, __a, __c, __m>& __lcr) 141 { 142 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 143 typedef typename __ostream_type::ios_base __ios_base; 144 145 const typename __ios_base::fmtflags __flags = __os.flags(); 146 const _CharT __fill = __os.fill(); 147 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 148 __os.fill(__os.widen(' ')); 149 150 __os << __lcr._M_x; 151 152 __os.flags(__flags); 153 __os.fill(__fill); 154 return __os; 155 } 156 157 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 158 typename _CharT, typename _Traits> 159 std::basic_istream<_CharT, _Traits>& 160 operator>>(std::basic_istream<_CharT, _Traits>& __is, 161 linear_congruential<_UIntType, __a, __c, __m>& __lcr) 162 { 163 typedef std::basic_istream<_CharT, _Traits> __istream_type; 164 typedef typename __istream_type::ios_base __ios_base; 165 166 const typename __ios_base::fmtflags __flags = __is.flags(); 167 __is.flags(__ios_base::dec); 168 169 __is >> __lcr._M_x; 170 171 __is.flags(__flags); 172 return __is; 173 } 174 175 176 template<class _UIntType, int __w, int __n, int __m, int __r, 177 _UIntType __a, int __u, int __s, 178 _UIntType __b, int __t, _UIntType __c, int __l> 179 void 180 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, 181 __b, __t, __c, __l>:: 182 seed(unsigned long __value) 183 { 184 _M_x[0] = __detail::__mod<_UIntType, 1, 0, 185 __detail::_Shift<_UIntType, __w>::__value>(__value); 186 187 for (int __i = 1; __i < state_size; ++__i) 188 { 189 _UIntType __x = _M_x[__i - 1]; 190 __x ^= __x >> (__w - 2); 191 __x *= 1812433253ul; 192 __x += __i; 193 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, 194 __detail::_Shift<_UIntType, __w>::__value>(__x); 195 } 196 _M_p = state_size; 197 } 198 199 template<class _UIntType, int __w, int __n, int __m, int __r, 200 _UIntType __a, int __u, int __s, 201 _UIntType __b, int __t, _UIntType __c, int __l> 202 template<class _Gen> 203 void 204 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, 205 __b, __t, __c, __l>:: 206 seed(_Gen& __gen, false_type) 207 { 208 for (int __i = 0; __i < state_size; ++__i) 209 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, 210 __detail::_Shift<_UIntType, __w>::__value>(__gen()); 211 _M_p = state_size; 212 } 213 214 template<class _UIntType, int __w, int __n, int __m, int __r, 215 _UIntType __a, int __u, int __s, 216 _UIntType __b, int __t, _UIntType __c, int __l> 217 typename 218 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, 219 __b, __t, __c, __l>::result_type 220 mersenne_twister<_UIntType, __w, __n, __m, __r, __a, __u, __s, 221 __b, __t, __c, __l>:: 222 operator()() 223 { 224 // Reload the vector - cost is O(n) amortized over n calls. 225 if (_M_p >= state_size) 226 { 227 const _UIntType __upper_mask = (~_UIntType()) << __r; 228 const _UIntType __lower_mask = ~__upper_mask; 229 230 for (int __k = 0; __k < (__n - __m); ++__k) 231 { 232 _UIntType __y = ((_M_x[__k] & __upper_mask) 233 | (_M_x[__k + 1] & __lower_mask)); 234 _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1) 235 ^ ((__y & 0x01) ? __a : 0)); 236 } 237 238 for (int __k = (__n - __m); __k < (__n - 1); ++__k) 239 { 240 _UIntType __y = ((_M_x[__k] & __upper_mask) 241 | (_M_x[__k + 1] & __lower_mask)); 242 _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1) 243 ^ ((__y & 0x01) ? __a : 0)); 244 } 245 246 _UIntType __y = ((_M_x[__n - 1] & __upper_mask) 247 | (_M_x[0] & __lower_mask)); 248 _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1) 249 ^ ((__y & 0x01) ? __a : 0)); 250 _M_p = 0; 251 } 252 253 // Calculate o(x(i)). 254 result_type __z = _M_x[_M_p++]; 255 __z ^= (__z >> __u); 256 __z ^= (__z << __s) & __b; 257 __z ^= (__z << __t) & __c; 258 __z ^= (__z >> __l); 259 260 return __z; 261 } 262 263 template<class _UIntType, int __w, int __n, int __m, int __r, 264 _UIntType __a, int __u, int __s, _UIntType __b, int __t, 265 _UIntType __c, int __l, 266 typename _CharT, typename _Traits> 267 std::basic_ostream<_CharT, _Traits>& 268 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 269 const mersenne_twister<_UIntType, __w, __n, __m, 270 __r, __a, __u, __s, __b, __t, __c, __l>& __x) 271 { 272 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 273 typedef typename __ostream_type::ios_base __ios_base; 274 275 const typename __ios_base::fmtflags __flags = __os.flags(); 276 const _CharT __fill = __os.fill(); 277 const _CharT __space = __os.widen(' '); 278 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 279 __os.fill(__space); 280 281 for (int __i = 0; __i < __n - 1; ++__i) 282 __os << __x._M_x[__i] << __space; 283 __os << __x._M_x[__n - 1]; 284 285 __os.flags(__flags); 286 __os.fill(__fill); 287 return __os; 288 } 289 290 template<class _UIntType, int __w, int __n, int __m, int __r, 291 _UIntType __a, int __u, int __s, _UIntType __b, int __t, 292 _UIntType __c, int __l, 293 typename _CharT, typename _Traits> 294 std::basic_istream<_CharT, _Traits>& 295 operator>>(std::basic_istream<_CharT, _Traits>& __is, 296 mersenne_twister<_UIntType, __w, __n, __m, 297 __r, __a, __u, __s, __b, __t, __c, __l>& __x) 298 { 299 typedef std::basic_istream<_CharT, _Traits> __istream_type; 300 typedef typename __istream_type::ios_base __ios_base; 301 302 const typename __ios_base::fmtflags __flags = __is.flags(); 303 __is.flags(__ios_base::dec | __ios_base::skipws); 304 305 for (int __i = 0; __i < __n; ++__i) 306 __is >> __x._M_x[__i]; 307 308 __is.flags(__flags); 309 return __is; 310 } 311 312 313 template<typename _IntType, _IntType __m, int __s, int __r> 314 void 315 subtract_with_carry<_IntType, __m, __s, __r>:: 316 seed(unsigned long __value) 317 { 318 if (__value == 0) 319 __value = 19780503; 320 321 std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563> 322 __lcg(__value); 323 324 for (int __i = 0; __i < long_lag; ++__i) 325 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__lcg()); 326 327 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 328 _M_p = 0; 329 } 330 331 template<typename _IntType, _IntType __m, int __s, int __r> 332 template<class _Gen> 333 void 334 subtract_with_carry<_IntType, __m, __s, __r>:: 335 seed(_Gen& __gen, false_type) 336 { 337 const int __n = (std::numeric_limits<_UIntType>::digits + 31) / 32; 338 339 for (int __i = 0; __i < long_lag; ++__i) 340 { 341 _UIntType __tmp = 0; 342 _UIntType __factor = 1; 343 for (int __j = 0; __j < __n; ++__j) 344 { 345 __tmp += __detail::__mod<__detail::_UInt32Type, 1, 0, 0> 346 (__gen()) * __factor; 347 __factor *= __detail::_Shift<_UIntType, 32>::__value; 348 } 349 _M_x[__i] = __detail::__mod<_UIntType, 1, 0, modulus>(__tmp); 350 } 351 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 352 _M_p = 0; 353 } 354 355 template<typename _IntType, _IntType __m, int __s, int __r> 356 typename subtract_with_carry<_IntType, __m, __s, __r>::result_type 357 subtract_with_carry<_IntType, __m, __s, __r>:: 358 operator()() 359 { 360 // Derive short lag index from current index. 361 int __ps = _M_p - short_lag; 362 if (__ps < 0) 363 __ps += long_lag; 364 365 // Calculate new x(i) without overflow or division. 366 // NB: Thanks to the requirements for _IntType, _M_x[_M_p] + _M_carry 367 // cannot overflow. 368 _UIntType __xi; 369 if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) 370 { 371 __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; 372 _M_carry = 0; 373 } 374 else 375 { 376 __xi = modulus - _M_x[_M_p] - _M_carry + _M_x[__ps]; 377 _M_carry = 1; 378 } 379 _M_x[_M_p] = __xi; 380 381 // Adjust current index to loop around in ring buffer. 382 if (++_M_p >= long_lag) 383 _M_p = 0; 384 385 return __xi; 386 } 387 388 template<typename _IntType, _IntType __m, int __s, int __r, 389 typename _CharT, typename _Traits> 390 std::basic_ostream<_CharT, _Traits>& 391 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 392 const subtract_with_carry<_IntType, __m, __s, __r>& __x) 393 { 394 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 395 typedef typename __ostream_type::ios_base __ios_base; 396 397 const typename __ios_base::fmtflags __flags = __os.flags(); 398 const _CharT __fill = __os.fill(); 399 const _CharT __space = __os.widen(' '); 400 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 401 __os.fill(__space); 402 403 for (int __i = 0; __i < __r; ++__i) 404 __os << __x._M_x[__i] << __space; 405 __os << __x._M_carry; 406 407 __os.flags(__flags); 408 __os.fill(__fill); 409 return __os; 410 } 411 412 template<typename _IntType, _IntType __m, int __s, int __r, 413 typename _CharT, typename _Traits> 414 std::basic_istream<_CharT, _Traits>& 415 operator>>(std::basic_istream<_CharT, _Traits>& __is, 416 subtract_with_carry<_IntType, __m, __s, __r>& __x) 417 { 418 typedef std::basic_ostream<_CharT, _Traits> __istream_type; 419 typedef typename __istream_type::ios_base __ios_base; 420 421 const typename __ios_base::fmtflags __flags = __is.flags(); 422 __is.flags(__ios_base::dec | __ios_base::skipws); 423 424 for (int __i = 0; __i < __r; ++__i) 425 __is >> __x._M_x[__i]; 426 __is >> __x._M_carry; 427 428 __is.flags(__flags); 429 return __is; 430 } 431 432 433 template<typename _RealType, int __w, int __s, int __r> 434 void 435 subtract_with_carry_01<_RealType, __w, __s, __r>:: 436 _M_initialize_npows() 437 { 438 for (int __j = 0; __j < __n; ++__j) 439 #if _GLIBCXX_USE_C99_MATH_TR1 440 _M_npows[__j] = std::_GLIBCXX_TR1 ldexp(_RealType(1), -__w + __j * 32); 441 #else 442 _M_npows[__j] = std::pow(_RealType(2), -__w + __j * 32); 443 #endif 444 } 445 446 template<typename _RealType, int __w, int __s, int __r> 447 void 448 subtract_with_carry_01<_RealType, __w, __s, __r>:: 449 seed(unsigned long __value) 450 { 451 if (__value == 0) 452 __value = 19780503; 453 454 // _GLIBCXX_RESOLVE_LIB_DEFECTS 455 // 512. Seeding subtract_with_carry_01 from a single unsigned long. 456 std::_GLIBCXX_TR1 linear_congruential<unsigned long, 40014, 0, 2147483563> 457 __lcg(__value); 458 459 this->seed(__lcg); 460 } 461 462 template<typename _RealType, int __w, int __s, int __r> 463 template<class _Gen> 464 void 465 subtract_with_carry_01<_RealType, __w, __s, __r>:: 466 seed(_Gen& __gen, false_type) 467 { 468 for (int __i = 0; __i < long_lag; ++__i) 469 { 470 for (int __j = 0; __j < __n - 1; ++__j) 471 _M_x[__i][__j] = __detail::__mod<_UInt32Type, 1, 0, 0>(__gen()); 472 _M_x[__i][__n - 1] = __detail::__mod<_UInt32Type, 1, 0, 473 __detail::_Shift<_UInt32Type, __w % 32>::__value>(__gen()); 474 } 475 476 _M_carry = 1; 477 for (int __j = 0; __j < __n; ++__j) 478 if (_M_x[long_lag - 1][__j] != 0) 479 { 480 _M_carry = 0; 481 break; 482 } 483 484 _M_p = 0; 485 } 486 487 template<typename _RealType, int __w, int __s, int __r> 488 typename subtract_with_carry_01<_RealType, __w, __s, __r>::result_type 489 subtract_with_carry_01<_RealType, __w, __s, __r>:: 490 operator()() 491 { 492 // Derive short lag index from current index. 493 int __ps = _M_p - short_lag; 494 if (__ps < 0) 495 __ps += long_lag; 496 497 _UInt32Type __new_carry; 498 for (int __j = 0; __j < __n - 1; ++__j) 499 { 500 if (_M_x[__ps][__j] > _M_x[_M_p][__j] 501 || (_M_x[__ps][__j] == _M_x[_M_p][__j] && _M_carry == 0)) 502 __new_carry = 0; 503 else 504 __new_carry = 1; 505 506 _M_x[_M_p][__j] = _M_x[__ps][__j] - _M_x[_M_p][__j] - _M_carry; 507 _M_carry = __new_carry; 508 } 509 510 if (_M_x[__ps][__n - 1] > _M_x[_M_p][__n - 1] 511 || (_M_x[__ps][__n - 1] == _M_x[_M_p][__n - 1] && _M_carry == 0)) 512 __new_carry = 0; 513 else 514 __new_carry = 1; 515 516 _M_x[_M_p][__n - 1] = __detail::__mod<_UInt32Type, 1, 0, 517 __detail::_Shift<_UInt32Type, __w % 32>::__value> 518 (_M_x[__ps][__n - 1] - _M_x[_M_p][__n - 1] - _M_carry); 519 _M_carry = __new_carry; 520 521 result_type __ret = 0.0; 522 for (int __j = 0; __j < __n; ++__j) 523 __ret += _M_x[_M_p][__j] * _M_npows[__j]; 524 525 // Adjust current index to loop around in ring buffer. 526 if (++_M_p >= long_lag) 527 _M_p = 0; 528 529 return __ret; 530 } 531 532 template<typename _RealType, int __w, int __s, int __r, 533 typename _CharT, typename _Traits> 534 std::basic_ostream<_CharT, _Traits>& 535 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 536 const subtract_with_carry_01<_RealType, __w, __s, __r>& __x) 537 { 538 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 539 typedef typename __ostream_type::ios_base __ios_base; 540 541 const typename __ios_base::fmtflags __flags = __os.flags(); 542 const _CharT __fill = __os.fill(); 543 const _CharT __space = __os.widen(' '); 544 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 545 __os.fill(__space); 546 547 for (int __i = 0; __i < __r; ++__i) 548 for (int __j = 0; __j < __x.__n; ++__j) 549 __os << __x._M_x[__i][__j] << __space; 550 __os << __x._M_carry; 551 552 __os.flags(__flags); 553 __os.fill(__fill); 554 return __os; 555 } 556 557 template<typename _RealType, int __w, int __s, int __r, 558 typename _CharT, typename _Traits> 559 std::basic_istream<_CharT, _Traits>& 560 operator>>(std::basic_istream<_CharT, _Traits>& __is, 561 subtract_with_carry_01<_RealType, __w, __s, __r>& __x) 562 { 563 typedef std::basic_istream<_CharT, _Traits> __istream_type; 564 typedef typename __istream_type::ios_base __ios_base; 565 566 const typename __ios_base::fmtflags __flags = __is.flags(); 567 __is.flags(__ios_base::dec | __ios_base::skipws); 568 569 for (int __i = 0; __i < __r; ++__i) 570 for (int __j = 0; __j < __x.__n; ++__j) 571 __is >> __x._M_x[__i][__j]; 572 __is >> __x._M_carry; 573 574 __is.flags(__flags); 575 return __is; 576 } 577 578 579 template<class _UniformRandomNumberGenerator, int __p, int __r> 580 typename discard_block<_UniformRandomNumberGenerator, 581 __p, __r>::result_type 582 discard_block<_UniformRandomNumberGenerator, __p, __r>:: 583 operator()() 584 { 585 if (_M_n >= used_block) 586 { 587 while (_M_n < block_size) 588 { 589 _M_b(); 590 ++_M_n; 591 } 592 _M_n = 0; 593 } 594 ++_M_n; 595 return _M_b(); 596 } 597 598 template<class _UniformRandomNumberGenerator, int __p, int __r, 599 typename _CharT, typename _Traits> 600 std::basic_ostream<_CharT, _Traits>& 601 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 602 const discard_block<_UniformRandomNumberGenerator, 603 __p, __r>& __x) 604 { 605 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 606 typedef typename __ostream_type::ios_base __ios_base; 607 608 const typename __ios_base::fmtflags __flags = __os.flags(); 609 const _CharT __fill = __os.fill(); 610 const _CharT __space = __os.widen(' '); 611 __os.flags(__ios_base::dec | __ios_base::fixed 612 | __ios_base::left); 613 __os.fill(__space); 614 615 __os << __x._M_b << __space << __x._M_n; 616 617 __os.flags(__flags); 618 __os.fill(__fill); 619 return __os; 620 } 621 622 template<class _UniformRandomNumberGenerator, int __p, int __r, 623 typename _CharT, typename _Traits> 624 std::basic_istream<_CharT, _Traits>& 625 operator>>(std::basic_istream<_CharT, _Traits>& __is, 626 discard_block<_UniformRandomNumberGenerator, __p, __r>& __x) 627 { 628 typedef std::basic_istream<_CharT, _Traits> __istream_type; 629 typedef typename __istream_type::ios_base __ios_base; 630 631 const typename __ios_base::fmtflags __flags = __is.flags(); 632 __is.flags(__ios_base::dec | __ios_base::skipws); 633 634 __is >> __x._M_b >> __x._M_n; 635 636 __is.flags(__flags); 637 return __is; 638 } 639 640 641 template<class _UniformRandomNumberGenerator1, int __s1, 642 class _UniformRandomNumberGenerator2, int __s2> 643 void 644 xor_combine<_UniformRandomNumberGenerator1, __s1, 645 _UniformRandomNumberGenerator2, __s2>:: 646 _M_initialize_max() 647 { 648 const int __w = std::numeric_limits<result_type>::digits; 649 650 const result_type __m1 = 651 std::min(result_type(_M_b1.max() - _M_b1.min()), 652 __detail::_Shift<result_type, __w - __s1>::__value - 1); 653 654 const result_type __m2 = 655 std::min(result_type(_M_b2.max() - _M_b2.min()), 656 __detail::_Shift<result_type, __w - __s2>::__value - 1); 657 658 // NB: In TR1 s1 is not required to be >= s2. 659 if (__s1 < __s2) 660 _M_max = _M_initialize_max_aux(__m2, __m1, __s2 - __s1) << __s1; 661 else 662 _M_max = _M_initialize_max_aux(__m1, __m2, __s1 - __s2) << __s2; 663 } 664 665 template<class _UniformRandomNumberGenerator1, int __s1, 666 class _UniformRandomNumberGenerator2, int __s2> 667 typename xor_combine<_UniformRandomNumberGenerator1, __s1, 668 _UniformRandomNumberGenerator2, __s2>::result_type 669 xor_combine<_UniformRandomNumberGenerator1, __s1, 670 _UniformRandomNumberGenerator2, __s2>:: 671 _M_initialize_max_aux(result_type __a, result_type __b, int __d) 672 { 673 const result_type __two2d = result_type(1) << __d; 674 const result_type __c = __a * __two2d; 675 676 if (__a == 0 || __b < __two2d) 677 return __c + __b; 678 679 const result_type __t = std::max(__c, __b); 680 const result_type __u = std::min(__c, __b); 681 682 result_type __ub = __u; 683 result_type __p; 684 for (__p = 0; __ub != 1; __ub >>= 1) 685 ++__p; 686 687 const result_type __two2p = result_type(1) << __p; 688 const result_type __k = __t / __two2p; 689 690 if (__k & 1) 691 return (__k + 1) * __two2p - 1; 692 693 if (__c >= __b) 694 return (__k + 1) * __two2p + _M_initialize_max_aux((__t % __two2p) 695 / __two2d, 696 __u % __two2p, __d); 697 else 698 return (__k + 1) * __two2p + _M_initialize_max_aux((__u % __two2p) 699 / __two2d, 700 __t % __two2p, __d); 701 } 702 703 template<class _UniformRandomNumberGenerator1, int __s1, 704 class _UniformRandomNumberGenerator2, int __s2, 705 typename _CharT, typename _Traits> 706 std::basic_ostream<_CharT, _Traits>& 707 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 708 const xor_combine<_UniformRandomNumberGenerator1, __s1, 709 _UniformRandomNumberGenerator2, __s2>& __x) 710 { 711 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 712 typedef typename __ostream_type::ios_base __ios_base; 713 714 const typename __ios_base::fmtflags __flags = __os.flags(); 715 const _CharT __fill = __os.fill(); 716 const _CharT __space = __os.widen(' '); 717 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 718 __os.fill(__space); 719 720 __os << __x.base1() << __space << __x.base2(); 721 722 __os.flags(__flags); 723 __os.fill(__fill); 724 return __os; 725 } 726 727 template<class _UniformRandomNumberGenerator1, int __s1, 728 class _UniformRandomNumberGenerator2, int __s2, 729 typename _CharT, typename _Traits> 730 std::basic_istream<_CharT, _Traits>& 731 operator>>(std::basic_istream<_CharT, _Traits>& __is, 732 xor_combine<_UniformRandomNumberGenerator1, __s1, 733 _UniformRandomNumberGenerator2, __s2>& __x) 734 { 735 typedef std::basic_istream<_CharT, _Traits> __istream_type; 736 typedef typename __istream_type::ios_base __ios_base; 737 738 const typename __ios_base::fmtflags __flags = __is.flags(); 739 __is.flags(__ios_base::skipws); 740 741 __is >> __x._M_b1 >> __x._M_b2; 742 743 __is.flags(__flags); 744 return __is; 745 } 746 747 748 template<typename _IntType> 749 template<typename _UniformRandomNumberGenerator> 750 typename uniform_int<_IntType>::result_type 751 uniform_int<_IntType>:: 752 _M_call(_UniformRandomNumberGenerator& __urng, 753 result_type __min, result_type __max, true_type) 754 { 755 // XXX Must be fixed to work well for *arbitrary* __urng.max(), 756 // __urng.min(), __max, __min. Currently works fine only in the 757 // most common case __urng.max() - __urng.min() >= __max - __min, 758 // with __urng.max() > __urng.min() >= 0. 759 typedef typename __gnu_cxx::__add_unsigned<typename 760 _UniformRandomNumberGenerator::result_type>::__type __urntype; 761 typedef typename __gnu_cxx::__add_unsigned<result_type>::__type 762 __utype; 763 typedef typename __gnu_cxx::__conditional_type<(sizeof(__urntype) 764 > sizeof(__utype)), 765 __urntype, __utype>::__type __uctype; 766 767 result_type __ret; 768 769 const __urntype __urnmin = __urng.min(); 770 const __urntype __urnmax = __urng.max(); 771 const __urntype __urnrange = __urnmax - __urnmin; 772 const __uctype __urange = __max - __min; 773 const __uctype __udenom = (__urnrange <= __urange 774 ? 1 : __urnrange / (__urange + 1)); 775 do 776 __ret = (__urntype(__urng()) - __urnmin) / __udenom; 777 while (__ret > __max - __min); 778 779 return __ret + __min; 780 } 781 782 template<typename _IntType, typename _CharT, typename _Traits> 783 std::basic_ostream<_CharT, _Traits>& 784 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 785 const uniform_int<_IntType>& __x) 786 { 787 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 788 typedef typename __ostream_type::ios_base __ios_base; 789 790 const typename __ios_base::fmtflags __flags = __os.flags(); 791 const _CharT __fill = __os.fill(); 792 const _CharT __space = __os.widen(' '); 793 __os.flags(__ios_base::scientific | __ios_base::left); 794 __os.fill(__space); 795 796 __os << __x.min() << __space << __x.max(); 797 798 __os.flags(__flags); 799 __os.fill(__fill); 800 return __os; 801 } 802 803 template<typename _IntType, typename _CharT, typename _Traits> 804 std::basic_istream<_CharT, _Traits>& 805 operator>>(std::basic_istream<_CharT, _Traits>& __is, 806 uniform_int<_IntType>& __x) 807 { 808 typedef std::basic_istream<_CharT, _Traits> __istream_type; 809 typedef typename __istream_type::ios_base __ios_base; 810 811 const typename __ios_base::fmtflags __flags = __is.flags(); 812 __is.flags(__ios_base::dec | __ios_base::skipws); 813 814 __is >> __x._M_min >> __x._M_max; 815 816 __is.flags(__flags); 817 return __is; 818 } 819 820 821 template<typename _CharT, typename _Traits> 822 std::basic_ostream<_CharT, _Traits>& 823 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 824 const bernoulli_distribution& __x) 825 { 826 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 827 typedef typename __ostream_type::ios_base __ios_base; 828 829 const typename __ios_base::fmtflags __flags = __os.flags(); 830 const _CharT __fill = __os.fill(); 831 const std::streamsize __precision = __os.precision(); 832 __os.flags(__ios_base::scientific | __ios_base::left); 833 __os.fill(__os.widen(' ')); 834 __os.precision(__gnu_cxx::__numeric_traits<double>::__max_digits10); 835 836 __os << __x.p(); 837 838 __os.flags(__flags); 839 __os.fill(__fill); 840 __os.precision(__precision); 841 return __os; 842 } 843 844 845 template<typename _IntType, typename _RealType> 846 template<class _UniformRandomNumberGenerator> 847 typename geometric_distribution<_IntType, _RealType>::result_type 848 geometric_distribution<_IntType, _RealType>:: 849 operator()(_UniformRandomNumberGenerator& __urng) 850 { 851 // About the epsilon thing see this thread: 852 // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html 853 const _RealType __naf = 854 (1 - std::numeric_limits<_RealType>::epsilon()) / 2; 855 // The largest _RealType convertible to _IntType. 856 const _RealType __thr = 857 std::numeric_limits<_IntType>::max() + __naf; 858 859 _RealType __cand; 860 do 861 __cand = std::ceil(std::log(__urng()) / _M_log_p); 862 while (__cand >= __thr); 863 864 return result_type(__cand + __naf); 865 } 866 867 template<typename _IntType, typename _RealType, 868 typename _CharT, typename _Traits> 869 std::basic_ostream<_CharT, _Traits>& 870 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 871 const geometric_distribution<_IntType, _RealType>& __x) 872 { 873 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 874 typedef typename __ostream_type::ios_base __ios_base; 875 876 const typename __ios_base::fmtflags __flags = __os.flags(); 877 const _CharT __fill = __os.fill(); 878 const std::streamsize __precision = __os.precision(); 879 __os.flags(__ios_base::scientific | __ios_base::left); 880 __os.fill(__os.widen(' ')); 881 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); 882 883 __os << __x.p(); 884 885 __os.flags(__flags); 886 __os.fill(__fill); 887 __os.precision(__precision); 888 return __os; 889 } 890 891 892 template<typename _IntType, typename _RealType> 893 void 894 poisson_distribution<_IntType, _RealType>:: 895 _M_initialize() 896 { 897 #if _GLIBCXX_USE_C99_MATH_TR1 898 if (_M_mean >= 12) 899 { 900 const _RealType __m = std::floor(_M_mean); 901 _M_lm_thr = std::log(_M_mean); 902 _M_lfm = std::_GLIBCXX_TR1 lgamma(__m + 1); 903 _M_sm = std::sqrt(__m); 904 905 const _RealType __pi_4 = 0.7853981633974483096156608458198757L; 906 const _RealType __dx = std::sqrt(2 * __m * std::log(32 * __m 907 / __pi_4)); 908 _M_d = std::_GLIBCXX_TR1 round(std::max(_RealType(6), 909 std::min(__m, __dx))); 910 const _RealType __cx = 2 * __m + _M_d; 911 _M_scx = std::sqrt(__cx / 2); 912 _M_1cx = 1 / __cx; 913 914 _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx); 915 _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d; 916 } 917 else 918 #endif 919 _M_lm_thr = std::exp(-_M_mean); 920 } 921 922 /** 923 * A rejection algorithm when mean >= 12 and a simple method based 924 * upon the multiplication of uniform random variates otherwise. 925 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 926 * is defined. 927 * 928 * Reference: 929 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, 930 * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!). 931 */ 932 template<typename _IntType, typename _RealType> 933 template<class _UniformRandomNumberGenerator> 934 typename poisson_distribution<_IntType, _RealType>::result_type 935 poisson_distribution<_IntType, _RealType>:: 936 operator()(_UniformRandomNumberGenerator& __urng) 937 { 938 #if _GLIBCXX_USE_C99_MATH_TR1 939 if (_M_mean >= 12) 940 { 941 _RealType __x; 942 943 // See comments above... 944 const _RealType __naf = 945 (1 - std::numeric_limits<_RealType>::epsilon()) / 2; 946 const _RealType __thr = 947 std::numeric_limits<_IntType>::max() + __naf; 948 949 const _RealType __m = std::floor(_M_mean); 950 // sqrt(pi / 2) 951 const _RealType __spi_2 = 1.2533141373155002512078826424055226L; 952 const _RealType __c1 = _M_sm * __spi_2; 953 const _RealType __c2 = _M_c2b + __c1; 954 const _RealType __c3 = __c2 + 1; 955 const _RealType __c4 = __c3 + 1; 956 // e^(1 / 78) 957 const _RealType __e178 = 1.0129030479320018583185514777512983L; 958 const _RealType __c5 = __c4 + __e178; 959 const _RealType __c = _M_cb + __c5; 960 const _RealType __2cx = 2 * (2 * __m + _M_d); 961 962 bool __reject = true; 963 do 964 { 965 const _RealType __u = __c * __urng(); 966 const _RealType __e = -std::log(__urng()); 967 968 _RealType __w = 0.0; 969 970 if (__u <= __c1) 971 { 972 const _RealType __n = _M_nd(__urng); 973 const _RealType __y = -std::abs(__n) * _M_sm - 1; 974 __x = std::floor(__y); 975 __w = -__n * __n / 2; 976 if (__x < -__m) 977 continue; 978 } 979 else if (__u <= __c2) 980 { 981 const _RealType __n = _M_nd(__urng); 982 const _RealType __y = 1 + std::abs(__n) * _M_scx; 983 __x = std::ceil(__y); 984 __w = __y * (2 - __y) * _M_1cx; 985 if (__x > _M_d) 986 continue; 987 } 988 else if (__u <= __c3) 989 // NB: This case not in the book, nor in the Errata, 990 // but should be ok... 991 __x = -1; 992 else if (__u <= __c4) 993 __x = 0; 994 else if (__u <= __c5) 995 __x = 1; 996 else 997 { 998 const _RealType __v = -std::log(__urng()); 999 const _RealType __y = _M_d + __v * __2cx / _M_d; 1000 __x = std::ceil(__y); 1001 __w = -_M_d * _M_1cx * (1 + __y / 2); 1002 } 1003 1004 __reject = (__w - __e - __x * _M_lm_thr 1005 > _M_lfm - std::_GLIBCXX_TR1 lgamma(__x + __m + 1)); 1006 1007 __reject |= __x + __m >= __thr; 1008 1009 } while (__reject); 1010 1011 return result_type(__x + __m + __naf); 1012 } 1013 else 1014 #endif 1015 { 1016 _IntType __x = 0; 1017 _RealType __prod = 1.0; 1018 1019 do 1020 { 1021 __prod *= __urng(); 1022 __x += 1; 1023 } 1024 while (__prod > _M_lm_thr); 1025 1026 return __x - 1; 1027 } 1028 } 1029 1030 template<typename _IntType, typename _RealType, 1031 typename _CharT, typename _Traits> 1032 std::basic_ostream<_CharT, _Traits>& 1033 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1034 const poisson_distribution<_IntType, _RealType>& __x) 1035 { 1036 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 1037 typedef typename __ostream_type::ios_base __ios_base; 1038 1039 const typename __ios_base::fmtflags __flags = __os.flags(); 1040 const _CharT __fill = __os.fill(); 1041 const std::streamsize __precision = __os.precision(); 1042 const _CharT __space = __os.widen(' '); 1043 __os.flags(__ios_base::scientific | __ios_base::left); 1044 __os.fill(__space); 1045 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); 1046 1047 __os << __x.mean() << __space << __x._M_nd; 1048 1049 __os.flags(__flags); 1050 __os.fill(__fill); 1051 __os.precision(__precision); 1052 return __os; 1053 } 1054 1055 template<typename _IntType, typename _RealType, 1056 typename _CharT, typename _Traits> 1057 std::basic_istream<_CharT, _Traits>& 1058 operator>>(std::basic_istream<_CharT, _Traits>& __is, 1059 poisson_distribution<_IntType, _RealType>& __x) 1060 { 1061 typedef std::basic_istream<_CharT, _Traits> __istream_type; 1062 typedef typename __istream_type::ios_base __ios_base; 1063 1064 const typename __ios_base::fmtflags __flags = __is.flags(); 1065 __is.flags(__ios_base::skipws); 1066 1067 __is >> __x._M_mean >> __x._M_nd; 1068 __x._M_initialize(); 1069 1070 __is.flags(__flags); 1071 return __is; 1072 } 1073 1074 1075 template<typename _IntType, typename _RealType> 1076 void 1077 binomial_distribution<_IntType, _RealType>:: 1078 _M_initialize() 1079 { 1080 const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; 1081 1082 _M_easy = true; 1083 1084 #if _GLIBCXX_USE_C99_MATH_TR1 1085 if (_M_t * __p12 >= 8) 1086 { 1087 _M_easy = false; 1088 const _RealType __np = std::floor(_M_t * __p12); 1089 const _RealType __pa = __np / _M_t; 1090 const _RealType __1p = 1 - __pa; 1091 1092 const _RealType __pi_4 = 0.7853981633974483096156608458198757L; 1093 const _RealType __d1x = 1094 std::sqrt(__np * __1p * std::log(32 * __np 1095 / (81 * __pi_4 * __1p))); 1096 _M_d1 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d1x)); 1097 const _RealType __d2x = 1098 std::sqrt(__np * __1p * std::log(32 * _M_t * __1p 1099 / (__pi_4 * __pa))); 1100 _M_d2 = std::_GLIBCXX_TR1 round(std::max(_RealType(1), __d2x)); 1101 1102 // sqrt(pi / 2) 1103 const _RealType __spi_2 = 1.2533141373155002512078826424055226L; 1104 _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np)); 1105 _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p)); 1106 _M_c = 2 * _M_d1 / __np; 1107 _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2; 1108 const _RealType __a12 = _M_a1 + _M_s2 * __spi_2; 1109 const _RealType __s1s = _M_s1 * _M_s1; 1110 _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p)) 1111 * 2 * __s1s / _M_d1 1112 * std::exp(-_M_d1 * _M_d1 / (2 * __s1s))); 1113 const _RealType __s2s = _M_s2 * _M_s2; 1114 _M_s = (_M_a123 + 2 * __s2s / _M_d2 1115 * std::exp(-_M_d2 * _M_d2 / (2 * __s2s))); 1116 _M_lf = (std::_GLIBCXX_TR1 lgamma(__np + 1) 1117 + std::_GLIBCXX_TR1 lgamma(_M_t - __np + 1)); 1118 _M_lp1p = std::log(__pa / __1p); 1119 1120 _M_q = -std::log(1 - (__p12 - __pa) / __1p); 1121 } 1122 else 1123 #endif 1124 _M_q = -std::log(1 - __p12); 1125 } 1126 1127 template<typename _IntType, typename _RealType> 1128 template<class _UniformRandomNumberGenerator> 1129 typename binomial_distribution<_IntType, _RealType>::result_type 1130 binomial_distribution<_IntType, _RealType>:: 1131 _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t) 1132 { 1133 _IntType __x = 0; 1134 _RealType __sum = 0; 1135 1136 do 1137 { 1138 const _RealType __e = -std::log(__urng()); 1139 __sum += __e / (__t - __x); 1140 __x += 1; 1141 } 1142 while (__sum <= _M_q); 1143 1144 return __x - 1; 1145 } 1146 1147 /** 1148 * A rejection algorithm when t * p >= 8 and a simple waiting time 1149 * method - the second in the referenced book - otherwise. 1150 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 1151 * is defined. 1152 * 1153 * Reference: 1154 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, 1155 * New York, 1986, Ch. X, Sect. 4 (+ Errata!). 1156 */ 1157 template<typename _IntType, typename _RealType> 1158 template<class _UniformRandomNumberGenerator> 1159 typename binomial_distribution<_IntType, _RealType>::result_type 1160 binomial_distribution<_IntType, _RealType>:: 1161 operator()(_UniformRandomNumberGenerator& __urng) 1162 { 1163 result_type __ret; 1164 const _RealType __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; 1165 1166 #if _GLIBCXX_USE_C99_MATH_TR1 1167 if (!_M_easy) 1168 { 1169 _RealType __x; 1170 1171 // See comments above... 1172 const _RealType __naf = 1173 (1 - std::numeric_limits<_RealType>::epsilon()) / 2; 1174 const _RealType __thr = 1175 std::numeric_limits<_IntType>::max() + __naf; 1176 1177 const _RealType __np = std::floor(_M_t * __p12); 1178 const _RealType __pa = __np / _M_t; 1179 1180 // sqrt(pi / 2) 1181 const _RealType __spi_2 = 1.2533141373155002512078826424055226L; 1182 const _RealType __a1 = _M_a1; 1183 const _RealType __a12 = __a1 + _M_s2 * __spi_2; 1184 const _RealType __a123 = _M_a123; 1185 const _RealType __s1s = _M_s1 * _M_s1; 1186 const _RealType __s2s = _M_s2 * _M_s2; 1187 1188 bool __reject; 1189 do 1190 { 1191 const _RealType __u = _M_s * __urng(); 1192 1193 _RealType __v; 1194 1195 if (__u <= __a1) 1196 { 1197 const _RealType __n = _M_nd(__urng); 1198 const _RealType __y = _M_s1 * std::abs(__n); 1199 __reject = __y >= _M_d1; 1200 if (!__reject) 1201 { 1202 const _RealType __e = -std::log(__urng()); 1203 __x = std::floor(__y); 1204 __v = -__e - __n * __n / 2 + _M_c; 1205 } 1206 } 1207 else if (__u <= __a12) 1208 { 1209 const _RealType __n = _M_nd(__urng); 1210 const _RealType __y = _M_s2 * std::abs(__n); 1211 __reject = __y >= _M_d2; 1212 if (!__reject) 1213 { 1214 const _RealType __e = -std::log(__urng()); 1215 __x = std::floor(-__y); 1216 __v = -__e - __n * __n / 2; 1217 } 1218 } 1219 else if (__u <= __a123) 1220 { 1221 const _RealType __e1 = -std::log(__urng()); 1222 const _RealType __e2 = -std::log(__urng()); 1223 1224 const _RealType __y = _M_d1 + 2 * __s1s * __e1 / _M_d1; 1225 __x = std::floor(__y); 1226 __v = (-__e2 + _M_d1 * (1 / (_M_t - __np) 1227 -__y / (2 * __s1s))); 1228 __reject = false; 1229 } 1230 else 1231 { 1232 const _RealType __e1 = -std::log(__urng()); 1233 const _RealType __e2 = -std::log(__urng()); 1234 1235 const _RealType __y = _M_d2 + 2 * __s2s * __e1 / _M_d2; 1236 __x = std::floor(-__y); 1237 __v = -__e2 - _M_d2 * __y / (2 * __s2s); 1238 __reject = false; 1239 } 1240 1241 __reject = __reject || __x < -__np || __x > _M_t - __np; 1242 if (!__reject) 1243 { 1244 const _RealType __lfx = 1245 std::_GLIBCXX_TR1 lgamma(__np + __x + 1) 1246 + std::_GLIBCXX_TR1 lgamma(_M_t - (__np + __x) + 1); 1247 __reject = __v > _M_lf - __lfx + __x * _M_lp1p; 1248 } 1249 1250 __reject |= __x + __np >= __thr; 1251 } 1252 while (__reject); 1253 1254 __x += __np + __naf; 1255 1256 const _IntType __z = _M_waiting(__urng, _M_t - _IntType(__x)); 1257 __ret = _IntType(__x) + __z; 1258 } 1259 else 1260 #endif 1261 __ret = _M_waiting(__urng, _M_t); 1262 1263 if (__p12 != _M_p) 1264 __ret = _M_t - __ret; 1265 return __ret; 1266 } 1267 1268 template<typename _IntType, typename _RealType, 1269 typename _CharT, typename _Traits> 1270 std::basic_ostream<_CharT, _Traits>& 1271 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1272 const binomial_distribution<_IntType, _RealType>& __x) 1273 { 1274 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 1275 typedef typename __ostream_type::ios_base __ios_base; 1276 1277 const typename __ios_base::fmtflags __flags = __os.flags(); 1278 const _CharT __fill = __os.fill(); 1279 const std::streamsize __precision = __os.precision(); 1280 const _CharT __space = __os.widen(' '); 1281 __os.flags(__ios_base::scientific | __ios_base::left); 1282 __os.fill(__space); 1283 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); 1284 1285 __os << __x.t() << __space << __x.p() 1286 << __space << __x._M_nd; 1287 1288 __os.flags(__flags); 1289 __os.fill(__fill); 1290 __os.precision(__precision); 1291 return __os; 1292 } 1293 1294 template<typename _IntType, typename _RealType, 1295 typename _CharT, typename _Traits> 1296 std::basic_istream<_CharT, _Traits>& 1297 operator>>(std::basic_istream<_CharT, _Traits>& __is, 1298 binomial_distribution<_IntType, _RealType>& __x) 1299 { 1300 typedef std::basic_istream<_CharT, _Traits> __istream_type; 1301 typedef typename __istream_type::ios_base __ios_base; 1302 1303 const typename __ios_base::fmtflags __flags = __is.flags(); 1304 __is.flags(__ios_base::dec | __ios_base::skipws); 1305 1306 __is >> __x._M_t >> __x._M_p >> __x._M_nd; 1307 __x._M_initialize(); 1308 1309 __is.flags(__flags); 1310 return __is; 1311 } 1312 1313 1314 template<typename _RealType, typename _CharT, typename _Traits> 1315 std::basic_ostream<_CharT, _Traits>& 1316 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1317 const uniform_real<_RealType>& __x) 1318 { 1319 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 1320 typedef typename __ostream_type::ios_base __ios_base; 1321 1322 const typename __ios_base::fmtflags __flags = __os.flags(); 1323 const _CharT __fill = __os.fill(); 1324 const std::streamsize __precision = __os.precision(); 1325 const _CharT __space = __os.widen(' '); 1326 __os.flags(__ios_base::scientific | __ios_base::left); 1327 __os.fill(__space); 1328 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); 1329 1330 __os << __x.min() << __space << __x.max(); 1331 1332 __os.flags(__flags); 1333 __os.fill(__fill); 1334 __os.precision(__precision); 1335 return __os; 1336 } 1337 1338 template<typename _RealType, typename _CharT, typename _Traits> 1339 std::basic_istream<_CharT, _Traits>& 1340 operator>>(std::basic_istream<_CharT, _Traits>& __is, 1341 uniform_real<_RealType>& __x) 1342 { 1343 typedef std::basic_istream<_CharT, _Traits> __istream_type; 1344 typedef typename __istream_type::ios_base __ios_base; 1345 1346 const typename __ios_base::fmtflags __flags = __is.flags(); 1347 __is.flags(__ios_base::skipws); 1348 1349 __is >> __x._M_min >> __x._M_max; 1350 1351 __is.flags(__flags); 1352 return __is; 1353 } 1354 1355 1356 template<typename _RealType, typename _CharT, typename _Traits> 1357 std::basic_ostream<_CharT, _Traits>& 1358 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1359 const exponential_distribution<_RealType>& __x) 1360 { 1361 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 1362 typedef typename __ostream_type::ios_base __ios_base; 1363 1364 const typename __ios_base::fmtflags __flags = __os.flags(); 1365 const _CharT __fill = __os.fill(); 1366 const std::streamsize __precision = __os.precision(); 1367 __os.flags(__ios_base::scientific | __ios_base::left); 1368 __os.fill(__os.widen(' ')); 1369 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); 1370 1371 __os << __x.lambda(); 1372 1373 __os.flags(__flags); 1374 __os.fill(__fill); 1375 __os.precision(__precision); 1376 return __os; 1377 } 1378 1379 1380 /** 1381 * Polar method due to Marsaglia. 1382 * 1383 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, 1384 * New York, 1986, Ch. V, Sect. 4.4. 1385 */ 1386 template<typename _RealType> 1387 template<class _UniformRandomNumberGenerator> 1388 typename normal_distribution<_RealType>::result_type 1389 normal_distribution<_RealType>:: 1390 operator()(_UniformRandomNumberGenerator& __urng) 1391 { 1392 result_type __ret; 1393 1394 if (_M_saved_available) 1395 { 1396 _M_saved_available = false; 1397 __ret = _M_saved; 1398 } 1399 else 1400 { 1401 result_type __x, __y, __r2; 1402 do 1403 { 1404 __x = result_type(2.0) * __urng() - 1.0; 1405 __y = result_type(2.0) * __urng() - 1.0; 1406 __r2 = __x * __x + __y * __y; 1407 } 1408 while (__r2 > 1.0 || __r2 == 0.0); 1409 1410 const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 1411 _M_saved = __x * __mult; 1412 _M_saved_available = true; 1413 __ret = __y * __mult; 1414 } 1415 1416 __ret = __ret * _M_sigma + _M_mean; 1417 return __ret; 1418 } 1419 1420 template<typename _RealType, typename _CharT, typename _Traits> 1421 std::basic_ostream<_CharT, _Traits>& 1422 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1423 const normal_distribution<_RealType>& __x) 1424 { 1425 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 1426 typedef typename __ostream_type::ios_base __ios_base; 1427 1428 const typename __ios_base::fmtflags __flags = __os.flags(); 1429 const _CharT __fill = __os.fill(); 1430 const std::streamsize __precision = __os.precision(); 1431 const _CharT __space = __os.widen(' '); 1432 __os.flags(__ios_base::scientific | __ios_base::left); 1433 __os.fill(__space); 1434 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); 1435 1436 __os << __x._M_saved_available << __space 1437 << __x.mean() << __space 1438 << __x.sigma(); 1439 if (__x._M_saved_available) 1440 __os << __space << __x._M_saved; 1441 1442 __os.flags(__flags); 1443 __os.fill(__fill); 1444 __os.precision(__precision); 1445 return __os; 1446 } 1447 1448 template<typename _RealType, typename _CharT, typename _Traits> 1449 std::basic_istream<_CharT, _Traits>& 1450 operator>>(std::basic_istream<_CharT, _Traits>& __is, 1451 normal_distribution<_RealType>& __x) 1452 { 1453 typedef std::basic_istream<_CharT, _Traits> __istream_type; 1454 typedef typename __istream_type::ios_base __ios_base; 1455 1456 const typename __ios_base::fmtflags __flags = __is.flags(); 1457 __is.flags(__ios_base::dec | __ios_base::skipws); 1458 1459 __is >> __x._M_saved_available >> __x._M_mean 1460 >> __x._M_sigma; 1461 if (__x._M_saved_available) 1462 __is >> __x._M_saved; 1463 1464 __is.flags(__flags); 1465 return __is; 1466 } 1467 1468 1469 template<typename _RealType> 1470 void 1471 gamma_distribution<_RealType>:: 1472 _M_initialize() 1473 { 1474 if (_M_alpha >= 1) 1475 _M_l_d = std::sqrt(2 * _M_alpha - 1); 1476 else 1477 _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha)) 1478 * (1 - _M_alpha)); 1479 } 1480 1481 /** 1482 * Cheng's rejection algorithm GB for alpha >= 1 and a modification 1483 * of Vaduva's rejection from Weibull algorithm due to Devroye for 1484 * alpha < 1. 1485 * 1486 * References: 1487 * Cheng, R. C. "The Generation of Gamma Random Variables with Non-integral 1488 * Shape Parameter." Applied Statistics, 26, 71-75, 1977. 1489 * 1490 * Vaduva, I. "Computer Generation of Gamma Gandom Variables by Rejection 1491 * and Composition Procedures." Math. Operationsforschung and Statistik, 1492 * Series in Statistics, 8, 545-576, 1977. 1493 * 1494 * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag, 1495 * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!). 1496 */ 1497 template<typename _RealType> 1498 template<class _UniformRandomNumberGenerator> 1499 typename gamma_distribution<_RealType>::result_type 1500 gamma_distribution<_RealType>:: 1501 operator()(_UniformRandomNumberGenerator& __urng) 1502 { 1503 result_type __x; 1504 1505 bool __reject; 1506 if (_M_alpha >= 1) 1507 { 1508 // alpha - log(4) 1509 const result_type __b = _M_alpha 1510 - result_type(1.3862943611198906188344642429163531L); 1511 const result_type __c = _M_alpha + _M_l_d; 1512 const result_type __1l = 1 / _M_l_d; 1513 1514 // 1 + log(9 / 2) 1515 const result_type __k = 2.5040773967762740733732583523868748L; 1516 1517 do 1518 { 1519 const result_type __u = __urng(); 1520 const result_type __v = __urng(); 1521 1522 const result_type __y = __1l * std::log(__v / (1 - __v)); 1523 __x = _M_alpha * std::exp(__y); 1524 1525 const result_type __z = __u * __v * __v; 1526 const result_type __r = __b + __c * __y - __x; 1527 1528 __reject = __r < result_type(4.5) * __z - __k; 1529 if (__reject) 1530 __reject = __r < std::log(__z); 1531 } 1532 while (__reject); 1533 } 1534 else 1535 { 1536 const result_type __c = 1 / _M_alpha; 1537 1538 do 1539 { 1540 const result_type __z = -std::log(__urng()); 1541 const result_type __e = -std::log(__urng()); 1542 1543 __x = std::pow(__z, __c); 1544 1545 __reject = __z + __e < _M_l_d + __x; 1546 } 1547 while (__reject); 1548 } 1549 1550 return __x; 1551 } 1552 1553 template<typename _RealType, typename _CharT, typename _Traits> 1554 std::basic_ostream<_CharT, _Traits>& 1555 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1556 const gamma_distribution<_RealType>& __x) 1557 { 1558 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 1559 typedef typename __ostream_type::ios_base __ios_base; 1560 1561 const typename __ios_base::fmtflags __flags = __os.flags(); 1562 const _CharT __fill = __os.fill(); 1563 const std::streamsize __precision = __os.precision(); 1564 __os.flags(__ios_base::scientific | __ios_base::left); 1565 __os.fill(__os.widen(' ')); 1566 __os.precision(__gnu_cxx::__numeric_traits<_RealType>::__max_digits10); 1567 1568 __os << __x.alpha(); 1569 1570 __os.flags(__flags); 1571 __os.fill(__fill); 1572 __os.precision(__precision); 1573 return __os; 1574 } 1575 1576 _GLIBCXX_END_NAMESPACE_TR1 1577 } 1578