138fd1498Szrj // random number generation (out of line) -*- C++ -*- 238fd1498Szrj 338fd1498Szrj // Copyright (C) 2009-2018 Free Software Foundation, Inc. 438fd1498Szrj // 538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 638fd1498Szrj // software; you can redistribute it and/or modify it under the 738fd1498Szrj // terms of the GNU General Public License as published by the 838fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj // any later version. 1038fd1498Szrj 1138fd1498Szrj // This library is distributed in the hope that it will be useful, 1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj // GNU General Public License for more details. 1538fd1498Szrj 1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 1838fd1498Szrj // 3.1, as published by the Free Software Foundation. 1938fd1498Szrj 2038fd1498Szrj // You should have received a copy of the GNU General Public License and 2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2338fd1498Szrj // <http://www.gnu.org/licenses/>. 2438fd1498Szrj 2538fd1498Szrj /** @file bits/random.tcc 2638fd1498Szrj * This is an internal header file, included by other library headers. 2738fd1498Szrj * Do not attempt to use it directly. @headername{random} 2838fd1498Szrj */ 2938fd1498Szrj 3038fd1498Szrj #ifndef _RANDOM_TCC 3138fd1498Szrj #define _RANDOM_TCC 1 3238fd1498Szrj 3338fd1498Szrj #include <numeric> // std::accumulate and std::partial_sum 3438fd1498Szrj 3538fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 3638fd1498Szrj { 3738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 3838fd1498Szrj 3938fd1498Szrj /* 4038fd1498Szrj * (Further) implementation-space details. 4138fd1498Szrj */ 4238fd1498Szrj namespace __detail 4338fd1498Szrj { 4438fd1498Szrj // General case for x = (ax + c) mod m -- use Schrage's algorithm 4538fd1498Szrj // to avoid integer overflow. 4638fd1498Szrj // 4738fd1498Szrj // Preconditions: a > 0, m > 0. 4838fd1498Szrj // 4938fd1498Szrj // Note: only works correctly for __m % __a < __m / __a. 5038fd1498Szrj template<typename _Tp, _Tp __m, _Tp __a, _Tp __c> 5138fd1498Szrj _Tp 5238fd1498Szrj _Mod<_Tp, __m, __a, __c, false, true>:: __calc(_Tp __x)5338fd1498Szrj __calc(_Tp __x) 5438fd1498Szrj { 5538fd1498Szrj if (__a == 1) 5638fd1498Szrj __x %= __m; 5738fd1498Szrj else 5838fd1498Szrj { 5938fd1498Szrj static const _Tp __q = __m / __a; 6038fd1498Szrj static const _Tp __r = __m % __a; 6138fd1498Szrj 6238fd1498Szrj _Tp __t1 = __a * (__x % __q); 6338fd1498Szrj _Tp __t2 = __r * (__x / __q); 6438fd1498Szrj if (__t1 >= __t2) 6538fd1498Szrj __x = __t1 - __t2; 6638fd1498Szrj else 6738fd1498Szrj __x = __m - __t2 + __t1; 6838fd1498Szrj } 6938fd1498Szrj 7038fd1498Szrj if (__c != 0) 7138fd1498Szrj { 7238fd1498Szrj const _Tp __d = __m - __x; 7338fd1498Szrj if (__d > __c) 7438fd1498Szrj __x += __c; 7538fd1498Szrj else 7638fd1498Szrj __x = __c - __d; 7738fd1498Szrj } 7838fd1498Szrj return __x; 7938fd1498Szrj } 8038fd1498Szrj 8138fd1498Szrj template<typename _InputIterator, typename _OutputIterator, 8238fd1498Szrj typename _Tp> 8338fd1498Szrj _OutputIterator __normalize(_InputIterator __first,_InputIterator __last,_OutputIterator __result,const _Tp & __factor)8438fd1498Szrj __normalize(_InputIterator __first, _InputIterator __last, 8538fd1498Szrj _OutputIterator __result, const _Tp& __factor) 8638fd1498Szrj { 8738fd1498Szrj for (; __first != __last; ++__first, ++__result) 8838fd1498Szrj *__result = *__first / __factor; 8938fd1498Szrj return __result; 9038fd1498Szrj } 9138fd1498Szrj 9238fd1498Szrj } // namespace __detail 9338fd1498Szrj 9438fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 9538fd1498Szrj constexpr _UIntType 9638fd1498Szrj linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier; 9738fd1498Szrj 9838fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 9938fd1498Szrj constexpr _UIntType 10038fd1498Szrj linear_congruential_engine<_UIntType, __a, __c, __m>::increment; 10138fd1498Szrj 10238fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 10338fd1498Szrj constexpr _UIntType 10438fd1498Szrj linear_congruential_engine<_UIntType, __a, __c, __m>::modulus; 10538fd1498Szrj 10638fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 10738fd1498Szrj constexpr _UIntType 10838fd1498Szrj linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed; 10938fd1498Szrj 11038fd1498Szrj /** 11138fd1498Szrj * Seeds the LCR with integral value @p __s, adjusted so that the 11238fd1498Szrj * ring identity is never a member of the convergence set. 11338fd1498Szrj */ 11438fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 11538fd1498Szrj void 11638fd1498Szrj linear_congruential_engine<_UIntType, __a, __c, __m>:: seed(result_type __s)11738fd1498Szrj seed(result_type __s) 11838fd1498Szrj { 11938fd1498Szrj if ((__detail::__mod<_UIntType, __m>(__c) == 0) 12038fd1498Szrj && (__detail::__mod<_UIntType, __m>(__s) == 0)) 12138fd1498Szrj _M_x = 1; 12238fd1498Szrj else 12338fd1498Szrj _M_x = __detail::__mod<_UIntType, __m>(__s); 12438fd1498Szrj } 12538fd1498Szrj 12638fd1498Szrj /** 12738fd1498Szrj * Seeds the LCR engine with a value generated by @p __q. 12838fd1498Szrj */ 12938fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 13038fd1498Szrj template<typename _Sseq> 13138fd1498Szrj typename std::enable_if<std::is_class<_Sseq>::value>::type 13238fd1498Szrj linear_congruential_engine<_UIntType, __a, __c, __m>:: seed(_Sseq & __q)13338fd1498Szrj seed(_Sseq& __q) 13438fd1498Szrj { 13538fd1498Szrj const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits 13638fd1498Szrj : std::__lg(__m); 13738fd1498Szrj const _UIntType __k = (__k0 + 31) / 32; 13838fd1498Szrj uint_least32_t __arr[__k + 3]; 13938fd1498Szrj __q.generate(__arr + 0, __arr + __k + 3); 14038fd1498Szrj _UIntType __factor = 1u; 14138fd1498Szrj _UIntType __sum = 0u; 14238fd1498Szrj for (size_t __j = 0; __j < __k; ++__j) 14338fd1498Szrj { 14438fd1498Szrj __sum += __arr[__j + 3] * __factor; 14538fd1498Szrj __factor *= __detail::_Shift<_UIntType, 32>::__value; 14638fd1498Szrj } 14738fd1498Szrj seed(__sum); 14838fd1498Szrj } 14938fd1498Szrj 15038fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 15138fd1498Szrj typename _CharT, typename _Traits> 15238fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const linear_congruential_engine<_UIntType,__a,__c,__m> & __lcr)15338fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 15438fd1498Szrj const linear_congruential_engine<_UIntType, 15538fd1498Szrj __a, __c, __m>& __lcr) 15638fd1498Szrj { 15738fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 15838fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 15938fd1498Szrj 16038fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 16138fd1498Szrj const _CharT __fill = __os.fill(); 16238fd1498Szrj __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 16338fd1498Szrj __os.fill(__os.widen(' ')); 16438fd1498Szrj 16538fd1498Szrj __os << __lcr._M_x; 16638fd1498Szrj 16738fd1498Szrj __os.flags(__flags); 16838fd1498Szrj __os.fill(__fill); 16938fd1498Szrj return __os; 17038fd1498Szrj } 17138fd1498Szrj 17238fd1498Szrj template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, 17338fd1498Szrj typename _CharT, typename _Traits> 17438fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,linear_congruential_engine<_UIntType,__a,__c,__m> & __lcr)17538fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 17638fd1498Szrj linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr) 17738fd1498Szrj { 17838fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 17938fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 18038fd1498Szrj 18138fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 18238fd1498Szrj __is.flags(__ios_base::dec); 18338fd1498Szrj 18438fd1498Szrj __is >> __lcr._M_x; 18538fd1498Szrj 18638fd1498Szrj __is.flags(__flags); 18738fd1498Szrj return __is; 18838fd1498Szrj } 18938fd1498Szrj 19038fd1498Szrj 19138fd1498Szrj template<typename _UIntType, 19238fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 19338fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 19438fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 19538fd1498Szrj _UIntType __f> 19638fd1498Szrj constexpr size_t 19738fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 19838fd1498Szrj __s, __b, __t, __c, __l, __f>::word_size; 19938fd1498Szrj 20038fd1498Szrj template<typename _UIntType, 20138fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 20238fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 20338fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 20438fd1498Szrj _UIntType __f> 20538fd1498Szrj constexpr size_t 20638fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 20738fd1498Szrj __s, __b, __t, __c, __l, __f>::state_size; 20838fd1498Szrj 20938fd1498Szrj template<typename _UIntType, 21038fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 21138fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 21238fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 21338fd1498Szrj _UIntType __f> 21438fd1498Szrj constexpr size_t 21538fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 21638fd1498Szrj __s, __b, __t, __c, __l, __f>::shift_size; 21738fd1498Szrj 21838fd1498Szrj template<typename _UIntType, 21938fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 22038fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 22138fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 22238fd1498Szrj _UIntType __f> 22338fd1498Szrj constexpr size_t 22438fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 22538fd1498Szrj __s, __b, __t, __c, __l, __f>::mask_bits; 22638fd1498Szrj 22738fd1498Szrj template<typename _UIntType, 22838fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 22938fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 23038fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 23138fd1498Szrj _UIntType __f> 23238fd1498Szrj constexpr _UIntType 23338fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 23438fd1498Szrj __s, __b, __t, __c, __l, __f>::xor_mask; 23538fd1498Szrj 23638fd1498Szrj template<typename _UIntType, 23738fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 23838fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 23938fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 24038fd1498Szrj _UIntType __f> 24138fd1498Szrj constexpr size_t 24238fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 24338fd1498Szrj __s, __b, __t, __c, __l, __f>::tempering_u; 24438fd1498Szrj 24538fd1498Szrj template<typename _UIntType, 24638fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 24738fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 24838fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 24938fd1498Szrj _UIntType __f> 25038fd1498Szrj constexpr _UIntType 25138fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 25238fd1498Szrj __s, __b, __t, __c, __l, __f>::tempering_d; 25338fd1498Szrj 25438fd1498Szrj template<typename _UIntType, 25538fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 25638fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 25738fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 25838fd1498Szrj _UIntType __f> 25938fd1498Szrj constexpr size_t 26038fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 26138fd1498Szrj __s, __b, __t, __c, __l, __f>::tempering_s; 26238fd1498Szrj 26338fd1498Szrj template<typename _UIntType, 26438fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 26538fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 26638fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 26738fd1498Szrj _UIntType __f> 26838fd1498Szrj constexpr _UIntType 26938fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 27038fd1498Szrj __s, __b, __t, __c, __l, __f>::tempering_b; 27138fd1498Szrj 27238fd1498Szrj template<typename _UIntType, 27338fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 27438fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 27538fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 27638fd1498Szrj _UIntType __f> 27738fd1498Szrj constexpr size_t 27838fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 27938fd1498Szrj __s, __b, __t, __c, __l, __f>::tempering_t; 28038fd1498Szrj 28138fd1498Szrj template<typename _UIntType, 28238fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 28338fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 28438fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 28538fd1498Szrj _UIntType __f> 28638fd1498Szrj constexpr _UIntType 28738fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 28838fd1498Szrj __s, __b, __t, __c, __l, __f>::tempering_c; 28938fd1498Szrj 29038fd1498Szrj template<typename _UIntType, 29138fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 29238fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 29338fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 29438fd1498Szrj _UIntType __f> 29538fd1498Szrj constexpr size_t 29638fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 29738fd1498Szrj __s, __b, __t, __c, __l, __f>::tempering_l; 29838fd1498Szrj 29938fd1498Szrj template<typename _UIntType, 30038fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 30138fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 30238fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 30338fd1498Szrj _UIntType __f> 30438fd1498Szrj constexpr _UIntType 30538fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 30638fd1498Szrj __s, __b, __t, __c, __l, __f>:: 30738fd1498Szrj initialization_multiplier; 30838fd1498Szrj 30938fd1498Szrj template<typename _UIntType, 31038fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 31138fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 31238fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 31338fd1498Szrj _UIntType __f> 31438fd1498Szrj constexpr _UIntType 31538fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 31638fd1498Szrj __s, __b, __t, __c, __l, __f>::default_seed; 31738fd1498Szrj 31838fd1498Szrj template<typename _UIntType, 31938fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 32038fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 32138fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 32238fd1498Szrj _UIntType __f> 32338fd1498Szrj void 32438fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 32538fd1498Szrj __s, __b, __t, __c, __l, __f>:: seed(result_type __sd)32638fd1498Szrj seed(result_type __sd) 32738fd1498Szrj { 32838fd1498Szrj _M_x[0] = __detail::__mod<_UIntType, 32938fd1498Szrj __detail::_Shift<_UIntType, __w>::__value>(__sd); 33038fd1498Szrj 33138fd1498Szrj for (size_t __i = 1; __i < state_size; ++__i) 33238fd1498Szrj { 33338fd1498Szrj _UIntType __x = _M_x[__i - 1]; 33438fd1498Szrj __x ^= __x >> (__w - 2); 33538fd1498Szrj __x *= __f; 33638fd1498Szrj __x += __detail::__mod<_UIntType, __n>(__i); 33738fd1498Szrj _M_x[__i] = __detail::__mod<_UIntType, 33838fd1498Szrj __detail::_Shift<_UIntType, __w>::__value>(__x); 33938fd1498Szrj } 34038fd1498Szrj _M_p = state_size; 34138fd1498Szrj } 34238fd1498Szrj 34338fd1498Szrj template<typename _UIntType, 34438fd1498Szrj size_t __w, size_t __n, size_t __m, size_t __r, 34538fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 34638fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 34738fd1498Szrj _UIntType __f> 34838fd1498Szrj template<typename _Sseq> 34938fd1498Szrj typename std::enable_if<std::is_class<_Sseq>::value>::type 35038fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 35138fd1498Szrj __s, __b, __t, __c, __l, __f>:: seed(_Sseq & __q)35238fd1498Szrj seed(_Sseq& __q) 35338fd1498Szrj { 35438fd1498Szrj const _UIntType __upper_mask = (~_UIntType()) << __r; 35538fd1498Szrj const size_t __k = (__w + 31) / 32; 35638fd1498Szrj uint_least32_t __arr[__n * __k]; 35738fd1498Szrj __q.generate(__arr + 0, __arr + __n * __k); 35838fd1498Szrj 35938fd1498Szrj bool __zero = true; 36038fd1498Szrj for (size_t __i = 0; __i < state_size; ++__i) 36138fd1498Szrj { 36238fd1498Szrj _UIntType __factor = 1u; 36338fd1498Szrj _UIntType __sum = 0u; 36438fd1498Szrj for (size_t __j = 0; __j < __k; ++__j) 36538fd1498Szrj { 36638fd1498Szrj __sum += __arr[__k * __i + __j] * __factor; 36738fd1498Szrj __factor *= __detail::_Shift<_UIntType, 32>::__value; 36838fd1498Szrj } 36938fd1498Szrj _M_x[__i] = __detail::__mod<_UIntType, 37038fd1498Szrj __detail::_Shift<_UIntType, __w>::__value>(__sum); 37138fd1498Szrj 37238fd1498Szrj if (__zero) 37338fd1498Szrj { 37438fd1498Szrj if (__i == 0) 37538fd1498Szrj { 37638fd1498Szrj if ((_M_x[0] & __upper_mask) != 0u) 37738fd1498Szrj __zero = false; 37838fd1498Szrj } 37938fd1498Szrj else if (_M_x[__i] != 0u) 38038fd1498Szrj __zero = false; 38138fd1498Szrj } 38238fd1498Szrj } 38338fd1498Szrj if (__zero) 38438fd1498Szrj _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value; 38538fd1498Szrj _M_p = state_size; 38638fd1498Szrj } 38738fd1498Szrj 38838fd1498Szrj template<typename _UIntType, size_t __w, 38938fd1498Szrj size_t __n, size_t __m, size_t __r, 39038fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 39138fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 39238fd1498Szrj _UIntType __f> 39338fd1498Szrj void 39438fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 39538fd1498Szrj __s, __b, __t, __c, __l, __f>:: _M_gen_rand(void)39638fd1498Szrj _M_gen_rand(void) 39738fd1498Szrj { 39838fd1498Szrj const _UIntType __upper_mask = (~_UIntType()) << __r; 39938fd1498Szrj const _UIntType __lower_mask = ~__upper_mask; 40038fd1498Szrj 40138fd1498Szrj for (size_t __k = 0; __k < (__n - __m); ++__k) 40238fd1498Szrj { 40338fd1498Szrj _UIntType __y = ((_M_x[__k] & __upper_mask) 40438fd1498Szrj | (_M_x[__k + 1] & __lower_mask)); 40538fd1498Szrj _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1) 40638fd1498Szrj ^ ((__y & 0x01) ? __a : 0)); 40738fd1498Szrj } 40838fd1498Szrj 40938fd1498Szrj for (size_t __k = (__n - __m); __k < (__n - 1); ++__k) 41038fd1498Szrj { 41138fd1498Szrj _UIntType __y = ((_M_x[__k] & __upper_mask) 41238fd1498Szrj | (_M_x[__k + 1] & __lower_mask)); 41338fd1498Szrj _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1) 41438fd1498Szrj ^ ((__y & 0x01) ? __a : 0)); 41538fd1498Szrj } 41638fd1498Szrj 41738fd1498Szrj _UIntType __y = ((_M_x[__n - 1] & __upper_mask) 41838fd1498Szrj | (_M_x[0] & __lower_mask)); 41938fd1498Szrj _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1) 42038fd1498Szrj ^ ((__y & 0x01) ? __a : 0)); 42138fd1498Szrj _M_p = 0; 42238fd1498Szrj } 42338fd1498Szrj 42438fd1498Szrj template<typename _UIntType, size_t __w, 42538fd1498Szrj size_t __n, size_t __m, size_t __r, 42638fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 42738fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 42838fd1498Szrj _UIntType __f> 42938fd1498Szrj void 43038fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 43138fd1498Szrj __s, __b, __t, __c, __l, __f>:: discard(unsigned long long __z)43238fd1498Szrj discard(unsigned long long __z) 43338fd1498Szrj { 43438fd1498Szrj while (__z > state_size - _M_p) 43538fd1498Szrj { 43638fd1498Szrj __z -= state_size - _M_p; 43738fd1498Szrj _M_gen_rand(); 43838fd1498Szrj } 43938fd1498Szrj _M_p += __z; 44038fd1498Szrj } 44138fd1498Szrj 44238fd1498Szrj template<typename _UIntType, size_t __w, 44338fd1498Szrj size_t __n, size_t __m, size_t __r, 44438fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 44538fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 44638fd1498Szrj _UIntType __f> 44738fd1498Szrj typename 44838fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 44938fd1498Szrj __s, __b, __t, __c, __l, __f>::result_type 45038fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, 45138fd1498Szrj __s, __b, __t, __c, __l, __f>:: operator ()()45238fd1498Szrj operator()() 45338fd1498Szrj { 45438fd1498Szrj // Reload the vector - cost is O(n) amortized over n calls. 45538fd1498Szrj if (_M_p >= state_size) 45638fd1498Szrj _M_gen_rand(); 45738fd1498Szrj 45838fd1498Szrj // Calculate o(x(i)). 45938fd1498Szrj result_type __z = _M_x[_M_p++]; 46038fd1498Szrj __z ^= (__z >> __u) & __d; 46138fd1498Szrj __z ^= (__z << __s) & __b; 46238fd1498Szrj __z ^= (__z << __t) & __c; 46338fd1498Szrj __z ^= (__z >> __l); 46438fd1498Szrj 46538fd1498Szrj return __z; 46638fd1498Szrj } 46738fd1498Szrj 46838fd1498Szrj template<typename _UIntType, size_t __w, 46938fd1498Szrj size_t __n, size_t __m, size_t __r, 47038fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 47138fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 47238fd1498Szrj _UIntType __f, typename _CharT, typename _Traits> 47338fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const mersenne_twister_engine<_UIntType,__w,__n,__m,__r,__a,__u,__d,__s,__b,__t,__c,__l,__f> & __x)47438fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 47538fd1498Szrj const mersenne_twister_engine<_UIntType, __w, __n, __m, 47638fd1498Szrj __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) 47738fd1498Szrj { 47838fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 47938fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 48038fd1498Szrj 48138fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 48238fd1498Szrj const _CharT __fill = __os.fill(); 48338fd1498Szrj const _CharT __space = __os.widen(' '); 48438fd1498Szrj __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 48538fd1498Szrj __os.fill(__space); 48638fd1498Szrj 48738fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 48838fd1498Szrj __os << __x._M_x[__i] << __space; 48938fd1498Szrj __os << __x._M_p; 49038fd1498Szrj 49138fd1498Szrj __os.flags(__flags); 49238fd1498Szrj __os.fill(__fill); 49338fd1498Szrj return __os; 49438fd1498Szrj } 49538fd1498Szrj 49638fd1498Szrj template<typename _UIntType, size_t __w, 49738fd1498Szrj size_t __n, size_t __m, size_t __r, 49838fd1498Szrj _UIntType __a, size_t __u, _UIntType __d, size_t __s, 49938fd1498Szrj _UIntType __b, size_t __t, _UIntType __c, size_t __l, 50038fd1498Szrj _UIntType __f, typename _CharT, typename _Traits> 50138fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,mersenne_twister_engine<_UIntType,__w,__n,__m,__r,__a,__u,__d,__s,__b,__t,__c,__l,__f> & __x)50238fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 50338fd1498Szrj mersenne_twister_engine<_UIntType, __w, __n, __m, 50438fd1498Szrj __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) 50538fd1498Szrj { 50638fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 50738fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 50838fd1498Szrj 50938fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 51038fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 51138fd1498Szrj 51238fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 51338fd1498Szrj __is >> __x._M_x[__i]; 51438fd1498Szrj __is >> __x._M_p; 51538fd1498Szrj 51638fd1498Szrj __is.flags(__flags); 51738fd1498Szrj return __is; 51838fd1498Szrj } 51938fd1498Szrj 52038fd1498Szrj 52138fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r> 52238fd1498Szrj constexpr size_t 52338fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size; 52438fd1498Szrj 52538fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r> 52638fd1498Szrj constexpr size_t 52738fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag; 52838fd1498Szrj 52938fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r> 53038fd1498Szrj constexpr size_t 53138fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag; 53238fd1498Szrj 53338fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r> 53438fd1498Szrj constexpr _UIntType 53538fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed; 53638fd1498Szrj 53738fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r> 53838fd1498Szrj void 53938fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>:: seed(result_type __value)54038fd1498Szrj seed(result_type __value) 54138fd1498Szrj { 54238fd1498Szrj std::linear_congruential_engine<result_type, 40014u, 0u, 2147483563u> 54338fd1498Szrj __lcg(__value == 0u ? default_seed : __value); 54438fd1498Szrj 54538fd1498Szrj const size_t __n = (__w + 31) / 32; 54638fd1498Szrj 54738fd1498Szrj for (size_t __i = 0; __i < long_lag; ++__i) 54838fd1498Szrj { 54938fd1498Szrj _UIntType __sum = 0u; 55038fd1498Szrj _UIntType __factor = 1u; 55138fd1498Szrj for (size_t __j = 0; __j < __n; ++__j) 55238fd1498Szrj { 55338fd1498Szrj __sum += __detail::__mod<uint_least32_t, 55438fd1498Szrj __detail::_Shift<uint_least32_t, 32>::__value> 55538fd1498Szrj (__lcg()) * __factor; 55638fd1498Szrj __factor *= __detail::_Shift<_UIntType, 32>::__value; 55738fd1498Szrj } 55838fd1498Szrj _M_x[__i] = __detail::__mod<_UIntType, 55938fd1498Szrj __detail::_Shift<_UIntType, __w>::__value>(__sum); 56038fd1498Szrj } 56138fd1498Szrj _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 56238fd1498Szrj _M_p = 0; 56338fd1498Szrj } 56438fd1498Szrj 56538fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r> 56638fd1498Szrj template<typename _Sseq> 56738fd1498Szrj typename std::enable_if<std::is_class<_Sseq>::value>::type 56838fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>:: seed(_Sseq & __q)56938fd1498Szrj seed(_Sseq& __q) 57038fd1498Szrj { 57138fd1498Szrj const size_t __k = (__w + 31) / 32; 57238fd1498Szrj uint_least32_t __arr[__r * __k]; 57338fd1498Szrj __q.generate(__arr + 0, __arr + __r * __k); 57438fd1498Szrj 57538fd1498Szrj for (size_t __i = 0; __i < long_lag; ++__i) 57638fd1498Szrj { 57738fd1498Szrj _UIntType __sum = 0u; 57838fd1498Szrj _UIntType __factor = 1u; 57938fd1498Szrj for (size_t __j = 0; __j < __k; ++__j) 58038fd1498Szrj { 58138fd1498Szrj __sum += __arr[__k * __i + __j] * __factor; 58238fd1498Szrj __factor *= __detail::_Shift<_UIntType, 32>::__value; 58338fd1498Szrj } 58438fd1498Szrj _M_x[__i] = __detail::__mod<_UIntType, 58538fd1498Szrj __detail::_Shift<_UIntType, __w>::__value>(__sum); 58638fd1498Szrj } 58738fd1498Szrj _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; 58838fd1498Szrj _M_p = 0; 58938fd1498Szrj } 59038fd1498Szrj 59138fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r> 59238fd1498Szrj typename subtract_with_carry_engine<_UIntType, __w, __s, __r>:: 59338fd1498Szrj result_type 59438fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>:: operator ()()59538fd1498Szrj operator()() 59638fd1498Szrj { 59738fd1498Szrj // Derive short lag index from current index. 59838fd1498Szrj long __ps = _M_p - short_lag; 59938fd1498Szrj if (__ps < 0) 60038fd1498Szrj __ps += long_lag; 60138fd1498Szrj 60238fd1498Szrj // Calculate new x(i) without overflow or division. 60338fd1498Szrj // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry 60438fd1498Szrj // cannot overflow. 60538fd1498Szrj _UIntType __xi; 60638fd1498Szrj if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) 60738fd1498Szrj { 60838fd1498Szrj __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; 60938fd1498Szrj _M_carry = 0; 61038fd1498Szrj } 61138fd1498Szrj else 61238fd1498Szrj { 61338fd1498Szrj __xi = (__detail::_Shift<_UIntType, __w>::__value 61438fd1498Szrj - _M_x[_M_p] - _M_carry + _M_x[__ps]); 61538fd1498Szrj _M_carry = 1; 61638fd1498Szrj } 61738fd1498Szrj _M_x[_M_p] = __xi; 61838fd1498Szrj 61938fd1498Szrj // Adjust current index to loop around in ring buffer. 62038fd1498Szrj if (++_M_p >= long_lag) 62138fd1498Szrj _M_p = 0; 62238fd1498Szrj 62338fd1498Szrj return __xi; 62438fd1498Szrj } 62538fd1498Szrj 62638fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r, 62738fd1498Szrj typename _CharT, typename _Traits> 62838fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const subtract_with_carry_engine<_UIntType,__w,__s,__r> & __x)62938fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 63038fd1498Szrj const subtract_with_carry_engine<_UIntType, 63138fd1498Szrj __w, __s, __r>& __x) 63238fd1498Szrj { 63338fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 63438fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 63538fd1498Szrj 63638fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 63738fd1498Szrj const _CharT __fill = __os.fill(); 63838fd1498Szrj const _CharT __space = __os.widen(' '); 63938fd1498Szrj __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 64038fd1498Szrj __os.fill(__space); 64138fd1498Szrj 64238fd1498Szrj for (size_t __i = 0; __i < __r; ++__i) 64338fd1498Szrj __os << __x._M_x[__i] << __space; 64438fd1498Szrj __os << __x._M_carry << __space << __x._M_p; 64538fd1498Szrj 64638fd1498Szrj __os.flags(__flags); 64738fd1498Szrj __os.fill(__fill); 64838fd1498Szrj return __os; 64938fd1498Szrj } 65038fd1498Szrj 65138fd1498Szrj template<typename _UIntType, size_t __w, size_t __s, size_t __r, 65238fd1498Szrj typename _CharT, typename _Traits> 65338fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,subtract_with_carry_engine<_UIntType,__w,__s,__r> & __x)65438fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 65538fd1498Szrj subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x) 65638fd1498Szrj { 65738fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __istream_type; 65838fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 65938fd1498Szrj 66038fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 66138fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 66238fd1498Szrj 66338fd1498Szrj for (size_t __i = 0; __i < __r; ++__i) 66438fd1498Szrj __is >> __x._M_x[__i]; 66538fd1498Szrj __is >> __x._M_carry; 66638fd1498Szrj __is >> __x._M_p; 66738fd1498Szrj 66838fd1498Szrj __is.flags(__flags); 66938fd1498Szrj return __is; 67038fd1498Szrj } 67138fd1498Szrj 67238fd1498Szrj 67338fd1498Szrj template<typename _RandomNumberEngine, size_t __p, size_t __r> 67438fd1498Szrj constexpr size_t 67538fd1498Szrj discard_block_engine<_RandomNumberEngine, __p, __r>::block_size; 67638fd1498Szrj 67738fd1498Szrj template<typename _RandomNumberEngine, size_t __p, size_t __r> 67838fd1498Szrj constexpr size_t 67938fd1498Szrj discard_block_engine<_RandomNumberEngine, __p, __r>::used_block; 68038fd1498Szrj 68138fd1498Szrj template<typename _RandomNumberEngine, size_t __p, size_t __r> 68238fd1498Szrj typename discard_block_engine<_RandomNumberEngine, 68338fd1498Szrj __p, __r>::result_type 68438fd1498Szrj discard_block_engine<_RandomNumberEngine, __p, __r>:: operator ()()68538fd1498Szrj operator()() 68638fd1498Szrj { 68738fd1498Szrj if (_M_n >= used_block) 68838fd1498Szrj { 68938fd1498Szrj _M_b.discard(block_size - _M_n); 69038fd1498Szrj _M_n = 0; 69138fd1498Szrj } 69238fd1498Szrj ++_M_n; 69338fd1498Szrj return _M_b(); 69438fd1498Szrj } 69538fd1498Szrj 69638fd1498Szrj template<typename _RandomNumberEngine, size_t __p, size_t __r, 69738fd1498Szrj typename _CharT, typename _Traits> 69838fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const discard_block_engine<_RandomNumberEngine,__p,__r> & __x)69938fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 70038fd1498Szrj const discard_block_engine<_RandomNumberEngine, 70138fd1498Szrj __p, __r>& __x) 70238fd1498Szrj { 70338fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 70438fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 70538fd1498Szrj 70638fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 70738fd1498Szrj const _CharT __fill = __os.fill(); 70838fd1498Szrj const _CharT __space = __os.widen(' '); 70938fd1498Szrj __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 71038fd1498Szrj __os.fill(__space); 71138fd1498Szrj 71238fd1498Szrj __os << __x.base() << __space << __x._M_n; 71338fd1498Szrj 71438fd1498Szrj __os.flags(__flags); 71538fd1498Szrj __os.fill(__fill); 71638fd1498Szrj return __os; 71738fd1498Szrj } 71838fd1498Szrj 71938fd1498Szrj template<typename _RandomNumberEngine, size_t __p, size_t __r, 72038fd1498Szrj typename _CharT, typename _Traits> 72138fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,discard_block_engine<_RandomNumberEngine,__p,__r> & __x)72238fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 72338fd1498Szrj discard_block_engine<_RandomNumberEngine, __p, __r>& __x) 72438fd1498Szrj { 72538fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 72638fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 72738fd1498Szrj 72838fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 72938fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 73038fd1498Szrj 73138fd1498Szrj __is >> __x._M_b >> __x._M_n; 73238fd1498Szrj 73338fd1498Szrj __is.flags(__flags); 73438fd1498Szrj return __is; 73538fd1498Szrj } 73638fd1498Szrj 73738fd1498Szrj 73838fd1498Szrj template<typename _RandomNumberEngine, size_t __w, typename _UIntType> 73938fd1498Szrj typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: 74038fd1498Szrj result_type 74138fd1498Szrj independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: operator ()()74238fd1498Szrj operator()() 74338fd1498Szrj { 74438fd1498Szrj typedef typename _RandomNumberEngine::result_type _Eresult_type; 74538fd1498Szrj const _Eresult_type __r 74638fd1498Szrj = (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max() 74738fd1498Szrj ? _M_b.max() - _M_b.min() + 1 : 0); 74838fd1498Szrj const unsigned __edig = std::numeric_limits<_Eresult_type>::digits; 74938fd1498Szrj const unsigned __m = __r ? std::__lg(__r) : __edig; 75038fd1498Szrj 75138fd1498Szrj typedef typename std::common_type<_Eresult_type, result_type>::type 75238fd1498Szrj __ctype; 75338fd1498Szrj const unsigned __cdig = std::numeric_limits<__ctype>::digits; 75438fd1498Szrj 75538fd1498Szrj unsigned __n, __n0; 75638fd1498Szrj __ctype __s0, __s1, __y0, __y1; 75738fd1498Szrj 75838fd1498Szrj for (size_t __i = 0; __i < 2; ++__i) 75938fd1498Szrj { 76038fd1498Szrj __n = (__w + __m - 1) / __m + __i; 76138fd1498Szrj __n0 = __n - __w % __n; 76238fd1498Szrj const unsigned __w0 = __w / __n; // __w0 <= __m 76338fd1498Szrj 76438fd1498Szrj __s0 = 0; 76538fd1498Szrj __s1 = 0; 76638fd1498Szrj if (__w0 < __cdig) 76738fd1498Szrj { 76838fd1498Szrj __s0 = __ctype(1) << __w0; 76938fd1498Szrj __s1 = __s0 << 1; 77038fd1498Szrj } 77138fd1498Szrj 77238fd1498Szrj __y0 = 0; 77338fd1498Szrj __y1 = 0; 77438fd1498Szrj if (__r) 77538fd1498Szrj { 77638fd1498Szrj __y0 = __s0 * (__r / __s0); 77738fd1498Szrj if (__s1) 77838fd1498Szrj __y1 = __s1 * (__r / __s1); 77938fd1498Szrj 78038fd1498Szrj if (__r - __y0 <= __y0 / __n) 78138fd1498Szrj break; 78238fd1498Szrj } 78338fd1498Szrj else 78438fd1498Szrj break; 78538fd1498Szrj } 78638fd1498Szrj 78738fd1498Szrj result_type __sum = 0; 78838fd1498Szrj for (size_t __k = 0; __k < __n0; ++__k) 78938fd1498Szrj { 79038fd1498Szrj __ctype __u; 79138fd1498Szrj do 79238fd1498Szrj __u = _M_b() - _M_b.min(); 79338fd1498Szrj while (__y0 && __u >= __y0); 79438fd1498Szrj __sum = __s0 * __sum + (__s0 ? __u % __s0 : __u); 79538fd1498Szrj } 79638fd1498Szrj for (size_t __k = __n0; __k < __n; ++__k) 79738fd1498Szrj { 79838fd1498Szrj __ctype __u; 79938fd1498Szrj do 80038fd1498Szrj __u = _M_b() - _M_b.min(); 80138fd1498Szrj while (__y1 && __u >= __y1); 80238fd1498Szrj __sum = __s1 * __sum + (__s1 ? __u % __s1 : __u); 80338fd1498Szrj } 80438fd1498Szrj return __sum; 80538fd1498Szrj } 80638fd1498Szrj 80738fd1498Szrj 80838fd1498Szrj template<typename _RandomNumberEngine, size_t __k> 80938fd1498Szrj constexpr size_t 81038fd1498Szrj shuffle_order_engine<_RandomNumberEngine, __k>::table_size; 81138fd1498Szrj 81238fd1498Szrj template<typename _RandomNumberEngine, size_t __k> 81338fd1498Szrj typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type 81438fd1498Szrj shuffle_order_engine<_RandomNumberEngine, __k>:: operator ()()81538fd1498Szrj operator()() 81638fd1498Szrj { 81738fd1498Szrj size_t __j = __k * ((_M_y - _M_b.min()) 81838fd1498Szrj / (_M_b.max() - _M_b.min() + 1.0L)); 81938fd1498Szrj _M_y = _M_v[__j]; 82038fd1498Szrj _M_v[__j] = _M_b(); 82138fd1498Szrj 82238fd1498Szrj return _M_y; 82338fd1498Szrj } 82438fd1498Szrj 82538fd1498Szrj template<typename _RandomNumberEngine, size_t __k, 82638fd1498Szrj typename _CharT, typename _Traits> 82738fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const shuffle_order_engine<_RandomNumberEngine,__k> & __x)82838fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 82938fd1498Szrj const shuffle_order_engine<_RandomNumberEngine, __k>& __x) 83038fd1498Szrj { 83138fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 83238fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 83338fd1498Szrj 83438fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 83538fd1498Szrj const _CharT __fill = __os.fill(); 83638fd1498Szrj const _CharT __space = __os.widen(' '); 83738fd1498Szrj __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); 83838fd1498Szrj __os.fill(__space); 83938fd1498Szrj 84038fd1498Szrj __os << __x.base(); 84138fd1498Szrj for (size_t __i = 0; __i < __k; ++__i) 84238fd1498Szrj __os << __space << __x._M_v[__i]; 84338fd1498Szrj __os << __space << __x._M_y; 84438fd1498Szrj 84538fd1498Szrj __os.flags(__flags); 84638fd1498Szrj __os.fill(__fill); 84738fd1498Szrj return __os; 84838fd1498Szrj } 84938fd1498Szrj 85038fd1498Szrj template<typename _RandomNumberEngine, size_t __k, 85138fd1498Szrj typename _CharT, typename _Traits> 85238fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,shuffle_order_engine<_RandomNumberEngine,__k> & __x)85338fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 85438fd1498Szrj shuffle_order_engine<_RandomNumberEngine, __k>& __x) 85538fd1498Szrj { 85638fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 85738fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 85838fd1498Szrj 85938fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 86038fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 86138fd1498Szrj 86238fd1498Szrj __is >> __x._M_b; 86338fd1498Szrj for (size_t __i = 0; __i < __k; ++__i) 86438fd1498Szrj __is >> __x._M_v[__i]; 86538fd1498Szrj __is >> __x._M_y; 86638fd1498Szrj 86738fd1498Szrj __is.flags(__flags); 86838fd1498Szrj return __is; 86938fd1498Szrj } 87038fd1498Szrj 87138fd1498Szrj 87238fd1498Szrj template<typename _IntType, typename _CharT, typename _Traits> 87338fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const uniform_int_distribution<_IntType> & __x)87438fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 87538fd1498Szrj const uniform_int_distribution<_IntType>& __x) 87638fd1498Szrj { 87738fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 87838fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 87938fd1498Szrj 88038fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 88138fd1498Szrj const _CharT __fill = __os.fill(); 88238fd1498Szrj const _CharT __space = __os.widen(' '); 88338fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 88438fd1498Szrj __os.fill(__space); 88538fd1498Szrj 88638fd1498Szrj __os << __x.a() << __space << __x.b(); 88738fd1498Szrj 88838fd1498Szrj __os.flags(__flags); 88938fd1498Szrj __os.fill(__fill); 89038fd1498Szrj return __os; 89138fd1498Szrj } 89238fd1498Szrj 89338fd1498Szrj template<typename _IntType, typename _CharT, typename _Traits> 89438fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,uniform_int_distribution<_IntType> & __x)89538fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 89638fd1498Szrj uniform_int_distribution<_IntType>& __x) 89738fd1498Szrj { 89838fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 89938fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 90038fd1498Szrj 90138fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 90238fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 90338fd1498Szrj 90438fd1498Szrj _IntType __a, __b; 90538fd1498Szrj __is >> __a >> __b; 90638fd1498Szrj __x.param(typename uniform_int_distribution<_IntType>:: 90738fd1498Szrj param_type(__a, __b)); 90838fd1498Szrj 90938fd1498Szrj __is.flags(__flags); 91038fd1498Szrj return __is; 91138fd1498Szrj } 91238fd1498Szrj 91338fd1498Szrj 91438fd1498Szrj template<typename _RealType> 91538fd1498Szrj template<typename _ForwardIterator, 91638fd1498Szrj typename _UniformRandomNumberGenerator> 91738fd1498Szrj void 91838fd1498Szrj uniform_real_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)91938fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 92038fd1498Szrj _UniformRandomNumberGenerator& __urng, 92138fd1498Szrj const param_type& __p) 92238fd1498Szrj { 92338fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 92438fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 92538fd1498Szrj __aurng(__urng); 92638fd1498Szrj auto __range = __p.b() - __p.a(); 92738fd1498Szrj while (__f != __t) 92838fd1498Szrj *__f++ = __aurng() * __range + __p.a(); 92938fd1498Szrj } 93038fd1498Szrj 93138fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 93238fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const uniform_real_distribution<_RealType> & __x)93338fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 93438fd1498Szrj const uniform_real_distribution<_RealType>& __x) 93538fd1498Szrj { 93638fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 93738fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 93838fd1498Szrj 93938fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 94038fd1498Szrj const _CharT __fill = __os.fill(); 94138fd1498Szrj const std::streamsize __precision = __os.precision(); 94238fd1498Szrj const _CharT __space = __os.widen(' '); 94338fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 94438fd1498Szrj __os.fill(__space); 94538fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 94638fd1498Szrj 94738fd1498Szrj __os << __x.a() << __space << __x.b(); 94838fd1498Szrj 94938fd1498Szrj __os.flags(__flags); 95038fd1498Szrj __os.fill(__fill); 95138fd1498Szrj __os.precision(__precision); 95238fd1498Szrj return __os; 95338fd1498Szrj } 95438fd1498Szrj 95538fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 95638fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,uniform_real_distribution<_RealType> & __x)95738fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 95838fd1498Szrj uniform_real_distribution<_RealType>& __x) 95938fd1498Szrj { 96038fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 96138fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 96238fd1498Szrj 96338fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 96438fd1498Szrj __is.flags(__ios_base::skipws); 96538fd1498Szrj 96638fd1498Szrj _RealType __a, __b; 96738fd1498Szrj __is >> __a >> __b; 96838fd1498Szrj __x.param(typename uniform_real_distribution<_RealType>:: 96938fd1498Szrj param_type(__a, __b)); 97038fd1498Szrj 97138fd1498Szrj __is.flags(__flags); 97238fd1498Szrj return __is; 97338fd1498Szrj } 97438fd1498Szrj 97538fd1498Szrj 97638fd1498Szrj template<typename _ForwardIterator, 97738fd1498Szrj typename _UniformRandomNumberGenerator> 97838fd1498Szrj void 97938fd1498Szrj std::bernoulli_distribution:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)98038fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 98138fd1498Szrj _UniformRandomNumberGenerator& __urng, 98238fd1498Szrj const param_type& __p) 98338fd1498Szrj { 98438fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 98538fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 98638fd1498Szrj __aurng(__urng); 98738fd1498Szrj auto __limit = __p.p() * (__aurng.max() - __aurng.min()); 98838fd1498Szrj 98938fd1498Szrj while (__f != __t) 99038fd1498Szrj *__f++ = (__aurng() - __aurng.min()) < __limit; 99138fd1498Szrj } 99238fd1498Szrj 99338fd1498Szrj template<typename _CharT, typename _Traits> 99438fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const bernoulli_distribution & __x)99538fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 99638fd1498Szrj const bernoulli_distribution& __x) 99738fd1498Szrj { 99838fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 99938fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 100038fd1498Szrj 100138fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 100238fd1498Szrj const _CharT __fill = __os.fill(); 100338fd1498Szrj const std::streamsize __precision = __os.precision(); 100438fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 100538fd1498Szrj __os.fill(__os.widen(' ')); 100638fd1498Szrj __os.precision(std::numeric_limits<double>::max_digits10); 100738fd1498Szrj 100838fd1498Szrj __os << __x.p(); 100938fd1498Szrj 101038fd1498Szrj __os.flags(__flags); 101138fd1498Szrj __os.fill(__fill); 101238fd1498Szrj __os.precision(__precision); 101338fd1498Szrj return __os; 101438fd1498Szrj } 101538fd1498Szrj 101638fd1498Szrj 101738fd1498Szrj template<typename _IntType> 101838fd1498Szrj template<typename _UniformRandomNumberGenerator> 101938fd1498Szrj typename geometric_distribution<_IntType>::result_type 102038fd1498Szrj geometric_distribution<_IntType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)102138fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 102238fd1498Szrj const param_type& __param) 102338fd1498Szrj { 102438fd1498Szrj // About the epsilon thing see this thread: 102538fd1498Szrj // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html 102638fd1498Szrj const double __naf = 102738fd1498Szrj (1 - std::numeric_limits<double>::epsilon()) / 2; 102838fd1498Szrj // The largest _RealType convertible to _IntType. 102938fd1498Szrj const double __thr = 103038fd1498Szrj std::numeric_limits<_IntType>::max() + __naf; 103138fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 103238fd1498Szrj __aurng(__urng); 103338fd1498Szrj 103438fd1498Szrj double __cand; 103538fd1498Szrj do 103638fd1498Szrj __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p); 103738fd1498Szrj while (__cand >= __thr); 103838fd1498Szrj 103938fd1498Szrj return result_type(__cand + __naf); 104038fd1498Szrj } 104138fd1498Szrj 104238fd1498Szrj template<typename _IntType> 104338fd1498Szrj template<typename _ForwardIterator, 104438fd1498Szrj typename _UniformRandomNumberGenerator> 104538fd1498Szrj void 104638fd1498Szrj geometric_distribution<_IntType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)104738fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 104838fd1498Szrj _UniformRandomNumberGenerator& __urng, 104938fd1498Szrj const param_type& __param) 105038fd1498Szrj { 105138fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 105238fd1498Szrj // About the epsilon thing see this thread: 105338fd1498Szrj // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html 105438fd1498Szrj const double __naf = 105538fd1498Szrj (1 - std::numeric_limits<double>::epsilon()) / 2; 105638fd1498Szrj // The largest _RealType convertible to _IntType. 105738fd1498Szrj const double __thr = 105838fd1498Szrj std::numeric_limits<_IntType>::max() + __naf; 105938fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 106038fd1498Szrj __aurng(__urng); 106138fd1498Szrj 106238fd1498Szrj while (__f != __t) 106338fd1498Szrj { 106438fd1498Szrj double __cand; 106538fd1498Szrj do 106638fd1498Szrj __cand = std::floor(std::log(1.0 - __aurng()) 106738fd1498Szrj / __param._M_log_1_p); 106838fd1498Szrj while (__cand >= __thr); 106938fd1498Szrj 107038fd1498Szrj *__f++ = __cand + __naf; 107138fd1498Szrj } 107238fd1498Szrj } 107338fd1498Szrj 107438fd1498Szrj template<typename _IntType, 107538fd1498Szrj typename _CharT, typename _Traits> 107638fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const geometric_distribution<_IntType> & __x)107738fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 107838fd1498Szrj const geometric_distribution<_IntType>& __x) 107938fd1498Szrj { 108038fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 108138fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 108238fd1498Szrj 108338fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 108438fd1498Szrj const _CharT __fill = __os.fill(); 108538fd1498Szrj const std::streamsize __precision = __os.precision(); 108638fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 108738fd1498Szrj __os.fill(__os.widen(' ')); 108838fd1498Szrj __os.precision(std::numeric_limits<double>::max_digits10); 108938fd1498Szrj 109038fd1498Szrj __os << __x.p(); 109138fd1498Szrj 109238fd1498Szrj __os.flags(__flags); 109338fd1498Szrj __os.fill(__fill); 109438fd1498Szrj __os.precision(__precision); 109538fd1498Szrj return __os; 109638fd1498Szrj } 109738fd1498Szrj 109838fd1498Szrj template<typename _IntType, 109938fd1498Szrj typename _CharT, typename _Traits> 110038fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,geometric_distribution<_IntType> & __x)110138fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 110238fd1498Szrj geometric_distribution<_IntType>& __x) 110338fd1498Szrj { 110438fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 110538fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 110638fd1498Szrj 110738fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 110838fd1498Szrj __is.flags(__ios_base::skipws); 110938fd1498Szrj 111038fd1498Szrj double __p; 111138fd1498Szrj __is >> __p; 111238fd1498Szrj __x.param(typename geometric_distribution<_IntType>::param_type(__p)); 111338fd1498Szrj 111438fd1498Szrj __is.flags(__flags); 111538fd1498Szrj return __is; 111638fd1498Szrj } 111738fd1498Szrj 111838fd1498Szrj // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5. 111938fd1498Szrj template<typename _IntType> 112038fd1498Szrj template<typename _UniformRandomNumberGenerator> 112138fd1498Szrj typename negative_binomial_distribution<_IntType>::result_type 112238fd1498Szrj negative_binomial_distribution<_IntType>:: operator ()(_UniformRandomNumberGenerator & __urng)112338fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng) 112438fd1498Szrj { 112538fd1498Szrj const double __y = _M_gd(__urng); 112638fd1498Szrj 112738fd1498Szrj // XXX Is the constructor too slow? 112838fd1498Szrj std::poisson_distribution<result_type> __poisson(__y); 112938fd1498Szrj return __poisson(__urng); 113038fd1498Szrj } 113138fd1498Szrj 113238fd1498Szrj template<typename _IntType> 113338fd1498Szrj template<typename _UniformRandomNumberGenerator> 113438fd1498Szrj typename negative_binomial_distribution<_IntType>::result_type 113538fd1498Szrj negative_binomial_distribution<_IntType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)113638fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 113738fd1498Szrj const param_type& __p) 113838fd1498Szrj { 113938fd1498Szrj typedef typename std::gamma_distribution<double>::param_type 114038fd1498Szrj param_type; 114138fd1498Szrj 114238fd1498Szrj const double __y = 114338fd1498Szrj _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p())); 114438fd1498Szrj 114538fd1498Szrj std::poisson_distribution<result_type> __poisson(__y); 114638fd1498Szrj return __poisson(__urng); 114738fd1498Szrj } 114838fd1498Szrj 114938fd1498Szrj template<typename _IntType> 115038fd1498Szrj template<typename _ForwardIterator, 115138fd1498Szrj typename _UniformRandomNumberGenerator> 115238fd1498Szrj void 115338fd1498Szrj negative_binomial_distribution<_IntType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)115438fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 115538fd1498Szrj _UniformRandomNumberGenerator& __urng) 115638fd1498Szrj { 115738fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 115838fd1498Szrj while (__f != __t) 115938fd1498Szrj { 116038fd1498Szrj const double __y = _M_gd(__urng); 116138fd1498Szrj 116238fd1498Szrj // XXX Is the constructor too slow? 116338fd1498Szrj std::poisson_distribution<result_type> __poisson(__y); 116438fd1498Szrj *__f++ = __poisson(__urng); 116538fd1498Szrj } 116638fd1498Szrj } 116738fd1498Szrj 116838fd1498Szrj template<typename _IntType> 116938fd1498Szrj template<typename _ForwardIterator, 117038fd1498Szrj typename _UniformRandomNumberGenerator> 117138fd1498Szrj void 117238fd1498Szrj negative_binomial_distribution<_IntType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)117338fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 117438fd1498Szrj _UniformRandomNumberGenerator& __urng, 117538fd1498Szrj const param_type& __p) 117638fd1498Szrj { 117738fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 117838fd1498Szrj typename std::gamma_distribution<result_type>::param_type 117938fd1498Szrj __p2(__p.k(), (1.0 - __p.p()) / __p.p()); 118038fd1498Szrj 118138fd1498Szrj while (__f != __t) 118238fd1498Szrj { 118338fd1498Szrj const double __y = _M_gd(__urng, __p2); 118438fd1498Szrj 118538fd1498Szrj std::poisson_distribution<result_type> __poisson(__y); 118638fd1498Szrj *__f++ = __poisson(__urng); 118738fd1498Szrj } 118838fd1498Szrj } 118938fd1498Szrj 119038fd1498Szrj template<typename _IntType, typename _CharT, typename _Traits> 119138fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const negative_binomial_distribution<_IntType> & __x)119238fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 119338fd1498Szrj const negative_binomial_distribution<_IntType>& __x) 119438fd1498Szrj { 119538fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 119638fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 119738fd1498Szrj 119838fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 119938fd1498Szrj const _CharT __fill = __os.fill(); 120038fd1498Szrj const std::streamsize __precision = __os.precision(); 120138fd1498Szrj const _CharT __space = __os.widen(' '); 120238fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 120338fd1498Szrj __os.fill(__os.widen(' ')); 120438fd1498Szrj __os.precision(std::numeric_limits<double>::max_digits10); 120538fd1498Szrj 120638fd1498Szrj __os << __x.k() << __space << __x.p() 120738fd1498Szrj << __space << __x._M_gd; 120838fd1498Szrj 120938fd1498Szrj __os.flags(__flags); 121038fd1498Szrj __os.fill(__fill); 121138fd1498Szrj __os.precision(__precision); 121238fd1498Szrj return __os; 121338fd1498Szrj } 121438fd1498Szrj 121538fd1498Szrj template<typename _IntType, typename _CharT, typename _Traits> 121638fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,negative_binomial_distribution<_IntType> & __x)121738fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 121838fd1498Szrj negative_binomial_distribution<_IntType>& __x) 121938fd1498Szrj { 122038fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 122138fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 122238fd1498Szrj 122338fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 122438fd1498Szrj __is.flags(__ios_base::skipws); 122538fd1498Szrj 122638fd1498Szrj _IntType __k; 122738fd1498Szrj double __p; 122838fd1498Szrj __is >> __k >> __p >> __x._M_gd; 122938fd1498Szrj __x.param(typename negative_binomial_distribution<_IntType>:: 123038fd1498Szrj param_type(__k, __p)); 123138fd1498Szrj 123238fd1498Szrj __is.flags(__flags); 123338fd1498Szrj return __is; 123438fd1498Szrj } 123538fd1498Szrj 123638fd1498Szrj 123738fd1498Szrj template<typename _IntType> 123838fd1498Szrj void 123938fd1498Szrj poisson_distribution<_IntType>::param_type:: _M_initialize()124038fd1498Szrj _M_initialize() 124138fd1498Szrj { 124238fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1 124338fd1498Szrj if (_M_mean >= 12) 124438fd1498Szrj { 124538fd1498Szrj const double __m = std::floor(_M_mean); 124638fd1498Szrj _M_lm_thr = std::log(_M_mean); 124738fd1498Szrj _M_lfm = std::lgamma(__m + 1); 124838fd1498Szrj _M_sm = std::sqrt(__m); 124938fd1498Szrj 125038fd1498Szrj const double __pi_4 = 0.7853981633974483096156608458198757L; 125138fd1498Szrj const double __dx = std::sqrt(2 * __m * std::log(32 * __m 125238fd1498Szrj / __pi_4)); 125338fd1498Szrj _M_d = std::round(std::max<double>(6.0, std::min(__m, __dx))); 125438fd1498Szrj const double __cx = 2 * __m + _M_d; 125538fd1498Szrj _M_scx = std::sqrt(__cx / 2); 125638fd1498Szrj _M_1cx = 1 / __cx; 125738fd1498Szrj 125838fd1498Szrj _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx); 125938fd1498Szrj _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) 126038fd1498Szrj / _M_d; 126138fd1498Szrj } 126238fd1498Szrj else 126338fd1498Szrj #endif 126438fd1498Szrj _M_lm_thr = std::exp(-_M_mean); 126538fd1498Szrj } 126638fd1498Szrj 126738fd1498Szrj /** 126838fd1498Szrj * A rejection algorithm when mean >= 12 and a simple method based 126938fd1498Szrj * upon the multiplication of uniform random variates otherwise. 127038fd1498Szrj * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 127138fd1498Szrj * is defined. 127238fd1498Szrj * 127338fd1498Szrj * Reference: 127438fd1498Szrj * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 127538fd1498Szrj * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!). 127638fd1498Szrj */ 127738fd1498Szrj template<typename _IntType> 127838fd1498Szrj template<typename _UniformRandomNumberGenerator> 127938fd1498Szrj typename poisson_distribution<_IntType>::result_type 128038fd1498Szrj poisson_distribution<_IntType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)128138fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 128238fd1498Szrj const param_type& __param) 128338fd1498Szrj { 128438fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 128538fd1498Szrj __aurng(__urng); 128638fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1 128738fd1498Szrj if (__param.mean() >= 12) 128838fd1498Szrj { 128938fd1498Szrj double __x; 129038fd1498Szrj 129138fd1498Szrj // See comments above... 129238fd1498Szrj const double __naf = 129338fd1498Szrj (1 - std::numeric_limits<double>::epsilon()) / 2; 129438fd1498Szrj const double __thr = 129538fd1498Szrj std::numeric_limits<_IntType>::max() + __naf; 129638fd1498Szrj 129738fd1498Szrj const double __m = std::floor(__param.mean()); 129838fd1498Szrj // sqrt(pi / 2) 129938fd1498Szrj const double __spi_2 = 1.2533141373155002512078826424055226L; 130038fd1498Szrj const double __c1 = __param._M_sm * __spi_2; 130138fd1498Szrj const double __c2 = __param._M_c2b + __c1; 130238fd1498Szrj const double __c3 = __c2 + 1; 130338fd1498Szrj const double __c4 = __c3 + 1; 130438fd1498Szrj // 1 / 78 130538fd1498Szrj const double __178 = 0.0128205128205128205128205128205128L; 130638fd1498Szrj // e^(1 / 78) 130738fd1498Szrj const double __e178 = 1.0129030479320018583185514777512983L; 130838fd1498Szrj const double __c5 = __c4 + __e178; 130938fd1498Szrj const double __c = __param._M_cb + __c5; 131038fd1498Szrj const double __2cx = 2 * (2 * __m + __param._M_d); 131138fd1498Szrj 131238fd1498Szrj bool __reject = true; 131338fd1498Szrj do 131438fd1498Szrj { 131538fd1498Szrj const double __u = __c * __aurng(); 131638fd1498Szrj const double __e = -std::log(1.0 - __aurng()); 131738fd1498Szrj 131838fd1498Szrj double __w = 0.0; 131938fd1498Szrj 132038fd1498Szrj if (__u <= __c1) 132138fd1498Szrj { 132238fd1498Szrj const double __n = _M_nd(__urng); 132338fd1498Szrj const double __y = -std::abs(__n) * __param._M_sm - 1; 132438fd1498Szrj __x = std::floor(__y); 132538fd1498Szrj __w = -__n * __n / 2; 132638fd1498Szrj if (__x < -__m) 132738fd1498Szrj continue; 132838fd1498Szrj } 132938fd1498Szrj else if (__u <= __c2) 133038fd1498Szrj { 133138fd1498Szrj const double __n = _M_nd(__urng); 133238fd1498Szrj const double __y = 1 + std::abs(__n) * __param._M_scx; 133338fd1498Szrj __x = std::ceil(__y); 133438fd1498Szrj __w = __y * (2 - __y) * __param._M_1cx; 133538fd1498Szrj if (__x > __param._M_d) 133638fd1498Szrj continue; 133738fd1498Szrj } 133838fd1498Szrj else if (__u <= __c3) 133938fd1498Szrj // NB: This case not in the book, nor in the Errata, 134038fd1498Szrj // but should be ok... 134138fd1498Szrj __x = -1; 134238fd1498Szrj else if (__u <= __c4) 134338fd1498Szrj __x = 0; 134438fd1498Szrj else if (__u <= __c5) 134538fd1498Szrj { 134638fd1498Szrj __x = 1; 134738fd1498Szrj // Only in the Errata, see libstdc++/83237. 134838fd1498Szrj __w = __178; 134938fd1498Szrj } 135038fd1498Szrj else 135138fd1498Szrj { 135238fd1498Szrj const double __v = -std::log(1.0 - __aurng()); 135338fd1498Szrj const double __y = __param._M_d 135438fd1498Szrj + __v * __2cx / __param._M_d; 135538fd1498Szrj __x = std::ceil(__y); 135638fd1498Szrj __w = -__param._M_d * __param._M_1cx * (1 + __y / 2); 135738fd1498Szrj } 135838fd1498Szrj 135938fd1498Szrj __reject = (__w - __e - __x * __param._M_lm_thr 136038fd1498Szrj > __param._M_lfm - std::lgamma(__x + __m + 1)); 136138fd1498Szrj 136238fd1498Szrj __reject |= __x + __m >= __thr; 136338fd1498Szrj 136438fd1498Szrj } while (__reject); 136538fd1498Szrj 136638fd1498Szrj return result_type(__x + __m + __naf); 136738fd1498Szrj } 136838fd1498Szrj else 136938fd1498Szrj #endif 137038fd1498Szrj { 137138fd1498Szrj _IntType __x = 0; 137238fd1498Szrj double __prod = 1.0; 137338fd1498Szrj 137438fd1498Szrj do 137538fd1498Szrj { 137638fd1498Szrj __prod *= __aurng(); 137738fd1498Szrj __x += 1; 137838fd1498Szrj } 137938fd1498Szrj while (__prod > __param._M_lm_thr); 138038fd1498Szrj 138138fd1498Szrj return __x - 1; 138238fd1498Szrj } 138338fd1498Szrj } 138438fd1498Szrj 138538fd1498Szrj template<typename _IntType> 138638fd1498Szrj template<typename _ForwardIterator, 138738fd1498Szrj typename _UniformRandomNumberGenerator> 138838fd1498Szrj void 138938fd1498Szrj poisson_distribution<_IntType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)139038fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 139138fd1498Szrj _UniformRandomNumberGenerator& __urng, 139238fd1498Szrj const param_type& __param) 139338fd1498Szrj { 139438fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 139538fd1498Szrj // We could duplicate everything from operator()... 139638fd1498Szrj while (__f != __t) 139738fd1498Szrj *__f++ = this->operator()(__urng, __param); 139838fd1498Szrj } 139938fd1498Szrj 140038fd1498Szrj template<typename _IntType, 140138fd1498Szrj typename _CharT, typename _Traits> 140238fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const poisson_distribution<_IntType> & __x)140338fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 140438fd1498Szrj const poisson_distribution<_IntType>& __x) 140538fd1498Szrj { 140638fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 140738fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 140838fd1498Szrj 140938fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 141038fd1498Szrj const _CharT __fill = __os.fill(); 141138fd1498Szrj const std::streamsize __precision = __os.precision(); 141238fd1498Szrj const _CharT __space = __os.widen(' '); 141338fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 141438fd1498Szrj __os.fill(__space); 141538fd1498Szrj __os.precision(std::numeric_limits<double>::max_digits10); 141638fd1498Szrj 141738fd1498Szrj __os << __x.mean() << __space << __x._M_nd; 141838fd1498Szrj 141938fd1498Szrj __os.flags(__flags); 142038fd1498Szrj __os.fill(__fill); 142138fd1498Szrj __os.precision(__precision); 142238fd1498Szrj return __os; 142338fd1498Szrj } 142438fd1498Szrj 142538fd1498Szrj template<typename _IntType, 142638fd1498Szrj typename _CharT, typename _Traits> 142738fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,poisson_distribution<_IntType> & __x)142838fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 142938fd1498Szrj poisson_distribution<_IntType>& __x) 143038fd1498Szrj { 143138fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 143238fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 143338fd1498Szrj 143438fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 143538fd1498Szrj __is.flags(__ios_base::skipws); 143638fd1498Szrj 143738fd1498Szrj double __mean; 143838fd1498Szrj __is >> __mean >> __x._M_nd; 143938fd1498Szrj __x.param(typename poisson_distribution<_IntType>::param_type(__mean)); 144038fd1498Szrj 144138fd1498Szrj __is.flags(__flags); 144238fd1498Szrj return __is; 144338fd1498Szrj } 144438fd1498Szrj 144538fd1498Szrj 144638fd1498Szrj template<typename _IntType> 144738fd1498Szrj void 144838fd1498Szrj binomial_distribution<_IntType>::param_type:: _M_initialize()144938fd1498Szrj _M_initialize() 145038fd1498Szrj { 145138fd1498Szrj const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; 145238fd1498Szrj 145338fd1498Szrj _M_easy = true; 145438fd1498Szrj 145538fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1 145638fd1498Szrj if (_M_t * __p12 >= 8) 145738fd1498Szrj { 145838fd1498Szrj _M_easy = false; 145938fd1498Szrj const double __np = std::floor(_M_t * __p12); 146038fd1498Szrj const double __pa = __np / _M_t; 146138fd1498Szrj const double __1p = 1 - __pa; 146238fd1498Szrj 146338fd1498Szrj const double __pi_4 = 0.7853981633974483096156608458198757L; 146438fd1498Szrj const double __d1x = 146538fd1498Szrj std::sqrt(__np * __1p * std::log(32 * __np 146638fd1498Szrj / (81 * __pi_4 * __1p))); 146738fd1498Szrj _M_d1 = std::round(std::max<double>(1.0, __d1x)); 146838fd1498Szrj const double __d2x = 146938fd1498Szrj std::sqrt(__np * __1p * std::log(32 * _M_t * __1p 147038fd1498Szrj / (__pi_4 * __pa))); 147138fd1498Szrj _M_d2 = std::round(std::max<double>(1.0, __d2x)); 147238fd1498Szrj 147338fd1498Szrj // sqrt(pi / 2) 147438fd1498Szrj const double __spi_2 = 1.2533141373155002512078826424055226L; 147538fd1498Szrj _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np)); 147638fd1498Szrj _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p)); 147738fd1498Szrj _M_c = 2 * _M_d1 / __np; 147838fd1498Szrj _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2; 147938fd1498Szrj const double __a12 = _M_a1 + _M_s2 * __spi_2; 148038fd1498Szrj const double __s1s = _M_s1 * _M_s1; 148138fd1498Szrj _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p)) 148238fd1498Szrj * 2 * __s1s / _M_d1 148338fd1498Szrj * std::exp(-_M_d1 * _M_d1 / (2 * __s1s))); 148438fd1498Szrj const double __s2s = _M_s2 * _M_s2; 148538fd1498Szrj _M_s = (_M_a123 + 2 * __s2s / _M_d2 148638fd1498Szrj * std::exp(-_M_d2 * _M_d2 / (2 * __s2s))); 148738fd1498Szrj _M_lf = (std::lgamma(__np + 1) 148838fd1498Szrj + std::lgamma(_M_t - __np + 1)); 148938fd1498Szrj _M_lp1p = std::log(__pa / __1p); 149038fd1498Szrj 149138fd1498Szrj _M_q = -std::log(1 - (__p12 - __pa) / __1p); 149238fd1498Szrj } 149338fd1498Szrj else 149438fd1498Szrj #endif 149538fd1498Szrj _M_q = -std::log(1 - __p12); 149638fd1498Szrj } 149738fd1498Szrj 149838fd1498Szrj template<typename _IntType> 149938fd1498Szrj template<typename _UniformRandomNumberGenerator> 150038fd1498Szrj typename binomial_distribution<_IntType>::result_type 150138fd1498Szrj binomial_distribution<_IntType>:: _M_waiting(_UniformRandomNumberGenerator & __urng,_IntType __t,double __q)150238fd1498Szrj _M_waiting(_UniformRandomNumberGenerator& __urng, 150338fd1498Szrj _IntType __t, double __q) 150438fd1498Szrj { 150538fd1498Szrj _IntType __x = 0; 150638fd1498Szrj double __sum = 0.0; 150738fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 150838fd1498Szrj __aurng(__urng); 150938fd1498Szrj 151038fd1498Szrj do 151138fd1498Szrj { 151238fd1498Szrj if (__t == __x) 151338fd1498Szrj return __x; 151438fd1498Szrj const double __e = -std::log(1.0 - __aurng()); 151538fd1498Szrj __sum += __e / (__t - __x); 151638fd1498Szrj __x += 1; 151738fd1498Szrj } 151838fd1498Szrj while (__sum <= __q); 151938fd1498Szrj 152038fd1498Szrj return __x - 1; 152138fd1498Szrj } 152238fd1498Szrj 152338fd1498Szrj /** 152438fd1498Szrj * A rejection algorithm when t * p >= 8 and a simple waiting time 152538fd1498Szrj * method - the second in the referenced book - otherwise. 152638fd1498Szrj * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 152738fd1498Szrj * is defined. 152838fd1498Szrj * 152938fd1498Szrj * Reference: 153038fd1498Szrj * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 153138fd1498Szrj * New York, 1986, Ch. X, Sect. 4 (+ Errata!). 153238fd1498Szrj */ 153338fd1498Szrj template<typename _IntType> 153438fd1498Szrj template<typename _UniformRandomNumberGenerator> 153538fd1498Szrj typename binomial_distribution<_IntType>::result_type 153638fd1498Szrj binomial_distribution<_IntType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)153738fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 153838fd1498Szrj const param_type& __param) 153938fd1498Szrj { 154038fd1498Szrj result_type __ret; 154138fd1498Szrj const _IntType __t = __param.t(); 154238fd1498Szrj const double __p = __param.p(); 154338fd1498Szrj const double __p12 = __p <= 0.5 ? __p : 1.0 - __p; 154438fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 154538fd1498Szrj __aurng(__urng); 154638fd1498Szrj 154738fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1 154838fd1498Szrj if (!__param._M_easy) 154938fd1498Szrj { 155038fd1498Szrj double __x; 155138fd1498Szrj 155238fd1498Szrj // See comments above... 155338fd1498Szrj const double __naf = 155438fd1498Szrj (1 - std::numeric_limits<double>::epsilon()) / 2; 155538fd1498Szrj const double __thr = 155638fd1498Szrj std::numeric_limits<_IntType>::max() + __naf; 155738fd1498Szrj 155838fd1498Szrj const double __np = std::floor(__t * __p12); 155938fd1498Szrj 156038fd1498Szrj // sqrt(pi / 2) 156138fd1498Szrj const double __spi_2 = 1.2533141373155002512078826424055226L; 156238fd1498Szrj const double __a1 = __param._M_a1; 156338fd1498Szrj const double __a12 = __a1 + __param._M_s2 * __spi_2; 156438fd1498Szrj const double __a123 = __param._M_a123; 156538fd1498Szrj const double __s1s = __param._M_s1 * __param._M_s1; 156638fd1498Szrj const double __s2s = __param._M_s2 * __param._M_s2; 156738fd1498Szrj 156838fd1498Szrj bool __reject; 156938fd1498Szrj do 157038fd1498Szrj { 157138fd1498Szrj const double __u = __param._M_s * __aurng(); 157238fd1498Szrj 157338fd1498Szrj double __v; 157438fd1498Szrj 157538fd1498Szrj if (__u <= __a1) 157638fd1498Szrj { 157738fd1498Szrj const double __n = _M_nd(__urng); 157838fd1498Szrj const double __y = __param._M_s1 * std::abs(__n); 157938fd1498Szrj __reject = __y >= __param._M_d1; 158038fd1498Szrj if (!__reject) 158138fd1498Szrj { 158238fd1498Szrj const double __e = -std::log(1.0 - __aurng()); 158338fd1498Szrj __x = std::floor(__y); 158438fd1498Szrj __v = -__e - __n * __n / 2 + __param._M_c; 158538fd1498Szrj } 158638fd1498Szrj } 158738fd1498Szrj else if (__u <= __a12) 158838fd1498Szrj { 158938fd1498Szrj const double __n = _M_nd(__urng); 159038fd1498Szrj const double __y = __param._M_s2 * std::abs(__n); 159138fd1498Szrj __reject = __y >= __param._M_d2; 159238fd1498Szrj if (!__reject) 159338fd1498Szrj { 159438fd1498Szrj const double __e = -std::log(1.0 - __aurng()); 159538fd1498Szrj __x = std::floor(-__y); 159638fd1498Szrj __v = -__e - __n * __n / 2; 159738fd1498Szrj } 159838fd1498Szrj } 159938fd1498Szrj else if (__u <= __a123) 160038fd1498Szrj { 160138fd1498Szrj const double __e1 = -std::log(1.0 - __aurng()); 160238fd1498Szrj const double __e2 = -std::log(1.0 - __aurng()); 160338fd1498Szrj 160438fd1498Szrj const double __y = __param._M_d1 160538fd1498Szrj + 2 * __s1s * __e1 / __param._M_d1; 160638fd1498Szrj __x = std::floor(__y); 160738fd1498Szrj __v = (-__e2 + __param._M_d1 * (1 / (__t - __np) 160838fd1498Szrj -__y / (2 * __s1s))); 160938fd1498Szrj __reject = false; 161038fd1498Szrj } 161138fd1498Szrj else 161238fd1498Szrj { 161338fd1498Szrj const double __e1 = -std::log(1.0 - __aurng()); 161438fd1498Szrj const double __e2 = -std::log(1.0 - __aurng()); 161538fd1498Szrj 161638fd1498Szrj const double __y = __param._M_d2 161738fd1498Szrj + 2 * __s2s * __e1 / __param._M_d2; 161838fd1498Szrj __x = std::floor(-__y); 161938fd1498Szrj __v = -__e2 - __param._M_d2 * __y / (2 * __s2s); 162038fd1498Szrj __reject = false; 162138fd1498Szrj } 162238fd1498Szrj 162338fd1498Szrj __reject = __reject || __x < -__np || __x > __t - __np; 162438fd1498Szrj if (!__reject) 162538fd1498Szrj { 162638fd1498Szrj const double __lfx = 162738fd1498Szrj std::lgamma(__np + __x + 1) 162838fd1498Szrj + std::lgamma(__t - (__np + __x) + 1); 162938fd1498Szrj __reject = __v > __param._M_lf - __lfx 163038fd1498Szrj + __x * __param._M_lp1p; 163138fd1498Szrj } 163238fd1498Szrj 163338fd1498Szrj __reject |= __x + __np >= __thr; 163438fd1498Szrj } 163538fd1498Szrj while (__reject); 163638fd1498Szrj 163738fd1498Szrj __x += __np + __naf; 163838fd1498Szrj 163938fd1498Szrj const _IntType __z = _M_waiting(__urng, __t - _IntType(__x), 164038fd1498Szrj __param._M_q); 164138fd1498Szrj __ret = _IntType(__x) + __z; 164238fd1498Szrj } 164338fd1498Szrj else 164438fd1498Szrj #endif 164538fd1498Szrj __ret = _M_waiting(__urng, __t, __param._M_q); 164638fd1498Szrj 164738fd1498Szrj if (__p12 != __p) 164838fd1498Szrj __ret = __t - __ret; 164938fd1498Szrj return __ret; 165038fd1498Szrj } 165138fd1498Szrj 165238fd1498Szrj template<typename _IntType> 165338fd1498Szrj template<typename _ForwardIterator, 165438fd1498Szrj typename _UniformRandomNumberGenerator> 165538fd1498Szrj void 165638fd1498Szrj binomial_distribution<_IntType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)165738fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 165838fd1498Szrj _UniformRandomNumberGenerator& __urng, 165938fd1498Szrj const param_type& __param) 166038fd1498Szrj { 166138fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 166238fd1498Szrj // We could duplicate everything from operator()... 166338fd1498Szrj while (__f != __t) 166438fd1498Szrj *__f++ = this->operator()(__urng, __param); 166538fd1498Szrj } 166638fd1498Szrj 166738fd1498Szrj template<typename _IntType, 166838fd1498Szrj typename _CharT, typename _Traits> 166938fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const binomial_distribution<_IntType> & __x)167038fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 167138fd1498Szrj const binomial_distribution<_IntType>& __x) 167238fd1498Szrj { 167338fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 167438fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 167538fd1498Szrj 167638fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 167738fd1498Szrj const _CharT __fill = __os.fill(); 167838fd1498Szrj const std::streamsize __precision = __os.precision(); 167938fd1498Szrj const _CharT __space = __os.widen(' '); 168038fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 168138fd1498Szrj __os.fill(__space); 168238fd1498Szrj __os.precision(std::numeric_limits<double>::max_digits10); 168338fd1498Szrj 168438fd1498Szrj __os << __x.t() << __space << __x.p() 168538fd1498Szrj << __space << __x._M_nd; 168638fd1498Szrj 168738fd1498Szrj __os.flags(__flags); 168838fd1498Szrj __os.fill(__fill); 168938fd1498Szrj __os.precision(__precision); 169038fd1498Szrj return __os; 169138fd1498Szrj } 169238fd1498Szrj 169338fd1498Szrj template<typename _IntType, 169438fd1498Szrj typename _CharT, typename _Traits> 169538fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,binomial_distribution<_IntType> & __x)169638fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 169738fd1498Szrj binomial_distribution<_IntType>& __x) 169838fd1498Szrj { 169938fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 170038fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 170138fd1498Szrj 170238fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 170338fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 170438fd1498Szrj 170538fd1498Szrj _IntType __t; 170638fd1498Szrj double __p; 170738fd1498Szrj __is >> __t >> __p >> __x._M_nd; 170838fd1498Szrj __x.param(typename binomial_distribution<_IntType>:: 170938fd1498Szrj param_type(__t, __p)); 171038fd1498Szrj 171138fd1498Szrj __is.flags(__flags); 171238fd1498Szrj return __is; 171338fd1498Szrj } 171438fd1498Szrj 171538fd1498Szrj 171638fd1498Szrj template<typename _RealType> 171738fd1498Szrj template<typename _ForwardIterator, 171838fd1498Szrj typename _UniformRandomNumberGenerator> 171938fd1498Szrj void 172038fd1498Szrj std::exponential_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)172138fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 172238fd1498Szrj _UniformRandomNumberGenerator& __urng, 172338fd1498Szrj const param_type& __p) 172438fd1498Szrj { 172538fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 172638fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 172738fd1498Szrj __aurng(__urng); 172838fd1498Szrj while (__f != __t) 172938fd1498Szrj *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda(); 173038fd1498Szrj } 173138fd1498Szrj 173238fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 173338fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const exponential_distribution<_RealType> & __x)173438fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 173538fd1498Szrj const exponential_distribution<_RealType>& __x) 173638fd1498Szrj { 173738fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 173838fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 173938fd1498Szrj 174038fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 174138fd1498Szrj const _CharT __fill = __os.fill(); 174238fd1498Szrj const std::streamsize __precision = __os.precision(); 174338fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 174438fd1498Szrj __os.fill(__os.widen(' ')); 174538fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 174638fd1498Szrj 174738fd1498Szrj __os << __x.lambda(); 174838fd1498Szrj 174938fd1498Szrj __os.flags(__flags); 175038fd1498Szrj __os.fill(__fill); 175138fd1498Szrj __os.precision(__precision); 175238fd1498Szrj return __os; 175338fd1498Szrj } 175438fd1498Szrj 175538fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 175638fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,exponential_distribution<_RealType> & __x)175738fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 175838fd1498Szrj exponential_distribution<_RealType>& __x) 175938fd1498Szrj { 176038fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 176138fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 176238fd1498Szrj 176338fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 176438fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 176538fd1498Szrj 176638fd1498Szrj _RealType __lambda; 176738fd1498Szrj __is >> __lambda; 176838fd1498Szrj __x.param(typename exponential_distribution<_RealType>:: 176938fd1498Szrj param_type(__lambda)); 177038fd1498Szrj 177138fd1498Szrj __is.flags(__flags); 177238fd1498Szrj return __is; 177338fd1498Szrj } 177438fd1498Szrj 177538fd1498Szrj 177638fd1498Szrj /** 177738fd1498Szrj * Polar method due to Marsaglia. 177838fd1498Szrj * 177938fd1498Szrj * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, 178038fd1498Szrj * New York, 1986, Ch. V, Sect. 4.4. 178138fd1498Szrj */ 178238fd1498Szrj template<typename _RealType> 178338fd1498Szrj template<typename _UniformRandomNumberGenerator> 178438fd1498Szrj typename normal_distribution<_RealType>::result_type 178538fd1498Szrj normal_distribution<_RealType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)178638fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 178738fd1498Szrj const param_type& __param) 178838fd1498Szrj { 178938fd1498Szrj result_type __ret; 179038fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 179138fd1498Szrj __aurng(__urng); 179238fd1498Szrj 179338fd1498Szrj if (_M_saved_available) 179438fd1498Szrj { 179538fd1498Szrj _M_saved_available = false; 179638fd1498Szrj __ret = _M_saved; 179738fd1498Szrj } 179838fd1498Szrj else 179938fd1498Szrj { 180038fd1498Szrj result_type __x, __y, __r2; 180138fd1498Szrj do 180238fd1498Szrj { 180338fd1498Szrj __x = result_type(2.0) * __aurng() - 1.0; 180438fd1498Szrj __y = result_type(2.0) * __aurng() - 1.0; 180538fd1498Szrj __r2 = __x * __x + __y * __y; 180638fd1498Szrj } 180738fd1498Szrj while (__r2 > 1.0 || __r2 == 0.0); 180838fd1498Szrj 180938fd1498Szrj const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 181038fd1498Szrj _M_saved = __x * __mult; 181138fd1498Szrj _M_saved_available = true; 181238fd1498Szrj __ret = __y * __mult; 181338fd1498Szrj } 181438fd1498Szrj 181538fd1498Szrj __ret = __ret * __param.stddev() + __param.mean(); 181638fd1498Szrj return __ret; 181738fd1498Szrj } 181838fd1498Szrj 181938fd1498Szrj template<typename _RealType> 182038fd1498Szrj template<typename _ForwardIterator, 182138fd1498Szrj typename _UniformRandomNumberGenerator> 182238fd1498Szrj void 182338fd1498Szrj normal_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)182438fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 182538fd1498Szrj _UniformRandomNumberGenerator& __urng, 182638fd1498Szrj const param_type& __param) 182738fd1498Szrj { 182838fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 182938fd1498Szrj 183038fd1498Szrj if (__f == __t) 183138fd1498Szrj return; 183238fd1498Szrj 183338fd1498Szrj if (_M_saved_available) 183438fd1498Szrj { 183538fd1498Szrj _M_saved_available = false; 183638fd1498Szrj *__f++ = _M_saved * __param.stddev() + __param.mean(); 183738fd1498Szrj 183838fd1498Szrj if (__f == __t) 183938fd1498Szrj return; 184038fd1498Szrj } 184138fd1498Szrj 184238fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 184338fd1498Szrj __aurng(__urng); 184438fd1498Szrj 184538fd1498Szrj while (__f + 1 < __t) 184638fd1498Szrj { 184738fd1498Szrj result_type __x, __y, __r2; 184838fd1498Szrj do 184938fd1498Szrj { 185038fd1498Szrj __x = result_type(2.0) * __aurng() - 1.0; 185138fd1498Szrj __y = result_type(2.0) * __aurng() - 1.0; 185238fd1498Szrj __r2 = __x * __x + __y * __y; 185338fd1498Szrj } 185438fd1498Szrj while (__r2 > 1.0 || __r2 == 0.0); 185538fd1498Szrj 185638fd1498Szrj const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 185738fd1498Szrj *__f++ = __y * __mult * __param.stddev() + __param.mean(); 185838fd1498Szrj *__f++ = __x * __mult * __param.stddev() + __param.mean(); 185938fd1498Szrj } 186038fd1498Szrj 186138fd1498Szrj if (__f != __t) 186238fd1498Szrj { 186338fd1498Szrj result_type __x, __y, __r2; 186438fd1498Szrj do 186538fd1498Szrj { 186638fd1498Szrj __x = result_type(2.0) * __aurng() - 1.0; 186738fd1498Szrj __y = result_type(2.0) * __aurng() - 1.0; 186838fd1498Szrj __r2 = __x * __x + __y * __y; 186938fd1498Szrj } 187038fd1498Szrj while (__r2 > 1.0 || __r2 == 0.0); 187138fd1498Szrj 187238fd1498Szrj const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); 187338fd1498Szrj _M_saved = __x * __mult; 187438fd1498Szrj _M_saved_available = true; 187538fd1498Szrj *__f = __y * __mult * __param.stddev() + __param.mean(); 187638fd1498Szrj } 187738fd1498Szrj } 187838fd1498Szrj 187938fd1498Szrj template<typename _RealType> 188038fd1498Szrj bool operator ==(const std::normal_distribution<_RealType> & __d1,const std::normal_distribution<_RealType> & __d2)188138fd1498Szrj operator==(const std::normal_distribution<_RealType>& __d1, 188238fd1498Szrj const std::normal_distribution<_RealType>& __d2) 188338fd1498Szrj { 188438fd1498Szrj if (__d1._M_param == __d2._M_param 188538fd1498Szrj && __d1._M_saved_available == __d2._M_saved_available) 188638fd1498Szrj { 188738fd1498Szrj if (__d1._M_saved_available 188838fd1498Szrj && __d1._M_saved == __d2._M_saved) 188938fd1498Szrj return true; 189038fd1498Szrj else if(!__d1._M_saved_available) 189138fd1498Szrj return true; 189238fd1498Szrj else 189338fd1498Szrj return false; 189438fd1498Szrj } 189538fd1498Szrj else 189638fd1498Szrj return false; 189738fd1498Szrj } 189838fd1498Szrj 189938fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 190038fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const normal_distribution<_RealType> & __x)190138fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 190238fd1498Szrj const normal_distribution<_RealType>& __x) 190338fd1498Szrj { 190438fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 190538fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 190638fd1498Szrj 190738fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 190838fd1498Szrj const _CharT __fill = __os.fill(); 190938fd1498Szrj const std::streamsize __precision = __os.precision(); 191038fd1498Szrj const _CharT __space = __os.widen(' '); 191138fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 191238fd1498Szrj __os.fill(__space); 191338fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 191438fd1498Szrj 191538fd1498Szrj __os << __x.mean() << __space << __x.stddev() 191638fd1498Szrj << __space << __x._M_saved_available; 191738fd1498Szrj if (__x._M_saved_available) 191838fd1498Szrj __os << __space << __x._M_saved; 191938fd1498Szrj 192038fd1498Szrj __os.flags(__flags); 192138fd1498Szrj __os.fill(__fill); 192238fd1498Szrj __os.precision(__precision); 192338fd1498Szrj return __os; 192438fd1498Szrj } 192538fd1498Szrj 192638fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 192738fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,normal_distribution<_RealType> & __x)192838fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 192938fd1498Szrj normal_distribution<_RealType>& __x) 193038fd1498Szrj { 193138fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 193238fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 193338fd1498Szrj 193438fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 193538fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 193638fd1498Szrj 193738fd1498Szrj double __mean, __stddev; 193838fd1498Szrj __is >> __mean >> __stddev 193938fd1498Szrj >> __x._M_saved_available; 194038fd1498Szrj if (__x._M_saved_available) 194138fd1498Szrj __is >> __x._M_saved; 194238fd1498Szrj __x.param(typename normal_distribution<_RealType>:: 194338fd1498Szrj param_type(__mean, __stddev)); 194438fd1498Szrj 194538fd1498Szrj __is.flags(__flags); 194638fd1498Szrj return __is; 194738fd1498Szrj } 194838fd1498Szrj 194938fd1498Szrj 195038fd1498Szrj template<typename _RealType> 195138fd1498Szrj template<typename _ForwardIterator, 195238fd1498Szrj typename _UniformRandomNumberGenerator> 195338fd1498Szrj void 195438fd1498Szrj lognormal_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)195538fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 195638fd1498Szrj _UniformRandomNumberGenerator& __urng, 195738fd1498Szrj const param_type& __p) 195838fd1498Szrj { 195938fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 196038fd1498Szrj while (__f != __t) 196138fd1498Szrj *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m()); 196238fd1498Szrj } 196338fd1498Szrj 196438fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 196538fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const lognormal_distribution<_RealType> & __x)196638fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 196738fd1498Szrj const lognormal_distribution<_RealType>& __x) 196838fd1498Szrj { 196938fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 197038fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 197138fd1498Szrj 197238fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 197338fd1498Szrj const _CharT __fill = __os.fill(); 197438fd1498Szrj const std::streamsize __precision = __os.precision(); 197538fd1498Szrj const _CharT __space = __os.widen(' '); 197638fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 197738fd1498Szrj __os.fill(__space); 197838fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 197938fd1498Szrj 198038fd1498Szrj __os << __x.m() << __space << __x.s() 198138fd1498Szrj << __space << __x._M_nd; 198238fd1498Szrj 198338fd1498Szrj __os.flags(__flags); 198438fd1498Szrj __os.fill(__fill); 198538fd1498Szrj __os.precision(__precision); 198638fd1498Szrj return __os; 198738fd1498Szrj } 198838fd1498Szrj 198938fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 199038fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,lognormal_distribution<_RealType> & __x)199138fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 199238fd1498Szrj lognormal_distribution<_RealType>& __x) 199338fd1498Szrj { 199438fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 199538fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 199638fd1498Szrj 199738fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 199838fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 199938fd1498Szrj 200038fd1498Szrj _RealType __m, __s; 200138fd1498Szrj __is >> __m >> __s >> __x._M_nd; 200238fd1498Szrj __x.param(typename lognormal_distribution<_RealType>:: 200338fd1498Szrj param_type(__m, __s)); 200438fd1498Szrj 200538fd1498Szrj __is.flags(__flags); 200638fd1498Szrj return __is; 200738fd1498Szrj } 200838fd1498Szrj 200938fd1498Szrj template<typename _RealType> 201038fd1498Szrj template<typename _ForwardIterator, 201138fd1498Szrj typename _UniformRandomNumberGenerator> 201238fd1498Szrj void 201338fd1498Szrj std::chi_squared_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)201438fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 201538fd1498Szrj _UniformRandomNumberGenerator& __urng) 201638fd1498Szrj { 201738fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 201838fd1498Szrj while (__f != __t) 201938fd1498Szrj *__f++ = 2 * _M_gd(__urng); 202038fd1498Szrj } 202138fd1498Szrj 202238fd1498Szrj template<typename _RealType> 202338fd1498Szrj template<typename _ForwardIterator, 202438fd1498Szrj typename _UniformRandomNumberGenerator> 202538fd1498Szrj void 202638fd1498Szrj std::chi_squared_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const typename std::gamma_distribution<result_type>::param_type & __p)202738fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 202838fd1498Szrj _UniformRandomNumberGenerator& __urng, 202938fd1498Szrj const typename 203038fd1498Szrj std::gamma_distribution<result_type>::param_type& __p) 203138fd1498Szrj { 203238fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 203338fd1498Szrj while (__f != __t) 203438fd1498Szrj *__f++ = 2 * _M_gd(__urng, __p); 203538fd1498Szrj } 203638fd1498Szrj 203738fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 203838fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const chi_squared_distribution<_RealType> & __x)203938fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 204038fd1498Szrj const chi_squared_distribution<_RealType>& __x) 204138fd1498Szrj { 204238fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 204338fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 204438fd1498Szrj 204538fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 204638fd1498Szrj const _CharT __fill = __os.fill(); 204738fd1498Szrj const std::streamsize __precision = __os.precision(); 204838fd1498Szrj const _CharT __space = __os.widen(' '); 204938fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 205038fd1498Szrj __os.fill(__space); 205138fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 205238fd1498Szrj 205338fd1498Szrj __os << __x.n() << __space << __x._M_gd; 205438fd1498Szrj 205538fd1498Szrj __os.flags(__flags); 205638fd1498Szrj __os.fill(__fill); 205738fd1498Szrj __os.precision(__precision); 205838fd1498Szrj return __os; 205938fd1498Szrj } 206038fd1498Szrj 206138fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 206238fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,chi_squared_distribution<_RealType> & __x)206338fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 206438fd1498Szrj chi_squared_distribution<_RealType>& __x) 206538fd1498Szrj { 206638fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 206738fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 206838fd1498Szrj 206938fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 207038fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 207138fd1498Szrj 207238fd1498Szrj _RealType __n; 207338fd1498Szrj __is >> __n >> __x._M_gd; 207438fd1498Szrj __x.param(typename chi_squared_distribution<_RealType>:: 207538fd1498Szrj param_type(__n)); 207638fd1498Szrj 207738fd1498Szrj __is.flags(__flags); 207838fd1498Szrj return __is; 207938fd1498Szrj } 208038fd1498Szrj 208138fd1498Szrj 208238fd1498Szrj template<typename _RealType> 208338fd1498Szrj template<typename _UniformRandomNumberGenerator> 208438fd1498Szrj typename cauchy_distribution<_RealType>::result_type 208538fd1498Szrj cauchy_distribution<_RealType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)208638fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 208738fd1498Szrj const param_type& __p) 208838fd1498Szrj { 208938fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 209038fd1498Szrj __aurng(__urng); 209138fd1498Szrj _RealType __u; 209238fd1498Szrj do 209338fd1498Szrj __u = __aurng(); 209438fd1498Szrj while (__u == 0.5); 209538fd1498Szrj 209638fd1498Szrj const _RealType __pi = 3.1415926535897932384626433832795029L; 209738fd1498Szrj return __p.a() + __p.b() * std::tan(__pi * __u); 209838fd1498Szrj } 209938fd1498Szrj 210038fd1498Szrj template<typename _RealType> 210138fd1498Szrj template<typename _ForwardIterator, 210238fd1498Szrj typename _UniformRandomNumberGenerator> 210338fd1498Szrj void 210438fd1498Szrj cauchy_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)210538fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 210638fd1498Szrj _UniformRandomNumberGenerator& __urng, 210738fd1498Szrj const param_type& __p) 210838fd1498Szrj { 210938fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 211038fd1498Szrj const _RealType __pi = 3.1415926535897932384626433832795029L; 211138fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 211238fd1498Szrj __aurng(__urng); 211338fd1498Szrj while (__f != __t) 211438fd1498Szrj { 211538fd1498Szrj _RealType __u; 211638fd1498Szrj do 211738fd1498Szrj __u = __aurng(); 211838fd1498Szrj while (__u == 0.5); 211938fd1498Szrj 212038fd1498Szrj *__f++ = __p.a() + __p.b() * std::tan(__pi * __u); 212138fd1498Szrj } 212238fd1498Szrj } 212338fd1498Szrj 212438fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 212538fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const cauchy_distribution<_RealType> & __x)212638fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 212738fd1498Szrj const cauchy_distribution<_RealType>& __x) 212838fd1498Szrj { 212938fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 213038fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 213138fd1498Szrj 213238fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 213338fd1498Szrj const _CharT __fill = __os.fill(); 213438fd1498Szrj const std::streamsize __precision = __os.precision(); 213538fd1498Szrj const _CharT __space = __os.widen(' '); 213638fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 213738fd1498Szrj __os.fill(__space); 213838fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 213938fd1498Szrj 214038fd1498Szrj __os << __x.a() << __space << __x.b(); 214138fd1498Szrj 214238fd1498Szrj __os.flags(__flags); 214338fd1498Szrj __os.fill(__fill); 214438fd1498Szrj __os.precision(__precision); 214538fd1498Szrj return __os; 214638fd1498Szrj } 214738fd1498Szrj 214838fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 214938fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,cauchy_distribution<_RealType> & __x)215038fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 215138fd1498Szrj cauchy_distribution<_RealType>& __x) 215238fd1498Szrj { 215338fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 215438fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 215538fd1498Szrj 215638fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 215738fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 215838fd1498Szrj 215938fd1498Szrj _RealType __a, __b; 216038fd1498Szrj __is >> __a >> __b; 216138fd1498Szrj __x.param(typename cauchy_distribution<_RealType>:: 216238fd1498Szrj param_type(__a, __b)); 216338fd1498Szrj 216438fd1498Szrj __is.flags(__flags); 216538fd1498Szrj return __is; 216638fd1498Szrj } 216738fd1498Szrj 216838fd1498Szrj 216938fd1498Szrj template<typename _RealType> 217038fd1498Szrj template<typename _ForwardIterator, 217138fd1498Szrj typename _UniformRandomNumberGenerator> 217238fd1498Szrj void 217338fd1498Szrj std::fisher_f_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)217438fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 217538fd1498Szrj _UniformRandomNumberGenerator& __urng) 217638fd1498Szrj { 217738fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 217838fd1498Szrj while (__f != __t) 217938fd1498Szrj *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m())); 218038fd1498Szrj } 218138fd1498Szrj 218238fd1498Szrj template<typename _RealType> 218338fd1498Szrj template<typename _ForwardIterator, 218438fd1498Szrj typename _UniformRandomNumberGenerator> 218538fd1498Szrj void 218638fd1498Szrj std::fisher_f_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)218738fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 218838fd1498Szrj _UniformRandomNumberGenerator& __urng, 218938fd1498Szrj const param_type& __p) 219038fd1498Szrj { 219138fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 219238fd1498Szrj typedef typename std::gamma_distribution<result_type>::param_type 219338fd1498Szrj param_type; 219438fd1498Szrj param_type __p1(__p.m() / 2); 219538fd1498Szrj param_type __p2(__p.n() / 2); 219638fd1498Szrj while (__f != __t) 219738fd1498Szrj *__f++ = ((_M_gd_x(__urng, __p1) * n()) 219838fd1498Szrj / (_M_gd_y(__urng, __p2) * m())); 219938fd1498Szrj } 220038fd1498Szrj 220138fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 220238fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const fisher_f_distribution<_RealType> & __x)220338fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 220438fd1498Szrj const fisher_f_distribution<_RealType>& __x) 220538fd1498Szrj { 220638fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 220738fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 220838fd1498Szrj 220938fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 221038fd1498Szrj const _CharT __fill = __os.fill(); 221138fd1498Szrj const std::streamsize __precision = __os.precision(); 221238fd1498Szrj const _CharT __space = __os.widen(' '); 221338fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 221438fd1498Szrj __os.fill(__space); 221538fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 221638fd1498Szrj 221738fd1498Szrj __os << __x.m() << __space << __x.n() 221838fd1498Szrj << __space << __x._M_gd_x << __space << __x._M_gd_y; 221938fd1498Szrj 222038fd1498Szrj __os.flags(__flags); 222138fd1498Szrj __os.fill(__fill); 222238fd1498Szrj __os.precision(__precision); 222338fd1498Szrj return __os; 222438fd1498Szrj } 222538fd1498Szrj 222638fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 222738fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,fisher_f_distribution<_RealType> & __x)222838fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 222938fd1498Szrj fisher_f_distribution<_RealType>& __x) 223038fd1498Szrj { 223138fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 223238fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 223338fd1498Szrj 223438fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 223538fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 223638fd1498Szrj 223738fd1498Szrj _RealType __m, __n; 223838fd1498Szrj __is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y; 223938fd1498Szrj __x.param(typename fisher_f_distribution<_RealType>:: 224038fd1498Szrj param_type(__m, __n)); 224138fd1498Szrj 224238fd1498Szrj __is.flags(__flags); 224338fd1498Szrj return __is; 224438fd1498Szrj } 224538fd1498Szrj 224638fd1498Szrj 224738fd1498Szrj template<typename _RealType> 224838fd1498Szrj template<typename _ForwardIterator, 224938fd1498Szrj typename _UniformRandomNumberGenerator> 225038fd1498Szrj void 225138fd1498Szrj std::student_t_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)225238fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 225338fd1498Szrj _UniformRandomNumberGenerator& __urng) 225438fd1498Szrj { 225538fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 225638fd1498Szrj while (__f != __t) 225738fd1498Szrj *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); 225838fd1498Szrj } 225938fd1498Szrj 226038fd1498Szrj template<typename _RealType> 226138fd1498Szrj template<typename _ForwardIterator, 226238fd1498Szrj typename _UniformRandomNumberGenerator> 226338fd1498Szrj void 226438fd1498Szrj std::student_t_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)226538fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 226638fd1498Szrj _UniformRandomNumberGenerator& __urng, 226738fd1498Szrj const param_type& __p) 226838fd1498Szrj { 226938fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 227038fd1498Szrj typename std::gamma_distribution<result_type>::param_type 227138fd1498Szrj __p2(__p.n() / 2, 2); 227238fd1498Szrj while (__f != __t) 227338fd1498Szrj *__f++ = _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2)); 227438fd1498Szrj } 227538fd1498Szrj 227638fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 227738fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const student_t_distribution<_RealType> & __x)227838fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 227938fd1498Szrj const student_t_distribution<_RealType>& __x) 228038fd1498Szrj { 228138fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 228238fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 228338fd1498Szrj 228438fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 228538fd1498Szrj const _CharT __fill = __os.fill(); 228638fd1498Szrj const std::streamsize __precision = __os.precision(); 228738fd1498Szrj const _CharT __space = __os.widen(' '); 228838fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 228938fd1498Szrj __os.fill(__space); 229038fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 229138fd1498Szrj 229238fd1498Szrj __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd; 229338fd1498Szrj 229438fd1498Szrj __os.flags(__flags); 229538fd1498Szrj __os.fill(__fill); 229638fd1498Szrj __os.precision(__precision); 229738fd1498Szrj return __os; 229838fd1498Szrj } 229938fd1498Szrj 230038fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 230138fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,student_t_distribution<_RealType> & __x)230238fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 230338fd1498Szrj student_t_distribution<_RealType>& __x) 230438fd1498Szrj { 230538fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 230638fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 230738fd1498Szrj 230838fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 230938fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 231038fd1498Szrj 231138fd1498Szrj _RealType __n; 231238fd1498Szrj __is >> __n >> __x._M_nd >> __x._M_gd; 231338fd1498Szrj __x.param(typename student_t_distribution<_RealType>::param_type(__n)); 231438fd1498Szrj 231538fd1498Szrj __is.flags(__flags); 231638fd1498Szrj return __is; 231738fd1498Szrj } 231838fd1498Szrj 231938fd1498Szrj 232038fd1498Szrj template<typename _RealType> 232138fd1498Szrj void 232238fd1498Szrj gamma_distribution<_RealType>::param_type:: _M_initialize()232338fd1498Szrj _M_initialize() 232438fd1498Szrj { 232538fd1498Szrj _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha; 232638fd1498Szrj 232738fd1498Szrj const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0); 232838fd1498Szrj _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1); 232938fd1498Szrj } 233038fd1498Szrj 233138fd1498Szrj /** 233238fd1498Szrj * Marsaglia, G. and Tsang, W. W. 233338fd1498Szrj * "A Simple Method for Generating Gamma Variables" 233438fd1498Szrj * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000. 233538fd1498Szrj */ 233638fd1498Szrj template<typename _RealType> 233738fd1498Szrj template<typename _UniformRandomNumberGenerator> 233838fd1498Szrj typename gamma_distribution<_RealType>::result_type 233938fd1498Szrj gamma_distribution<_RealType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)234038fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 234138fd1498Szrj const param_type& __param) 234238fd1498Szrj { 234338fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 234438fd1498Szrj __aurng(__urng); 234538fd1498Szrj 234638fd1498Szrj result_type __u, __v, __n; 234738fd1498Szrj const result_type __a1 = (__param._M_malpha 234838fd1498Szrj - _RealType(1.0) / _RealType(3.0)); 234938fd1498Szrj 235038fd1498Szrj do 235138fd1498Szrj { 235238fd1498Szrj do 235338fd1498Szrj { 235438fd1498Szrj __n = _M_nd(__urng); 235538fd1498Szrj __v = result_type(1.0) + __param._M_a2 * __n; 235638fd1498Szrj } 235738fd1498Szrj while (__v <= 0.0); 235838fd1498Szrj 235938fd1498Szrj __v = __v * __v * __v; 236038fd1498Szrj __u = __aurng(); 236138fd1498Szrj } 236238fd1498Szrj while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n 236338fd1498Szrj && (std::log(__u) > (0.5 * __n * __n + __a1 236438fd1498Szrj * (1.0 - __v + std::log(__v))))); 236538fd1498Szrj 236638fd1498Szrj if (__param.alpha() == __param._M_malpha) 236738fd1498Szrj return __a1 * __v * __param.beta(); 236838fd1498Szrj else 236938fd1498Szrj { 237038fd1498Szrj do 237138fd1498Szrj __u = __aurng(); 237238fd1498Szrj while (__u == 0.0); 237338fd1498Szrj 237438fd1498Szrj return (std::pow(__u, result_type(1.0) / __param.alpha()) 237538fd1498Szrj * __a1 * __v * __param.beta()); 237638fd1498Szrj } 237738fd1498Szrj } 237838fd1498Szrj 237938fd1498Szrj template<typename _RealType> 238038fd1498Szrj template<typename _ForwardIterator, 238138fd1498Szrj typename _UniformRandomNumberGenerator> 238238fd1498Szrj void 238338fd1498Szrj gamma_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)238438fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 238538fd1498Szrj _UniformRandomNumberGenerator& __urng, 238638fd1498Szrj const param_type& __param) 238738fd1498Szrj { 238838fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 238938fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 239038fd1498Szrj __aurng(__urng); 239138fd1498Szrj 239238fd1498Szrj result_type __u, __v, __n; 239338fd1498Szrj const result_type __a1 = (__param._M_malpha 239438fd1498Szrj - _RealType(1.0) / _RealType(3.0)); 239538fd1498Szrj 239638fd1498Szrj if (__param.alpha() == __param._M_malpha) 239738fd1498Szrj while (__f != __t) 239838fd1498Szrj { 239938fd1498Szrj do 240038fd1498Szrj { 240138fd1498Szrj do 240238fd1498Szrj { 240338fd1498Szrj __n = _M_nd(__urng); 240438fd1498Szrj __v = result_type(1.0) + __param._M_a2 * __n; 240538fd1498Szrj } 240638fd1498Szrj while (__v <= 0.0); 240738fd1498Szrj 240838fd1498Szrj __v = __v * __v * __v; 240938fd1498Szrj __u = __aurng(); 241038fd1498Szrj } 2411*58e805e6Szrj while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n 241238fd1498Szrj && (std::log(__u) > (0.5 * __n * __n + __a1 241338fd1498Szrj * (1.0 - __v + std::log(__v))))); 241438fd1498Szrj 241538fd1498Szrj *__f++ = __a1 * __v * __param.beta(); 241638fd1498Szrj } 241738fd1498Szrj else 241838fd1498Szrj while (__f != __t) 241938fd1498Szrj { 242038fd1498Szrj do 242138fd1498Szrj { 242238fd1498Szrj do 242338fd1498Szrj { 242438fd1498Szrj __n = _M_nd(__urng); 242538fd1498Szrj __v = result_type(1.0) + __param._M_a2 * __n; 242638fd1498Szrj } 242738fd1498Szrj while (__v <= 0.0); 242838fd1498Szrj 242938fd1498Szrj __v = __v * __v * __v; 243038fd1498Szrj __u = __aurng(); 243138fd1498Szrj } 2432*58e805e6Szrj while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n 243338fd1498Szrj && (std::log(__u) > (0.5 * __n * __n + __a1 243438fd1498Szrj * (1.0 - __v + std::log(__v))))); 243538fd1498Szrj 243638fd1498Szrj do 243738fd1498Szrj __u = __aurng(); 243838fd1498Szrj while (__u == 0.0); 243938fd1498Szrj 244038fd1498Szrj *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha()) 244138fd1498Szrj * __a1 * __v * __param.beta()); 244238fd1498Szrj } 244338fd1498Szrj } 244438fd1498Szrj 244538fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 244638fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const gamma_distribution<_RealType> & __x)244738fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 244838fd1498Szrj const gamma_distribution<_RealType>& __x) 244938fd1498Szrj { 245038fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 245138fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 245238fd1498Szrj 245338fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 245438fd1498Szrj const _CharT __fill = __os.fill(); 245538fd1498Szrj const std::streamsize __precision = __os.precision(); 245638fd1498Szrj const _CharT __space = __os.widen(' '); 245738fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 245838fd1498Szrj __os.fill(__space); 245938fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 246038fd1498Szrj 246138fd1498Szrj __os << __x.alpha() << __space << __x.beta() 246238fd1498Szrj << __space << __x._M_nd; 246338fd1498Szrj 246438fd1498Szrj __os.flags(__flags); 246538fd1498Szrj __os.fill(__fill); 246638fd1498Szrj __os.precision(__precision); 246738fd1498Szrj return __os; 246838fd1498Szrj } 246938fd1498Szrj 247038fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 247138fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,gamma_distribution<_RealType> & __x)247238fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 247338fd1498Szrj gamma_distribution<_RealType>& __x) 247438fd1498Szrj { 247538fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 247638fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 247738fd1498Szrj 247838fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 247938fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 248038fd1498Szrj 248138fd1498Szrj _RealType __alpha_val, __beta_val; 248238fd1498Szrj __is >> __alpha_val >> __beta_val >> __x._M_nd; 248338fd1498Szrj __x.param(typename gamma_distribution<_RealType>:: 248438fd1498Szrj param_type(__alpha_val, __beta_val)); 248538fd1498Szrj 248638fd1498Szrj __is.flags(__flags); 248738fd1498Szrj return __is; 248838fd1498Szrj } 248938fd1498Szrj 249038fd1498Szrj 249138fd1498Szrj template<typename _RealType> 249238fd1498Szrj template<typename _UniformRandomNumberGenerator> 249338fd1498Szrj typename weibull_distribution<_RealType>::result_type 249438fd1498Szrj weibull_distribution<_RealType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)249538fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 249638fd1498Szrj const param_type& __p) 249738fd1498Szrj { 249838fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 249938fd1498Szrj __aurng(__urng); 250038fd1498Szrj return __p.b() * std::pow(-std::log(result_type(1) - __aurng()), 250138fd1498Szrj result_type(1) / __p.a()); 250238fd1498Szrj } 250338fd1498Szrj 250438fd1498Szrj template<typename _RealType> 250538fd1498Szrj template<typename _ForwardIterator, 250638fd1498Szrj typename _UniformRandomNumberGenerator> 250738fd1498Szrj void 250838fd1498Szrj weibull_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)250938fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 251038fd1498Szrj _UniformRandomNumberGenerator& __urng, 251138fd1498Szrj const param_type& __p) 251238fd1498Szrj { 251338fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 251438fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 251538fd1498Szrj __aurng(__urng); 251638fd1498Szrj auto __inv_a = result_type(1) / __p.a(); 251738fd1498Szrj 251838fd1498Szrj while (__f != __t) 251938fd1498Szrj *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()), 252038fd1498Szrj __inv_a); 252138fd1498Szrj } 252238fd1498Szrj 252338fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 252438fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const weibull_distribution<_RealType> & __x)252538fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 252638fd1498Szrj const weibull_distribution<_RealType>& __x) 252738fd1498Szrj { 252838fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 252938fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 253038fd1498Szrj 253138fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 253238fd1498Szrj const _CharT __fill = __os.fill(); 253338fd1498Szrj const std::streamsize __precision = __os.precision(); 253438fd1498Szrj const _CharT __space = __os.widen(' '); 253538fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 253638fd1498Szrj __os.fill(__space); 253738fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 253838fd1498Szrj 253938fd1498Szrj __os << __x.a() << __space << __x.b(); 254038fd1498Szrj 254138fd1498Szrj __os.flags(__flags); 254238fd1498Szrj __os.fill(__fill); 254338fd1498Szrj __os.precision(__precision); 254438fd1498Szrj return __os; 254538fd1498Szrj } 254638fd1498Szrj 254738fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 254838fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,weibull_distribution<_RealType> & __x)254938fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 255038fd1498Szrj weibull_distribution<_RealType>& __x) 255138fd1498Szrj { 255238fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 255338fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 255438fd1498Szrj 255538fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 255638fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 255738fd1498Szrj 255838fd1498Szrj _RealType __a, __b; 255938fd1498Szrj __is >> __a >> __b; 256038fd1498Szrj __x.param(typename weibull_distribution<_RealType>:: 256138fd1498Szrj param_type(__a, __b)); 256238fd1498Szrj 256338fd1498Szrj __is.flags(__flags); 256438fd1498Szrj return __is; 256538fd1498Szrj } 256638fd1498Szrj 256738fd1498Szrj 256838fd1498Szrj template<typename _RealType> 256938fd1498Szrj template<typename _UniformRandomNumberGenerator> 257038fd1498Szrj typename extreme_value_distribution<_RealType>::result_type 257138fd1498Szrj extreme_value_distribution<_RealType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)257238fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 257338fd1498Szrj const param_type& __p) 257438fd1498Szrj { 257538fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 257638fd1498Szrj __aurng(__urng); 257738fd1498Szrj return __p.a() - __p.b() * std::log(-std::log(result_type(1) 257838fd1498Szrj - __aurng())); 257938fd1498Szrj } 258038fd1498Szrj 258138fd1498Szrj template<typename _RealType> 258238fd1498Szrj template<typename _ForwardIterator, 258338fd1498Szrj typename _UniformRandomNumberGenerator> 258438fd1498Szrj void 258538fd1498Szrj extreme_value_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)258638fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 258738fd1498Szrj _UniformRandomNumberGenerator& __urng, 258838fd1498Szrj const param_type& __p) 258938fd1498Szrj { 259038fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 259138fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 259238fd1498Szrj __aurng(__urng); 259338fd1498Szrj 259438fd1498Szrj while (__f != __t) 259538fd1498Szrj *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1) 259638fd1498Szrj - __aurng())); 259738fd1498Szrj } 259838fd1498Szrj 259938fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 260038fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const extreme_value_distribution<_RealType> & __x)260138fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 260238fd1498Szrj const extreme_value_distribution<_RealType>& __x) 260338fd1498Szrj { 260438fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 260538fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 260638fd1498Szrj 260738fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 260838fd1498Szrj const _CharT __fill = __os.fill(); 260938fd1498Szrj const std::streamsize __precision = __os.precision(); 261038fd1498Szrj const _CharT __space = __os.widen(' '); 261138fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 261238fd1498Szrj __os.fill(__space); 261338fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 261438fd1498Szrj 261538fd1498Szrj __os << __x.a() << __space << __x.b(); 261638fd1498Szrj 261738fd1498Szrj __os.flags(__flags); 261838fd1498Szrj __os.fill(__fill); 261938fd1498Szrj __os.precision(__precision); 262038fd1498Szrj return __os; 262138fd1498Szrj } 262238fd1498Szrj 262338fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 262438fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,extreme_value_distribution<_RealType> & __x)262538fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 262638fd1498Szrj extreme_value_distribution<_RealType>& __x) 262738fd1498Szrj { 262838fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 262938fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 263038fd1498Szrj 263138fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 263238fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 263338fd1498Szrj 263438fd1498Szrj _RealType __a, __b; 263538fd1498Szrj __is >> __a >> __b; 263638fd1498Szrj __x.param(typename extreme_value_distribution<_RealType>:: 263738fd1498Szrj param_type(__a, __b)); 263838fd1498Szrj 263938fd1498Szrj __is.flags(__flags); 264038fd1498Szrj return __is; 264138fd1498Szrj } 264238fd1498Szrj 264338fd1498Szrj 264438fd1498Szrj template<typename _IntType> 264538fd1498Szrj void 264638fd1498Szrj discrete_distribution<_IntType>::param_type:: _M_initialize()264738fd1498Szrj _M_initialize() 264838fd1498Szrj { 264938fd1498Szrj if (_M_prob.size() < 2) 265038fd1498Szrj { 265138fd1498Szrj _M_prob.clear(); 265238fd1498Szrj return; 265338fd1498Szrj } 265438fd1498Szrj 265538fd1498Szrj const double __sum = std::accumulate(_M_prob.begin(), 265638fd1498Szrj _M_prob.end(), 0.0); 265738fd1498Szrj // Now normalize the probabilites. 265838fd1498Szrj __detail::__normalize(_M_prob.begin(), _M_prob.end(), _M_prob.begin(), 265938fd1498Szrj __sum); 266038fd1498Szrj // Accumulate partial sums. 266138fd1498Szrj _M_cp.reserve(_M_prob.size()); 266238fd1498Szrj std::partial_sum(_M_prob.begin(), _M_prob.end(), 266338fd1498Szrj std::back_inserter(_M_cp)); 266438fd1498Szrj // Make sure the last cumulative probability is one. 266538fd1498Szrj _M_cp[_M_cp.size() - 1] = 1.0; 266638fd1498Szrj } 266738fd1498Szrj 266838fd1498Szrj template<typename _IntType> 266938fd1498Szrj template<typename _Func> 267038fd1498Szrj discrete_distribution<_IntType>::param_type:: param_type(size_t __nw,double __xmin,double __xmax,_Func __fw)267138fd1498Szrj param_type(size_t __nw, double __xmin, double __xmax, _Func __fw) 267238fd1498Szrj : _M_prob(), _M_cp() 267338fd1498Szrj { 267438fd1498Szrj const size_t __n = __nw == 0 ? 1 : __nw; 267538fd1498Szrj const double __delta = (__xmax - __xmin) / __n; 267638fd1498Szrj 267738fd1498Szrj _M_prob.reserve(__n); 267838fd1498Szrj for (size_t __k = 0; __k < __nw; ++__k) 267938fd1498Szrj _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta)); 268038fd1498Szrj 268138fd1498Szrj _M_initialize(); 268238fd1498Szrj } 268338fd1498Szrj 268438fd1498Szrj template<typename _IntType> 268538fd1498Szrj template<typename _UniformRandomNumberGenerator> 268638fd1498Szrj typename discrete_distribution<_IntType>::result_type 268738fd1498Szrj discrete_distribution<_IntType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)268838fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 268938fd1498Szrj const param_type& __param) 269038fd1498Szrj { 269138fd1498Szrj if (__param._M_cp.empty()) 269238fd1498Szrj return result_type(0); 269338fd1498Szrj 269438fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 269538fd1498Szrj __aurng(__urng); 269638fd1498Szrj 269738fd1498Szrj const double __p = __aurng(); 269838fd1498Szrj auto __pos = std::lower_bound(__param._M_cp.begin(), 269938fd1498Szrj __param._M_cp.end(), __p); 270038fd1498Szrj 270138fd1498Szrj return __pos - __param._M_cp.begin(); 270238fd1498Szrj } 270338fd1498Szrj 270438fd1498Szrj template<typename _IntType> 270538fd1498Szrj template<typename _ForwardIterator, 270638fd1498Szrj typename _UniformRandomNumberGenerator> 270738fd1498Szrj void 270838fd1498Szrj discrete_distribution<_IntType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)270938fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 271038fd1498Szrj _UniformRandomNumberGenerator& __urng, 271138fd1498Szrj const param_type& __param) 271238fd1498Szrj { 271338fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 271438fd1498Szrj 271538fd1498Szrj if (__param._M_cp.empty()) 271638fd1498Szrj { 271738fd1498Szrj while (__f != __t) 271838fd1498Szrj *__f++ = result_type(0); 271938fd1498Szrj return; 272038fd1498Szrj } 272138fd1498Szrj 272238fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 272338fd1498Szrj __aurng(__urng); 272438fd1498Szrj 272538fd1498Szrj while (__f != __t) 272638fd1498Szrj { 272738fd1498Szrj const double __p = __aurng(); 272838fd1498Szrj auto __pos = std::lower_bound(__param._M_cp.begin(), 272938fd1498Szrj __param._M_cp.end(), __p); 273038fd1498Szrj 273138fd1498Szrj *__f++ = __pos - __param._M_cp.begin(); 273238fd1498Szrj } 273338fd1498Szrj } 273438fd1498Szrj 273538fd1498Szrj template<typename _IntType, typename _CharT, typename _Traits> 273638fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const discrete_distribution<_IntType> & __x)273738fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 273838fd1498Szrj const discrete_distribution<_IntType>& __x) 273938fd1498Szrj { 274038fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 274138fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 274238fd1498Szrj 274338fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 274438fd1498Szrj const _CharT __fill = __os.fill(); 274538fd1498Szrj const std::streamsize __precision = __os.precision(); 274638fd1498Szrj const _CharT __space = __os.widen(' '); 274738fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 274838fd1498Szrj __os.fill(__space); 274938fd1498Szrj __os.precision(std::numeric_limits<double>::max_digits10); 275038fd1498Szrj 275138fd1498Szrj std::vector<double> __prob = __x.probabilities(); 275238fd1498Szrj __os << __prob.size(); 275338fd1498Szrj for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit) 275438fd1498Szrj __os << __space << *__dit; 275538fd1498Szrj 275638fd1498Szrj __os.flags(__flags); 275738fd1498Szrj __os.fill(__fill); 275838fd1498Szrj __os.precision(__precision); 275938fd1498Szrj return __os; 276038fd1498Szrj } 276138fd1498Szrj 276238fd1498Szrj template<typename _IntType, typename _CharT, typename _Traits> 276338fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,discrete_distribution<_IntType> & __x)276438fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 276538fd1498Szrj discrete_distribution<_IntType>& __x) 276638fd1498Szrj { 276738fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 276838fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 276938fd1498Szrj 277038fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 277138fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 277238fd1498Szrj 277338fd1498Szrj size_t __n; 277438fd1498Szrj __is >> __n; 277538fd1498Szrj 277638fd1498Szrj std::vector<double> __prob_vec; 277738fd1498Szrj __prob_vec.reserve(__n); 277838fd1498Szrj for (; __n != 0; --__n) 277938fd1498Szrj { 278038fd1498Szrj double __prob; 278138fd1498Szrj __is >> __prob; 278238fd1498Szrj __prob_vec.push_back(__prob); 278338fd1498Szrj } 278438fd1498Szrj 278538fd1498Szrj __x.param(typename discrete_distribution<_IntType>:: 278638fd1498Szrj param_type(__prob_vec.begin(), __prob_vec.end())); 278738fd1498Szrj 278838fd1498Szrj __is.flags(__flags); 278938fd1498Szrj return __is; 279038fd1498Szrj } 279138fd1498Szrj 279238fd1498Szrj 279338fd1498Szrj template<typename _RealType> 279438fd1498Szrj void 279538fd1498Szrj piecewise_constant_distribution<_RealType>::param_type:: _M_initialize()279638fd1498Szrj _M_initialize() 279738fd1498Szrj { 279838fd1498Szrj if (_M_int.size() < 2 279938fd1498Szrj || (_M_int.size() == 2 280038fd1498Szrj && _M_int[0] == _RealType(0) 280138fd1498Szrj && _M_int[1] == _RealType(1))) 280238fd1498Szrj { 280338fd1498Szrj _M_int.clear(); 280438fd1498Szrj _M_den.clear(); 280538fd1498Szrj return; 280638fd1498Szrj } 280738fd1498Szrj 280838fd1498Szrj const double __sum = std::accumulate(_M_den.begin(), 280938fd1498Szrj _M_den.end(), 0.0); 281038fd1498Szrj 281138fd1498Szrj __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(), 281238fd1498Szrj __sum); 281338fd1498Szrj 281438fd1498Szrj _M_cp.reserve(_M_den.size()); 281538fd1498Szrj std::partial_sum(_M_den.begin(), _M_den.end(), 281638fd1498Szrj std::back_inserter(_M_cp)); 281738fd1498Szrj 281838fd1498Szrj // Make sure the last cumulative probability is one. 281938fd1498Szrj _M_cp[_M_cp.size() - 1] = 1.0; 282038fd1498Szrj 282138fd1498Szrj for (size_t __k = 0; __k < _M_den.size(); ++__k) 282238fd1498Szrj _M_den[__k] /= _M_int[__k + 1] - _M_int[__k]; 282338fd1498Szrj } 282438fd1498Szrj 282538fd1498Szrj template<typename _RealType> 282638fd1498Szrj template<typename _InputIteratorB, typename _InputIteratorW> 282738fd1498Szrj piecewise_constant_distribution<_RealType>::param_type:: param_type(_InputIteratorB __bbegin,_InputIteratorB __bend,_InputIteratorW __wbegin)282838fd1498Szrj param_type(_InputIteratorB __bbegin, 282938fd1498Szrj _InputIteratorB __bend, 283038fd1498Szrj _InputIteratorW __wbegin) 283138fd1498Szrj : _M_int(), _M_den(), _M_cp() 283238fd1498Szrj { 283338fd1498Szrj if (__bbegin != __bend) 283438fd1498Szrj { 283538fd1498Szrj for (;;) 283638fd1498Szrj { 283738fd1498Szrj _M_int.push_back(*__bbegin); 283838fd1498Szrj ++__bbegin; 283938fd1498Szrj if (__bbegin == __bend) 284038fd1498Szrj break; 284138fd1498Szrj 284238fd1498Szrj _M_den.push_back(*__wbegin); 284338fd1498Szrj ++__wbegin; 284438fd1498Szrj } 284538fd1498Szrj } 284638fd1498Szrj 284738fd1498Szrj _M_initialize(); 284838fd1498Szrj } 284938fd1498Szrj 285038fd1498Szrj template<typename _RealType> 285138fd1498Szrj template<typename _Func> 285238fd1498Szrj piecewise_constant_distribution<_RealType>::param_type:: param_type(initializer_list<_RealType> __bl,_Func __fw)285338fd1498Szrj param_type(initializer_list<_RealType> __bl, _Func __fw) 285438fd1498Szrj : _M_int(), _M_den(), _M_cp() 285538fd1498Szrj { 285638fd1498Szrj _M_int.reserve(__bl.size()); 285738fd1498Szrj for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) 285838fd1498Szrj _M_int.push_back(*__biter); 285938fd1498Szrj 286038fd1498Szrj _M_den.reserve(_M_int.size() - 1); 286138fd1498Szrj for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) 286238fd1498Szrj _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k]))); 286338fd1498Szrj 286438fd1498Szrj _M_initialize(); 286538fd1498Szrj } 286638fd1498Szrj 286738fd1498Szrj template<typename _RealType> 286838fd1498Szrj template<typename _Func> 286938fd1498Szrj piecewise_constant_distribution<_RealType>::param_type:: param_type(size_t __nw,_RealType __xmin,_RealType __xmax,_Func __fw)287038fd1498Szrj param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) 287138fd1498Szrj : _M_int(), _M_den(), _M_cp() 287238fd1498Szrj { 287338fd1498Szrj const size_t __n = __nw == 0 ? 1 : __nw; 287438fd1498Szrj const _RealType __delta = (__xmax - __xmin) / __n; 287538fd1498Szrj 287638fd1498Szrj _M_int.reserve(__n + 1); 287738fd1498Szrj for (size_t __k = 0; __k <= __nw; ++__k) 287838fd1498Szrj _M_int.push_back(__xmin + __k * __delta); 287938fd1498Szrj 288038fd1498Szrj _M_den.reserve(__n); 288138fd1498Szrj for (size_t __k = 0; __k < __nw; ++__k) 288238fd1498Szrj _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta)); 288338fd1498Szrj 288438fd1498Szrj _M_initialize(); 288538fd1498Szrj } 288638fd1498Szrj 288738fd1498Szrj template<typename _RealType> 288838fd1498Szrj template<typename _UniformRandomNumberGenerator> 288938fd1498Szrj typename piecewise_constant_distribution<_RealType>::result_type 289038fd1498Szrj piecewise_constant_distribution<_RealType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)289138fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 289238fd1498Szrj const param_type& __param) 289338fd1498Szrj { 289438fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 289538fd1498Szrj __aurng(__urng); 289638fd1498Szrj 289738fd1498Szrj const double __p = __aurng(); 289838fd1498Szrj if (__param._M_cp.empty()) 289938fd1498Szrj return __p; 290038fd1498Szrj 290138fd1498Szrj auto __pos = std::lower_bound(__param._M_cp.begin(), 290238fd1498Szrj __param._M_cp.end(), __p); 290338fd1498Szrj const size_t __i = __pos - __param._M_cp.begin(); 290438fd1498Szrj 290538fd1498Szrj const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 290638fd1498Szrj 290738fd1498Szrj return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i]; 290838fd1498Szrj } 290938fd1498Szrj 291038fd1498Szrj template<typename _RealType> 291138fd1498Szrj template<typename _ForwardIterator, 291238fd1498Szrj typename _UniformRandomNumberGenerator> 291338fd1498Szrj void 291438fd1498Szrj piecewise_constant_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)291538fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 291638fd1498Szrj _UniformRandomNumberGenerator& __urng, 291738fd1498Szrj const param_type& __param) 291838fd1498Szrj { 291938fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 292038fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 292138fd1498Szrj __aurng(__urng); 292238fd1498Szrj 292338fd1498Szrj if (__param._M_cp.empty()) 292438fd1498Szrj { 292538fd1498Szrj while (__f != __t) 292638fd1498Szrj *__f++ = __aurng(); 292738fd1498Szrj return; 292838fd1498Szrj } 292938fd1498Szrj 293038fd1498Szrj while (__f != __t) 293138fd1498Szrj { 293238fd1498Szrj const double __p = __aurng(); 293338fd1498Szrj 293438fd1498Szrj auto __pos = std::lower_bound(__param._M_cp.begin(), 293538fd1498Szrj __param._M_cp.end(), __p); 293638fd1498Szrj const size_t __i = __pos - __param._M_cp.begin(); 293738fd1498Szrj 293838fd1498Szrj const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 293938fd1498Szrj 294038fd1498Szrj *__f++ = (__param._M_int[__i] 294138fd1498Szrj + (__p - __pref) / __param._M_den[__i]); 294238fd1498Szrj } 294338fd1498Szrj } 294438fd1498Szrj 294538fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 294638fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const piecewise_constant_distribution<_RealType> & __x)294738fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 294838fd1498Szrj const piecewise_constant_distribution<_RealType>& __x) 294938fd1498Szrj { 295038fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 295138fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 295238fd1498Szrj 295338fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 295438fd1498Szrj const _CharT __fill = __os.fill(); 295538fd1498Szrj const std::streamsize __precision = __os.precision(); 295638fd1498Szrj const _CharT __space = __os.widen(' '); 295738fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 295838fd1498Szrj __os.fill(__space); 295938fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 296038fd1498Szrj 296138fd1498Szrj std::vector<_RealType> __int = __x.intervals(); 296238fd1498Szrj __os << __int.size() - 1; 296338fd1498Szrj 296438fd1498Szrj for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) 296538fd1498Szrj __os << __space << *__xit; 296638fd1498Szrj 296738fd1498Szrj std::vector<double> __den = __x.densities(); 296838fd1498Szrj for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) 296938fd1498Szrj __os << __space << *__dit; 297038fd1498Szrj 297138fd1498Szrj __os.flags(__flags); 297238fd1498Szrj __os.fill(__fill); 297338fd1498Szrj __os.precision(__precision); 297438fd1498Szrj return __os; 297538fd1498Szrj } 297638fd1498Szrj 297738fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 297838fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,piecewise_constant_distribution<_RealType> & __x)297938fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 298038fd1498Szrj piecewise_constant_distribution<_RealType>& __x) 298138fd1498Szrj { 298238fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 298338fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 298438fd1498Szrj 298538fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 298638fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 298738fd1498Szrj 298838fd1498Szrj size_t __n; 298938fd1498Szrj __is >> __n; 299038fd1498Szrj 299138fd1498Szrj std::vector<_RealType> __int_vec; 299238fd1498Szrj __int_vec.reserve(__n + 1); 299338fd1498Szrj for (size_t __i = 0; __i <= __n; ++__i) 299438fd1498Szrj { 299538fd1498Szrj _RealType __int; 299638fd1498Szrj __is >> __int; 299738fd1498Szrj __int_vec.push_back(__int); 299838fd1498Szrj } 299938fd1498Szrj 300038fd1498Szrj std::vector<double> __den_vec; 300138fd1498Szrj __den_vec.reserve(__n); 300238fd1498Szrj for (size_t __i = 0; __i < __n; ++__i) 300338fd1498Szrj { 300438fd1498Szrj double __den; 300538fd1498Szrj __is >> __den; 300638fd1498Szrj __den_vec.push_back(__den); 300738fd1498Szrj } 300838fd1498Szrj 300938fd1498Szrj __x.param(typename piecewise_constant_distribution<_RealType>:: 301038fd1498Szrj param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin())); 301138fd1498Szrj 301238fd1498Szrj __is.flags(__flags); 301338fd1498Szrj return __is; 301438fd1498Szrj } 301538fd1498Szrj 301638fd1498Szrj 301738fd1498Szrj template<typename _RealType> 301838fd1498Szrj void 301938fd1498Szrj piecewise_linear_distribution<_RealType>::param_type:: _M_initialize()302038fd1498Szrj _M_initialize() 302138fd1498Szrj { 302238fd1498Szrj if (_M_int.size() < 2 302338fd1498Szrj || (_M_int.size() == 2 302438fd1498Szrj && _M_int[0] == _RealType(0) 302538fd1498Szrj && _M_int[1] == _RealType(1) 302638fd1498Szrj && _M_den[0] == _M_den[1])) 302738fd1498Szrj { 302838fd1498Szrj _M_int.clear(); 302938fd1498Szrj _M_den.clear(); 303038fd1498Szrj return; 303138fd1498Szrj } 303238fd1498Szrj 303338fd1498Szrj double __sum = 0.0; 303438fd1498Szrj _M_cp.reserve(_M_int.size() - 1); 303538fd1498Szrj _M_m.reserve(_M_int.size() - 1); 303638fd1498Szrj for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) 303738fd1498Szrj { 303838fd1498Szrj const _RealType __delta = _M_int[__k + 1] - _M_int[__k]; 303938fd1498Szrj __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta; 304038fd1498Szrj _M_cp.push_back(__sum); 304138fd1498Szrj _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta); 304238fd1498Szrj } 304338fd1498Szrj 304438fd1498Szrj // Now normalize the densities... 304538fd1498Szrj __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(), 304638fd1498Szrj __sum); 304738fd1498Szrj // ... and partial sums... 304838fd1498Szrj __detail::__normalize(_M_cp.begin(), _M_cp.end(), _M_cp.begin(), __sum); 304938fd1498Szrj // ... and slopes. 305038fd1498Szrj __detail::__normalize(_M_m.begin(), _M_m.end(), _M_m.begin(), __sum); 305138fd1498Szrj 305238fd1498Szrj // Make sure the last cumulative probablility is one. 305338fd1498Szrj _M_cp[_M_cp.size() - 1] = 1.0; 305438fd1498Szrj } 305538fd1498Szrj 305638fd1498Szrj template<typename _RealType> 305738fd1498Szrj template<typename _InputIteratorB, typename _InputIteratorW> 305838fd1498Szrj piecewise_linear_distribution<_RealType>::param_type:: param_type(_InputIteratorB __bbegin,_InputIteratorB __bend,_InputIteratorW __wbegin)305938fd1498Szrj param_type(_InputIteratorB __bbegin, 306038fd1498Szrj _InputIteratorB __bend, 306138fd1498Szrj _InputIteratorW __wbegin) 306238fd1498Szrj : _M_int(), _M_den(), _M_cp(), _M_m() 306338fd1498Szrj { 306438fd1498Szrj for (; __bbegin != __bend; ++__bbegin, ++__wbegin) 306538fd1498Szrj { 306638fd1498Szrj _M_int.push_back(*__bbegin); 306738fd1498Szrj _M_den.push_back(*__wbegin); 306838fd1498Szrj } 306938fd1498Szrj 307038fd1498Szrj _M_initialize(); 307138fd1498Szrj } 307238fd1498Szrj 307338fd1498Szrj template<typename _RealType> 307438fd1498Szrj template<typename _Func> 307538fd1498Szrj piecewise_linear_distribution<_RealType>::param_type:: param_type(initializer_list<_RealType> __bl,_Func __fw)307638fd1498Szrj param_type(initializer_list<_RealType> __bl, _Func __fw) 307738fd1498Szrj : _M_int(), _M_den(), _M_cp(), _M_m() 307838fd1498Szrj { 307938fd1498Szrj _M_int.reserve(__bl.size()); 308038fd1498Szrj _M_den.reserve(__bl.size()); 308138fd1498Szrj for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) 308238fd1498Szrj { 308338fd1498Szrj _M_int.push_back(*__biter); 308438fd1498Szrj _M_den.push_back(__fw(*__biter)); 308538fd1498Szrj } 308638fd1498Szrj 308738fd1498Szrj _M_initialize(); 308838fd1498Szrj } 308938fd1498Szrj 309038fd1498Szrj template<typename _RealType> 309138fd1498Szrj template<typename _Func> 309238fd1498Szrj piecewise_linear_distribution<_RealType>::param_type:: param_type(size_t __nw,_RealType __xmin,_RealType __xmax,_Func __fw)309338fd1498Szrj param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) 309438fd1498Szrj : _M_int(), _M_den(), _M_cp(), _M_m() 309538fd1498Szrj { 309638fd1498Szrj const size_t __n = __nw == 0 ? 1 : __nw; 309738fd1498Szrj const _RealType __delta = (__xmax - __xmin) / __n; 309838fd1498Szrj 309938fd1498Szrj _M_int.reserve(__n + 1); 310038fd1498Szrj _M_den.reserve(__n + 1); 310138fd1498Szrj for (size_t __k = 0; __k <= __nw; ++__k) 310238fd1498Szrj { 310338fd1498Szrj _M_int.push_back(__xmin + __k * __delta); 310438fd1498Szrj _M_den.push_back(__fw(_M_int[__k] + __delta)); 310538fd1498Szrj } 310638fd1498Szrj 310738fd1498Szrj _M_initialize(); 310838fd1498Szrj } 310938fd1498Szrj 311038fd1498Szrj template<typename _RealType> 311138fd1498Szrj template<typename _UniformRandomNumberGenerator> 311238fd1498Szrj typename piecewise_linear_distribution<_RealType>::result_type 311338fd1498Szrj piecewise_linear_distribution<_RealType>:: operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)311438fd1498Szrj operator()(_UniformRandomNumberGenerator& __urng, 311538fd1498Szrj const param_type& __param) 311638fd1498Szrj { 311738fd1498Szrj __detail::_Adaptor<_UniformRandomNumberGenerator, double> 311838fd1498Szrj __aurng(__urng); 311938fd1498Szrj 312038fd1498Szrj const double __p = __aurng(); 312138fd1498Szrj if (__param._M_cp.empty()) 312238fd1498Szrj return __p; 312338fd1498Szrj 312438fd1498Szrj auto __pos = std::lower_bound(__param._M_cp.begin(), 312538fd1498Szrj __param._M_cp.end(), __p); 312638fd1498Szrj const size_t __i = __pos - __param._M_cp.begin(); 312738fd1498Szrj 312838fd1498Szrj const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; 312938fd1498Szrj 313038fd1498Szrj const double __a = 0.5 * __param._M_m[__i]; 313138fd1498Szrj const double __b = __param._M_den[__i]; 313238fd1498Szrj const double __cm = __p - __pref; 313338fd1498Szrj 313438fd1498Szrj _RealType __x = __param._M_int[__i]; 313538fd1498Szrj if (__a == 0) 313638fd1498Szrj __x += __cm / __b; 313738fd1498Szrj else 313838fd1498Szrj { 313938fd1498Szrj const double __d = __b * __b + 4.0 * __a * __cm; 314038fd1498Szrj __x += 0.5 * (std::sqrt(__d) - __b) / __a; 314138fd1498Szrj } 314238fd1498Szrj 314338fd1498Szrj return __x; 314438fd1498Szrj } 314538fd1498Szrj 314638fd1498Szrj template<typename _RealType> 314738fd1498Szrj template<typename _ForwardIterator, 314838fd1498Szrj typename _UniformRandomNumberGenerator> 314938fd1498Szrj void 315038fd1498Szrj piecewise_linear_distribution<_RealType>:: __generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)315138fd1498Szrj __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 315238fd1498Szrj _UniformRandomNumberGenerator& __urng, 315338fd1498Szrj const param_type& __param) 315438fd1498Szrj { 315538fd1498Szrj __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) 315638fd1498Szrj // We could duplicate everything from operator()... 315738fd1498Szrj while (__f != __t) 315838fd1498Szrj *__f++ = this->operator()(__urng, __param); 315938fd1498Szrj } 316038fd1498Szrj 316138fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 316238fd1498Szrj std::basic_ostream<_CharT, _Traits>& operator <<(std::basic_ostream<_CharT,_Traits> & __os,const piecewise_linear_distribution<_RealType> & __x)316338fd1498Szrj operator<<(std::basic_ostream<_CharT, _Traits>& __os, 316438fd1498Szrj const piecewise_linear_distribution<_RealType>& __x) 316538fd1498Szrj { 316638fd1498Szrj typedef std::basic_ostream<_CharT, _Traits> __ostream_type; 316738fd1498Szrj typedef typename __ostream_type::ios_base __ios_base; 316838fd1498Szrj 316938fd1498Szrj const typename __ios_base::fmtflags __flags = __os.flags(); 317038fd1498Szrj const _CharT __fill = __os.fill(); 317138fd1498Szrj const std::streamsize __precision = __os.precision(); 317238fd1498Szrj const _CharT __space = __os.widen(' '); 317338fd1498Szrj __os.flags(__ios_base::scientific | __ios_base::left); 317438fd1498Szrj __os.fill(__space); 317538fd1498Szrj __os.precision(std::numeric_limits<_RealType>::max_digits10); 317638fd1498Szrj 317738fd1498Szrj std::vector<_RealType> __int = __x.intervals(); 317838fd1498Szrj __os << __int.size() - 1; 317938fd1498Szrj 318038fd1498Szrj for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) 318138fd1498Szrj __os << __space << *__xit; 318238fd1498Szrj 318338fd1498Szrj std::vector<double> __den = __x.densities(); 318438fd1498Szrj for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) 318538fd1498Szrj __os << __space << *__dit; 318638fd1498Szrj 318738fd1498Szrj __os.flags(__flags); 318838fd1498Szrj __os.fill(__fill); 318938fd1498Szrj __os.precision(__precision); 319038fd1498Szrj return __os; 319138fd1498Szrj } 319238fd1498Szrj 319338fd1498Szrj template<typename _RealType, typename _CharT, typename _Traits> 319438fd1498Szrj std::basic_istream<_CharT, _Traits>& operator >>(std::basic_istream<_CharT,_Traits> & __is,piecewise_linear_distribution<_RealType> & __x)319538fd1498Szrj operator>>(std::basic_istream<_CharT, _Traits>& __is, 319638fd1498Szrj piecewise_linear_distribution<_RealType>& __x) 319738fd1498Szrj { 319838fd1498Szrj typedef std::basic_istream<_CharT, _Traits> __istream_type; 319938fd1498Szrj typedef typename __istream_type::ios_base __ios_base; 320038fd1498Szrj 320138fd1498Szrj const typename __ios_base::fmtflags __flags = __is.flags(); 320238fd1498Szrj __is.flags(__ios_base::dec | __ios_base::skipws); 320338fd1498Szrj 320438fd1498Szrj size_t __n; 320538fd1498Szrj __is >> __n; 320638fd1498Szrj 320738fd1498Szrj std::vector<_RealType> __int_vec; 320838fd1498Szrj __int_vec.reserve(__n + 1); 320938fd1498Szrj for (size_t __i = 0; __i <= __n; ++__i) 321038fd1498Szrj { 321138fd1498Szrj _RealType __int; 321238fd1498Szrj __is >> __int; 321338fd1498Szrj __int_vec.push_back(__int); 321438fd1498Szrj } 321538fd1498Szrj 321638fd1498Szrj std::vector<double> __den_vec; 321738fd1498Szrj __den_vec.reserve(__n + 1); 321838fd1498Szrj for (size_t __i = 0; __i <= __n; ++__i) 321938fd1498Szrj { 322038fd1498Szrj double __den; 322138fd1498Szrj __is >> __den; 322238fd1498Szrj __den_vec.push_back(__den); 322338fd1498Szrj } 322438fd1498Szrj 322538fd1498Szrj __x.param(typename piecewise_linear_distribution<_RealType>:: 322638fd1498Szrj param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin())); 322738fd1498Szrj 322838fd1498Szrj __is.flags(__flags); 322938fd1498Szrj return __is; 323038fd1498Szrj } 323138fd1498Szrj 323238fd1498Szrj 323338fd1498Szrj template<typename _IntType> seed_seq(std::initializer_list<_IntType> __il)323438fd1498Szrj seed_seq::seed_seq(std::initializer_list<_IntType> __il) 323538fd1498Szrj { 323638fd1498Szrj for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter) 323738fd1498Szrj _M_v.push_back(__detail::__mod<result_type, 323838fd1498Szrj __detail::_Shift<result_type, 32>::__value>(*__iter)); 323938fd1498Szrj } 324038fd1498Szrj 324138fd1498Szrj template<typename _InputIterator> seed_seq(_InputIterator __begin,_InputIterator __end)324238fd1498Szrj seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end) 324338fd1498Szrj { 324438fd1498Szrj for (_InputIterator __iter = __begin; __iter != __end; ++__iter) 324538fd1498Szrj _M_v.push_back(__detail::__mod<result_type, 324638fd1498Szrj __detail::_Shift<result_type, 32>::__value>(*__iter)); 324738fd1498Szrj } 324838fd1498Szrj 324938fd1498Szrj template<typename _RandomAccessIterator> 325038fd1498Szrj void generate(_RandomAccessIterator __begin,_RandomAccessIterator __end)325138fd1498Szrj seed_seq::generate(_RandomAccessIterator __begin, 325238fd1498Szrj _RandomAccessIterator __end) 325338fd1498Szrj { 325438fd1498Szrj typedef typename iterator_traits<_RandomAccessIterator>::value_type 325538fd1498Szrj _Type; 325638fd1498Szrj 325738fd1498Szrj if (__begin == __end) 325838fd1498Szrj return; 325938fd1498Szrj 326038fd1498Szrj std::fill(__begin, __end, _Type(0x8b8b8b8bu)); 326138fd1498Szrj 326238fd1498Szrj const size_t __n = __end - __begin; 326338fd1498Szrj const size_t __s = _M_v.size(); 326438fd1498Szrj const size_t __t = (__n >= 623) ? 11 326538fd1498Szrj : (__n >= 68) ? 7 326638fd1498Szrj : (__n >= 39) ? 5 326738fd1498Szrj : (__n >= 7) ? 3 326838fd1498Szrj : (__n - 1) / 2; 326938fd1498Szrj const size_t __p = (__n - __t) / 2; 327038fd1498Szrj const size_t __q = __p + __t; 327138fd1498Szrj const size_t __m = std::max(size_t(__s + 1), __n); 327238fd1498Szrj 327338fd1498Szrj for (size_t __k = 0; __k < __m; ++__k) 327438fd1498Szrj { 327538fd1498Szrj _Type __arg = (__begin[__k % __n] 327638fd1498Szrj ^ __begin[(__k + __p) % __n] 327738fd1498Szrj ^ __begin[(__k - 1) % __n]); 327838fd1498Szrj _Type __r1 = __arg ^ (__arg >> 27); 327938fd1498Szrj __r1 = __detail::__mod<_Type, 328038fd1498Szrj __detail::_Shift<_Type, 32>::__value>(1664525u * __r1); 328138fd1498Szrj _Type __r2 = __r1; 328238fd1498Szrj if (__k == 0) 328338fd1498Szrj __r2 += __s; 328438fd1498Szrj else if (__k <= __s) 328538fd1498Szrj __r2 += __k % __n + _M_v[__k - 1]; 328638fd1498Szrj else 328738fd1498Szrj __r2 += __k % __n; 328838fd1498Szrj __r2 = __detail::__mod<_Type, 328938fd1498Szrj __detail::_Shift<_Type, 32>::__value>(__r2); 329038fd1498Szrj __begin[(__k + __p) % __n] += __r1; 329138fd1498Szrj __begin[(__k + __q) % __n] += __r2; 329238fd1498Szrj __begin[__k % __n] = __r2; 329338fd1498Szrj } 329438fd1498Szrj 329538fd1498Szrj for (size_t __k = __m; __k < __m + __n; ++__k) 329638fd1498Szrj { 329738fd1498Szrj _Type __arg = (__begin[__k % __n] 329838fd1498Szrj + __begin[(__k + __p) % __n] 329938fd1498Szrj + __begin[(__k - 1) % __n]); 330038fd1498Szrj _Type __r3 = __arg ^ (__arg >> 27); 330138fd1498Szrj __r3 = __detail::__mod<_Type, 330238fd1498Szrj __detail::_Shift<_Type, 32>::__value>(1566083941u * __r3); 330338fd1498Szrj _Type __r4 = __r3 - __k % __n; 330438fd1498Szrj __r4 = __detail::__mod<_Type, 330538fd1498Szrj __detail::_Shift<_Type, 32>::__value>(__r4); 330638fd1498Szrj __begin[(__k + __p) % __n] ^= __r3; 330738fd1498Szrj __begin[(__k + __q) % __n] ^= __r4; 330838fd1498Szrj __begin[__k % __n] = __r4; 330938fd1498Szrj } 331038fd1498Szrj } 331138fd1498Szrj 331238fd1498Szrj template<typename _RealType, size_t __bits, 331338fd1498Szrj typename _UniformRandomNumberGenerator> 331438fd1498Szrj _RealType generate_canonical(_UniformRandomNumberGenerator & __urng)331538fd1498Szrj generate_canonical(_UniformRandomNumberGenerator& __urng) 331638fd1498Szrj { 331738fd1498Szrj static_assert(std::is_floating_point<_RealType>::value, 331838fd1498Szrj "template argument must be a floating point type"); 331938fd1498Szrj 332038fd1498Szrj const size_t __b 332138fd1498Szrj = std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits), 332238fd1498Szrj __bits); 332338fd1498Szrj const long double __r = static_cast<long double>(__urng.max()) 332438fd1498Szrj - static_cast<long double>(__urng.min()) + 1.0L; 332538fd1498Szrj const size_t __log2r = std::log(__r) / std::log(2.0L); 332638fd1498Szrj const size_t __m = std::max<size_t>(1UL, 332738fd1498Szrj (__b + __log2r - 1UL) / __log2r); 332838fd1498Szrj _RealType __ret; 332938fd1498Szrj _RealType __sum = _RealType(0); 333038fd1498Szrj _RealType __tmp = _RealType(1); 333138fd1498Szrj for (size_t __k = __m; __k != 0; --__k) 333238fd1498Szrj { 333338fd1498Szrj __sum += _RealType(__urng() - __urng.min()) * __tmp; 333438fd1498Szrj __tmp *= __r; 333538fd1498Szrj } 333638fd1498Szrj __ret = __sum / __tmp; 333738fd1498Szrj if (__builtin_expect(__ret >= _RealType(1), 0)) 333838fd1498Szrj { 333938fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1 334038fd1498Szrj __ret = std::nextafter(_RealType(1), _RealType(0)); 334138fd1498Szrj #else 334238fd1498Szrj __ret = _RealType(1) 334338fd1498Szrj - std::numeric_limits<_RealType>::epsilon() / _RealType(2); 334438fd1498Szrj #endif 334538fd1498Szrj } 334638fd1498Szrj return __ret; 334738fd1498Szrj } 334838fd1498Szrj 334938fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 335038fd1498Szrj } // namespace 335138fd1498Szrj 335238fd1498Szrj #endif 3353