1 1.1 mrg // random number generation (out of line) -*- C++ -*- 2 1.1 mrg 3 1.1.1.16 mrg // Copyright (C) 2009-2024 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file bits/random.tcc 26 1.1 mrg * This is an internal header file, included by other library headers. 27 1.1.1.2 mrg * Do not attempt to use it directly. @headername{random} 28 1.1 mrg */ 29 1.1 mrg 30 1.1.1.2 mrg #ifndef _RANDOM_TCC 31 1.1.1.2 mrg #define _RANDOM_TCC 1 32 1.1.1.2 mrg 33 1.1 mrg #include <numeric> // std::accumulate and std::partial_sum 34 1.1 mrg 35 1.1.1.2 mrg namespace std _GLIBCXX_VISIBILITY(default) 36 1.1 mrg { 37 1.1.1.10 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 38 1.1.1.10 mrg 39 1.1.1.14 mrg /// @cond undocumented 40 1.1.1.14 mrg // (Further) implementation-space details. 41 1.1 mrg namespace __detail 42 1.1 mrg { 43 1.1.1.2 mrg // General case for x = (ax + c) mod m -- use Schrage's algorithm 44 1.1.1.2 mrg // to avoid integer overflow. 45 1.1 mrg // 46 1.1 mrg // Preconditions: a > 0, m > 0. 47 1.1 mrg // 48 1.1.1.2 mrg // Note: only works correctly for __m % __a < __m / __a. 49 1.1.1.2 mrg template<typename _Tp, _Tp __m, _Tp __a, _Tp __c> 50 1.1.1.2 mrg _Tp 51 1.1.1.2 mrg _Mod<_Tp, __m, __a, __c, false, true>:: 52 1.1.1.2 mrg __calc(_Tp __x) 53 1.1 mrg { 54 1.1.1.2 mrg if (__a == 1) 55 1.1.1.2 mrg __x %= __m; 56 1.1.1.2 mrg else 57 1.1.1.2 mrg { 58 1.1.1.2 mrg static const _Tp __q = __m / __a; 59 1.1.1.2 mrg static const _Tp __r = __m % __a; 60 1.1 mrg 61 1.1.1.2 mrg _Tp __t1 = __a * (__x % __q); 62 1.1.1.2 mrg _Tp __t2 = __r * (__x / __q); 63 1.1.1.2 mrg if (__t1 >= __t2) 64 1.1.1.2 mrg __x = __t1 - __t2; 65 1.1.1.2 mrg else 66 1.1.1.2 mrg __x = __m - __t2 + __t1; 67 1.1.1.2 mrg } 68 1.1 mrg 69 1.1.1.2 mrg if (__c != 0) 70 1.1.1.2 mrg { 71 1.1.1.2 mrg const _Tp __d = __m - __x; 72 1.1.1.2 mrg if (__d > __c) 73 1.1.1.2 mrg __x += __c; 74 1.1.1.2 mrg else 75 1.1.1.2 mrg __x = __c - __d; 76 1.1.1.2 mrg } 77 1.1.1.2 mrg return __x; 78 1.1.1.2 mrg } 79 1.1 mrg 80 1.1 mrg template<typename _InputIterator, typename _OutputIterator, 81 1.1.1.2 mrg typename _Tp> 82 1.1 mrg _OutputIterator 83 1.1.1.2 mrg __normalize(_InputIterator __first, _InputIterator __last, 84 1.1.1.2 mrg _OutputIterator __result, const _Tp& __factor) 85 1.1 mrg { 86 1.1 mrg for (; __first != __last; ++__first, ++__result) 87 1.1.1.2 mrg *__result = *__first / __factor; 88 1.1 mrg return __result; 89 1.1 mrg } 90 1.1.1.2 mrg 91 1.1 mrg } // namespace __detail 92 1.1.1.14 mrg /// @endcond 93 1.1 mrg 94 1.1.1.14 mrg #if ! __cpp_inline_variables 95 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 96 1.1.1.2 mrg constexpr _UIntType 97 1.1 mrg linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier; 98 1.1 mrg 99 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 100 1.1.1.2 mrg constexpr _UIntType 101 1.1 mrg linear_congruential_engine<_UIntType, __a, __c, __m>::increment; 102 1.1 mrg 103 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 104 1.1.1.2 mrg constexpr _UIntType 105 1.1 mrg linear_congruential_engine<_UIntType, __a, __c, __m>::modulus; 106 1.1 mrg 107 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 108 1.1.1.2 mrg constexpr _UIntType 109 1.1 mrg linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed; 110 1.1.1.14 mrg #endif 111 1.1 mrg 112 1.1 mrg /** 113 1.1 mrg * Seeds the LCR with integral value @p __s, adjusted so that the 114 1.1 mrg * ring identity is never a member of the convergence set. 115 1.1 mrg */ 116 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 117 1.1 mrg void 118 1.1 mrg linear_congruential_engine<_UIntType, __a, __c, __m>:: 119 1.1 mrg seed(result_type __s) 120 1.1 mrg { 121 1.1 mrg if ((__detail::__mod<_UIntType, __m>(__c) == 0) 122 1.1 mrg && (__detail::__mod<_UIntType, __m>(__s) == 0)) 123 1.1 mrg _M_x = 1; 124 1.1 mrg else 125 1.1 mrg _M_x = __detail::__mod<_UIntType, __m>(__s); 126 1.1 mrg } 127 1.1 mrg 128 1.1 mrg /** 129 1.1 mrg * Seeds the LCR engine with a value generated by @p __q. 130 1.1 mrg */ 131 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 132 1.1 mrg template<typename _Sseq> 133 1.1.1.11 mrg auto 134 1.1 mrg linear_congruential_engine<_UIntType, __a, __c, __m>:: 135 1.1 mrg seed(_Sseq& __q) 136 1.1.1.11 mrg -> _If_seed_seq<_Sseq> 137 1.1 mrg { 138 1.1 mrg const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits 139 1.1 mrg : std::__lg(__m); 140 1.1 mrg const _UIntType __k = (__k0 + 31) / 32; 141 1.1 mrg uint_least32_t __arr[__k + 3]; 142 1.1 mrg __q.generate(__arr + 0, __arr + __k + 3); 143 1.1 mrg _UIntType __factor = 1u; 144 1.1 mrg _UIntType __sum = 0u; 145 1.1 mrg for (size_t __j = 0; __j < __k; ++__j) 146 1.1 mrg { 147 1.1 mrg __sum += __arr[__j + 3] * __factor; 148 1.1 mrg __factor *= __detail::_Shift<_UIntType, 32>::__value; 149 1.1 mrg } 150 1.1 mrg seed(__sum); 151 1.1 mrg } 152 1.1 mrg 153 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 154 1.1 mrg typename _CharT, typename _Traits> 155 1.1 mrg std::basic_ostream<_CharT, _Traits>& 156 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 157 1.1 mrg const linear_congruential_engine<_UIntType, 158 1.1 mrg __a, __c, __m>& __lcr) 159 1.1 mrg { 160 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 161 1.1 mrg 162 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 163 1.1 mrg const _CharT __fill = __os.fill(); 164 1.1 mrg __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 165 1.1 mrg __os.fill(__os.widen(' ')); 166 1.1 mrg 167 1.1 mrg __os << __lcr._M_x; 168 1.1 mrg 169 1.1 mrg __os.flags(__flags); 170 1.1 mrg __os.fill(__fill); 171 1.1 mrg return __os; 172 1.1 mrg } 173 1.1 mrg 174 1.1 mrg template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 175 1.1 mrg typename _CharT, typename _Traits> 176 1.1 mrg std::basic_istream<_CharT, _Traits>& 177 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 178 1.1 mrg linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr) 179 1.1 mrg { 180 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 181 1.1 mrg 182 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 183 1.1 mrg __is.flags(__ios_base::dec); 184 1.1 mrg 185 1.1 mrg __is >> __lcr._M_x; 186 1.1 mrg 187 1.1 mrg __is.flags(__flags); 188 1.1 mrg return __is; 189 1.1 mrg } 190 1.1 mrg 191 1.1.1.14 mrg #if ! __cpp_inline_variables 192 1.1 mrg template<typename _UIntType, 193 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 194 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 195 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 196 1.1 mrg _UIntType __f> 197 1.1.1.2 mrg constexpr size_t 198 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 199 1.1 mrg __s, __b, __t, __c, __l, __f>::word_size; 200 1.1 mrg 201 1.1 mrg template<typename _UIntType, 202 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 203 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 204 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 205 1.1 mrg _UIntType __f> 206 1.1.1.2 mrg constexpr size_t 207 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 208 1.1 mrg __s, __b, __t, __c, __l, __f>::state_size; 209 1.1 mrg 210 1.1 mrg template<typename _UIntType, 211 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 212 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 213 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 214 1.1 mrg _UIntType __f> 215 1.1.1.2 mrg constexpr size_t 216 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 217 1.1 mrg __s, __b, __t, __c, __l, __f>::shift_size; 218 1.1 mrg 219 1.1 mrg template<typename _UIntType, 220 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 221 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 222 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 223 1.1 mrg _UIntType __f> 224 1.1.1.2 mrg constexpr size_t 225 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 226 1.1 mrg __s, __b, __t, __c, __l, __f>::mask_bits; 227 1.1 mrg 228 1.1 mrg template<typename _UIntType, 229 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 230 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 231 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 232 1.1 mrg _UIntType __f> 233 1.1.1.2 mrg constexpr _UIntType 234 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 235 1.1 mrg __s, __b, __t, __c, __l, __f>::xor_mask; 236 1.1 mrg 237 1.1 mrg template<typename _UIntType, 238 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 239 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 240 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 241 1.1 mrg _UIntType __f> 242 1.1.1.2 mrg constexpr size_t 243 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 244 1.1 mrg __s, __b, __t, __c, __l, __f>::tempering_u; 245 1.1 mrg 246 1.1 mrg template<typename _UIntType, 247 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 248 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 249 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 250 1.1 mrg _UIntType __f> 251 1.1.1.2 mrg constexpr _UIntType 252 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 253 1.1 mrg __s, __b, __t, __c, __l, __f>::tempering_d; 254 1.1 mrg 255 1.1 mrg template<typename _UIntType, 256 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 257 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 258 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 259 1.1 mrg _UIntType __f> 260 1.1.1.2 mrg constexpr size_t 261 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 262 1.1 mrg __s, __b, __t, __c, __l, __f>::tempering_s; 263 1.1 mrg 264 1.1 mrg template<typename _UIntType, 265 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 266 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 267 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 268 1.1 mrg _UIntType __f> 269 1.1.1.2 mrg constexpr _UIntType 270 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 271 1.1 mrg __s, __b, __t, __c, __l, __f>::tempering_b; 272 1.1 mrg 273 1.1 mrg template<typename _UIntType, 274 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 275 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 276 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 277 1.1 mrg _UIntType __f> 278 1.1.1.2 mrg constexpr size_t 279 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 280 1.1 mrg __s, __b, __t, __c, __l, __f>::tempering_t; 281 1.1 mrg 282 1.1 mrg template<typename _UIntType, 283 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 284 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 285 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 286 1.1 mrg _UIntType __f> 287 1.1.1.2 mrg constexpr _UIntType 288 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 289 1.1 mrg __s, __b, __t, __c, __l, __f>::tempering_c; 290 1.1 mrg 291 1.1 mrg template<typename _UIntType, 292 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 293 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 294 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 295 1.1 mrg _UIntType __f> 296 1.1.1.2 mrg constexpr size_t 297 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 298 1.1 mrg __s, __b, __t, __c, __l, __f>::tempering_l; 299 1.1 mrg 300 1.1 mrg template<typename _UIntType, 301 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 302 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 303 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 304 1.1 mrg _UIntType __f> 305 1.1.1.2 mrg constexpr _UIntType 306 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 307 1.1 mrg __s, __b, __t, __c, __l, __f>:: 308 1.1 mrg initialization_multiplier; 309 1.1 mrg 310 1.1 mrg template<typename _UIntType, 311 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 312 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 313 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 314 1.1 mrg _UIntType __f> 315 1.1.1.2 mrg constexpr _UIntType 316 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 317 1.1 mrg __s, __b, __t, __c, __l, __f>::default_seed; 318 1.1.1.14 mrg #endif 319 1.1 mrg 320 1.1 mrg template<typename _UIntType, 321 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 322 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 323 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 324 1.1 mrg _UIntType __f> 325 1.1 mrg void 326 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 327 1.1 mrg __s, __b, __t, __c, __l, __f>:: 328 1.1 mrg seed(result_type __sd) 329 1.1 mrg { 330 1.1 mrg _M_x[0] = __detail::__mod<_UIntType, 331 1.1 mrg __detail::_Shift<_UIntType, __w>::__value>(__sd); 332 1.1 mrg 333 1.1 mrg for (size_t __i = 1; __i < state_size; ++__i) 334 1.1 mrg { 335 1.1 mrg _UIntType __x = _M_x[__i - 1]; 336 1.1 mrg __x ^= __x >> (__w - 2); 337 1.1 mrg __x *= __f; 338 1.1 mrg __x += __detail::__mod<_UIntType, __n>(__i); 339 1.1 mrg _M_x[__i] = __detail::__mod<_UIntType, 340 1.1 mrg __detail::_Shift<_UIntType, __w>::__value>(__x); 341 1.1 mrg } 342 1.1 mrg _M_p = state_size; 343 1.1 mrg } 344 1.1 mrg 345 1.1 mrg template<typename _UIntType, 346 1.1 mrg size_t __w, size_t __n, size_t __m, size_t __r, 347 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 348 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 349 1.1 mrg _UIntType __f> 350 1.1 mrg template<typename _Sseq> 351 1.1.1.11 mrg auto 352 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 353 1.1 mrg __s, __b, __t, __c, __l, __f>:: 354 1.1 mrg seed(_Sseq& __q) 355 1.1.1.11 mrg -> _If_seed_seq<_Sseq> 356 1.1 mrg { 357 1.1 mrg const _UIntType __upper_mask = (~_UIntType()) << __r; 358 1.1 mrg const size_t __k = (__w + 31) / 32; 359 1.1 mrg uint_least32_t __arr[__n * __k]; 360 1.1 mrg __q.generate(__arr + 0, __arr + __n * __k); 361 1.1 mrg 362 1.1 mrg bool __zero = true; 363 1.1 mrg for (size_t __i = 0; __i < state_size; ++__i) 364 1.1 mrg { 365 1.1 mrg _UIntType __factor = 1u; 366 1.1 mrg _UIntType __sum = 0u; 367 1.1 mrg for (size_t __j = 0; __j < __k; ++__j) 368 1.1 mrg { 369 1.1 mrg __sum += __arr[__k * __i + __j] * __factor; 370 1.1 mrg __factor *= __detail::_Shift<_UIntType, 32>::__value; 371 1.1 mrg } 372 1.1 mrg _M_x[__i] = __detail::__mod<_UIntType, 373 1.1 mrg __detail::_Shift<_UIntType, __w>::__value>(__sum); 374 1.1 mrg 375 1.1 mrg if (__zero) 376 1.1 mrg { 377 1.1 mrg if (__i == 0) 378 1.1 mrg { 379 1.1 mrg if ((_M_x[0] & __upper_mask) != 0u) 380 1.1 mrg __zero = false; 381 1.1 mrg } 382 1.1 mrg else if (_M_x[__i] != 0u) 383 1.1 mrg __zero = false; 384 1.1 mrg } 385 1.1 mrg } 386 1.1 mrg if (__zero) 387 1.1 mrg _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value; 388 1.1.1.2 mrg _M_p = state_size; 389 1.1 mrg } 390 1.1 mrg 391 1.1 mrg template<typename _UIntType, size_t __w, 392 1.1 mrg size_t __n, size_t __m, size_t __r, 393 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 394 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 395 1.1 mrg _UIntType __f> 396 1.1.1.2 mrg void 397 1.1.1.2 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 398 1.1.1.2 mrg __s, __b, __t, __c, __l, __f>:: 399 1.1.1.2 mrg _M_gen_rand(void) 400 1.1.1.2 mrg { 401 1.1.1.2 mrg const _UIntType __upper_mask = (~_UIntType()) << __r; 402 1.1.1.2 mrg const _UIntType __lower_mask = ~__upper_mask; 403 1.1.1.2 mrg 404 1.1.1.2 mrg for (size_t __k = 0; __k < (__n - __m); ++__k) 405 1.1.1.2 mrg { 406 1.1.1.2 mrg _UIntType __y = ((_M_x[__k] & __upper_mask) 407 1.1.1.2 mrg | (_M_x[__k + 1] & __lower_mask)); 408 1.1.1.2 mrg _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1) 409 1.1.1.2 mrg ^ ((__y & 0x01) ? __a : 0)); 410 1.1.1.2 mrg } 411 1.1.1.2 mrg 412 1.1.1.2 mrg for (size_t __k = (__n - __m); __k < (__n - 1); ++__k) 413 1.1.1.2 mrg { 414 1.1.1.2 mrg _UIntType __y = ((_M_x[__k] & __upper_mask) 415 1.1.1.2 mrg | (_M_x[__k + 1] & __lower_mask)); 416 1.1.1.2 mrg _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1) 417 1.1.1.2 mrg ^ ((__y & 0x01) ? __a : 0)); 418 1.1.1.2 mrg } 419 1.1.1.2 mrg 420 1.1.1.2 mrg _UIntType __y = ((_M_x[__n - 1] & __upper_mask) 421 1.1.1.2 mrg | (_M_x[0] & __lower_mask)); 422 1.1.1.2 mrg _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1) 423 1.1.1.2 mrg ^ ((__y & 0x01) ? __a : 0)); 424 1.1.1.2 mrg _M_p = 0; 425 1.1.1.2 mrg } 426 1.1.1.2 mrg 427 1.1.1.2 mrg template<typename _UIntType, size_t __w, 428 1.1.1.2 mrg size_t __n, size_t __m, size_t __r, 429 1.1.1.2 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 430 1.1.1.2 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 431 1.1.1.2 mrg _UIntType __f> 432 1.1.1.2 mrg void 433 1.1.1.2 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 434 1.1.1.2 mrg __s, __b, __t, __c, __l, __f>:: 435 1.1.1.2 mrg discard(unsigned long long __z) 436 1.1.1.2 mrg { 437 1.1.1.2 mrg while (__z > state_size - _M_p) 438 1.1.1.2 mrg { 439 1.1.1.2 mrg __z -= state_size - _M_p; 440 1.1.1.2 mrg _M_gen_rand(); 441 1.1.1.2 mrg } 442 1.1.1.2 mrg _M_p += __z; 443 1.1.1.2 mrg } 444 1.1.1.2 mrg 445 1.1.1.2 mrg template<typename _UIntType, size_t __w, 446 1.1.1.2 mrg size_t __n, size_t __m, size_t __r, 447 1.1.1.2 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 448 1.1.1.2 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 449 1.1.1.2 mrg _UIntType __f> 450 1.1 mrg typename 451 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 452 1.1 mrg __s, __b, __t, __c, __l, __f>::result_type 453 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 454 1.1 mrg __s, __b, __t, __c, __l, __f>:: 455 1.1 mrg operator()() 456 1.1 mrg { 457 1.1 mrg // Reload the vector - cost is O(n) amortized over n calls. 458 1.1 mrg if (_M_p >= state_size) 459 1.1.1.2 mrg _M_gen_rand(); 460 1.1 mrg 461 1.1 mrg // Calculate o(x(i)). 462 1.1 mrg result_type __z = _M_x[_M_p++]; 463 1.1 mrg __z ^= (__z >> __u) & __d; 464 1.1 mrg __z ^= (__z << __s) & __b; 465 1.1 mrg __z ^= (__z << __t) & __c; 466 1.1 mrg __z ^= (__z >> __l); 467 1.1 mrg 468 1.1 mrg return __z; 469 1.1 mrg } 470 1.1 mrg 471 1.1 mrg template<typename _UIntType, size_t __w, 472 1.1 mrg size_t __n, size_t __m, size_t __r, 473 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 474 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 475 1.1 mrg _UIntType __f, typename _CharT, typename _Traits> 476 1.1 mrg std::basic_ostream<_CharT, _Traits>& 477 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 478 1.1 mrg const mersenne_twister_engine<_UIntType, __w, __n, __m, 479 1.1 mrg __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) 480 1.1 mrg { 481 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 482 1.1 mrg 483 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 484 1.1 mrg const _CharT __fill = __os.fill(); 485 1.1 mrg const _CharT __space = __os.widen(' '); 486 1.1 mrg __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 487 1.1 mrg __os.fill(__space); 488 1.1 mrg 489 1.1.1.2 mrg for (size_t __i = 0; __i < __n; ++__i) 490 1.1 mrg __os << __x._M_x[__i] << __space; 491 1.1.1.2 mrg __os << __x._M_p; 492 1.1 mrg 493 1.1 mrg __os.flags(__flags); 494 1.1 mrg __os.fill(__fill); 495 1.1 mrg return __os; 496 1.1 mrg } 497 1.1 mrg 498 1.1 mrg template<typename _UIntType, size_t __w, 499 1.1 mrg size_t __n, size_t __m, size_t __r, 500 1.1 mrg _UIntType __a, size_t __u, _UIntType __d, size_t __s, 501 1.1 mrg _UIntType __b, size_t __t, _UIntType __c, size_t __l, 502 1.1 mrg _UIntType __f, typename _CharT, typename _Traits> 503 1.1 mrg std::basic_istream<_CharT, _Traits>& 504 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 505 1.1 mrg mersenne_twister_engine<_UIntType, __w, __n, __m, 506 1.1 mrg __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) 507 1.1 mrg { 508 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 509 1.1 mrg 510 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 511 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 512 1.1 mrg 513 1.1 mrg for (size_t __i = 0; __i < __n; ++__i) 514 1.1 mrg __is >> __x._M_x[__i]; 515 1.1.1.2 mrg __is >> __x._M_p; 516 1.1 mrg 517 1.1 mrg __is.flags(__flags); 518 1.1 mrg return __is; 519 1.1 mrg } 520 1.1 mrg 521 1.1.1.14 mrg #if ! __cpp_inline_variables 522 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r> 523 1.1.1.2 mrg constexpr size_t 524 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size; 525 1.1 mrg 526 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r> 527 1.1.1.2 mrg constexpr size_t 528 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag; 529 1.1 mrg 530 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r> 531 1.1.1.2 mrg constexpr size_t 532 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag; 533 1.1 mrg 534 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r> 535 1.1.1.14 mrg constexpr uint_least32_t 536 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed; 537 1.1.1.14 mrg #endif 538 1.1 mrg 539 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r> 540 1.1 mrg void 541 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 542 1.1 mrg seed(result_type __value) 543 1.1 mrg { 544 1.1.1.15 mrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 545 1.1.1.15 mrg // 3809. Is std::subtract_with_carry_engine<uint16_t> supposed to work? 546 1.1.1.15 mrg // 4014. LWG 3809 changes behavior of some existing code 547 1.1.1.14 mrg std::linear_congruential_engine<uint_least32_t, 40014u, 0u, 2147483563u> 548 1.1.1.15 mrg __lcg(__value == 0u ? default_seed : __value % 2147483563u); 549 1.1 mrg 550 1.1 mrg const size_t __n = (__w + 31) / 32; 551 1.1 mrg 552 1.1 mrg for (size_t __i = 0; __i < long_lag; ++__i) 553 1.1 mrg { 554 1.1 mrg _UIntType __sum = 0u; 555 1.1 mrg _UIntType __factor = 1u; 556 1.1 mrg for (size_t __j = 0; __j < __n; ++__j) 557 1.1 mrg { 558 1.1 mrg __sum += __detail::__mod<uint_least32_t, 559 1.1 mrg __detail::_Shift<uint_least32_t, 32>::__value> 560 1.1 mrg (__lcg()) * __factor; 561 1.1 mrg __factor *= __detail::_Shift<_UIntType, 32>::__value; 562 1.1 mrg } 563 1.1 mrg _M_x[__i] = __detail::__mod<_UIntType, 564 1.1 mrg __detail::_Shift<_UIntType, __w>::__value>(__sum); 565 1.1 mrg } 566 1.1 mrg _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 567 1.1 mrg _M_p = 0; 568 1.1 mrg } 569 1.1 mrg 570 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r> 571 1.1 mrg template<typename _Sseq> 572 1.1.1.11 mrg auto 573 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 574 1.1 mrg seed(_Sseq& __q) 575 1.1.1.11 mrg -> _If_seed_seq<_Sseq> 576 1.1 mrg { 577 1.1 mrg const size_t __k = (__w + 31) / 32; 578 1.1 mrg uint_least32_t __arr[__r * __k]; 579 1.1 mrg __q.generate(__arr + 0, __arr + __r * __k); 580 1.1 mrg 581 1.1 mrg for (size_t __i = 0; __i < long_lag; ++__i) 582 1.1 mrg { 583 1.1 mrg _UIntType __sum = 0u; 584 1.1 mrg _UIntType __factor = 1u; 585 1.1 mrg for (size_t __j = 0; __j < __k; ++__j) 586 1.1 mrg { 587 1.1 mrg __sum += __arr[__k * __i + __j] * __factor; 588 1.1 mrg __factor *= __detail::_Shift<_UIntType, 32>::__value; 589 1.1 mrg } 590 1.1 mrg _M_x[__i] = __detail::__mod<_UIntType, 591 1.1 mrg __detail::_Shift<_UIntType, __w>::__value>(__sum); 592 1.1 mrg } 593 1.1 mrg _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 594 1.1 mrg _M_p = 0; 595 1.1 mrg } 596 1.1 mrg 597 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r> 598 1.1 mrg typename subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 599 1.1 mrg result_type 600 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 601 1.1 mrg operator()() 602 1.1 mrg { 603 1.1 mrg // Derive short lag index from current index. 604 1.1 mrg long __ps = _M_p - short_lag; 605 1.1 mrg if (__ps < 0) 606 1.1 mrg __ps += long_lag; 607 1.1 mrg 608 1.1 mrg // Calculate new x(i) without overflow or division. 609 1.1 mrg // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry 610 1.1 mrg // cannot overflow. 611 1.1 mrg _UIntType __xi; 612 1.1 mrg if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) 613 1.1 mrg { 614 1.1 mrg __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; 615 1.1 mrg _M_carry = 0; 616 1.1 mrg } 617 1.1 mrg else 618 1.1 mrg { 619 1.1 mrg __xi = (__detail::_Shift<_UIntType, __w>::__value 620 1.1 mrg - _M_x[_M_p] - _M_carry + _M_x[__ps]); 621 1.1 mrg _M_carry = 1; 622 1.1 mrg } 623 1.1 mrg _M_x[_M_p] = __xi; 624 1.1 mrg 625 1.1 mrg // Adjust current index to loop around in ring buffer. 626 1.1 mrg if (++_M_p >= long_lag) 627 1.1 mrg _M_p = 0; 628 1.1 mrg 629 1.1 mrg return __xi; 630 1.1 mrg } 631 1.1 mrg 632 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r, 633 1.1 mrg typename _CharT, typename _Traits> 634 1.1 mrg std::basic_ostream<_CharT, _Traits>& 635 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 636 1.1 mrg const subtract_with_carry_engine<_UIntType, 637 1.1 mrg __w, __s, __r>& __x) 638 1.1 mrg { 639 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 640 1.1 mrg 641 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 642 1.1 mrg const _CharT __fill = __os.fill(); 643 1.1 mrg const _CharT __space = __os.widen(' '); 644 1.1 mrg __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 645 1.1 mrg __os.fill(__space); 646 1.1 mrg 647 1.1 mrg for (size_t __i = 0; __i < __r; ++__i) 648 1.1 mrg __os << __x._M_x[__i] << __space; 649 1.1.1.2 mrg __os << __x._M_carry << __space << __x._M_p; 650 1.1 mrg 651 1.1 mrg __os.flags(__flags); 652 1.1 mrg __os.fill(__fill); 653 1.1 mrg return __os; 654 1.1 mrg } 655 1.1 mrg 656 1.1 mrg template<typename _UIntType, size_t __w, size_t __s, size_t __r, 657 1.1 mrg typename _CharT, typename _Traits> 658 1.1 mrg std::basic_istream<_CharT, _Traits>& 659 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 660 1.1 mrg subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x) 661 1.1 mrg { 662 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 663 1.1 mrg 664 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 665 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 666 1.1 mrg 667 1.1 mrg for (size_t __i = 0; __i < __r; ++__i) 668 1.1 mrg __is >> __x._M_x[__i]; 669 1.1 mrg __is >> __x._M_carry; 670 1.1.1.2 mrg __is >> __x._M_p; 671 1.1 mrg 672 1.1 mrg __is.flags(__flags); 673 1.1 mrg return __is; 674 1.1 mrg } 675 1.1 mrg 676 1.1.1.14 mrg #if ! __cpp_inline_variables 677 1.1 mrg template<typename _RandomNumberEngine, size_t __p, size_t __r> 678 1.1.1.2 mrg constexpr size_t 679 1.1 mrg discard_block_engine<_RandomNumberEngine, __p, __r>::block_size; 680 1.1 mrg 681 1.1 mrg template<typename _RandomNumberEngine, size_t __p, size_t __r> 682 1.1.1.2 mrg constexpr size_t 683 1.1 mrg discard_block_engine<_RandomNumberEngine, __p, __r>::used_block; 684 1.1.1.14 mrg #endif 685 1.1 mrg 686 1.1 mrg template<typename _RandomNumberEngine, size_t __p, size_t __r> 687 1.1 mrg typename discard_block_engine<_RandomNumberEngine, 688 1.1 mrg __p, __r>::result_type 689 1.1 mrg discard_block_engine<_RandomNumberEngine, __p, __r>:: 690 1.1 mrg operator()() 691 1.1 mrg { 692 1.1 mrg if (_M_n >= used_block) 693 1.1 mrg { 694 1.1 mrg _M_b.discard(block_size - _M_n); 695 1.1 mrg _M_n = 0; 696 1.1 mrg } 697 1.1 mrg ++_M_n; 698 1.1 mrg return _M_b(); 699 1.1 mrg } 700 1.1 mrg 701 1.1 mrg template<typename _RandomNumberEngine, size_t __p, size_t __r, 702 1.1 mrg typename _CharT, typename _Traits> 703 1.1 mrg std::basic_ostream<_CharT, _Traits>& 704 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 705 1.1 mrg const discard_block_engine<_RandomNumberEngine, 706 1.1 mrg __p, __r>& __x) 707 1.1 mrg { 708 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 709 1.1 mrg 710 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 711 1.1 mrg const _CharT __fill = __os.fill(); 712 1.1 mrg const _CharT __space = __os.widen(' '); 713 1.1 mrg __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 714 1.1 mrg __os.fill(__space); 715 1.1 mrg 716 1.1 mrg __os << __x.base() << __space << __x._M_n; 717 1.1 mrg 718 1.1 mrg __os.flags(__flags); 719 1.1 mrg __os.fill(__fill); 720 1.1 mrg return __os; 721 1.1 mrg } 722 1.1 mrg 723 1.1 mrg template<typename _RandomNumberEngine, size_t __p, size_t __r, 724 1.1 mrg typename _CharT, typename _Traits> 725 1.1 mrg std::basic_istream<_CharT, _Traits>& 726 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 727 1.1 mrg discard_block_engine<_RandomNumberEngine, __p, __r>& __x) 728 1.1 mrg { 729 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 730 1.1 mrg 731 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 732 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 733 1.1 mrg 734 1.1 mrg __is >> __x._M_b >> __x._M_n; 735 1.1 mrg 736 1.1 mrg __is.flags(__flags); 737 1.1 mrg return __is; 738 1.1 mrg } 739 1.1 mrg 740 1.1 mrg 741 1.1 mrg template<typename _RandomNumberEngine, size_t __w, typename _UIntType> 742 1.1 mrg typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: 743 1.1 mrg result_type 744 1.1 mrg independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: 745 1.1 mrg operator()() 746 1.1 mrg { 747 1.1.1.2 mrg typedef typename _RandomNumberEngine::result_type _Eresult_type; 748 1.1.1.2 mrg const _Eresult_type __r 749 1.1.1.2 mrg = (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max() 750 1.1.1.2 mrg ? _M_b.max() - _M_b.min() + 1 : 0); 751 1.1.1.2 mrg const unsigned __edig = std::numeric_limits<_Eresult_type>::digits; 752 1.1.1.2 mrg const unsigned __m = __r ? std::__lg(__r) : __edig; 753 1.1.1.2 mrg 754 1.1.1.2 mrg typedef typename std::common_type<_Eresult_type, result_type>::type 755 1.1.1.2 mrg __ctype; 756 1.1.1.2 mrg const unsigned __cdig = std::numeric_limits<__ctype>::digits; 757 1.1.1.2 mrg 758 1.1.1.2 mrg unsigned __n, __n0; 759 1.1.1.2 mrg __ctype __s0, __s1, __y0, __y1; 760 1.1.1.2 mrg 761 1.1 mrg for (size_t __i = 0; __i < 2; ++__i) 762 1.1 mrg { 763 1.1 mrg __n = (__w + __m - 1) / __m + __i; 764 1.1 mrg __n0 = __n - __w % __n; 765 1.1.1.2 mrg const unsigned __w0 = __w / __n; // __w0 <= __m 766 1.1.1.2 mrg 767 1.1.1.2 mrg __s0 = 0; 768 1.1.1.2 mrg __s1 = 0; 769 1.1.1.2 mrg if (__w0 < __cdig) 770 1.1.1.2 mrg { 771 1.1.1.2 mrg __s0 = __ctype(1) << __w0; 772 1.1.1.2 mrg __s1 = __s0 << 1; 773 1.1.1.2 mrg } 774 1.1.1.2 mrg 775 1.1.1.2 mrg __y0 = 0; 776 1.1.1.2 mrg __y1 = 0; 777 1.1.1.2 mrg if (__r) 778 1.1.1.2 mrg { 779 1.1.1.2 mrg __y0 = __s0 * (__r / __s0); 780 1.1.1.2 mrg if (__s1) 781 1.1.1.2 mrg __y1 = __s1 * (__r / __s1); 782 1.1.1.2 mrg 783 1.1.1.2 mrg if (__r - __y0 <= __y0 / __n) 784 1.1.1.2 mrg break; 785 1.1.1.2 mrg } 786 1.1.1.2 mrg else 787 1.1 mrg break; 788 1.1 mrg } 789 1.1 mrg 790 1.1 mrg result_type __sum = 0; 791 1.1 mrg for (size_t __k = 0; __k < __n0; ++__k) 792 1.1 mrg { 793 1.1.1.2 mrg __ctype __u; 794 1.1 mrg do 795 1.1 mrg __u = _M_b() - _M_b.min(); 796 1.1.1.2 mrg while (__y0 && __u >= __y0); 797 1.1.1.2 mrg __sum = __s0 * __sum + (__s0 ? __u % __s0 : __u); 798 1.1 mrg } 799 1.1 mrg for (size_t __k = __n0; __k < __n; ++__k) 800 1.1 mrg { 801 1.1.1.2 mrg __ctype __u; 802 1.1 mrg do 803 1.1 mrg __u = _M_b() - _M_b.min(); 804 1.1.1.2 mrg while (__y1 && __u >= __y1); 805 1.1.1.2 mrg __sum = __s1 * __sum + (__s1 ? __u % __s1 : __u); 806 1.1 mrg } 807 1.1 mrg return __sum; 808 1.1 mrg } 809 1.1 mrg 810 1.1.1.14 mrg #if ! __cpp_inline_variables 811 1.1 mrg template<typename _RandomNumberEngine, size_t __k> 812 1.1.1.2 mrg constexpr size_t 813 1.1 mrg shuffle_order_engine<_RandomNumberEngine, __k>::table_size; 814 1.1.1.14 mrg #endif 815 1.1.1.14 mrg 816 1.1.1.14 mrg namespace __detail 817 1.1.1.14 mrg { 818 1.1.1.14 mrg // Determine whether an integer is representable as double. 819 1.1.1.14 mrg template<typename _Tp> 820 1.1.1.14 mrg constexpr bool 821 1.1.1.14 mrg __representable_as_double(_Tp __x) noexcept 822 1.1.1.14 mrg { 823 1.1.1.14 mrg static_assert(numeric_limits<_Tp>::is_integer, ""); 824 1.1.1.14 mrg static_assert(!numeric_limits<_Tp>::is_signed, ""); 825 1.1.1.14 mrg // All integers <= 2^53 are representable. 826 1.1.1.14 mrg return (__x <= (1ull << __DBL_MANT_DIG__)) 827 1.1.1.14 mrg // Between 2^53 and 2^54 only even numbers are representable. 828 1.1.1.14 mrg || (!(__x & 1) && __detail::__representable_as_double(__x >> 1)); 829 1.1.1.14 mrg } 830 1.1.1.14 mrg 831 1.1.1.14 mrg // Determine whether x+1 is representable as double. 832 1.1.1.14 mrg template<typename _Tp> 833 1.1.1.14 mrg constexpr bool 834 1.1.1.14 mrg __p1_representable_as_double(_Tp __x) noexcept 835 1.1.1.14 mrg { 836 1.1.1.14 mrg static_assert(numeric_limits<_Tp>::is_integer, ""); 837 1.1.1.14 mrg static_assert(!numeric_limits<_Tp>::is_signed, ""); 838 1.1.1.14 mrg return numeric_limits<_Tp>::digits < __DBL_MANT_DIG__ 839 1.1.1.14 mrg || (bool(__x + 1u) // return false if x+1 wraps around to zero 840 1.1.1.14 mrg && __detail::__representable_as_double(__x + 1u)); 841 1.1.1.14 mrg } 842 1.1.1.14 mrg } 843 1.1 mrg 844 1.1 mrg template<typename _RandomNumberEngine, size_t __k> 845 1.1 mrg typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type 846 1.1 mrg shuffle_order_engine<_RandomNumberEngine, __k>:: 847 1.1 mrg operator()() 848 1.1 mrg { 849 1.1.1.14 mrg constexpr result_type __range = max() - min(); 850 1.1.1.14 mrg size_t __j = __k; 851 1.1.1.14 mrg const result_type __y = _M_y - min(); 852 1.1.1.14 mrg // Avoid using slower long double arithmetic if possible. 853 1.1.1.14 mrg if _GLIBCXX17_CONSTEXPR (__detail::__p1_representable_as_double(__range)) 854 1.1.1.14 mrg __j *= __y / (__range + 1.0); 855 1.1.1.14 mrg else 856 1.1.1.14 mrg __j *= __y / (__range + 1.0L); 857 1.1 mrg _M_y = _M_v[__j]; 858 1.1 mrg _M_v[__j] = _M_b(); 859 1.1 mrg 860 1.1 mrg return _M_y; 861 1.1 mrg } 862 1.1 mrg 863 1.1 mrg template<typename _RandomNumberEngine, size_t __k, 864 1.1 mrg typename _CharT, typename _Traits> 865 1.1 mrg std::basic_ostream<_CharT, _Traits>& 866 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 867 1.1 mrg const shuffle_order_engine<_RandomNumberEngine, __k>& __x) 868 1.1 mrg { 869 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 870 1.1 mrg 871 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 872 1.1 mrg const _CharT __fill = __os.fill(); 873 1.1 mrg const _CharT __space = __os.widen(' '); 874 1.1 mrg __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 875 1.1 mrg __os.fill(__space); 876 1.1 mrg 877 1.1 mrg __os << __x.base(); 878 1.1 mrg for (size_t __i = 0; __i < __k; ++__i) 879 1.1 mrg __os << __space << __x._M_v[__i]; 880 1.1 mrg __os << __space << __x._M_y; 881 1.1 mrg 882 1.1 mrg __os.flags(__flags); 883 1.1 mrg __os.fill(__fill); 884 1.1 mrg return __os; 885 1.1 mrg } 886 1.1 mrg 887 1.1 mrg template<typename _RandomNumberEngine, size_t __k, 888 1.1 mrg typename _CharT, typename _Traits> 889 1.1 mrg std::basic_istream<_CharT, _Traits>& 890 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 891 1.1 mrg shuffle_order_engine<_RandomNumberEngine, __k>& __x) 892 1.1 mrg { 893 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 894 1.1 mrg 895 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 896 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 897 1.1 mrg 898 1.1 mrg __is >> __x._M_b; 899 1.1 mrg for (size_t __i = 0; __i < __k; ++__i) 900 1.1 mrg __is >> __x._M_v[__i]; 901 1.1 mrg __is >> __x._M_y; 902 1.1 mrg 903 1.1 mrg __is.flags(__flags); 904 1.1 mrg return __is; 905 1.1 mrg } 906 1.1 mrg 907 1.1 mrg 908 1.1 mrg template<typename _IntType, typename _CharT, typename _Traits> 909 1.1 mrg std::basic_ostream<_CharT, _Traits>& 910 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 911 1.1 mrg const uniform_int_distribution<_IntType>& __x) 912 1.1 mrg { 913 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 914 1.1 mrg 915 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 916 1.1 mrg const _CharT __fill = __os.fill(); 917 1.1 mrg const _CharT __space = __os.widen(' '); 918 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 919 1.1 mrg __os.fill(__space); 920 1.1 mrg 921 1.1 mrg __os << __x.a() << __space << __x.b(); 922 1.1 mrg 923 1.1 mrg __os.flags(__flags); 924 1.1 mrg __os.fill(__fill); 925 1.1 mrg return __os; 926 1.1 mrg } 927 1.1 mrg 928 1.1 mrg template<typename _IntType, typename _CharT, typename _Traits> 929 1.1 mrg std::basic_istream<_CharT, _Traits>& 930 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 931 1.1 mrg uniform_int_distribution<_IntType>& __x) 932 1.1 mrg { 933 1.1.1.12 mrg using param_type 934 1.1.1.12 mrg = typename uniform_int_distribution<_IntType>::param_type; 935 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 936 1.1 mrg 937 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 938 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 939 1.1 mrg 940 1.1 mrg _IntType __a, __b; 941 1.1.1.10 mrg if (__is >> __a >> __b) 942 1.1.1.12 mrg __x.param(param_type(__a, __b)); 943 1.1 mrg 944 1.1 mrg __is.flags(__flags); 945 1.1 mrg return __is; 946 1.1 mrg } 947 1.1 mrg 948 1.1 mrg 949 1.1.1.2 mrg template<typename _RealType> 950 1.1.1.2 mrg template<typename _ForwardIterator, 951 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 952 1.1.1.2 mrg void 953 1.1.1.2 mrg uniform_real_distribution<_RealType>:: 954 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 955 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 956 1.1.1.2 mrg const param_type& __p) 957 1.1.1.2 mrg { 958 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 959 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 960 1.1.1.2 mrg __aurng(__urng); 961 1.1.1.2 mrg auto __range = __p.b() - __p.a(); 962 1.1.1.2 mrg while (__f != __t) 963 1.1.1.2 mrg *__f++ = __aurng() * __range + __p.a(); 964 1.1.1.2 mrg } 965 1.1.1.2 mrg 966 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 967 1.1 mrg std::basic_ostream<_CharT, _Traits>& 968 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 969 1.1 mrg const uniform_real_distribution<_RealType>& __x) 970 1.1 mrg { 971 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 972 1.1 mrg 973 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 974 1.1 mrg const _CharT __fill = __os.fill(); 975 1.1 mrg const std::streamsize __precision = __os.precision(); 976 1.1 mrg const _CharT __space = __os.widen(' '); 977 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 978 1.1 mrg __os.fill(__space); 979 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 980 1.1 mrg 981 1.1 mrg __os << __x.a() << __space << __x.b(); 982 1.1 mrg 983 1.1 mrg __os.flags(__flags); 984 1.1 mrg __os.fill(__fill); 985 1.1 mrg __os.precision(__precision); 986 1.1 mrg return __os; 987 1.1 mrg } 988 1.1 mrg 989 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 990 1.1 mrg std::basic_istream<_CharT, _Traits>& 991 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 992 1.1 mrg uniform_real_distribution<_RealType>& __x) 993 1.1 mrg { 994 1.1.1.12 mrg using param_type 995 1.1.1.12 mrg = typename uniform_real_distribution<_RealType>::param_type; 996 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 997 1.1 mrg 998 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 999 1.1 mrg __is.flags(__ios_base::skipws); 1000 1.1 mrg 1001 1.1 mrg _RealType __a, __b; 1002 1.1.1.10 mrg if (__is >> __a >> __b) 1003 1.1.1.12 mrg __x.param(param_type(__a, __b)); 1004 1.1 mrg 1005 1.1 mrg __is.flags(__flags); 1006 1.1 mrg return __is; 1007 1.1 mrg } 1008 1.1 mrg 1009 1.1 mrg 1010 1.1.1.2 mrg template<typename _ForwardIterator, 1011 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1012 1.1.1.2 mrg void 1013 1.1.1.2 mrg std::bernoulli_distribution:: 1014 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1015 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1016 1.1.1.2 mrg const param_type& __p) 1017 1.1.1.2 mrg { 1018 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1019 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 1020 1.1.1.2 mrg __aurng(__urng); 1021 1.1.1.2 mrg auto __limit = __p.p() * (__aurng.max() - __aurng.min()); 1022 1.1.1.2 mrg 1023 1.1.1.2 mrg while (__f != __t) 1024 1.1.1.2 mrg *__f++ = (__aurng() - __aurng.min()) < __limit; 1025 1.1.1.2 mrg } 1026 1.1.1.2 mrg 1027 1.1 mrg template<typename _CharT, typename _Traits> 1028 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1029 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1030 1.1 mrg const bernoulli_distribution& __x) 1031 1.1 mrg { 1032 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1033 1.1 mrg 1034 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1035 1.1 mrg const _CharT __fill = __os.fill(); 1036 1.1 mrg const std::streamsize __precision = __os.precision(); 1037 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1038 1.1 mrg __os.fill(__os.widen(' ')); 1039 1.1 mrg __os.precision(std::numeric_limits<double>::max_digits10); 1040 1.1 mrg 1041 1.1 mrg __os << __x.p(); 1042 1.1 mrg 1043 1.1 mrg __os.flags(__flags); 1044 1.1 mrg __os.fill(__fill); 1045 1.1 mrg __os.precision(__precision); 1046 1.1 mrg return __os; 1047 1.1 mrg } 1048 1.1 mrg 1049 1.1 mrg 1050 1.1 mrg template<typename _IntType> 1051 1.1 mrg template<typename _UniformRandomNumberGenerator> 1052 1.1 mrg typename geometric_distribution<_IntType>::result_type 1053 1.1 mrg geometric_distribution<_IntType>:: 1054 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 1055 1.1 mrg const param_type& __param) 1056 1.1 mrg { 1057 1.1 mrg // About the epsilon thing see this thread: 1058 1.1 mrg // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html 1059 1.1 mrg const double __naf = 1060 1.1 mrg (1 - std::numeric_limits<double>::epsilon()) / 2; 1061 1.1 mrg // The largest _RealType convertible to _IntType. 1062 1.1 mrg const double __thr = 1063 1.1 mrg std::numeric_limits<_IntType>::max() + __naf; 1064 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 1065 1.1 mrg __aurng(__urng); 1066 1.1 mrg 1067 1.1 mrg double __cand; 1068 1.1 mrg do 1069 1.1.1.2 mrg __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p); 1070 1.1 mrg while (__cand >= __thr); 1071 1.1 mrg 1072 1.1 mrg return result_type(__cand + __naf); 1073 1.1 mrg } 1074 1.1 mrg 1075 1.1.1.2 mrg template<typename _IntType> 1076 1.1.1.2 mrg template<typename _ForwardIterator, 1077 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1078 1.1.1.2 mrg void 1079 1.1.1.2 mrg geometric_distribution<_IntType>:: 1080 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1081 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1082 1.1.1.2 mrg const param_type& __param) 1083 1.1.1.2 mrg { 1084 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1085 1.1.1.2 mrg // About the epsilon thing see this thread: 1086 1.1.1.2 mrg // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html 1087 1.1.1.2 mrg const double __naf = 1088 1.1.1.2 mrg (1 - std::numeric_limits<double>::epsilon()) / 2; 1089 1.1.1.2 mrg // The largest _RealType convertible to _IntType. 1090 1.1.1.2 mrg const double __thr = 1091 1.1.1.2 mrg std::numeric_limits<_IntType>::max() + __naf; 1092 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 1093 1.1.1.2 mrg __aurng(__urng); 1094 1.1.1.2 mrg 1095 1.1.1.2 mrg while (__f != __t) 1096 1.1.1.2 mrg { 1097 1.1.1.2 mrg double __cand; 1098 1.1.1.2 mrg do 1099 1.1.1.2 mrg __cand = std::floor(std::log(1.0 - __aurng()) 1100 1.1.1.2 mrg / __param._M_log_1_p); 1101 1.1.1.2 mrg while (__cand >= __thr); 1102 1.1.1.2 mrg 1103 1.1.1.2 mrg *__f++ = __cand + __naf; 1104 1.1.1.2 mrg } 1105 1.1.1.2 mrg } 1106 1.1.1.2 mrg 1107 1.1 mrg template<typename _IntType, 1108 1.1 mrg typename _CharT, typename _Traits> 1109 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1110 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1111 1.1 mrg const geometric_distribution<_IntType>& __x) 1112 1.1 mrg { 1113 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1114 1.1 mrg 1115 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1116 1.1 mrg const _CharT __fill = __os.fill(); 1117 1.1 mrg const std::streamsize __precision = __os.precision(); 1118 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1119 1.1 mrg __os.fill(__os.widen(' ')); 1120 1.1 mrg __os.precision(std::numeric_limits<double>::max_digits10); 1121 1.1 mrg 1122 1.1 mrg __os << __x.p(); 1123 1.1 mrg 1124 1.1 mrg __os.flags(__flags); 1125 1.1 mrg __os.fill(__fill); 1126 1.1 mrg __os.precision(__precision); 1127 1.1 mrg return __os; 1128 1.1 mrg } 1129 1.1 mrg 1130 1.1 mrg template<typename _IntType, 1131 1.1 mrg typename _CharT, typename _Traits> 1132 1.1 mrg std::basic_istream<_CharT, _Traits>& 1133 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 1134 1.1 mrg geometric_distribution<_IntType>& __x) 1135 1.1 mrg { 1136 1.1.1.12 mrg using param_type = typename geometric_distribution<_IntType>::param_type; 1137 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 1138 1.1 mrg 1139 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 1140 1.1 mrg __is.flags(__ios_base::skipws); 1141 1.1 mrg 1142 1.1 mrg double __p; 1143 1.1.1.10 mrg if (__is >> __p) 1144 1.1.1.12 mrg __x.param(param_type(__p)); 1145 1.1 mrg 1146 1.1 mrg __is.flags(__flags); 1147 1.1 mrg return __is; 1148 1.1 mrg } 1149 1.1 mrg 1150 1.1.1.2 mrg // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5. 1151 1.1 mrg template<typename _IntType> 1152 1.1 mrg template<typename _UniformRandomNumberGenerator> 1153 1.1 mrg typename negative_binomial_distribution<_IntType>::result_type 1154 1.1 mrg negative_binomial_distribution<_IntType>:: 1155 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng) 1156 1.1 mrg { 1157 1.1 mrg const double __y = _M_gd(__urng); 1158 1.1 mrg 1159 1.1 mrg // XXX Is the constructor too slow? 1160 1.1 mrg std::poisson_distribution<result_type> __poisson(__y); 1161 1.1 mrg return __poisson(__urng); 1162 1.1 mrg } 1163 1.1 mrg 1164 1.1 mrg template<typename _IntType> 1165 1.1 mrg template<typename _UniformRandomNumberGenerator> 1166 1.1 mrg typename negative_binomial_distribution<_IntType>::result_type 1167 1.1 mrg negative_binomial_distribution<_IntType>:: 1168 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 1169 1.1 mrg const param_type& __p) 1170 1.1 mrg { 1171 1.1.1.2 mrg typedef typename std::gamma_distribution<double>::param_type 1172 1.1 mrg param_type; 1173 1.1 mrg 1174 1.1 mrg const double __y = 1175 1.1.1.2 mrg _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p())); 1176 1.1 mrg 1177 1.1 mrg std::poisson_distribution<result_type> __poisson(__y); 1178 1.1 mrg return __poisson(__urng); 1179 1.1 mrg } 1180 1.1 mrg 1181 1.1.1.2 mrg template<typename _IntType> 1182 1.1.1.2 mrg template<typename _ForwardIterator, 1183 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1184 1.1.1.2 mrg void 1185 1.1.1.2 mrg negative_binomial_distribution<_IntType>:: 1186 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1187 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng) 1188 1.1.1.2 mrg { 1189 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1190 1.1.1.2 mrg while (__f != __t) 1191 1.1.1.2 mrg { 1192 1.1.1.2 mrg const double __y = _M_gd(__urng); 1193 1.1.1.2 mrg 1194 1.1.1.2 mrg // XXX Is the constructor too slow? 1195 1.1.1.2 mrg std::poisson_distribution<result_type> __poisson(__y); 1196 1.1.1.2 mrg *__f++ = __poisson(__urng); 1197 1.1.1.2 mrg } 1198 1.1.1.2 mrg } 1199 1.1.1.2 mrg 1200 1.1.1.2 mrg template<typename _IntType> 1201 1.1.1.2 mrg template<typename _ForwardIterator, 1202 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1203 1.1.1.2 mrg void 1204 1.1.1.2 mrg negative_binomial_distribution<_IntType>:: 1205 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1206 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1207 1.1.1.2 mrg const param_type& __p) 1208 1.1.1.2 mrg { 1209 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1210 1.1.1.2 mrg typename std::gamma_distribution<result_type>::param_type 1211 1.1.1.2 mrg __p2(__p.k(), (1.0 - __p.p()) / __p.p()); 1212 1.1.1.2 mrg 1213 1.1.1.2 mrg while (__f != __t) 1214 1.1.1.2 mrg { 1215 1.1.1.2 mrg const double __y = _M_gd(__urng, __p2); 1216 1.1.1.2 mrg 1217 1.1.1.2 mrg std::poisson_distribution<result_type> __poisson(__y); 1218 1.1.1.2 mrg *__f++ = __poisson(__urng); 1219 1.1.1.2 mrg } 1220 1.1.1.2 mrg } 1221 1.1.1.2 mrg 1222 1.1 mrg template<typename _IntType, typename _CharT, typename _Traits> 1223 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1224 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1225 1.1 mrg const negative_binomial_distribution<_IntType>& __x) 1226 1.1 mrg { 1227 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1228 1.1 mrg 1229 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1230 1.1 mrg const _CharT __fill = __os.fill(); 1231 1.1 mrg const std::streamsize __precision = __os.precision(); 1232 1.1 mrg const _CharT __space = __os.widen(' '); 1233 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1234 1.1 mrg __os.fill(__os.widen(' ')); 1235 1.1 mrg __os.precision(std::numeric_limits<double>::max_digits10); 1236 1.1 mrg 1237 1.1 mrg __os << __x.k() << __space << __x.p() 1238 1.1 mrg << __space << __x._M_gd; 1239 1.1 mrg 1240 1.1 mrg __os.flags(__flags); 1241 1.1 mrg __os.fill(__fill); 1242 1.1 mrg __os.precision(__precision); 1243 1.1 mrg return __os; 1244 1.1 mrg } 1245 1.1 mrg 1246 1.1 mrg template<typename _IntType, typename _CharT, typename _Traits> 1247 1.1 mrg std::basic_istream<_CharT, _Traits>& 1248 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 1249 1.1 mrg negative_binomial_distribution<_IntType>& __x) 1250 1.1 mrg { 1251 1.1.1.12 mrg using param_type 1252 1.1.1.12 mrg = typename negative_binomial_distribution<_IntType>::param_type; 1253 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 1254 1.1 mrg 1255 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 1256 1.1 mrg __is.flags(__ios_base::skipws); 1257 1.1 mrg 1258 1.1 mrg _IntType __k; 1259 1.1 mrg double __p; 1260 1.1.1.10 mrg if (__is >> __k >> __p >> __x._M_gd) 1261 1.1.1.12 mrg __x.param(param_type(__k, __p)); 1262 1.1 mrg 1263 1.1 mrg __is.flags(__flags); 1264 1.1 mrg return __is; 1265 1.1 mrg } 1266 1.1 mrg 1267 1.1 mrg 1268 1.1 mrg template<typename _IntType> 1269 1.1 mrg void 1270 1.1 mrg poisson_distribution<_IntType>::param_type:: 1271 1.1 mrg _M_initialize() 1272 1.1 mrg { 1273 1.1.1.16 mrg #if _GLIBCXX_USE_C99_MATH_FUNCS 1274 1.1 mrg if (_M_mean >= 12) 1275 1.1 mrg { 1276 1.1 mrg const double __m = std::floor(_M_mean); 1277 1.1 mrg _M_lm_thr = std::log(_M_mean); 1278 1.1 mrg _M_lfm = std::lgamma(__m + 1); 1279 1.1 mrg _M_sm = std::sqrt(__m); 1280 1.1 mrg 1281 1.1 mrg const double __pi_4 = 0.7853981633974483096156608458198757L; 1282 1.1 mrg const double __dx = std::sqrt(2 * __m * std::log(32 * __m 1283 1.1 mrg / __pi_4)); 1284 1.1.1.5 mrg _M_d = std::round(std::max<double>(6.0, std::min(__m, __dx))); 1285 1.1 mrg const double __cx = 2 * __m + _M_d; 1286 1.1 mrg _M_scx = std::sqrt(__cx / 2); 1287 1.1 mrg _M_1cx = 1 / __cx; 1288 1.1 mrg 1289 1.1 mrg _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx); 1290 1.1 mrg _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) 1291 1.1 mrg / _M_d; 1292 1.1 mrg } 1293 1.1 mrg else 1294 1.1 mrg #endif 1295 1.1 mrg _M_lm_thr = std::exp(-_M_mean); 1296 1.1 mrg } 1297 1.1 mrg 1298 1.1 mrg /** 1299 1.1 mrg * A rejection algorithm when mean >= 12 and a simple method based 1300 1.1 mrg * upon the multiplication of uniform random variates otherwise. 1301 1.1.1.16 mrg * NB: The former is available only if _GLIBCXX_USE_C99_MATH_FUNCS 1302 1.1 mrg * is defined. 1303 1.1 mrg * 1304 1.1 mrg * Reference: 1305 1.1 mrg * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 1306 1.1 mrg * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!). 1307 1.1 mrg */ 1308 1.1 mrg template<typename _IntType> 1309 1.1 mrg template<typename _UniformRandomNumberGenerator> 1310 1.1 mrg typename poisson_distribution<_IntType>::result_type 1311 1.1 mrg poisson_distribution<_IntType>:: 1312 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 1313 1.1 mrg const param_type& __param) 1314 1.1 mrg { 1315 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 1316 1.1 mrg __aurng(__urng); 1317 1.1.1.16 mrg #if _GLIBCXX_USE_C99_MATH_FUNCS 1318 1.1 mrg if (__param.mean() >= 12) 1319 1.1 mrg { 1320 1.1 mrg double __x; 1321 1.1 mrg 1322 1.1 mrg // See comments above... 1323 1.1 mrg const double __naf = 1324 1.1 mrg (1 - std::numeric_limits<double>::epsilon()) / 2; 1325 1.1 mrg const double __thr = 1326 1.1 mrg std::numeric_limits<_IntType>::max() + __naf; 1327 1.1 mrg 1328 1.1 mrg const double __m = std::floor(__param.mean()); 1329 1.1 mrg // sqrt(pi / 2) 1330 1.1 mrg const double __spi_2 = 1.2533141373155002512078826424055226L; 1331 1.1 mrg const double __c1 = __param._M_sm * __spi_2; 1332 1.1 mrg const double __c2 = __param._M_c2b + __c1; 1333 1.1 mrg const double __c3 = __c2 + 1; 1334 1.1 mrg const double __c4 = __c3 + 1; 1335 1.1.1.10 mrg // 1 / 78 1336 1.1.1.10 mrg const double __178 = 0.0128205128205128205128205128205128L; 1337 1.1 mrg // e^(1 / 78) 1338 1.1 mrg const double __e178 = 1.0129030479320018583185514777512983L; 1339 1.1 mrg const double __c5 = __c4 + __e178; 1340 1.1 mrg const double __c = __param._M_cb + __c5; 1341 1.1 mrg const double __2cx = 2 * (2 * __m + __param._M_d); 1342 1.1 mrg 1343 1.1 mrg bool __reject = true; 1344 1.1 mrg do 1345 1.1 mrg { 1346 1.1 mrg const double __u = __c * __aurng(); 1347 1.1.1.2 mrg const double __e = -std::log(1.0 - __aurng()); 1348 1.1 mrg 1349 1.1 mrg double __w = 0.0; 1350 1.1 mrg 1351 1.1 mrg if (__u <= __c1) 1352 1.1 mrg { 1353 1.1 mrg const double __n = _M_nd(__urng); 1354 1.1 mrg const double __y = -std::abs(__n) * __param._M_sm - 1; 1355 1.1 mrg __x = std::floor(__y); 1356 1.1 mrg __w = -__n * __n / 2; 1357 1.1 mrg if (__x < -__m) 1358 1.1 mrg continue; 1359 1.1 mrg } 1360 1.1 mrg else if (__u <= __c2) 1361 1.1 mrg { 1362 1.1 mrg const double __n = _M_nd(__urng); 1363 1.1 mrg const double __y = 1 + std::abs(__n) * __param._M_scx; 1364 1.1 mrg __x = std::ceil(__y); 1365 1.1 mrg __w = __y * (2 - __y) * __param._M_1cx; 1366 1.1 mrg if (__x > __param._M_d) 1367 1.1 mrg continue; 1368 1.1 mrg } 1369 1.1 mrg else if (__u <= __c3) 1370 1.1 mrg // NB: This case not in the book, nor in the Errata, 1371 1.1 mrg // but should be ok... 1372 1.1 mrg __x = -1; 1373 1.1 mrg else if (__u <= __c4) 1374 1.1 mrg __x = 0; 1375 1.1 mrg else if (__u <= __c5) 1376 1.1.1.10 mrg { 1377 1.1.1.10 mrg __x = 1; 1378 1.1.1.10 mrg // Only in the Errata, see libstdc++/83237. 1379 1.1.1.10 mrg __w = __178; 1380 1.1.1.10 mrg } 1381 1.1 mrg else 1382 1.1 mrg { 1383 1.1.1.2 mrg const double __v = -std::log(1.0 - __aurng()); 1384 1.1 mrg const double __y = __param._M_d 1385 1.1 mrg + __v * __2cx / __param._M_d; 1386 1.1 mrg __x = std::ceil(__y); 1387 1.1 mrg __w = -__param._M_d * __param._M_1cx * (1 + __y / 2); 1388 1.1 mrg } 1389 1.1 mrg 1390 1.1 mrg __reject = (__w - __e - __x * __param._M_lm_thr 1391 1.1 mrg > __param._M_lfm - std::lgamma(__x + __m + 1)); 1392 1.1 mrg 1393 1.1 mrg __reject |= __x + __m >= __thr; 1394 1.1 mrg 1395 1.1 mrg } while (__reject); 1396 1.1 mrg 1397 1.1 mrg return result_type(__x + __m + __naf); 1398 1.1 mrg } 1399 1.1 mrg else 1400 1.1 mrg #endif 1401 1.1 mrg { 1402 1.1 mrg _IntType __x = 0; 1403 1.1 mrg double __prod = 1.0; 1404 1.1 mrg 1405 1.1 mrg do 1406 1.1 mrg { 1407 1.1 mrg __prod *= __aurng(); 1408 1.1 mrg __x += 1; 1409 1.1 mrg } 1410 1.1 mrg while (__prod > __param._M_lm_thr); 1411 1.1 mrg 1412 1.1 mrg return __x - 1; 1413 1.1 mrg } 1414 1.1 mrg } 1415 1.1 mrg 1416 1.1.1.2 mrg template<typename _IntType> 1417 1.1.1.2 mrg template<typename _ForwardIterator, 1418 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1419 1.1.1.2 mrg void 1420 1.1.1.2 mrg poisson_distribution<_IntType>:: 1421 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1422 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1423 1.1.1.2 mrg const param_type& __param) 1424 1.1.1.2 mrg { 1425 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1426 1.1.1.2 mrg // We could duplicate everything from operator()... 1427 1.1.1.2 mrg while (__f != __t) 1428 1.1.1.2 mrg *__f++ = this->operator()(__urng, __param); 1429 1.1.1.2 mrg } 1430 1.1.1.2 mrg 1431 1.1 mrg template<typename _IntType, 1432 1.1 mrg typename _CharT, typename _Traits> 1433 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1434 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1435 1.1 mrg const poisson_distribution<_IntType>& __x) 1436 1.1 mrg { 1437 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1438 1.1 mrg 1439 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1440 1.1 mrg const _CharT __fill = __os.fill(); 1441 1.1 mrg const std::streamsize __precision = __os.precision(); 1442 1.1 mrg const _CharT __space = __os.widen(' '); 1443 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1444 1.1 mrg __os.fill(__space); 1445 1.1 mrg __os.precision(std::numeric_limits<double>::max_digits10); 1446 1.1 mrg 1447 1.1 mrg __os << __x.mean() << __space << __x._M_nd; 1448 1.1 mrg 1449 1.1 mrg __os.flags(__flags); 1450 1.1 mrg __os.fill(__fill); 1451 1.1 mrg __os.precision(__precision); 1452 1.1 mrg return __os; 1453 1.1 mrg } 1454 1.1 mrg 1455 1.1 mrg template<typename _IntType, 1456 1.1 mrg typename _CharT, typename _Traits> 1457 1.1 mrg std::basic_istream<_CharT, _Traits>& 1458 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 1459 1.1 mrg poisson_distribution<_IntType>& __x) 1460 1.1 mrg { 1461 1.1.1.12 mrg using param_type = typename poisson_distribution<_IntType>::param_type; 1462 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 1463 1.1 mrg 1464 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 1465 1.1 mrg __is.flags(__ios_base::skipws); 1466 1.1 mrg 1467 1.1 mrg double __mean; 1468 1.1.1.10 mrg if (__is >> __mean >> __x._M_nd) 1469 1.1.1.12 mrg __x.param(param_type(__mean)); 1470 1.1 mrg 1471 1.1 mrg __is.flags(__flags); 1472 1.1 mrg return __is; 1473 1.1 mrg } 1474 1.1 mrg 1475 1.1 mrg 1476 1.1 mrg template<typename _IntType> 1477 1.1 mrg void 1478 1.1 mrg binomial_distribution<_IntType>::param_type:: 1479 1.1 mrg _M_initialize() 1480 1.1 mrg { 1481 1.1 mrg const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; 1482 1.1 mrg 1483 1.1 mrg _M_easy = true; 1484 1.1 mrg 1485 1.1.1.16 mrg #if _GLIBCXX_USE_C99_MATH_FUNCS 1486 1.1 mrg if (_M_t * __p12 >= 8) 1487 1.1 mrg { 1488 1.1 mrg _M_easy = false; 1489 1.1 mrg const double __np = std::floor(_M_t * __p12); 1490 1.1 mrg const double __pa = __np / _M_t; 1491 1.1 mrg const double __1p = 1 - __pa; 1492 1.1 mrg 1493 1.1 mrg const double __pi_4 = 0.7853981633974483096156608458198757L; 1494 1.1 mrg const double __d1x = 1495 1.1 mrg std::sqrt(__np * __1p * std::log(32 * __np 1496 1.1 mrg / (81 * __pi_4 * __1p))); 1497 1.1.1.5 mrg _M_d1 = std::round(std::max<double>(1.0, __d1x)); 1498 1.1 mrg const double __d2x = 1499 1.1 mrg std::sqrt(__np * __1p * std::log(32 * _M_t * __1p 1500 1.1 mrg / (__pi_4 * __pa))); 1501 1.1.1.5 mrg _M_d2 = std::round(std::max<double>(1.0, __d2x)); 1502 1.1 mrg 1503 1.1 mrg // sqrt(pi / 2) 1504 1.1 mrg const double __spi_2 = 1.2533141373155002512078826424055226L; 1505 1.1 mrg _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np)); 1506 1.1.1.15 mrg _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * (_M_t * __1p))); 1507 1.1 mrg _M_c = 2 * _M_d1 / __np; 1508 1.1 mrg _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2; 1509 1.1 mrg const double __a12 = _M_a1 + _M_s2 * __spi_2; 1510 1.1 mrg const double __s1s = _M_s1 * _M_s1; 1511 1.1 mrg _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p)) 1512 1.1 mrg * 2 * __s1s / _M_d1 1513 1.1 mrg * std::exp(-_M_d1 * _M_d1 / (2 * __s1s))); 1514 1.1 mrg const double __s2s = _M_s2 * _M_s2; 1515 1.1 mrg _M_s = (_M_a123 + 2 * __s2s / _M_d2 1516 1.1 mrg * std::exp(-_M_d2 * _M_d2 / (2 * __s2s))); 1517 1.1 mrg _M_lf = (std::lgamma(__np + 1) 1518 1.1 mrg + std::lgamma(_M_t - __np + 1)); 1519 1.1 mrg _M_lp1p = std::log(__pa / __1p); 1520 1.1 mrg 1521 1.1 mrg _M_q = -std::log(1 - (__p12 - __pa) / __1p); 1522 1.1 mrg } 1523 1.1 mrg else 1524 1.1 mrg #endif 1525 1.1 mrg _M_q = -std::log(1 - __p12); 1526 1.1 mrg } 1527 1.1 mrg 1528 1.1 mrg template<typename _IntType> 1529 1.1 mrg template<typename _UniformRandomNumberGenerator> 1530 1.1 mrg typename binomial_distribution<_IntType>::result_type 1531 1.1 mrg binomial_distribution<_IntType>:: 1532 1.1.1.2 mrg _M_waiting(_UniformRandomNumberGenerator& __urng, 1533 1.1.1.2 mrg _IntType __t, double __q) 1534 1.1 mrg { 1535 1.1 mrg _IntType __x = 0; 1536 1.1 mrg double __sum = 0.0; 1537 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 1538 1.1 mrg __aurng(__urng); 1539 1.1 mrg 1540 1.1 mrg do 1541 1.1 mrg { 1542 1.1.1.2 mrg if (__t == __x) 1543 1.1.1.2 mrg return __x; 1544 1.1.1.2 mrg const double __e = -std::log(1.0 - __aurng()); 1545 1.1 mrg __sum += __e / (__t - __x); 1546 1.1 mrg __x += 1; 1547 1.1 mrg } 1548 1.1.1.2 mrg while (__sum <= __q); 1549 1.1 mrg 1550 1.1 mrg return __x - 1; 1551 1.1 mrg } 1552 1.1 mrg 1553 1.1 mrg /** 1554 1.1 mrg * A rejection algorithm when t * p >= 8 and a simple waiting time 1555 1.1 mrg * method - the second in the referenced book - otherwise. 1556 1.1.1.16 mrg * NB: The former is available only if _GLIBCXX_USE_C99_MATH_FUNCS 1557 1.1 mrg * is defined. 1558 1.1 mrg * 1559 1.1 mrg * Reference: 1560 1.1 mrg * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 1561 1.1 mrg * New York, 1986, Ch. X, Sect. 4 (+ Errata!). 1562 1.1 mrg */ 1563 1.1 mrg template<typename _IntType> 1564 1.1 mrg template<typename _UniformRandomNumberGenerator> 1565 1.1 mrg typename binomial_distribution<_IntType>::result_type 1566 1.1 mrg binomial_distribution<_IntType>:: 1567 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 1568 1.1 mrg const param_type& __param) 1569 1.1 mrg { 1570 1.1 mrg result_type __ret; 1571 1.1 mrg const _IntType __t = __param.t(); 1572 1.1 mrg const double __p = __param.p(); 1573 1.1 mrg const double __p12 = __p <= 0.5 ? __p : 1.0 - __p; 1574 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 1575 1.1 mrg __aurng(__urng); 1576 1.1 mrg 1577 1.1.1.16 mrg #if _GLIBCXX_USE_C99_MATH_FUNCS 1578 1.1 mrg if (!__param._M_easy) 1579 1.1 mrg { 1580 1.1 mrg double __x; 1581 1.1 mrg 1582 1.1 mrg // See comments above... 1583 1.1 mrg const double __naf = 1584 1.1 mrg (1 - std::numeric_limits<double>::epsilon()) / 2; 1585 1.1 mrg const double __thr = 1586 1.1 mrg std::numeric_limits<_IntType>::max() + __naf; 1587 1.1 mrg 1588 1.1 mrg const double __np = std::floor(__t * __p12); 1589 1.1 mrg 1590 1.1 mrg // sqrt(pi / 2) 1591 1.1 mrg const double __spi_2 = 1.2533141373155002512078826424055226L; 1592 1.1 mrg const double __a1 = __param._M_a1; 1593 1.1 mrg const double __a12 = __a1 + __param._M_s2 * __spi_2; 1594 1.1 mrg const double __a123 = __param._M_a123; 1595 1.1 mrg const double __s1s = __param._M_s1 * __param._M_s1; 1596 1.1 mrg const double __s2s = __param._M_s2 * __param._M_s2; 1597 1.1 mrg 1598 1.1 mrg bool __reject; 1599 1.1 mrg do 1600 1.1 mrg { 1601 1.1 mrg const double __u = __param._M_s * __aurng(); 1602 1.1 mrg 1603 1.1 mrg double __v; 1604 1.1 mrg 1605 1.1 mrg if (__u <= __a1) 1606 1.1 mrg { 1607 1.1 mrg const double __n = _M_nd(__urng); 1608 1.1 mrg const double __y = __param._M_s1 * std::abs(__n); 1609 1.1 mrg __reject = __y >= __param._M_d1; 1610 1.1 mrg if (!__reject) 1611 1.1 mrg { 1612 1.1.1.2 mrg const double __e = -std::log(1.0 - __aurng()); 1613 1.1 mrg __x = std::floor(__y); 1614 1.1 mrg __v = -__e - __n * __n / 2 + __param._M_c; 1615 1.1 mrg } 1616 1.1 mrg } 1617 1.1 mrg else if (__u <= __a12) 1618 1.1 mrg { 1619 1.1 mrg const double __n = _M_nd(__urng); 1620 1.1 mrg const double __y = __param._M_s2 * std::abs(__n); 1621 1.1 mrg __reject = __y >= __param._M_d2; 1622 1.1 mrg if (!__reject) 1623 1.1 mrg { 1624 1.1.1.2 mrg const double __e = -std::log(1.0 - __aurng()); 1625 1.1 mrg __x = std::floor(-__y); 1626 1.1 mrg __v = -__e - __n * __n / 2; 1627 1.1 mrg } 1628 1.1 mrg } 1629 1.1 mrg else if (__u <= __a123) 1630 1.1 mrg { 1631 1.1.1.2 mrg const double __e1 = -std::log(1.0 - __aurng()); 1632 1.1.1.2 mrg const double __e2 = -std::log(1.0 - __aurng()); 1633 1.1 mrg 1634 1.1 mrg const double __y = __param._M_d1 1635 1.1 mrg + 2 * __s1s * __e1 / __param._M_d1; 1636 1.1 mrg __x = std::floor(__y); 1637 1.1 mrg __v = (-__e2 + __param._M_d1 * (1 / (__t - __np) 1638 1.1 mrg -__y / (2 * __s1s))); 1639 1.1 mrg __reject = false; 1640 1.1 mrg } 1641 1.1 mrg else 1642 1.1 mrg { 1643 1.1.1.2 mrg const double __e1 = -std::log(1.0 - __aurng()); 1644 1.1.1.2 mrg const double __e2 = -std::log(1.0 - __aurng()); 1645 1.1 mrg 1646 1.1 mrg const double __y = __param._M_d2 1647 1.1 mrg + 2 * __s2s * __e1 / __param._M_d2; 1648 1.1 mrg __x = std::floor(-__y); 1649 1.1 mrg __v = -__e2 - __param._M_d2 * __y / (2 * __s2s); 1650 1.1 mrg __reject = false; 1651 1.1 mrg } 1652 1.1 mrg 1653 1.1 mrg __reject = __reject || __x < -__np || __x > __t - __np; 1654 1.1 mrg if (!__reject) 1655 1.1 mrg { 1656 1.1 mrg const double __lfx = 1657 1.1 mrg std::lgamma(__np + __x + 1) 1658 1.1 mrg + std::lgamma(__t - (__np + __x) + 1); 1659 1.1 mrg __reject = __v > __param._M_lf - __lfx 1660 1.1 mrg + __x * __param._M_lp1p; 1661 1.1 mrg } 1662 1.1 mrg 1663 1.1 mrg __reject |= __x + __np >= __thr; 1664 1.1 mrg } 1665 1.1 mrg while (__reject); 1666 1.1 mrg 1667 1.1 mrg __x += __np + __naf; 1668 1.1 mrg 1669 1.1.1.2 mrg const _IntType __z = _M_waiting(__urng, __t - _IntType(__x), 1670 1.1.1.2 mrg __param._M_q); 1671 1.1 mrg __ret = _IntType(__x) + __z; 1672 1.1 mrg } 1673 1.1 mrg else 1674 1.1 mrg #endif 1675 1.1.1.2 mrg __ret = _M_waiting(__urng, __t, __param._M_q); 1676 1.1 mrg 1677 1.1 mrg if (__p12 != __p) 1678 1.1 mrg __ret = __t - __ret; 1679 1.1 mrg return __ret; 1680 1.1 mrg } 1681 1.1 mrg 1682 1.1.1.2 mrg template<typename _IntType> 1683 1.1.1.2 mrg template<typename _ForwardIterator, 1684 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1685 1.1.1.2 mrg void 1686 1.1.1.2 mrg binomial_distribution<_IntType>:: 1687 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1688 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1689 1.1.1.2 mrg const param_type& __param) 1690 1.1.1.2 mrg { 1691 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1692 1.1.1.2 mrg // We could duplicate everything from operator()... 1693 1.1.1.2 mrg while (__f != __t) 1694 1.1.1.2 mrg *__f++ = this->operator()(__urng, __param); 1695 1.1.1.2 mrg } 1696 1.1.1.2 mrg 1697 1.1 mrg template<typename _IntType, 1698 1.1 mrg typename _CharT, typename _Traits> 1699 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1700 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1701 1.1 mrg const binomial_distribution<_IntType>& __x) 1702 1.1 mrg { 1703 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1704 1.1 mrg 1705 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1706 1.1 mrg const _CharT __fill = __os.fill(); 1707 1.1 mrg const std::streamsize __precision = __os.precision(); 1708 1.1 mrg const _CharT __space = __os.widen(' '); 1709 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1710 1.1 mrg __os.fill(__space); 1711 1.1 mrg __os.precision(std::numeric_limits<double>::max_digits10); 1712 1.1 mrg 1713 1.1 mrg __os << __x.t() << __space << __x.p() 1714 1.1 mrg << __space << __x._M_nd; 1715 1.1 mrg 1716 1.1 mrg __os.flags(__flags); 1717 1.1 mrg __os.fill(__fill); 1718 1.1 mrg __os.precision(__precision); 1719 1.1 mrg return __os; 1720 1.1 mrg } 1721 1.1 mrg 1722 1.1 mrg template<typename _IntType, 1723 1.1 mrg typename _CharT, typename _Traits> 1724 1.1 mrg std::basic_istream<_CharT, _Traits>& 1725 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 1726 1.1 mrg binomial_distribution<_IntType>& __x) 1727 1.1 mrg { 1728 1.1.1.12 mrg using param_type = typename binomial_distribution<_IntType>::param_type; 1729 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 1730 1.1 mrg 1731 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 1732 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 1733 1.1 mrg 1734 1.1 mrg _IntType __t; 1735 1.1 mrg double __p; 1736 1.1.1.10 mrg if (__is >> __t >> __p >> __x._M_nd) 1737 1.1.1.12 mrg __x.param(param_type(__t, __p)); 1738 1.1 mrg 1739 1.1 mrg __is.flags(__flags); 1740 1.1 mrg return __is; 1741 1.1 mrg } 1742 1.1 mrg 1743 1.1 mrg 1744 1.1.1.2 mrg template<typename _RealType> 1745 1.1.1.2 mrg template<typename _ForwardIterator, 1746 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1747 1.1.1.2 mrg void 1748 1.1.1.2 mrg std::exponential_distribution<_RealType>:: 1749 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1750 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1751 1.1.1.2 mrg const param_type& __p) 1752 1.1.1.2 mrg { 1753 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1754 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 1755 1.1.1.2 mrg __aurng(__urng); 1756 1.1.1.2 mrg while (__f != __t) 1757 1.1.1.2 mrg *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda(); 1758 1.1.1.2 mrg } 1759 1.1.1.2 mrg 1760 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 1761 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1762 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1763 1.1 mrg const exponential_distribution<_RealType>& __x) 1764 1.1 mrg { 1765 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1766 1.1 mrg 1767 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1768 1.1 mrg const _CharT __fill = __os.fill(); 1769 1.1 mrg const std::streamsize __precision = __os.precision(); 1770 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1771 1.1 mrg __os.fill(__os.widen(' ')); 1772 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 1773 1.1 mrg 1774 1.1 mrg __os << __x.lambda(); 1775 1.1 mrg 1776 1.1 mrg __os.flags(__flags); 1777 1.1 mrg __os.fill(__fill); 1778 1.1 mrg __os.precision(__precision); 1779 1.1 mrg return __os; 1780 1.1 mrg } 1781 1.1 mrg 1782 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 1783 1.1 mrg std::basic_istream<_CharT, _Traits>& 1784 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 1785 1.1 mrg exponential_distribution<_RealType>& __x) 1786 1.1 mrg { 1787 1.1.1.12 mrg using param_type 1788 1.1.1.12 mrg = typename exponential_distribution<_RealType>::param_type; 1789 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 1790 1.1 mrg 1791 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 1792 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 1793 1.1 mrg 1794 1.1 mrg _RealType __lambda; 1795 1.1.1.10 mrg if (__is >> __lambda) 1796 1.1.1.12 mrg __x.param(param_type(__lambda)); 1797 1.1 mrg 1798 1.1 mrg __is.flags(__flags); 1799 1.1 mrg return __is; 1800 1.1 mrg } 1801 1.1 mrg 1802 1.1 mrg 1803 1.1 mrg /** 1804 1.1 mrg * Polar method due to Marsaglia. 1805 1.1 mrg * 1806 1.1 mrg * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 1807 1.1 mrg * New York, 1986, Ch. V, Sect. 4.4. 1808 1.1 mrg */ 1809 1.1 mrg template<typename _RealType> 1810 1.1 mrg template<typename _UniformRandomNumberGenerator> 1811 1.1 mrg typename normal_distribution<_RealType>::result_type 1812 1.1 mrg normal_distribution<_RealType>:: 1813 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 1814 1.1 mrg const param_type& __param) 1815 1.1 mrg { 1816 1.1 mrg result_type __ret; 1817 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 1818 1.1 mrg __aurng(__urng); 1819 1.1 mrg 1820 1.1 mrg if (_M_saved_available) 1821 1.1 mrg { 1822 1.1 mrg _M_saved_available = false; 1823 1.1 mrg __ret = _M_saved; 1824 1.1 mrg } 1825 1.1 mrg else 1826 1.1 mrg { 1827 1.1 mrg result_type __x, __y, __r2; 1828 1.1 mrg do 1829 1.1 mrg { 1830 1.1 mrg __x = result_type(2.0) * __aurng() - 1.0; 1831 1.1 mrg __y = result_type(2.0) * __aurng() - 1.0; 1832 1.1 mrg __r2 = __x * __x + __y * __y; 1833 1.1 mrg } 1834 1.1 mrg while (__r2 > 1.0 || __r2 == 0.0); 1835 1.1 mrg 1836 1.1 mrg const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 1837 1.1 mrg _M_saved = __x * __mult; 1838 1.1 mrg _M_saved_available = true; 1839 1.1 mrg __ret = __y * __mult; 1840 1.1 mrg } 1841 1.1 mrg 1842 1.1 mrg __ret = __ret * __param.stddev() + __param.mean(); 1843 1.1 mrg return __ret; 1844 1.1 mrg } 1845 1.1 mrg 1846 1.1 mrg template<typename _RealType> 1847 1.1.1.2 mrg template<typename _ForwardIterator, 1848 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1849 1.1.1.2 mrg void 1850 1.1.1.2 mrg normal_distribution<_RealType>:: 1851 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1852 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1853 1.1.1.2 mrg const param_type& __param) 1854 1.1.1.2 mrg { 1855 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1856 1.1.1.2 mrg 1857 1.1.1.2 mrg if (__f == __t) 1858 1.1.1.2 mrg return; 1859 1.1.1.2 mrg 1860 1.1.1.2 mrg if (_M_saved_available) 1861 1.1.1.2 mrg { 1862 1.1.1.2 mrg _M_saved_available = false; 1863 1.1.1.2 mrg *__f++ = _M_saved * __param.stddev() + __param.mean(); 1864 1.1.1.2 mrg 1865 1.1.1.2 mrg if (__f == __t) 1866 1.1.1.2 mrg return; 1867 1.1.1.2 mrg } 1868 1.1.1.2 mrg 1869 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 1870 1.1.1.2 mrg __aurng(__urng); 1871 1.1.1.2 mrg 1872 1.1.1.2 mrg while (__f + 1 < __t) 1873 1.1.1.2 mrg { 1874 1.1.1.2 mrg result_type __x, __y, __r2; 1875 1.1.1.2 mrg do 1876 1.1.1.2 mrg { 1877 1.1.1.2 mrg __x = result_type(2.0) * __aurng() - 1.0; 1878 1.1.1.2 mrg __y = result_type(2.0) * __aurng() - 1.0; 1879 1.1.1.2 mrg __r2 = __x * __x + __y * __y; 1880 1.1.1.2 mrg } 1881 1.1.1.2 mrg while (__r2 > 1.0 || __r2 == 0.0); 1882 1.1.1.2 mrg 1883 1.1.1.2 mrg const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 1884 1.1.1.2 mrg *__f++ = __y * __mult * __param.stddev() + __param.mean(); 1885 1.1.1.2 mrg *__f++ = __x * __mult * __param.stddev() + __param.mean(); 1886 1.1.1.2 mrg } 1887 1.1.1.2 mrg 1888 1.1.1.2 mrg if (__f != __t) 1889 1.1.1.2 mrg { 1890 1.1.1.2 mrg result_type __x, __y, __r2; 1891 1.1.1.2 mrg do 1892 1.1.1.2 mrg { 1893 1.1.1.2 mrg __x = result_type(2.0) * __aurng() - 1.0; 1894 1.1.1.2 mrg __y = result_type(2.0) * __aurng() - 1.0; 1895 1.1.1.2 mrg __r2 = __x * __x + __y * __y; 1896 1.1.1.2 mrg } 1897 1.1.1.2 mrg while (__r2 > 1.0 || __r2 == 0.0); 1898 1.1.1.2 mrg 1899 1.1.1.2 mrg const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 1900 1.1.1.2 mrg _M_saved = __x * __mult; 1901 1.1.1.2 mrg _M_saved_available = true; 1902 1.1.1.2 mrg *__f = __y * __mult * __param.stddev() + __param.mean(); 1903 1.1.1.2 mrg } 1904 1.1.1.2 mrg } 1905 1.1.1.2 mrg 1906 1.1.1.2 mrg template<typename _RealType> 1907 1.1 mrg bool 1908 1.1 mrg operator==(const std::normal_distribution<_RealType>& __d1, 1909 1.1 mrg const std::normal_distribution<_RealType>& __d2) 1910 1.1 mrg { 1911 1.1 mrg if (__d1._M_param == __d2._M_param 1912 1.1 mrg && __d1._M_saved_available == __d2._M_saved_available) 1913 1.1.1.16 mrg return __d1._M_saved_available ? __d1._M_saved == __d2._M_saved : true; 1914 1.1 mrg else 1915 1.1 mrg return false; 1916 1.1 mrg } 1917 1.1 mrg 1918 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 1919 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1920 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1921 1.1 mrg const normal_distribution<_RealType>& __x) 1922 1.1 mrg { 1923 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1924 1.1 mrg 1925 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1926 1.1 mrg const _CharT __fill = __os.fill(); 1927 1.1 mrg const std::streamsize __precision = __os.precision(); 1928 1.1 mrg const _CharT __space = __os.widen(' '); 1929 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1930 1.1 mrg __os.fill(__space); 1931 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 1932 1.1 mrg 1933 1.1 mrg __os << __x.mean() << __space << __x.stddev() 1934 1.1 mrg << __space << __x._M_saved_available; 1935 1.1 mrg if (__x._M_saved_available) 1936 1.1 mrg __os << __space << __x._M_saved; 1937 1.1 mrg 1938 1.1 mrg __os.flags(__flags); 1939 1.1 mrg __os.fill(__fill); 1940 1.1 mrg __os.precision(__precision); 1941 1.1 mrg return __os; 1942 1.1 mrg } 1943 1.1 mrg 1944 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 1945 1.1 mrg std::basic_istream<_CharT, _Traits>& 1946 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 1947 1.1 mrg normal_distribution<_RealType>& __x) 1948 1.1 mrg { 1949 1.1.1.12 mrg using param_type = typename normal_distribution<_RealType>::param_type; 1950 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 1951 1.1 mrg 1952 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 1953 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 1954 1.1 mrg 1955 1.1 mrg double __mean, __stddev; 1956 1.1.1.10 mrg bool __saved_avail; 1957 1.1.1.10 mrg if (__is >> __mean >> __stddev >> __saved_avail) 1958 1.1.1.10 mrg { 1959 1.1.1.13 mrg if (!__saved_avail || (__is >> __x._M_saved)) 1960 1.1.1.10 mrg { 1961 1.1.1.10 mrg __x._M_saved_available = __saved_avail; 1962 1.1.1.12 mrg __x.param(param_type(__mean, __stddev)); 1963 1.1.1.10 mrg } 1964 1.1.1.10 mrg } 1965 1.1 mrg 1966 1.1 mrg __is.flags(__flags); 1967 1.1 mrg return __is; 1968 1.1 mrg } 1969 1.1 mrg 1970 1.1 mrg 1971 1.1.1.2 mrg template<typename _RealType> 1972 1.1.1.2 mrg template<typename _ForwardIterator, 1973 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 1974 1.1.1.2 mrg void 1975 1.1.1.2 mrg lognormal_distribution<_RealType>:: 1976 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1977 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 1978 1.1.1.2 mrg const param_type& __p) 1979 1.1.1.2 mrg { 1980 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 1981 1.1.1.2 mrg while (__f != __t) 1982 1.1.1.2 mrg *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m()); 1983 1.1.1.2 mrg } 1984 1.1.1.2 mrg 1985 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 1986 1.1 mrg std::basic_ostream<_CharT, _Traits>& 1987 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1988 1.1 mrg const lognormal_distribution<_RealType>& __x) 1989 1.1 mrg { 1990 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 1991 1.1 mrg 1992 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 1993 1.1 mrg const _CharT __fill = __os.fill(); 1994 1.1 mrg const std::streamsize __precision = __os.precision(); 1995 1.1 mrg const _CharT __space = __os.widen(' '); 1996 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 1997 1.1 mrg __os.fill(__space); 1998 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 1999 1.1 mrg 2000 1.1 mrg __os << __x.m() << __space << __x.s() 2001 1.1 mrg << __space << __x._M_nd; 2002 1.1 mrg 2003 1.1 mrg __os.flags(__flags); 2004 1.1 mrg __os.fill(__fill); 2005 1.1 mrg __os.precision(__precision); 2006 1.1 mrg return __os; 2007 1.1 mrg } 2008 1.1 mrg 2009 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2010 1.1 mrg std::basic_istream<_CharT, _Traits>& 2011 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2012 1.1 mrg lognormal_distribution<_RealType>& __x) 2013 1.1 mrg { 2014 1.1.1.12 mrg using param_type 2015 1.1.1.12 mrg = typename lognormal_distribution<_RealType>::param_type; 2016 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2017 1.1 mrg 2018 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2019 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2020 1.1 mrg 2021 1.1 mrg _RealType __m, __s; 2022 1.1.1.10 mrg if (__is >> __m >> __s >> __x._M_nd) 2023 1.1.1.12 mrg __x.param(param_type(__m, __s)); 2024 1.1 mrg 2025 1.1 mrg __is.flags(__flags); 2026 1.1 mrg return __is; 2027 1.1 mrg } 2028 1.1 mrg 2029 1.1.1.2 mrg template<typename _RealType> 2030 1.1.1.2 mrg template<typename _ForwardIterator, 2031 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2032 1.1.1.2 mrg void 2033 1.1.1.2 mrg std::chi_squared_distribution<_RealType>:: 2034 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2035 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng) 2036 1.1.1.2 mrg { 2037 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2038 1.1.1.2 mrg while (__f != __t) 2039 1.1.1.2 mrg *__f++ = 2 * _M_gd(__urng); 2040 1.1.1.2 mrg } 2041 1.1.1.2 mrg 2042 1.1.1.2 mrg template<typename _RealType> 2043 1.1.1.2 mrg template<typename _ForwardIterator, 2044 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2045 1.1.1.2 mrg void 2046 1.1.1.2 mrg std::chi_squared_distribution<_RealType>:: 2047 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2048 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2049 1.1.1.2 mrg const typename 2050 1.1.1.2 mrg std::gamma_distribution<result_type>::param_type& __p) 2051 1.1.1.2 mrg { 2052 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2053 1.1.1.2 mrg while (__f != __t) 2054 1.1.1.2 mrg *__f++ = 2 * _M_gd(__urng, __p); 2055 1.1.1.2 mrg } 2056 1.1 mrg 2057 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2058 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2059 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2060 1.1 mrg const chi_squared_distribution<_RealType>& __x) 2061 1.1 mrg { 2062 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2063 1.1 mrg 2064 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2065 1.1 mrg const _CharT __fill = __os.fill(); 2066 1.1 mrg const std::streamsize __precision = __os.precision(); 2067 1.1 mrg const _CharT __space = __os.widen(' '); 2068 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2069 1.1 mrg __os.fill(__space); 2070 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2071 1.1 mrg 2072 1.1 mrg __os << __x.n() << __space << __x._M_gd; 2073 1.1 mrg 2074 1.1 mrg __os.flags(__flags); 2075 1.1 mrg __os.fill(__fill); 2076 1.1 mrg __os.precision(__precision); 2077 1.1 mrg return __os; 2078 1.1 mrg } 2079 1.1 mrg 2080 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2081 1.1 mrg std::basic_istream<_CharT, _Traits>& 2082 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2083 1.1 mrg chi_squared_distribution<_RealType>& __x) 2084 1.1 mrg { 2085 1.1.1.12 mrg using param_type 2086 1.1.1.12 mrg = typename chi_squared_distribution<_RealType>::param_type; 2087 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2088 1.1 mrg 2089 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2090 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2091 1.1 mrg 2092 1.1 mrg _RealType __n; 2093 1.1.1.10 mrg if (__is >> __n >> __x._M_gd) 2094 1.1.1.12 mrg __x.param(param_type(__n)); 2095 1.1 mrg 2096 1.1 mrg __is.flags(__flags); 2097 1.1 mrg return __is; 2098 1.1 mrg } 2099 1.1 mrg 2100 1.1 mrg 2101 1.1 mrg template<typename _RealType> 2102 1.1 mrg template<typename _UniformRandomNumberGenerator> 2103 1.1 mrg typename cauchy_distribution<_RealType>::result_type 2104 1.1 mrg cauchy_distribution<_RealType>:: 2105 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 2106 1.1 mrg const param_type& __p) 2107 1.1 mrg { 2108 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2109 1.1 mrg __aurng(__urng); 2110 1.1 mrg _RealType __u; 2111 1.1 mrg do 2112 1.1 mrg __u = __aurng(); 2113 1.1 mrg while (__u == 0.5); 2114 1.1 mrg 2115 1.1 mrg const _RealType __pi = 3.1415926535897932384626433832795029L; 2116 1.1 mrg return __p.a() + __p.b() * std::tan(__pi * __u); 2117 1.1 mrg } 2118 1.1 mrg 2119 1.1.1.2 mrg template<typename _RealType> 2120 1.1.1.2 mrg template<typename _ForwardIterator, 2121 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2122 1.1.1.2 mrg void 2123 1.1.1.2 mrg cauchy_distribution<_RealType>:: 2124 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2125 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2126 1.1.1.2 mrg const param_type& __p) 2127 1.1.1.2 mrg { 2128 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2129 1.1.1.2 mrg const _RealType __pi = 3.1415926535897932384626433832795029L; 2130 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2131 1.1.1.2 mrg __aurng(__urng); 2132 1.1.1.2 mrg while (__f != __t) 2133 1.1.1.2 mrg { 2134 1.1.1.2 mrg _RealType __u; 2135 1.1.1.2 mrg do 2136 1.1.1.2 mrg __u = __aurng(); 2137 1.1.1.2 mrg while (__u == 0.5); 2138 1.1.1.2 mrg 2139 1.1.1.2 mrg *__f++ = __p.a() + __p.b() * std::tan(__pi * __u); 2140 1.1.1.2 mrg } 2141 1.1.1.2 mrg } 2142 1.1.1.2 mrg 2143 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2144 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2145 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2146 1.1 mrg const cauchy_distribution<_RealType>& __x) 2147 1.1 mrg { 2148 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2149 1.1 mrg 2150 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2151 1.1 mrg const _CharT __fill = __os.fill(); 2152 1.1 mrg const std::streamsize __precision = __os.precision(); 2153 1.1 mrg const _CharT __space = __os.widen(' '); 2154 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2155 1.1 mrg __os.fill(__space); 2156 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2157 1.1 mrg 2158 1.1 mrg __os << __x.a() << __space << __x.b(); 2159 1.1 mrg 2160 1.1 mrg __os.flags(__flags); 2161 1.1 mrg __os.fill(__fill); 2162 1.1 mrg __os.precision(__precision); 2163 1.1 mrg return __os; 2164 1.1 mrg } 2165 1.1 mrg 2166 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2167 1.1 mrg std::basic_istream<_CharT, _Traits>& 2168 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2169 1.1 mrg cauchy_distribution<_RealType>& __x) 2170 1.1 mrg { 2171 1.1.1.12 mrg using param_type = typename cauchy_distribution<_RealType>::param_type; 2172 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2173 1.1 mrg 2174 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2175 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2176 1.1 mrg 2177 1.1 mrg _RealType __a, __b; 2178 1.1.1.10 mrg if (__is >> __a >> __b) 2179 1.1.1.12 mrg __x.param(param_type(__a, __b)); 2180 1.1 mrg 2181 1.1 mrg __is.flags(__flags); 2182 1.1 mrg return __is; 2183 1.1 mrg } 2184 1.1 mrg 2185 1.1 mrg 2186 1.1.1.2 mrg template<typename _RealType> 2187 1.1.1.2 mrg template<typename _ForwardIterator, 2188 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2189 1.1.1.2 mrg void 2190 1.1.1.2 mrg std::fisher_f_distribution<_RealType>:: 2191 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2192 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng) 2193 1.1.1.2 mrg { 2194 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2195 1.1.1.2 mrg while (__f != __t) 2196 1.1.1.2 mrg *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m())); 2197 1.1.1.2 mrg } 2198 1.1.1.2 mrg 2199 1.1.1.2 mrg template<typename _RealType> 2200 1.1.1.2 mrg template<typename _ForwardIterator, 2201 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2202 1.1.1.2 mrg void 2203 1.1.1.2 mrg std::fisher_f_distribution<_RealType>:: 2204 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2205 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2206 1.1.1.2 mrg const param_type& __p) 2207 1.1.1.2 mrg { 2208 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2209 1.1.1.2 mrg typedef typename std::gamma_distribution<result_type>::param_type 2210 1.1.1.2 mrg param_type; 2211 1.1.1.2 mrg param_type __p1(__p.m() / 2); 2212 1.1.1.2 mrg param_type __p2(__p.n() / 2); 2213 1.1.1.2 mrg while (__f != __t) 2214 1.1.1.2 mrg *__f++ = ((_M_gd_x(__urng, __p1) * n()) 2215 1.1.1.2 mrg / (_M_gd_y(__urng, __p2) * m())); 2216 1.1.1.2 mrg } 2217 1.1.1.2 mrg 2218 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2219 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2220 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2221 1.1 mrg const fisher_f_distribution<_RealType>& __x) 2222 1.1 mrg { 2223 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2224 1.1 mrg 2225 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2226 1.1 mrg const _CharT __fill = __os.fill(); 2227 1.1 mrg const std::streamsize __precision = __os.precision(); 2228 1.1 mrg const _CharT __space = __os.widen(' '); 2229 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2230 1.1 mrg __os.fill(__space); 2231 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2232 1.1 mrg 2233 1.1 mrg __os << __x.m() << __space << __x.n() 2234 1.1 mrg << __space << __x._M_gd_x << __space << __x._M_gd_y; 2235 1.1 mrg 2236 1.1 mrg __os.flags(__flags); 2237 1.1 mrg __os.fill(__fill); 2238 1.1 mrg __os.precision(__precision); 2239 1.1 mrg return __os; 2240 1.1 mrg } 2241 1.1 mrg 2242 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2243 1.1 mrg std::basic_istream<_CharT, _Traits>& 2244 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2245 1.1 mrg fisher_f_distribution<_RealType>& __x) 2246 1.1 mrg { 2247 1.1.1.12 mrg using param_type 2248 1.1.1.12 mrg = typename fisher_f_distribution<_RealType>::param_type; 2249 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2250 1.1 mrg 2251 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2252 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2253 1.1 mrg 2254 1.1 mrg _RealType __m, __n; 2255 1.1.1.10 mrg if (__is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y) 2256 1.1.1.12 mrg __x.param(param_type(__m, __n)); 2257 1.1 mrg 2258 1.1 mrg __is.flags(__flags); 2259 1.1 mrg return __is; 2260 1.1 mrg } 2261 1.1 mrg 2262 1.1 mrg 2263 1.1.1.2 mrg template<typename _RealType> 2264 1.1.1.2 mrg template<typename _ForwardIterator, 2265 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2266 1.1.1.2 mrg void 2267 1.1.1.2 mrg std::student_t_distribution<_RealType>:: 2268 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2269 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng) 2270 1.1.1.2 mrg { 2271 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2272 1.1.1.2 mrg while (__f != __t) 2273 1.1.1.2 mrg *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); 2274 1.1.1.2 mrg } 2275 1.1.1.2 mrg 2276 1.1.1.2 mrg template<typename _RealType> 2277 1.1.1.2 mrg template<typename _ForwardIterator, 2278 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2279 1.1.1.2 mrg void 2280 1.1.1.2 mrg std::student_t_distribution<_RealType>:: 2281 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2282 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2283 1.1.1.2 mrg const param_type& __p) 2284 1.1.1.2 mrg { 2285 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2286 1.1.1.2 mrg typename std::gamma_distribution<result_type>::param_type 2287 1.1.1.2 mrg __p2(__p.n() / 2, 2); 2288 1.1.1.2 mrg while (__f != __t) 2289 1.1.1.2 mrg *__f++ = _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2)); 2290 1.1.1.2 mrg } 2291 1.1.1.2 mrg 2292 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2293 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2294 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2295 1.1 mrg const student_t_distribution<_RealType>& __x) 2296 1.1 mrg { 2297 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2298 1.1 mrg 2299 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2300 1.1 mrg const _CharT __fill = __os.fill(); 2301 1.1 mrg const std::streamsize __precision = __os.precision(); 2302 1.1 mrg const _CharT __space = __os.widen(' '); 2303 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2304 1.1 mrg __os.fill(__space); 2305 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2306 1.1 mrg 2307 1.1 mrg __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd; 2308 1.1 mrg 2309 1.1 mrg __os.flags(__flags); 2310 1.1 mrg __os.fill(__fill); 2311 1.1 mrg __os.precision(__precision); 2312 1.1 mrg return __os; 2313 1.1 mrg } 2314 1.1 mrg 2315 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2316 1.1 mrg std::basic_istream<_CharT, _Traits>& 2317 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2318 1.1 mrg student_t_distribution<_RealType>& __x) 2319 1.1 mrg { 2320 1.1.1.12 mrg using param_type 2321 1.1.1.12 mrg = typename student_t_distribution<_RealType>::param_type; 2322 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2323 1.1 mrg 2324 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2325 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2326 1.1 mrg 2327 1.1 mrg _RealType __n; 2328 1.1.1.10 mrg if (__is >> __n >> __x._M_nd >> __x._M_gd) 2329 1.1.1.12 mrg __x.param(param_type(__n)); 2330 1.1 mrg 2331 1.1 mrg __is.flags(__flags); 2332 1.1 mrg return __is; 2333 1.1 mrg } 2334 1.1 mrg 2335 1.1 mrg 2336 1.1 mrg template<typename _RealType> 2337 1.1 mrg void 2338 1.1 mrg gamma_distribution<_RealType>::param_type:: 2339 1.1 mrg _M_initialize() 2340 1.1 mrg { 2341 1.1 mrg _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha; 2342 1.1 mrg 2343 1.1 mrg const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0); 2344 1.1 mrg _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1); 2345 1.1 mrg } 2346 1.1 mrg 2347 1.1 mrg /** 2348 1.1 mrg * Marsaglia, G. and Tsang, W. W. 2349 1.1 mrg * "A Simple Method for Generating Gamma Variables" 2350 1.1 mrg * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000. 2351 1.1 mrg */ 2352 1.1 mrg template<typename _RealType> 2353 1.1 mrg template<typename _UniformRandomNumberGenerator> 2354 1.1 mrg typename gamma_distribution<_RealType>::result_type 2355 1.1 mrg gamma_distribution<_RealType>:: 2356 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 2357 1.1 mrg const param_type& __param) 2358 1.1 mrg { 2359 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2360 1.1 mrg __aurng(__urng); 2361 1.1 mrg 2362 1.1 mrg result_type __u, __v, __n; 2363 1.1 mrg const result_type __a1 = (__param._M_malpha 2364 1.1 mrg - _RealType(1.0) / _RealType(3.0)); 2365 1.1 mrg 2366 1.1 mrg do 2367 1.1 mrg { 2368 1.1 mrg do 2369 1.1 mrg { 2370 1.1 mrg __n = _M_nd(__urng); 2371 1.1 mrg __v = result_type(1.0) + __param._M_a2 * __n; 2372 1.1 mrg } 2373 1.1 mrg while (__v <= 0.0); 2374 1.1 mrg 2375 1.1 mrg __v = __v * __v * __v; 2376 1.1 mrg __u = __aurng(); 2377 1.1 mrg } 2378 1.1.1.6 mrg while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n 2379 1.1 mrg && (std::log(__u) > (0.5 * __n * __n + __a1 2380 1.1 mrg * (1.0 - __v + std::log(__v))))); 2381 1.1 mrg 2382 1.1 mrg if (__param.alpha() == __param._M_malpha) 2383 1.1 mrg return __a1 * __v * __param.beta(); 2384 1.1 mrg else 2385 1.1 mrg { 2386 1.1 mrg do 2387 1.1 mrg __u = __aurng(); 2388 1.1 mrg while (__u == 0.0); 2389 1.1 mrg 2390 1.1 mrg return (std::pow(__u, result_type(1.0) / __param.alpha()) 2391 1.1 mrg * __a1 * __v * __param.beta()); 2392 1.1 mrg } 2393 1.1 mrg } 2394 1.1 mrg 2395 1.1.1.2 mrg template<typename _RealType> 2396 1.1.1.2 mrg template<typename _ForwardIterator, 2397 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2398 1.1.1.2 mrg void 2399 1.1.1.2 mrg gamma_distribution<_RealType>:: 2400 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2401 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2402 1.1.1.2 mrg const param_type& __param) 2403 1.1.1.2 mrg { 2404 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2405 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2406 1.1.1.2 mrg __aurng(__urng); 2407 1.1.1.2 mrg 2408 1.1.1.2 mrg result_type __u, __v, __n; 2409 1.1.1.2 mrg const result_type __a1 = (__param._M_malpha 2410 1.1.1.2 mrg - _RealType(1.0) / _RealType(3.0)); 2411 1.1.1.2 mrg 2412 1.1.1.2 mrg if (__param.alpha() == __param._M_malpha) 2413 1.1.1.2 mrg while (__f != __t) 2414 1.1.1.2 mrg { 2415 1.1.1.2 mrg do 2416 1.1.1.2 mrg { 2417 1.1.1.2 mrg do 2418 1.1.1.2 mrg { 2419 1.1.1.2 mrg __n = _M_nd(__urng); 2420 1.1.1.2 mrg __v = result_type(1.0) + __param._M_a2 * __n; 2421 1.1.1.2 mrg } 2422 1.1.1.2 mrg while (__v <= 0.0); 2423 1.1.1.2 mrg 2424 1.1.1.2 mrg __v = __v * __v * __v; 2425 1.1.1.2 mrg __u = __aurng(); 2426 1.1.1.2 mrg } 2427 1.1.1.6 mrg while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n 2428 1.1.1.2 mrg && (std::log(__u) > (0.5 * __n * __n + __a1 2429 1.1.1.2 mrg * (1.0 - __v + std::log(__v))))); 2430 1.1.1.2 mrg 2431 1.1.1.2 mrg *__f++ = __a1 * __v * __param.beta(); 2432 1.1.1.2 mrg } 2433 1.1.1.2 mrg else 2434 1.1.1.2 mrg while (__f != __t) 2435 1.1.1.2 mrg { 2436 1.1.1.2 mrg do 2437 1.1.1.2 mrg { 2438 1.1.1.2 mrg do 2439 1.1.1.2 mrg { 2440 1.1.1.2 mrg __n = _M_nd(__urng); 2441 1.1.1.2 mrg __v = result_type(1.0) + __param._M_a2 * __n; 2442 1.1.1.2 mrg } 2443 1.1.1.2 mrg while (__v <= 0.0); 2444 1.1.1.2 mrg 2445 1.1.1.2 mrg __v = __v * __v * __v; 2446 1.1.1.2 mrg __u = __aurng(); 2447 1.1.1.2 mrg } 2448 1.1.1.6 mrg while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n 2449 1.1.1.2 mrg && (std::log(__u) > (0.5 * __n * __n + __a1 2450 1.1.1.2 mrg * (1.0 - __v + std::log(__v))))); 2451 1.1.1.2 mrg 2452 1.1.1.2 mrg do 2453 1.1.1.2 mrg __u = __aurng(); 2454 1.1.1.2 mrg while (__u == 0.0); 2455 1.1.1.2 mrg 2456 1.1.1.2 mrg *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha()) 2457 1.1.1.2 mrg * __a1 * __v * __param.beta()); 2458 1.1.1.2 mrg } 2459 1.1.1.2 mrg } 2460 1.1.1.2 mrg 2461 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2462 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2463 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2464 1.1 mrg const gamma_distribution<_RealType>& __x) 2465 1.1 mrg { 2466 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2467 1.1 mrg 2468 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2469 1.1 mrg const _CharT __fill = __os.fill(); 2470 1.1 mrg const std::streamsize __precision = __os.precision(); 2471 1.1 mrg const _CharT __space = __os.widen(' '); 2472 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2473 1.1 mrg __os.fill(__space); 2474 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2475 1.1 mrg 2476 1.1 mrg __os << __x.alpha() << __space << __x.beta() 2477 1.1 mrg << __space << __x._M_nd; 2478 1.1 mrg 2479 1.1 mrg __os.flags(__flags); 2480 1.1 mrg __os.fill(__fill); 2481 1.1 mrg __os.precision(__precision); 2482 1.1 mrg return __os; 2483 1.1 mrg } 2484 1.1 mrg 2485 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2486 1.1 mrg std::basic_istream<_CharT, _Traits>& 2487 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2488 1.1 mrg gamma_distribution<_RealType>& __x) 2489 1.1 mrg { 2490 1.1.1.12 mrg using param_type = typename gamma_distribution<_RealType>::param_type; 2491 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2492 1.1 mrg 2493 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2494 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2495 1.1 mrg 2496 1.1 mrg _RealType __alpha_val, __beta_val; 2497 1.1.1.10 mrg if (__is >> __alpha_val >> __beta_val >> __x._M_nd) 2498 1.1.1.12 mrg __x.param(param_type(__alpha_val, __beta_val)); 2499 1.1 mrg 2500 1.1 mrg __is.flags(__flags); 2501 1.1 mrg return __is; 2502 1.1 mrg } 2503 1.1 mrg 2504 1.1 mrg 2505 1.1 mrg template<typename _RealType> 2506 1.1 mrg template<typename _UniformRandomNumberGenerator> 2507 1.1 mrg typename weibull_distribution<_RealType>::result_type 2508 1.1 mrg weibull_distribution<_RealType>:: 2509 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 2510 1.1 mrg const param_type& __p) 2511 1.1 mrg { 2512 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2513 1.1 mrg __aurng(__urng); 2514 1.1.1.2 mrg return __p.b() * std::pow(-std::log(result_type(1) - __aurng()), 2515 1.1 mrg result_type(1) / __p.a()); 2516 1.1 mrg } 2517 1.1 mrg 2518 1.1.1.2 mrg template<typename _RealType> 2519 1.1.1.2 mrg template<typename _ForwardIterator, 2520 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2521 1.1.1.2 mrg void 2522 1.1.1.2 mrg weibull_distribution<_RealType>:: 2523 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2524 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2525 1.1.1.2 mrg const param_type& __p) 2526 1.1.1.2 mrg { 2527 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2528 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2529 1.1.1.2 mrg __aurng(__urng); 2530 1.1.1.2 mrg auto __inv_a = result_type(1) / __p.a(); 2531 1.1.1.2 mrg 2532 1.1.1.2 mrg while (__f != __t) 2533 1.1.1.2 mrg *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()), 2534 1.1.1.2 mrg __inv_a); 2535 1.1.1.2 mrg } 2536 1.1.1.2 mrg 2537 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2538 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2539 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2540 1.1 mrg const weibull_distribution<_RealType>& __x) 2541 1.1 mrg { 2542 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2543 1.1 mrg 2544 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2545 1.1 mrg const _CharT __fill = __os.fill(); 2546 1.1 mrg const std::streamsize __precision = __os.precision(); 2547 1.1 mrg const _CharT __space = __os.widen(' '); 2548 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2549 1.1 mrg __os.fill(__space); 2550 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2551 1.1 mrg 2552 1.1 mrg __os << __x.a() << __space << __x.b(); 2553 1.1 mrg 2554 1.1 mrg __os.flags(__flags); 2555 1.1 mrg __os.fill(__fill); 2556 1.1 mrg __os.precision(__precision); 2557 1.1 mrg return __os; 2558 1.1 mrg } 2559 1.1 mrg 2560 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2561 1.1 mrg std::basic_istream<_CharT, _Traits>& 2562 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2563 1.1 mrg weibull_distribution<_RealType>& __x) 2564 1.1 mrg { 2565 1.1.1.12 mrg using param_type = typename weibull_distribution<_RealType>::param_type; 2566 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2567 1.1 mrg 2568 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2569 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2570 1.1 mrg 2571 1.1 mrg _RealType __a, __b; 2572 1.1.1.10 mrg if (__is >> __a >> __b) 2573 1.1.1.12 mrg __x.param(param_type(__a, __b)); 2574 1.1 mrg 2575 1.1 mrg __is.flags(__flags); 2576 1.1 mrg return __is; 2577 1.1 mrg } 2578 1.1 mrg 2579 1.1 mrg 2580 1.1 mrg template<typename _RealType> 2581 1.1 mrg template<typename _UniformRandomNumberGenerator> 2582 1.1 mrg typename extreme_value_distribution<_RealType>::result_type 2583 1.1 mrg extreme_value_distribution<_RealType>:: 2584 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 2585 1.1 mrg const param_type& __p) 2586 1.1 mrg { 2587 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2588 1.1 mrg __aurng(__urng); 2589 1.1.1.2 mrg return __p.a() - __p.b() * std::log(-std::log(result_type(1) 2590 1.1.1.2 mrg - __aurng())); 2591 1.1.1.2 mrg } 2592 1.1.1.2 mrg 2593 1.1.1.2 mrg template<typename _RealType> 2594 1.1.1.2 mrg template<typename _ForwardIterator, 2595 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2596 1.1.1.2 mrg void 2597 1.1.1.2 mrg extreme_value_distribution<_RealType>:: 2598 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2599 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2600 1.1.1.2 mrg const param_type& __p) 2601 1.1.1.2 mrg { 2602 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2603 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2604 1.1.1.2 mrg __aurng(__urng); 2605 1.1.1.2 mrg 2606 1.1.1.2 mrg while (__f != __t) 2607 1.1.1.2 mrg *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1) 2608 1.1.1.2 mrg - __aurng())); 2609 1.1 mrg } 2610 1.1 mrg 2611 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2612 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2613 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2614 1.1 mrg const extreme_value_distribution<_RealType>& __x) 2615 1.1 mrg { 2616 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2617 1.1 mrg 2618 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2619 1.1 mrg const _CharT __fill = __os.fill(); 2620 1.1 mrg const std::streamsize __precision = __os.precision(); 2621 1.1 mrg const _CharT __space = __os.widen(' '); 2622 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2623 1.1 mrg __os.fill(__space); 2624 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2625 1.1 mrg 2626 1.1 mrg __os << __x.a() << __space << __x.b(); 2627 1.1 mrg 2628 1.1 mrg __os.flags(__flags); 2629 1.1 mrg __os.fill(__fill); 2630 1.1 mrg __os.precision(__precision); 2631 1.1 mrg return __os; 2632 1.1 mrg } 2633 1.1 mrg 2634 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2635 1.1 mrg std::basic_istream<_CharT, _Traits>& 2636 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2637 1.1 mrg extreme_value_distribution<_RealType>& __x) 2638 1.1 mrg { 2639 1.1.1.12 mrg using param_type 2640 1.1.1.12 mrg = typename extreme_value_distribution<_RealType>::param_type; 2641 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2642 1.1 mrg 2643 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2644 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2645 1.1 mrg 2646 1.1 mrg _RealType __a, __b; 2647 1.1.1.10 mrg if (__is >> __a >> __b) 2648 1.1.1.12 mrg __x.param(param_type(__a, __b)); 2649 1.1 mrg 2650 1.1 mrg __is.flags(__flags); 2651 1.1 mrg return __is; 2652 1.1 mrg } 2653 1.1 mrg 2654 1.1 mrg 2655 1.1 mrg template<typename _IntType> 2656 1.1 mrg void 2657 1.1 mrg discrete_distribution<_IntType>::param_type:: 2658 1.1 mrg _M_initialize() 2659 1.1 mrg { 2660 1.1 mrg if (_M_prob.size() < 2) 2661 1.1 mrg { 2662 1.1 mrg _M_prob.clear(); 2663 1.1 mrg return; 2664 1.1 mrg } 2665 1.1 mrg 2666 1.1 mrg const double __sum = std::accumulate(_M_prob.begin(), 2667 1.1 mrg _M_prob.end(), 0.0); 2668 1.1.1.12 mrg __glibcxx_assert(__sum > 0); 2669 1.1 mrg // Now normalize the probabilites. 2670 1.1.1.2 mrg __detail::__normalize(_M_prob.begin(), _M_prob.end(), _M_prob.begin(), 2671 1.1.1.2 mrg __sum); 2672 1.1 mrg // Accumulate partial sums. 2673 1.1 mrg _M_cp.reserve(_M_prob.size()); 2674 1.1 mrg std::partial_sum(_M_prob.begin(), _M_prob.end(), 2675 1.1 mrg std::back_inserter(_M_cp)); 2676 1.1 mrg // Make sure the last cumulative probability is one. 2677 1.1 mrg _M_cp[_M_cp.size() - 1] = 1.0; 2678 1.1 mrg } 2679 1.1 mrg 2680 1.1 mrg template<typename _IntType> 2681 1.1 mrg template<typename _Func> 2682 1.1 mrg discrete_distribution<_IntType>::param_type:: 2683 1.1 mrg param_type(size_t __nw, double __xmin, double __xmax, _Func __fw) 2684 1.1 mrg : _M_prob(), _M_cp() 2685 1.1 mrg { 2686 1.1 mrg const size_t __n = __nw == 0 ? 1 : __nw; 2687 1.1 mrg const double __delta = (__xmax - __xmin) / __n; 2688 1.1 mrg 2689 1.1 mrg _M_prob.reserve(__n); 2690 1.1 mrg for (size_t __k = 0; __k < __nw; ++__k) 2691 1.1 mrg _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta)); 2692 1.1 mrg 2693 1.1 mrg _M_initialize(); 2694 1.1 mrg } 2695 1.1 mrg 2696 1.1 mrg template<typename _IntType> 2697 1.1 mrg template<typename _UniformRandomNumberGenerator> 2698 1.1 mrg typename discrete_distribution<_IntType>::result_type 2699 1.1 mrg discrete_distribution<_IntType>:: 2700 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 2701 1.1 mrg const param_type& __param) 2702 1.1 mrg { 2703 1.1.1.2 mrg if (__param._M_cp.empty()) 2704 1.1.1.2 mrg return result_type(0); 2705 1.1.1.2 mrg 2706 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 2707 1.1 mrg __aurng(__urng); 2708 1.1 mrg 2709 1.1 mrg const double __p = __aurng(); 2710 1.1 mrg auto __pos = std::lower_bound(__param._M_cp.begin(), 2711 1.1 mrg __param._M_cp.end(), __p); 2712 1.1 mrg 2713 1.1 mrg return __pos - __param._M_cp.begin(); 2714 1.1 mrg } 2715 1.1 mrg 2716 1.1.1.2 mrg template<typename _IntType> 2717 1.1.1.2 mrg template<typename _ForwardIterator, 2718 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2719 1.1.1.2 mrg void 2720 1.1.1.2 mrg discrete_distribution<_IntType>:: 2721 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2722 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2723 1.1.1.2 mrg const param_type& __param) 2724 1.1.1.2 mrg { 2725 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2726 1.1.1.2 mrg 2727 1.1.1.2 mrg if (__param._M_cp.empty()) 2728 1.1.1.2 mrg { 2729 1.1.1.2 mrg while (__f != __t) 2730 1.1.1.2 mrg *__f++ = result_type(0); 2731 1.1.1.2 mrg return; 2732 1.1.1.2 mrg } 2733 1.1.1.2 mrg 2734 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 2735 1.1.1.2 mrg __aurng(__urng); 2736 1.1.1.2 mrg 2737 1.1.1.2 mrg while (__f != __t) 2738 1.1.1.2 mrg { 2739 1.1.1.2 mrg const double __p = __aurng(); 2740 1.1.1.2 mrg auto __pos = std::lower_bound(__param._M_cp.begin(), 2741 1.1.1.2 mrg __param._M_cp.end(), __p); 2742 1.1.1.2 mrg 2743 1.1.1.2 mrg *__f++ = __pos - __param._M_cp.begin(); 2744 1.1.1.2 mrg } 2745 1.1.1.2 mrg } 2746 1.1.1.2 mrg 2747 1.1 mrg template<typename _IntType, typename _CharT, typename _Traits> 2748 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2749 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2750 1.1 mrg const discrete_distribution<_IntType>& __x) 2751 1.1 mrg { 2752 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2753 1.1 mrg 2754 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2755 1.1 mrg const _CharT __fill = __os.fill(); 2756 1.1 mrg const std::streamsize __precision = __os.precision(); 2757 1.1 mrg const _CharT __space = __os.widen(' '); 2758 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2759 1.1 mrg __os.fill(__space); 2760 1.1 mrg __os.precision(std::numeric_limits<double>::max_digits10); 2761 1.1 mrg 2762 1.1 mrg std::vector<double> __prob = __x.probabilities(); 2763 1.1 mrg __os << __prob.size(); 2764 1.1 mrg for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit) 2765 1.1 mrg __os << __space << *__dit; 2766 1.1 mrg 2767 1.1 mrg __os.flags(__flags); 2768 1.1 mrg __os.fill(__fill); 2769 1.1 mrg __os.precision(__precision); 2770 1.1 mrg return __os; 2771 1.1 mrg } 2772 1.1 mrg 2773 1.1.1.10 mrg namespace __detail 2774 1.1.1.10 mrg { 2775 1.1.1.10 mrg template<typename _ValT, typename _CharT, typename _Traits> 2776 1.1.1.10 mrg basic_istream<_CharT, _Traits>& 2777 1.1.1.10 mrg __extract_params(basic_istream<_CharT, _Traits>& __is, 2778 1.1.1.10 mrg vector<_ValT>& __vals, size_t __n) 2779 1.1.1.10 mrg { 2780 1.1.1.10 mrg __vals.reserve(__n); 2781 1.1.1.10 mrg while (__n--) 2782 1.1.1.10 mrg { 2783 1.1.1.10 mrg _ValT __val; 2784 1.1.1.10 mrg if (__is >> __val) 2785 1.1.1.10 mrg __vals.push_back(__val); 2786 1.1.1.10 mrg else 2787 1.1.1.10 mrg break; 2788 1.1.1.10 mrg } 2789 1.1.1.10 mrg return __is; 2790 1.1.1.10 mrg } 2791 1.1.1.10 mrg } // namespace __detail 2792 1.1.1.10 mrg 2793 1.1 mrg template<typename _IntType, typename _CharT, typename _Traits> 2794 1.1 mrg std::basic_istream<_CharT, _Traits>& 2795 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 2796 1.1 mrg discrete_distribution<_IntType>& __x) 2797 1.1 mrg { 2798 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 2799 1.1 mrg 2800 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 2801 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 2802 1.1 mrg 2803 1.1 mrg size_t __n; 2804 1.1.1.10 mrg if (__is >> __n) 2805 1.1 mrg { 2806 1.1.1.10 mrg std::vector<double> __prob_vec; 2807 1.1.1.10 mrg if (__detail::__extract_params(__is, __prob_vec, __n)) 2808 1.1.1.10 mrg __x.param({__prob_vec.begin(), __prob_vec.end()}); 2809 1.1 mrg } 2810 1.1 mrg 2811 1.1 mrg __is.flags(__flags); 2812 1.1 mrg return __is; 2813 1.1 mrg } 2814 1.1 mrg 2815 1.1 mrg 2816 1.1 mrg template<typename _RealType> 2817 1.1 mrg void 2818 1.1 mrg piecewise_constant_distribution<_RealType>::param_type:: 2819 1.1 mrg _M_initialize() 2820 1.1 mrg { 2821 1.1.1.2 mrg if (_M_int.size() < 2 2822 1.1.1.2 mrg || (_M_int.size() == 2 2823 1.1.1.2 mrg && _M_int[0] == _RealType(0) 2824 1.1.1.2 mrg && _M_int[1] == _RealType(1))) 2825 1.1 mrg { 2826 1.1 mrg _M_int.clear(); 2827 1.1 mrg _M_den.clear(); 2828 1.1 mrg return; 2829 1.1 mrg } 2830 1.1 mrg 2831 1.1 mrg const double __sum = std::accumulate(_M_den.begin(), 2832 1.1 mrg _M_den.end(), 0.0); 2833 1.1.1.12 mrg __glibcxx_assert(__sum > 0); 2834 1.1 mrg 2835 1.1.1.2 mrg __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(), 2836 1.1.1.2 mrg __sum); 2837 1.1 mrg 2838 1.1 mrg _M_cp.reserve(_M_den.size()); 2839 1.1 mrg std::partial_sum(_M_den.begin(), _M_den.end(), 2840 1.1 mrg std::back_inserter(_M_cp)); 2841 1.1 mrg 2842 1.1 mrg // Make sure the last cumulative probability is one. 2843 1.1 mrg _M_cp[_M_cp.size() - 1] = 1.0; 2844 1.1 mrg 2845 1.1 mrg for (size_t __k = 0; __k < _M_den.size(); ++__k) 2846 1.1 mrg _M_den[__k] /= _M_int[__k + 1] - _M_int[__k]; 2847 1.1 mrg } 2848 1.1 mrg 2849 1.1 mrg template<typename _RealType> 2850 1.1 mrg template<typename _InputIteratorB, typename _InputIteratorW> 2851 1.1 mrg piecewise_constant_distribution<_RealType>::param_type:: 2852 1.1 mrg param_type(_InputIteratorB __bbegin, 2853 1.1 mrg _InputIteratorB __bend, 2854 1.1 mrg _InputIteratorW __wbegin) 2855 1.1 mrg : _M_int(), _M_den(), _M_cp() 2856 1.1 mrg { 2857 1.1 mrg if (__bbegin != __bend) 2858 1.1 mrg { 2859 1.1 mrg for (;;) 2860 1.1 mrg { 2861 1.1 mrg _M_int.push_back(*__bbegin); 2862 1.1 mrg ++__bbegin; 2863 1.1 mrg if (__bbegin == __bend) 2864 1.1 mrg break; 2865 1.1 mrg 2866 1.1 mrg _M_den.push_back(*__wbegin); 2867 1.1 mrg ++__wbegin; 2868 1.1 mrg } 2869 1.1 mrg } 2870 1.1 mrg 2871 1.1 mrg _M_initialize(); 2872 1.1 mrg } 2873 1.1 mrg 2874 1.1 mrg template<typename _RealType> 2875 1.1 mrg template<typename _Func> 2876 1.1 mrg piecewise_constant_distribution<_RealType>::param_type:: 2877 1.1 mrg param_type(initializer_list<_RealType> __bl, _Func __fw) 2878 1.1 mrg : _M_int(), _M_den(), _M_cp() 2879 1.1 mrg { 2880 1.1 mrg _M_int.reserve(__bl.size()); 2881 1.1 mrg for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) 2882 1.1 mrg _M_int.push_back(*__biter); 2883 1.1 mrg 2884 1.1 mrg _M_den.reserve(_M_int.size() - 1); 2885 1.1 mrg for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) 2886 1.1 mrg _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k]))); 2887 1.1 mrg 2888 1.1 mrg _M_initialize(); 2889 1.1 mrg } 2890 1.1 mrg 2891 1.1 mrg template<typename _RealType> 2892 1.1 mrg template<typename _Func> 2893 1.1 mrg piecewise_constant_distribution<_RealType>::param_type:: 2894 1.1 mrg param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) 2895 1.1 mrg : _M_int(), _M_den(), _M_cp() 2896 1.1 mrg { 2897 1.1 mrg const size_t __n = __nw == 0 ? 1 : __nw; 2898 1.1 mrg const _RealType __delta = (__xmax - __xmin) / __n; 2899 1.1 mrg 2900 1.1 mrg _M_int.reserve(__n + 1); 2901 1.1 mrg for (size_t __k = 0; __k <= __nw; ++__k) 2902 1.1 mrg _M_int.push_back(__xmin + __k * __delta); 2903 1.1 mrg 2904 1.1 mrg _M_den.reserve(__n); 2905 1.1 mrg for (size_t __k = 0; __k < __nw; ++__k) 2906 1.1 mrg _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta)); 2907 1.1 mrg 2908 1.1 mrg _M_initialize(); 2909 1.1 mrg } 2910 1.1 mrg 2911 1.1 mrg template<typename _RealType> 2912 1.1 mrg template<typename _UniformRandomNumberGenerator> 2913 1.1 mrg typename piecewise_constant_distribution<_RealType>::result_type 2914 1.1 mrg piecewise_constant_distribution<_RealType>:: 2915 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 2916 1.1 mrg const param_type& __param) 2917 1.1 mrg { 2918 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 2919 1.1 mrg __aurng(__urng); 2920 1.1 mrg 2921 1.1 mrg const double __p = __aurng(); 2922 1.1.1.2 mrg if (__param._M_cp.empty()) 2923 1.1.1.2 mrg return __p; 2924 1.1.1.2 mrg 2925 1.1 mrg auto __pos = std::lower_bound(__param._M_cp.begin(), 2926 1.1 mrg __param._M_cp.end(), __p); 2927 1.1 mrg const size_t __i = __pos - __param._M_cp.begin(); 2928 1.1 mrg 2929 1.1 mrg const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 2930 1.1 mrg 2931 1.1 mrg return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i]; 2932 1.1 mrg } 2933 1.1 mrg 2934 1.1.1.2 mrg template<typename _RealType> 2935 1.1.1.2 mrg template<typename _ForwardIterator, 2936 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 2937 1.1.1.2 mrg void 2938 1.1.1.2 mrg piecewise_constant_distribution<_RealType>:: 2939 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2940 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 2941 1.1.1.2 mrg const param_type& __param) 2942 1.1.1.2 mrg { 2943 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 2944 1.1.1.2 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 2945 1.1.1.2 mrg __aurng(__urng); 2946 1.1.1.2 mrg 2947 1.1.1.2 mrg if (__param._M_cp.empty()) 2948 1.1.1.2 mrg { 2949 1.1.1.2 mrg while (__f != __t) 2950 1.1.1.2 mrg *__f++ = __aurng(); 2951 1.1.1.2 mrg return; 2952 1.1.1.2 mrg } 2953 1.1.1.2 mrg 2954 1.1.1.2 mrg while (__f != __t) 2955 1.1.1.2 mrg { 2956 1.1.1.2 mrg const double __p = __aurng(); 2957 1.1.1.2 mrg 2958 1.1.1.2 mrg auto __pos = std::lower_bound(__param._M_cp.begin(), 2959 1.1.1.2 mrg __param._M_cp.end(), __p); 2960 1.1.1.2 mrg const size_t __i = __pos - __param._M_cp.begin(); 2961 1.1.1.2 mrg 2962 1.1.1.2 mrg const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 2963 1.1.1.2 mrg 2964 1.1.1.2 mrg *__f++ = (__param._M_int[__i] 2965 1.1.1.2 mrg + (__p - __pref) / __param._M_den[__i]); 2966 1.1.1.2 mrg } 2967 1.1.1.2 mrg } 2968 1.1.1.2 mrg 2969 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 2970 1.1 mrg std::basic_ostream<_CharT, _Traits>& 2971 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2972 1.1 mrg const piecewise_constant_distribution<_RealType>& __x) 2973 1.1 mrg { 2974 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 2975 1.1 mrg 2976 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 2977 1.1 mrg const _CharT __fill = __os.fill(); 2978 1.1 mrg const std::streamsize __precision = __os.precision(); 2979 1.1 mrg const _CharT __space = __os.widen(' '); 2980 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 2981 1.1 mrg __os.fill(__space); 2982 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 2983 1.1 mrg 2984 1.1 mrg std::vector<_RealType> __int = __x.intervals(); 2985 1.1 mrg __os << __int.size() - 1; 2986 1.1 mrg 2987 1.1 mrg for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) 2988 1.1 mrg __os << __space << *__xit; 2989 1.1 mrg 2990 1.1 mrg std::vector<double> __den = __x.densities(); 2991 1.1 mrg for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) 2992 1.1 mrg __os << __space << *__dit; 2993 1.1 mrg 2994 1.1 mrg __os.flags(__flags); 2995 1.1 mrg __os.fill(__fill); 2996 1.1 mrg __os.precision(__precision); 2997 1.1 mrg return __os; 2998 1.1 mrg } 2999 1.1 mrg 3000 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 3001 1.1 mrg std::basic_istream<_CharT, _Traits>& 3002 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 3003 1.1 mrg piecewise_constant_distribution<_RealType>& __x) 3004 1.1 mrg { 3005 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 3006 1.1 mrg 3007 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 3008 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 3009 1.1 mrg 3010 1.1 mrg size_t __n; 3011 1.1.1.10 mrg if (__is >> __n) 3012 1.1.1.9 mrg { 3013 1.1.1.10 mrg std::vector<_RealType> __int_vec; 3014 1.1.1.10 mrg if (__detail::__extract_params(__is, __int_vec, __n + 1)) 3015 1.1.1.10 mrg { 3016 1.1.1.10 mrg std::vector<double> __den_vec; 3017 1.1.1.10 mrg if (__detail::__extract_params(__is, __den_vec, __n)) 3018 1.1.1.10 mrg { 3019 1.1.1.10 mrg __x.param({ __int_vec.begin(), __int_vec.end(), 3020 1.1.1.10 mrg __den_vec.begin() }); 3021 1.1.1.10 mrg } 3022 1.1.1.10 mrg } 3023 1.1.1.9 mrg } 3024 1.1.1.9 mrg 3025 1.1 mrg __is.flags(__flags); 3026 1.1 mrg return __is; 3027 1.1 mrg } 3028 1.1 mrg 3029 1.1 mrg 3030 1.1 mrg template<typename _RealType> 3031 1.1 mrg void 3032 1.1 mrg piecewise_linear_distribution<_RealType>::param_type:: 3033 1.1 mrg _M_initialize() 3034 1.1 mrg { 3035 1.1.1.2 mrg if (_M_int.size() < 2 3036 1.1.1.2 mrg || (_M_int.size() == 2 3037 1.1.1.2 mrg && _M_int[0] == _RealType(0) 3038 1.1.1.2 mrg && _M_int[1] == _RealType(1) 3039 1.1.1.2 mrg && _M_den[0] == _M_den[1])) 3040 1.1 mrg { 3041 1.1 mrg _M_int.clear(); 3042 1.1 mrg _M_den.clear(); 3043 1.1 mrg return; 3044 1.1 mrg } 3045 1.1 mrg 3046 1.1 mrg double __sum = 0.0; 3047 1.1 mrg _M_cp.reserve(_M_int.size() - 1); 3048 1.1 mrg _M_m.reserve(_M_int.size() - 1); 3049 1.1 mrg for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) 3050 1.1 mrg { 3051 1.1 mrg const _RealType __delta = _M_int[__k + 1] - _M_int[__k]; 3052 1.1 mrg __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta; 3053 1.1 mrg _M_cp.push_back(__sum); 3054 1.1 mrg _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta); 3055 1.1 mrg } 3056 1.1.1.12 mrg __glibcxx_assert(__sum > 0); 3057 1.1 mrg 3058 1.1 mrg // Now normalize the densities... 3059 1.1.1.2 mrg __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(), 3060 1.1.1.2 mrg __sum); 3061 1.1 mrg // ... and partial sums... 3062 1.1.1.2 mrg __detail::__normalize(_M_cp.begin(), _M_cp.end(), _M_cp.begin(), __sum); 3063 1.1 mrg // ... and slopes. 3064 1.1.1.2 mrg __detail::__normalize(_M_m.begin(), _M_m.end(), _M_m.begin(), __sum); 3065 1.1.1.2 mrg 3066 1.1 mrg // Make sure the last cumulative probablility is one. 3067 1.1 mrg _M_cp[_M_cp.size() - 1] = 1.0; 3068 1.1 mrg } 3069 1.1 mrg 3070 1.1 mrg template<typename _RealType> 3071 1.1 mrg template<typename _InputIteratorB, typename _InputIteratorW> 3072 1.1 mrg piecewise_linear_distribution<_RealType>::param_type:: 3073 1.1 mrg param_type(_InputIteratorB __bbegin, 3074 1.1 mrg _InputIteratorB __bend, 3075 1.1 mrg _InputIteratorW __wbegin) 3076 1.1 mrg : _M_int(), _M_den(), _M_cp(), _M_m() 3077 1.1 mrg { 3078 1.1 mrg for (; __bbegin != __bend; ++__bbegin, ++__wbegin) 3079 1.1 mrg { 3080 1.1 mrg _M_int.push_back(*__bbegin); 3081 1.1 mrg _M_den.push_back(*__wbegin); 3082 1.1 mrg } 3083 1.1 mrg 3084 1.1 mrg _M_initialize(); 3085 1.1 mrg } 3086 1.1 mrg 3087 1.1 mrg template<typename _RealType> 3088 1.1 mrg template<typename _Func> 3089 1.1 mrg piecewise_linear_distribution<_RealType>::param_type:: 3090 1.1 mrg param_type(initializer_list<_RealType> __bl, _Func __fw) 3091 1.1 mrg : _M_int(), _M_den(), _M_cp(), _M_m() 3092 1.1 mrg { 3093 1.1 mrg _M_int.reserve(__bl.size()); 3094 1.1 mrg _M_den.reserve(__bl.size()); 3095 1.1 mrg for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) 3096 1.1 mrg { 3097 1.1 mrg _M_int.push_back(*__biter); 3098 1.1 mrg _M_den.push_back(__fw(*__biter)); 3099 1.1 mrg } 3100 1.1 mrg 3101 1.1 mrg _M_initialize(); 3102 1.1 mrg } 3103 1.1 mrg 3104 1.1 mrg template<typename _RealType> 3105 1.1 mrg template<typename _Func> 3106 1.1 mrg piecewise_linear_distribution<_RealType>::param_type:: 3107 1.1 mrg param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) 3108 1.1 mrg : _M_int(), _M_den(), _M_cp(), _M_m() 3109 1.1 mrg { 3110 1.1 mrg const size_t __n = __nw == 0 ? 1 : __nw; 3111 1.1 mrg const _RealType __delta = (__xmax - __xmin) / __n; 3112 1.1 mrg 3113 1.1 mrg _M_int.reserve(__n + 1); 3114 1.1 mrg _M_den.reserve(__n + 1); 3115 1.1 mrg for (size_t __k = 0; __k <= __nw; ++__k) 3116 1.1 mrg { 3117 1.1 mrg _M_int.push_back(__xmin + __k * __delta); 3118 1.1 mrg _M_den.push_back(__fw(_M_int[__k] + __delta)); 3119 1.1 mrg } 3120 1.1 mrg 3121 1.1 mrg _M_initialize(); 3122 1.1 mrg } 3123 1.1 mrg 3124 1.1 mrg template<typename _RealType> 3125 1.1 mrg template<typename _UniformRandomNumberGenerator> 3126 1.1 mrg typename piecewise_linear_distribution<_RealType>::result_type 3127 1.1 mrg piecewise_linear_distribution<_RealType>:: 3128 1.1 mrg operator()(_UniformRandomNumberGenerator& __urng, 3129 1.1 mrg const param_type& __param) 3130 1.1 mrg { 3131 1.1 mrg __detail::_Adaptor<_UniformRandomNumberGenerator, double> 3132 1.1 mrg __aurng(__urng); 3133 1.1 mrg 3134 1.1 mrg const double __p = __aurng(); 3135 1.1.1.2 mrg if (__param._M_cp.empty()) 3136 1.1 mrg return __p; 3137 1.1 mrg 3138 1.1 mrg auto __pos = std::lower_bound(__param._M_cp.begin(), 3139 1.1 mrg __param._M_cp.end(), __p); 3140 1.1 mrg const size_t __i = __pos - __param._M_cp.begin(); 3141 1.1 mrg 3142 1.1 mrg const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 3143 1.1 mrg 3144 1.1 mrg const double __a = 0.5 * __param._M_m[__i]; 3145 1.1 mrg const double __b = __param._M_den[__i]; 3146 1.1 mrg const double __cm = __p - __pref; 3147 1.1 mrg 3148 1.1 mrg _RealType __x = __param._M_int[__i]; 3149 1.1 mrg if (__a == 0) 3150 1.1 mrg __x += __cm / __b; 3151 1.1 mrg else 3152 1.1 mrg { 3153 1.1 mrg const double __d = __b * __b + 4.0 * __a * __cm; 3154 1.1 mrg __x += 0.5 * (std::sqrt(__d) - __b) / __a; 3155 1.1 mrg } 3156 1.1 mrg 3157 1.1 mrg return __x; 3158 1.1 mrg } 3159 1.1 mrg 3160 1.1.1.2 mrg template<typename _RealType> 3161 1.1.1.2 mrg template<typename _ForwardIterator, 3162 1.1.1.2 mrg typename _UniformRandomNumberGenerator> 3163 1.1.1.2 mrg void 3164 1.1.1.2 mrg piecewise_linear_distribution<_RealType>:: 3165 1.1.1.2 mrg __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3166 1.1.1.2 mrg _UniformRandomNumberGenerator& __urng, 3167 1.1.1.2 mrg const param_type& __param) 3168 1.1.1.2 mrg { 3169 1.1.1.2 mrg __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 3170 1.1.1.2 mrg // We could duplicate everything from operator()... 3171 1.1.1.2 mrg while (__f != __t) 3172 1.1.1.2 mrg *__f++ = this->operator()(__urng, __param); 3173 1.1.1.2 mrg } 3174 1.1.1.2 mrg 3175 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 3176 1.1 mrg std::basic_ostream<_CharT, _Traits>& 3177 1.1 mrg operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3178 1.1 mrg const piecewise_linear_distribution<_RealType>& __x) 3179 1.1 mrg { 3180 1.1.1.12 mrg using __ios_base = typename basic_ostream<_CharT, _Traits>::ios_base; 3181 1.1 mrg 3182 1.1 mrg const typename __ios_base::fmtflags __flags = __os.flags(); 3183 1.1 mrg const _CharT __fill = __os.fill(); 3184 1.1 mrg const std::streamsize __precision = __os.precision(); 3185 1.1 mrg const _CharT __space = __os.widen(' '); 3186 1.1 mrg __os.flags(__ios_base::scientific | __ios_base::left); 3187 1.1 mrg __os.fill(__space); 3188 1.1 mrg __os.precision(std::numeric_limits<_RealType>::max_digits10); 3189 1.1 mrg 3190 1.1 mrg std::vector<_RealType> __int = __x.intervals(); 3191 1.1 mrg __os << __int.size() - 1; 3192 1.1 mrg 3193 1.1 mrg for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) 3194 1.1 mrg __os << __space << *__xit; 3195 1.1 mrg 3196 1.1 mrg std::vector<double> __den = __x.densities(); 3197 1.1 mrg for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) 3198 1.1 mrg __os << __space << *__dit; 3199 1.1 mrg 3200 1.1 mrg __os.flags(__flags); 3201 1.1 mrg __os.fill(__fill); 3202 1.1 mrg __os.precision(__precision); 3203 1.1 mrg return __os; 3204 1.1 mrg } 3205 1.1 mrg 3206 1.1 mrg template<typename _RealType, typename _CharT, typename _Traits> 3207 1.1 mrg std::basic_istream<_CharT, _Traits>& 3208 1.1 mrg operator>>(std::basic_istream<_CharT, _Traits>& __is, 3209 1.1 mrg piecewise_linear_distribution<_RealType>& __x) 3210 1.1 mrg { 3211 1.1.1.12 mrg using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base; 3212 1.1 mrg 3213 1.1 mrg const typename __ios_base::fmtflags __flags = __is.flags(); 3214 1.1 mrg __is.flags(__ios_base::dec | __ios_base::skipws); 3215 1.1 mrg 3216 1.1 mrg size_t __n; 3217 1.1.1.10 mrg if (__is >> __n) 3218 1.1 mrg { 3219 1.1.1.10 mrg vector<_RealType> __int_vec; 3220 1.1.1.10 mrg if (__detail::__extract_params(__is, __int_vec, __n + 1)) 3221 1.1.1.10 mrg { 3222 1.1.1.10 mrg vector<double> __den_vec; 3223 1.1.1.10 mrg if (__detail::__extract_params(__is, __den_vec, __n + 1)) 3224 1.1.1.10 mrg { 3225 1.1.1.10 mrg __x.param({ __int_vec.begin(), __int_vec.end(), 3226 1.1.1.10 mrg __den_vec.begin() }); 3227 1.1.1.10 mrg } 3228 1.1.1.10 mrg } 3229 1.1.1.9 mrg } 3230 1.1 mrg __is.flags(__flags); 3231 1.1 mrg return __is; 3232 1.1 mrg } 3233 1.1 mrg 3234 1.1 mrg 3235 1.1.1.13 mrg template<typename _IntType, typename> 3236 1.1 mrg seed_seq::seed_seq(std::initializer_list<_IntType> __il) 3237 1.1 mrg { 3238 1.1.1.13 mrg _M_v.reserve(__il.size()); 3239 1.1 mrg for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter) 3240 1.1 mrg _M_v.push_back(__detail::__mod<result_type, 3241 1.1 mrg __detail::_Shift<result_type, 32>::__value>(*__iter)); 3242 1.1 mrg } 3243 1.1 mrg 3244 1.1 mrg template<typename _InputIterator> 3245 1.1 mrg seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end) 3246 1.1 mrg { 3247 1.1.1.13 mrg if _GLIBCXX17_CONSTEXPR (__is_random_access_iter<_InputIterator>::value) 3248 1.1.1.13 mrg _M_v.reserve(std::distance(__begin, __end)); 3249 1.1.1.13 mrg 3250 1.1 mrg for (_InputIterator __iter = __begin; __iter != __end; ++__iter) 3251 1.1 mrg _M_v.push_back(__detail::__mod<result_type, 3252 1.1 mrg __detail::_Shift<result_type, 32>::__value>(*__iter)); 3253 1.1 mrg } 3254 1.1 mrg 3255 1.1 mrg template<typename _RandomAccessIterator> 3256 1.1 mrg void 3257 1.1 mrg seed_seq::generate(_RandomAccessIterator __begin, 3258 1.1 mrg _RandomAccessIterator __end) 3259 1.1 mrg { 3260 1.1 mrg typedef typename iterator_traits<_RandomAccessIterator>::value_type 3261 1.1 mrg _Type; 3262 1.1 mrg 3263 1.1 mrg if (__begin == __end) 3264 1.1 mrg return; 3265 1.1 mrg 3266 1.1 mrg std::fill(__begin, __end, _Type(0x8b8b8b8bu)); 3267 1.1 mrg 3268 1.1 mrg const size_t __n = __end - __begin; 3269 1.1 mrg const size_t __s = _M_v.size(); 3270 1.1 mrg const size_t __t = (__n >= 623) ? 11 3271 1.1 mrg : (__n >= 68) ? 7 3272 1.1 mrg : (__n >= 39) ? 5 3273 1.1 mrg : (__n >= 7) ? 3 3274 1.1 mrg : (__n - 1) / 2; 3275 1.1 mrg const size_t __p = (__n - __t) / 2; 3276 1.1 mrg const size_t __q = __p + __t; 3277 1.1.1.2 mrg const size_t __m = std::max(size_t(__s + 1), __n); 3278 1.1 mrg 3279 1.1.1.14 mrg #ifndef __UINT32_TYPE__ 3280 1.1.1.14 mrg struct _Up 3281 1.1.1.14 mrg { 3282 1.1.1.14 mrg _Up(uint_least32_t v) : _M_v(v & 0xffffffffu) { } 3283 1.1.1.14 mrg 3284 1.1.1.14 mrg operator uint_least32_t() const { return _M_v; } 3285 1.1.1.14 mrg 3286 1.1.1.14 mrg uint_least32_t _M_v; 3287 1.1.1.14 mrg }; 3288 1.1.1.14 mrg using uint32_t = _Up; 3289 1.1.1.14 mrg #endif 3290 1.1.1.14 mrg 3291 1.1.1.14 mrg // k == 0, every element in [begin,end) equals 0x8b8b8b8bu 3292 1.1 mrg { 3293 1.1.1.14 mrg uint32_t __r1 = 1371501266u; 3294 1.1.1.14 mrg uint32_t __r2 = __r1 + __s; 3295 1.1.1.14 mrg __begin[__p] += __r1; 3296 1.1.1.14 mrg __begin[__q] = (uint32_t)__begin[__q] + __r2; 3297 1.1.1.14 mrg __begin[0] = __r2; 3298 1.1.1.14 mrg } 3299 1.1.1.14 mrg 3300 1.1.1.14 mrg for (size_t __k = 1; __k <= __s; ++__k) 3301 1.1.1.14 mrg { 3302 1.1.1.14 mrg const size_t __kn = __k % __n; 3303 1.1.1.14 mrg const size_t __kpn = (__k + __p) % __n; 3304 1.1.1.14 mrg const size_t __kqn = (__k + __q) % __n; 3305 1.1.1.14 mrg uint32_t __arg = (__begin[__kn] 3306 1.1.1.14 mrg ^ __begin[__kpn] 3307 1.1.1.14 mrg ^ __begin[(__k - 1) % __n]); 3308 1.1.1.14 mrg uint32_t __r1 = 1664525u * (__arg ^ (__arg >> 27)); 3309 1.1.1.14 mrg uint32_t __r2 = __r1 + (uint32_t)__kn + _M_v[__k - 1]; 3310 1.1.1.14 mrg __begin[__kpn] = (uint32_t)__begin[__kpn] + __r1; 3311 1.1.1.14 mrg __begin[__kqn] = (uint32_t)__begin[__kqn] + __r2; 3312 1.1.1.14 mrg __begin[__kn] = __r2; 3313 1.1.1.14 mrg } 3314 1.1.1.14 mrg 3315 1.1.1.14 mrg for (size_t __k = __s + 1; __k < __m; ++__k) 3316 1.1.1.14 mrg { 3317 1.1.1.14 mrg const size_t __kn = __k % __n; 3318 1.1.1.14 mrg const size_t __kpn = (__k + __p) % __n; 3319 1.1.1.14 mrg const size_t __kqn = (__k + __q) % __n; 3320 1.1.1.14 mrg uint32_t __arg = (__begin[__kn] 3321 1.1.1.14 mrg ^ __begin[__kpn] 3322 1.1.1.14 mrg ^ __begin[(__k - 1) % __n]); 3323 1.1.1.14 mrg uint32_t __r1 = 1664525u * (__arg ^ (__arg >> 27)); 3324 1.1.1.14 mrg uint32_t __r2 = __r1 + (uint32_t)__kn; 3325 1.1.1.14 mrg __begin[__kpn] = (uint32_t)__begin[__kpn] + __r1; 3326 1.1.1.14 mrg __begin[__kqn] = (uint32_t)__begin[__kqn] + __r2; 3327 1.1.1.14 mrg __begin[__kn] = __r2; 3328 1.1 mrg } 3329 1.1 mrg 3330 1.1 mrg for (size_t __k = __m; __k < __m + __n; ++__k) 3331 1.1 mrg { 3332 1.1.1.14 mrg const size_t __kn = __k % __n; 3333 1.1.1.14 mrg const size_t __kpn = (__k + __p) % __n; 3334 1.1.1.14 mrg const size_t __kqn = (__k + __q) % __n; 3335 1.1.1.14 mrg uint32_t __arg = (__begin[__kn] 3336 1.1.1.14 mrg + __begin[__kpn] 3337 1.1.1.14 mrg + __begin[(__k - 1) % __n]); 3338 1.1.1.14 mrg uint32_t __r3 = 1566083941u * (__arg ^ (__arg >> 27)); 3339 1.1.1.14 mrg uint32_t __r4 = __r3 - __kn; 3340 1.1.1.14 mrg __begin[__kpn] ^= __r3; 3341 1.1.1.14 mrg __begin[__kqn] ^= __r4; 3342 1.1.1.14 mrg __begin[__kn] = __r4; 3343 1.1 mrg } 3344 1.1 mrg } 3345 1.1 mrg 3346 1.1 mrg template<typename _RealType, size_t __bits, 3347 1.1 mrg typename _UniformRandomNumberGenerator> 3348 1.1 mrg _RealType 3349 1.1 mrg generate_canonical(_UniformRandomNumberGenerator& __urng) 3350 1.1 mrg { 3351 1.1.1.3 mrg static_assert(std::is_floating_point<_RealType>::value, 3352 1.1.1.6 mrg "template argument must be a floating point type"); 3353 1.1.1.3 mrg 3354 1.1 mrg const size_t __b 3355 1.1 mrg = std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits), 3356 1.1 mrg __bits); 3357 1.1 mrg const long double __r = static_cast<long double>(__urng.max()) 3358 1.1 mrg - static_cast<long double>(__urng.min()) + 1.0L; 3359 1.1 mrg const size_t __log2r = std::log(__r) / std::log(2.0L); 3360 1.1.1.5 mrg const size_t __m = std::max<size_t>(1UL, 3361 1.1.1.5 mrg (__b + __log2r - 1UL) / __log2r); 3362 1.1.1.5 mrg _RealType __ret; 3363 1.1 mrg _RealType __sum = _RealType(0); 3364 1.1 mrg _RealType __tmp = _RealType(1); 3365 1.1.1.5 mrg for (size_t __k = __m; __k != 0; --__k) 3366 1.1 mrg { 3367 1.1 mrg __sum += _RealType(__urng() - __urng.min()) * __tmp; 3368 1.1 mrg __tmp *= __r; 3369 1.1 mrg } 3370 1.1.1.5 mrg __ret = __sum / __tmp; 3371 1.1.1.5 mrg if (__builtin_expect(__ret >= _RealType(1), 0)) 3372 1.1.1.5 mrg { 3373 1.1.1.16 mrg #if _GLIBCXX_USE_C99_MATH_FUNCS 3374 1.1.1.5 mrg __ret = std::nextafter(_RealType(1), _RealType(0)); 3375 1.1.1.5 mrg #else 3376 1.1.1.5 mrg __ret = _RealType(1) 3377 1.1.1.5 mrg - std::numeric_limits<_RealType>::epsilon() / _RealType(2); 3378 1.1.1.5 mrg #endif 3379 1.1.1.5 mrg } 3380 1.1.1.5 mrg return __ret; 3381 1.1 mrg } 3382 1.1.1.2 mrg 3383 1.1.1.2 mrg _GLIBCXX_END_NAMESPACE_VERSION 3384 1.1.1.2 mrg } // namespace 3385 1.1.1.2 mrg 3386 1.1.1.2 mrg #endif 3387