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