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