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