libstdc++
|
00001 // random number generation (out of line) -*- C++ -*- 00002 00003 // Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/random.tcc 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{random} 00028 */ 00029 00030 #ifndef _RANDOM_TCC 00031 #define _RANDOM_TCC 1 00032 00033 #include <numeric> // std::accumulate and std::partial_sum 00034 00035 namespace std _GLIBCXX_VISIBILITY(default) 00036 { 00037 /* 00038 * (Further) implementation-space details. 00039 */ 00040 namespace __detail 00041 { 00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00043 00044 // General case for x = (ax + c) mod m -- use Schrage's algorithm to 00045 // avoid integer overflow. 00046 // 00047 // Because a and c are compile-time integral constants the compiler 00048 // kindly elides any unreachable paths. 00049 // 00050 // Preconditions: a > 0, m > 0. 00051 // 00052 // XXX FIXME: as-is, only works correctly for __m % __a < __m / __a. 00053 // 00054 template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool> 00055 struct _Mod 00056 { 00057 static _Tp 00058 __calc(_Tp __x) 00059 { 00060 if (__a == 1) 00061 __x %= __m; 00062 else 00063 { 00064 static const _Tp __q = __m / __a; 00065 static const _Tp __r = __m % __a; 00066 00067 _Tp __t1 = __a * (__x % __q); 00068 _Tp __t2 = __r * (__x / __q); 00069 if (__t1 >= __t2) 00070 __x = __t1 - __t2; 00071 else 00072 __x = __m - __t2 + __t1; 00073 } 00074 00075 if (__c != 0) 00076 { 00077 const _Tp __d = __m - __x; 00078 if (__d > __c) 00079 __x += __c; 00080 else 00081 __x = __c - __d; 00082 } 00083 return __x; 00084 } 00085 }; 00086 00087 // Special case for m == 0 -- use unsigned integer overflow as modulo 00088 // operator. 00089 template<typename _Tp, _Tp __m, _Tp __a, _Tp __c> 00090 struct _Mod<_Tp, __m, __a, __c, true> 00091 { 00092 static _Tp 00093 __calc(_Tp __x) 00094 { return __a * __x + __c; } 00095 }; 00096 00097 template<typename _InputIterator, typename _OutputIterator, 00098 typename _UnaryOperation> 00099 _OutputIterator 00100 __transform(_InputIterator __first, _InputIterator __last, 00101 _OutputIterator __result, _UnaryOperation __unary_op) 00102 { 00103 for (; __first != __last; ++__first, ++__result) 00104 *__result = __unary_op(*__first); 00105 return __result; 00106 } 00107 00108 _GLIBCXX_END_NAMESPACE_VERSION 00109 } // namespace __detail 00110 00111 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00112 00113 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 00114 constexpr _UIntType 00115 linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier; 00116 00117 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 00118 constexpr _UIntType 00119 linear_congruential_engine<_UIntType, __a, __c, __m>::increment; 00120 00121 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 00122 constexpr _UIntType 00123 linear_congruential_engine<_UIntType, __a, __c, __m>::modulus; 00124 00125 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 00126 constexpr _UIntType 00127 linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed; 00128 00129 /** 00130 * Seeds the LCR with integral value @p __s, adjusted so that the 00131 * ring identity is never a member of the convergence set. 00132 */ 00133 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 00134 void 00135 linear_congruential_engine<_UIntType, __a, __c, __m>:: 00136 seed(result_type __s) 00137 { 00138 if ((__detail::__mod<_UIntType, __m>(__c) == 0) 00139 && (__detail::__mod<_UIntType, __m>(__s) == 0)) 00140 _M_x = 1; 00141 else 00142 _M_x = __detail::__mod<_UIntType, __m>(__s); 00143 } 00144 00145 /** 00146 * Seeds the LCR engine with a value generated by @p __q. 00147 */ 00148 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 00149 template<typename _Sseq> 00150 typename std::enable_if<std::is_class<_Sseq>::value>::type 00151 linear_congruential_engine<_UIntType, __a, __c, __m>:: 00152 seed(_Sseq& __q) 00153 { 00154 const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits 00155 : std::__lg(__m); 00156 const _UIntType __k = (__k0 + 31) / 32; 00157 uint_least32_t __arr[__k + 3]; 00158 __q.generate(__arr + 0, __arr + __k + 3); 00159 _UIntType __factor = 1u; 00160 _UIntType __sum = 0u; 00161 for (size_t __j = 0; __j < __k; ++__j) 00162 { 00163 __sum += __arr[__j + 3] * __factor; 00164 __factor *= __detail::_Shift<_UIntType, 32>::__value; 00165 } 00166 seed(__sum); 00167 } 00168 00169 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 00170 typename _CharT, typename _Traits> 00171 std::basic_ostream<_CharT, _Traits>& 00172 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00173 const linear_congruential_engine<_UIntType, 00174 __a, __c, __m>& __lcr) 00175 { 00176 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00177 typedef typename __ostream_type::ios_base __ios_base; 00178 00179 const typename __ios_base::fmtflags __flags = __os.flags(); 00180 const _CharT __fill = __os.fill(); 00181 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 00182 __os.fill(__os.widen(' ')); 00183 00184 __os << __lcr._M_x; 00185 00186 __os.flags(__flags); 00187 __os.fill(__fill); 00188 return __os; 00189 } 00190 00191 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 00192 typename _CharT, typename _Traits> 00193 std::basic_istream<_CharT, _Traits>& 00194 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00195 linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr) 00196 { 00197 typedef std::basic_istream<_CharT, _Traits> __istream_type; 00198 typedef typename __istream_type::ios_base __ios_base; 00199 00200 const typename __ios_base::fmtflags __flags = __is.flags(); 00201 __is.flags(__ios_base::dec); 00202 00203 __is >> __lcr._M_x; 00204 00205 __is.flags(__flags); 00206 return __is; 00207 } 00208 00209 00210 template<typename _UIntType, 00211 size_t __w, size_t __n, size_t __m, size_t __r, 00212 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00213 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00214 _UIntType __f> 00215 constexpr size_t 00216 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00217 __s, __b, __t, __c, __l, __f>::word_size; 00218 00219 template<typename _UIntType, 00220 size_t __w, size_t __n, size_t __m, size_t __r, 00221 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00222 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00223 _UIntType __f> 00224 constexpr size_t 00225 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00226 __s, __b, __t, __c, __l, __f>::state_size; 00227 00228 template<typename _UIntType, 00229 size_t __w, size_t __n, size_t __m, size_t __r, 00230 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00231 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00232 _UIntType __f> 00233 constexpr size_t 00234 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00235 __s, __b, __t, __c, __l, __f>::shift_size; 00236 00237 template<typename _UIntType, 00238 size_t __w, size_t __n, size_t __m, size_t __r, 00239 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00240 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00241 _UIntType __f> 00242 constexpr size_t 00243 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00244 __s, __b, __t, __c, __l, __f>::mask_bits; 00245 00246 template<typename _UIntType, 00247 size_t __w, size_t __n, size_t __m, size_t __r, 00248 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00249 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00250 _UIntType __f> 00251 constexpr _UIntType 00252 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00253 __s, __b, __t, __c, __l, __f>::xor_mask; 00254 00255 template<typename _UIntType, 00256 size_t __w, size_t __n, size_t __m, size_t __r, 00257 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00258 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00259 _UIntType __f> 00260 constexpr size_t 00261 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00262 __s, __b, __t, __c, __l, __f>::tempering_u; 00263 00264 template<typename _UIntType, 00265 size_t __w, size_t __n, size_t __m, size_t __r, 00266 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00267 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00268 _UIntType __f> 00269 constexpr _UIntType 00270 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00271 __s, __b, __t, __c, __l, __f>::tempering_d; 00272 00273 template<typename _UIntType, 00274 size_t __w, size_t __n, size_t __m, size_t __r, 00275 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00276 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00277 _UIntType __f> 00278 constexpr size_t 00279 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00280 __s, __b, __t, __c, __l, __f>::tempering_s; 00281 00282 template<typename _UIntType, 00283 size_t __w, size_t __n, size_t __m, size_t __r, 00284 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00285 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00286 _UIntType __f> 00287 constexpr _UIntType 00288 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00289 __s, __b, __t, __c, __l, __f>::tempering_b; 00290 00291 template<typename _UIntType, 00292 size_t __w, size_t __n, size_t __m, size_t __r, 00293 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00294 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00295 _UIntType __f> 00296 constexpr size_t 00297 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00298 __s, __b, __t, __c, __l, __f>::tempering_t; 00299 00300 template<typename _UIntType, 00301 size_t __w, size_t __n, size_t __m, size_t __r, 00302 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00303 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00304 _UIntType __f> 00305 constexpr _UIntType 00306 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00307 __s, __b, __t, __c, __l, __f>::tempering_c; 00308 00309 template<typename _UIntType, 00310 size_t __w, size_t __n, size_t __m, size_t __r, 00311 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00312 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00313 _UIntType __f> 00314 constexpr size_t 00315 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00316 __s, __b, __t, __c, __l, __f>::tempering_l; 00317 00318 template<typename _UIntType, 00319 size_t __w, size_t __n, size_t __m, size_t __r, 00320 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00321 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00322 _UIntType __f> 00323 constexpr _UIntType 00324 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00325 __s, __b, __t, __c, __l, __f>:: 00326 initialization_multiplier; 00327 00328 template<typename _UIntType, 00329 size_t __w, size_t __n, size_t __m, size_t __r, 00330 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00331 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00332 _UIntType __f> 00333 constexpr _UIntType 00334 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00335 __s, __b, __t, __c, __l, __f>::default_seed; 00336 00337 template<typename _UIntType, 00338 size_t __w, size_t __n, size_t __m, size_t __r, 00339 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00340 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00341 _UIntType __f> 00342 void 00343 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00344 __s, __b, __t, __c, __l, __f>:: 00345 seed(result_type __sd) 00346 { 00347 _M_x[0] = __detail::__mod<_UIntType, 00348 __detail::_Shift<_UIntType, __w>::__value>(__sd); 00349 00350 for (size_t __i = 1; __i < state_size; ++__i) 00351 { 00352 _UIntType __x = _M_x[__i - 1]; 00353 __x ^= __x >> (__w - 2); 00354 __x *= __f; 00355 __x += __detail::__mod<_UIntType, __n>(__i); 00356 _M_x[__i] = __detail::__mod<_UIntType, 00357 __detail::_Shift<_UIntType, __w>::__value>(__x); 00358 } 00359 _M_p = state_size; 00360 } 00361 00362 template<typename _UIntType, 00363 size_t __w, size_t __n, size_t __m, size_t __r, 00364 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00365 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00366 _UIntType __f> 00367 template<typename _Sseq> 00368 typename std::enable_if<std::is_class<_Sseq>::value>::type 00369 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00370 __s, __b, __t, __c, __l, __f>:: 00371 seed(_Sseq& __q) 00372 { 00373 const _UIntType __upper_mask = (~_UIntType()) << __r; 00374 const size_t __k = (__w + 31) / 32; 00375 uint_least32_t __arr[__n * __k]; 00376 __q.generate(__arr + 0, __arr + __n * __k); 00377 00378 bool __zero = true; 00379 for (size_t __i = 0; __i < state_size; ++__i) 00380 { 00381 _UIntType __factor = 1u; 00382 _UIntType __sum = 0u; 00383 for (size_t __j = 0; __j < __k; ++__j) 00384 { 00385 __sum += __arr[__k * __i + __j] * __factor; 00386 __factor *= __detail::_Shift<_UIntType, 32>::__value; 00387 } 00388 _M_x[__i] = __detail::__mod<_UIntType, 00389 __detail::_Shift<_UIntType, __w>::__value>(__sum); 00390 00391 if (__zero) 00392 { 00393 if (__i == 0) 00394 { 00395 if ((_M_x[0] & __upper_mask) != 0u) 00396 __zero = false; 00397 } 00398 else if (_M_x[__i] != 0u) 00399 __zero = false; 00400 } 00401 } 00402 if (__zero) 00403 _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value; 00404 } 00405 00406 template<typename _UIntType, size_t __w, 00407 size_t __n, size_t __m, size_t __r, 00408 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00409 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00410 _UIntType __f> 00411 typename 00412 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00413 __s, __b, __t, __c, __l, __f>::result_type 00414 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 00415 __s, __b, __t, __c, __l, __f>:: 00416 operator()() 00417 { 00418 // Reload the vector - cost is O(n) amortized over n calls. 00419 if (_M_p >= state_size) 00420 { 00421 const _UIntType __upper_mask = (~_UIntType()) << __r; 00422 const _UIntType __lower_mask = ~__upper_mask; 00423 00424 for (size_t __k = 0; __k < (__n - __m); ++__k) 00425 { 00426 _UIntType __y = ((_M_x[__k] & __upper_mask) 00427 | (_M_x[__k + 1] & __lower_mask)); 00428 _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1) 00429 ^ ((__y & 0x01) ? __a : 0)); 00430 } 00431 00432 for (size_t __k = (__n - __m); __k < (__n - 1); ++__k) 00433 { 00434 _UIntType __y = ((_M_x[__k] & __upper_mask) 00435 | (_M_x[__k + 1] & __lower_mask)); 00436 _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1) 00437 ^ ((__y & 0x01) ? __a : 0)); 00438 } 00439 00440 _UIntType __y = ((_M_x[__n - 1] & __upper_mask) 00441 | (_M_x[0] & __lower_mask)); 00442 _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1) 00443 ^ ((__y & 0x01) ? __a : 0)); 00444 _M_p = 0; 00445 } 00446 00447 // Calculate o(x(i)). 00448 result_type __z = _M_x[_M_p++]; 00449 __z ^= (__z >> __u) & __d; 00450 __z ^= (__z << __s) & __b; 00451 __z ^= (__z << __t) & __c; 00452 __z ^= (__z >> __l); 00453 00454 return __z; 00455 } 00456 00457 template<typename _UIntType, size_t __w, 00458 size_t __n, size_t __m, size_t __r, 00459 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00460 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00461 _UIntType __f, typename _CharT, typename _Traits> 00462 std::basic_ostream<_CharT, _Traits>& 00463 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00464 const mersenne_twister_engine<_UIntType, __w, __n, __m, 00465 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) 00466 { 00467 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00468 typedef typename __ostream_type::ios_base __ios_base; 00469 00470 const typename __ios_base::fmtflags __flags = __os.flags(); 00471 const _CharT __fill = __os.fill(); 00472 const _CharT __space = __os.widen(' '); 00473 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 00474 __os.fill(__space); 00475 00476 for (size_t __i = 0; __i < __n; ++__i) 00477 __os << __x._M_x[__i] << __space; 00478 __os << __x._M_p; 00479 00480 __os.flags(__flags); 00481 __os.fill(__fill); 00482 return __os; 00483 } 00484 00485 template<typename _UIntType, size_t __w, 00486 size_t __n, size_t __m, size_t __r, 00487 _UIntType __a, size_t __u, _UIntType __d, size_t __s, 00488 _UIntType __b, size_t __t, _UIntType __c, size_t __l, 00489 _UIntType __f, typename _CharT, typename _Traits> 00490 std::basic_istream<_CharT, _Traits>& 00491 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00492 mersenne_twister_engine<_UIntType, __w, __n, __m, 00493 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) 00494 { 00495 typedef std::basic_istream<_CharT, _Traits> __istream_type; 00496 typedef typename __istream_type::ios_base __ios_base; 00497 00498 const typename __ios_base::fmtflags __flags = __is.flags(); 00499 __is.flags(__ios_base::dec | __ios_base::skipws); 00500 00501 for (size_t __i = 0; __i < __n; ++__i) 00502 __is >> __x._M_x[__i]; 00503 __is >> __x._M_p; 00504 00505 __is.flags(__flags); 00506 return __is; 00507 } 00508 00509 00510 template<typename _UIntType, size_t __w, size_t __s, size_t __r> 00511 constexpr size_t 00512 subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size; 00513 00514 template<typename _UIntType, size_t __w, size_t __s, size_t __r> 00515 constexpr size_t 00516 subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag; 00517 00518 template<typename _UIntType, size_t __w, size_t __s, size_t __r> 00519 constexpr size_t 00520 subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag; 00521 00522 template<typename _UIntType, size_t __w, size_t __s, size_t __r> 00523 constexpr _UIntType 00524 subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed; 00525 00526 template<typename _UIntType, size_t __w, size_t __s, size_t __r> 00527 void 00528 subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 00529 seed(result_type __value) 00530 { 00531 std::linear_congruential_engine<result_type, 40014u, 0u, 2147483563u> 00532 __lcg(__value == 0u ? default_seed : __value); 00533 00534 const size_t __n = (__w + 31) / 32; 00535 00536 for (size_t __i = 0; __i < long_lag; ++__i) 00537 { 00538 _UIntType __sum = 0u; 00539 _UIntType __factor = 1u; 00540 for (size_t __j = 0; __j < __n; ++__j) 00541 { 00542 __sum += __detail::__mod<uint_least32_t, 00543 __detail::_Shift<uint_least32_t, 32>::__value> 00544 (__lcg()) * __factor; 00545 __factor *= __detail::_Shift<_UIntType, 32>::__value; 00546 } 00547 _M_x[__i] = __detail::__mod<_UIntType, 00548 __detail::_Shift<_UIntType, __w>::__value>(__sum); 00549 } 00550 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 00551 _M_p = 0; 00552 } 00553 00554 template<typename _UIntType, size_t __w, size_t __s, size_t __r> 00555 template<typename _Sseq> 00556 typename std::enable_if<std::is_class<_Sseq>::value>::type 00557 subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 00558 seed(_Sseq& __q) 00559 { 00560 const size_t __k = (__w + 31) / 32; 00561 uint_least32_t __arr[__r * __k]; 00562 __q.generate(__arr + 0, __arr + __r * __k); 00563 00564 for (size_t __i = 0; __i < long_lag; ++__i) 00565 { 00566 _UIntType __sum = 0u; 00567 _UIntType __factor = 1u; 00568 for (size_t __j = 0; __j < __k; ++__j) 00569 { 00570 __sum += __arr[__k * __i + __j] * __factor; 00571 __factor *= __detail::_Shift<_UIntType, 32>::__value; 00572 } 00573 _M_x[__i] = __detail::__mod<_UIntType, 00574 __detail::_Shift<_UIntType, __w>::__value>(__sum); 00575 } 00576 _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 00577 _M_p = 0; 00578 } 00579 00580 template<typename _UIntType, size_t __w, size_t __s, size_t __r> 00581 typename subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 00582 result_type 00583 subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 00584 operator()() 00585 { 00586 // Derive short lag index from current index. 00587 long __ps = _M_p - short_lag; 00588 if (__ps < 0) 00589 __ps += long_lag; 00590 00591 // Calculate new x(i) without overflow or division. 00592 // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry 00593 // cannot overflow. 00594 _UIntType __xi; 00595 if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) 00596 { 00597 __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; 00598 _M_carry = 0; 00599 } 00600 else 00601 { 00602 __xi = (__detail::_Shift<_UIntType, __w>::__value 00603 - _M_x[_M_p] - _M_carry + _M_x[__ps]); 00604 _M_carry = 1; 00605 } 00606 _M_x[_M_p] = __xi; 00607 00608 // Adjust current index to loop around in ring buffer. 00609 if (++_M_p >= long_lag) 00610 _M_p = 0; 00611 00612 return __xi; 00613 } 00614 00615 template<typename _UIntType, size_t __w, size_t __s, size_t __r, 00616 typename _CharT, typename _Traits> 00617 std::basic_ostream<_CharT, _Traits>& 00618 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00619 const subtract_with_carry_engine<_UIntType, 00620 __w, __s, __r>& __x) 00621 { 00622 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00623 typedef typename __ostream_type::ios_base __ios_base; 00624 00625 const typename __ios_base::fmtflags __flags = __os.flags(); 00626 const _CharT __fill = __os.fill(); 00627 const _CharT __space = __os.widen(' '); 00628 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 00629 __os.fill(__space); 00630 00631 for (size_t __i = 0; __i < __r; ++__i) 00632 __os << __x._M_x[__i] << __space; 00633 __os << __x._M_carry << __space << __x._M_p; 00634 00635 __os.flags(__flags); 00636 __os.fill(__fill); 00637 return __os; 00638 } 00639 00640 template<typename _UIntType, size_t __w, size_t __s, size_t __r, 00641 typename _CharT, typename _Traits> 00642 std::basic_istream<_CharT, _Traits>& 00643 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00644 subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x) 00645 { 00646 typedef std::basic_ostream<_CharT, _Traits> __istream_type; 00647 typedef typename __istream_type::ios_base __ios_base; 00648 00649 const typename __ios_base::fmtflags __flags = __is.flags(); 00650 __is.flags(__ios_base::dec | __ios_base::skipws); 00651 00652 for (size_t __i = 0; __i < __r; ++__i) 00653 __is >> __x._M_x[__i]; 00654 __is >> __x._M_carry; 00655 __is >> __x._M_p; 00656 00657 __is.flags(__flags); 00658 return __is; 00659 } 00660 00661 00662 template<typename _RandomNumberEngine, size_t __p, size_t __r> 00663 constexpr size_t 00664 discard_block_engine<_RandomNumberEngine, __p, __r>::block_size; 00665 00666 template<typename _RandomNumberEngine, size_t __p, size_t __r> 00667 constexpr size_t 00668 discard_block_engine<_RandomNumberEngine, __p, __r>::used_block; 00669 00670 template<typename _RandomNumberEngine, size_t __p, size_t __r> 00671 typename discard_block_engine<_RandomNumberEngine, 00672 __p, __r>::result_type 00673 discard_block_engine<_RandomNumberEngine, __p, __r>:: 00674 operator()() 00675 { 00676 if (_M_n >= used_block) 00677 { 00678 _M_b.discard(block_size - _M_n); 00679 _M_n = 0; 00680 } 00681 ++_M_n; 00682 return _M_b(); 00683 } 00684 00685 template<typename _RandomNumberEngine, size_t __p, size_t __r, 00686 typename _CharT, typename _Traits> 00687 std::basic_ostream<_CharT, _Traits>& 00688 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00689 const discard_block_engine<_RandomNumberEngine, 00690 __p, __r>& __x) 00691 { 00692 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00693 typedef typename __ostream_type::ios_base __ios_base; 00694 00695 const typename __ios_base::fmtflags __flags = __os.flags(); 00696 const _CharT __fill = __os.fill(); 00697 const _CharT __space = __os.widen(' '); 00698 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 00699 __os.fill(__space); 00700 00701 __os << __x.base() << __space << __x._M_n; 00702 00703 __os.flags(__flags); 00704 __os.fill(__fill); 00705 return __os; 00706 } 00707 00708 template<typename _RandomNumberEngine, size_t __p, size_t __r, 00709 typename _CharT, typename _Traits> 00710 std::basic_istream<_CharT, _Traits>& 00711 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00712 discard_block_engine<_RandomNumberEngine, __p, __r>& __x) 00713 { 00714 typedef std::basic_istream<_CharT, _Traits> __istream_type; 00715 typedef typename __istream_type::ios_base __ios_base; 00716 00717 const typename __ios_base::fmtflags __flags = __is.flags(); 00718 __is.flags(__ios_base::dec | __ios_base::skipws); 00719 00720 __is >> __x._M_b >> __x._M_n; 00721 00722 __is.flags(__flags); 00723 return __is; 00724 } 00725 00726 00727 template<typename _RandomNumberEngine, size_t __w, typename _UIntType> 00728 typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: 00729 result_type 00730 independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: 00731 operator()() 00732 { 00733 const long double __r = static_cast<long double>(_M_b.max()) 00734 - static_cast<long double>(_M_b.min()) + 1.0L; 00735 const result_type __m = std::log(__r) / std::log(2.0L); 00736 result_type __n, __n0, __y0, __y1, __s0, __s1; 00737 for (size_t __i = 0; __i < 2; ++__i) 00738 { 00739 __n = (__w + __m - 1) / __m + __i; 00740 __n0 = __n - __w % __n; 00741 const result_type __w0 = __w / __n; 00742 const result_type __w1 = __w0 + 1; 00743 __s0 = result_type(1) << __w0; 00744 __s1 = result_type(1) << __w1; 00745 __y0 = __s0 * (__r / __s0); 00746 __y1 = __s1 * (__r / __s1); 00747 if (__r - __y0 <= __y0 / __n) 00748 break; 00749 } 00750 00751 result_type __sum = 0; 00752 for (size_t __k = 0; __k < __n0; ++__k) 00753 { 00754 result_type __u; 00755 do 00756 __u = _M_b() - _M_b.min(); 00757 while (__u >= __y0); 00758 __sum = __s0 * __sum + __u % __s0; 00759 } 00760 for (size_t __k = __n0; __k < __n; ++__k) 00761 { 00762 result_type __u; 00763 do 00764 __u = _M_b() - _M_b.min(); 00765 while (__u >= __y1); 00766 __sum = __s1 * __sum + __u % __s1; 00767 } 00768 return __sum; 00769 } 00770 00771 00772 template<typename _RandomNumberEngine, size_t __k> 00773 constexpr size_t 00774 shuffle_order_engine<_RandomNumberEngine, __k>::table_size; 00775 00776 template<typename _RandomNumberEngine, size_t __k> 00777 typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type 00778 shuffle_order_engine<_RandomNumberEngine, __k>:: 00779 operator()() 00780 { 00781 size_t __j = __k * ((_M_y - _M_b.min()) 00782 / (_M_b.max() - _M_b.min() + 1.0L)); 00783 _M_y = _M_v[__j]; 00784 _M_v[__j] = _M_b(); 00785 00786 return _M_y; 00787 } 00788 00789 template<typename _RandomNumberEngine, size_t __k, 00790 typename _CharT, typename _Traits> 00791 std::basic_ostream<_CharT, _Traits>& 00792 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00793 const shuffle_order_engine<_RandomNumberEngine, __k>& __x) 00794 { 00795 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00796 typedef typename __ostream_type::ios_base __ios_base; 00797 00798 const typename __ios_base::fmtflags __flags = __os.flags(); 00799 const _CharT __fill = __os.fill(); 00800 const _CharT __space = __os.widen(' '); 00801 __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 00802 __os.fill(__space); 00803 00804 __os << __x.base(); 00805 for (size_t __i = 0; __i < __k; ++__i) 00806 __os << __space << __x._M_v[__i]; 00807 __os << __space << __x._M_y; 00808 00809 __os.flags(__flags); 00810 __os.fill(__fill); 00811 return __os; 00812 } 00813 00814 template<typename _RandomNumberEngine, size_t __k, 00815 typename _CharT, typename _Traits> 00816 std::basic_istream<_CharT, _Traits>& 00817 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00818 shuffle_order_engine<_RandomNumberEngine, __k>& __x) 00819 { 00820 typedef std::basic_istream<_CharT, _Traits> __istream_type; 00821 typedef typename __istream_type::ios_base __ios_base; 00822 00823 const typename __ios_base::fmtflags __flags = __is.flags(); 00824 __is.flags(__ios_base::dec | __ios_base::skipws); 00825 00826 __is >> __x._M_b; 00827 for (size_t __i = 0; __i < __k; ++__i) 00828 __is >> __x._M_v[__i]; 00829 __is >> __x._M_y; 00830 00831 __is.flags(__flags); 00832 return __is; 00833 } 00834 00835 00836 template<typename _IntType> 00837 template<typename _UniformRandomNumberGenerator> 00838 typename uniform_int_distribution<_IntType>::result_type 00839 uniform_int_distribution<_IntType>:: 00840 operator()(_UniformRandomNumberGenerator& __urng, 00841 const param_type& __param) 00842 { 00843 typedef typename std::make_unsigned<typename 00844 _UniformRandomNumberGenerator::result_type>::type __urngtype; 00845 typedef typename std::make_unsigned<result_type>::type __utype; 00846 typedef typename std::conditional<(sizeof(__urngtype) 00847 > sizeof(__utype)), 00848 __urngtype, __utype>::type __uctype; 00849 00850 const __uctype __urngmin = __urng.min(); 00851 const __uctype __urngmax = __urng.max(); 00852 const __uctype __urngrange = __urngmax - __urngmin; 00853 const __uctype __urange 00854 = __uctype(__param.b()) - __uctype(__param.a()); 00855 00856 __uctype __ret; 00857 00858 if (__urngrange > __urange) 00859 { 00860 // downscaling 00861 const __uctype __uerange = __urange + 1; // __urange can be zero 00862 const __uctype __scaling = __urngrange / __uerange; 00863 const __uctype __past = __uerange * __scaling; 00864 do 00865 __ret = __uctype(__urng()) - __urngmin; 00866 while (__ret >= __past); 00867 __ret /= __scaling; 00868 } 00869 else if (__urngrange < __urange) 00870 { 00871 // upscaling 00872 /* 00873 Note that every value in [0, urange] 00874 can be written uniquely as 00875 00876 (urngrange + 1) * high + low 00877 00878 where 00879 00880 high in [0, urange / (urngrange + 1)] 00881 00882 and 00883 00884 low in [0, urngrange]. 00885 */ 00886 __uctype __tmp; // wraparound control 00887 do 00888 { 00889 const __uctype __uerngrange = __urngrange + 1; 00890 __tmp = (__uerngrange * operator() 00891 (__urng, param_type(0, __urange / __uerngrange))); 00892 __ret = __tmp + (__uctype(__urng()) - __urngmin); 00893 } 00894 while (__ret > __urange || __ret < __tmp); 00895 } 00896 else 00897 __ret = __uctype(__urng()) - __urngmin; 00898 00899 return __ret + __param.a(); 00900 } 00901 00902 template<typename _IntType, typename _CharT, typename _Traits> 00903 std::basic_ostream<_CharT, _Traits>& 00904 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00905 const uniform_int_distribution<_IntType>& __x) 00906 { 00907 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00908 typedef typename __ostream_type::ios_base __ios_base; 00909 00910 const typename __ios_base::fmtflags __flags = __os.flags(); 00911 const _CharT __fill = __os.fill(); 00912 const _CharT __space = __os.widen(' '); 00913 __os.flags(__ios_base::scientific | __ios_base::left); 00914 __os.fill(__space); 00915 00916 __os << __x.a() << __space << __x.b(); 00917 00918 __os.flags(__flags); 00919 __os.fill(__fill); 00920 return __os; 00921 } 00922 00923 template<typename _IntType, typename _CharT, typename _Traits> 00924 std::basic_istream<_CharT, _Traits>& 00925 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00926 uniform_int_distribution<_IntType>& __x) 00927 { 00928 typedef std::basic_istream<_CharT, _Traits> __istream_type; 00929 typedef typename __istream_type::ios_base __ios_base; 00930 00931 const typename __ios_base::fmtflags __flags = __is.flags(); 00932 __is.flags(__ios_base::dec | __ios_base::skipws); 00933 00934 _IntType __a, __b; 00935 __is >> __a >> __b; 00936 __x.param(typename uniform_int_distribution<_IntType>:: 00937 param_type(__a, __b)); 00938 00939 __is.flags(__flags); 00940 return __is; 00941 } 00942 00943 00944 template<typename _RealType, typename _CharT, typename _Traits> 00945 std::basic_ostream<_CharT, _Traits>& 00946 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00947 const uniform_real_distribution<_RealType>& __x) 00948 { 00949 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00950 typedef typename __ostream_type::ios_base __ios_base; 00951 00952 const typename __ios_base::fmtflags __flags = __os.flags(); 00953 const _CharT __fill = __os.fill(); 00954 const std::streamsize __precision = __os.precision(); 00955 const _CharT __space = __os.widen(' '); 00956 __os.flags(__ios_base::scientific | __ios_base::left); 00957 __os.fill(__space); 00958 __os.precision(std::numeric_limits<_RealType>::max_digits10); 00959 00960 __os << __x.a() << __space << __x.b(); 00961 00962 __os.flags(__flags); 00963 __os.fill(__fill); 00964 __os.precision(__precision); 00965 return __os; 00966 } 00967 00968 template<typename _RealType, typename _CharT, typename _Traits> 00969 std::basic_istream<_CharT, _Traits>& 00970 operator>>(std::basic_istream<_CharT, _Traits>& __is, 00971 uniform_real_distribution<_RealType>& __x) 00972 { 00973 typedef std::basic_istream<_CharT, _Traits> __istream_type; 00974 typedef typename __istream_type::ios_base __ios_base; 00975 00976 const typename __ios_base::fmtflags __flags = __is.flags(); 00977 __is.flags(__ios_base::skipws); 00978 00979 _RealType __a, __b; 00980 __is >> __a >> __b; 00981 __x.param(typename uniform_real_distribution<_RealType>:: 00982 param_type(__a, __b)); 00983 00984 __is.flags(__flags); 00985 return __is; 00986 } 00987 00988 00989 template<typename _CharT, typename _Traits> 00990 std::basic_ostream<_CharT, _Traits>& 00991 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 00992 const bernoulli_distribution& __x) 00993 { 00994 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 00995 typedef typename __ostream_type::ios_base __ios_base; 00996 00997 const typename __ios_base::fmtflags __flags = __os.flags(); 00998 const _CharT __fill = __os.fill(); 00999 const std::streamsize __precision = __os.precision(); 01000 __os.flags(__ios_base::scientific | __ios_base::left); 01001 __os.fill(__os.widen(' ')); 01002 __os.precision(std::numeric_limits<double>::max_digits10); 01003 01004 __os << __x.p(); 01005 01006 __os.flags(__flags); 01007 __os.fill(__fill); 01008 __os.precision(__precision); 01009 return __os; 01010 } 01011 01012 01013 template<typename _IntType> 01014 template<typename _UniformRandomNumberGenerator> 01015 typename geometric_distribution<_IntType>::result_type 01016 geometric_distribution<_IntType>:: 01017 operator()(_UniformRandomNumberGenerator& __urng, 01018 const param_type& __param) 01019 { 01020 // About the epsilon thing see this thread: 01021 // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html 01022 const double __naf = 01023 (1 - std::numeric_limits<double>::epsilon()) / 2; 01024 // The largest _RealType convertible to _IntType. 01025 const double __thr = 01026 std::numeric_limits<_IntType>::max() + __naf; 01027 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 01028 __aurng(__urng); 01029 01030 double __cand; 01031 do 01032 __cand = std::floor(std::log(__aurng()) / __param._M_log_1_p); 01033 while (__cand >= __thr); 01034 01035 return result_type(__cand + __naf); 01036 } 01037 01038 template<typename _IntType, 01039 typename _CharT, typename _Traits> 01040 std::basic_ostream<_CharT, _Traits>& 01041 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01042 const geometric_distribution<_IntType>& __x) 01043 { 01044 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01045 typedef typename __ostream_type::ios_base __ios_base; 01046 01047 const typename __ios_base::fmtflags __flags = __os.flags(); 01048 const _CharT __fill = __os.fill(); 01049 const std::streamsize __precision = __os.precision(); 01050 __os.flags(__ios_base::scientific | __ios_base::left); 01051 __os.fill(__os.widen(' ')); 01052 __os.precision(std::numeric_limits<double>::max_digits10); 01053 01054 __os << __x.p(); 01055 01056 __os.flags(__flags); 01057 __os.fill(__fill); 01058 __os.precision(__precision); 01059 return __os; 01060 } 01061 01062 template<typename _IntType, 01063 typename _CharT, typename _Traits> 01064 std::basic_istream<_CharT, _Traits>& 01065 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01066 geometric_distribution<_IntType>& __x) 01067 { 01068 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01069 typedef typename __istream_type::ios_base __ios_base; 01070 01071 const typename __ios_base::fmtflags __flags = __is.flags(); 01072 __is.flags(__ios_base::skipws); 01073 01074 double __p; 01075 __is >> __p; 01076 __x.param(typename geometric_distribution<_IntType>::param_type(__p)); 01077 01078 __is.flags(__flags); 01079 return __is; 01080 } 01081 01082 // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5. 01083 template<typename _IntType> 01084 template<typename _UniformRandomNumberGenerator> 01085 typename negative_binomial_distribution<_IntType>::result_type 01086 negative_binomial_distribution<_IntType>:: 01087 operator()(_UniformRandomNumberGenerator& __urng) 01088 { 01089 const double __y = _M_gd(__urng); 01090 01091 // XXX Is the constructor too slow? 01092 std::poisson_distribution<result_type> __poisson(__y); 01093 return __poisson(__urng); 01094 } 01095 01096 template<typename _IntType> 01097 template<typename _UniformRandomNumberGenerator> 01098 typename negative_binomial_distribution<_IntType>::result_type 01099 negative_binomial_distribution<_IntType>:: 01100 operator()(_UniformRandomNumberGenerator& __urng, 01101 const param_type& __p) 01102 { 01103 typedef typename std::gamma_distribution<result_type>::param_type 01104 param_type; 01105 01106 const double __y = 01107 _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p())); 01108 01109 std::poisson_distribution<result_type> __poisson(__y); 01110 return __poisson(__urng); 01111 } 01112 01113 template<typename _IntType, typename _CharT, typename _Traits> 01114 std::basic_ostream<_CharT, _Traits>& 01115 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01116 const negative_binomial_distribution<_IntType>& __x) 01117 { 01118 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01119 typedef typename __ostream_type::ios_base __ios_base; 01120 01121 const typename __ios_base::fmtflags __flags = __os.flags(); 01122 const _CharT __fill = __os.fill(); 01123 const std::streamsize __precision = __os.precision(); 01124 const _CharT __space = __os.widen(' '); 01125 __os.flags(__ios_base::scientific | __ios_base::left); 01126 __os.fill(__os.widen(' ')); 01127 __os.precision(std::numeric_limits<double>::max_digits10); 01128 01129 __os << __x.k() << __space << __x.p() 01130 << __space << __x._M_gd; 01131 01132 __os.flags(__flags); 01133 __os.fill(__fill); 01134 __os.precision(__precision); 01135 return __os; 01136 } 01137 01138 template<typename _IntType, typename _CharT, typename _Traits> 01139 std::basic_istream<_CharT, _Traits>& 01140 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01141 negative_binomial_distribution<_IntType>& __x) 01142 { 01143 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01144 typedef typename __istream_type::ios_base __ios_base; 01145 01146 const typename __ios_base::fmtflags __flags = __is.flags(); 01147 __is.flags(__ios_base::skipws); 01148 01149 _IntType __k; 01150 double __p; 01151 __is >> __k >> __p >> __x._M_gd; 01152 __x.param(typename negative_binomial_distribution<_IntType>:: 01153 param_type(__k, __p)); 01154 01155 __is.flags(__flags); 01156 return __is; 01157 } 01158 01159 01160 template<typename _IntType> 01161 void 01162 poisson_distribution<_IntType>::param_type:: 01163 _M_initialize() 01164 { 01165 #if _GLIBCXX_USE_C99_MATH_TR1 01166 if (_M_mean >= 12) 01167 { 01168 const double __m = std::floor(_M_mean); 01169 _M_lm_thr = std::log(_M_mean); 01170 _M_lfm = std::lgamma(__m + 1); 01171 _M_sm = std::sqrt(__m); 01172 01173 const double __pi_4 = 0.7853981633974483096156608458198757L; 01174 const double __dx = std::sqrt(2 * __m * std::log(32 * __m 01175 / __pi_4)); 01176 _M_d = std::round(std::max(6.0, std::min(__m, __dx))); 01177 const double __cx = 2 * __m + _M_d; 01178 _M_scx = std::sqrt(__cx / 2); 01179 _M_1cx = 1 / __cx; 01180 01181 _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx); 01182 _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) 01183 / _M_d; 01184 } 01185 else 01186 #endif 01187 _M_lm_thr = std::exp(-_M_mean); 01188 } 01189 01190 /** 01191 * A rejection algorithm when mean >= 12 and a simple method based 01192 * upon the multiplication of uniform random variates otherwise. 01193 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 01194 * is defined. 01195 * 01196 * Reference: 01197 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 01198 * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!). 01199 */ 01200 template<typename _IntType> 01201 template<typename _UniformRandomNumberGenerator> 01202 typename poisson_distribution<_IntType>::result_type 01203 poisson_distribution<_IntType>:: 01204 operator()(_UniformRandomNumberGenerator& __urng, 01205 const param_type& __param) 01206 { 01207 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 01208 __aurng(__urng); 01209 #if _GLIBCXX_USE_C99_MATH_TR1 01210 if (__param.mean() >= 12) 01211 { 01212 double __x; 01213 01214 // See comments above... 01215 const double __naf = 01216 (1 - std::numeric_limits<double>::epsilon()) / 2; 01217 const double __thr = 01218 std::numeric_limits<_IntType>::max() + __naf; 01219 01220 const double __m = std::floor(__param.mean()); 01221 // sqrt(pi / 2) 01222 const double __spi_2 = 1.2533141373155002512078826424055226L; 01223 const double __c1 = __param._M_sm * __spi_2; 01224 const double __c2 = __param._M_c2b + __c1; 01225 const double __c3 = __c2 + 1; 01226 const double __c4 = __c3 + 1; 01227 // e^(1 / 78) 01228 const double __e178 = 1.0129030479320018583185514777512983L; 01229 const double __c5 = __c4 + __e178; 01230 const double __c = __param._M_cb + __c5; 01231 const double __2cx = 2 * (2 * __m + __param._M_d); 01232 01233 bool __reject = true; 01234 do 01235 { 01236 const double __u = __c * __aurng(); 01237 const double __e = -std::log(__aurng()); 01238 01239 double __w = 0.0; 01240 01241 if (__u <= __c1) 01242 { 01243 const double __n = _M_nd(__urng); 01244 const double __y = -std::abs(__n) * __param._M_sm - 1; 01245 __x = std::floor(__y); 01246 __w = -__n * __n / 2; 01247 if (__x < -__m) 01248 continue; 01249 } 01250 else if (__u <= __c2) 01251 { 01252 const double __n = _M_nd(__urng); 01253 const double __y = 1 + std::abs(__n) * __param._M_scx; 01254 __x = std::ceil(__y); 01255 __w = __y * (2 - __y) * __param._M_1cx; 01256 if (__x > __param._M_d) 01257 continue; 01258 } 01259 else if (__u <= __c3) 01260 // NB: This case not in the book, nor in the Errata, 01261 // but should be ok... 01262 __x = -1; 01263 else if (__u <= __c4) 01264 __x = 0; 01265 else if (__u <= __c5) 01266 __x = 1; 01267 else 01268 { 01269 const double __v = -std::log(__aurng()); 01270 const double __y = __param._M_d 01271 + __v * __2cx / __param._M_d; 01272 __x = std::ceil(__y); 01273 __w = -__param._M_d * __param._M_1cx * (1 + __y / 2); 01274 } 01275 01276 __reject = (__w - __e - __x * __param._M_lm_thr 01277 > __param._M_lfm - std::lgamma(__x + __m + 1)); 01278 01279 __reject |= __x + __m >= __thr; 01280 01281 } while (__reject); 01282 01283 return result_type(__x + __m + __naf); 01284 } 01285 else 01286 #endif 01287 { 01288 _IntType __x = 0; 01289 double __prod = 1.0; 01290 01291 do 01292 { 01293 __prod *= __aurng(); 01294 __x += 1; 01295 } 01296 while (__prod > __param._M_lm_thr); 01297 01298 return __x - 1; 01299 } 01300 } 01301 01302 template<typename _IntType, 01303 typename _CharT, typename _Traits> 01304 std::basic_ostream<_CharT, _Traits>& 01305 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01306 const poisson_distribution<_IntType>& __x) 01307 { 01308 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01309 typedef typename __ostream_type::ios_base __ios_base; 01310 01311 const typename __ios_base::fmtflags __flags = __os.flags(); 01312 const _CharT __fill = __os.fill(); 01313 const std::streamsize __precision = __os.precision(); 01314 const _CharT __space = __os.widen(' '); 01315 __os.flags(__ios_base::scientific | __ios_base::left); 01316 __os.fill(__space); 01317 __os.precision(std::numeric_limits<double>::max_digits10); 01318 01319 __os << __x.mean() << __space << __x._M_nd; 01320 01321 __os.flags(__flags); 01322 __os.fill(__fill); 01323 __os.precision(__precision); 01324 return __os; 01325 } 01326 01327 template<typename _IntType, 01328 typename _CharT, typename _Traits> 01329 std::basic_istream<_CharT, _Traits>& 01330 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01331 poisson_distribution<_IntType>& __x) 01332 { 01333 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01334 typedef typename __istream_type::ios_base __ios_base; 01335 01336 const typename __ios_base::fmtflags __flags = __is.flags(); 01337 __is.flags(__ios_base::skipws); 01338 01339 double __mean; 01340 __is >> __mean >> __x._M_nd; 01341 __x.param(typename poisson_distribution<_IntType>::param_type(__mean)); 01342 01343 __is.flags(__flags); 01344 return __is; 01345 } 01346 01347 01348 template<typename _IntType> 01349 void 01350 binomial_distribution<_IntType>::param_type:: 01351 _M_initialize() 01352 { 01353 const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; 01354 01355 _M_easy = true; 01356 01357 #if _GLIBCXX_USE_C99_MATH_TR1 01358 if (_M_t * __p12 >= 8) 01359 { 01360 _M_easy = false; 01361 const double __np = std::floor(_M_t * __p12); 01362 const double __pa = __np / _M_t; 01363 const double __1p = 1 - __pa; 01364 01365 const double __pi_4 = 0.7853981633974483096156608458198757L; 01366 const double __d1x = 01367 std::sqrt(__np * __1p * std::log(32 * __np 01368 / (81 * __pi_4 * __1p))); 01369 _M_d1 = std::round(std::max(1.0, __d1x)); 01370 const double __d2x = 01371 std::sqrt(__np * __1p * std::log(32 * _M_t * __1p 01372 / (__pi_4 * __pa))); 01373 _M_d2 = std::round(std::max(1.0, __d2x)); 01374 01375 // sqrt(pi / 2) 01376 const double __spi_2 = 1.2533141373155002512078826424055226L; 01377 _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np)); 01378 _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p)); 01379 _M_c = 2 * _M_d1 / __np; 01380 _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2; 01381 const double __a12 = _M_a1 + _M_s2 * __spi_2; 01382 const double __s1s = _M_s1 * _M_s1; 01383 _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p)) 01384 * 2 * __s1s / _M_d1 01385 * std::exp(-_M_d1 * _M_d1 / (2 * __s1s))); 01386 const double __s2s = _M_s2 * _M_s2; 01387 _M_s = (_M_a123 + 2 * __s2s / _M_d2 01388 * std::exp(-_M_d2 * _M_d2 / (2 * __s2s))); 01389 _M_lf = (std::lgamma(__np + 1) 01390 + std::lgamma(_M_t - __np + 1)); 01391 _M_lp1p = std::log(__pa / __1p); 01392 01393 _M_q = -std::log(1 - (__p12 - __pa) / __1p); 01394 } 01395 else 01396 #endif 01397 _M_q = -std::log(1 - __p12); 01398 } 01399 01400 template<typename _IntType> 01401 template<typename _UniformRandomNumberGenerator> 01402 typename binomial_distribution<_IntType>::result_type 01403 binomial_distribution<_IntType>:: 01404 _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t) 01405 { 01406 _IntType __x = 0; 01407 double __sum = 0.0; 01408 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 01409 __aurng(__urng); 01410 01411 do 01412 { 01413 const double __e = -std::log(__aurng()); 01414 __sum += __e / (__t - __x); 01415 __x += 1; 01416 } 01417 while (__sum <= _M_param._M_q); 01418 01419 return __x - 1; 01420 } 01421 01422 /** 01423 * A rejection algorithm when t * p >= 8 and a simple waiting time 01424 * method - the second in the referenced book - otherwise. 01425 * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 01426 * is defined. 01427 * 01428 * Reference: 01429 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 01430 * New York, 1986, Ch. X, Sect. 4 (+ Errata!). 01431 */ 01432 template<typename _IntType> 01433 template<typename _UniformRandomNumberGenerator> 01434 typename binomial_distribution<_IntType>::result_type 01435 binomial_distribution<_IntType>:: 01436 operator()(_UniformRandomNumberGenerator& __urng, 01437 const param_type& __param) 01438 { 01439 result_type __ret; 01440 const _IntType __t = __param.t(); 01441 const double __p = __param.p(); 01442 const double __p12 = __p <= 0.5 ? __p : 1.0 - __p; 01443 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 01444 __aurng(__urng); 01445 01446 #if _GLIBCXX_USE_C99_MATH_TR1 01447 if (!__param._M_easy) 01448 { 01449 double __x; 01450 01451 // See comments above... 01452 const double __naf = 01453 (1 - std::numeric_limits<double>::epsilon()) / 2; 01454 const double __thr = 01455 std::numeric_limits<_IntType>::max() + __naf; 01456 01457 const double __np = std::floor(__t * __p12); 01458 01459 // sqrt(pi / 2) 01460 const double __spi_2 = 1.2533141373155002512078826424055226L; 01461 const double __a1 = __param._M_a1; 01462 const double __a12 = __a1 + __param._M_s2 * __spi_2; 01463 const double __a123 = __param._M_a123; 01464 const double __s1s = __param._M_s1 * __param._M_s1; 01465 const double __s2s = __param._M_s2 * __param._M_s2; 01466 01467 bool __reject; 01468 do 01469 { 01470 const double __u = __param._M_s * __aurng(); 01471 01472 double __v; 01473 01474 if (__u <= __a1) 01475 { 01476 const double __n = _M_nd(__urng); 01477 const double __y = __param._M_s1 * std::abs(__n); 01478 __reject = __y >= __param._M_d1; 01479 if (!__reject) 01480 { 01481 const double __e = -std::log(__aurng()); 01482 __x = std::floor(__y); 01483 __v = -__e - __n * __n / 2 + __param._M_c; 01484 } 01485 } 01486 else if (__u <= __a12) 01487 { 01488 const double __n = _M_nd(__urng); 01489 const double __y = __param._M_s2 * std::abs(__n); 01490 __reject = __y >= __param._M_d2; 01491 if (!__reject) 01492 { 01493 const double __e = -std::log(__aurng()); 01494 __x = std::floor(-__y); 01495 __v = -__e - __n * __n / 2; 01496 } 01497 } 01498 else if (__u <= __a123) 01499 { 01500 const double __e1 = -std::log(__aurng()); 01501 const double __e2 = -std::log(__aurng()); 01502 01503 const double __y = __param._M_d1 01504 + 2 * __s1s * __e1 / __param._M_d1; 01505 __x = std::floor(__y); 01506 __v = (-__e2 + __param._M_d1 * (1 / (__t - __np) 01507 -__y / (2 * __s1s))); 01508 __reject = false; 01509 } 01510 else 01511 { 01512 const double __e1 = -std::log(__aurng()); 01513 const double __e2 = -std::log(__aurng()); 01514 01515 const double __y = __param._M_d2 01516 + 2 * __s2s * __e1 / __param._M_d2; 01517 __x = std::floor(-__y); 01518 __v = -__e2 - __param._M_d2 * __y / (2 * __s2s); 01519 __reject = false; 01520 } 01521 01522 __reject = __reject || __x < -__np || __x > __t - __np; 01523 if (!__reject) 01524 { 01525 const double __lfx = 01526 std::lgamma(__np + __x + 1) 01527 + std::lgamma(__t - (__np + __x) + 1); 01528 __reject = __v > __param._M_lf - __lfx 01529 + __x * __param._M_lp1p; 01530 } 01531 01532 __reject |= __x + __np >= __thr; 01533 } 01534 while (__reject); 01535 01536 __x += __np + __naf; 01537 01538 const _IntType __z = _M_waiting(__urng, __t - _IntType(__x)); 01539 __ret = _IntType(__x) + __z; 01540 } 01541 else 01542 #endif 01543 __ret = _M_waiting(__urng, __t); 01544 01545 if (__p12 != __p) 01546 __ret = __t - __ret; 01547 return __ret; 01548 } 01549 01550 template<typename _IntType, 01551 typename _CharT, typename _Traits> 01552 std::basic_ostream<_CharT, _Traits>& 01553 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01554 const binomial_distribution<_IntType>& __x) 01555 { 01556 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01557 typedef typename __ostream_type::ios_base __ios_base; 01558 01559 const typename __ios_base::fmtflags __flags = __os.flags(); 01560 const _CharT __fill = __os.fill(); 01561 const std::streamsize __precision = __os.precision(); 01562 const _CharT __space = __os.widen(' '); 01563 __os.flags(__ios_base::scientific | __ios_base::left); 01564 __os.fill(__space); 01565 __os.precision(std::numeric_limits<double>::max_digits10); 01566 01567 __os << __x.t() << __space << __x.p() 01568 << __space << __x._M_nd; 01569 01570 __os.flags(__flags); 01571 __os.fill(__fill); 01572 __os.precision(__precision); 01573 return __os; 01574 } 01575 01576 template<typename _IntType, 01577 typename _CharT, typename _Traits> 01578 std::basic_istream<_CharT, _Traits>& 01579 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01580 binomial_distribution<_IntType>& __x) 01581 { 01582 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01583 typedef typename __istream_type::ios_base __ios_base; 01584 01585 const typename __ios_base::fmtflags __flags = __is.flags(); 01586 __is.flags(__ios_base::dec | __ios_base::skipws); 01587 01588 _IntType __t; 01589 double __p; 01590 __is >> __t >> __p >> __x._M_nd; 01591 __x.param(typename binomial_distribution<_IntType>:: 01592 param_type(__t, __p)); 01593 01594 __is.flags(__flags); 01595 return __is; 01596 } 01597 01598 01599 template<typename _RealType, typename _CharT, typename _Traits> 01600 std::basic_ostream<_CharT, _Traits>& 01601 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01602 const exponential_distribution<_RealType>& __x) 01603 { 01604 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01605 typedef typename __ostream_type::ios_base __ios_base; 01606 01607 const typename __ios_base::fmtflags __flags = __os.flags(); 01608 const _CharT __fill = __os.fill(); 01609 const std::streamsize __precision = __os.precision(); 01610 __os.flags(__ios_base::scientific | __ios_base::left); 01611 __os.fill(__os.widen(' ')); 01612 __os.precision(std::numeric_limits<_RealType>::max_digits10); 01613 01614 __os << __x.lambda(); 01615 01616 __os.flags(__flags); 01617 __os.fill(__fill); 01618 __os.precision(__precision); 01619 return __os; 01620 } 01621 01622 template<typename _RealType, typename _CharT, typename _Traits> 01623 std::basic_istream<_CharT, _Traits>& 01624 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01625 exponential_distribution<_RealType>& __x) 01626 { 01627 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01628 typedef typename __istream_type::ios_base __ios_base; 01629 01630 const typename __ios_base::fmtflags __flags = __is.flags(); 01631 __is.flags(__ios_base::dec | __ios_base::skipws); 01632 01633 _RealType __lambda; 01634 __is >> __lambda; 01635 __x.param(typename exponential_distribution<_RealType>:: 01636 param_type(__lambda)); 01637 01638 __is.flags(__flags); 01639 return __is; 01640 } 01641 01642 01643 /** 01644 * Polar method due to Marsaglia. 01645 * 01646 * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 01647 * New York, 1986, Ch. V, Sect. 4.4. 01648 */ 01649 template<typename _RealType> 01650 template<typename _UniformRandomNumberGenerator> 01651 typename normal_distribution<_RealType>::result_type 01652 normal_distribution<_RealType>:: 01653 operator()(_UniformRandomNumberGenerator& __urng, 01654 const param_type& __param) 01655 { 01656 result_type __ret; 01657 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 01658 __aurng(__urng); 01659 01660 if (_M_saved_available) 01661 { 01662 _M_saved_available = false; 01663 __ret = _M_saved; 01664 } 01665 else 01666 { 01667 result_type __x, __y, __r2; 01668 do 01669 { 01670 __x = result_type(2.0) * __aurng() - 1.0; 01671 __y = result_type(2.0) * __aurng() - 1.0; 01672 __r2 = __x * __x + __y * __y; 01673 } 01674 while (__r2 > 1.0 || __r2 == 0.0); 01675 01676 const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 01677 _M_saved = __x * __mult; 01678 _M_saved_available = true; 01679 __ret = __y * __mult; 01680 } 01681 01682 __ret = __ret * __param.stddev() + __param.mean(); 01683 return __ret; 01684 } 01685 01686 template<typename _RealType> 01687 bool 01688 operator==(const std::normal_distribution<_RealType>& __d1, 01689 const std::normal_distribution<_RealType>& __d2) 01690 { 01691 if (__d1._M_param == __d2._M_param 01692 && __d1._M_saved_available == __d2._M_saved_available) 01693 { 01694 if (__d1._M_saved_available 01695 && __d1._M_saved == __d2._M_saved) 01696 return true; 01697 else if(!__d1._M_saved_available) 01698 return true; 01699 else 01700 return false; 01701 } 01702 else 01703 return false; 01704 } 01705 01706 template<typename _RealType, typename _CharT, typename _Traits> 01707 std::basic_ostream<_CharT, _Traits>& 01708 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01709 const normal_distribution<_RealType>& __x) 01710 { 01711 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01712 typedef typename __ostream_type::ios_base __ios_base; 01713 01714 const typename __ios_base::fmtflags __flags = __os.flags(); 01715 const _CharT __fill = __os.fill(); 01716 const std::streamsize __precision = __os.precision(); 01717 const _CharT __space = __os.widen(' '); 01718 __os.flags(__ios_base::scientific | __ios_base::left); 01719 __os.fill(__space); 01720 __os.precision(std::numeric_limits<_RealType>::max_digits10); 01721 01722 __os << __x.mean() << __space << __x.stddev() 01723 << __space << __x._M_saved_available; 01724 if (__x._M_saved_available) 01725 __os << __space << __x._M_saved; 01726 01727 __os.flags(__flags); 01728 __os.fill(__fill); 01729 __os.precision(__precision); 01730 return __os; 01731 } 01732 01733 template<typename _RealType, typename _CharT, typename _Traits> 01734 std::basic_istream<_CharT, _Traits>& 01735 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01736 normal_distribution<_RealType>& __x) 01737 { 01738 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01739 typedef typename __istream_type::ios_base __ios_base; 01740 01741 const typename __ios_base::fmtflags __flags = __is.flags(); 01742 __is.flags(__ios_base::dec | __ios_base::skipws); 01743 01744 double __mean, __stddev; 01745 __is >> __mean >> __stddev 01746 >> __x._M_saved_available; 01747 if (__x._M_saved_available) 01748 __is >> __x._M_saved; 01749 __x.param(typename normal_distribution<_RealType>:: 01750 param_type(__mean, __stddev)); 01751 01752 __is.flags(__flags); 01753 return __is; 01754 } 01755 01756 01757 template<typename _RealType, typename _CharT, typename _Traits> 01758 std::basic_ostream<_CharT, _Traits>& 01759 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01760 const lognormal_distribution<_RealType>& __x) 01761 { 01762 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01763 typedef typename __ostream_type::ios_base __ios_base; 01764 01765 const typename __ios_base::fmtflags __flags = __os.flags(); 01766 const _CharT __fill = __os.fill(); 01767 const std::streamsize __precision = __os.precision(); 01768 const _CharT __space = __os.widen(' '); 01769 __os.flags(__ios_base::scientific | __ios_base::left); 01770 __os.fill(__space); 01771 __os.precision(std::numeric_limits<_RealType>::max_digits10); 01772 01773 __os << __x.m() << __space << __x.s() 01774 << __space << __x._M_nd; 01775 01776 __os.flags(__flags); 01777 __os.fill(__fill); 01778 __os.precision(__precision); 01779 return __os; 01780 } 01781 01782 template<typename _RealType, typename _CharT, typename _Traits> 01783 std::basic_istream<_CharT, _Traits>& 01784 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01785 lognormal_distribution<_RealType>& __x) 01786 { 01787 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01788 typedef typename __istream_type::ios_base __ios_base; 01789 01790 const typename __ios_base::fmtflags __flags = __is.flags(); 01791 __is.flags(__ios_base::dec | __ios_base::skipws); 01792 01793 _RealType __m, __s; 01794 __is >> __m >> __s >> __x._M_nd; 01795 __x.param(typename lognormal_distribution<_RealType>:: 01796 param_type(__m, __s)); 01797 01798 __is.flags(__flags); 01799 return __is; 01800 } 01801 01802 01803 template<typename _RealType, typename _CharT, typename _Traits> 01804 std::basic_ostream<_CharT, _Traits>& 01805 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01806 const chi_squared_distribution<_RealType>& __x) 01807 { 01808 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01809 typedef typename __ostream_type::ios_base __ios_base; 01810 01811 const typename __ios_base::fmtflags __flags = __os.flags(); 01812 const _CharT __fill = __os.fill(); 01813 const std::streamsize __precision = __os.precision(); 01814 const _CharT __space = __os.widen(' '); 01815 __os.flags(__ios_base::scientific | __ios_base::left); 01816 __os.fill(__space); 01817 __os.precision(std::numeric_limits<_RealType>::max_digits10); 01818 01819 __os << __x.n() << __space << __x._M_gd; 01820 01821 __os.flags(__flags); 01822 __os.fill(__fill); 01823 __os.precision(__precision); 01824 return __os; 01825 } 01826 01827 template<typename _RealType, typename _CharT, typename _Traits> 01828 std::basic_istream<_CharT, _Traits>& 01829 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01830 chi_squared_distribution<_RealType>& __x) 01831 { 01832 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01833 typedef typename __istream_type::ios_base __ios_base; 01834 01835 const typename __ios_base::fmtflags __flags = __is.flags(); 01836 __is.flags(__ios_base::dec | __ios_base::skipws); 01837 01838 _RealType __n; 01839 __is >> __n >> __x._M_gd; 01840 __x.param(typename chi_squared_distribution<_RealType>:: 01841 param_type(__n)); 01842 01843 __is.flags(__flags); 01844 return __is; 01845 } 01846 01847 01848 template<typename _RealType> 01849 template<typename _UniformRandomNumberGenerator> 01850 typename cauchy_distribution<_RealType>::result_type 01851 cauchy_distribution<_RealType>:: 01852 operator()(_UniformRandomNumberGenerator& __urng, 01853 const param_type& __p) 01854 { 01855 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 01856 __aurng(__urng); 01857 _RealType __u; 01858 do 01859 __u = __aurng(); 01860 while (__u == 0.5); 01861 01862 const _RealType __pi = 3.1415926535897932384626433832795029L; 01863 return __p.a() + __p.b() * std::tan(__pi * __u); 01864 } 01865 01866 template<typename _RealType, typename _CharT, typename _Traits> 01867 std::basic_ostream<_CharT, _Traits>& 01868 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01869 const cauchy_distribution<_RealType>& __x) 01870 { 01871 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01872 typedef typename __ostream_type::ios_base __ios_base; 01873 01874 const typename __ios_base::fmtflags __flags = __os.flags(); 01875 const _CharT __fill = __os.fill(); 01876 const std::streamsize __precision = __os.precision(); 01877 const _CharT __space = __os.widen(' '); 01878 __os.flags(__ios_base::scientific | __ios_base::left); 01879 __os.fill(__space); 01880 __os.precision(std::numeric_limits<_RealType>::max_digits10); 01881 01882 __os << __x.a() << __space << __x.b(); 01883 01884 __os.flags(__flags); 01885 __os.fill(__fill); 01886 __os.precision(__precision); 01887 return __os; 01888 } 01889 01890 template<typename _RealType, typename _CharT, typename _Traits> 01891 std::basic_istream<_CharT, _Traits>& 01892 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01893 cauchy_distribution<_RealType>& __x) 01894 { 01895 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01896 typedef typename __istream_type::ios_base __ios_base; 01897 01898 const typename __ios_base::fmtflags __flags = __is.flags(); 01899 __is.flags(__ios_base::dec | __ios_base::skipws); 01900 01901 _RealType __a, __b; 01902 __is >> __a >> __b; 01903 __x.param(typename cauchy_distribution<_RealType>:: 01904 param_type(__a, __b)); 01905 01906 __is.flags(__flags); 01907 return __is; 01908 } 01909 01910 01911 template<typename _RealType, typename _CharT, typename _Traits> 01912 std::basic_ostream<_CharT, _Traits>& 01913 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01914 const fisher_f_distribution<_RealType>& __x) 01915 { 01916 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01917 typedef typename __ostream_type::ios_base __ios_base; 01918 01919 const typename __ios_base::fmtflags __flags = __os.flags(); 01920 const _CharT __fill = __os.fill(); 01921 const std::streamsize __precision = __os.precision(); 01922 const _CharT __space = __os.widen(' '); 01923 __os.flags(__ios_base::scientific | __ios_base::left); 01924 __os.fill(__space); 01925 __os.precision(std::numeric_limits<_RealType>::max_digits10); 01926 01927 __os << __x.m() << __space << __x.n() 01928 << __space << __x._M_gd_x << __space << __x._M_gd_y; 01929 01930 __os.flags(__flags); 01931 __os.fill(__fill); 01932 __os.precision(__precision); 01933 return __os; 01934 } 01935 01936 template<typename _RealType, typename _CharT, typename _Traits> 01937 std::basic_istream<_CharT, _Traits>& 01938 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01939 fisher_f_distribution<_RealType>& __x) 01940 { 01941 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01942 typedef typename __istream_type::ios_base __ios_base; 01943 01944 const typename __ios_base::fmtflags __flags = __is.flags(); 01945 __is.flags(__ios_base::dec | __ios_base::skipws); 01946 01947 _RealType __m, __n; 01948 __is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y; 01949 __x.param(typename fisher_f_distribution<_RealType>:: 01950 param_type(__m, __n)); 01951 01952 __is.flags(__flags); 01953 return __is; 01954 } 01955 01956 01957 template<typename _RealType, typename _CharT, typename _Traits> 01958 std::basic_ostream<_CharT, _Traits>& 01959 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 01960 const student_t_distribution<_RealType>& __x) 01961 { 01962 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 01963 typedef typename __ostream_type::ios_base __ios_base; 01964 01965 const typename __ios_base::fmtflags __flags = __os.flags(); 01966 const _CharT __fill = __os.fill(); 01967 const std::streamsize __precision = __os.precision(); 01968 const _CharT __space = __os.widen(' '); 01969 __os.flags(__ios_base::scientific | __ios_base::left); 01970 __os.fill(__space); 01971 __os.precision(std::numeric_limits<_RealType>::max_digits10); 01972 01973 __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd; 01974 01975 __os.flags(__flags); 01976 __os.fill(__fill); 01977 __os.precision(__precision); 01978 return __os; 01979 } 01980 01981 template<typename _RealType, typename _CharT, typename _Traits> 01982 std::basic_istream<_CharT, _Traits>& 01983 operator>>(std::basic_istream<_CharT, _Traits>& __is, 01984 student_t_distribution<_RealType>& __x) 01985 { 01986 typedef std::basic_istream<_CharT, _Traits> __istream_type; 01987 typedef typename __istream_type::ios_base __ios_base; 01988 01989 const typename __ios_base::fmtflags __flags = __is.flags(); 01990 __is.flags(__ios_base::dec | __ios_base::skipws); 01991 01992 _RealType __n; 01993 __is >> __n >> __x._M_nd >> __x._M_gd; 01994 __x.param(typename student_t_distribution<_RealType>::param_type(__n)); 01995 01996 __is.flags(__flags); 01997 return __is; 01998 } 01999 02000 02001 template<typename _RealType> 02002 void 02003 gamma_distribution<_RealType>::param_type:: 02004 _M_initialize() 02005 { 02006 _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha; 02007 02008 const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0); 02009 _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1); 02010 } 02011 02012 /** 02013 * Marsaglia, G. and Tsang, W. W. 02014 * "A Simple Method for Generating Gamma Variables" 02015 * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000. 02016 */ 02017 template<typename _RealType> 02018 template<typename _UniformRandomNumberGenerator> 02019 typename gamma_distribution<_RealType>::result_type 02020 gamma_distribution<_RealType>:: 02021 operator()(_UniformRandomNumberGenerator& __urng, 02022 const param_type& __param) 02023 { 02024 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 02025 __aurng(__urng); 02026 02027 result_type __u, __v, __n; 02028 const result_type __a1 = (__param._M_malpha 02029 - _RealType(1.0) / _RealType(3.0)); 02030 02031 do 02032 { 02033 do 02034 { 02035 __n = _M_nd(__urng); 02036 __v = result_type(1.0) + __param._M_a2 * __n; 02037 } 02038 while (__v <= 0.0); 02039 02040 __v = __v * __v * __v; 02041 __u = __aurng(); 02042 } 02043 while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n 02044 && (std::log(__u) > (0.5 * __n * __n + __a1 02045 * (1.0 - __v + std::log(__v))))); 02046 02047 if (__param.alpha() == __param._M_malpha) 02048 return __a1 * __v * __param.beta(); 02049 else 02050 { 02051 do 02052 __u = __aurng(); 02053 while (__u == 0.0); 02054 02055 return (std::pow(__u, result_type(1.0) / __param.alpha()) 02056 * __a1 * __v * __param.beta()); 02057 } 02058 } 02059 02060 template<typename _RealType, typename _CharT, typename _Traits> 02061 std::basic_ostream<_CharT, _Traits>& 02062 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 02063 const gamma_distribution<_RealType>& __x) 02064 { 02065 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 02066 typedef typename __ostream_type::ios_base __ios_base; 02067 02068 const typename __ios_base::fmtflags __flags = __os.flags(); 02069 const _CharT __fill = __os.fill(); 02070 const std::streamsize __precision = __os.precision(); 02071 const _CharT __space = __os.widen(' '); 02072 __os.flags(__ios_base::scientific | __ios_base::left); 02073 __os.fill(__space); 02074 __os.precision(std::numeric_limits<_RealType>::max_digits10); 02075 02076 __os << __x.alpha() << __space << __x.beta() 02077 << __space << __x._M_nd; 02078 02079 __os.flags(__flags); 02080 __os.fill(__fill); 02081 __os.precision(__precision); 02082 return __os; 02083 } 02084 02085 template<typename _RealType, typename _CharT, typename _Traits> 02086 std::basic_istream<_CharT, _Traits>& 02087 operator>>(std::basic_istream<_CharT, _Traits>& __is, 02088 gamma_distribution<_RealType>& __x) 02089 { 02090 typedef std::basic_istream<_CharT, _Traits> __istream_type; 02091 typedef typename __istream_type::ios_base __ios_base; 02092 02093 const typename __ios_base::fmtflags __flags = __is.flags(); 02094 __is.flags(__ios_base::dec | __ios_base::skipws); 02095 02096 _RealType __alpha_val, __beta_val; 02097 __is >> __alpha_val >> __beta_val >> __x._M_nd; 02098 __x.param(typename gamma_distribution<_RealType>:: 02099 param_type(__alpha_val, __beta_val)); 02100 02101 __is.flags(__flags); 02102 return __is; 02103 } 02104 02105 02106 template<typename _RealType> 02107 template<typename _UniformRandomNumberGenerator> 02108 typename weibull_distribution<_RealType>::result_type 02109 weibull_distribution<_RealType>:: 02110 operator()(_UniformRandomNumberGenerator& __urng, 02111 const param_type& __p) 02112 { 02113 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 02114 __aurng(__urng); 02115 return __p.b() * std::pow(-std::log(__aurng()), 02116 result_type(1) / __p.a()); 02117 } 02118 02119 template<typename _RealType, typename _CharT, typename _Traits> 02120 std::basic_ostream<_CharT, _Traits>& 02121 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 02122 const weibull_distribution<_RealType>& __x) 02123 { 02124 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 02125 typedef typename __ostream_type::ios_base __ios_base; 02126 02127 const typename __ios_base::fmtflags __flags = __os.flags(); 02128 const _CharT __fill = __os.fill(); 02129 const std::streamsize __precision = __os.precision(); 02130 const _CharT __space = __os.widen(' '); 02131 __os.flags(__ios_base::scientific | __ios_base::left); 02132 __os.fill(__space); 02133 __os.precision(std::numeric_limits<_RealType>::max_digits10); 02134 02135 __os << __x.a() << __space << __x.b(); 02136 02137 __os.flags(__flags); 02138 __os.fill(__fill); 02139 __os.precision(__precision); 02140 return __os; 02141 } 02142 02143 template<typename _RealType, typename _CharT, typename _Traits> 02144 std::basic_istream<_CharT, _Traits>& 02145 operator>>(std::basic_istream<_CharT, _Traits>& __is, 02146 weibull_distribution<_RealType>& __x) 02147 { 02148 typedef std::basic_istream<_CharT, _Traits> __istream_type; 02149 typedef typename __istream_type::ios_base __ios_base; 02150 02151 const typename __ios_base::fmtflags __flags = __is.flags(); 02152 __is.flags(__ios_base::dec | __ios_base::skipws); 02153 02154 _RealType __a, __b; 02155 __is >> __a >> __b; 02156 __x.param(typename weibull_distribution<_RealType>:: 02157 param_type(__a, __b)); 02158 02159 __is.flags(__flags); 02160 return __is; 02161 } 02162 02163 02164 template<typename _RealType> 02165 template<typename _UniformRandomNumberGenerator> 02166 typename extreme_value_distribution<_RealType>::result_type 02167 extreme_value_distribution<_RealType>:: 02168 operator()(_UniformRandomNumberGenerator& __urng, 02169 const param_type& __p) 02170 { 02171 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 02172 __aurng(__urng); 02173 return __p.a() - __p.b() * std::log(-std::log(__aurng())); 02174 } 02175 02176 template<typename _RealType, typename _CharT, typename _Traits> 02177 std::basic_ostream<_CharT, _Traits>& 02178 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 02179 const extreme_value_distribution<_RealType>& __x) 02180 { 02181 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 02182 typedef typename __ostream_type::ios_base __ios_base; 02183 02184 const typename __ios_base::fmtflags __flags = __os.flags(); 02185 const _CharT __fill = __os.fill(); 02186 const std::streamsize __precision = __os.precision(); 02187 const _CharT __space = __os.widen(' '); 02188 __os.flags(__ios_base::scientific | __ios_base::left); 02189 __os.fill(__space); 02190 __os.precision(std::numeric_limits<_RealType>::max_digits10); 02191 02192 __os << __x.a() << __space << __x.b(); 02193 02194 __os.flags(__flags); 02195 __os.fill(__fill); 02196 __os.precision(__precision); 02197 return __os; 02198 } 02199 02200 template<typename _RealType, typename _CharT, typename _Traits> 02201 std::basic_istream<_CharT, _Traits>& 02202 operator>>(std::basic_istream<_CharT, _Traits>& __is, 02203 extreme_value_distribution<_RealType>& __x) 02204 { 02205 typedef std::basic_istream<_CharT, _Traits> __istream_type; 02206 typedef typename __istream_type::ios_base __ios_base; 02207 02208 const typename __ios_base::fmtflags __flags = __is.flags(); 02209 __is.flags(__ios_base::dec | __ios_base::skipws); 02210 02211 _RealType __a, __b; 02212 __is >> __a >> __b; 02213 __x.param(typename extreme_value_distribution<_RealType>:: 02214 param_type(__a, __b)); 02215 02216 __is.flags(__flags); 02217 return __is; 02218 } 02219 02220 02221 template<typename _IntType> 02222 void 02223 discrete_distribution<_IntType>::param_type:: 02224 _M_initialize() 02225 { 02226 if (_M_prob.size() < 2) 02227 { 02228 _M_prob.clear(); 02229 return; 02230 } 02231 02232 const double __sum = std::accumulate(_M_prob.begin(), 02233 _M_prob.end(), 0.0); 02234 // Now normalize the probabilites. 02235 __detail::__transform(_M_prob.begin(), _M_prob.end(), _M_prob.begin(), 02236 std::bind2nd(std::divides<double>(), __sum)); 02237 // Accumulate partial sums. 02238 _M_cp.reserve(_M_prob.size()); 02239 std::partial_sum(_M_prob.begin(), _M_prob.end(), 02240 std::back_inserter(_M_cp)); 02241 // Make sure the last cumulative probability is one. 02242 _M_cp[_M_cp.size() - 1] = 1.0; 02243 } 02244 02245 template<typename _IntType> 02246 template<typename _Func> 02247 discrete_distribution<_IntType>::param_type:: 02248 param_type(size_t __nw, double __xmin, double __xmax, _Func __fw) 02249 : _M_prob(), _M_cp() 02250 { 02251 const size_t __n = __nw == 0 ? 1 : __nw; 02252 const double __delta = (__xmax - __xmin) / __n; 02253 02254 _M_prob.reserve(__n); 02255 for (size_t __k = 0; __k < __nw; ++__k) 02256 _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta)); 02257 02258 _M_initialize(); 02259 } 02260 02261 template<typename _IntType> 02262 template<typename _UniformRandomNumberGenerator> 02263 typename discrete_distribution<_IntType>::result_type 02264 discrete_distribution<_IntType>:: 02265 operator()(_UniformRandomNumberGenerator& __urng, 02266 const param_type& __param) 02267 { 02268 if (__param._M_cp.empty()) 02269 return result_type(0); 02270 02271 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 02272 __aurng(__urng); 02273 02274 const double __p = __aurng(); 02275 auto __pos = std::lower_bound(__param._M_cp.begin(), 02276 __param._M_cp.end(), __p); 02277 02278 return __pos - __param._M_cp.begin(); 02279 } 02280 02281 template<typename _IntType, typename _CharT, typename _Traits> 02282 std::basic_ostream<_CharT, _Traits>& 02283 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 02284 const discrete_distribution<_IntType>& __x) 02285 { 02286 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 02287 typedef typename __ostream_type::ios_base __ios_base; 02288 02289 const typename __ios_base::fmtflags __flags = __os.flags(); 02290 const _CharT __fill = __os.fill(); 02291 const std::streamsize __precision = __os.precision(); 02292 const _CharT __space = __os.widen(' '); 02293 __os.flags(__ios_base::scientific | __ios_base::left); 02294 __os.fill(__space); 02295 __os.precision(std::numeric_limits<double>::max_digits10); 02296 02297 std::vector<double> __prob = __x.probabilities(); 02298 __os << __prob.size(); 02299 for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit) 02300 __os << __space << *__dit; 02301 02302 __os.flags(__flags); 02303 __os.fill(__fill); 02304 __os.precision(__precision); 02305 return __os; 02306 } 02307 02308 template<typename _IntType, typename _CharT, typename _Traits> 02309 std::basic_istream<_CharT, _Traits>& 02310 operator>>(std::basic_istream<_CharT, _Traits>& __is, 02311 discrete_distribution<_IntType>& __x) 02312 { 02313 typedef std::basic_istream<_CharT, _Traits> __istream_type; 02314 typedef typename __istream_type::ios_base __ios_base; 02315 02316 const typename __ios_base::fmtflags __flags = __is.flags(); 02317 __is.flags(__ios_base::dec | __ios_base::skipws); 02318 02319 size_t __n; 02320 __is >> __n; 02321 02322 std::vector<double> __prob_vec; 02323 __prob_vec.reserve(__n); 02324 for (; __n != 0; --__n) 02325 { 02326 double __prob; 02327 __is >> __prob; 02328 __prob_vec.push_back(__prob); 02329 } 02330 02331 __x.param(typename discrete_distribution<_IntType>:: 02332 param_type(__prob_vec.begin(), __prob_vec.end())); 02333 02334 __is.flags(__flags); 02335 return __is; 02336 } 02337 02338 02339 template<typename _RealType> 02340 void 02341 piecewise_constant_distribution<_RealType>::param_type:: 02342 _M_initialize() 02343 { 02344 if (_M_int.size() < 2 02345 || (_M_int.size() == 2 02346 && _M_int[0] == _RealType(0) 02347 && _M_int[1] == _RealType(1))) 02348 { 02349 _M_int.clear(); 02350 _M_den.clear(); 02351 return; 02352 } 02353 02354 const double __sum = std::accumulate(_M_den.begin(), 02355 _M_den.end(), 0.0); 02356 02357 __detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(), 02358 std::bind2nd(std::divides<double>(), __sum)); 02359 02360 _M_cp.reserve(_M_den.size()); 02361 std::partial_sum(_M_den.begin(), _M_den.end(), 02362 std::back_inserter(_M_cp)); 02363 02364 // Make sure the last cumulative probability is one. 02365 _M_cp[_M_cp.size() - 1] = 1.0; 02366 02367 for (size_t __k = 0; __k < _M_den.size(); ++__k) 02368 _M_den[__k] /= _M_int[__k + 1] - _M_int[__k]; 02369 } 02370 02371 template<typename _RealType> 02372 template<typename _InputIteratorB, typename _InputIteratorW> 02373 piecewise_constant_distribution<_RealType>::param_type:: 02374 param_type(_InputIteratorB __bbegin, 02375 _InputIteratorB __bend, 02376 _InputIteratorW __wbegin) 02377 : _M_int(), _M_den(), _M_cp() 02378 { 02379 if (__bbegin != __bend) 02380 { 02381 for (;;) 02382 { 02383 _M_int.push_back(*__bbegin); 02384 ++__bbegin; 02385 if (__bbegin == __bend) 02386 break; 02387 02388 _M_den.push_back(*__wbegin); 02389 ++__wbegin; 02390 } 02391 } 02392 02393 _M_initialize(); 02394 } 02395 02396 template<typename _RealType> 02397 template<typename _Func> 02398 piecewise_constant_distribution<_RealType>::param_type:: 02399 param_type(initializer_list<_RealType> __bl, _Func __fw) 02400 : _M_int(), _M_den(), _M_cp() 02401 { 02402 _M_int.reserve(__bl.size()); 02403 for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) 02404 _M_int.push_back(*__biter); 02405 02406 _M_den.reserve(_M_int.size() - 1); 02407 for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) 02408 _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k]))); 02409 02410 _M_initialize(); 02411 } 02412 02413 template<typename _RealType> 02414 template<typename _Func> 02415 piecewise_constant_distribution<_RealType>::param_type:: 02416 param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) 02417 : _M_int(), _M_den(), _M_cp() 02418 { 02419 const size_t __n = __nw == 0 ? 1 : __nw; 02420 const _RealType __delta = (__xmax - __xmin) / __n; 02421 02422 _M_int.reserve(__n + 1); 02423 for (size_t __k = 0; __k <= __nw; ++__k) 02424 _M_int.push_back(__xmin + __k * __delta); 02425 02426 _M_den.reserve(__n); 02427 for (size_t __k = 0; __k < __nw; ++__k) 02428 _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta)); 02429 02430 _M_initialize(); 02431 } 02432 02433 template<typename _RealType> 02434 template<typename _UniformRandomNumberGenerator> 02435 typename piecewise_constant_distribution<_RealType>::result_type 02436 piecewise_constant_distribution<_RealType>:: 02437 operator()(_UniformRandomNumberGenerator& __urng, 02438 const param_type& __param) 02439 { 02440 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 02441 __aurng(__urng); 02442 02443 const double __p = __aurng(); 02444 if (__param._M_cp.empty()) 02445 return __p; 02446 02447 auto __pos = std::lower_bound(__param._M_cp.begin(), 02448 __param._M_cp.end(), __p); 02449 const size_t __i = __pos - __param._M_cp.begin(); 02450 02451 const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 02452 02453 return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i]; 02454 } 02455 02456 template<typename _RealType, typename _CharT, typename _Traits> 02457 std::basic_ostream<_CharT, _Traits>& 02458 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 02459 const piecewise_constant_distribution<_RealType>& __x) 02460 { 02461 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 02462 typedef typename __ostream_type::ios_base __ios_base; 02463 02464 const typename __ios_base::fmtflags __flags = __os.flags(); 02465 const _CharT __fill = __os.fill(); 02466 const std::streamsize __precision = __os.precision(); 02467 const _CharT __space = __os.widen(' '); 02468 __os.flags(__ios_base::scientific | __ios_base::left); 02469 __os.fill(__space); 02470 __os.precision(std::numeric_limits<_RealType>::max_digits10); 02471 02472 std::vector<_RealType> __int = __x.intervals(); 02473 __os << __int.size() - 1; 02474 02475 for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) 02476 __os << __space << *__xit; 02477 02478 std::vector<double> __den = __x.densities(); 02479 for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) 02480 __os << __space << *__dit; 02481 02482 __os.flags(__flags); 02483 __os.fill(__fill); 02484 __os.precision(__precision); 02485 return __os; 02486 } 02487 02488 template<typename _RealType, typename _CharT, typename _Traits> 02489 std::basic_istream<_CharT, _Traits>& 02490 operator>>(std::basic_istream<_CharT, _Traits>& __is, 02491 piecewise_constant_distribution<_RealType>& __x) 02492 { 02493 typedef std::basic_istream<_CharT, _Traits> __istream_type; 02494 typedef typename __istream_type::ios_base __ios_base; 02495 02496 const typename __ios_base::fmtflags __flags = __is.flags(); 02497 __is.flags(__ios_base::dec | __ios_base::skipws); 02498 02499 size_t __n; 02500 __is >> __n; 02501 02502 std::vector<_RealType> __int_vec; 02503 __int_vec.reserve(__n + 1); 02504 for (size_t __i = 0; __i <= __n; ++__i) 02505 { 02506 _RealType __int; 02507 __is >> __int; 02508 __int_vec.push_back(__int); 02509 } 02510 02511 std::vector<double> __den_vec; 02512 __den_vec.reserve(__n); 02513 for (size_t __i = 0; __i < __n; ++__i) 02514 { 02515 double __den; 02516 __is >> __den; 02517 __den_vec.push_back(__den); 02518 } 02519 02520 __x.param(typename piecewise_constant_distribution<_RealType>:: 02521 param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin())); 02522 02523 __is.flags(__flags); 02524 return __is; 02525 } 02526 02527 02528 template<typename _RealType> 02529 void 02530 piecewise_linear_distribution<_RealType>::param_type:: 02531 _M_initialize() 02532 { 02533 if (_M_int.size() < 2 02534 || (_M_int.size() == 2 02535 && _M_int[0] == _RealType(0) 02536 && _M_int[1] == _RealType(1) 02537 && _M_den[0] == _M_den[1])) 02538 { 02539 _M_int.clear(); 02540 _M_den.clear(); 02541 return; 02542 } 02543 02544 double __sum = 0.0; 02545 _M_cp.reserve(_M_int.size() - 1); 02546 _M_m.reserve(_M_int.size() - 1); 02547 for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) 02548 { 02549 const _RealType __delta = _M_int[__k + 1] - _M_int[__k]; 02550 __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta; 02551 _M_cp.push_back(__sum); 02552 _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta); 02553 } 02554 02555 // Now normalize the densities... 02556 __detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(), 02557 std::bind2nd(std::divides<double>(), __sum)); 02558 // ... and partial sums... 02559 __detail::__transform(_M_cp.begin(), _M_cp.end(), _M_cp.begin(), 02560 std::bind2nd(std::divides<double>(), __sum)); 02561 // ... and slopes. 02562 __detail::__transform(_M_m.begin(), _M_m.end(), _M_m.begin(), 02563 std::bind2nd(std::divides<double>(), __sum)); 02564 // Make sure the last cumulative probablility is one. 02565 _M_cp[_M_cp.size() - 1] = 1.0; 02566 } 02567 02568 template<typename _RealType> 02569 template<typename _InputIteratorB, typename _InputIteratorW> 02570 piecewise_linear_distribution<_RealType>::param_type:: 02571 param_type(_InputIteratorB __bbegin, 02572 _InputIteratorB __bend, 02573 _InputIteratorW __wbegin) 02574 : _M_int(), _M_den(), _M_cp(), _M_m() 02575 { 02576 for (; __bbegin != __bend; ++__bbegin, ++__wbegin) 02577 { 02578 _M_int.push_back(*__bbegin); 02579 _M_den.push_back(*__wbegin); 02580 } 02581 02582 _M_initialize(); 02583 } 02584 02585 template<typename _RealType> 02586 template<typename _Func> 02587 piecewise_linear_distribution<_RealType>::param_type:: 02588 param_type(initializer_list<_RealType> __bl, _Func __fw) 02589 : _M_int(), _M_den(), _M_cp(), _M_m() 02590 { 02591 _M_int.reserve(__bl.size()); 02592 _M_den.reserve(__bl.size()); 02593 for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) 02594 { 02595 _M_int.push_back(*__biter); 02596 _M_den.push_back(__fw(*__biter)); 02597 } 02598 02599 _M_initialize(); 02600 } 02601 02602 template<typename _RealType> 02603 template<typename _Func> 02604 piecewise_linear_distribution<_RealType>::param_type:: 02605 param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) 02606 : _M_int(), _M_den(), _M_cp(), _M_m() 02607 { 02608 const size_t __n = __nw == 0 ? 1 : __nw; 02609 const _RealType __delta = (__xmax - __xmin) / __n; 02610 02611 _M_int.reserve(__n + 1); 02612 _M_den.reserve(__n + 1); 02613 for (size_t __k = 0; __k <= __nw; ++__k) 02614 { 02615 _M_int.push_back(__xmin + __k * __delta); 02616 _M_den.push_back(__fw(_M_int[__k] + __delta)); 02617 } 02618 02619 _M_initialize(); 02620 } 02621 02622 template<typename _RealType> 02623 template<typename _UniformRandomNumberGenerator> 02624 typename piecewise_linear_distribution<_RealType>::result_type 02625 piecewise_linear_distribution<_RealType>:: 02626 operator()(_UniformRandomNumberGenerator& __urng, 02627 const param_type& __param) 02628 { 02629 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 02630 __aurng(__urng); 02631 02632 const double __p = __aurng(); 02633 if (__param._M_cp.empty()) 02634 return __p; 02635 02636 auto __pos = std::lower_bound(__param._M_cp.begin(), 02637 __param._M_cp.end(), __p); 02638 const size_t __i = __pos - __param._M_cp.begin(); 02639 02640 const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 02641 02642 const double __a = 0.5 * __param._M_m[__i]; 02643 const double __b = __param._M_den[__i]; 02644 const double __cm = __p - __pref; 02645 02646 _RealType __x = __param._M_int[__i]; 02647 if (__a == 0) 02648 __x += __cm / __b; 02649 else 02650 { 02651 const double __d = __b * __b + 4.0 * __a * __cm; 02652 __x += 0.5 * (std::sqrt(__d) - __b) / __a; 02653 } 02654 02655 return __x; 02656 } 02657 02658 template<typename _RealType, typename _CharT, typename _Traits> 02659 std::basic_ostream<_CharT, _Traits>& 02660 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 02661 const piecewise_linear_distribution<_RealType>& __x) 02662 { 02663 typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 02664 typedef typename __ostream_type::ios_base __ios_base; 02665 02666 const typename __ios_base::fmtflags __flags = __os.flags(); 02667 const _CharT __fill = __os.fill(); 02668 const std::streamsize __precision = __os.precision(); 02669 const _CharT __space = __os.widen(' '); 02670 __os.flags(__ios_base::scientific | __ios_base::left); 02671 __os.fill(__space); 02672 __os.precision(std::numeric_limits<_RealType>::max_digits10); 02673 02674 std::vector<_RealType> __int = __x.intervals(); 02675 __os << __int.size() - 1; 02676 02677 for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) 02678 __os << __space << *__xit; 02679 02680 std::vector<double> __den = __x.densities(); 02681 for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) 02682 __os << __space << *__dit; 02683 02684 __os.flags(__flags); 02685 __os.fill(__fill); 02686 __os.precision(__precision); 02687 return __os; 02688 } 02689 02690 template<typename _RealType, typename _CharT, typename _Traits> 02691 std::basic_istream<_CharT, _Traits>& 02692 operator>>(std::basic_istream<_CharT, _Traits>& __is, 02693 piecewise_linear_distribution<_RealType>& __x) 02694 { 02695 typedef std::basic_istream<_CharT, _Traits> __istream_type; 02696 typedef typename __istream_type::ios_base __ios_base; 02697 02698 const typename __ios_base::fmtflags __flags = __is.flags(); 02699 __is.flags(__ios_base::dec | __ios_base::skipws); 02700 02701 size_t __n; 02702 __is >> __n; 02703 02704 std::vector<_RealType> __int_vec; 02705 __int_vec.reserve(__n + 1); 02706 for (size_t __i = 0; __i <= __n; ++__i) 02707 { 02708 _RealType __int; 02709 __is >> __int; 02710 __int_vec.push_back(__int); 02711 } 02712 02713 std::vector<double> __den_vec; 02714 __den_vec.reserve(__n + 1); 02715 for (size_t __i = 0; __i <= __n; ++__i) 02716 { 02717 double __den; 02718 __is >> __den; 02719 __den_vec.push_back(__den); 02720 } 02721 02722 __x.param(typename piecewise_linear_distribution<_RealType>:: 02723 param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin())); 02724 02725 __is.flags(__flags); 02726 return __is; 02727 } 02728 02729 02730 template<typename _IntType> 02731 seed_seq::seed_seq(std::initializer_list<_IntType> __il) 02732 { 02733 for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter) 02734 _M_v.push_back(__detail::__mod<result_type, 02735 __detail::_Shift<result_type, 32>::__value>(*__iter)); 02736 } 02737 02738 template<typename _InputIterator> 02739 seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end) 02740 { 02741 for (_InputIterator __iter = __begin; __iter != __end; ++__iter) 02742 _M_v.push_back(__detail::__mod<result_type, 02743 __detail::_Shift<result_type, 32>::__value>(*__iter)); 02744 } 02745 02746 template<typename _RandomAccessIterator> 02747 void 02748 seed_seq::generate(_RandomAccessIterator __begin, 02749 _RandomAccessIterator __end) 02750 { 02751 typedef typename iterator_traits<_RandomAccessIterator>::value_type 02752 _Type; 02753 02754 if (__begin == __end) 02755 return; 02756 02757 std::fill(__begin, __end, _Type(0x8b8b8b8bu)); 02758 02759 const size_t __n = __end - __begin; 02760 const size_t __s = _M_v.size(); 02761 const size_t __t = (__n >= 623) ? 11 02762 : (__n >= 68) ? 7 02763 : (__n >= 39) ? 5 02764 : (__n >= 7) ? 3 02765 : (__n - 1) / 2; 02766 const size_t __p = (__n - __t) / 2; 02767 const size_t __q = __p + __t; 02768 const size_t __m = std::max(__s + 1, __n); 02769 02770 for (size_t __k = 0; __k < __m; ++__k) 02771 { 02772 _Type __arg = (__begin[__k % __n] 02773 ^ __begin[(__k + __p) % __n] 02774 ^ __begin[(__k - 1) % __n]); 02775 _Type __r1 = __arg ^ (__arg >> 27); 02776 __r1 = __detail::__mod<_Type, 02777 __detail::_Shift<_Type, 32>::__value>(1664525u * __r1); 02778 _Type __r2 = __r1; 02779 if (__k == 0) 02780 __r2 += __s; 02781 else if (__k <= __s) 02782 __r2 += __k % __n + _M_v[__k - 1]; 02783 else 02784 __r2 += __k % __n; 02785 __r2 = __detail::__mod<_Type, 02786 __detail::_Shift<_Type, 32>::__value>(__r2); 02787 __begin[(__k + __p) % __n] += __r1; 02788 __begin[(__k + __q) % __n] += __r2; 02789 __begin[__k % __n] = __r2; 02790 } 02791 02792 for (size_t __k = __m; __k < __m + __n; ++__k) 02793 { 02794 _Type __arg = (__begin[__k % __n] 02795 + __begin[(__k + __p) % __n] 02796 + __begin[(__k - 1) % __n]); 02797 _Type __r3 = __arg ^ (__arg >> 27); 02798 __r3 = __detail::__mod<_Type, 02799 __detail::_Shift<_Type, 32>::__value>(1566083941u * __r3); 02800 _Type __r4 = __r3 - __k % __n; 02801 __r4 = __detail::__mod<_Type, 02802 __detail::_Shift<_Type, 32>::__value>(__r4); 02803 __begin[(__k + __p) % __n] ^= __r3; 02804 __begin[(__k + __q) % __n] ^= __r4; 02805 __begin[__k % __n] = __r4; 02806 } 02807 } 02808 02809 template<typename _RealType, size_t __bits, 02810 typename _UniformRandomNumberGenerator> 02811 _RealType 02812 generate_canonical(_UniformRandomNumberGenerator& __urng) 02813 { 02814 const size_t __b 02815 = std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits), 02816 __bits); 02817 const long double __r = static_cast<long double>(__urng.max()) 02818 - static_cast<long double>(__urng.min()) + 1.0L; 02819 const size_t __log2r = std::log(__r) / std::log(2.0L); 02820 size_t __k = std::max<size_t>(1UL, (__b + __log2r - 1UL) / __log2r); 02821 _RealType __sum = _RealType(0); 02822 _RealType __tmp = _RealType(1); 02823 for (; __k != 0; --__k) 02824 { 02825 __sum += _RealType(__urng() - __urng.min()) * __tmp; 02826 __tmp *= __r; 02827 } 02828 return __sum / __tmp; 02829 } 02830 02831 _GLIBCXX_END_NAMESPACE_VERSION 02832 } // namespace 02833 02834 #endif