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