Home | History | Annotate | Line # | Download | only in ext
      1 // Random number extensions -*- C++ -*-
      2 
      3 // Copyright (C) 2012-2022 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file ext/random
     26  *  This file is a GNU extension to the Standard C++ Library.
     27  */
     28 
     29 #ifndef _EXT_RANDOM
     30 #define _EXT_RANDOM 1
     31 
     32 #pragma GCC system_header
     33 
     34 #if __cplusplus < 201103L
     35 # include <bits/c++0x_warning.h>
     36 #else
     37 
     38 #include <random>
     39 #include <algorithm>
     40 #include <array>
     41 #include <ext/cmath>
     42 #ifdef __SSE2__
     43 # include <emmintrin.h>
     44 #endif
     45 
     46 #if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C)
     47 
     48 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
     49 {
     50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     51 
     52 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     53 
     54   /* Mersenne twister implementation optimized for vector operations.
     55    *
     56    * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
     57    */
     58   template<typename _UIntType, size_t __m,
     59 	   size_t __pos1, size_t __sl1, size_t __sl2,
     60 	   size_t __sr1, size_t __sr2,
     61 	   uint32_t __msk1, uint32_t __msk2,
     62 	   uint32_t __msk3, uint32_t __msk4,
     63 	   uint32_t __parity1, uint32_t __parity2,
     64 	   uint32_t __parity3, uint32_t __parity4>
     65     class simd_fast_mersenne_twister_engine
     66     {
     67       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
     68 		    "substituting _UIntType not an unsigned integral type");
     69       static_assert(__sr1 < 32, "first right shift too large");
     70       static_assert(__sr2 < 16, "second right shift too large");
     71       static_assert(__sl1 < 32, "first left shift too large");
     72       static_assert(__sl2 < 16, "second left shift too large");
     73 
     74     public:
     75       typedef _UIntType result_type;
     76 
     77     private:
     78       static constexpr size_t m_w = sizeof(result_type) * 8;
     79       static constexpr size_t _M_nstate = __m / 128 + 1;
     80       static constexpr size_t _M_nstate32 = _M_nstate * 4;
     81 
     82       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
     83 		    "substituting _UIntType not an unsigned integral type");
     84       static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size");
     85       static_assert(16 % sizeof(_UIntType) == 0,
     86 		    "UIntType size must divide 16");
     87 
     88       template<typename _Sseq>
     89 	using _If_seed_seq
     90 	  = typename std::enable_if<std::__detail::__is_seed_seq<
     91 	    _Sseq, simd_fast_mersenne_twister_engine, result_type>::value
     92 	    >::type;
     93 
     94     public:
     95       static constexpr size_t state_size = _M_nstate * (16
     96 							/ sizeof(result_type));
     97       static constexpr result_type default_seed = 5489u;
     98 
     99       // constructors and member functions
    100 
    101       simd_fast_mersenne_twister_engine()
    102       : simd_fast_mersenne_twister_engine(default_seed)
    103       { }
    104 
    105       explicit
    106       simd_fast_mersenne_twister_engine(result_type __sd)
    107       { seed(__sd); }
    108 
    109       template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
    110 	explicit
    111 	simd_fast_mersenne_twister_engine(_Sseq& __q)
    112 	{ seed(__q); }
    113 
    114       void
    115       seed(result_type __sd = default_seed);
    116 
    117       template<typename _Sseq>
    118 	_If_seed_seq<_Sseq>
    119 	seed(_Sseq& __q);
    120 
    121       static constexpr result_type
    122       min()
    123       { return 0; }
    124 
    125       static constexpr result_type
    126       max()
    127       { return std::numeric_limits<result_type>::max(); }
    128 
    129       void
    130       discard(unsigned long long __z);
    131 
    132       result_type
    133       operator()()
    134       {
    135 	if (__builtin_expect(_M_pos >= state_size, 0))
    136 	  _M_gen_rand();
    137 
    138 	return _M_stateT[_M_pos++];
    139       }
    140 
    141       template<typename _UIntType_2, size_t __m_2,
    142 	       size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
    143 	       size_t __sr1_2, size_t __sr2_2,
    144 	       uint32_t __msk1_2, uint32_t __msk2_2,
    145 	       uint32_t __msk3_2, uint32_t __msk4_2,
    146 	       uint32_t __parity1_2, uint32_t __parity2_2,
    147 	       uint32_t __parity3_2, uint32_t __parity4_2>
    148 	friend bool
    149 	operator==(const simd_fast_mersenne_twister_engine<_UIntType_2,
    150 		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
    151 		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
    152 		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs,
    153 		   const simd_fast_mersenne_twister_engine<_UIntType_2,
    154 		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
    155 		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
    156 		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs);
    157 
    158       template<typename _UIntType_2, size_t __m_2,
    159 	       size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
    160 	       size_t __sr1_2, size_t __sr2_2,
    161 	       uint32_t __msk1_2, uint32_t __msk2_2,
    162 	       uint32_t __msk3_2, uint32_t __msk4_2,
    163 	       uint32_t __parity1_2, uint32_t __parity2_2,
    164 	       uint32_t __parity3_2, uint32_t __parity4_2,
    165 	       typename _CharT, typename _Traits>
    166 	friend std::basic_ostream<_CharT, _Traits>&
    167 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    168 		   const __gnu_cxx::simd_fast_mersenne_twister_engine
    169 		   <_UIntType_2,
    170 		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
    171 		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
    172 		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
    173 
    174       template<typename _UIntType_2, size_t __m_2,
    175 	       size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
    176 	       size_t __sr1_2, size_t __sr2_2,
    177 	       uint32_t __msk1_2, uint32_t __msk2_2,
    178 	       uint32_t __msk3_2, uint32_t __msk4_2,
    179 	       uint32_t __parity1_2, uint32_t __parity2_2,
    180 	       uint32_t __parity3_2, uint32_t __parity4_2,
    181 	       typename _CharT, typename _Traits>
    182 	friend std::basic_istream<_CharT, _Traits>&
    183 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
    184 		   __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2,
    185 		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
    186 		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
    187 		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
    188 
    189     private:
    190       union
    191       {
    192 #ifdef __SSE2__
    193 	__m128i _M_state[_M_nstate];
    194 #endif
    195 #ifdef __ARM_NEON
    196 #ifdef __aarch64__
    197 	__Uint32x4_t _M_state[_M_nstate];
    198 #endif
    199 #endif
    200 	uint32_t _M_state32[_M_nstate32];
    201 	result_type _M_stateT[state_size];
    202       } __attribute__ ((__aligned__ (16)));
    203       size_t _M_pos;
    204 
    205       void _M_gen_rand(void);
    206       void _M_period_certification();
    207   };
    208 
    209 
    210   template<typename _UIntType, size_t __m,
    211 	   size_t __pos1, size_t __sl1, size_t __sl2,
    212 	   size_t __sr1, size_t __sr2,
    213 	   uint32_t __msk1, uint32_t __msk2,
    214 	   uint32_t __msk3, uint32_t __msk4,
    215 	   uint32_t __parity1, uint32_t __parity2,
    216 	   uint32_t __parity3, uint32_t __parity4>
    217     inline bool
    218     operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
    219 	       __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
    220 	       __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs,
    221 	       const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
    222 	       __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
    223 	       __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs)
    224     { return !(__lhs == __rhs); }
    225 
    226 
    227   /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined
    228    * in the C implementation by Daito and Matsumoto, as both a 32-bit
    229    * and 64-bit version.
    230    */
    231   typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2,
    232 					    15, 3, 13, 3,
    233 					    0xfdff37ffU, 0xef7f3f7dU,
    234 					    0xff777b7dU, 0x7ff7fb2fU,
    235 					    0x00000001U, 0x00000000U,
    236 					    0x00000000U, 0x5986f054U>
    237     sfmt607;
    238 
    239   typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2,
    240 					    15, 3, 13, 3,
    241 					    0xfdff37ffU, 0xef7f3f7dU,
    242 					    0xff777b7dU, 0x7ff7fb2fU,
    243 					    0x00000001U, 0x00000000U,
    244 					    0x00000000U, 0x5986f054U>
    245     sfmt607_64;
    246 
    247 
    248   typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7,
    249 					    14, 3, 5, 1,
    250 					    0xf7fefffdU, 0x7fefcfffU,
    251 					    0xaff3ef3fU, 0xb5ffff7fU,
    252 					    0x00000001U, 0x00000000U,
    253 					    0x00000000U, 0x20000000U>
    254     sfmt1279;
    255 
    256   typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7,
    257 					    14, 3, 5, 1,
    258 					    0xf7fefffdU, 0x7fefcfffU,
    259 					    0xaff3ef3fU, 0xb5ffff7fU,
    260 					    0x00000001U, 0x00000000U,
    261 					    0x00000000U, 0x20000000U>
    262     sfmt1279_64;
    263 
    264 
    265   typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12,
    266 					    19, 1, 5, 1,
    267 					    0xbff7ffbfU, 0xfdfffffeU,
    268 					    0xf7ffef7fU, 0xf2f7cbbfU,
    269 					    0x00000001U, 0x00000000U,
    270 					    0x00000000U, 0x41dfa600U>
    271     sfmt2281;
    272 
    273   typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12,
    274 					    19, 1, 5, 1,
    275 					    0xbff7ffbfU, 0xfdfffffeU,
    276 					    0xf7ffef7fU, 0xf2f7cbbfU,
    277 					    0x00000001U, 0x00000000U,
    278 					    0x00000000U, 0x41dfa600U>
    279     sfmt2281_64;
    280 
    281 
    282   typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17,
    283 					    20, 1, 7, 1,
    284 					    0x9f7bffffU, 0x9fffff5fU,
    285 					    0x3efffffbU, 0xfffff7bbU,
    286 					    0xa8000001U, 0xaf5390a3U,
    287 					    0xb740b3f8U, 0x6c11486dU>
    288     sfmt4253;
    289 
    290   typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17,
    291 					    20, 1, 7, 1,
    292 					    0x9f7bffffU, 0x9fffff5fU,
    293 					    0x3efffffbU, 0xfffff7bbU,
    294 					    0xa8000001U, 0xaf5390a3U,
    295 					    0xb740b3f8U, 0x6c11486dU>
    296     sfmt4253_64;
    297 
    298 
    299   typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68,
    300 					    14, 3, 7, 3,
    301 					    0xeffff7fbU, 0xffffffefU,
    302 					    0xdfdfbfffU, 0x7fffdbfdU,
    303 					    0x00000001U, 0x00000000U,
    304 					    0xe8148000U, 0xd0c7afa3U>
    305     sfmt11213;
    306 
    307   typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68,
    308 					    14, 3, 7, 3,
    309 					    0xeffff7fbU, 0xffffffefU,
    310 					    0xdfdfbfffU, 0x7fffdbfdU,
    311 					    0x00000001U, 0x00000000U,
    312 					    0xe8148000U, 0xd0c7afa3U>
    313     sfmt11213_64;
    314 
    315 
    316   typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122,
    317 					    18, 1, 11, 1,
    318 					    0xdfffffefU, 0xddfecb7fU,
    319 					    0xbffaffffU, 0xbffffff6U,
    320 					    0x00000001U, 0x00000000U,
    321 					    0x00000000U, 0x13c9e684U>
    322     sfmt19937;
    323 
    324   typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122,
    325 					    18, 1, 11, 1,
    326 					    0xdfffffefU, 0xddfecb7fU,
    327 					    0xbffaffffU, 0xbffffff6U,
    328 					    0x00000001U, 0x00000000U,
    329 					    0x00000000U, 0x13c9e684U>
    330     sfmt19937_64;
    331 
    332 
    333   typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330,
    334 					    5, 3, 9, 3,
    335 					    0xeffffffbU, 0xdfbebfffU,
    336 					    0xbfbf7befU, 0x9ffd7bffU,
    337 					    0x00000001U, 0x00000000U,
    338 					    0xa3ac4000U, 0xecc1327aU>
    339     sfmt44497;
    340 
    341   typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330,
    342 					    5, 3, 9, 3,
    343 					    0xeffffffbU, 0xdfbebfffU,
    344 					    0xbfbf7befU, 0x9ffd7bffU,
    345 					    0x00000001U, 0x00000000U,
    346 					    0xa3ac4000U, 0xecc1327aU>
    347     sfmt44497_64;
    348 
    349 #if __SIZE_WIDTH__ >= 32
    350 
    351   typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366,
    352 					    6, 7, 19, 1,
    353 					    0xfdbffbffU, 0xbff7ff3fU,
    354 					    0xfd77efffU, 0xbf9ff3ffU,
    355 					    0x00000001U, 0x00000000U,
    356 					    0x00000000U, 0xe9528d85U>
    357     sfmt86243;
    358 
    359   typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366,
    360 					    6, 7, 19, 1,
    361 					    0xfdbffbffU, 0xbff7ff3fU,
    362 					    0xfd77efffU, 0xbf9ff3ffU,
    363 					    0x00000001U, 0x00000000U,
    364 					    0x00000000U, 0xe9528d85U>
    365     sfmt86243_64;
    366 
    367 
    368   typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110,
    369 					    19, 1, 21, 1,
    370 					    0xffffbb5fU, 0xfb6ebf95U,
    371 					    0xfffefffaU, 0xcff77fffU,
    372 					    0x00000001U, 0x00000000U,
    373 					    0xcb520000U, 0xc7e91c7dU>
    374     sfmt132049;
    375 
    376   typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110,
    377 					    19, 1, 21, 1,
    378 					    0xffffbb5fU, 0xfb6ebf95U,
    379 					    0xfffefffaU, 0xcff77fffU,
    380 					    0x00000001U, 0x00000000U,
    381 					    0xcb520000U, 0xc7e91c7dU>
    382     sfmt132049_64;
    383 
    384 
    385   typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627,
    386 					    11, 3, 10, 1,
    387 					    0xbff7bff7U, 0xbfffffffU,
    388 					    0xbffffa7fU, 0xffddfbfbU,
    389 					    0xf8000001U, 0x89e80709U,
    390 					    0x3bd2b64bU, 0x0c64b1e4U>
    391     sfmt216091;
    392 
    393   typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627,
    394 					    11, 3, 10, 1,
    395 					    0xbff7bff7U, 0xbfffffffU,
    396 					    0xbffffa7fU, 0xffddfbfbU,
    397 					    0xf8000001U, 0x89e80709U,
    398 					    0x3bd2b64bU, 0x0c64b1e4U>
    399     sfmt216091_64;
    400 #endif // __SIZE_WIDTH__ >= 32
    401 
    402 #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    403 
    404   /**
    405    * @brief A beta continuous distribution for random numbers.
    406    *
    407    * The formula for the beta probability density function is:
    408    * @f[
    409    *     p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)}
    410    *                         x^{\alpha - 1} (1 - x)^{\beta - 1}
    411    * @f]
    412    */
    413   template<typename _RealType = double>
    414     class beta_distribution
    415     {
    416       static_assert(std::is_floating_point<_RealType>::value,
    417 		    "template argument not a floating point type");
    418 
    419     public:
    420       /** The type of the range of the distribution. */
    421       typedef _RealType result_type;
    422 
    423       /** Parameter type. */
    424       struct param_type
    425       {
    426 	typedef beta_distribution<_RealType> distribution_type;
    427 	friend class beta_distribution<_RealType>;
    428 
    429 	param_type() : param_type(1) { }
    430 
    431 	explicit
    432 	param_type(_RealType __alpha_val, _RealType __beta_val = _RealType(1))
    433 	: _M_alpha(__alpha_val), _M_beta(__beta_val)
    434 	{
    435 	  __glibcxx_assert(_M_alpha > _RealType(0));
    436 	  __glibcxx_assert(_M_beta > _RealType(0));
    437 	}
    438 
    439 	_RealType
    440 	alpha() const
    441 	{ return _M_alpha; }
    442 
    443 	_RealType
    444 	beta() const
    445 	{ return _M_beta; }
    446 
    447 	friend bool
    448 	operator==(const param_type& __p1, const param_type& __p2)
    449 	{ return (__p1._M_alpha == __p2._M_alpha
    450 		  && __p1._M_beta == __p2._M_beta); }
    451 
    452 	friend bool
    453 	operator!=(const param_type& __p1, const param_type& __p2)
    454 	{ return !(__p1 == __p2); }
    455 
    456       private:
    457 	void
    458 	_M_initialize();
    459 
    460 	_RealType _M_alpha;
    461 	_RealType _M_beta;
    462       };
    463 
    464     public:
    465       beta_distribution() : beta_distribution(1.0) { }
    466 
    467       /**
    468        * @brief Constructs a beta distribution with parameters
    469        * @f$\alpha@f$ and @f$\beta@f$.
    470        */
    471       explicit
    472       beta_distribution(_RealType __alpha_val,
    473 			_RealType __beta_val = _RealType(1))
    474       : _M_param(__alpha_val, __beta_val)
    475       { }
    476 
    477       explicit
    478       beta_distribution(const param_type& __p)
    479       : _M_param(__p)
    480       { }
    481 
    482       /**
    483        * @brief Resets the distribution state.
    484        */
    485       void
    486       reset()
    487       { }
    488 
    489       /**
    490        * @brief Returns the @f$\alpha@f$ of the distribution.
    491        */
    492       _RealType
    493       alpha() const
    494       { return _M_param.alpha(); }
    495 
    496       /**
    497        * @brief Returns the @f$\beta@f$ of the distribution.
    498        */
    499       _RealType
    500       beta() const
    501       { return _M_param.beta(); }
    502 
    503       /**
    504        * @brief Returns the parameter set of the distribution.
    505        */
    506       param_type
    507       param() const
    508       { return _M_param; }
    509 
    510       /**
    511        * @brief Sets the parameter set of the distribution.
    512        * @param __param The new parameter set of the distribution.
    513        */
    514       void
    515       param(const param_type& __param)
    516       { _M_param = __param; }
    517 
    518       /**
    519        * @brief Returns the greatest lower bound value of the distribution.
    520        */
    521       result_type
    522       min() const
    523       { return result_type(0); }
    524 
    525       /**
    526        * @brief Returns the least upper bound value of the distribution.
    527        */
    528       result_type
    529       max() const
    530       { return result_type(1); }
    531 
    532       /**
    533        * @brief Generating functions.
    534        */
    535       template<typename _UniformRandomNumberGenerator>
    536 	result_type
    537 	operator()(_UniformRandomNumberGenerator& __urng)
    538 	{ return this->operator()(__urng, _M_param); }
    539 
    540       template<typename _UniformRandomNumberGenerator>
    541 	result_type
    542 	operator()(_UniformRandomNumberGenerator& __urng,
    543 		   const param_type& __p);
    544 
    545       template<typename _ForwardIterator,
    546 	       typename _UniformRandomNumberGenerator>
    547 	void
    548 	__generate(_ForwardIterator __f, _ForwardIterator __t,
    549 		   _UniformRandomNumberGenerator& __urng)
    550 	{ this->__generate(__f, __t, __urng, _M_param); }
    551 
    552       template<typename _ForwardIterator,
    553 	       typename _UniformRandomNumberGenerator>
    554 	void
    555 	__generate(_ForwardIterator __f, _ForwardIterator __t,
    556 		   _UniformRandomNumberGenerator& __urng,
    557 		   const param_type& __p)
    558 	{ this->__generate_impl(__f, __t, __urng, __p); }
    559 
    560       template<typename _UniformRandomNumberGenerator>
    561 	void
    562 	__generate(result_type* __f, result_type* __t,
    563 		   _UniformRandomNumberGenerator& __urng,
    564 		   const param_type& __p)
    565 	{ this->__generate_impl(__f, __t, __urng, __p); }
    566 
    567       /**
    568        * @brief Return true if two beta distributions have the same
    569        *        parameters and the sequences that would be generated
    570        *        are equal.
    571        */
    572       friend bool
    573       operator==(const beta_distribution& __d1,
    574 		 const beta_distribution& __d2)
    575       { return __d1._M_param == __d2._M_param; }
    576 
    577       /**
    578        * @brief Inserts a %beta_distribution random number distribution
    579        * @p __x into the output stream @p __os.
    580        *
    581        * @param __os An output stream.
    582        * @param __x  A %beta_distribution random number distribution.
    583        *
    584        * @returns The output stream with the state of @p __x inserted or in
    585        * an error state.
    586        */
    587       template<typename _RealType1, typename _CharT, typename _Traits>
    588 	friend std::basic_ostream<_CharT, _Traits>&
    589 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    590 		   const __gnu_cxx::beta_distribution<_RealType1>& __x);
    591 
    592       /**
    593        * @brief Extracts a %beta_distribution random number distribution
    594        * @p __x from the input stream @p __is.
    595        *
    596        * @param __is An input stream.
    597        * @param __x  A %beta_distribution random number generator engine.
    598        *
    599        * @returns The input stream with @p __x extracted or in an error state.
    600        */
    601       template<typename _RealType1, typename _CharT, typename _Traits>
    602 	friend std::basic_istream<_CharT, _Traits>&
    603 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
    604 		   __gnu_cxx::beta_distribution<_RealType1>& __x);
    605 
    606     private:
    607       template<typename _ForwardIterator,
    608 	       typename _UniformRandomNumberGenerator>
    609 	void
    610 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
    611 			_UniformRandomNumberGenerator& __urng,
    612 			const param_type& __p);
    613 
    614       param_type _M_param;
    615     };
    616 
    617   /**
    618    * @brief Return true if two beta distributions are different.
    619    */
    620   template<typename _RealType>
    621     inline bool
    622     operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
    623 	       const __gnu_cxx::beta_distribution<_RealType>& __d2)
    624     { return !(__d1 == __d2); }
    625 
    626 
    627   /**
    628    * @brief A multi-variate normal continuous distribution for random numbers.
    629    *
    630    * The formula for the normal probability density function is
    631    * @f[
    632    *     p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) =
    633    *       \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}}
    634    *       e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T}
    635    *          \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})}
    636    * @f]
    637    *
    638    * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are
    639    * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance
    640    * matrix (which must be positive-definite).
    641    */
    642   template<std::size_t _Dimen, typename _RealType = double>
    643     class normal_mv_distribution
    644     {
    645       static_assert(std::is_floating_point<_RealType>::value,
    646 		    "template argument not a floating point type");
    647       static_assert(_Dimen != 0, "dimension is zero");
    648 
    649     public:
    650       /** The type of the range of the distribution. */
    651       typedef std::array<_RealType, _Dimen> result_type;
    652       /** Parameter type. */
    653       class param_type
    654       {
    655 	static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2;
    656 
    657       public:
    658 	typedef normal_mv_distribution<_Dimen, _RealType> distribution_type;
    659 	friend class normal_mv_distribution<_Dimen, _RealType>;
    660 
    661 	param_type()
    662 	{
    663 	  std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0));
    664 	  auto __it = _M_t.begin();
    665 	  for (size_t __i = 0; __i < _Dimen; ++__i)
    666 	    {
    667 	      std::fill_n(__it, __i, _RealType(0));
    668 	      __it += __i;
    669 	      *__it++ = _RealType(1);
    670 	    }
    671 	}
    672 
    673 	template<typename _ForwardIterator1, typename _ForwardIterator2>
    674 	  param_type(_ForwardIterator1 __meanbegin,
    675 		     _ForwardIterator1 __meanend,
    676 		     _ForwardIterator2 __varcovbegin,
    677 		     _ForwardIterator2 __varcovend)
    678 	{
    679 	  __glibcxx_function_requires(_ForwardIteratorConcept<
    680 				      _ForwardIterator1>)
    681 	  __glibcxx_function_requires(_ForwardIteratorConcept<
    682 				      _ForwardIterator2>)
    683 	  _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend)
    684 				<= _Dimen);
    685 	  const auto __dist = std::distance(__varcovbegin, __varcovend);
    686 	  _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen
    687 				|| __dist == _Dimen * (_Dimen + 1) / 2
    688 				|| __dist == _Dimen);
    689 
    690 	  if (__dist == _Dimen * _Dimen)
    691 	    _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend);
    692 	  else if (__dist == _Dimen * (_Dimen + 1) / 2)
    693 	    _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend);
    694 	  else
    695 	    {
    696 	      __glibcxx_assert(__dist == _Dimen);
    697 	      _M_init_diagonal(__meanbegin, __meanend,
    698 			       __varcovbegin, __varcovend);
    699 	    }
    700 	}
    701 
    702 	param_type(std::initializer_list<_RealType> __mean,
    703 		   std::initializer_list<_RealType> __varcov)
    704 	{
    705 	  _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen);
    706 	  _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen
    707 				|| __varcov.size() == _Dimen * (_Dimen + 1) / 2
    708 				|| __varcov.size() == _Dimen);
    709 
    710 	  if (__varcov.size() == _Dimen * _Dimen)
    711 	    _M_init_full(__mean.begin(), __mean.end(),
    712 			 __varcov.begin(), __varcov.end());
    713 	  else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2)
    714 	    _M_init_lower(__mean.begin(), __mean.end(),
    715 			  __varcov.begin(), __varcov.end());
    716 	  else
    717 	    {
    718 	      __glibcxx_assert(__varcov.size() == _Dimen);
    719 	      _M_init_diagonal(__mean.begin(), __mean.end(),
    720 			       __varcov.begin(), __varcov.end());
    721 	    }
    722 	}
    723 
    724 	std::array<_RealType, _Dimen>
    725 	mean() const
    726 	{ return _M_mean; }
    727 
    728 	std::array<_RealType, _M_t_size>
    729 	varcov() const
    730 	{ return _M_t; }
    731 
    732 	friend bool
    733 	operator==(const param_type& __p1, const param_type& __p2)
    734 	{ return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; }
    735 
    736 	friend bool
    737 	operator!=(const param_type& __p1, const param_type& __p2)
    738 	{ return !(__p1 == __p2); }
    739 
    740       private:
    741 	template <typename _InputIterator1, typename _InputIterator2>
    742 	  void _M_init_full(_InputIterator1 __meanbegin,
    743 			    _InputIterator1 __meanend,
    744 			    _InputIterator2 __varcovbegin,
    745 			    _InputIterator2 __varcovend);
    746 	template <typename _InputIterator1, typename _InputIterator2>
    747 	  void _M_init_lower(_InputIterator1 __meanbegin,
    748 			     _InputIterator1 __meanend,
    749 			     _InputIterator2 __varcovbegin,
    750 			     _InputIterator2 __varcovend);
    751 	template <typename _InputIterator1, typename _InputIterator2>
    752 	  void _M_init_diagonal(_InputIterator1 __meanbegin,
    753 				_InputIterator1 __meanend,
    754 				_InputIterator2 __varbegin,
    755 				_InputIterator2 __varend);
    756 
    757 	// param_type constructors apply Cholesky decomposition to the
    758 	// varcov matrix in _M_init_full and _M_init_lower, but the
    759 	// varcov matrix output ot a stream is already decomposed, so
    760 	// we need means to restore it as-is when reading it back in.
    761 	template<size_t _Dimen1, typename _RealType1,
    762 		 typename _CharT, typename _Traits>
    763 	friend std::basic_istream<_CharT, _Traits>&
    764 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
    765 		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
    766 		   __x);
    767 	param_type(std::array<_RealType, _Dimen> const &__mean,
    768 		   std::array<_RealType, _M_t_size> const &__varcov)
    769 	  : _M_mean (__mean), _M_t (__varcov)
    770 	{}
    771 
    772 	std::array<_RealType, _Dimen> _M_mean;
    773 	std::array<_RealType, _M_t_size> _M_t;
    774       };
    775 
    776     public:
    777       normal_mv_distribution()
    778       : _M_param(), _M_nd()
    779       { }
    780 
    781       template<typename _ForwardIterator1, typename _ForwardIterator2>
    782 	normal_mv_distribution(_ForwardIterator1 __meanbegin,
    783 			       _ForwardIterator1 __meanend,
    784 			       _ForwardIterator2 __varcovbegin,
    785 			       _ForwardIterator2 __varcovend)
    786 	: _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend),
    787 	  _M_nd()
    788 	{ }
    789 
    790       normal_mv_distribution(std::initializer_list<_RealType> __mean,
    791 			     std::initializer_list<_RealType> __varcov)
    792       : _M_param(__mean, __varcov), _M_nd()
    793       { }
    794 
    795       explicit
    796       normal_mv_distribution(const param_type& __p)
    797       : _M_param(__p), _M_nd()
    798       { }
    799 
    800       /**
    801        * @brief Resets the distribution state.
    802        */
    803       void
    804       reset()
    805       { _M_nd.reset(); }
    806 
    807       /**
    808        * @brief Returns the mean of the distribution.
    809        */
    810       result_type
    811       mean() const
    812       { return _M_param.mean(); }
    813 
    814       /**
    815        * @brief Returns the compact form of the variance/covariance
    816        * matrix of the distribution.
    817        */
    818       std::array<_RealType, _Dimen * (_Dimen + 1) / 2>
    819       varcov() const
    820       { return _M_param.varcov(); }
    821 
    822       /**
    823        * @brief Returns the parameter set of the distribution.
    824        */
    825       param_type
    826       param() const
    827       { return _M_param; }
    828 
    829       /**
    830        * @brief Sets the parameter set of the distribution.
    831        * @param __param The new parameter set of the distribution.
    832        */
    833       void
    834       param(const param_type& __param)
    835       { _M_param = __param; }
    836 
    837       /**
    838        * @brief Returns the greatest lower bound value of the distribution.
    839        */
    840       result_type
    841       min() const
    842       { result_type __res;
    843 	__res.fill(std::numeric_limits<_RealType>::lowest());
    844 	return __res; }
    845 
    846       /**
    847        * @brief Returns the least upper bound value of the distribution.
    848        */
    849       result_type
    850       max() const
    851       { result_type __res;
    852 	__res.fill(std::numeric_limits<_RealType>::max());
    853 	return __res; }
    854 
    855       /**
    856        * @brief Generating functions.
    857        */
    858       template<typename _UniformRandomNumberGenerator>
    859 	result_type
    860 	operator()(_UniformRandomNumberGenerator& __urng)
    861 	{ return this->operator()(__urng, _M_param); }
    862 
    863       template<typename _UniformRandomNumberGenerator>
    864 	result_type
    865 	operator()(_UniformRandomNumberGenerator& __urng,
    866 		   const param_type& __p);
    867 
    868       template<typename _ForwardIterator,
    869 	       typename _UniformRandomNumberGenerator>
    870 	void
    871 	__generate(_ForwardIterator __f, _ForwardIterator __t,
    872 		   _UniformRandomNumberGenerator& __urng)
    873 	{ return this->__generate_impl(__f, __t, __urng, _M_param); }
    874 
    875       template<typename _ForwardIterator,
    876 	       typename _UniformRandomNumberGenerator>
    877 	void
    878 	__generate(_ForwardIterator __f, _ForwardIterator __t,
    879 		   _UniformRandomNumberGenerator& __urng,
    880 		   const param_type& __p)
    881 	{ return this->__generate_impl(__f, __t, __urng, __p); }
    882 
    883       /**
    884        * @brief Return true if two multi-variant normal distributions have
    885        *        the same parameters and the sequences that would
    886        *        be generated are equal.
    887        */
    888       template<size_t _Dimen1, typename _RealType1>
    889 	friend bool
    890 	operator==(const
    891 		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
    892 		   __d1,
    893 		   const
    894 		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
    895 		   __d2);
    896 
    897       /**
    898        * @brief Inserts a %normal_mv_distribution random number distribution
    899        * @p __x into the output stream @p __os.
    900        *
    901        * @param __os An output stream.
    902        * @param __x  A %normal_mv_distribution random number distribution.
    903        *
    904        * @returns The output stream with the state of @p __x inserted or in
    905        * an error state.
    906        */
    907       template<size_t _Dimen1, typename _RealType1,
    908 	       typename _CharT, typename _Traits>
    909 	friend std::basic_ostream<_CharT, _Traits>&
    910 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
    911 		   const
    912 		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
    913 		   __x);
    914 
    915       /**
    916        * @brief Extracts a %normal_mv_distribution random number distribution
    917        * @p __x from the input stream @p __is.
    918        *
    919        * @param __is An input stream.
    920        * @param __x  A %normal_mv_distribution random number generator engine.
    921        *
    922        * @returns The input stream with @p __x extracted or in an error
    923        *          state.
    924        */
    925       template<size_t _Dimen1, typename _RealType1,
    926 	       typename _CharT, typename _Traits>
    927 	friend std::basic_istream<_CharT, _Traits>&
    928 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
    929 		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
    930 		   __x);
    931 
    932     private:
    933       template<typename _ForwardIterator,
    934 	       typename _UniformRandomNumberGenerator>
    935 	void
    936 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
    937 			_UniformRandomNumberGenerator& __urng,
    938 			const param_type& __p);
    939 
    940       param_type _M_param;
    941       std::normal_distribution<_RealType> _M_nd;
    942   };
    943 
    944   /**
    945    * @brief Return true if two multi-variate normal distributions are
    946    * different.
    947    */
    948   template<size_t _Dimen, typename _RealType>
    949     inline bool
    950     operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
    951 	       __d1,
    952 	       const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
    953 	       __d2)
    954     { return !(__d1 == __d2); }
    955 
    956 
    957   /**
    958    * @brief A Rice continuous distribution for random numbers.
    959    *
    960    * The formula for the Rice probability density function is
    961    * @f[
    962    *     p(x|\nu,\sigma) = \frac{x}{\sigma^2}
    963    *                       \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right)
    964    *                       I_0\left(\frac{x \nu}{\sigma^2}\right)
    965    * @f]
    966    * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
    967    * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$.
    968    *
    969    * <table border=1 cellpadding=10 cellspacing=0>
    970    * <caption align=top>Distribution Statistics</caption>
    971    * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
    972    * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2
    973    *                   + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
    974    * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
    975    * </table>
    976    * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2.
    977    */
    978   template<typename _RealType = double>
    979     class
    980     rice_distribution
    981     {
    982       static_assert(std::is_floating_point<_RealType>::value,
    983 		    "template argument not a floating point type");
    984     public:
    985       /** The type of the range of the distribution. */
    986       typedef _RealType result_type;
    987 
    988       /** Parameter type. */
    989       struct param_type
    990       {
    991 	typedef rice_distribution<result_type> distribution_type;
    992 
    993 	param_type() : param_type(0) { }
    994 
    995 	param_type(result_type __nu_val,
    996 		   result_type __sigma_val = result_type(1))
    997 	: _M_nu(__nu_val), _M_sigma(__sigma_val)
    998 	{
    999 	  __glibcxx_assert(_M_nu >= result_type(0));
   1000 	  __glibcxx_assert(_M_sigma > result_type(0));
   1001 	}
   1002 
   1003 	result_type
   1004 	nu() const
   1005 	{ return _M_nu; }
   1006 
   1007 	result_type
   1008 	sigma() const
   1009 	{ return _M_sigma; }
   1010 
   1011 	friend bool
   1012 	operator==(const param_type& __p1, const param_type& __p2)
   1013 	{ return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; }
   1014 
   1015 	friend bool
   1016 	operator!=(const param_type& __p1, const param_type& __p2)
   1017 	{ return !(__p1 == __p2); }
   1018 
   1019       private:
   1020 	void _M_initialize();
   1021 
   1022 	result_type _M_nu;
   1023 	result_type _M_sigma;
   1024       };
   1025 
   1026       /**
   1027        * @brief Constructors.
   1028        * @{
   1029        */
   1030 
   1031       rice_distribution() : rice_distribution(0) { }
   1032 
   1033       explicit
   1034       rice_distribution(result_type __nu_val,
   1035 			result_type __sigma_val = result_type(1))
   1036       : _M_param(__nu_val, __sigma_val),
   1037 	_M_ndx(__nu_val, __sigma_val),
   1038 	_M_ndy(result_type(0), __sigma_val)
   1039       { }
   1040 
   1041       explicit
   1042       rice_distribution(const param_type& __p)
   1043       : _M_param(__p),
   1044 	_M_ndx(__p.nu(), __p.sigma()),
   1045 	_M_ndy(result_type(0), __p.sigma())
   1046       { }
   1047 
   1048       /// @}
   1049 
   1050       /**
   1051        * @brief Resets the distribution state.
   1052        */
   1053       void
   1054       reset()
   1055       {
   1056 	_M_ndx.reset();
   1057 	_M_ndy.reset();
   1058       }
   1059 
   1060       /**
   1061        * @brief Return the parameters of the distribution.
   1062        */
   1063       result_type
   1064       nu() const
   1065       { return _M_param.nu(); }
   1066 
   1067       result_type
   1068       sigma() const
   1069       { return _M_param.sigma(); }
   1070 
   1071       /**
   1072        * @brief Returns the parameter set of the distribution.
   1073        */
   1074       param_type
   1075       param() const
   1076       { return _M_param; }
   1077 
   1078       /**
   1079        * @brief Sets the parameter set of the distribution.
   1080        * @param __param The new parameter set of the distribution.
   1081        */
   1082       void
   1083       param(const param_type& __param)
   1084       { _M_param = __param; }
   1085 
   1086       /**
   1087        * @brief Returns the greatest lower bound value of the distribution.
   1088        */
   1089       result_type
   1090       min() const
   1091       { return result_type(0); }
   1092 
   1093       /**
   1094        * @brief Returns the least upper bound value of the distribution.
   1095        */
   1096       result_type
   1097       max() const
   1098       { return std::numeric_limits<result_type>::max(); }
   1099 
   1100       /**
   1101        * @brief Generating functions.
   1102        */
   1103       template<typename _UniformRandomNumberGenerator>
   1104 	result_type
   1105 	operator()(_UniformRandomNumberGenerator& __urng)
   1106 	{
   1107 	  result_type __x = this->_M_ndx(__urng);
   1108 	  result_type __y = this->_M_ndy(__urng);
   1109 #if _GLIBCXX_USE_C99_MATH_TR1
   1110 	  return std::hypot(__x, __y);
   1111 #else
   1112 	  return std::sqrt(__x * __x + __y * __y);
   1113 #endif
   1114 	}
   1115 
   1116       template<typename _UniformRandomNumberGenerator>
   1117 	result_type
   1118 	operator()(_UniformRandomNumberGenerator& __urng,
   1119 		   const param_type& __p)
   1120 	{
   1121 	  typename std::normal_distribution<result_type>::param_type
   1122 	    __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
   1123 	  result_type __x = this->_M_ndx(__px, __urng);
   1124 	  result_type __y = this->_M_ndy(__py, __urng);
   1125 #if _GLIBCXX_USE_C99_MATH_TR1
   1126 	  return std::hypot(__x, __y);
   1127 #else
   1128 	  return std::sqrt(__x * __x + __y * __y);
   1129 #endif
   1130 	}
   1131 
   1132       template<typename _ForwardIterator,
   1133 	       typename _UniformRandomNumberGenerator>
   1134 	void
   1135 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1136 		   _UniformRandomNumberGenerator& __urng)
   1137 	{ this->__generate(__f, __t, __urng, _M_param); }
   1138 
   1139       template<typename _ForwardIterator,
   1140 	       typename _UniformRandomNumberGenerator>
   1141 	void
   1142 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1143 		   _UniformRandomNumberGenerator& __urng,
   1144 		   const param_type& __p)
   1145 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1146 
   1147       template<typename _UniformRandomNumberGenerator>
   1148 	void
   1149 	__generate(result_type* __f, result_type* __t,
   1150 		   _UniformRandomNumberGenerator& __urng,
   1151 		   const param_type& __p)
   1152 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1153 
   1154       /**
   1155        * @brief Return true if two Rice distributions have
   1156        *        the same parameters and the sequences that would
   1157        *        be generated are equal.
   1158        */
   1159       friend bool
   1160       operator==(const rice_distribution& __d1,
   1161 		 const rice_distribution& __d2)
   1162       { return (__d1._M_param == __d2._M_param
   1163 		&& __d1._M_ndx == __d2._M_ndx
   1164 		&& __d1._M_ndy == __d2._M_ndy); }
   1165 
   1166       /**
   1167        * @brief Inserts a %rice_distribution random number distribution
   1168        * @p __x into the output stream @p __os.
   1169        *
   1170        * @param __os An output stream.
   1171        * @param __x  A %rice_distribution random number distribution.
   1172        *
   1173        * @returns The output stream with the state of @p __x inserted or in
   1174        * an error state.
   1175        */
   1176       template<typename _RealType1, typename _CharT, typename _Traits>
   1177 	friend std::basic_ostream<_CharT, _Traits>&
   1178 	operator<<(std::basic_ostream<_CharT, _Traits>&,
   1179 		   const rice_distribution<_RealType1>&);
   1180 
   1181       /**
   1182        * @brief Extracts a %rice_distribution random number distribution
   1183        * @p __x from the input stream @p __is.
   1184        *
   1185        * @param __is An input stream.
   1186        * @param __x A %rice_distribution random number
   1187        *            generator engine.
   1188        *
   1189        * @returns The input stream with @p __x extracted or in an error state.
   1190        */
   1191       template<typename _RealType1, typename _CharT, typename _Traits>
   1192 	friend std::basic_istream<_CharT, _Traits>&
   1193 	operator>>(std::basic_istream<_CharT, _Traits>&,
   1194 		   rice_distribution<_RealType1>&);
   1195 
   1196     private:
   1197       template<typename _ForwardIterator,
   1198 	       typename _UniformRandomNumberGenerator>
   1199 	void
   1200 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   1201 			_UniformRandomNumberGenerator& __urng,
   1202 			const param_type& __p);
   1203 
   1204       param_type _M_param;
   1205 
   1206       std::normal_distribution<result_type> _M_ndx;
   1207       std::normal_distribution<result_type> _M_ndy;
   1208     };
   1209 
   1210   /**
   1211    * @brief Return true if two Rice distributions are not equal.
   1212    */
   1213   template<typename _RealType1>
   1214     inline bool
   1215     operator!=(const rice_distribution<_RealType1>& __d1,
   1216 	       const rice_distribution<_RealType1>& __d2)
   1217     { return !(__d1 == __d2); }
   1218 
   1219 
   1220   /**
   1221    * @brief A Nakagami continuous distribution for random numbers.
   1222    *
   1223    * The formula for the Nakagami probability density function is
   1224    * @f[
   1225    *     p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu}
   1226    *                       x^{2\mu-1}e^{-\mu x / \omega}
   1227    * @f]
   1228    * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$
   1229    * and @f$\omega > 0@f$.
   1230    */
   1231   template<typename _RealType = double>
   1232     class
   1233     nakagami_distribution
   1234     {
   1235       static_assert(std::is_floating_point<_RealType>::value,
   1236 		    "template argument not a floating point type");
   1237 
   1238     public:
   1239       /** The type of the range of the distribution. */
   1240       typedef _RealType result_type;
   1241 
   1242       /** Parameter type. */
   1243       struct param_type
   1244       {
   1245 	typedef nakagami_distribution<result_type> distribution_type;
   1246 
   1247 	param_type() : param_type(1) { }
   1248 
   1249 	param_type(result_type __mu_val,
   1250 		   result_type __omega_val = result_type(1))
   1251 	: _M_mu(__mu_val), _M_omega(__omega_val)
   1252 	{
   1253 	  __glibcxx_assert(_M_mu >= result_type(0.5L));
   1254 	  __glibcxx_assert(_M_omega > result_type(0));
   1255 	}
   1256 
   1257 	result_type
   1258 	mu() const
   1259 	{ return _M_mu; }
   1260 
   1261 	result_type
   1262 	omega() const
   1263 	{ return _M_omega; }
   1264 
   1265 	friend bool
   1266 	operator==(const param_type& __p1, const param_type& __p2)
   1267 	{ return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; }
   1268 
   1269 	friend bool
   1270 	operator!=(const param_type& __p1, const param_type& __p2)
   1271 	{ return !(__p1 == __p2); }
   1272 
   1273       private:
   1274 	void _M_initialize();
   1275 
   1276 	result_type _M_mu;
   1277 	result_type _M_omega;
   1278       };
   1279 
   1280       /**
   1281        * @brief Constructors.
   1282        * @{
   1283        */
   1284 
   1285       nakagami_distribution() : nakagami_distribution(1) { }
   1286 
   1287       explicit
   1288       nakagami_distribution(result_type __mu_val,
   1289 			    result_type __omega_val = result_type(1))
   1290       : _M_param(__mu_val, __omega_val),
   1291 	_M_gd(__mu_val, __omega_val / __mu_val)
   1292       { }
   1293 
   1294       explicit
   1295       nakagami_distribution(const param_type& __p)
   1296       : _M_param(__p),
   1297 	_M_gd(__p.mu(), __p.omega() / __p.mu())
   1298       { }
   1299 
   1300       /// @}
   1301 
   1302       /**
   1303        * @brief Resets the distribution state.
   1304        */
   1305       void
   1306       reset()
   1307       { _M_gd.reset(); }
   1308 
   1309       /**
   1310        * @brief Return the parameters of the distribution.
   1311        */
   1312       result_type
   1313       mu() const
   1314       { return _M_param.mu(); }
   1315 
   1316       result_type
   1317       omega() const
   1318       { return _M_param.omega(); }
   1319 
   1320       /**
   1321        * @brief Returns the parameter set of the distribution.
   1322        */
   1323       param_type
   1324       param() const
   1325       { return _M_param; }
   1326 
   1327       /**
   1328        * @brief Sets the parameter set of the distribution.
   1329        * @param __param The new parameter set of the distribution.
   1330        */
   1331       void
   1332       param(const param_type& __param)
   1333       { _M_param = __param; }
   1334 
   1335       /**
   1336        * @brief Returns the greatest lower bound value of the distribution.
   1337        */
   1338       result_type
   1339       min() const
   1340       { return result_type(0); }
   1341 
   1342       /**
   1343        * @brief Returns the least upper bound value of the distribution.
   1344        */
   1345       result_type
   1346       max() const
   1347       { return std::numeric_limits<result_type>::max(); }
   1348 
   1349       /**
   1350        * @brief Generating functions.
   1351        */
   1352       template<typename _UniformRandomNumberGenerator>
   1353 	result_type
   1354 	operator()(_UniformRandomNumberGenerator& __urng)
   1355 	{ return std::sqrt(this->_M_gd(__urng)); }
   1356 
   1357       template<typename _UniformRandomNumberGenerator>
   1358 	result_type
   1359 	operator()(_UniformRandomNumberGenerator& __urng,
   1360 		   const param_type& __p)
   1361 	{
   1362 	  typename std::gamma_distribution<result_type>::param_type
   1363 	    __pg(__p.mu(), __p.omega() / __p.mu());
   1364 	  return std::sqrt(this->_M_gd(__pg, __urng));
   1365 	}
   1366 
   1367       template<typename _ForwardIterator,
   1368 	       typename _UniformRandomNumberGenerator>
   1369 	void
   1370 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1371 		   _UniformRandomNumberGenerator& __urng)
   1372 	{ this->__generate(__f, __t, __urng, _M_param); }
   1373 
   1374       template<typename _ForwardIterator,
   1375 	       typename _UniformRandomNumberGenerator>
   1376 	void
   1377 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1378 		   _UniformRandomNumberGenerator& __urng,
   1379 		   const param_type& __p)
   1380 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1381 
   1382       template<typename _UniformRandomNumberGenerator>
   1383 	void
   1384 	__generate(result_type* __f, result_type* __t,
   1385 		   _UniformRandomNumberGenerator& __urng,
   1386 		   const param_type& __p)
   1387 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1388 
   1389       /**
   1390        * @brief Return true if two Nakagami distributions have
   1391        *        the same parameters and the sequences that would
   1392        *        be generated are equal.
   1393        */
   1394       friend bool
   1395       operator==(const nakagami_distribution& __d1,
   1396 		 const nakagami_distribution& __d2)
   1397       { return (__d1._M_param == __d2._M_param
   1398 		&& __d1._M_gd == __d2._M_gd); }
   1399 
   1400       /**
   1401        * @brief Inserts a %nakagami_distribution random number distribution
   1402        * @p __x into the output stream @p __os.
   1403        *
   1404        * @param __os An output stream.
   1405        * @param __x  A %nakagami_distribution random number distribution.
   1406        *
   1407        * @returns The output stream with the state of @p __x inserted or in
   1408        * an error state.
   1409        */
   1410       template<typename _RealType1, typename _CharT, typename _Traits>
   1411 	friend std::basic_ostream<_CharT, _Traits>&
   1412 	operator<<(std::basic_ostream<_CharT, _Traits>&,
   1413 		   const nakagami_distribution<_RealType1>&);
   1414 
   1415       /**
   1416        * @brief Extracts a %nakagami_distribution random number distribution
   1417        * @p __x from the input stream @p __is.
   1418        *
   1419        * @param __is An input stream.
   1420        * @param __x A %nakagami_distribution random number
   1421        *            generator engine.
   1422        *
   1423        * @returns The input stream with @p __x extracted or in an error state.
   1424        */
   1425       template<typename _RealType1, typename _CharT, typename _Traits>
   1426 	friend std::basic_istream<_CharT, _Traits>&
   1427 	operator>>(std::basic_istream<_CharT, _Traits>&,
   1428 		   nakagami_distribution<_RealType1>&);
   1429 
   1430     private:
   1431       template<typename _ForwardIterator,
   1432 	       typename _UniformRandomNumberGenerator>
   1433 	void
   1434 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   1435 			_UniformRandomNumberGenerator& __urng,
   1436 			const param_type& __p);
   1437 
   1438       param_type _M_param;
   1439 
   1440       std::gamma_distribution<result_type> _M_gd;
   1441     };
   1442 
   1443   /**
   1444    * @brief Return true if two Nakagami distributions are not equal.
   1445    */
   1446   template<typename _RealType>
   1447     inline bool
   1448     operator!=(const nakagami_distribution<_RealType>& __d1,
   1449 	       const nakagami_distribution<_RealType>& __d2)
   1450     { return !(__d1 == __d2); }
   1451 
   1452 
   1453   /**
   1454    * @brief A Pareto continuous distribution for random numbers.
   1455    *
   1456    * The formula for the Pareto cumulative probability function is
   1457    * @f[
   1458    *     P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha
   1459    * @f]
   1460    * The formula for the Pareto probability density function is
   1461    * @f[
   1462    *     p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu}
   1463    *                       \left(\frac{\mu}{x}\right)^{\alpha + 1}
   1464    * @f]
   1465    * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$.
   1466    *
   1467    * <table border=1 cellpadding=10 cellspacing=0>
   1468    * <caption align=top>Distribution Statistics</caption>
   1469    * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$
   1470    *              for @f$\alpha > 1@f$</td></tr>
   1471    * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$
   1472    *              for @f$\alpha > 2@f$</td></tr>
   1473    * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr>
   1474    * </table>
   1475    */
   1476   template<typename _RealType = double>
   1477     class
   1478     pareto_distribution
   1479     {
   1480       static_assert(std::is_floating_point<_RealType>::value,
   1481 		    "template argument not a floating point type");
   1482 
   1483     public:
   1484       /** The type of the range of the distribution. */
   1485       typedef _RealType result_type;
   1486 
   1487       /** Parameter type. */
   1488       struct param_type
   1489       {
   1490 	typedef pareto_distribution<result_type> distribution_type;
   1491 
   1492 	param_type() : param_type(1) { }
   1493 
   1494 	param_type(result_type __alpha_val,
   1495 		   result_type __mu_val = result_type(1))
   1496 	: _M_alpha(__alpha_val), _M_mu(__mu_val)
   1497 	{
   1498 	  __glibcxx_assert(_M_alpha > result_type(0));
   1499 	  __glibcxx_assert(_M_mu > result_type(0));
   1500 	}
   1501 
   1502 	result_type
   1503 	alpha() const
   1504 	{ return _M_alpha; }
   1505 
   1506 	result_type
   1507 	mu() const
   1508 	{ return _M_mu; }
   1509 
   1510 	friend bool
   1511 	operator==(const param_type& __p1, const param_type& __p2)
   1512 	{ return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; }
   1513 
   1514 	friend bool
   1515 	operator!=(const param_type& __p1, const param_type& __p2)
   1516 	{ return !(__p1 == __p2); }
   1517 
   1518       private:
   1519 	void _M_initialize();
   1520 
   1521 	result_type _M_alpha;
   1522 	result_type _M_mu;
   1523       };
   1524 
   1525       /**
   1526        * @brief Constructors.
   1527        * @{
   1528        */
   1529 
   1530       pareto_distribution() : pareto_distribution(1) { }
   1531 
   1532       explicit
   1533       pareto_distribution(result_type __alpha_val,
   1534 			  result_type __mu_val = result_type(1))
   1535       : _M_param(__alpha_val, __mu_val),
   1536 	_M_ud()
   1537       { }
   1538 
   1539       explicit
   1540       pareto_distribution(const param_type& __p)
   1541       : _M_param(__p),
   1542 	_M_ud()
   1543       { }
   1544 
   1545       /// @}
   1546 
   1547       /**
   1548        * @brief Resets the distribution state.
   1549        */
   1550       void
   1551       reset()
   1552       {
   1553 	_M_ud.reset();
   1554       }
   1555 
   1556       /**
   1557        * @brief Return the parameters of the distribution.
   1558        */
   1559       result_type
   1560       alpha() const
   1561       { return _M_param.alpha(); }
   1562 
   1563       result_type
   1564       mu() const
   1565       { return _M_param.mu(); }
   1566 
   1567       /**
   1568        * @brief Returns the parameter set of the distribution.
   1569        */
   1570       param_type
   1571       param() const
   1572       { return _M_param; }
   1573 
   1574       /**
   1575        * @brief Sets the parameter set of the distribution.
   1576        * @param __param The new parameter set of the distribution.
   1577        */
   1578       void
   1579       param(const param_type& __param)
   1580       { _M_param = __param; }
   1581 
   1582       /**
   1583        * @brief Returns the greatest lower bound value of the distribution.
   1584        */
   1585       result_type
   1586       min() const
   1587       { return this->mu(); }
   1588 
   1589       /**
   1590        * @brief Returns the least upper bound value of the distribution.
   1591        */
   1592       result_type
   1593       max() const
   1594       { return std::numeric_limits<result_type>::max(); }
   1595 
   1596       /**
   1597        * @brief Generating functions.
   1598        */
   1599       template<typename _UniformRandomNumberGenerator>
   1600 	result_type
   1601 	operator()(_UniformRandomNumberGenerator& __urng)
   1602 	{
   1603 	  return this->mu() * std::pow(this->_M_ud(__urng),
   1604 				       -result_type(1) / this->alpha());
   1605 	}
   1606 
   1607       template<typename _UniformRandomNumberGenerator>
   1608 	result_type
   1609 	operator()(_UniformRandomNumberGenerator& __urng,
   1610 		   const param_type& __p)
   1611 	{
   1612 	  return __p.mu() * std::pow(this->_M_ud(__urng),
   1613 					   -result_type(1) / __p.alpha());
   1614 	}
   1615 
   1616       template<typename _ForwardIterator,
   1617 	       typename _UniformRandomNumberGenerator>
   1618 	void
   1619 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1620 		   _UniformRandomNumberGenerator& __urng)
   1621 	{ this->__generate(__f, __t, __urng, _M_param); }
   1622 
   1623       template<typename _ForwardIterator,
   1624 	       typename _UniformRandomNumberGenerator>
   1625 	void
   1626 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1627 		   _UniformRandomNumberGenerator& __urng,
   1628 		   const param_type& __p)
   1629 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1630 
   1631       template<typename _UniformRandomNumberGenerator>
   1632 	void
   1633 	__generate(result_type* __f, result_type* __t,
   1634 		   _UniformRandomNumberGenerator& __urng,
   1635 		   const param_type& __p)
   1636 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1637 
   1638       /**
   1639        * @brief Return true if two Pareto distributions have
   1640        *        the same parameters and the sequences that would
   1641        *        be generated are equal.
   1642        */
   1643       friend bool
   1644       operator==(const pareto_distribution& __d1,
   1645 		 const pareto_distribution& __d2)
   1646       { return (__d1._M_param == __d2._M_param
   1647 		&& __d1._M_ud == __d2._M_ud); }
   1648 
   1649       /**
   1650        * @brief Inserts a %pareto_distribution random number distribution
   1651        * @p __x into the output stream @p __os.
   1652        *
   1653        * @param __os An output stream.
   1654        * @param __x  A %pareto_distribution random number distribution.
   1655        *
   1656        * @returns The output stream with the state of @p __x inserted or in
   1657        * an error state.
   1658        */
   1659       template<typename _RealType1, typename _CharT, typename _Traits>
   1660 	friend std::basic_ostream<_CharT, _Traits>&
   1661 	operator<<(std::basic_ostream<_CharT, _Traits>&,
   1662 		   const pareto_distribution<_RealType1>&);
   1663 
   1664       /**
   1665        * @brief Extracts a %pareto_distribution random number distribution
   1666        * @p __x from the input stream @p __is.
   1667        *
   1668        * @param __is An input stream.
   1669        * @param __x A %pareto_distribution random number
   1670        *            generator engine.
   1671        *
   1672        * @returns The input stream with @p __x extracted or in an error state.
   1673        */
   1674       template<typename _RealType1, typename _CharT, typename _Traits>
   1675 	friend std::basic_istream<_CharT, _Traits>&
   1676 	operator>>(std::basic_istream<_CharT, _Traits>&,
   1677 		   pareto_distribution<_RealType1>&);
   1678 
   1679     private:
   1680       template<typename _ForwardIterator,
   1681 	       typename _UniformRandomNumberGenerator>
   1682 	void
   1683 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   1684 			_UniformRandomNumberGenerator& __urng,
   1685 			const param_type& __p);
   1686 
   1687       param_type _M_param;
   1688 
   1689       std::uniform_real_distribution<result_type> _M_ud;
   1690     };
   1691 
   1692   /**
   1693    * @brief Return true if two Pareto distributions are not equal.
   1694    */
   1695   template<typename _RealType>
   1696     inline bool
   1697     operator!=(const pareto_distribution<_RealType>& __d1,
   1698 	       const pareto_distribution<_RealType>& __d2)
   1699     { return !(__d1 == __d2); }
   1700 
   1701 
   1702   /**
   1703    * @brief A K continuous distribution for random numbers.
   1704    *
   1705    * The formula for the K probability density function is
   1706    * @f[
   1707    *     p(x|\lambda, \mu, \nu) = \frac{2}{x}
   1708    *             \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}}
   1709    *             \frac{1}{\Gamma(\lambda)\Gamma(\nu)}
   1710    *             K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right)
   1711    * @f]
   1712    * where @f$I_0(z)@f$ is the modified Bessel function of the second kind
   1713    * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$
   1714    * and @f$\nu > 0@f$.
   1715    *
   1716    * <table border=1 cellpadding=10 cellspacing=0>
   1717    * <caption align=top>Distribution Statistics</caption>
   1718    * <tr><td>Mean</td><td>@f$\mu@f$</td></tr>
   1719    * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr>
   1720    * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
   1721    * </table>
   1722    */
   1723   template<typename _RealType = double>
   1724     class
   1725     k_distribution
   1726     {
   1727       static_assert(std::is_floating_point<_RealType>::value,
   1728 		    "template argument not a floating point type");
   1729 
   1730     public:
   1731       /** The type of the range of the distribution. */
   1732       typedef _RealType result_type;
   1733 
   1734       /** Parameter type. */
   1735       struct param_type
   1736       {
   1737 	typedef k_distribution<result_type> distribution_type;
   1738 
   1739 	param_type() : param_type(1) { }
   1740 
   1741 	param_type(result_type __lambda_val,
   1742 		   result_type __mu_val = result_type(1),
   1743 		   result_type __nu_val = result_type(1))
   1744 	: _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val)
   1745 	{
   1746 	  __glibcxx_assert(_M_lambda > result_type(0));
   1747 	  __glibcxx_assert(_M_mu > result_type(0));
   1748 	  __glibcxx_assert(_M_nu > result_type(0));
   1749 	}
   1750 
   1751 	result_type
   1752 	lambda() const
   1753 	{ return _M_lambda; }
   1754 
   1755 	result_type
   1756 	mu() const
   1757 	{ return _M_mu; }
   1758 
   1759 	result_type
   1760 	nu() const
   1761 	{ return _M_nu; }
   1762 
   1763 	friend bool
   1764 	operator==(const param_type& __p1, const param_type& __p2)
   1765 	{
   1766 	  return __p1._M_lambda == __p2._M_lambda
   1767 	      && __p1._M_mu == __p2._M_mu
   1768 	      && __p1._M_nu == __p2._M_nu;
   1769 	}
   1770 
   1771 	friend bool
   1772 	operator!=(const param_type& __p1, const param_type& __p2)
   1773 	{ return !(__p1 == __p2); }
   1774 
   1775       private:
   1776 	void _M_initialize();
   1777 
   1778 	result_type _M_lambda;
   1779 	result_type _M_mu;
   1780 	result_type _M_nu;
   1781       };
   1782 
   1783       /**
   1784        * @brief Constructors.
   1785        * @{
   1786        */
   1787 
   1788       k_distribution() : k_distribution(1) { }
   1789 
   1790       explicit
   1791       k_distribution(result_type __lambda_val,
   1792 		     result_type __mu_val = result_type(1),
   1793 		     result_type __nu_val = result_type(1))
   1794       : _M_param(__lambda_val, __mu_val, __nu_val),
   1795 	_M_gd1(__lambda_val, result_type(1) / __lambda_val),
   1796 	_M_gd2(__nu_val, __mu_val / __nu_val)
   1797       { }
   1798 
   1799       explicit
   1800       k_distribution(const param_type& __p)
   1801       : _M_param(__p),
   1802 	_M_gd1(__p.lambda(), result_type(1) / __p.lambda()),
   1803 	_M_gd2(__p.nu(), __p.mu() / __p.nu())
   1804       { }
   1805 
   1806       /// @}
   1807 
   1808       /**
   1809        * @brief Resets the distribution state.
   1810        */
   1811       void
   1812       reset()
   1813       {
   1814 	_M_gd1.reset();
   1815 	_M_gd2.reset();
   1816       }
   1817 
   1818       /**
   1819        * @brief Return the parameters of the distribution.
   1820        */
   1821       result_type
   1822       lambda() const
   1823       { return _M_param.lambda(); }
   1824 
   1825       result_type
   1826       mu() const
   1827       { return _M_param.mu(); }
   1828 
   1829       result_type
   1830       nu() const
   1831       { return _M_param.nu(); }
   1832 
   1833       /**
   1834        * @brief Returns the parameter set of the distribution.
   1835        */
   1836       param_type
   1837       param() const
   1838       { return _M_param; }
   1839 
   1840       /**
   1841        * @brief Sets the parameter set of the distribution.
   1842        * @param __param The new parameter set of the distribution.
   1843        */
   1844       void
   1845       param(const param_type& __param)
   1846       { _M_param = __param; }
   1847 
   1848       /**
   1849        * @brief Returns the greatest lower bound value of the distribution.
   1850        */
   1851       result_type
   1852       min() const
   1853       { return result_type(0); }
   1854 
   1855       /**
   1856        * @brief Returns the least upper bound value of the distribution.
   1857        */
   1858       result_type
   1859       max() const
   1860       { return std::numeric_limits<result_type>::max(); }
   1861 
   1862       /**
   1863        * @brief Generating functions.
   1864        */
   1865       template<typename _UniformRandomNumberGenerator>
   1866 	result_type
   1867 	operator()(_UniformRandomNumberGenerator&);
   1868 
   1869       template<typename _UniformRandomNumberGenerator>
   1870 	result_type
   1871 	operator()(_UniformRandomNumberGenerator&, const param_type&);
   1872 
   1873       template<typename _ForwardIterator,
   1874 	       typename _UniformRandomNumberGenerator>
   1875 	void
   1876 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1877 		   _UniformRandomNumberGenerator& __urng)
   1878 	{ this->__generate(__f, __t, __urng, _M_param); }
   1879 
   1880       template<typename _ForwardIterator,
   1881 	       typename _UniformRandomNumberGenerator>
   1882 	void
   1883 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   1884 		   _UniformRandomNumberGenerator& __urng,
   1885 		   const param_type& __p)
   1886 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1887 
   1888       template<typename _UniformRandomNumberGenerator>
   1889 	void
   1890 	__generate(result_type* __f, result_type* __t,
   1891 		   _UniformRandomNumberGenerator& __urng,
   1892 		   const param_type& __p)
   1893 	{ this->__generate_impl(__f, __t, __urng, __p); }
   1894 
   1895       /**
   1896        * @brief Return true if two K distributions have
   1897        *        the same parameters and the sequences that would
   1898        *        be generated are equal.
   1899        */
   1900       friend bool
   1901       operator==(const k_distribution& __d1,
   1902 		 const k_distribution& __d2)
   1903       { return (__d1._M_param == __d2._M_param
   1904 		&& __d1._M_gd1 == __d2._M_gd1
   1905 		&& __d1._M_gd2 == __d2._M_gd2); }
   1906 
   1907       /**
   1908        * @brief Inserts a %k_distribution random number distribution
   1909        * @p __x into the output stream @p __os.
   1910        *
   1911        * @param __os An output stream.
   1912        * @param __x  A %k_distribution random number distribution.
   1913        *
   1914        * @returns The output stream with the state of @p __x inserted or in
   1915        * an error state.
   1916        */
   1917       template<typename _RealType1, typename _CharT, typename _Traits>
   1918 	friend std::basic_ostream<_CharT, _Traits>&
   1919 	operator<<(std::basic_ostream<_CharT, _Traits>&,
   1920 		   const k_distribution<_RealType1>&);
   1921 
   1922       /**
   1923        * @brief Extracts a %k_distribution random number distribution
   1924        * @p __x from the input stream @p __is.
   1925        *
   1926        * @param __is An input stream.
   1927        * @param __x A %k_distribution random number
   1928        *            generator engine.
   1929        *
   1930        * @returns The input stream with @p __x extracted or in an error state.
   1931        */
   1932       template<typename _RealType1, typename _CharT, typename _Traits>
   1933 	friend std::basic_istream<_CharT, _Traits>&
   1934 	operator>>(std::basic_istream<_CharT, _Traits>&,
   1935 		   k_distribution<_RealType1>&);
   1936 
   1937     private:
   1938       template<typename _ForwardIterator,
   1939 	       typename _UniformRandomNumberGenerator>
   1940 	void
   1941 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   1942 			_UniformRandomNumberGenerator& __urng,
   1943 			const param_type& __p);
   1944 
   1945       param_type _M_param;
   1946 
   1947       std::gamma_distribution<result_type> _M_gd1;
   1948       std::gamma_distribution<result_type> _M_gd2;
   1949     };
   1950 
   1951   /**
   1952    * @brief Return true if two K distributions are not equal.
   1953    */
   1954   template<typename _RealType>
   1955     inline bool
   1956     operator!=(const k_distribution<_RealType>& __d1,
   1957 	       const k_distribution<_RealType>& __d2)
   1958     { return !(__d1 == __d2); }
   1959 
   1960 
   1961   /**
   1962    * @brief An arcsine continuous distribution for random numbers.
   1963    *
   1964    * The formula for the arcsine probability density function is
   1965    * @f[
   1966    *     p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
   1967    * @f]
   1968    * where @f$x >= a@f$ and @f$x <= b@f$.
   1969    *
   1970    * <table border=1 cellpadding=10 cellspacing=0>
   1971    * <caption align=top>Distribution Statistics</caption>
   1972    * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr>
   1973    * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr>
   1974    * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr>
   1975    * </table>
   1976    */
   1977   template<typename _RealType = double>
   1978     class
   1979     arcsine_distribution
   1980     {
   1981       static_assert(std::is_floating_point<_RealType>::value,
   1982 		    "template argument not a floating point type");
   1983 
   1984     public:
   1985       /** The type of the range of the distribution. */
   1986       typedef _RealType result_type;
   1987 
   1988       /** Parameter type. */
   1989       struct param_type
   1990       {
   1991 	typedef arcsine_distribution<result_type> distribution_type;
   1992 
   1993 	param_type() : param_type(0) { }
   1994 
   1995 	param_type(result_type __a, result_type __b = result_type(1))
   1996 	: _M_a(__a), _M_b(__b)
   1997 	{
   1998 	  __glibcxx_assert(_M_a <= _M_b);
   1999 	}
   2000 
   2001 	result_type
   2002 	a() const
   2003 	{ return _M_a; }
   2004 
   2005 	result_type
   2006 	b() const
   2007 	{ return _M_b; }
   2008 
   2009 	friend bool
   2010 	operator==(const param_type& __p1, const param_type& __p2)
   2011 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
   2012 
   2013 	friend bool
   2014 	operator!=(const param_type& __p1, const param_type& __p2)
   2015 	{ return !(__p1 == __p2); }
   2016 
   2017       private:
   2018 	void _M_initialize();
   2019 
   2020 	result_type _M_a;
   2021 	result_type _M_b;
   2022       };
   2023 
   2024       /**
   2025        * @brief Constructors.
   2026        * :{
   2027        */
   2028 
   2029       arcsine_distribution() : arcsine_distribution(0) { }
   2030 
   2031       explicit
   2032       arcsine_distribution(result_type __a, result_type __b = result_type(1))
   2033       : _M_param(__a, __b),
   2034 	_M_ud(-1.5707963267948966192313216916397514L,
   2035 	      +1.5707963267948966192313216916397514L)
   2036       { }
   2037 
   2038       explicit
   2039       arcsine_distribution(const param_type& __p)
   2040       : _M_param(__p),
   2041 	_M_ud(-1.5707963267948966192313216916397514L,
   2042 	      +1.5707963267948966192313216916397514L)
   2043       { }
   2044 
   2045       /// @}
   2046 
   2047       /**
   2048        * @brief Resets the distribution state.
   2049        */
   2050       void
   2051       reset()
   2052       { _M_ud.reset(); }
   2053 
   2054       /**
   2055        * @brief Return the parameters of the distribution.
   2056        */
   2057       result_type
   2058       a() const
   2059       { return _M_param.a(); }
   2060 
   2061       result_type
   2062       b() const
   2063       { return _M_param.b(); }
   2064 
   2065       /**
   2066        * @brief Returns the parameter set of the distribution.
   2067        */
   2068       param_type
   2069       param() const
   2070       { return _M_param; }
   2071 
   2072       /**
   2073        * @brief Sets the parameter set of the distribution.
   2074        * @param __param The new parameter set of the distribution.
   2075        */
   2076       void
   2077       param(const param_type& __param)
   2078       { _M_param = __param; }
   2079 
   2080       /**
   2081        * @brief Returns the greatest lower bound value of the distribution.
   2082        */
   2083       result_type
   2084       min() const
   2085       { return this->a(); }
   2086 
   2087       /**
   2088        * @brief Returns the least upper bound value of the distribution.
   2089        */
   2090       result_type
   2091       max() const
   2092       { return this->b(); }
   2093 
   2094       /**
   2095        * @brief Generating functions.
   2096        */
   2097       template<typename _UniformRandomNumberGenerator>
   2098 	result_type
   2099 	operator()(_UniformRandomNumberGenerator& __urng)
   2100 	{
   2101 	  result_type __x = std::sin(this->_M_ud(__urng));
   2102 	  return (__x * (this->b() - this->a())
   2103 		  + this->a() + this->b()) / result_type(2);
   2104 	}
   2105 
   2106       template<typename _UniformRandomNumberGenerator>
   2107 	result_type
   2108 	operator()(_UniformRandomNumberGenerator& __urng,
   2109 		   const param_type& __p)
   2110 	{
   2111 	  result_type __x = std::sin(this->_M_ud(__urng));
   2112 	  return (__x * (__p.b() - __p.a())
   2113 		  + __p.a() + __p.b()) / result_type(2);
   2114 	}
   2115 
   2116       template<typename _ForwardIterator,
   2117 	       typename _UniformRandomNumberGenerator>
   2118 	void
   2119 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2120 		   _UniformRandomNumberGenerator& __urng)
   2121 	{ this->__generate(__f, __t, __urng, _M_param); }
   2122 
   2123       template<typename _ForwardIterator,
   2124 	       typename _UniformRandomNumberGenerator>
   2125 	void
   2126 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2127 		   _UniformRandomNumberGenerator& __urng,
   2128 		   const param_type& __p)
   2129 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2130 
   2131       template<typename _UniformRandomNumberGenerator>
   2132 	void
   2133 	__generate(result_type* __f, result_type* __t,
   2134 		   _UniformRandomNumberGenerator& __urng,
   2135 		   const param_type& __p)
   2136 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2137 
   2138       /**
   2139        * @brief Return true if two arcsine distributions have
   2140        *        the same parameters and the sequences that would
   2141        *        be generated are equal.
   2142        */
   2143       friend bool
   2144       operator==(const arcsine_distribution& __d1,
   2145 		 const arcsine_distribution& __d2)
   2146       { return (__d1._M_param == __d2._M_param
   2147 		&& __d1._M_ud == __d2._M_ud); }
   2148 
   2149       /**
   2150        * @brief Inserts a %arcsine_distribution random number distribution
   2151        * @p __x into the output stream @p __os.
   2152        *
   2153        * @param __os An output stream.
   2154        * @param __x  A %arcsine_distribution random number distribution.
   2155        *
   2156        * @returns The output stream with the state of @p __x inserted or in
   2157        * an error state.
   2158        */
   2159       template<typename _RealType1, typename _CharT, typename _Traits>
   2160 	friend std::basic_ostream<_CharT, _Traits>&
   2161 	operator<<(std::basic_ostream<_CharT, _Traits>&,
   2162 		   const arcsine_distribution<_RealType1>&);
   2163 
   2164       /**
   2165        * @brief Extracts a %arcsine_distribution random number distribution
   2166        * @p __x from the input stream @p __is.
   2167        *
   2168        * @param __is An input stream.
   2169        * @param __x A %arcsine_distribution random number
   2170        *            generator engine.
   2171        *
   2172        * @returns The input stream with @p __x extracted or in an error state.
   2173        */
   2174       template<typename _RealType1, typename _CharT, typename _Traits>
   2175 	friend std::basic_istream<_CharT, _Traits>&
   2176 	operator>>(std::basic_istream<_CharT, _Traits>&,
   2177 		   arcsine_distribution<_RealType1>&);
   2178 
   2179     private:
   2180       template<typename _ForwardIterator,
   2181 	       typename _UniformRandomNumberGenerator>
   2182 	void
   2183 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   2184 			_UniformRandomNumberGenerator& __urng,
   2185 			const param_type& __p);
   2186 
   2187       param_type _M_param;
   2188 
   2189       std::uniform_real_distribution<result_type> _M_ud;
   2190     };
   2191 
   2192   /**
   2193    * @brief Return true if two arcsine distributions are not equal.
   2194    */
   2195   template<typename _RealType>
   2196     inline bool
   2197     operator!=(const arcsine_distribution<_RealType>& __d1,
   2198 	       const arcsine_distribution<_RealType>& __d2)
   2199     { return !(__d1 == __d2); }
   2200 
   2201 
   2202   /**
   2203    * @brief A Hoyt continuous distribution for random numbers.
   2204    *
   2205    * The formula for the Hoyt probability density function is
   2206    * @f[
   2207    *     p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
   2208    *                     \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
   2209    *                       I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
   2210    * @f]
   2211    * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
   2212    * of order 0 and @f$0 < q < 1@f$.
   2213    *
   2214    * <table border=1 cellpadding=10 cellspacing=0>
   2215    * <caption align=top>Distribution Statistics</caption>
   2216    * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
   2217    *                       E(1 - q^2) @f$</td></tr>
   2218    * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
   2219    *                                      {\pi (1 + q^2)}\right) @f$</td></tr>
   2220    * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
   2221    * </table>
   2222    * where @f$E(x)@f$ is the elliptic function of the second kind.
   2223    */
   2224   template<typename _RealType = double>
   2225     class
   2226     hoyt_distribution
   2227     {
   2228       static_assert(std::is_floating_point<_RealType>::value,
   2229 		    "template argument not a floating point type");
   2230 
   2231     public:
   2232       /** The type of the range of the distribution. */
   2233       typedef _RealType result_type;
   2234 
   2235       /** Parameter type. */
   2236       struct param_type
   2237       {
   2238 	typedef hoyt_distribution<result_type> distribution_type;
   2239 
   2240 	param_type() : param_type(0.5) { }
   2241 
   2242 	param_type(result_type __q, result_type __omega = result_type(1))
   2243 	: _M_q(__q), _M_omega(__omega)
   2244 	{
   2245 	  __glibcxx_assert(_M_q > result_type(0));
   2246 	  __glibcxx_assert(_M_q < result_type(1));
   2247 	}
   2248 
   2249 	result_type
   2250 	q() const
   2251 	{ return _M_q; }
   2252 
   2253 	result_type
   2254 	omega() const
   2255 	{ return _M_omega; }
   2256 
   2257 	friend bool
   2258 	operator==(const param_type& __p1, const param_type& __p2)
   2259 	{ return __p1._M_q == __p2._M_q && __p1._M_omega == __p2._M_omega; }
   2260 
   2261 	friend bool
   2262 	operator!=(const param_type& __p1, const param_type& __p2)
   2263 	{ return !(__p1 == __p2); }
   2264 
   2265       private:
   2266 	void _M_initialize();
   2267 
   2268 	result_type _M_q;
   2269 	result_type _M_omega;
   2270       };
   2271 
   2272       /**
   2273        * @brief Constructors.
   2274        * @{
   2275        */
   2276 
   2277       hoyt_distribution() : hoyt_distribution(0.5) { }
   2278 
   2279       explicit
   2280       hoyt_distribution(result_type __q, result_type __omega = result_type(1))
   2281       : _M_param(__q, __omega),
   2282 	_M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
   2283 	      result_type(0.5L) * (result_type(1) + __q * __q)
   2284 				/ (__q * __q)),
   2285 	_M_ed(result_type(1))
   2286       { }
   2287 
   2288       explicit
   2289       hoyt_distribution(const param_type& __p)
   2290       : _M_param(__p),
   2291 	_M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
   2292 	      result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
   2293 				/ (__p.q() * __p.q())),
   2294 	_M_ed(result_type(1))
   2295       { }
   2296 
   2297       /**
   2298        * @brief Resets the distribution state.
   2299        */
   2300       void
   2301       reset()
   2302       {
   2303 	_M_ad.reset();
   2304 	_M_ed.reset();
   2305       }
   2306 
   2307       /**
   2308        * @brief Return the parameters of the distribution.
   2309        */
   2310       result_type
   2311       q() const
   2312       { return _M_param.q(); }
   2313 
   2314       result_type
   2315       omega() const
   2316       { return _M_param.omega(); }
   2317 
   2318       /**
   2319        * @brief Returns the parameter set of the distribution.
   2320        */
   2321       param_type
   2322       param() const
   2323       { return _M_param; }
   2324 
   2325       /**
   2326        * @brief Sets the parameter set of the distribution.
   2327        * @param __param The new parameter set of the distribution.
   2328        */
   2329       void
   2330       param(const param_type& __param)
   2331       { _M_param = __param; }
   2332 
   2333       /**
   2334        * @brief Returns the greatest lower bound value of the distribution.
   2335        */
   2336       result_type
   2337       min() const
   2338       { return result_type(0); }
   2339 
   2340       /**
   2341        * @brief Returns the least upper bound value of the distribution.
   2342        */
   2343       result_type
   2344       max() const
   2345       { return std::numeric_limits<result_type>::max(); }
   2346 
   2347       /**
   2348        * @brief Generating functions.
   2349        */
   2350       template<typename _UniformRandomNumberGenerator>
   2351 	result_type
   2352 	operator()(_UniformRandomNumberGenerator& __urng);
   2353 
   2354       template<typename _UniformRandomNumberGenerator>
   2355 	result_type
   2356 	operator()(_UniformRandomNumberGenerator& __urng,
   2357 		   const param_type& __p);
   2358 
   2359       template<typename _ForwardIterator,
   2360 	       typename _UniformRandomNumberGenerator>
   2361 	void
   2362 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2363 		   _UniformRandomNumberGenerator& __urng)
   2364 	{ this->__generate(__f, __t, __urng, _M_param); }
   2365 
   2366       template<typename _ForwardIterator,
   2367 	       typename _UniformRandomNumberGenerator>
   2368 	void
   2369 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2370 		   _UniformRandomNumberGenerator& __urng,
   2371 		   const param_type& __p)
   2372 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2373 
   2374       template<typename _UniformRandomNumberGenerator>
   2375 	void
   2376 	__generate(result_type* __f, result_type* __t,
   2377 		   _UniformRandomNumberGenerator& __urng,
   2378 		   const param_type& __p)
   2379 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2380 
   2381       /**
   2382        * @brief Return true if two Hoyt distributions have
   2383        *        the same parameters and the sequences that would
   2384        *        be generated are equal.
   2385        */
   2386       friend bool
   2387       operator==(const hoyt_distribution& __d1,
   2388 		 const hoyt_distribution& __d2)
   2389       { return (__d1._M_param == __d2._M_param
   2390 		&& __d1._M_ad == __d2._M_ad
   2391 		&& __d1._M_ed == __d2._M_ed); }
   2392 
   2393       /**
   2394        * @brief Inserts a %hoyt_distribution random number distribution
   2395        * @p __x into the output stream @p __os.
   2396        *
   2397        * @param __os An output stream.
   2398        * @param __x  A %hoyt_distribution random number distribution.
   2399        *
   2400        * @returns The output stream with the state of @p __x inserted or in
   2401        * an error state.
   2402        */
   2403       template<typename _RealType1, typename _CharT, typename _Traits>
   2404 	friend std::basic_ostream<_CharT, _Traits>&
   2405 	operator<<(std::basic_ostream<_CharT, _Traits>&,
   2406 		   const hoyt_distribution<_RealType1>&);
   2407 
   2408       /**
   2409        * @brief Extracts a %hoyt_distribution random number distribution
   2410        * @p __x from the input stream @p __is.
   2411        *
   2412        * @param __is An input stream.
   2413        * @param __x A %hoyt_distribution random number
   2414        *            generator engine.
   2415        *
   2416        * @returns The input stream with @p __x extracted or in an error state.
   2417        */
   2418       template<typename _RealType1, typename _CharT, typename _Traits>
   2419 	friend std::basic_istream<_CharT, _Traits>&
   2420 	operator>>(std::basic_istream<_CharT, _Traits>&,
   2421 		   hoyt_distribution<_RealType1>&);
   2422 
   2423     private:
   2424       template<typename _ForwardIterator,
   2425 	       typename _UniformRandomNumberGenerator>
   2426 	void
   2427 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   2428 			_UniformRandomNumberGenerator& __urng,
   2429 			const param_type& __p);
   2430 
   2431       param_type _M_param;
   2432 
   2433       __gnu_cxx::arcsine_distribution<result_type> _M_ad;
   2434       std::exponential_distribution<result_type> _M_ed;
   2435     };
   2436 
   2437   /**
   2438    * @brief Return true if two Hoyt distributions are not equal.
   2439    */
   2440   template<typename _RealType>
   2441     inline bool
   2442     operator!=(const hoyt_distribution<_RealType>& __d1,
   2443 	       const hoyt_distribution<_RealType>& __d2)
   2444     { return !(__d1 == __d2); }
   2445 
   2446 
   2447   /**
   2448    * @brief A triangular distribution for random numbers.
   2449    *
   2450    * The formula for the triangular probability density function is
   2451    * @f[
   2452    *                  / 0                          for x < a
   2453    *     p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)}  for a <= x <= b
   2454    *                  | \frac{2(c-x)}{(c-a)(c-b)}  for b < x <= c
   2455    *                  \ 0                          for c < x
   2456    * @f]
   2457    *
   2458    * <table border=1 cellpadding=10 cellspacing=0>
   2459    * <caption align=top>Distribution Statistics</caption>
   2460    * <tr><td>Mean</td><td>@f$ \frac{a+b+c}{2} @f$</td></tr>
   2461    * <tr><td>Variance</td><td>@f$ \frac{a^2+b^2+c^2-ab-ac-bc}
   2462    *                                   {18}@f$</td></tr>
   2463    * <tr><td>Range</td><td>@f$[a, c]@f$</td></tr>
   2464    * </table>
   2465    */
   2466   template<typename _RealType = double>
   2467     class triangular_distribution
   2468     {
   2469       static_assert(std::is_floating_point<_RealType>::value,
   2470 		    "template argument not a floating point type");
   2471 
   2472     public:
   2473       /** The type of the range of the distribution. */
   2474       typedef _RealType result_type;
   2475 
   2476       /** Parameter type. */
   2477       struct param_type
   2478       {
   2479 	friend class triangular_distribution<_RealType>;
   2480 
   2481 	param_type() : param_type(0) { }
   2482 
   2483 	explicit
   2484 	param_type(_RealType __a,
   2485 		   _RealType __b = _RealType(0.5),
   2486 		   _RealType __c = _RealType(1))
   2487 	: _M_a(__a), _M_b(__b), _M_c(__c)
   2488 	{
   2489 	  __glibcxx_assert(_M_a <= _M_b);
   2490 	  __glibcxx_assert(_M_b <= _M_c);
   2491 	  __glibcxx_assert(_M_a < _M_c);
   2492 
   2493 	  _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a);
   2494 	  _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a);
   2495 	  _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a);
   2496 	}
   2497 
   2498 	_RealType
   2499 	a() const
   2500 	{ return _M_a; }
   2501 
   2502 	_RealType
   2503 	b() const
   2504 	{ return _M_b; }
   2505 
   2506 	_RealType
   2507 	c() const
   2508 	{ return _M_c; }
   2509 
   2510 	friend bool
   2511 	operator==(const param_type& __p1, const param_type& __p2)
   2512 	{
   2513 	  return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b
   2514 		  && __p1._M_c == __p2._M_c);
   2515 	}
   2516 
   2517 	friend bool
   2518 	operator!=(const param_type& __p1, const param_type& __p2)
   2519 	{ return !(__p1 == __p2); }
   2520 
   2521       private:
   2522 
   2523 	_RealType _M_a;
   2524 	_RealType _M_b;
   2525 	_RealType _M_c;
   2526 	_RealType _M_r_ab;
   2527 	_RealType _M_f_ab_ac;
   2528 	_RealType _M_f_bc_ac;
   2529       };
   2530 
   2531       triangular_distribution() : triangular_distribution(0.0) { }
   2532 
   2533       /**
   2534        * @brief Constructs a triangle distribution with parameters
   2535        * @f$ a @f$, @f$ b @f$ and @f$ c @f$.
   2536        */
   2537       explicit
   2538       triangular_distribution(result_type __a,
   2539 			      result_type __b = result_type(0.5),
   2540 			      result_type __c = result_type(1))
   2541       : _M_param(__a, __b, __c)
   2542       { }
   2543 
   2544       explicit
   2545       triangular_distribution(const param_type& __p)
   2546       : _M_param(__p)
   2547       { }
   2548 
   2549       /**
   2550        * @brief Resets the distribution state.
   2551        */
   2552       void
   2553       reset()
   2554       { }
   2555 
   2556       /**
   2557        * @brief Returns the @f$ a @f$ of the distribution.
   2558        */
   2559       result_type
   2560       a() const
   2561       { return _M_param.a(); }
   2562 
   2563       /**
   2564        * @brief Returns the @f$ b @f$ of the distribution.
   2565        */
   2566       result_type
   2567       b() const
   2568       { return _M_param.b(); }
   2569 
   2570       /**
   2571        * @brief Returns the @f$ c @f$ of the distribution.
   2572        */
   2573       result_type
   2574       c() const
   2575       { return _M_param.c(); }
   2576 
   2577       /**
   2578        * @brief Returns the parameter set of the distribution.
   2579        */
   2580       param_type
   2581       param() const
   2582       { return _M_param; }
   2583 
   2584       /**
   2585        * @brief Sets the parameter set of the distribution.
   2586        * @param __param The new parameter set of the distribution.
   2587        */
   2588       void
   2589       param(const param_type& __param)
   2590       { _M_param = __param; }
   2591 
   2592       /**
   2593        * @brief Returns the greatest lower bound value of the distribution.
   2594        */
   2595       result_type
   2596       min() const
   2597       { return _M_param._M_a; }
   2598 
   2599       /**
   2600        * @brief Returns the least upper bound value of the distribution.
   2601        */
   2602       result_type
   2603       max() const
   2604       { return _M_param._M_c; }
   2605 
   2606       /**
   2607        * @brief Generating functions.
   2608        */
   2609       template<typename _UniformRandomNumberGenerator>
   2610 	result_type
   2611 	operator()(_UniformRandomNumberGenerator& __urng)
   2612 	{ return this->operator()(__urng, _M_param); }
   2613 
   2614       template<typename _UniformRandomNumberGenerator>
   2615 	result_type
   2616 	operator()(_UniformRandomNumberGenerator& __urng,
   2617 		   const param_type& __p)
   2618 	{
   2619 	  std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
   2620 	    __aurng(__urng);
   2621 	  result_type __rnd = __aurng();
   2622 	  if (__rnd <= __p._M_r_ab)
   2623 	    return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac);
   2624 	  else
   2625 	    return __p.c() - std::sqrt((result_type(1) - __rnd)
   2626 				       * __p._M_f_bc_ac);
   2627 	}
   2628 
   2629       template<typename _ForwardIterator,
   2630 	       typename _UniformRandomNumberGenerator>
   2631 	void
   2632 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2633 		   _UniformRandomNumberGenerator& __urng)
   2634 	{ this->__generate(__f, __t, __urng, _M_param); }
   2635 
   2636       template<typename _ForwardIterator,
   2637 	       typename _UniformRandomNumberGenerator>
   2638 	void
   2639 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2640 		   _UniformRandomNumberGenerator& __urng,
   2641 		   const param_type& __p)
   2642 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2643 
   2644       template<typename _UniformRandomNumberGenerator>
   2645 	void
   2646 	__generate(result_type* __f, result_type* __t,
   2647 		   _UniformRandomNumberGenerator& __urng,
   2648 		   const param_type& __p)
   2649 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2650 
   2651       /**
   2652        * @brief Return true if two triangle distributions have the same
   2653        *        parameters and the sequences that would be generated
   2654        *        are equal.
   2655        */
   2656       friend bool
   2657       operator==(const triangular_distribution& __d1,
   2658 		 const triangular_distribution& __d2)
   2659       { return __d1._M_param == __d2._M_param; }
   2660 
   2661       /**
   2662        * @brief Inserts a %triangular_distribution random number distribution
   2663        * @p __x into the output stream @p __os.
   2664        *
   2665        * @param __os An output stream.
   2666        * @param __x  A %triangular_distribution random number distribution.
   2667        *
   2668        * @returns The output stream with the state of @p __x inserted or in
   2669        * an error state.
   2670        */
   2671       template<typename _RealType1, typename _CharT, typename _Traits>
   2672 	friend std::basic_ostream<_CharT, _Traits>&
   2673 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   2674 		   const __gnu_cxx::triangular_distribution<_RealType1>& __x);
   2675 
   2676       /**
   2677        * @brief Extracts a %triangular_distribution random number distribution
   2678        * @p __x from the input stream @p __is.
   2679        *
   2680        * @param __is An input stream.
   2681        * @param __x  A %triangular_distribution random number generator engine.
   2682        *
   2683        * @returns The input stream with @p __x extracted or in an error state.
   2684        */
   2685       template<typename _RealType1, typename _CharT, typename _Traits>
   2686 	friend std::basic_istream<_CharT, _Traits>&
   2687 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
   2688 		   __gnu_cxx::triangular_distribution<_RealType1>& __x);
   2689 
   2690     private:
   2691       template<typename _ForwardIterator,
   2692 	       typename _UniformRandomNumberGenerator>
   2693 	void
   2694 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   2695 			_UniformRandomNumberGenerator& __urng,
   2696 			const param_type& __p);
   2697 
   2698       param_type _M_param;
   2699     };
   2700 
   2701   /**
   2702    * @brief Return true if two triangle distributions are different.
   2703    */
   2704   template<typename _RealType>
   2705     inline bool
   2706     operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1,
   2707 	       const __gnu_cxx::triangular_distribution<_RealType>& __d2)
   2708     { return !(__d1 == __d2); }
   2709 
   2710 
   2711   /**
   2712    * @brief A von Mises distribution for random numbers.
   2713    *
   2714    * The formula for the von Mises probability density function is
   2715    * @f[
   2716    *     p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}}
   2717    *                            {2\pi I_0(\kappa)}
   2718    * @f]
   2719    *
   2720    * The generating functions use the method according to:
   2721    *
   2722    * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the
   2723    * von Mises Distribution", Journal of the Royal Statistical Society.
   2724    * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157.
   2725    *
   2726    * <table border=1 cellpadding=10 cellspacing=0>
   2727    * <caption align=top>Distribution Statistics</caption>
   2728    * <tr><td>Mean</td><td>@f$ \mu @f$</td></tr>
   2729    * <tr><td>Variance</td><td>@f$ 1-I_1(\kappa)/I_0(\kappa) @f$</td></tr>
   2730    * <tr><td>Range</td><td>@f$[-\pi, \pi]@f$</td></tr>
   2731    * </table>
   2732    */
   2733   template<typename _RealType = double>
   2734     class von_mises_distribution
   2735     {
   2736       static_assert(std::is_floating_point<_RealType>::value,
   2737 		    "template argument not a floating point type");
   2738 
   2739     public:
   2740       /** The type of the range of the distribution. */
   2741       typedef _RealType result_type;
   2742 
   2743       /** Parameter type. */
   2744       struct param_type
   2745       {
   2746 	friend class von_mises_distribution<_RealType>;
   2747 
   2748 	param_type() : param_type(0) { }
   2749 
   2750 	explicit
   2751 	param_type(_RealType __mu, _RealType __kappa = _RealType(1))
   2752 	: _M_mu(__mu), _M_kappa(__kappa)
   2753 	{
   2754 	  const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi;
   2755 	  __glibcxx_assert(_M_mu >= -__pi && _M_mu <= __pi);
   2756 	  __glibcxx_assert(_M_kappa >= _RealType(0));
   2757 
   2758 	  auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa
   2759 				 + _RealType(1)) + _RealType(1);
   2760 	  auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau))
   2761 			/ (_RealType(2) * _M_kappa));
   2762 	  _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho);
   2763 	}
   2764 
   2765 	_RealType
   2766 	mu() const
   2767 	{ return _M_mu; }
   2768 
   2769 	_RealType
   2770 	kappa() const
   2771 	{ return _M_kappa; }
   2772 
   2773 	friend bool
   2774 	operator==(const param_type& __p1, const param_type& __p2)
   2775 	{ return __p1._M_mu == __p2._M_mu && __p1._M_kappa == __p2._M_kappa; }
   2776 
   2777 	friend bool
   2778 	operator!=(const param_type& __p1, const param_type& __p2)
   2779 	{ return !(__p1 == __p2); }
   2780 
   2781       private:
   2782 	_RealType _M_mu;
   2783 	_RealType _M_kappa;
   2784 	_RealType _M_r;
   2785       };
   2786 
   2787       von_mises_distribution() : von_mises_distribution(0.0) { }
   2788 
   2789       /**
   2790        * @brief Constructs a von Mises distribution with parameters
   2791        * @f$\mu@f$ and @f$\kappa@f$.
   2792        */
   2793       explicit
   2794       von_mises_distribution(result_type __mu,
   2795 			     result_type __kappa = result_type(1))
   2796       : _M_param(__mu, __kappa)
   2797       { }
   2798 
   2799       explicit
   2800       von_mises_distribution(const param_type& __p)
   2801       : _M_param(__p)
   2802       { }
   2803 
   2804       /**
   2805        * @brief Resets the distribution state.
   2806        */
   2807       void
   2808       reset()
   2809       { }
   2810 
   2811       /**
   2812        * @brief Returns the @f$ \mu @f$ of the distribution.
   2813        */
   2814       result_type
   2815       mu() const
   2816       { return _M_param.mu(); }
   2817 
   2818       /**
   2819        * @brief Returns the @f$ \kappa @f$ of the distribution.
   2820        */
   2821       result_type
   2822       kappa() const
   2823       { return _M_param.kappa(); }
   2824 
   2825       /**
   2826        * @brief Returns the parameter set of the distribution.
   2827        */
   2828       param_type
   2829       param() const
   2830       { return _M_param; }
   2831 
   2832       /**
   2833        * @brief Sets the parameter set of the distribution.
   2834        * @param __param The new parameter set of the distribution.
   2835        */
   2836       void
   2837       param(const param_type& __param)
   2838       { _M_param = __param; }
   2839 
   2840       /**
   2841        * @brief Returns the greatest lower bound value of the distribution.
   2842        */
   2843       result_type
   2844       min() const
   2845       {
   2846 	return -__gnu_cxx::__math_constants<result_type>::__pi;
   2847       }
   2848 
   2849       /**
   2850        * @brief Returns the least upper bound value of the distribution.
   2851        */
   2852       result_type
   2853       max() const
   2854       {
   2855 	return __gnu_cxx::__math_constants<result_type>::__pi;
   2856       }
   2857 
   2858       /**
   2859        * @brief Generating functions.
   2860        */
   2861       template<typename _UniformRandomNumberGenerator>
   2862 	result_type
   2863 	operator()(_UniformRandomNumberGenerator& __urng)
   2864 	{ return this->operator()(__urng, _M_param); }
   2865 
   2866       template<typename _UniformRandomNumberGenerator>
   2867 	result_type
   2868 	operator()(_UniformRandomNumberGenerator& __urng,
   2869 		   const param_type& __p);
   2870 
   2871       template<typename _ForwardIterator,
   2872 	       typename _UniformRandomNumberGenerator>
   2873 	void
   2874 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2875 		   _UniformRandomNumberGenerator& __urng)
   2876 	{ this->__generate(__f, __t, __urng, _M_param); }
   2877 
   2878       template<typename _ForwardIterator,
   2879 	       typename _UniformRandomNumberGenerator>
   2880 	void
   2881 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   2882 		   _UniformRandomNumberGenerator& __urng,
   2883 		   const param_type& __p)
   2884 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2885 
   2886       template<typename _UniformRandomNumberGenerator>
   2887 	void
   2888 	__generate(result_type* __f, result_type* __t,
   2889 		   _UniformRandomNumberGenerator& __urng,
   2890 		   const param_type& __p)
   2891 	{ this->__generate_impl(__f, __t, __urng, __p); }
   2892 
   2893       /**
   2894        * @brief Return true if two von Mises distributions have the same
   2895        *        parameters and the sequences that would be generated
   2896        *        are equal.
   2897        */
   2898       friend bool
   2899       operator==(const von_mises_distribution& __d1,
   2900 		 const von_mises_distribution& __d2)
   2901       { return __d1._M_param == __d2._M_param; }
   2902 
   2903       /**
   2904        * @brief Inserts a %von_mises_distribution random number distribution
   2905        * @p __x into the output stream @p __os.
   2906        *
   2907        * @param __os An output stream.
   2908        * @param __x  A %von_mises_distribution random number distribution.
   2909        *
   2910        * @returns The output stream with the state of @p __x inserted or in
   2911        * an error state.
   2912        */
   2913       template<typename _RealType1, typename _CharT, typename _Traits>
   2914 	friend std::basic_ostream<_CharT, _Traits>&
   2915 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   2916 		   const __gnu_cxx::von_mises_distribution<_RealType1>& __x);
   2917 
   2918       /**
   2919        * @brief Extracts a %von_mises_distribution random number distribution
   2920        * @p __x from the input stream @p __is.
   2921        *
   2922        * @param __is An input stream.
   2923        * @param __x  A %von_mises_distribution random number generator engine.
   2924        *
   2925        * @returns The input stream with @p __x extracted or in an error state.
   2926        */
   2927       template<typename _RealType1, typename _CharT, typename _Traits>
   2928 	friend std::basic_istream<_CharT, _Traits>&
   2929 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
   2930 		   __gnu_cxx::von_mises_distribution<_RealType1>& __x);
   2931 
   2932     private:
   2933       template<typename _ForwardIterator,
   2934 	       typename _UniformRandomNumberGenerator>
   2935 	void
   2936 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   2937 			_UniformRandomNumberGenerator& __urng,
   2938 			const param_type& __p);
   2939 
   2940       param_type _M_param;
   2941     };
   2942 
   2943   /**
   2944    * @brief Return true if two von Mises distributions are different.
   2945    */
   2946   template<typename _RealType>
   2947     inline bool
   2948     operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1,
   2949 	       const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
   2950     { return !(__d1 == __d2); }
   2951 
   2952 
   2953   /**
   2954    * @brief A discrete hypergeometric random number distribution.
   2955    *
   2956    * The hypergeometric distribution is a discrete probability distribution
   2957    * that describes the probability of @p k successes in @p n draws @a without
   2958    * replacement from a finite population of size @p N containing exactly @p K
   2959    * successes.
   2960    *
   2961    * The formula for the hypergeometric probability density function is
   2962    * @f[
   2963    *   p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}}
   2964    * @f]
   2965    * where @f$N@f$ is the total population of the distribution,
   2966    * @f$K@f$ is the total population of the distribution.
   2967    *
   2968    * <table border=1 cellpadding=10 cellspacing=0>
   2969    * <caption align=top>Distribution Statistics</caption>
   2970    * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr>
   2971    * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}
   2972    *   @f$</td></tr>
   2973    * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr>
   2974    * </table>
   2975    */
   2976   template<typename _UIntType = unsigned int>
   2977     class hypergeometric_distribution
   2978     {
   2979       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
   2980 		    "substituting _UIntType not an unsigned integral type");
   2981 
   2982     public:
   2983       /** The type of the range of the distribution. */
   2984       typedef _UIntType  result_type;
   2985 
   2986       /** Parameter type. */
   2987       struct param_type
   2988       {
   2989 	typedef hypergeometric_distribution<_UIntType> distribution_type;
   2990 	friend class hypergeometric_distribution<_UIntType>;
   2991 
   2992 	param_type() : param_type(10) { }
   2993 
   2994 	explicit
   2995 	param_type(result_type __N, result_type __K = 5,
   2996 		   result_type __n = 1)
   2997 	: _M_N{__N}, _M_K{__K}, _M_n{__n}
   2998 	{
   2999 	  __glibcxx_assert(_M_N >= _M_K);
   3000 	  __glibcxx_assert(_M_N >= _M_n);
   3001 	}
   3002 
   3003 	result_type
   3004 	total_size() const
   3005 	{ return _M_N; }
   3006 
   3007 	result_type
   3008 	successful_size() const
   3009 	{ return _M_K; }
   3010 
   3011 	result_type
   3012 	unsuccessful_size() const
   3013 	{ return _M_N - _M_K; }
   3014 
   3015 	result_type
   3016 	total_draws() const
   3017 	{ return _M_n; }
   3018 
   3019 	friend bool
   3020 	operator==(const param_type& __p1, const param_type& __p2)
   3021 	{ return (__p1._M_N == __p2._M_N)
   3022 	      && (__p1._M_K == __p2._M_K)
   3023 	      && (__p1._M_n == __p2._M_n); }
   3024 
   3025 	friend bool
   3026 	operator!=(const param_type& __p1, const param_type& __p2)
   3027 	{ return !(__p1 == __p2); }
   3028 
   3029       private:
   3030 
   3031 	result_type _M_N;
   3032 	result_type _M_K;
   3033 	result_type _M_n;
   3034       };
   3035 
   3036       // constructors and member functions
   3037 
   3038       hypergeometric_distribution() : hypergeometric_distribution(10) { }
   3039 
   3040       explicit
   3041       hypergeometric_distribution(result_type __N, result_type __K = 5,
   3042 				  result_type __n = 1)
   3043       : _M_param{__N, __K, __n}
   3044       { }
   3045 
   3046       explicit
   3047       hypergeometric_distribution(const param_type& __p)
   3048       : _M_param{__p}
   3049       { }
   3050 
   3051       /**
   3052        * @brief Resets the distribution state.
   3053        */
   3054       void
   3055       reset()
   3056       { }
   3057 
   3058       /**
   3059        * @brief Returns the distribution parameter @p N,
   3060        *	the total number of items.
   3061        */
   3062       result_type
   3063       total_size() const
   3064       { return this->_M_param.total_size(); }
   3065 
   3066       /**
   3067        * @brief Returns the distribution parameter @p K,
   3068        *	the total number of successful items.
   3069        */
   3070       result_type
   3071       successful_size() const
   3072       { return this->_M_param.successful_size(); }
   3073 
   3074       /**
   3075        * @brief Returns the total number of unsuccessful items @f$ N - K @f$.
   3076        */
   3077       result_type
   3078       unsuccessful_size() const
   3079       { return this->_M_param.unsuccessful_size(); }
   3080 
   3081       /**
   3082        * @brief Returns the distribution parameter @p n,
   3083        *	the total number of draws.
   3084        */
   3085       result_type
   3086       total_draws() const
   3087       { return this->_M_param.total_draws(); }
   3088 
   3089       /**
   3090        * @brief Returns the parameter set of the distribution.
   3091        */
   3092       param_type
   3093       param() const
   3094       { return this->_M_param; }
   3095 
   3096       /**
   3097        * @brief Sets the parameter set of the distribution.
   3098        * @param __param The new parameter set of the distribution.
   3099        */
   3100       void
   3101       param(const param_type& __param)
   3102       { this->_M_param = __param; }
   3103 
   3104       /**
   3105        * @brief Returns the greatest lower bound value of the distribution.
   3106        */
   3107       result_type
   3108       min() const
   3109       {
   3110 	using _IntType = typename std::make_signed<result_type>::type;
   3111 	return static_cast<result_type>(std::max(static_cast<_IntType>(0),
   3112 				static_cast<_IntType>(this->total_draws()
   3113 						- this->unsuccessful_size())));
   3114       }
   3115 
   3116       /**
   3117        * @brief Returns the least upper bound value of the distribution.
   3118        */
   3119       result_type
   3120       max() const
   3121       { return std::min(this->successful_size(), this->total_draws()); }
   3122 
   3123       /**
   3124        * @brief Generating functions.
   3125        */
   3126       template<typename _UniformRandomNumberGenerator>
   3127 	result_type
   3128 	operator()(_UniformRandomNumberGenerator& __urng)
   3129 	{ return this->operator()(__urng, this->_M_param); }
   3130 
   3131       template<typename _UniformRandomNumberGenerator>
   3132 	result_type
   3133 	operator()(_UniformRandomNumberGenerator& __urng,
   3134 		   const param_type& __p);
   3135 
   3136       template<typename _ForwardIterator,
   3137 	       typename _UniformRandomNumberGenerator>
   3138 	void
   3139 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3140 		   _UniformRandomNumberGenerator& __urng)
   3141 	{ this->__generate(__f, __t, __urng, this->_M_param); }
   3142 
   3143       template<typename _ForwardIterator,
   3144 	       typename _UniformRandomNumberGenerator>
   3145 	void
   3146 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3147 		   _UniformRandomNumberGenerator& __urng,
   3148 		   const param_type& __p)
   3149 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3150 
   3151       template<typename _UniformRandomNumberGenerator>
   3152 	void
   3153 	__generate(result_type* __f, result_type* __t,
   3154 		   _UniformRandomNumberGenerator& __urng,
   3155 		   const param_type& __p)
   3156 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3157 
   3158        /**
   3159 	* @brief Return true if two hypergeometric distributions have the same
   3160 	*        parameters and the sequences that would be generated
   3161 	*        are equal.
   3162 	*/
   3163       friend bool
   3164       operator==(const hypergeometric_distribution& __d1,
   3165 		 const hypergeometric_distribution& __d2)
   3166       { return __d1._M_param == __d2._M_param; }
   3167 
   3168       /**
   3169        * @brief Inserts a %hypergeometric_distribution random number
   3170        * distribution @p __x into the output stream @p __os.
   3171        *
   3172        * @param __os An output stream.
   3173        * @param __x  A %hypergeometric_distribution random number
   3174        *             distribution.
   3175        *
   3176        * @returns The output stream with the state of @p __x inserted or in
   3177        * an error state.
   3178        */
   3179       template<typename _UIntType1, typename _CharT, typename _Traits>
   3180 	friend std::basic_ostream<_CharT, _Traits>&
   3181 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   3182 		   const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
   3183 		   __x);
   3184 
   3185       /**
   3186        * @brief Extracts a %hypergeometric_distribution random number
   3187        * distribution @p __x from the input stream @p __is.
   3188        *
   3189        * @param __is An input stream.
   3190        * @param __x  A %hypergeometric_distribution random number generator
   3191        *             distribution.
   3192        *
   3193        * @returns The input stream with @p __x extracted or in an error
   3194        *          state.
   3195        */
   3196       template<typename _UIntType1, typename _CharT, typename _Traits>
   3197 	friend std::basic_istream<_CharT, _Traits>&
   3198 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
   3199 		   __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x);
   3200 
   3201     private:
   3202 
   3203       template<typename _ForwardIterator,
   3204 	       typename _UniformRandomNumberGenerator>
   3205 	void
   3206 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   3207 			_UniformRandomNumberGenerator& __urng,
   3208 			const param_type& __p);
   3209 
   3210       param_type _M_param;
   3211     };
   3212 
   3213   /**
   3214    * @brief Return true if two hypergeometric distributions are different.
   3215    */
   3216   template<typename _UIntType>
   3217     inline bool
   3218     operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
   3219 	       const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
   3220     { return !(__d1 == __d2); }
   3221 
   3222   /**
   3223    * @brief A logistic continuous distribution for random numbers.
   3224    *
   3225    * The formula for the logistic probability density function is
   3226    * @f[
   3227    *     p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2}
   3228    * @f]
   3229    * where @f$b > 0@f$.
   3230    *
   3231    * The formula for the logistic probability function is
   3232    * @f[
   3233    *     cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}}
   3234    * @f]
   3235    * where @f$b > 0@f$.
   3236    *
   3237    * <table border=1 cellpadding=10 cellspacing=0>
   3238    * <caption align=top>Distribution Statistics</caption>
   3239    * <tr><td>Mean</td><td>@f$a@f$</td></tr>
   3240    * <tr><td>Variance</td><td>@f$b^2\pi^2/3@f$</td></tr>
   3241    * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
   3242    * </table>
   3243    */
   3244   template<typename _RealType = double>
   3245     class
   3246     logistic_distribution
   3247     {
   3248       static_assert(std::is_floating_point<_RealType>::value,
   3249 		    "template argument not a floating point type");
   3250 
   3251     public:
   3252       /** The type of the range of the distribution. */
   3253       typedef _RealType result_type;
   3254 
   3255       /** Parameter type. */
   3256       struct param_type
   3257       {
   3258 	typedef logistic_distribution<result_type> distribution_type;
   3259 
   3260 	param_type() : param_type(0) { }
   3261 
   3262 	explicit
   3263 	param_type(result_type __a, result_type __b = result_type(1))
   3264 	: _M_a(__a), _M_b(__b)
   3265 	{
   3266 	  __glibcxx_assert(_M_b > result_type(0));
   3267 	}
   3268 
   3269 	result_type
   3270 	a() const
   3271 	{ return _M_a; }
   3272 
   3273 	result_type
   3274 	b() const
   3275 	{ return _M_b; }
   3276 
   3277 	friend bool
   3278 	operator==(const param_type& __p1, const param_type& __p2)
   3279 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
   3280 
   3281 	friend bool
   3282 	operator!=(const param_type& __p1, const param_type& __p2)
   3283 	{ return !(__p1 == __p2); }
   3284 
   3285       private:
   3286 	void _M_initialize();
   3287 
   3288 	result_type _M_a;
   3289 	result_type _M_b;
   3290       };
   3291 
   3292       /**
   3293        * @brief Constructors.
   3294        * @{
   3295        */
   3296       logistic_distribution() : logistic_distribution(0.0) { }
   3297 
   3298       explicit
   3299       logistic_distribution(result_type __a, result_type __b = result_type(1))
   3300       : _M_param(__a, __b)
   3301       { }
   3302 
   3303       explicit
   3304       logistic_distribution(const param_type& __p)
   3305       : _M_param(__p)
   3306       { }
   3307 
   3308       /// @}
   3309 
   3310       /**
   3311        * @brief Resets the distribution state.
   3312        */
   3313       void
   3314       reset()
   3315       { }
   3316 
   3317       /**
   3318        * @brief Return the parameters of the distribution.
   3319        */
   3320       result_type
   3321       a() const
   3322       { return _M_param.a(); }
   3323 
   3324       result_type
   3325       b() const
   3326       { return _M_param.b(); }
   3327 
   3328       /**
   3329        * @brief Returns the parameter set of the distribution.
   3330        */
   3331       param_type
   3332       param() const
   3333       { return _M_param; }
   3334 
   3335       /**
   3336        * @brief Sets the parameter set of the distribution.
   3337        * @param __param The new parameter set of the distribution.
   3338        */
   3339       void
   3340       param(const param_type& __param)
   3341       { _M_param = __param; }
   3342 
   3343       /**
   3344        * @brief Returns the greatest lower bound value of the distribution.
   3345        */
   3346       result_type
   3347       min() const
   3348       { return -std::numeric_limits<result_type>::max(); }
   3349 
   3350       /**
   3351        * @brief Returns the least upper bound value of the distribution.
   3352        */
   3353       result_type
   3354       max() const
   3355       { return std::numeric_limits<result_type>::max(); }
   3356 
   3357       /**
   3358        * @brief Generating functions.
   3359        */
   3360       template<typename _UniformRandomNumberGenerator>
   3361 	result_type
   3362 	operator()(_UniformRandomNumberGenerator& __urng)
   3363 	{ return this->operator()(__urng, this->_M_param); }
   3364 
   3365       template<typename _UniformRandomNumberGenerator>
   3366 	result_type
   3367 	operator()(_UniformRandomNumberGenerator&,
   3368 		   const param_type&);
   3369 
   3370       template<typename _ForwardIterator,
   3371 	       typename _UniformRandomNumberGenerator>
   3372 	void
   3373 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3374 		   _UniformRandomNumberGenerator& __urng)
   3375 	{ this->__generate(__f, __t, __urng, this->param()); }
   3376 
   3377       template<typename _ForwardIterator,
   3378 	       typename _UniformRandomNumberGenerator>
   3379 	void
   3380 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3381 		   _UniformRandomNumberGenerator& __urng,
   3382 		   const param_type& __p)
   3383 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3384 
   3385       template<typename _UniformRandomNumberGenerator>
   3386 	void
   3387 	__generate(result_type* __f, result_type* __t,
   3388 		   _UniformRandomNumberGenerator& __urng,
   3389 		   const param_type& __p)
   3390 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3391 
   3392       /**
   3393        * @brief Return true if two logistic distributions have
   3394        *        the same parameters and the sequences that would
   3395        *        be generated are equal.
   3396        */
   3397       template<typename _RealType1>
   3398 	friend bool
   3399 	operator==(const logistic_distribution<_RealType1>& __d1,
   3400 		   const logistic_distribution<_RealType1>& __d2)
   3401 	{ return __d1.param() == __d2.param(); }
   3402 
   3403       /**
   3404        * @brief Inserts a %logistic_distribution random number distribution
   3405        * @p __x into the output stream @p __os.
   3406        *
   3407        * @param __os An output stream.
   3408        * @param __x  A %logistic_distribution random number distribution.
   3409        *
   3410        * @returns The output stream with the state of @p __x inserted or in
   3411        * an error state.
   3412        */
   3413       template<typename _RealType1, typename _CharT, typename _Traits>
   3414 	friend std::basic_ostream<_CharT, _Traits>&
   3415 	operator<<(std::basic_ostream<_CharT, _Traits>&,
   3416 		   const logistic_distribution<_RealType1>&);
   3417 
   3418       /**
   3419        * @brief Extracts a %logistic_distribution random number distribution
   3420        * @p __x from the input stream @p __is.
   3421        *
   3422        * @param __is An input stream.
   3423        * @param __x A %logistic_distribution random number
   3424        *            generator engine.
   3425        *
   3426        * @returns The input stream with @p __x extracted or in an error state.
   3427        */
   3428       template<typename _RealType1, typename _CharT, typename _Traits>
   3429 	friend std::basic_istream<_CharT, _Traits>&
   3430 	operator>>(std::basic_istream<_CharT, _Traits>&,
   3431 		   logistic_distribution<_RealType1>&);
   3432 
   3433     private:
   3434       template<typename _ForwardIterator,
   3435 	       typename _UniformRandomNumberGenerator>
   3436 	void
   3437 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   3438 			_UniformRandomNumberGenerator& __urng,
   3439 			const param_type& __p);
   3440 
   3441       param_type _M_param;
   3442     };
   3443 
   3444   /**
   3445    * @brief Return true if two logistic distributions are not equal.
   3446    */
   3447   template<typename _RealType1>
   3448     inline bool
   3449     operator!=(const logistic_distribution<_RealType1>& __d1,
   3450 	       const logistic_distribution<_RealType1>& __d2)
   3451     { return !(__d1 == __d2); }
   3452 
   3453 
   3454   /**
   3455    * @brief A distribution for random coordinates on a unit sphere.
   3456    *
   3457    * The method used in the generation function is attributed by Donald Knuth
   3458    * to G. W. Brown, Modern Mathematics for the Engineer (1956).
   3459    */
   3460   template<std::size_t _Dimen, typename _RealType = double>
   3461     class uniform_on_sphere_distribution
   3462     {
   3463       static_assert(std::is_floating_point<_RealType>::value,
   3464 		    "template argument not a floating point type");
   3465       static_assert(_Dimen != 0, "dimension is zero");
   3466 
   3467     public:
   3468       /** The type of the range of the distribution. */
   3469       typedef std::array<_RealType, _Dimen> result_type;
   3470 
   3471       /** Parameter type. */
   3472       struct param_type
   3473       {
   3474 	param_type() { }
   3475 
   3476 	friend bool
   3477 	operator==(const param_type&, const param_type&)
   3478 	{ return true; }
   3479 
   3480 	friend bool
   3481 	operator!=(const param_type&, const param_type&)
   3482 	{ return false; }
   3483       };
   3484 
   3485       /**
   3486        * @brief Constructs a uniform on sphere distribution.
   3487        */
   3488       uniform_on_sphere_distribution()
   3489       : _M_param(), _M_nd()
   3490       { }
   3491 
   3492       explicit
   3493       uniform_on_sphere_distribution(const param_type& __p)
   3494       : _M_param(__p), _M_nd()
   3495       { }
   3496 
   3497       /**
   3498        * @brief Resets the distribution state.
   3499        */
   3500       void
   3501       reset()
   3502       { _M_nd.reset(); }
   3503 
   3504       /**
   3505        * @brief Returns the parameter set of the distribution.
   3506        */
   3507       param_type
   3508       param() const
   3509       { return _M_param; }
   3510 
   3511       /**
   3512        * @brief Sets the parameter set of the distribution.
   3513        * @param __param The new parameter set of the distribution.
   3514        */
   3515       void
   3516       param(const param_type& __param)
   3517       { _M_param = __param; }
   3518 
   3519       /**
   3520        * @brief Returns the greatest lower bound value of the distribution.
   3521        * This function makes no sense for this distribution.
   3522        */
   3523       result_type
   3524       min() const
   3525       {
   3526 	result_type __res;
   3527 	__res.fill(0);
   3528 	return __res;
   3529       }
   3530 
   3531       /**
   3532        * @brief Returns the least upper bound value of the distribution.
   3533        * This function makes no sense for this distribution.
   3534        */
   3535       result_type
   3536       max() const
   3537       {
   3538 	result_type __res;
   3539 	__res.fill(0);
   3540 	return __res;
   3541       }
   3542 
   3543       /**
   3544        * @brief Generating functions.
   3545        */
   3546       template<typename _UniformRandomNumberGenerator>
   3547 	result_type
   3548 	operator()(_UniformRandomNumberGenerator& __urng)
   3549 	{ return this->operator()(__urng, _M_param); }
   3550 
   3551       template<typename _UniformRandomNumberGenerator>
   3552 	result_type
   3553 	operator()(_UniformRandomNumberGenerator& __urng,
   3554 		   const param_type& __p);
   3555 
   3556       template<typename _ForwardIterator,
   3557 	       typename _UniformRandomNumberGenerator>
   3558 	void
   3559 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3560 		   _UniformRandomNumberGenerator& __urng)
   3561 	{ this->__generate(__f, __t, __urng, this->param()); }
   3562 
   3563       template<typename _ForwardIterator,
   3564 	       typename _UniformRandomNumberGenerator>
   3565 	void
   3566 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3567 		   _UniformRandomNumberGenerator& __urng,
   3568 		   const param_type& __p)
   3569 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3570 
   3571       template<typename _UniformRandomNumberGenerator>
   3572 	void
   3573 	__generate(result_type* __f, result_type* __t,
   3574 		   _UniformRandomNumberGenerator& __urng,
   3575 		   const param_type& __p)
   3576 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3577 
   3578       /**
   3579        * @brief Return true if two uniform on sphere distributions have
   3580        *        the same parameters and the sequences that would be
   3581        *        generated are equal.
   3582        */
   3583       friend bool
   3584       operator==(const uniform_on_sphere_distribution& __d1,
   3585 		 const uniform_on_sphere_distribution& __d2)
   3586       { return __d1._M_nd == __d2._M_nd; }
   3587 
   3588       /**
   3589        * @brief Inserts a %uniform_on_sphere_distribution random number
   3590        *        distribution @p __x into the output stream @p __os.
   3591        *
   3592        * @param __os An output stream.
   3593        * @param __x  A %uniform_on_sphere_distribution random number
   3594        *             distribution.
   3595        *
   3596        * @returns The output stream with the state of @p __x inserted or in
   3597        * an error state.
   3598        */
   3599       template<size_t _Dimen1, typename _RealType1, typename _CharT,
   3600 	       typename _Traits>
   3601 	friend std::basic_ostream<_CharT, _Traits>&
   3602 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   3603 		   const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
   3604 								   _RealType1>&
   3605 		   __x);
   3606 
   3607       /**
   3608        * @brief Extracts a %uniform_on_sphere_distribution random number
   3609        *        distribution
   3610        * @p __x from the input stream @p __is.
   3611        *
   3612        * @param __is An input stream.
   3613        * @param __x  A %uniform_on_sphere_distribution random number
   3614        *             generator engine.
   3615        *
   3616        * @returns The input stream with @p __x extracted or in an error state.
   3617        */
   3618       template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
   3619 	       typename _Traits>
   3620 	friend std::basic_istream<_CharT, _Traits>&
   3621 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
   3622 		   __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
   3623 							     _RealType1>& __x);
   3624 
   3625     private:
   3626       template<typename _ForwardIterator,
   3627 	       typename _UniformRandomNumberGenerator>
   3628 	void
   3629 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   3630 			_UniformRandomNumberGenerator& __urng,
   3631 			const param_type& __p);
   3632 
   3633       param_type _M_param;
   3634       std::normal_distribution<_RealType> _M_nd;
   3635     };
   3636 
   3637   /**
   3638    * @brief Return true if two uniform on sphere distributions are different.
   3639    */
   3640   template<std::size_t _Dimen, typename _RealType>
   3641     inline bool
   3642     operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
   3643 	       _RealType>& __d1,
   3644 	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
   3645 	       _RealType>& __d2)
   3646     { return !(__d1 == __d2); }
   3647 
   3648 
   3649   /**
   3650    * @brief A distribution for random coordinates inside a unit sphere.
   3651    */
   3652   template<std::size_t _Dimen, typename _RealType = double>
   3653     class uniform_inside_sphere_distribution
   3654     {
   3655       static_assert(std::is_floating_point<_RealType>::value,
   3656 		    "template argument not a floating point type");
   3657       static_assert(_Dimen != 0, "dimension is zero");
   3658 
   3659     public:
   3660       /** The type of the range of the distribution. */
   3661       using result_type = std::array<_RealType, _Dimen>;
   3662 
   3663       /** Parameter type. */
   3664       struct param_type
   3665       {
   3666 	using distribution_type
   3667 	  = uniform_inside_sphere_distribution<_Dimen, _RealType>;
   3668 	friend class uniform_inside_sphere_distribution<_Dimen, _RealType>;
   3669 
   3670 	param_type() : param_type(1.0) { }
   3671 
   3672 	explicit
   3673 	param_type(_RealType __radius)
   3674 	: _M_radius(__radius)
   3675 	{
   3676 	  __glibcxx_assert(_M_radius > _RealType(0));
   3677 	}
   3678 
   3679 	_RealType
   3680 	radius() const
   3681 	{ return _M_radius; }
   3682 
   3683 	friend bool
   3684 	operator==(const param_type& __p1, const param_type& __p2)
   3685 	{ return __p1._M_radius == __p2._M_radius; }
   3686 
   3687 	friend bool
   3688 	operator!=(const param_type& __p1, const param_type& __p2)
   3689 	{ return !(__p1 == __p2); }
   3690 
   3691       private:
   3692 	_RealType _M_radius;
   3693       };
   3694 
   3695       /**
   3696        * @brief Constructors.
   3697        * @{
   3698        */
   3699 
   3700       uniform_inside_sphere_distribution()
   3701       : uniform_inside_sphere_distribution(1.0)
   3702       { }
   3703 
   3704       explicit
   3705       uniform_inside_sphere_distribution(_RealType __radius)
   3706       : _M_param(__radius), _M_uosd()
   3707       { }
   3708 
   3709       explicit
   3710       uniform_inside_sphere_distribution(const param_type& __p)
   3711       : _M_param(__p), _M_uosd()
   3712       { }
   3713 
   3714       /// @}
   3715 
   3716       /**
   3717        * @brief Resets the distribution state.
   3718        */
   3719       void
   3720       reset()
   3721       { _M_uosd.reset(); }
   3722 
   3723       /**
   3724        * @brief Returns the @f$radius@f$ of the distribution.
   3725        */
   3726       _RealType
   3727       radius() const
   3728       { return _M_param.radius(); }
   3729 
   3730       /**
   3731        * @brief Returns the parameter set of the distribution.
   3732        */
   3733       param_type
   3734       param() const
   3735       { return _M_param; }
   3736 
   3737       /**
   3738        * @brief Sets the parameter set of the distribution.
   3739        * @param __param The new parameter set of the distribution.
   3740        */
   3741       void
   3742       param(const param_type& __param)
   3743       { _M_param = __param; }
   3744 
   3745       /**
   3746        * @brief Returns the greatest lower bound value of the distribution.
   3747        * This function makes no sense for this distribution.
   3748        */
   3749       result_type
   3750       min() const
   3751       {
   3752 	result_type __res;
   3753 	__res.fill(0);
   3754 	return __res;
   3755       }
   3756 
   3757       /**
   3758        * @brief Returns the least upper bound value of the distribution.
   3759        * This function makes no sense for this distribution.
   3760        */
   3761       result_type
   3762       max() const
   3763       {
   3764 	result_type __res;
   3765 	__res.fill(0);
   3766 	return __res;
   3767       }
   3768 
   3769       /**
   3770        * @brief Generating functions.
   3771        */
   3772       template<typename _UniformRandomNumberGenerator>
   3773 	result_type
   3774 	operator()(_UniformRandomNumberGenerator& __urng)
   3775 	{ return this->operator()(__urng, _M_param); }
   3776 
   3777       template<typename _UniformRandomNumberGenerator>
   3778 	result_type
   3779 	operator()(_UniformRandomNumberGenerator& __urng,
   3780 		   const param_type& __p);
   3781 
   3782       template<typename _ForwardIterator,
   3783 	       typename _UniformRandomNumberGenerator>
   3784 	void
   3785 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3786 		   _UniformRandomNumberGenerator& __urng)
   3787 	{ this->__generate(__f, __t, __urng, this->param()); }
   3788 
   3789       template<typename _ForwardIterator,
   3790 	       typename _UniformRandomNumberGenerator>
   3791 	void
   3792 	__generate(_ForwardIterator __f, _ForwardIterator __t,
   3793 		   _UniformRandomNumberGenerator& __urng,
   3794 		   const param_type& __p)
   3795 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3796 
   3797       template<typename _UniformRandomNumberGenerator>
   3798 	void
   3799 	__generate(result_type* __f, result_type* __t,
   3800 		   _UniformRandomNumberGenerator& __urng,
   3801 		   const param_type& __p)
   3802 	{ this->__generate_impl(__f, __t, __urng, __p); }
   3803 
   3804       /**
   3805        * @brief Return true if two uniform on sphere distributions have
   3806        *        the same parameters and the sequences that would be
   3807        *        generated are equal.
   3808        */
   3809       friend bool
   3810       operator==(const uniform_inside_sphere_distribution& __d1,
   3811 		 const uniform_inside_sphere_distribution& __d2)
   3812       { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; }
   3813 
   3814       /**
   3815        * @brief Inserts a %uniform_inside_sphere_distribution random number
   3816        *        distribution @p __x into the output stream @p __os.
   3817        *
   3818        * @param __os An output stream.
   3819        * @param __x  A %uniform_inside_sphere_distribution random number
   3820        *             distribution.
   3821        *
   3822        * @returns The output stream with the state of @p __x inserted or in
   3823        * an error state.
   3824        */
   3825       template<size_t _Dimen1, typename _RealType1, typename _CharT,
   3826 	       typename _Traits>
   3827 	friend std::basic_ostream<_CharT, _Traits>&
   3828 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   3829 		   const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1,
   3830 								   _RealType1>&
   3831 		   );
   3832 
   3833       /**
   3834        * @brief Extracts a %uniform_inside_sphere_distribution random number
   3835        *        distribution
   3836        * @p __x from the input stream @p __is.
   3837        *
   3838        * @param __is An input stream.
   3839        * @param __x  A %uniform_inside_sphere_distribution random number
   3840        *             generator engine.
   3841        *
   3842        * @returns The input stream with @p __x extracted or in an error state.
   3843        */
   3844       template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
   3845 	       typename _Traits>
   3846 	friend std::basic_istream<_CharT, _Traits>&
   3847 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
   3848 		   __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1,
   3849 								 _RealType1>&);
   3850 
   3851     private:
   3852       template<typename _ForwardIterator,
   3853 	       typename _UniformRandomNumberGenerator>
   3854 	void
   3855 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
   3856 			_UniformRandomNumberGenerator& __urng,
   3857 			const param_type& __p);
   3858 
   3859       param_type _M_param;
   3860       uniform_on_sphere_distribution<_Dimen, _RealType> _M_uosd;
   3861     };
   3862 
   3863   /**
   3864    * @brief Return true if two uniform on sphere distributions are different.
   3865    */
   3866   template<std::size_t _Dimen, typename _RealType>
   3867     inline bool
   3868     operator!=(const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen,
   3869 	       _RealType>& __d1,
   3870 	       const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen,
   3871 	       _RealType>& __d2)
   3872     { return !(__d1 == __d2); }
   3873 
   3874 _GLIBCXX_END_NAMESPACE_VERSION
   3875 } // namespace __gnu_cxx
   3876 
   3877 #include <ext/opt_random.h>
   3878 #include <ext/random.tcc>
   3879 
   3880 #endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C
   3881 
   3882 #endif // C++11
   3883 
   3884 #endif // _EXT_RANDOM
   3885