xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/ext/random (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj// Random number extensions -*- C++ -*-
238fd1498Szrj
338fd1498Szrj// Copyright (C) 2012-2018 Free Software Foundation, Inc.
438fd1498Szrj//
538fd1498Szrj// This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj// software; you can redistribute it and/or modify it under the
738fd1498Szrj// terms of the GNU General Public License as published by the
838fd1498Szrj// Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj// any later version.
1038fd1498Szrj
1138fd1498Szrj// This library is distributed in the hope that it will be useful,
1238fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj// GNU General Public License for more details.
1538fd1498Szrj
1638fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj// permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj// 3.1, as published by the Free Software Foundation.
1938fd1498Szrj
2038fd1498Szrj// You should have received a copy of the GNU General Public License and
2138fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj// <http://www.gnu.org/licenses/>.
2438fd1498Szrj
2538fd1498Szrj/** @file ext/random
2638fd1498Szrj *  This file is a GNU extension to the Standard C++ Library.
2738fd1498Szrj */
2838fd1498Szrj
2938fd1498Szrj#ifndef _EXT_RANDOM
3038fd1498Szrj#define _EXT_RANDOM 1
3138fd1498Szrj
3238fd1498Szrj#pragma GCC system_header
3338fd1498Szrj
3438fd1498Szrj#if __cplusplus < 201103L
3538fd1498Szrj# include <bits/c++0x_warning.h>
3638fd1498Szrj#else
3738fd1498Szrj
3838fd1498Szrj#include <random>
3938fd1498Szrj#include <algorithm>
4038fd1498Szrj#include <array>
4138fd1498Szrj#include <ext/cmath>
4238fd1498Szrj#ifdef __SSE2__
4338fd1498Szrj# include <emmintrin.h>
4438fd1498Szrj#endif
4538fd1498Szrj
4638fd1498Szrj#if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C)
4738fd1498Szrj
4838fd1498Szrjnamespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
4938fd1498Szrj{
5038fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION
5138fd1498Szrj
5238fd1498Szrj#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
5338fd1498Szrj
5438fd1498Szrj  /* Mersenne twister implementation optimized for vector operations.
5538fd1498Szrj   *
5638fd1498Szrj   * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
5738fd1498Szrj   */
5838fd1498Szrj  template<typename _UIntType, size_t __m,
5938fd1498Szrj	   size_t __pos1, size_t __sl1, size_t __sl2,
6038fd1498Szrj	   size_t __sr1, size_t __sr2,
6138fd1498Szrj	   uint32_t __msk1, uint32_t __msk2,
6238fd1498Szrj	   uint32_t __msk3, uint32_t __msk4,
6338fd1498Szrj	   uint32_t __parity1, uint32_t __parity2,
6438fd1498Szrj	   uint32_t __parity3, uint32_t __parity4>
6538fd1498Szrj    class simd_fast_mersenne_twister_engine
6638fd1498Szrj    {
6738fd1498Szrj      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
6838fd1498Szrj		    "substituting _UIntType not an unsigned integral type");
6938fd1498Szrj      static_assert(__sr1 < 32, "first right shift too large");
7038fd1498Szrj      static_assert(__sr2 < 16, "second right shift too large");
7138fd1498Szrj      static_assert(__sl1 < 32, "first left shift too large");
7238fd1498Szrj      static_assert(__sl2 < 16, "second left shift too large");
7338fd1498Szrj
7438fd1498Szrj    public:
7538fd1498Szrj      typedef _UIntType result_type;
7638fd1498Szrj
7738fd1498Szrj    private:
7838fd1498Szrj      static constexpr size_t m_w = sizeof(result_type) * 8;
7938fd1498Szrj      static constexpr size_t _M_nstate = __m / 128 + 1;
8038fd1498Szrj      static constexpr size_t _M_nstate32 = _M_nstate * 4;
8138fd1498Szrj
8238fd1498Szrj      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
8338fd1498Szrj		    "substituting _UIntType not an unsigned integral type");
8438fd1498Szrj      static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size");
8538fd1498Szrj      static_assert(16 % sizeof(_UIntType) == 0,
8638fd1498Szrj		    "UIntType size must divide 16");
8738fd1498Szrj
8838fd1498Szrj    public:
8938fd1498Szrj      static constexpr size_t state_size = _M_nstate * (16
9038fd1498Szrj							/ sizeof(result_type));
9138fd1498Szrj      static constexpr result_type default_seed = 5489u;
9238fd1498Szrj
9338fd1498Szrj      // constructors and member function
9438fd1498Szrj      explicit
9538fd1498Szrj      simd_fast_mersenne_twister_engine(result_type __sd = default_seed)
9638fd1498Szrj      { seed(__sd); }
9738fd1498Szrj
9838fd1498Szrj      template<typename _Sseq, typename = typename
9938fd1498Szrj	std::enable_if<!std::is_same<_Sseq,
10038fd1498Szrj				     simd_fast_mersenne_twister_engine>::value>
10138fd1498Szrj	       ::type>
10238fd1498Szrj	explicit
10338fd1498Szrj	simd_fast_mersenne_twister_engine(_Sseq& __q)
10438fd1498Szrj	{ seed(__q); }
10538fd1498Szrj
10638fd1498Szrj      void
10738fd1498Szrj      seed(result_type __sd = default_seed);
10838fd1498Szrj
10938fd1498Szrj      template<typename _Sseq>
11038fd1498Szrj	typename std::enable_if<std::is_class<_Sseq>::value>::type
11138fd1498Szrj	seed(_Sseq& __q);
11238fd1498Szrj
11338fd1498Szrj      static constexpr result_type
11438fd1498Szrj      min()
11538fd1498Szrj      { return 0; }
11638fd1498Szrj
11738fd1498Szrj      static constexpr result_type
11838fd1498Szrj      max()
11938fd1498Szrj      { return std::numeric_limits<result_type>::max(); }
12038fd1498Szrj
12138fd1498Szrj      void
12238fd1498Szrj      discard(unsigned long long __z);
12338fd1498Szrj
12438fd1498Szrj      result_type
12538fd1498Szrj      operator()()
12638fd1498Szrj      {
12738fd1498Szrj	if (__builtin_expect(_M_pos >= state_size, 0))
12838fd1498Szrj	  _M_gen_rand();
12938fd1498Szrj
13038fd1498Szrj	return _M_stateT[_M_pos++];
13138fd1498Szrj      }
13238fd1498Szrj
13338fd1498Szrj      template<typename _UIntType_2, size_t __m_2,
13438fd1498Szrj	       size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
13538fd1498Szrj	       size_t __sr1_2, size_t __sr2_2,
13638fd1498Szrj	       uint32_t __msk1_2, uint32_t __msk2_2,
13738fd1498Szrj	       uint32_t __msk3_2, uint32_t __msk4_2,
13838fd1498Szrj	       uint32_t __parity1_2, uint32_t __parity2_2,
13938fd1498Szrj	       uint32_t __parity3_2, uint32_t __parity4_2>
14038fd1498Szrj	friend bool
14138fd1498Szrj	operator==(const simd_fast_mersenne_twister_engine<_UIntType_2,
14238fd1498Szrj		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
14338fd1498Szrj		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
14438fd1498Szrj		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs,
14538fd1498Szrj		   const simd_fast_mersenne_twister_engine<_UIntType_2,
14638fd1498Szrj		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
14738fd1498Szrj		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
14838fd1498Szrj		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs);
14938fd1498Szrj
15038fd1498Szrj      template<typename _UIntType_2, size_t __m_2,
15138fd1498Szrj	       size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
15238fd1498Szrj	       size_t __sr1_2, size_t __sr2_2,
15338fd1498Szrj	       uint32_t __msk1_2, uint32_t __msk2_2,
15438fd1498Szrj	       uint32_t __msk3_2, uint32_t __msk4_2,
15538fd1498Szrj	       uint32_t __parity1_2, uint32_t __parity2_2,
15638fd1498Szrj	       uint32_t __parity3_2, uint32_t __parity4_2,
15738fd1498Szrj	       typename _CharT, typename _Traits>
15838fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
15938fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
16038fd1498Szrj		   const __gnu_cxx::simd_fast_mersenne_twister_engine
16138fd1498Szrj		   <_UIntType_2,
16238fd1498Szrj		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
16338fd1498Szrj		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
16438fd1498Szrj		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
16538fd1498Szrj
16638fd1498Szrj      template<typename _UIntType_2, size_t __m_2,
16738fd1498Szrj	       size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
16838fd1498Szrj	       size_t __sr1_2, size_t __sr2_2,
16938fd1498Szrj	       uint32_t __msk1_2, uint32_t __msk2_2,
17038fd1498Szrj	       uint32_t __msk3_2, uint32_t __msk4_2,
17138fd1498Szrj	       uint32_t __parity1_2, uint32_t __parity2_2,
17238fd1498Szrj	       uint32_t __parity3_2, uint32_t __parity4_2,
17338fd1498Szrj	       typename _CharT, typename _Traits>
17438fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
17538fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
17638fd1498Szrj		   __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2,
17738fd1498Szrj		   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
17838fd1498Szrj		   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
17938fd1498Szrj		   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
18038fd1498Szrj
18138fd1498Szrj    private:
18238fd1498Szrj      union
18338fd1498Szrj      {
18438fd1498Szrj#ifdef __SSE2__
18538fd1498Szrj	__m128i _M_state[_M_nstate];
18638fd1498Szrj#endif
18738fd1498Szrj#ifdef __ARM_NEON
18838fd1498Szrj#ifdef __aarch64__
18938fd1498Szrj	__Uint32x4_t _M_state[_M_nstate];
19038fd1498Szrj#endif
19138fd1498Szrj#endif
19238fd1498Szrj	uint32_t _M_state32[_M_nstate32];
19338fd1498Szrj	result_type _M_stateT[state_size];
19438fd1498Szrj      } __attribute__ ((__aligned__ (16)));
19538fd1498Szrj      size_t _M_pos;
19638fd1498Szrj
19738fd1498Szrj      void _M_gen_rand(void);
19838fd1498Szrj      void _M_period_certification();
19938fd1498Szrj  };
20038fd1498Szrj
20138fd1498Szrj
20238fd1498Szrj  template<typename _UIntType, size_t __m,
20338fd1498Szrj	   size_t __pos1, size_t __sl1, size_t __sl2,
20438fd1498Szrj	   size_t __sr1, size_t __sr2,
20538fd1498Szrj	   uint32_t __msk1, uint32_t __msk2,
20638fd1498Szrj	   uint32_t __msk3, uint32_t __msk4,
20738fd1498Szrj	   uint32_t __parity1, uint32_t __parity2,
20838fd1498Szrj	   uint32_t __parity3, uint32_t __parity4>
20938fd1498Szrj    inline bool
21038fd1498Szrj    operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
21138fd1498Szrj	       __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
21238fd1498Szrj	       __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs,
21338fd1498Szrj	       const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
21438fd1498Szrj	       __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
21538fd1498Szrj	       __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs)
21638fd1498Szrj    { return !(__lhs == __rhs); }
21738fd1498Szrj
21838fd1498Szrj
21938fd1498Szrj  /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined
22038fd1498Szrj   * in the C implementation by Daito and Matsumoto, as both a 32-bit
22138fd1498Szrj   * and 64-bit version.
22238fd1498Szrj   */
22338fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2,
22438fd1498Szrj					    15, 3, 13, 3,
22538fd1498Szrj					    0xfdff37ffU, 0xef7f3f7dU,
22638fd1498Szrj					    0xff777b7dU, 0x7ff7fb2fU,
22738fd1498Szrj					    0x00000001U, 0x00000000U,
22838fd1498Szrj					    0x00000000U, 0x5986f054U>
22938fd1498Szrj    sfmt607;
23038fd1498Szrj
23138fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2,
23238fd1498Szrj					    15, 3, 13, 3,
23338fd1498Szrj					    0xfdff37ffU, 0xef7f3f7dU,
23438fd1498Szrj					    0xff777b7dU, 0x7ff7fb2fU,
23538fd1498Szrj					    0x00000001U, 0x00000000U,
23638fd1498Szrj					    0x00000000U, 0x5986f054U>
23738fd1498Szrj    sfmt607_64;
23838fd1498Szrj
23938fd1498Szrj
24038fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7,
24138fd1498Szrj					    14, 3, 5, 1,
24238fd1498Szrj					    0xf7fefffdU, 0x7fefcfffU,
24338fd1498Szrj					    0xaff3ef3fU, 0xb5ffff7fU,
24438fd1498Szrj					    0x00000001U, 0x00000000U,
24538fd1498Szrj					    0x00000000U, 0x20000000U>
24638fd1498Szrj    sfmt1279;
24738fd1498Szrj
24838fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7,
24938fd1498Szrj					    14, 3, 5, 1,
25038fd1498Szrj					    0xf7fefffdU, 0x7fefcfffU,
25138fd1498Szrj					    0xaff3ef3fU, 0xb5ffff7fU,
25238fd1498Szrj					    0x00000001U, 0x00000000U,
25338fd1498Szrj					    0x00000000U, 0x20000000U>
25438fd1498Szrj    sfmt1279_64;
25538fd1498Szrj
25638fd1498Szrj
25738fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12,
25838fd1498Szrj					    19, 1, 5, 1,
25938fd1498Szrj					    0xbff7ffbfU, 0xfdfffffeU,
26038fd1498Szrj					    0xf7ffef7fU, 0xf2f7cbbfU,
26138fd1498Szrj					    0x00000001U, 0x00000000U,
26238fd1498Szrj					    0x00000000U, 0x41dfa600U>
26338fd1498Szrj    sfmt2281;
26438fd1498Szrj
26538fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12,
26638fd1498Szrj					    19, 1, 5, 1,
26738fd1498Szrj					    0xbff7ffbfU, 0xfdfffffeU,
26838fd1498Szrj					    0xf7ffef7fU, 0xf2f7cbbfU,
26938fd1498Szrj					    0x00000001U, 0x00000000U,
27038fd1498Szrj					    0x00000000U, 0x41dfa600U>
27138fd1498Szrj    sfmt2281_64;
27238fd1498Szrj
27338fd1498Szrj
27438fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17,
27538fd1498Szrj					    20, 1, 7, 1,
27638fd1498Szrj					    0x9f7bffffU, 0x9fffff5fU,
27738fd1498Szrj					    0x3efffffbU, 0xfffff7bbU,
27838fd1498Szrj					    0xa8000001U, 0xaf5390a3U,
27938fd1498Szrj					    0xb740b3f8U, 0x6c11486dU>
28038fd1498Szrj    sfmt4253;
28138fd1498Szrj
28238fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17,
28338fd1498Szrj					    20, 1, 7, 1,
28438fd1498Szrj					    0x9f7bffffU, 0x9fffff5fU,
28538fd1498Szrj					    0x3efffffbU, 0xfffff7bbU,
28638fd1498Szrj					    0xa8000001U, 0xaf5390a3U,
28738fd1498Szrj					    0xb740b3f8U, 0x6c11486dU>
28838fd1498Szrj    sfmt4253_64;
28938fd1498Szrj
29038fd1498Szrj
29138fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68,
29238fd1498Szrj					    14, 3, 7, 3,
29338fd1498Szrj					    0xeffff7fbU, 0xffffffefU,
29438fd1498Szrj					    0xdfdfbfffU, 0x7fffdbfdU,
29538fd1498Szrj					    0x00000001U, 0x00000000U,
29638fd1498Szrj					    0xe8148000U, 0xd0c7afa3U>
29738fd1498Szrj    sfmt11213;
29838fd1498Szrj
29938fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68,
30038fd1498Szrj					    14, 3, 7, 3,
30138fd1498Szrj					    0xeffff7fbU, 0xffffffefU,
30238fd1498Szrj					    0xdfdfbfffU, 0x7fffdbfdU,
30338fd1498Szrj					    0x00000001U, 0x00000000U,
30438fd1498Szrj					    0xe8148000U, 0xd0c7afa3U>
30538fd1498Szrj    sfmt11213_64;
30638fd1498Szrj
30738fd1498Szrj
30838fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122,
30938fd1498Szrj					    18, 1, 11, 1,
31038fd1498Szrj					    0xdfffffefU, 0xddfecb7fU,
31138fd1498Szrj					    0xbffaffffU, 0xbffffff6U,
31238fd1498Szrj					    0x00000001U, 0x00000000U,
31338fd1498Szrj					    0x00000000U, 0x13c9e684U>
31438fd1498Szrj    sfmt19937;
31538fd1498Szrj
31638fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122,
31738fd1498Szrj					    18, 1, 11, 1,
31838fd1498Szrj					    0xdfffffefU, 0xddfecb7fU,
31938fd1498Szrj					    0xbffaffffU, 0xbffffff6U,
32038fd1498Szrj					    0x00000001U, 0x00000000U,
32138fd1498Szrj					    0x00000000U, 0x13c9e684U>
32238fd1498Szrj    sfmt19937_64;
32338fd1498Szrj
32438fd1498Szrj
32538fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330,
32638fd1498Szrj					    5, 3, 9, 3,
32738fd1498Szrj					    0xeffffffbU, 0xdfbebfffU,
32838fd1498Szrj					    0xbfbf7befU, 0x9ffd7bffU,
32938fd1498Szrj					    0x00000001U, 0x00000000U,
33038fd1498Szrj					    0xa3ac4000U, 0xecc1327aU>
33138fd1498Szrj    sfmt44497;
33238fd1498Szrj
33338fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330,
33438fd1498Szrj					    5, 3, 9, 3,
33538fd1498Szrj					    0xeffffffbU, 0xdfbebfffU,
33638fd1498Szrj					    0xbfbf7befU, 0x9ffd7bffU,
33738fd1498Szrj					    0x00000001U, 0x00000000U,
33838fd1498Szrj					    0xa3ac4000U, 0xecc1327aU>
33938fd1498Szrj    sfmt44497_64;
34038fd1498Szrj
34138fd1498Szrj
34238fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366,
34338fd1498Szrj					    6, 7, 19, 1,
34438fd1498Szrj					    0xfdbffbffU, 0xbff7ff3fU,
34538fd1498Szrj					    0xfd77efffU, 0xbf9ff3ffU,
34638fd1498Szrj					    0x00000001U, 0x00000000U,
34738fd1498Szrj					    0x00000000U, 0xe9528d85U>
34838fd1498Szrj    sfmt86243;
34938fd1498Szrj
35038fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366,
35138fd1498Szrj					    6, 7, 19, 1,
35238fd1498Szrj					    0xfdbffbffU, 0xbff7ff3fU,
35338fd1498Szrj					    0xfd77efffU, 0xbf9ff3ffU,
35438fd1498Szrj					    0x00000001U, 0x00000000U,
35538fd1498Szrj					    0x00000000U, 0xe9528d85U>
35638fd1498Szrj    sfmt86243_64;
35738fd1498Szrj
35838fd1498Szrj
35938fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110,
36038fd1498Szrj					    19, 1, 21, 1,
36138fd1498Szrj					    0xffffbb5fU, 0xfb6ebf95U,
36238fd1498Szrj					    0xfffefffaU, 0xcff77fffU,
36338fd1498Szrj					    0x00000001U, 0x00000000U,
36438fd1498Szrj					    0xcb520000U, 0xc7e91c7dU>
36538fd1498Szrj    sfmt132049;
36638fd1498Szrj
36738fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110,
36838fd1498Szrj					    19, 1, 21, 1,
36938fd1498Szrj					    0xffffbb5fU, 0xfb6ebf95U,
37038fd1498Szrj					    0xfffefffaU, 0xcff77fffU,
37138fd1498Szrj					    0x00000001U, 0x00000000U,
37238fd1498Szrj					    0xcb520000U, 0xc7e91c7dU>
37338fd1498Szrj    sfmt132049_64;
37438fd1498Szrj
37538fd1498Szrj
37638fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627,
37738fd1498Szrj					    11, 3, 10, 1,
37838fd1498Szrj					    0xbff7bff7U, 0xbfffffffU,
37938fd1498Szrj					    0xbffffa7fU, 0xffddfbfbU,
38038fd1498Szrj					    0xf8000001U, 0x89e80709U,
38138fd1498Szrj					    0x3bd2b64bU, 0x0c64b1e4U>
38238fd1498Szrj    sfmt216091;
38338fd1498Szrj
38438fd1498Szrj  typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627,
38538fd1498Szrj					    11, 3, 10, 1,
38638fd1498Szrj					    0xbff7bff7U, 0xbfffffffU,
38738fd1498Szrj					    0xbffffa7fU, 0xffddfbfbU,
38838fd1498Szrj					    0xf8000001U, 0x89e80709U,
38938fd1498Szrj					    0x3bd2b64bU, 0x0c64b1e4U>
39038fd1498Szrj    sfmt216091_64;
39138fd1498Szrj
39238fd1498Szrj#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
39338fd1498Szrj
39438fd1498Szrj  /**
39538fd1498Szrj   * @brief A beta continuous distribution for random numbers.
39638fd1498Szrj   *
39738fd1498Szrj   * The formula for the beta probability density function is:
39838fd1498Szrj   * @f[
39938fd1498Szrj   *     p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)}
40038fd1498Szrj   *                         x^{\alpha - 1} (1 - x)^{\beta - 1}
40138fd1498Szrj   * @f]
40238fd1498Szrj   */
40338fd1498Szrj  template<typename _RealType = double>
40438fd1498Szrj    class beta_distribution
40538fd1498Szrj    {
40638fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
40738fd1498Szrj		    "template argument not a floating point type");
40838fd1498Szrj
40938fd1498Szrj    public:
41038fd1498Szrj      /** The type of the range of the distribution. */
41138fd1498Szrj      typedef _RealType result_type;
41238fd1498Szrj
41338fd1498Szrj      /** Parameter type. */
41438fd1498Szrj      struct param_type
41538fd1498Szrj      {
41638fd1498Szrj	typedef beta_distribution<_RealType> distribution_type;
41738fd1498Szrj	friend class beta_distribution<_RealType>;
41838fd1498Szrj
41938fd1498Szrj	explicit
42038fd1498Szrj	param_type(_RealType __alpha_val = _RealType(1),
42138fd1498Szrj		   _RealType __beta_val = _RealType(1))
42238fd1498Szrj	: _M_alpha(__alpha_val), _M_beta(__beta_val)
42338fd1498Szrj	{
42438fd1498Szrj	  __glibcxx_assert(_M_alpha > _RealType(0));
42538fd1498Szrj	  __glibcxx_assert(_M_beta > _RealType(0));
42638fd1498Szrj	}
42738fd1498Szrj
42838fd1498Szrj	_RealType
42938fd1498Szrj	alpha() const
43038fd1498Szrj	{ return _M_alpha; }
43138fd1498Szrj
43238fd1498Szrj	_RealType
43338fd1498Szrj	beta() const
43438fd1498Szrj	{ return _M_beta; }
43538fd1498Szrj
43638fd1498Szrj	friend bool
43738fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
43838fd1498Szrj	{ return (__p1._M_alpha == __p2._M_alpha
43938fd1498Szrj		  && __p1._M_beta == __p2._M_beta); }
44038fd1498Szrj
44138fd1498Szrj	friend bool
44238fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
44338fd1498Szrj	{ return !(__p1 == __p2); }
44438fd1498Szrj
44538fd1498Szrj      private:
44638fd1498Szrj	void
44738fd1498Szrj	_M_initialize();
44838fd1498Szrj
44938fd1498Szrj	_RealType _M_alpha;
45038fd1498Szrj	_RealType _M_beta;
45138fd1498Szrj      };
45238fd1498Szrj
45338fd1498Szrj    public:
45438fd1498Szrj      /**
45538fd1498Szrj       * @brief Constructs a beta distribution with parameters
45638fd1498Szrj       * @f$\alpha@f$ and @f$\beta@f$.
45738fd1498Szrj       */
45838fd1498Szrj      explicit
45938fd1498Szrj      beta_distribution(_RealType __alpha_val = _RealType(1),
46038fd1498Szrj			_RealType __beta_val = _RealType(1))
46138fd1498Szrj      : _M_param(__alpha_val, __beta_val)
46238fd1498Szrj      { }
46338fd1498Szrj
46438fd1498Szrj      explicit
46538fd1498Szrj      beta_distribution(const param_type& __p)
46638fd1498Szrj      : _M_param(__p)
46738fd1498Szrj      { }
46838fd1498Szrj
46938fd1498Szrj      /**
47038fd1498Szrj       * @brief Resets the distribution state.
47138fd1498Szrj       */
47238fd1498Szrj      void
47338fd1498Szrj      reset()
47438fd1498Szrj      { }
47538fd1498Szrj
47638fd1498Szrj      /**
47738fd1498Szrj       * @brief Returns the @f$\alpha@f$ of the distribution.
47838fd1498Szrj       */
47938fd1498Szrj      _RealType
48038fd1498Szrj      alpha() const
48138fd1498Szrj      { return _M_param.alpha(); }
48238fd1498Szrj
48338fd1498Szrj      /**
48438fd1498Szrj       * @brief Returns the @f$\beta@f$ of the distribution.
48538fd1498Szrj       */
48638fd1498Szrj      _RealType
48738fd1498Szrj      beta() const
48838fd1498Szrj      { return _M_param.beta(); }
48938fd1498Szrj
49038fd1498Szrj      /**
49138fd1498Szrj       * @brief Returns the parameter set of the distribution.
49238fd1498Szrj       */
49338fd1498Szrj      param_type
49438fd1498Szrj      param() const
49538fd1498Szrj      { return _M_param; }
49638fd1498Szrj
49738fd1498Szrj      /**
49838fd1498Szrj       * @brief Sets the parameter set of the distribution.
49938fd1498Szrj       * @param __param The new parameter set of the distribution.
50038fd1498Szrj       */
50138fd1498Szrj      void
50238fd1498Szrj      param(const param_type& __param)
50338fd1498Szrj      { _M_param = __param; }
50438fd1498Szrj
50538fd1498Szrj      /**
50638fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
50738fd1498Szrj       */
50838fd1498Szrj      result_type
50938fd1498Szrj      min() const
51038fd1498Szrj      { return result_type(0); }
51138fd1498Szrj
51238fd1498Szrj      /**
51338fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
51438fd1498Szrj       */
51538fd1498Szrj      result_type
51638fd1498Szrj      max() const
51738fd1498Szrj      { return result_type(1); }
51838fd1498Szrj
51938fd1498Szrj      /**
52038fd1498Szrj       * @brief Generating functions.
52138fd1498Szrj       */
52238fd1498Szrj      template<typename _UniformRandomNumberGenerator>
52338fd1498Szrj	result_type
52438fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
52538fd1498Szrj	{ return this->operator()(__urng, _M_param); }
52638fd1498Szrj
52738fd1498Szrj      template<typename _UniformRandomNumberGenerator>
52838fd1498Szrj	result_type
52938fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
53038fd1498Szrj		   const param_type& __p);
53138fd1498Szrj
53238fd1498Szrj      template<typename _ForwardIterator,
53338fd1498Szrj	       typename _UniformRandomNumberGenerator>
53438fd1498Szrj	void
53538fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
53638fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
53738fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
53838fd1498Szrj
53938fd1498Szrj      template<typename _ForwardIterator,
54038fd1498Szrj	       typename _UniformRandomNumberGenerator>
54138fd1498Szrj	void
54238fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
54338fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
54438fd1498Szrj		   const param_type& __p)
54538fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
54638fd1498Szrj
54738fd1498Szrj      template<typename _UniformRandomNumberGenerator>
54838fd1498Szrj	void
54938fd1498Szrj	__generate(result_type* __f, result_type* __t,
55038fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
55138fd1498Szrj		   const param_type& __p)
55238fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
55338fd1498Szrj
55438fd1498Szrj      /**
55538fd1498Szrj       * @brief Return true if two beta distributions have the same
55638fd1498Szrj       *        parameters and the sequences that would be generated
55738fd1498Szrj       *        are equal.
55838fd1498Szrj       */
55938fd1498Szrj      friend bool
56038fd1498Szrj      operator==(const beta_distribution& __d1,
56138fd1498Szrj		 const beta_distribution& __d2)
56238fd1498Szrj      { return __d1._M_param == __d2._M_param; }
56338fd1498Szrj
56438fd1498Szrj      /**
56538fd1498Szrj       * @brief Inserts a %beta_distribution random number distribution
56638fd1498Szrj       * @p __x into the output stream @p __os.
56738fd1498Szrj       *
56838fd1498Szrj       * @param __os An output stream.
56938fd1498Szrj       * @param __x  A %beta_distribution random number distribution.
57038fd1498Szrj       *
57138fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
57238fd1498Szrj       * an error state.
57338fd1498Szrj       */
57438fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
57538fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
57638fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
57738fd1498Szrj		   const __gnu_cxx::beta_distribution<_RealType1>& __x);
57838fd1498Szrj
57938fd1498Szrj      /**
58038fd1498Szrj       * @brief Extracts a %beta_distribution random number distribution
58138fd1498Szrj       * @p __x from the input stream @p __is.
58238fd1498Szrj       *
58338fd1498Szrj       * @param __is An input stream.
58438fd1498Szrj       * @param __x  A %beta_distribution random number generator engine.
58538fd1498Szrj       *
58638fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
58738fd1498Szrj       */
58838fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
58938fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
59038fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
59138fd1498Szrj		   __gnu_cxx::beta_distribution<_RealType1>& __x);
59238fd1498Szrj
59338fd1498Szrj    private:
59438fd1498Szrj      template<typename _ForwardIterator,
59538fd1498Szrj	       typename _UniformRandomNumberGenerator>
59638fd1498Szrj	void
59738fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
59838fd1498Szrj			_UniformRandomNumberGenerator& __urng,
59938fd1498Szrj			const param_type& __p);
60038fd1498Szrj
60138fd1498Szrj      param_type _M_param;
60238fd1498Szrj    };
60338fd1498Szrj
60438fd1498Szrj  /**
60538fd1498Szrj   * @brief Return true if two beta distributions are different.
60638fd1498Szrj   */
60738fd1498Szrj  template<typename _RealType>
60838fd1498Szrj    inline bool
60938fd1498Szrj    operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
61038fd1498Szrj	       const __gnu_cxx::beta_distribution<_RealType>& __d2)
61138fd1498Szrj    { return !(__d1 == __d2); }
61238fd1498Szrj
61338fd1498Szrj
61438fd1498Szrj  /**
61538fd1498Szrj   * @brief A multi-variate normal continuous distribution for random numbers.
61638fd1498Szrj   *
61738fd1498Szrj   * The formula for the normal probability density function is
61838fd1498Szrj   * @f[
61938fd1498Szrj   *     p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) =
62038fd1498Szrj   *       \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}}
62138fd1498Szrj   *       e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T}
62238fd1498Szrj   *          \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})}
62338fd1498Szrj   * @f]
62438fd1498Szrj   *
62538fd1498Szrj   * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are
62638fd1498Szrj   * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance
62738fd1498Szrj   * matrix (which must be positive-definite).
62838fd1498Szrj   */
62938fd1498Szrj  template<std::size_t _Dimen, typename _RealType = double>
63038fd1498Szrj    class normal_mv_distribution
63138fd1498Szrj    {
63238fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
63338fd1498Szrj		    "template argument not a floating point type");
63438fd1498Szrj      static_assert(_Dimen != 0, "dimension is zero");
63538fd1498Szrj
63638fd1498Szrj    public:
63738fd1498Szrj      /** The type of the range of the distribution. */
63838fd1498Szrj      typedef std::array<_RealType, _Dimen> result_type;
63938fd1498Szrj      /** Parameter type. */
64038fd1498Szrj      class param_type
64138fd1498Szrj      {
64238fd1498Szrj	static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2;
64338fd1498Szrj
64438fd1498Szrj      public:
64538fd1498Szrj	typedef normal_mv_distribution<_Dimen, _RealType> distribution_type;
64638fd1498Szrj	friend class normal_mv_distribution<_Dimen, _RealType>;
64738fd1498Szrj
64838fd1498Szrj	param_type()
64938fd1498Szrj	{
65038fd1498Szrj	  std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0));
65138fd1498Szrj	  auto __it = _M_t.begin();
65238fd1498Szrj	  for (size_t __i = 0; __i < _Dimen; ++__i)
65338fd1498Szrj	    {
65438fd1498Szrj	      std::fill_n(__it, __i, _RealType(0));
65538fd1498Szrj	      __it += __i;
65638fd1498Szrj	      *__it++ = _RealType(1);
65738fd1498Szrj	    }
65838fd1498Szrj	}
65938fd1498Szrj
66038fd1498Szrj	template<typename _ForwardIterator1, typename _ForwardIterator2>
66138fd1498Szrj	  param_type(_ForwardIterator1 __meanbegin,
66238fd1498Szrj		     _ForwardIterator1 __meanend,
66338fd1498Szrj		     _ForwardIterator2 __varcovbegin,
66438fd1498Szrj		     _ForwardIterator2 __varcovend)
66538fd1498Szrj	{
66638fd1498Szrj	  __glibcxx_function_requires(_ForwardIteratorConcept<
66738fd1498Szrj				      _ForwardIterator1>)
66838fd1498Szrj	  __glibcxx_function_requires(_ForwardIteratorConcept<
66938fd1498Szrj				      _ForwardIterator2>)
67038fd1498Szrj	  _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend)
67138fd1498Szrj				<= _Dimen);
67238fd1498Szrj	  const auto __dist = std::distance(__varcovbegin, __varcovend);
67338fd1498Szrj	  _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen
67438fd1498Szrj				|| __dist == _Dimen * (_Dimen + 1) / 2
67538fd1498Szrj				|| __dist == _Dimen);
67638fd1498Szrj
67738fd1498Szrj	  if (__dist == _Dimen * _Dimen)
67838fd1498Szrj	    _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend);
67938fd1498Szrj	  else if (__dist == _Dimen * (_Dimen + 1) / 2)
68038fd1498Szrj	    _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend);
68138fd1498Szrj	  else
68238fd1498Szrj	    {
68338fd1498Szrj	      __glibcxx_assert(__dist == _Dimen);
68438fd1498Szrj	      _M_init_diagonal(__meanbegin, __meanend,
68538fd1498Szrj			       __varcovbegin, __varcovend);
68638fd1498Szrj	    }
68738fd1498Szrj	}
68838fd1498Szrj
68938fd1498Szrj	param_type(std::initializer_list<_RealType> __mean,
69038fd1498Szrj		   std::initializer_list<_RealType> __varcov)
69138fd1498Szrj	{
69238fd1498Szrj	  _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen);
69338fd1498Szrj	  _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen
69438fd1498Szrj				|| __varcov.size() == _Dimen * (_Dimen + 1) / 2
69538fd1498Szrj				|| __varcov.size() == _Dimen);
69638fd1498Szrj
69738fd1498Szrj	  if (__varcov.size() == _Dimen * _Dimen)
69838fd1498Szrj	    _M_init_full(__mean.begin(), __mean.end(),
69938fd1498Szrj			 __varcov.begin(), __varcov.end());
70038fd1498Szrj	  else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2)
70138fd1498Szrj	    _M_init_lower(__mean.begin(), __mean.end(),
70238fd1498Szrj			  __varcov.begin(), __varcov.end());
70338fd1498Szrj	  else
70438fd1498Szrj	    {
70538fd1498Szrj	      __glibcxx_assert(__varcov.size() == _Dimen);
70638fd1498Szrj	      _M_init_diagonal(__mean.begin(), __mean.end(),
70738fd1498Szrj			       __varcov.begin(), __varcov.end());
70838fd1498Szrj	    }
70938fd1498Szrj	}
71038fd1498Szrj
71138fd1498Szrj	std::array<_RealType, _Dimen>
71238fd1498Szrj	mean() const
71338fd1498Szrj	{ return _M_mean; }
71438fd1498Szrj
71538fd1498Szrj	std::array<_RealType, _M_t_size>
71638fd1498Szrj	varcov() const
71738fd1498Szrj	{ return _M_t; }
71838fd1498Szrj
71938fd1498Szrj	friend bool
72038fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
72138fd1498Szrj	{ return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; }
72238fd1498Szrj
72338fd1498Szrj	friend bool
72438fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
72538fd1498Szrj	{ return !(__p1 == __p2); }
72638fd1498Szrj
72738fd1498Szrj      private:
72838fd1498Szrj	template <typename _InputIterator1, typename _InputIterator2>
72938fd1498Szrj	  void _M_init_full(_InputIterator1 __meanbegin,
73038fd1498Szrj			    _InputIterator1 __meanend,
73138fd1498Szrj			    _InputIterator2 __varcovbegin,
73238fd1498Szrj			    _InputIterator2 __varcovend);
73338fd1498Szrj	template <typename _InputIterator1, typename _InputIterator2>
73438fd1498Szrj	  void _M_init_lower(_InputIterator1 __meanbegin,
73538fd1498Szrj			     _InputIterator1 __meanend,
73638fd1498Szrj			     _InputIterator2 __varcovbegin,
73738fd1498Szrj			     _InputIterator2 __varcovend);
73838fd1498Szrj	template <typename _InputIterator1, typename _InputIterator2>
73938fd1498Szrj	  void _M_init_diagonal(_InputIterator1 __meanbegin,
74038fd1498Szrj				_InputIterator1 __meanend,
74138fd1498Szrj				_InputIterator2 __varbegin,
74238fd1498Szrj				_InputIterator2 __varend);
74338fd1498Szrj
74438fd1498Szrj	std::array<_RealType, _Dimen> _M_mean;
74538fd1498Szrj	std::array<_RealType, _M_t_size> _M_t;
74638fd1498Szrj      };
74738fd1498Szrj
74838fd1498Szrj    public:
74938fd1498Szrj      normal_mv_distribution()
75038fd1498Szrj      : _M_param(), _M_nd()
75138fd1498Szrj      { }
75238fd1498Szrj
75338fd1498Szrj      template<typename _ForwardIterator1, typename _ForwardIterator2>
75438fd1498Szrj	normal_mv_distribution(_ForwardIterator1 __meanbegin,
75538fd1498Szrj			       _ForwardIterator1 __meanend,
75638fd1498Szrj			       _ForwardIterator2 __varcovbegin,
75738fd1498Szrj			       _ForwardIterator2 __varcovend)
75838fd1498Szrj	: _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend),
75938fd1498Szrj	  _M_nd()
76038fd1498Szrj	{ }
76138fd1498Szrj
76238fd1498Szrj      normal_mv_distribution(std::initializer_list<_RealType> __mean,
76338fd1498Szrj			     std::initializer_list<_RealType> __varcov)
76438fd1498Szrj      : _M_param(__mean, __varcov), _M_nd()
76538fd1498Szrj      { }
76638fd1498Szrj
76738fd1498Szrj      explicit
76838fd1498Szrj      normal_mv_distribution(const param_type& __p)
76938fd1498Szrj      : _M_param(__p), _M_nd()
77038fd1498Szrj      { }
77138fd1498Szrj
77238fd1498Szrj      /**
77338fd1498Szrj       * @brief Resets the distribution state.
77438fd1498Szrj       */
77538fd1498Szrj      void
77638fd1498Szrj      reset()
77738fd1498Szrj      { _M_nd.reset(); }
77838fd1498Szrj
77938fd1498Szrj      /**
78038fd1498Szrj       * @brief Returns the mean of the distribution.
78138fd1498Szrj       */
78238fd1498Szrj      result_type
78338fd1498Szrj      mean() const
78438fd1498Szrj      { return _M_param.mean(); }
78538fd1498Szrj
78638fd1498Szrj      /**
78738fd1498Szrj       * @brief Returns the compact form of the variance/covariance
78838fd1498Szrj       * matrix of the distribution.
78938fd1498Szrj       */
79038fd1498Szrj      std::array<_RealType, _Dimen * (_Dimen + 1) / 2>
79138fd1498Szrj      varcov() const
79238fd1498Szrj      { return _M_param.varcov(); }
79338fd1498Szrj
79438fd1498Szrj      /**
79538fd1498Szrj       * @brief Returns the parameter set of the distribution.
79638fd1498Szrj       */
79738fd1498Szrj      param_type
79838fd1498Szrj      param() const
79938fd1498Szrj      { return _M_param; }
80038fd1498Szrj
80138fd1498Szrj      /**
80238fd1498Szrj       * @brief Sets the parameter set of the distribution.
80338fd1498Szrj       * @param __param The new parameter set of the distribution.
80438fd1498Szrj       */
80538fd1498Szrj      void
80638fd1498Szrj      param(const param_type& __param)
80738fd1498Szrj      { _M_param = __param; }
80838fd1498Szrj
80938fd1498Szrj      /**
81038fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
81138fd1498Szrj       */
81238fd1498Szrj      result_type
81338fd1498Szrj      min() const
81438fd1498Szrj      { result_type __res;
81538fd1498Szrj	__res.fill(std::numeric_limits<_RealType>::lowest());
81638fd1498Szrj	return __res; }
81738fd1498Szrj
81838fd1498Szrj      /**
81938fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
82038fd1498Szrj       */
82138fd1498Szrj      result_type
82238fd1498Szrj      max() const
82338fd1498Szrj      { result_type __res;
82438fd1498Szrj	__res.fill(std::numeric_limits<_RealType>::max());
82538fd1498Szrj	return __res; }
82638fd1498Szrj
82738fd1498Szrj      /**
82838fd1498Szrj       * @brief Generating functions.
82938fd1498Szrj       */
83038fd1498Szrj      template<typename _UniformRandomNumberGenerator>
83138fd1498Szrj	result_type
83238fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
83338fd1498Szrj	{ return this->operator()(__urng, _M_param); }
83438fd1498Szrj
83538fd1498Szrj      template<typename _UniformRandomNumberGenerator>
83638fd1498Szrj	result_type
83738fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
83838fd1498Szrj		   const param_type& __p);
83938fd1498Szrj
84038fd1498Szrj      template<typename _ForwardIterator,
84138fd1498Szrj	       typename _UniformRandomNumberGenerator>
84238fd1498Szrj	void
84338fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
84438fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
84538fd1498Szrj	{ return this->__generate_impl(__f, __t, __urng, _M_param); }
84638fd1498Szrj
84738fd1498Szrj      template<typename _ForwardIterator,
84838fd1498Szrj	       typename _UniformRandomNumberGenerator>
84938fd1498Szrj	void
85038fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
85138fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
85238fd1498Szrj		   const param_type& __p)
85338fd1498Szrj	{ return this->__generate_impl(__f, __t, __urng, __p); }
85438fd1498Szrj
85538fd1498Szrj      /**
85638fd1498Szrj       * @brief Return true if two multi-variant normal distributions have
85738fd1498Szrj       *        the same parameters and the sequences that would
85838fd1498Szrj       *        be generated are equal.
85938fd1498Szrj       */
86038fd1498Szrj      template<size_t _Dimen1, typename _RealType1>
86138fd1498Szrj	friend bool
86238fd1498Szrj	operator==(const
86338fd1498Szrj		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
86438fd1498Szrj		   __d1,
86538fd1498Szrj		   const
86638fd1498Szrj		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
86738fd1498Szrj		   __d2);
86838fd1498Szrj
86938fd1498Szrj      /**
87038fd1498Szrj       * @brief Inserts a %normal_mv_distribution random number distribution
87138fd1498Szrj       * @p __x into the output stream @p __os.
87238fd1498Szrj       *
87338fd1498Szrj       * @param __os An output stream.
87438fd1498Szrj       * @param __x  A %normal_mv_distribution random number distribution.
87538fd1498Szrj       *
87638fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
87738fd1498Szrj       * an error state.
87838fd1498Szrj       */
87938fd1498Szrj      template<size_t _Dimen1, typename _RealType1,
88038fd1498Szrj	       typename _CharT, typename _Traits>
88138fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
88238fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
88338fd1498Szrj		   const
88438fd1498Szrj		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
88538fd1498Szrj		   __x);
88638fd1498Szrj
88738fd1498Szrj      /**
88838fd1498Szrj       * @brief Extracts a %normal_mv_distribution random number distribution
88938fd1498Szrj       * @p __x from the input stream @p __is.
89038fd1498Szrj       *
89138fd1498Szrj       * @param __is An input stream.
89238fd1498Szrj       * @param __x  A %normal_mv_distribution random number generator engine.
89338fd1498Szrj       *
89438fd1498Szrj       * @returns The input stream with @p __x extracted or in an error
89538fd1498Szrj       *          state.
89638fd1498Szrj       */
89738fd1498Szrj      template<size_t _Dimen1, typename _RealType1,
89838fd1498Szrj	       typename _CharT, typename _Traits>
89938fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
90038fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
90138fd1498Szrj		   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
90238fd1498Szrj		   __x);
90338fd1498Szrj
90438fd1498Szrj    private:
90538fd1498Szrj      template<typename _ForwardIterator,
90638fd1498Szrj	       typename _UniformRandomNumberGenerator>
90738fd1498Szrj	void
90838fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
90938fd1498Szrj			_UniformRandomNumberGenerator& __urng,
91038fd1498Szrj			const param_type& __p);
91138fd1498Szrj
91238fd1498Szrj      param_type _M_param;
91338fd1498Szrj      std::normal_distribution<_RealType> _M_nd;
91438fd1498Szrj  };
91538fd1498Szrj
91638fd1498Szrj  /**
91738fd1498Szrj   * @brief Return true if two multi-variate normal distributions are
91838fd1498Szrj   * different.
91938fd1498Szrj   */
92038fd1498Szrj  template<size_t _Dimen, typename _RealType>
92138fd1498Szrj    inline bool
92238fd1498Szrj    operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
92338fd1498Szrj	       __d1,
92438fd1498Szrj	       const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
92538fd1498Szrj	       __d2)
92638fd1498Szrj    { return !(__d1 == __d2); }
92738fd1498Szrj
92838fd1498Szrj
92938fd1498Szrj  /**
93038fd1498Szrj   * @brief A Rice continuous distribution for random numbers.
93138fd1498Szrj   *
93238fd1498Szrj   * The formula for the Rice probability density function is
93338fd1498Szrj   * @f[
93438fd1498Szrj   *     p(x|\nu,\sigma) = \frac{x}{\sigma^2}
93538fd1498Szrj   *                       \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right)
93638fd1498Szrj   *                       I_0\left(\frac{x \nu}{\sigma^2}\right)
93738fd1498Szrj   * @f]
93838fd1498Szrj   * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
93938fd1498Szrj   * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$.
94038fd1498Szrj   *
94138fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
94238fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
94338fd1498Szrj   * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
94438fd1498Szrj   * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2
94538fd1498Szrj   *                   + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
94638fd1498Szrj   * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
94738fd1498Szrj   * </table>
94838fd1498Szrj   * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2.
94938fd1498Szrj   */
95038fd1498Szrj  template<typename _RealType = double>
95138fd1498Szrj    class
95238fd1498Szrj    rice_distribution
95338fd1498Szrj    {
95438fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
95538fd1498Szrj		    "template argument not a floating point type");
95638fd1498Szrj    public:
95738fd1498Szrj      /** The type of the range of the distribution. */
95838fd1498Szrj      typedef _RealType result_type;
95938fd1498Szrj
96038fd1498Szrj      /** Parameter type. */
96138fd1498Szrj      struct param_type
96238fd1498Szrj      {
96338fd1498Szrj	typedef rice_distribution<result_type> distribution_type;
96438fd1498Szrj
96538fd1498Szrj	param_type(result_type __nu_val = result_type(0),
96638fd1498Szrj		   result_type __sigma_val = result_type(1))
96738fd1498Szrj	: _M_nu(__nu_val), _M_sigma(__sigma_val)
96838fd1498Szrj	{
96938fd1498Szrj	  __glibcxx_assert(_M_nu >= result_type(0));
97038fd1498Szrj	  __glibcxx_assert(_M_sigma > result_type(0));
97138fd1498Szrj	}
97238fd1498Szrj
97338fd1498Szrj	result_type
97438fd1498Szrj	nu() const
97538fd1498Szrj	{ return _M_nu; }
97638fd1498Szrj
97738fd1498Szrj	result_type
97838fd1498Szrj	sigma() const
97938fd1498Szrj	{ return _M_sigma; }
98038fd1498Szrj
98138fd1498Szrj	friend bool
98238fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
98338fd1498Szrj	{ return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; }
98438fd1498Szrj
98538fd1498Szrj	friend bool
98638fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
98738fd1498Szrj	{ return !(__p1 == __p2); }
98838fd1498Szrj
98938fd1498Szrj      private:
99038fd1498Szrj	void _M_initialize();
99138fd1498Szrj
99238fd1498Szrj	result_type _M_nu;
99338fd1498Szrj	result_type _M_sigma;
99438fd1498Szrj      };
99538fd1498Szrj
99638fd1498Szrj      /**
99738fd1498Szrj       * @brief Constructors.
99838fd1498Szrj       */
99938fd1498Szrj      explicit
100038fd1498Szrj      rice_distribution(result_type __nu_val = result_type(0),
100138fd1498Szrj			result_type __sigma_val = result_type(1))
100238fd1498Szrj      : _M_param(__nu_val, __sigma_val),
100338fd1498Szrj	_M_ndx(__nu_val, __sigma_val),
100438fd1498Szrj	_M_ndy(result_type(0), __sigma_val)
100538fd1498Szrj      { }
100638fd1498Szrj
100738fd1498Szrj      explicit
100838fd1498Szrj      rice_distribution(const param_type& __p)
100938fd1498Szrj      : _M_param(__p),
101038fd1498Szrj	_M_ndx(__p.nu(), __p.sigma()),
101138fd1498Szrj	_M_ndy(result_type(0), __p.sigma())
101238fd1498Szrj      { }
101338fd1498Szrj
101438fd1498Szrj      /**
101538fd1498Szrj       * @brief Resets the distribution state.
101638fd1498Szrj       */
101738fd1498Szrj      void
101838fd1498Szrj      reset()
101938fd1498Szrj      {
102038fd1498Szrj	_M_ndx.reset();
102138fd1498Szrj	_M_ndy.reset();
102238fd1498Szrj      }
102338fd1498Szrj
102438fd1498Szrj      /**
102538fd1498Szrj       * @brief Return the parameters of the distribution.
102638fd1498Szrj       */
102738fd1498Szrj      result_type
102838fd1498Szrj      nu() const
102938fd1498Szrj      { return _M_param.nu(); }
103038fd1498Szrj
103138fd1498Szrj      result_type
103238fd1498Szrj      sigma() const
103338fd1498Szrj      { return _M_param.sigma(); }
103438fd1498Szrj
103538fd1498Szrj      /**
103638fd1498Szrj       * @brief Returns the parameter set of the distribution.
103738fd1498Szrj       */
103838fd1498Szrj      param_type
103938fd1498Szrj      param() const
104038fd1498Szrj      { return _M_param; }
104138fd1498Szrj
104238fd1498Szrj      /**
104338fd1498Szrj       * @brief Sets the parameter set of the distribution.
104438fd1498Szrj       * @param __param The new parameter set of the distribution.
104538fd1498Szrj       */
104638fd1498Szrj      void
104738fd1498Szrj      param(const param_type& __param)
104838fd1498Szrj      { _M_param = __param; }
104938fd1498Szrj
105038fd1498Szrj      /**
105138fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
105238fd1498Szrj       */
105338fd1498Szrj      result_type
105438fd1498Szrj      min() const
105538fd1498Szrj      { return result_type(0); }
105638fd1498Szrj
105738fd1498Szrj      /**
105838fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
105938fd1498Szrj       */
106038fd1498Szrj      result_type
106138fd1498Szrj      max() const
106238fd1498Szrj      { return std::numeric_limits<result_type>::max(); }
106338fd1498Szrj
106438fd1498Szrj      /**
106538fd1498Szrj       * @brief Generating functions.
106638fd1498Szrj       */
106738fd1498Szrj      template<typename _UniformRandomNumberGenerator>
106838fd1498Szrj	result_type
106938fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
107038fd1498Szrj	{
107138fd1498Szrj	  result_type __x = this->_M_ndx(__urng);
107238fd1498Szrj	  result_type __y = this->_M_ndy(__urng);
107338fd1498Szrj#if _GLIBCXX_USE_C99_MATH_TR1
107438fd1498Szrj	  return std::hypot(__x, __y);
107538fd1498Szrj#else
107638fd1498Szrj	  return std::sqrt(__x * __x + __y * __y);
107738fd1498Szrj#endif
107838fd1498Szrj	}
107938fd1498Szrj
108038fd1498Szrj      template<typename _UniformRandomNumberGenerator>
108138fd1498Szrj	result_type
108238fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
108338fd1498Szrj		   const param_type& __p)
108438fd1498Szrj	{
108538fd1498Szrj	  typename std::normal_distribution<result_type>::param_type
108638fd1498Szrj	    __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
108738fd1498Szrj	  result_type __x = this->_M_ndx(__px, __urng);
108838fd1498Szrj	  result_type __y = this->_M_ndy(__py, __urng);
108938fd1498Szrj#if _GLIBCXX_USE_C99_MATH_TR1
109038fd1498Szrj	  return std::hypot(__x, __y);
109138fd1498Szrj#else
109238fd1498Szrj	  return std::sqrt(__x * __x + __y * __y);
109338fd1498Szrj#endif
109438fd1498Szrj	}
109538fd1498Szrj
109638fd1498Szrj      template<typename _ForwardIterator,
109738fd1498Szrj	       typename _UniformRandomNumberGenerator>
109838fd1498Szrj	void
109938fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
110038fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
110138fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
110238fd1498Szrj
110338fd1498Szrj      template<typename _ForwardIterator,
110438fd1498Szrj	       typename _UniformRandomNumberGenerator>
110538fd1498Szrj	void
110638fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
110738fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
110838fd1498Szrj		   const param_type& __p)
110938fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
111038fd1498Szrj
111138fd1498Szrj      template<typename _UniformRandomNumberGenerator>
111238fd1498Szrj	void
111338fd1498Szrj	__generate(result_type* __f, result_type* __t,
111438fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
111538fd1498Szrj		   const param_type& __p)
111638fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
111738fd1498Szrj
111838fd1498Szrj      /**
111938fd1498Szrj       * @brief Return true if two Rice distributions have
112038fd1498Szrj       *        the same parameters and the sequences that would
112138fd1498Szrj       *        be generated are equal.
112238fd1498Szrj       */
112338fd1498Szrj      friend bool
112438fd1498Szrj      operator==(const rice_distribution& __d1,
112538fd1498Szrj		 const rice_distribution& __d2)
112638fd1498Szrj      { return (__d1._M_param == __d2._M_param
112738fd1498Szrj		&& __d1._M_ndx == __d2._M_ndx
112838fd1498Szrj		&& __d1._M_ndy == __d2._M_ndy); }
112938fd1498Szrj
113038fd1498Szrj      /**
113138fd1498Szrj       * @brief Inserts a %rice_distribution random number distribution
113238fd1498Szrj       * @p __x into the output stream @p __os.
113338fd1498Szrj       *
113438fd1498Szrj       * @param __os An output stream.
113538fd1498Szrj       * @param __x  A %rice_distribution random number distribution.
113638fd1498Szrj       *
113738fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
113838fd1498Szrj       * an error state.
113938fd1498Szrj       */
114038fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
114138fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
114238fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>&,
114338fd1498Szrj		   const rice_distribution<_RealType1>&);
114438fd1498Szrj
114538fd1498Szrj      /**
114638fd1498Szrj       * @brief Extracts a %rice_distribution random number distribution
114738fd1498Szrj       * @p __x from the input stream @p __is.
114838fd1498Szrj       *
114938fd1498Szrj       * @param __is An input stream.
115038fd1498Szrj       * @param __x A %rice_distribution random number
115138fd1498Szrj       *            generator engine.
115238fd1498Szrj       *
115338fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
115438fd1498Szrj       */
115538fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
115638fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
115738fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>&,
115838fd1498Szrj		   rice_distribution<_RealType1>&);
115938fd1498Szrj
116038fd1498Szrj    private:
116138fd1498Szrj      template<typename _ForwardIterator,
116238fd1498Szrj	       typename _UniformRandomNumberGenerator>
116338fd1498Szrj	void
116438fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
116538fd1498Szrj			_UniformRandomNumberGenerator& __urng,
116638fd1498Szrj			const param_type& __p);
116738fd1498Szrj
116838fd1498Szrj      param_type _M_param;
116938fd1498Szrj
117038fd1498Szrj      std::normal_distribution<result_type> _M_ndx;
117138fd1498Szrj      std::normal_distribution<result_type> _M_ndy;
117238fd1498Szrj    };
117338fd1498Szrj
117438fd1498Szrj  /**
117538fd1498Szrj   * @brief Return true if two Rice distributions are not equal.
117638fd1498Szrj   */
117738fd1498Szrj  template<typename _RealType1>
117838fd1498Szrj    inline bool
117938fd1498Szrj    operator!=(const rice_distribution<_RealType1>& __d1,
118038fd1498Szrj	       const rice_distribution<_RealType1>& __d2)
118138fd1498Szrj    { return !(__d1 == __d2); }
118238fd1498Szrj
118338fd1498Szrj
118438fd1498Szrj  /**
118538fd1498Szrj   * @brief A Nakagami continuous distribution for random numbers.
118638fd1498Szrj   *
118738fd1498Szrj   * The formula for the Nakagami probability density function is
118838fd1498Szrj   * @f[
118938fd1498Szrj   *     p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu}
119038fd1498Szrj   *                       x^{2\mu-1}e^{-\mu x / \omega}
119138fd1498Szrj   * @f]
119238fd1498Szrj   * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$
119338fd1498Szrj   * and @f$\omega > 0@f$.
119438fd1498Szrj   */
119538fd1498Szrj  template<typename _RealType = double>
119638fd1498Szrj    class
119738fd1498Szrj    nakagami_distribution
119838fd1498Szrj    {
119938fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
120038fd1498Szrj		    "template argument not a floating point type");
120138fd1498Szrj
120238fd1498Szrj    public:
120338fd1498Szrj      /** The type of the range of the distribution. */
120438fd1498Szrj      typedef _RealType result_type;
120538fd1498Szrj
120638fd1498Szrj      /** Parameter type. */
120738fd1498Szrj      struct param_type
120838fd1498Szrj      {
120938fd1498Szrj	typedef nakagami_distribution<result_type> distribution_type;
121038fd1498Szrj
121138fd1498Szrj	param_type(result_type __mu_val = result_type(1),
121238fd1498Szrj		   result_type __omega_val = result_type(1))
121338fd1498Szrj	: _M_mu(__mu_val), _M_omega(__omega_val)
121438fd1498Szrj	{
121538fd1498Szrj	  __glibcxx_assert(_M_mu >= result_type(0.5L));
121638fd1498Szrj	  __glibcxx_assert(_M_omega > result_type(0));
121738fd1498Szrj	}
121838fd1498Szrj
121938fd1498Szrj	result_type
122038fd1498Szrj	mu() const
122138fd1498Szrj	{ return _M_mu; }
122238fd1498Szrj
122338fd1498Szrj	result_type
122438fd1498Szrj	omega() const
122538fd1498Szrj	{ return _M_omega; }
122638fd1498Szrj
122738fd1498Szrj	friend bool
122838fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
122938fd1498Szrj	{ return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; }
123038fd1498Szrj
123138fd1498Szrj	friend bool
123238fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
123338fd1498Szrj	{ return !(__p1 == __p2); }
123438fd1498Szrj
123538fd1498Szrj      private:
123638fd1498Szrj	void _M_initialize();
123738fd1498Szrj
123838fd1498Szrj	result_type _M_mu;
123938fd1498Szrj	result_type _M_omega;
124038fd1498Szrj      };
124138fd1498Szrj
124238fd1498Szrj      /**
124338fd1498Szrj       * @brief Constructors.
124438fd1498Szrj       */
124538fd1498Szrj      explicit
124638fd1498Szrj      nakagami_distribution(result_type __mu_val = result_type(1),
124738fd1498Szrj			    result_type __omega_val = result_type(1))
124838fd1498Szrj      : _M_param(__mu_val, __omega_val),
124938fd1498Szrj	_M_gd(__mu_val, __omega_val / __mu_val)
125038fd1498Szrj      { }
125138fd1498Szrj
125238fd1498Szrj      explicit
125338fd1498Szrj      nakagami_distribution(const param_type& __p)
125438fd1498Szrj      : _M_param(__p),
125538fd1498Szrj	_M_gd(__p.mu(), __p.omega() / __p.mu())
125638fd1498Szrj      { }
125738fd1498Szrj
125838fd1498Szrj      /**
125938fd1498Szrj       * @brief Resets the distribution state.
126038fd1498Szrj       */
126138fd1498Szrj      void
126238fd1498Szrj      reset()
126338fd1498Szrj      { _M_gd.reset(); }
126438fd1498Szrj
126538fd1498Szrj      /**
126638fd1498Szrj       * @brief Return the parameters of the distribution.
126738fd1498Szrj       */
126838fd1498Szrj      result_type
126938fd1498Szrj      mu() const
127038fd1498Szrj      { return _M_param.mu(); }
127138fd1498Szrj
127238fd1498Szrj      result_type
127338fd1498Szrj      omega() const
127438fd1498Szrj      { return _M_param.omega(); }
127538fd1498Szrj
127638fd1498Szrj      /**
127738fd1498Szrj       * @brief Returns the parameter set of the distribution.
127838fd1498Szrj       */
127938fd1498Szrj      param_type
128038fd1498Szrj      param() const
128138fd1498Szrj      { return _M_param; }
128238fd1498Szrj
128338fd1498Szrj      /**
128438fd1498Szrj       * @brief Sets the parameter set of the distribution.
128538fd1498Szrj       * @param __param The new parameter set of the distribution.
128638fd1498Szrj       */
128738fd1498Szrj      void
128838fd1498Szrj      param(const param_type& __param)
128938fd1498Szrj      { _M_param = __param; }
129038fd1498Szrj
129138fd1498Szrj      /**
129238fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
129338fd1498Szrj       */
129438fd1498Szrj      result_type
129538fd1498Szrj      min() const
129638fd1498Szrj      { return result_type(0); }
129738fd1498Szrj
129838fd1498Szrj      /**
129938fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
130038fd1498Szrj       */
130138fd1498Szrj      result_type
130238fd1498Szrj      max() const
130338fd1498Szrj      { return std::numeric_limits<result_type>::max(); }
130438fd1498Szrj
130538fd1498Szrj      /**
130638fd1498Szrj       * @brief Generating functions.
130738fd1498Szrj       */
130838fd1498Szrj      template<typename _UniformRandomNumberGenerator>
130938fd1498Szrj	result_type
131038fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
131138fd1498Szrj	{ return std::sqrt(this->_M_gd(__urng)); }
131238fd1498Szrj
131338fd1498Szrj      template<typename _UniformRandomNumberGenerator>
131438fd1498Szrj	result_type
131538fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
131638fd1498Szrj		   const param_type& __p)
131738fd1498Szrj	{
131838fd1498Szrj	  typename std::gamma_distribution<result_type>::param_type
131938fd1498Szrj	    __pg(__p.mu(), __p.omega() / __p.mu());
132038fd1498Szrj	  return std::sqrt(this->_M_gd(__pg, __urng));
132138fd1498Szrj	}
132238fd1498Szrj
132338fd1498Szrj      template<typename _ForwardIterator,
132438fd1498Szrj	       typename _UniformRandomNumberGenerator>
132538fd1498Szrj	void
132638fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
132738fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
132838fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
132938fd1498Szrj
133038fd1498Szrj      template<typename _ForwardIterator,
133138fd1498Szrj	       typename _UniformRandomNumberGenerator>
133238fd1498Szrj	void
133338fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
133438fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
133538fd1498Szrj		   const param_type& __p)
133638fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
133738fd1498Szrj
133838fd1498Szrj      template<typename _UniformRandomNumberGenerator>
133938fd1498Szrj	void
134038fd1498Szrj	__generate(result_type* __f, result_type* __t,
134138fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
134238fd1498Szrj		   const param_type& __p)
134338fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
134438fd1498Szrj
134538fd1498Szrj      /**
134638fd1498Szrj       * @brief Return true if two Nakagami distributions have
134738fd1498Szrj       *        the same parameters and the sequences that would
134838fd1498Szrj       *        be generated are equal.
134938fd1498Szrj       */
135038fd1498Szrj      friend bool
135138fd1498Szrj      operator==(const nakagami_distribution& __d1,
135238fd1498Szrj		 const nakagami_distribution& __d2)
135338fd1498Szrj      { return (__d1._M_param == __d2._M_param
135438fd1498Szrj		&& __d1._M_gd == __d2._M_gd); }
135538fd1498Szrj
135638fd1498Szrj      /**
135738fd1498Szrj       * @brief Inserts a %nakagami_distribution random number distribution
135838fd1498Szrj       * @p __x into the output stream @p __os.
135938fd1498Szrj       *
136038fd1498Szrj       * @param __os An output stream.
136138fd1498Szrj       * @param __x  A %nakagami_distribution random number distribution.
136238fd1498Szrj       *
136338fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
136438fd1498Szrj       * an error state.
136538fd1498Szrj       */
136638fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
136738fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
136838fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>&,
136938fd1498Szrj		   const nakagami_distribution<_RealType1>&);
137038fd1498Szrj
137138fd1498Szrj      /**
137238fd1498Szrj       * @brief Extracts a %nakagami_distribution random number distribution
137338fd1498Szrj       * @p __x from the input stream @p __is.
137438fd1498Szrj       *
137538fd1498Szrj       * @param __is An input stream.
137638fd1498Szrj       * @param __x A %nakagami_distribution random number
137738fd1498Szrj       *            generator engine.
137838fd1498Szrj       *
137938fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
138038fd1498Szrj       */
138138fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
138238fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
138338fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>&,
138438fd1498Szrj		   nakagami_distribution<_RealType1>&);
138538fd1498Szrj
138638fd1498Szrj    private:
138738fd1498Szrj      template<typename _ForwardIterator,
138838fd1498Szrj	       typename _UniformRandomNumberGenerator>
138938fd1498Szrj	void
139038fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
139138fd1498Szrj			_UniformRandomNumberGenerator& __urng,
139238fd1498Szrj			const param_type& __p);
139338fd1498Szrj
139438fd1498Szrj      param_type _M_param;
139538fd1498Szrj
139638fd1498Szrj      std::gamma_distribution<result_type> _M_gd;
139738fd1498Szrj    };
139838fd1498Szrj
139938fd1498Szrj  /**
140038fd1498Szrj   * @brief Return true if two Nakagami distributions are not equal.
140138fd1498Szrj   */
140238fd1498Szrj  template<typename _RealType>
140338fd1498Szrj    inline bool
140438fd1498Szrj    operator!=(const nakagami_distribution<_RealType>& __d1,
140538fd1498Szrj	       const nakagami_distribution<_RealType>& __d2)
140638fd1498Szrj    { return !(__d1 == __d2); }
140738fd1498Szrj
140838fd1498Szrj
140938fd1498Szrj  /**
141038fd1498Szrj   * @brief A Pareto continuous distribution for random numbers.
141138fd1498Szrj   *
141238fd1498Szrj   * The formula for the Pareto cumulative probability function is
141338fd1498Szrj   * @f[
141438fd1498Szrj   *     P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha
141538fd1498Szrj   * @f]
141638fd1498Szrj   * The formula for the Pareto probability density function is
141738fd1498Szrj   * @f[
141838fd1498Szrj   *     p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu}
141938fd1498Szrj   *                       \left(\frac{\mu}{x}\right)^{\alpha + 1}
142038fd1498Szrj   * @f]
142138fd1498Szrj   * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$.
142238fd1498Szrj   *
142338fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
142438fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
142538fd1498Szrj   * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$
142638fd1498Szrj   *              for @f$\alpha > 1@f$</td></tr>
142738fd1498Szrj   * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$
142838fd1498Szrj   *              for @f$\alpha > 2@f$</td></tr>
142938fd1498Szrj   * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr>
143038fd1498Szrj   * </table>
143138fd1498Szrj   */
143238fd1498Szrj  template<typename _RealType = double>
143338fd1498Szrj    class
143438fd1498Szrj    pareto_distribution
143538fd1498Szrj    {
143638fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
143738fd1498Szrj		    "template argument not a floating point type");
143838fd1498Szrj
143938fd1498Szrj    public:
144038fd1498Szrj      /** The type of the range of the distribution. */
144138fd1498Szrj      typedef _RealType result_type;
144238fd1498Szrj
144338fd1498Szrj      /** Parameter type. */
144438fd1498Szrj      struct param_type
144538fd1498Szrj      {
144638fd1498Szrj	typedef pareto_distribution<result_type> distribution_type;
144738fd1498Szrj
144838fd1498Szrj	param_type(result_type __alpha_val = result_type(1),
144938fd1498Szrj		   result_type __mu_val = result_type(1))
145038fd1498Szrj	: _M_alpha(__alpha_val), _M_mu(__mu_val)
145138fd1498Szrj	{
145238fd1498Szrj	  __glibcxx_assert(_M_alpha > result_type(0));
145338fd1498Szrj	  __glibcxx_assert(_M_mu > result_type(0));
145438fd1498Szrj	}
145538fd1498Szrj
145638fd1498Szrj	result_type
145738fd1498Szrj	alpha() const
145838fd1498Szrj	{ return _M_alpha; }
145938fd1498Szrj
146038fd1498Szrj	result_type
146138fd1498Szrj	mu() const
146238fd1498Szrj	{ return _M_mu; }
146338fd1498Szrj
146438fd1498Szrj	friend bool
146538fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
146638fd1498Szrj	{ return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; }
146738fd1498Szrj
146838fd1498Szrj	friend bool
146938fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
147038fd1498Szrj	{ return !(__p1 == __p2); }
147138fd1498Szrj
147238fd1498Szrj      private:
147338fd1498Szrj	void _M_initialize();
147438fd1498Szrj
147538fd1498Szrj	result_type _M_alpha;
147638fd1498Szrj	result_type _M_mu;
147738fd1498Szrj      };
147838fd1498Szrj
147938fd1498Szrj      /**
148038fd1498Szrj       * @brief Constructors.
148138fd1498Szrj       */
148238fd1498Szrj      explicit
148338fd1498Szrj      pareto_distribution(result_type __alpha_val = result_type(1),
148438fd1498Szrj			  result_type __mu_val = result_type(1))
148538fd1498Szrj      : _M_param(__alpha_val, __mu_val),
148638fd1498Szrj	_M_ud()
148738fd1498Szrj      { }
148838fd1498Szrj
148938fd1498Szrj      explicit
149038fd1498Szrj      pareto_distribution(const param_type& __p)
149138fd1498Szrj      : _M_param(__p),
149238fd1498Szrj	_M_ud()
149338fd1498Szrj      { }
149438fd1498Szrj
149538fd1498Szrj      /**
149638fd1498Szrj       * @brief Resets the distribution state.
149738fd1498Szrj       */
149838fd1498Szrj      void
149938fd1498Szrj      reset()
150038fd1498Szrj      {
150138fd1498Szrj	_M_ud.reset();
150238fd1498Szrj      }
150338fd1498Szrj
150438fd1498Szrj      /**
150538fd1498Szrj       * @brief Return the parameters of the distribution.
150638fd1498Szrj       */
150738fd1498Szrj      result_type
150838fd1498Szrj      alpha() const
150938fd1498Szrj      { return _M_param.alpha(); }
151038fd1498Szrj
151138fd1498Szrj      result_type
151238fd1498Szrj      mu() const
151338fd1498Szrj      { return _M_param.mu(); }
151438fd1498Szrj
151538fd1498Szrj      /**
151638fd1498Szrj       * @brief Returns the parameter set of the distribution.
151738fd1498Szrj       */
151838fd1498Szrj      param_type
151938fd1498Szrj      param() const
152038fd1498Szrj      { return _M_param; }
152138fd1498Szrj
152238fd1498Szrj      /**
152338fd1498Szrj       * @brief Sets the parameter set of the distribution.
152438fd1498Szrj       * @param __param The new parameter set of the distribution.
152538fd1498Szrj       */
152638fd1498Szrj      void
152738fd1498Szrj      param(const param_type& __param)
152838fd1498Szrj      { _M_param = __param; }
152938fd1498Szrj
153038fd1498Szrj      /**
153138fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
153238fd1498Szrj       */
153338fd1498Szrj      result_type
153438fd1498Szrj      min() const
153538fd1498Szrj      { return this->mu(); }
153638fd1498Szrj
153738fd1498Szrj      /**
153838fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
153938fd1498Szrj       */
154038fd1498Szrj      result_type
154138fd1498Szrj      max() const
154238fd1498Szrj      { return std::numeric_limits<result_type>::max(); }
154338fd1498Szrj
154438fd1498Szrj      /**
154538fd1498Szrj       * @brief Generating functions.
154638fd1498Szrj       */
154738fd1498Szrj      template<typename _UniformRandomNumberGenerator>
154838fd1498Szrj	result_type
154938fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
155038fd1498Szrj	{
155138fd1498Szrj	  return this->mu() * std::pow(this->_M_ud(__urng),
155238fd1498Szrj				       -result_type(1) / this->alpha());
155338fd1498Szrj	}
155438fd1498Szrj
155538fd1498Szrj      template<typename _UniformRandomNumberGenerator>
155638fd1498Szrj	result_type
155738fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
155838fd1498Szrj		   const param_type& __p)
155938fd1498Szrj	{
156038fd1498Szrj	  return __p.mu() * std::pow(this->_M_ud(__urng),
156138fd1498Szrj					   -result_type(1) / __p.alpha());
156238fd1498Szrj	}
156338fd1498Szrj
156438fd1498Szrj      template<typename _ForwardIterator,
156538fd1498Szrj	       typename _UniformRandomNumberGenerator>
156638fd1498Szrj	void
156738fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
156838fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
156938fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
157038fd1498Szrj
157138fd1498Szrj      template<typename _ForwardIterator,
157238fd1498Szrj	       typename _UniformRandomNumberGenerator>
157338fd1498Szrj	void
157438fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
157538fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
157638fd1498Szrj		   const param_type& __p)
157738fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
157838fd1498Szrj
157938fd1498Szrj      template<typename _UniformRandomNumberGenerator>
158038fd1498Szrj	void
158138fd1498Szrj	__generate(result_type* __f, result_type* __t,
158238fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
158338fd1498Szrj		   const param_type& __p)
158438fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
158538fd1498Szrj
158638fd1498Szrj      /**
158738fd1498Szrj       * @brief Return true if two Pareto distributions have
158838fd1498Szrj       *        the same parameters and the sequences that would
158938fd1498Szrj       *        be generated are equal.
159038fd1498Szrj       */
159138fd1498Szrj      friend bool
159238fd1498Szrj      operator==(const pareto_distribution& __d1,
159338fd1498Szrj		 const pareto_distribution& __d2)
159438fd1498Szrj      { return (__d1._M_param == __d2._M_param
159538fd1498Szrj		&& __d1._M_ud == __d2._M_ud); }
159638fd1498Szrj
159738fd1498Szrj      /**
159838fd1498Szrj       * @brief Inserts a %pareto_distribution random number distribution
159938fd1498Szrj       * @p __x into the output stream @p __os.
160038fd1498Szrj       *
160138fd1498Szrj       * @param __os An output stream.
160238fd1498Szrj       * @param __x  A %pareto_distribution random number distribution.
160338fd1498Szrj       *
160438fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
160538fd1498Szrj       * an error state.
160638fd1498Szrj       */
160738fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
160838fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
160938fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>&,
161038fd1498Szrj		   const pareto_distribution<_RealType1>&);
161138fd1498Szrj
161238fd1498Szrj      /**
161338fd1498Szrj       * @brief Extracts a %pareto_distribution random number distribution
161438fd1498Szrj       * @p __x from the input stream @p __is.
161538fd1498Szrj       *
161638fd1498Szrj       * @param __is An input stream.
161738fd1498Szrj       * @param __x A %pareto_distribution random number
161838fd1498Szrj       *            generator engine.
161938fd1498Szrj       *
162038fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
162138fd1498Szrj       */
162238fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
162338fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
162438fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>&,
162538fd1498Szrj		   pareto_distribution<_RealType1>&);
162638fd1498Szrj
162738fd1498Szrj    private:
162838fd1498Szrj      template<typename _ForwardIterator,
162938fd1498Szrj	       typename _UniformRandomNumberGenerator>
163038fd1498Szrj	void
163138fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
163238fd1498Szrj			_UniformRandomNumberGenerator& __urng,
163338fd1498Szrj			const param_type& __p);
163438fd1498Szrj
163538fd1498Szrj      param_type _M_param;
163638fd1498Szrj
163738fd1498Szrj      std::uniform_real_distribution<result_type> _M_ud;
163838fd1498Szrj    };
163938fd1498Szrj
164038fd1498Szrj  /**
164138fd1498Szrj   * @brief Return true if two Pareto distributions are not equal.
164238fd1498Szrj   */
164338fd1498Szrj  template<typename _RealType>
164438fd1498Szrj    inline bool
164538fd1498Szrj    operator!=(const pareto_distribution<_RealType>& __d1,
164638fd1498Szrj	       const pareto_distribution<_RealType>& __d2)
164738fd1498Szrj    { return !(__d1 == __d2); }
164838fd1498Szrj
164938fd1498Szrj
165038fd1498Szrj  /**
165138fd1498Szrj   * @brief A K continuous distribution for random numbers.
165238fd1498Szrj   *
165338fd1498Szrj   * The formula for the K probability density function is
165438fd1498Szrj   * @f[
165538fd1498Szrj   *     p(x|\lambda, \mu, \nu) = \frac{2}{x}
165638fd1498Szrj   *             \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}}
165738fd1498Szrj   *             \frac{1}{\Gamma(\lambda)\Gamma(\nu)}
165838fd1498Szrj   *             K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right)
165938fd1498Szrj   * @f]
166038fd1498Szrj   * where @f$I_0(z)@f$ is the modified Bessel function of the second kind
166138fd1498Szrj   * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$
166238fd1498Szrj   * and @f$\nu > 0@f$.
166338fd1498Szrj   *
166438fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
166538fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
166638fd1498Szrj   * <tr><td>Mean</td><td>@f$\mu@f$</td></tr>
166738fd1498Szrj   * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr>
166838fd1498Szrj   * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
166938fd1498Szrj   * </table>
167038fd1498Szrj   */
167138fd1498Szrj  template<typename _RealType = double>
167238fd1498Szrj    class
167338fd1498Szrj    k_distribution
167438fd1498Szrj    {
167538fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
167638fd1498Szrj		    "template argument not a floating point type");
167738fd1498Szrj
167838fd1498Szrj    public:
167938fd1498Szrj      /** The type of the range of the distribution. */
168038fd1498Szrj      typedef _RealType result_type;
168138fd1498Szrj
168238fd1498Szrj      /** Parameter type. */
168338fd1498Szrj      struct param_type
168438fd1498Szrj      {
168538fd1498Szrj	typedef k_distribution<result_type> distribution_type;
168638fd1498Szrj
168738fd1498Szrj	param_type(result_type __lambda_val = result_type(1),
168838fd1498Szrj		   result_type __mu_val = result_type(1),
168938fd1498Szrj		   result_type __nu_val = result_type(1))
169038fd1498Szrj	: _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val)
169138fd1498Szrj	{
169238fd1498Szrj	  __glibcxx_assert(_M_lambda > result_type(0));
169338fd1498Szrj	  __glibcxx_assert(_M_mu > result_type(0));
169438fd1498Szrj	  __glibcxx_assert(_M_nu > result_type(0));
169538fd1498Szrj	}
169638fd1498Szrj
169738fd1498Szrj	result_type
169838fd1498Szrj	lambda() const
169938fd1498Szrj	{ return _M_lambda; }
170038fd1498Szrj
170138fd1498Szrj	result_type
170238fd1498Szrj	mu() const
170338fd1498Szrj	{ return _M_mu; }
170438fd1498Szrj
170538fd1498Szrj	result_type
170638fd1498Szrj	nu() const
170738fd1498Szrj	{ return _M_nu; }
170838fd1498Szrj
170938fd1498Szrj	friend bool
171038fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
171138fd1498Szrj	{
171238fd1498Szrj	  return __p1._M_lambda == __p2._M_lambda
171338fd1498Szrj	      && __p1._M_mu == __p2._M_mu
171438fd1498Szrj	      && __p1._M_nu == __p2._M_nu;
171538fd1498Szrj	}
171638fd1498Szrj
171738fd1498Szrj	friend bool
171838fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
171938fd1498Szrj	{ return !(__p1 == __p2); }
172038fd1498Szrj
172138fd1498Szrj      private:
172238fd1498Szrj	void _M_initialize();
172338fd1498Szrj
172438fd1498Szrj	result_type _M_lambda;
172538fd1498Szrj	result_type _M_mu;
172638fd1498Szrj	result_type _M_nu;
172738fd1498Szrj      };
172838fd1498Szrj
172938fd1498Szrj      /**
173038fd1498Szrj       * @brief Constructors.
173138fd1498Szrj       */
173238fd1498Szrj      explicit
173338fd1498Szrj      k_distribution(result_type __lambda_val = result_type(1),
173438fd1498Szrj		     result_type __mu_val = result_type(1),
173538fd1498Szrj		     result_type __nu_val = result_type(1))
173638fd1498Szrj      : _M_param(__lambda_val, __mu_val, __nu_val),
173738fd1498Szrj	_M_gd1(__lambda_val, result_type(1) / __lambda_val),
173838fd1498Szrj	_M_gd2(__nu_val, __mu_val / __nu_val)
173938fd1498Szrj      { }
174038fd1498Szrj
174138fd1498Szrj      explicit
174238fd1498Szrj      k_distribution(const param_type& __p)
174338fd1498Szrj      : _M_param(__p),
174438fd1498Szrj	_M_gd1(__p.lambda(), result_type(1) / __p.lambda()),
174538fd1498Szrj	_M_gd2(__p.nu(), __p.mu() / __p.nu())
174638fd1498Szrj      { }
174738fd1498Szrj
174838fd1498Szrj      /**
174938fd1498Szrj       * @brief Resets the distribution state.
175038fd1498Szrj       */
175138fd1498Szrj      void
175238fd1498Szrj      reset()
175338fd1498Szrj      {
175438fd1498Szrj	_M_gd1.reset();
175538fd1498Szrj	_M_gd2.reset();
175638fd1498Szrj      }
175738fd1498Szrj
175838fd1498Szrj      /**
175938fd1498Szrj       * @brief Return the parameters of the distribution.
176038fd1498Szrj       */
176138fd1498Szrj      result_type
176238fd1498Szrj      lambda() const
176338fd1498Szrj      { return _M_param.lambda(); }
176438fd1498Szrj
176538fd1498Szrj      result_type
176638fd1498Szrj      mu() const
176738fd1498Szrj      { return _M_param.mu(); }
176838fd1498Szrj
176938fd1498Szrj      result_type
177038fd1498Szrj      nu() const
177138fd1498Szrj      { return _M_param.nu(); }
177238fd1498Szrj
177338fd1498Szrj      /**
177438fd1498Szrj       * @brief Returns the parameter set of the distribution.
177538fd1498Szrj       */
177638fd1498Szrj      param_type
177738fd1498Szrj      param() const
177838fd1498Szrj      { return _M_param; }
177938fd1498Szrj
178038fd1498Szrj      /**
178138fd1498Szrj       * @brief Sets the parameter set of the distribution.
178238fd1498Szrj       * @param __param The new parameter set of the distribution.
178338fd1498Szrj       */
178438fd1498Szrj      void
178538fd1498Szrj      param(const param_type& __param)
178638fd1498Szrj      { _M_param = __param; }
178738fd1498Szrj
178838fd1498Szrj      /**
178938fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
179038fd1498Szrj       */
179138fd1498Szrj      result_type
179238fd1498Szrj      min() const
179338fd1498Szrj      { return result_type(0); }
179438fd1498Szrj
179538fd1498Szrj      /**
179638fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
179738fd1498Szrj       */
179838fd1498Szrj      result_type
179938fd1498Szrj      max() const
180038fd1498Szrj      { return std::numeric_limits<result_type>::max(); }
180138fd1498Szrj
180238fd1498Szrj      /**
180338fd1498Szrj       * @brief Generating functions.
180438fd1498Szrj       */
180538fd1498Szrj      template<typename _UniformRandomNumberGenerator>
180638fd1498Szrj	result_type
180738fd1498Szrj	operator()(_UniformRandomNumberGenerator&);
180838fd1498Szrj
180938fd1498Szrj      template<typename _UniformRandomNumberGenerator>
181038fd1498Szrj	result_type
181138fd1498Szrj	operator()(_UniformRandomNumberGenerator&, const param_type&);
181238fd1498Szrj
181338fd1498Szrj      template<typename _ForwardIterator,
181438fd1498Szrj	       typename _UniformRandomNumberGenerator>
181538fd1498Szrj	void
181638fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
181738fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
181838fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
181938fd1498Szrj
182038fd1498Szrj      template<typename _ForwardIterator,
182138fd1498Szrj	       typename _UniformRandomNumberGenerator>
182238fd1498Szrj	void
182338fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
182438fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
182538fd1498Szrj		   const param_type& __p)
182638fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
182738fd1498Szrj
182838fd1498Szrj      template<typename _UniformRandomNumberGenerator>
182938fd1498Szrj	void
183038fd1498Szrj	__generate(result_type* __f, result_type* __t,
183138fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
183238fd1498Szrj		   const param_type& __p)
183338fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
183438fd1498Szrj
183538fd1498Szrj      /**
183638fd1498Szrj       * @brief Return true if two K distributions have
183738fd1498Szrj       *        the same parameters and the sequences that would
183838fd1498Szrj       *        be generated are equal.
183938fd1498Szrj       */
184038fd1498Szrj      friend bool
184138fd1498Szrj      operator==(const k_distribution& __d1,
184238fd1498Szrj		 const k_distribution& __d2)
184338fd1498Szrj      { return (__d1._M_param == __d2._M_param
184438fd1498Szrj		&& __d1._M_gd1 == __d2._M_gd1
184538fd1498Szrj		&& __d1._M_gd2 == __d2._M_gd2); }
184638fd1498Szrj
184738fd1498Szrj      /**
184838fd1498Szrj       * @brief Inserts a %k_distribution random number distribution
184938fd1498Szrj       * @p __x into the output stream @p __os.
185038fd1498Szrj       *
185138fd1498Szrj       * @param __os An output stream.
185238fd1498Szrj       * @param __x  A %k_distribution random number distribution.
185338fd1498Szrj       *
185438fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
185538fd1498Szrj       * an error state.
185638fd1498Szrj       */
185738fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
185838fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
185938fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>&,
186038fd1498Szrj		   const k_distribution<_RealType1>&);
186138fd1498Szrj
186238fd1498Szrj      /**
186338fd1498Szrj       * @brief Extracts a %k_distribution random number distribution
186438fd1498Szrj       * @p __x from the input stream @p __is.
186538fd1498Szrj       *
186638fd1498Szrj       * @param __is An input stream.
186738fd1498Szrj       * @param __x A %k_distribution random number
186838fd1498Szrj       *            generator engine.
186938fd1498Szrj       *
187038fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
187138fd1498Szrj       */
187238fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
187338fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
187438fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>&,
187538fd1498Szrj		   k_distribution<_RealType1>&);
187638fd1498Szrj
187738fd1498Szrj    private:
187838fd1498Szrj      template<typename _ForwardIterator,
187938fd1498Szrj	       typename _UniformRandomNumberGenerator>
188038fd1498Szrj	void
188138fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
188238fd1498Szrj			_UniformRandomNumberGenerator& __urng,
188338fd1498Szrj			const param_type& __p);
188438fd1498Szrj
188538fd1498Szrj      param_type _M_param;
188638fd1498Szrj
188738fd1498Szrj      std::gamma_distribution<result_type> _M_gd1;
188838fd1498Szrj      std::gamma_distribution<result_type> _M_gd2;
188938fd1498Szrj    };
189038fd1498Szrj
189138fd1498Szrj  /**
189238fd1498Szrj   * @brief Return true if two K distributions are not equal.
189338fd1498Szrj   */
189438fd1498Szrj  template<typename _RealType>
189538fd1498Szrj    inline bool
189638fd1498Szrj    operator!=(const k_distribution<_RealType>& __d1,
189738fd1498Szrj	       const k_distribution<_RealType>& __d2)
189838fd1498Szrj    { return !(__d1 == __d2); }
189938fd1498Szrj
190038fd1498Szrj
190138fd1498Szrj  /**
190238fd1498Szrj   * @brief An arcsine continuous distribution for random numbers.
190338fd1498Szrj   *
190438fd1498Szrj   * The formula for the arcsine probability density function is
190538fd1498Szrj   * @f[
190638fd1498Szrj   *     p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
190738fd1498Szrj   * @f]
190838fd1498Szrj   * where @f$x >= a@f$ and @f$x <= b@f$.
190938fd1498Szrj   *
191038fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
191138fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
191238fd1498Szrj   * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr>
191338fd1498Szrj   * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr>
191438fd1498Szrj   * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr>
191538fd1498Szrj   * </table>
191638fd1498Szrj   */
191738fd1498Szrj  template<typename _RealType = double>
191838fd1498Szrj    class
191938fd1498Szrj    arcsine_distribution
192038fd1498Szrj    {
192138fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
192238fd1498Szrj		    "template argument not a floating point type");
192338fd1498Szrj
192438fd1498Szrj    public:
192538fd1498Szrj      /** The type of the range of the distribution. */
192638fd1498Szrj      typedef _RealType result_type;
192738fd1498Szrj
192838fd1498Szrj      /** Parameter type. */
192938fd1498Szrj      struct param_type
193038fd1498Szrj      {
193138fd1498Szrj	typedef arcsine_distribution<result_type> distribution_type;
193238fd1498Szrj
193338fd1498Szrj	param_type(result_type __a = result_type(0),
193438fd1498Szrj		   result_type __b = result_type(1))
193538fd1498Szrj	: _M_a(__a), _M_b(__b)
193638fd1498Szrj	{
193738fd1498Szrj	  __glibcxx_assert(_M_a <= _M_b);
193838fd1498Szrj	}
193938fd1498Szrj
194038fd1498Szrj	result_type
194138fd1498Szrj	a() const
194238fd1498Szrj	{ return _M_a; }
194338fd1498Szrj
194438fd1498Szrj	result_type
194538fd1498Szrj	b() const
194638fd1498Szrj	{ return _M_b; }
194738fd1498Szrj
194838fd1498Szrj	friend bool
194938fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
195038fd1498Szrj	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
195138fd1498Szrj
195238fd1498Szrj	friend bool
195338fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
195438fd1498Szrj	{ return !(__p1 == __p2); }
195538fd1498Szrj
195638fd1498Szrj      private:
195738fd1498Szrj	void _M_initialize();
195838fd1498Szrj
195938fd1498Szrj	result_type _M_a;
196038fd1498Szrj	result_type _M_b;
196138fd1498Szrj      };
196238fd1498Szrj
196338fd1498Szrj      /**
196438fd1498Szrj       * @brief Constructors.
196538fd1498Szrj       */
196638fd1498Szrj      explicit
196738fd1498Szrj      arcsine_distribution(result_type __a = result_type(0),
196838fd1498Szrj			   result_type __b = result_type(1))
196938fd1498Szrj      : _M_param(__a, __b),
197038fd1498Szrj	_M_ud(-1.5707963267948966192313216916397514L,
197138fd1498Szrj	      +1.5707963267948966192313216916397514L)
197238fd1498Szrj      { }
197338fd1498Szrj
197438fd1498Szrj      explicit
197538fd1498Szrj      arcsine_distribution(const param_type& __p)
197638fd1498Szrj      : _M_param(__p),
197738fd1498Szrj	_M_ud(-1.5707963267948966192313216916397514L,
197838fd1498Szrj	      +1.5707963267948966192313216916397514L)
197938fd1498Szrj      { }
198038fd1498Szrj
198138fd1498Szrj      /**
198238fd1498Szrj       * @brief Resets the distribution state.
198338fd1498Szrj       */
198438fd1498Szrj      void
198538fd1498Szrj      reset()
198638fd1498Szrj      { _M_ud.reset(); }
198738fd1498Szrj
198838fd1498Szrj      /**
198938fd1498Szrj       * @brief Return the parameters of the distribution.
199038fd1498Szrj       */
199138fd1498Szrj      result_type
199238fd1498Szrj      a() const
199338fd1498Szrj      { return _M_param.a(); }
199438fd1498Szrj
199538fd1498Szrj      result_type
199638fd1498Szrj      b() const
199738fd1498Szrj      { return _M_param.b(); }
199838fd1498Szrj
199938fd1498Szrj      /**
200038fd1498Szrj       * @brief Returns the parameter set of the distribution.
200138fd1498Szrj       */
200238fd1498Szrj      param_type
200338fd1498Szrj      param() const
200438fd1498Szrj      { return _M_param; }
200538fd1498Szrj
200638fd1498Szrj      /**
200738fd1498Szrj       * @brief Sets the parameter set of the distribution.
200838fd1498Szrj       * @param __param The new parameter set of the distribution.
200938fd1498Szrj       */
201038fd1498Szrj      void
201138fd1498Szrj      param(const param_type& __param)
201238fd1498Szrj      { _M_param = __param; }
201338fd1498Szrj
201438fd1498Szrj      /**
201538fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
201638fd1498Szrj       */
201738fd1498Szrj      result_type
201838fd1498Szrj      min() const
201938fd1498Szrj      { return this->a(); }
202038fd1498Szrj
202138fd1498Szrj      /**
202238fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
202338fd1498Szrj       */
202438fd1498Szrj      result_type
202538fd1498Szrj      max() const
202638fd1498Szrj      { return this->b(); }
202738fd1498Szrj
202838fd1498Szrj      /**
202938fd1498Szrj       * @brief Generating functions.
203038fd1498Szrj       */
203138fd1498Szrj      template<typename _UniformRandomNumberGenerator>
203238fd1498Szrj	result_type
203338fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
203438fd1498Szrj	{
203538fd1498Szrj	  result_type __x = std::sin(this->_M_ud(__urng));
203638fd1498Szrj	  return (__x * (this->b() - this->a())
203738fd1498Szrj		  + this->a() + this->b()) / result_type(2);
203838fd1498Szrj	}
203938fd1498Szrj
204038fd1498Szrj      template<typename _UniformRandomNumberGenerator>
204138fd1498Szrj	result_type
204238fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
204338fd1498Szrj		   const param_type& __p)
204438fd1498Szrj	{
204538fd1498Szrj	  result_type __x = std::sin(this->_M_ud(__urng));
204638fd1498Szrj	  return (__x * (__p.b() - __p.a())
204738fd1498Szrj		  + __p.a() + __p.b()) / result_type(2);
204838fd1498Szrj	}
204938fd1498Szrj
205038fd1498Szrj      template<typename _ForwardIterator,
205138fd1498Szrj	       typename _UniformRandomNumberGenerator>
205238fd1498Szrj	void
205338fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
205438fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
205538fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
205638fd1498Szrj
205738fd1498Szrj      template<typename _ForwardIterator,
205838fd1498Szrj	       typename _UniformRandomNumberGenerator>
205938fd1498Szrj	void
206038fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
206138fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
206238fd1498Szrj		   const param_type& __p)
206338fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
206438fd1498Szrj
206538fd1498Szrj      template<typename _UniformRandomNumberGenerator>
206638fd1498Szrj	void
206738fd1498Szrj	__generate(result_type* __f, result_type* __t,
206838fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
206938fd1498Szrj		   const param_type& __p)
207038fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
207138fd1498Szrj
207238fd1498Szrj      /**
207338fd1498Szrj       * @brief Return true if two arcsine distributions have
207438fd1498Szrj       *        the same parameters and the sequences that would
207538fd1498Szrj       *        be generated are equal.
207638fd1498Szrj       */
207738fd1498Szrj      friend bool
207838fd1498Szrj      operator==(const arcsine_distribution& __d1,
207938fd1498Szrj		 const arcsine_distribution& __d2)
208038fd1498Szrj      { return (__d1._M_param == __d2._M_param
208138fd1498Szrj		&& __d1._M_ud == __d2._M_ud); }
208238fd1498Szrj
208338fd1498Szrj      /**
208438fd1498Szrj       * @brief Inserts a %arcsine_distribution random number distribution
208538fd1498Szrj       * @p __x into the output stream @p __os.
208638fd1498Szrj       *
208738fd1498Szrj       * @param __os An output stream.
208838fd1498Szrj       * @param __x  A %arcsine_distribution random number distribution.
208938fd1498Szrj       *
209038fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
209138fd1498Szrj       * an error state.
209238fd1498Szrj       */
209338fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
209438fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
209538fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>&,
209638fd1498Szrj		   const arcsine_distribution<_RealType1>&);
209738fd1498Szrj
209838fd1498Szrj      /**
209938fd1498Szrj       * @brief Extracts a %arcsine_distribution random number distribution
210038fd1498Szrj       * @p __x from the input stream @p __is.
210138fd1498Szrj       *
210238fd1498Szrj       * @param __is An input stream.
210338fd1498Szrj       * @param __x A %arcsine_distribution random number
210438fd1498Szrj       *            generator engine.
210538fd1498Szrj       *
210638fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
210738fd1498Szrj       */
210838fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
210938fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
211038fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>&,
211138fd1498Szrj		   arcsine_distribution<_RealType1>&);
211238fd1498Szrj
211338fd1498Szrj    private:
211438fd1498Szrj      template<typename _ForwardIterator,
211538fd1498Szrj	       typename _UniformRandomNumberGenerator>
211638fd1498Szrj	void
211738fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
211838fd1498Szrj			_UniformRandomNumberGenerator& __urng,
211938fd1498Szrj			const param_type& __p);
212038fd1498Szrj
212138fd1498Szrj      param_type _M_param;
212238fd1498Szrj
212338fd1498Szrj      std::uniform_real_distribution<result_type> _M_ud;
212438fd1498Szrj    };
212538fd1498Szrj
212638fd1498Szrj  /**
212738fd1498Szrj   * @brief Return true if two arcsine distributions are not equal.
212838fd1498Szrj   */
212938fd1498Szrj  template<typename _RealType>
213038fd1498Szrj    inline bool
213138fd1498Szrj    operator!=(const arcsine_distribution<_RealType>& __d1,
213238fd1498Szrj	       const arcsine_distribution<_RealType>& __d2)
213338fd1498Szrj    { return !(__d1 == __d2); }
213438fd1498Szrj
213538fd1498Szrj
213638fd1498Szrj  /**
213738fd1498Szrj   * @brief A Hoyt continuous distribution for random numbers.
213838fd1498Szrj   *
213938fd1498Szrj   * The formula for the Hoyt probability density function is
214038fd1498Szrj   * @f[
214138fd1498Szrj   *     p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
214238fd1498Szrj   *                     \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
214338fd1498Szrj   *                       I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
214438fd1498Szrj   * @f]
214538fd1498Szrj   * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
214638fd1498Szrj   * of order 0 and @f$0 < q < 1@f$.
214738fd1498Szrj   *
214838fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
214938fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
215038fd1498Szrj   * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
215138fd1498Szrj   *                       E(1 - q^2) @f$</td></tr>
215238fd1498Szrj   * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
215338fd1498Szrj   *                                      {\pi (1 + q^2)}\right) @f$</td></tr>
215438fd1498Szrj   * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
215538fd1498Szrj   * </table>
215638fd1498Szrj   * where @f$E(x)@f$ is the elliptic function of the second kind.
215738fd1498Szrj   */
215838fd1498Szrj  template<typename _RealType = double>
215938fd1498Szrj    class
216038fd1498Szrj    hoyt_distribution
216138fd1498Szrj    {
216238fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
216338fd1498Szrj		    "template argument not a floating point type");
216438fd1498Szrj
216538fd1498Szrj    public:
216638fd1498Szrj      /** The type of the range of the distribution. */
216738fd1498Szrj      typedef _RealType result_type;
216838fd1498Szrj
216938fd1498Szrj      /** Parameter type. */
217038fd1498Szrj      struct param_type
217138fd1498Szrj      {
217238fd1498Szrj	typedef hoyt_distribution<result_type> distribution_type;
217338fd1498Szrj
217438fd1498Szrj	param_type(result_type __q = result_type(0.5L),
217538fd1498Szrj		   result_type __omega = result_type(1))
217638fd1498Szrj	: _M_q(__q), _M_omega(__omega)
217738fd1498Szrj	{
217838fd1498Szrj	  __glibcxx_assert(_M_q > result_type(0));
217938fd1498Szrj	  __glibcxx_assert(_M_q < result_type(1));
218038fd1498Szrj	}
218138fd1498Szrj
218238fd1498Szrj	result_type
218338fd1498Szrj	q() const
218438fd1498Szrj	{ return _M_q; }
218538fd1498Szrj
218638fd1498Szrj	result_type
218738fd1498Szrj	omega() const
218838fd1498Szrj	{ return _M_omega; }
218938fd1498Szrj
219038fd1498Szrj	friend bool
219138fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
219238fd1498Szrj	{ return __p1._M_q == __p2._M_q && __p1._M_omega == __p2._M_omega; }
219338fd1498Szrj
219438fd1498Szrj	friend bool
219538fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
219638fd1498Szrj	{ return !(__p1 == __p2); }
219738fd1498Szrj
219838fd1498Szrj      private:
219938fd1498Szrj	void _M_initialize();
220038fd1498Szrj
220138fd1498Szrj	result_type _M_q;
220238fd1498Szrj	result_type _M_omega;
220338fd1498Szrj      };
220438fd1498Szrj
220538fd1498Szrj      /**
220638fd1498Szrj       * @brief Constructors.
220738fd1498Szrj       */
220838fd1498Szrj      explicit
220938fd1498Szrj      hoyt_distribution(result_type __q = result_type(0.5L),
221038fd1498Szrj			result_type __omega = result_type(1))
221138fd1498Szrj      : _M_param(__q, __omega),
221238fd1498Szrj	_M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
221338fd1498Szrj	      result_type(0.5L) * (result_type(1) + __q * __q)
221438fd1498Szrj				/ (__q * __q)),
221538fd1498Szrj	_M_ed(result_type(1))
221638fd1498Szrj      { }
221738fd1498Szrj
221838fd1498Szrj      explicit
221938fd1498Szrj      hoyt_distribution(const param_type& __p)
222038fd1498Szrj      : _M_param(__p),
222138fd1498Szrj	_M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
222238fd1498Szrj	      result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
222338fd1498Szrj				/ (__p.q() * __p.q())),
222438fd1498Szrj	_M_ed(result_type(1))
222538fd1498Szrj      { }
222638fd1498Szrj
222738fd1498Szrj      /**
222838fd1498Szrj       * @brief Resets the distribution state.
222938fd1498Szrj       */
223038fd1498Szrj      void
223138fd1498Szrj      reset()
223238fd1498Szrj      {
223338fd1498Szrj	_M_ad.reset();
223438fd1498Szrj	_M_ed.reset();
223538fd1498Szrj      }
223638fd1498Szrj
223738fd1498Szrj      /**
223838fd1498Szrj       * @brief Return the parameters of the distribution.
223938fd1498Szrj       */
224038fd1498Szrj      result_type
224138fd1498Szrj      q() const
224238fd1498Szrj      { return _M_param.q(); }
224338fd1498Szrj
224438fd1498Szrj      result_type
224538fd1498Szrj      omega() const
224638fd1498Szrj      { return _M_param.omega(); }
224738fd1498Szrj
224838fd1498Szrj      /**
224938fd1498Szrj       * @brief Returns the parameter set of the distribution.
225038fd1498Szrj       */
225138fd1498Szrj      param_type
225238fd1498Szrj      param() const
225338fd1498Szrj      { return _M_param; }
225438fd1498Szrj
225538fd1498Szrj      /**
225638fd1498Szrj       * @brief Sets the parameter set of the distribution.
225738fd1498Szrj       * @param __param The new parameter set of the distribution.
225838fd1498Szrj       */
225938fd1498Szrj      void
226038fd1498Szrj      param(const param_type& __param)
226138fd1498Szrj      { _M_param = __param; }
226238fd1498Szrj
226338fd1498Szrj      /**
226438fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
226538fd1498Szrj       */
226638fd1498Szrj      result_type
226738fd1498Szrj      min() const
226838fd1498Szrj      { return result_type(0); }
226938fd1498Szrj
227038fd1498Szrj      /**
227138fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
227238fd1498Szrj       */
227338fd1498Szrj      result_type
227438fd1498Szrj      max() const
227538fd1498Szrj      { return std::numeric_limits<result_type>::max(); }
227638fd1498Szrj
227738fd1498Szrj      /**
227838fd1498Szrj       * @brief Generating functions.
227938fd1498Szrj       */
228038fd1498Szrj      template<typename _UniformRandomNumberGenerator>
228138fd1498Szrj	result_type
228238fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng);
228338fd1498Szrj
228438fd1498Szrj      template<typename _UniformRandomNumberGenerator>
228538fd1498Szrj	result_type
228638fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
228738fd1498Szrj		   const param_type& __p);
228838fd1498Szrj
228938fd1498Szrj      template<typename _ForwardIterator,
229038fd1498Szrj	       typename _UniformRandomNumberGenerator>
229138fd1498Szrj	void
229238fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
229338fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
229438fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
229538fd1498Szrj
229638fd1498Szrj      template<typename _ForwardIterator,
229738fd1498Szrj	       typename _UniformRandomNumberGenerator>
229838fd1498Szrj	void
229938fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
230038fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
230138fd1498Szrj		   const param_type& __p)
230238fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
230338fd1498Szrj
230438fd1498Szrj      template<typename _UniformRandomNumberGenerator>
230538fd1498Szrj	void
230638fd1498Szrj	__generate(result_type* __f, result_type* __t,
230738fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
230838fd1498Szrj		   const param_type& __p)
230938fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
231038fd1498Szrj
231138fd1498Szrj      /**
231238fd1498Szrj       * @brief Return true if two Hoyt distributions have
231338fd1498Szrj       *        the same parameters and the sequences that would
231438fd1498Szrj       *        be generated are equal.
231538fd1498Szrj       */
231638fd1498Szrj      friend bool
231738fd1498Szrj      operator==(const hoyt_distribution& __d1,
231838fd1498Szrj		 const hoyt_distribution& __d2)
231938fd1498Szrj      { return (__d1._M_param == __d2._M_param
232038fd1498Szrj		&& __d1._M_ad == __d2._M_ad
232138fd1498Szrj		&& __d1._M_ed == __d2._M_ed); }
232238fd1498Szrj
232338fd1498Szrj      /**
232438fd1498Szrj       * @brief Inserts a %hoyt_distribution random number distribution
232538fd1498Szrj       * @p __x into the output stream @p __os.
232638fd1498Szrj       *
232738fd1498Szrj       * @param __os An output stream.
232838fd1498Szrj       * @param __x  A %hoyt_distribution random number distribution.
232938fd1498Szrj       *
233038fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
233138fd1498Szrj       * an error state.
233238fd1498Szrj       */
233338fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
233438fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
233538fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>&,
233638fd1498Szrj		   const hoyt_distribution<_RealType1>&);
233738fd1498Szrj
233838fd1498Szrj      /**
233938fd1498Szrj       * @brief Extracts a %hoyt_distribution random number distribution
234038fd1498Szrj       * @p __x from the input stream @p __is.
234138fd1498Szrj       *
234238fd1498Szrj       * @param __is An input stream.
234338fd1498Szrj       * @param __x A %hoyt_distribution random number
234438fd1498Szrj       *            generator engine.
234538fd1498Szrj       *
234638fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
234738fd1498Szrj       */
234838fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
234938fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
235038fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>&,
235138fd1498Szrj		   hoyt_distribution<_RealType1>&);
235238fd1498Szrj
235338fd1498Szrj    private:
235438fd1498Szrj      template<typename _ForwardIterator,
235538fd1498Szrj	       typename _UniformRandomNumberGenerator>
235638fd1498Szrj	void
235738fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
235838fd1498Szrj			_UniformRandomNumberGenerator& __urng,
235938fd1498Szrj			const param_type& __p);
236038fd1498Szrj
236138fd1498Szrj      param_type _M_param;
236238fd1498Szrj
236338fd1498Szrj      __gnu_cxx::arcsine_distribution<result_type> _M_ad;
236438fd1498Szrj      std::exponential_distribution<result_type> _M_ed;
236538fd1498Szrj    };
236638fd1498Szrj
236738fd1498Szrj  /**
236838fd1498Szrj   * @brief Return true if two Hoyt distributions are not equal.
236938fd1498Szrj   */
237038fd1498Szrj  template<typename _RealType>
237138fd1498Szrj    inline bool
237238fd1498Szrj    operator!=(const hoyt_distribution<_RealType>& __d1,
237338fd1498Szrj	       const hoyt_distribution<_RealType>& __d2)
237438fd1498Szrj    { return !(__d1 == __d2); }
237538fd1498Szrj
237638fd1498Szrj
237738fd1498Szrj  /**
237838fd1498Szrj   * @brief A triangular distribution for random numbers.
237938fd1498Szrj   *
238038fd1498Szrj   * The formula for the triangular probability density function is
238138fd1498Szrj   * @f[
238238fd1498Szrj   *                  / 0                          for x < a
238338fd1498Szrj   *     p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)}  for a <= x <= b
238438fd1498Szrj   *                  | \frac{2(c-x)}{(c-a)(c-b)}  for b < x <= c
238538fd1498Szrj   *                  \ 0                          for c < x
238638fd1498Szrj   * @f]
238738fd1498Szrj   *
238838fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
238938fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
239038fd1498Szrj   * <tr><td>Mean</td><td>@f$ \frac{a+b+c}{2} @f$</td></tr>
239138fd1498Szrj   * <tr><td>Variance</td><td>@f$ \frac{a^2+b^2+c^2-ab-ac-bc}
239238fd1498Szrj   *                                   {18}@f$</td></tr>
239338fd1498Szrj   * <tr><td>Range</td><td>@f$[a, c]@f$</td></tr>
239438fd1498Szrj   * </table>
239538fd1498Szrj   */
239638fd1498Szrj  template<typename _RealType = double>
239738fd1498Szrj    class triangular_distribution
239838fd1498Szrj    {
239938fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
240038fd1498Szrj		    "template argument not a floating point type");
240138fd1498Szrj
240238fd1498Szrj    public:
240338fd1498Szrj      /** The type of the range of the distribution. */
240438fd1498Szrj      typedef _RealType result_type;
240538fd1498Szrj
240638fd1498Szrj      /** Parameter type. */
240738fd1498Szrj      struct param_type
240838fd1498Szrj      {
240938fd1498Szrj	friend class triangular_distribution<_RealType>;
241038fd1498Szrj
241138fd1498Szrj	explicit
241238fd1498Szrj	param_type(_RealType __a = _RealType(0),
241338fd1498Szrj		   _RealType __b = _RealType(0.5),
241438fd1498Szrj		   _RealType __c = _RealType(1))
241538fd1498Szrj	: _M_a(__a), _M_b(__b), _M_c(__c)
241638fd1498Szrj	{
241738fd1498Szrj	  __glibcxx_assert(_M_a <= _M_b);
241838fd1498Szrj	  __glibcxx_assert(_M_b <= _M_c);
241938fd1498Szrj	  __glibcxx_assert(_M_a < _M_c);
242038fd1498Szrj
242138fd1498Szrj	  _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a);
242238fd1498Szrj	  _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a);
242338fd1498Szrj	  _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a);
242438fd1498Szrj	}
242538fd1498Szrj
242638fd1498Szrj	_RealType
242738fd1498Szrj	a() const
242838fd1498Szrj	{ return _M_a; }
242938fd1498Szrj
243038fd1498Szrj	_RealType
243138fd1498Szrj	b() const
243238fd1498Szrj	{ return _M_b; }
243338fd1498Szrj
243438fd1498Szrj	_RealType
243538fd1498Szrj	c() const
243638fd1498Szrj	{ return _M_c; }
243738fd1498Szrj
243838fd1498Szrj	friend bool
243938fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
244038fd1498Szrj	{
244138fd1498Szrj	  return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b
244238fd1498Szrj		  && __p1._M_c == __p2._M_c);
244338fd1498Szrj	}
244438fd1498Szrj
244538fd1498Szrj	friend bool
244638fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
244738fd1498Szrj	{ return !(__p1 == __p2); }
244838fd1498Szrj
244938fd1498Szrj      private:
245038fd1498Szrj
245138fd1498Szrj	_RealType _M_a;
245238fd1498Szrj	_RealType _M_b;
245338fd1498Szrj	_RealType _M_c;
245438fd1498Szrj	_RealType _M_r_ab;
245538fd1498Szrj	_RealType _M_f_ab_ac;
245638fd1498Szrj	_RealType _M_f_bc_ac;
245738fd1498Szrj      };
245838fd1498Szrj
245938fd1498Szrj      /**
246038fd1498Szrj       * @brief Constructs a triangle distribution with parameters
246138fd1498Szrj       * @f$ a @f$, @f$ b @f$ and @f$ c @f$.
246238fd1498Szrj       */
246338fd1498Szrj      explicit
246438fd1498Szrj      triangular_distribution(result_type __a = result_type(0),
246538fd1498Szrj			      result_type __b = result_type(0.5),
246638fd1498Szrj			      result_type __c = result_type(1))
246738fd1498Szrj      : _M_param(__a, __b, __c)
246838fd1498Szrj      { }
246938fd1498Szrj
247038fd1498Szrj      explicit
247138fd1498Szrj      triangular_distribution(const param_type& __p)
247238fd1498Szrj      : _M_param(__p)
247338fd1498Szrj      { }
247438fd1498Szrj
247538fd1498Szrj      /**
247638fd1498Szrj       * @brief Resets the distribution state.
247738fd1498Szrj       */
247838fd1498Szrj      void
247938fd1498Szrj      reset()
248038fd1498Szrj      { }
248138fd1498Szrj
248238fd1498Szrj      /**
248338fd1498Szrj       * @brief Returns the @f$ a @f$ of the distribution.
248438fd1498Szrj       */
248538fd1498Szrj      result_type
248638fd1498Szrj      a() const
248738fd1498Szrj      { return _M_param.a(); }
248838fd1498Szrj
248938fd1498Szrj      /**
249038fd1498Szrj       * @brief Returns the @f$ b @f$ of the distribution.
249138fd1498Szrj       */
249238fd1498Szrj      result_type
249338fd1498Szrj      b() const
249438fd1498Szrj      { return _M_param.b(); }
249538fd1498Szrj
249638fd1498Szrj      /**
249738fd1498Szrj       * @brief Returns the @f$ c @f$ of the distribution.
249838fd1498Szrj       */
249938fd1498Szrj      result_type
250038fd1498Szrj      c() const
250138fd1498Szrj      { return _M_param.c(); }
250238fd1498Szrj
250338fd1498Szrj      /**
250438fd1498Szrj       * @brief Returns the parameter set of the distribution.
250538fd1498Szrj       */
250638fd1498Szrj      param_type
250738fd1498Szrj      param() const
250838fd1498Szrj      { return _M_param; }
250938fd1498Szrj
251038fd1498Szrj      /**
251138fd1498Szrj       * @brief Sets the parameter set of the distribution.
251238fd1498Szrj       * @param __param The new parameter set of the distribution.
251338fd1498Szrj       */
251438fd1498Szrj      void
251538fd1498Szrj      param(const param_type& __param)
251638fd1498Szrj      { _M_param = __param; }
251738fd1498Szrj
251838fd1498Szrj      /**
251938fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
252038fd1498Szrj       */
252138fd1498Szrj      result_type
252238fd1498Szrj      min() const
252338fd1498Szrj      { return _M_param._M_a; }
252438fd1498Szrj
252538fd1498Szrj      /**
252638fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
252738fd1498Szrj       */
252838fd1498Szrj      result_type
252938fd1498Szrj      max() const
253038fd1498Szrj      { return _M_param._M_c; }
253138fd1498Szrj
253238fd1498Szrj      /**
253338fd1498Szrj       * @brief Generating functions.
253438fd1498Szrj       */
253538fd1498Szrj      template<typename _UniformRandomNumberGenerator>
253638fd1498Szrj	result_type
253738fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
253838fd1498Szrj	{ return this->operator()(__urng, _M_param); }
253938fd1498Szrj
254038fd1498Szrj      template<typename _UniformRandomNumberGenerator>
254138fd1498Szrj	result_type
254238fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
254338fd1498Szrj		   const param_type& __p)
254438fd1498Szrj	{
254538fd1498Szrj	  std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
254638fd1498Szrj	    __aurng(__urng);
254738fd1498Szrj	  result_type __rnd = __aurng();
254838fd1498Szrj	  if (__rnd <= __p._M_r_ab)
254938fd1498Szrj	    return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac);
255038fd1498Szrj	  else
255138fd1498Szrj	    return __p.c() - std::sqrt((result_type(1) - __rnd)
255238fd1498Szrj				       * __p._M_f_bc_ac);
255338fd1498Szrj	}
255438fd1498Szrj
255538fd1498Szrj      template<typename _ForwardIterator,
255638fd1498Szrj	       typename _UniformRandomNumberGenerator>
255738fd1498Szrj	void
255838fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
255938fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
256038fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
256138fd1498Szrj
256238fd1498Szrj      template<typename _ForwardIterator,
256338fd1498Szrj	       typename _UniformRandomNumberGenerator>
256438fd1498Szrj	void
256538fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
256638fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
256738fd1498Szrj		   const param_type& __p)
256838fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
256938fd1498Szrj
257038fd1498Szrj      template<typename _UniformRandomNumberGenerator>
257138fd1498Szrj	void
257238fd1498Szrj	__generate(result_type* __f, result_type* __t,
257338fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
257438fd1498Szrj		   const param_type& __p)
257538fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
257638fd1498Szrj
257738fd1498Szrj      /**
257838fd1498Szrj       * @brief Return true if two triangle distributions have the same
257938fd1498Szrj       *        parameters and the sequences that would be generated
258038fd1498Szrj       *        are equal.
258138fd1498Szrj       */
258238fd1498Szrj      friend bool
258338fd1498Szrj      operator==(const triangular_distribution& __d1,
258438fd1498Szrj		 const triangular_distribution& __d2)
258538fd1498Szrj      { return __d1._M_param == __d2._M_param; }
258638fd1498Szrj
258738fd1498Szrj      /**
258838fd1498Szrj       * @brief Inserts a %triangular_distribution random number distribution
258938fd1498Szrj       * @p __x into the output stream @p __os.
259038fd1498Szrj       *
259138fd1498Szrj       * @param __os An output stream.
259238fd1498Szrj       * @param __x  A %triangular_distribution random number distribution.
259338fd1498Szrj       *
259438fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
259538fd1498Szrj       * an error state.
259638fd1498Szrj       */
259738fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
259838fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
259938fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
260038fd1498Szrj		   const __gnu_cxx::triangular_distribution<_RealType1>& __x);
260138fd1498Szrj
260238fd1498Szrj      /**
260338fd1498Szrj       * @brief Extracts a %triangular_distribution random number distribution
260438fd1498Szrj       * @p __x from the input stream @p __is.
260538fd1498Szrj       *
260638fd1498Szrj       * @param __is An input stream.
260738fd1498Szrj       * @param __x  A %triangular_distribution random number generator engine.
260838fd1498Szrj       *
260938fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
261038fd1498Szrj       */
261138fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
261238fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
261338fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
261438fd1498Szrj		   __gnu_cxx::triangular_distribution<_RealType1>& __x);
261538fd1498Szrj
261638fd1498Szrj    private:
261738fd1498Szrj      template<typename _ForwardIterator,
261838fd1498Szrj	       typename _UniformRandomNumberGenerator>
261938fd1498Szrj	void
262038fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
262138fd1498Szrj			_UniformRandomNumberGenerator& __urng,
262238fd1498Szrj			const param_type& __p);
262338fd1498Szrj
262438fd1498Szrj      param_type _M_param;
262538fd1498Szrj    };
262638fd1498Szrj
262738fd1498Szrj  /**
262838fd1498Szrj   * @brief Return true if two triangle distributions are different.
262938fd1498Szrj   */
263038fd1498Szrj  template<typename _RealType>
263138fd1498Szrj    inline bool
263238fd1498Szrj    operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1,
263338fd1498Szrj	       const __gnu_cxx::triangular_distribution<_RealType>& __d2)
263438fd1498Szrj    { return !(__d1 == __d2); }
263538fd1498Szrj
263638fd1498Szrj
263738fd1498Szrj  /**
263838fd1498Szrj   * @brief A von Mises distribution for random numbers.
263938fd1498Szrj   *
264038fd1498Szrj   * The formula for the von Mises probability density function is
264138fd1498Szrj   * @f[
264238fd1498Szrj   *     p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}}
264338fd1498Szrj   *                            {2\pi I_0(\kappa)}
264438fd1498Szrj   * @f]
264538fd1498Szrj   *
264638fd1498Szrj   * The generating functions use the method according to:
264738fd1498Szrj   *
264838fd1498Szrj   * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the
264938fd1498Szrj   * von Mises Distribution", Journal of the Royal Statistical Society.
265038fd1498Szrj   * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157.
265138fd1498Szrj   *
265238fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
265338fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
265438fd1498Szrj   * <tr><td>Mean</td><td>@f$ \mu @f$</td></tr>
265538fd1498Szrj   * <tr><td>Variance</td><td>@f$ 1-I_1(\kappa)/I_0(\kappa) @f$</td></tr>
265638fd1498Szrj   * <tr><td>Range</td><td>@f$[-\pi, \pi]@f$</td></tr>
265738fd1498Szrj   * </table>
265838fd1498Szrj   */
265938fd1498Szrj  template<typename _RealType = double>
266038fd1498Szrj    class von_mises_distribution
266138fd1498Szrj    {
266238fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
266338fd1498Szrj		    "template argument not a floating point type");
266438fd1498Szrj
266538fd1498Szrj    public:
266638fd1498Szrj      /** The type of the range of the distribution. */
266738fd1498Szrj      typedef _RealType result_type;
266838fd1498Szrj      /** Parameter type. */
266938fd1498Szrj      struct param_type
267038fd1498Szrj      {
267138fd1498Szrj	friend class von_mises_distribution<_RealType>;
267238fd1498Szrj
267338fd1498Szrj	explicit
267438fd1498Szrj	param_type(_RealType __mu = _RealType(0),
267538fd1498Szrj		   _RealType __kappa = _RealType(1))
267638fd1498Szrj	: _M_mu(__mu), _M_kappa(__kappa)
267738fd1498Szrj	{
267838fd1498Szrj	  const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi;
267938fd1498Szrj	  __glibcxx_assert(_M_mu >= -__pi && _M_mu <= __pi);
268038fd1498Szrj	  __glibcxx_assert(_M_kappa >= _RealType(0));
268138fd1498Szrj
268238fd1498Szrj	  auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa
268338fd1498Szrj				 + _RealType(1)) + _RealType(1);
268438fd1498Szrj	  auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau))
268538fd1498Szrj			/ (_RealType(2) * _M_kappa));
268638fd1498Szrj	  _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho);
268738fd1498Szrj	}
268838fd1498Szrj
268938fd1498Szrj	_RealType
269038fd1498Szrj	mu() const
269138fd1498Szrj	{ return _M_mu; }
269238fd1498Szrj
269338fd1498Szrj	_RealType
269438fd1498Szrj	kappa() const
269538fd1498Szrj	{ return _M_kappa; }
269638fd1498Szrj
269738fd1498Szrj	friend bool
269838fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
269938fd1498Szrj	{ return __p1._M_mu == __p2._M_mu && __p1._M_kappa == __p2._M_kappa; }
270038fd1498Szrj
270138fd1498Szrj	friend bool
270238fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
270338fd1498Szrj	{ return !(__p1 == __p2); }
270438fd1498Szrj
270538fd1498Szrj      private:
270638fd1498Szrj	_RealType _M_mu;
270738fd1498Szrj	_RealType _M_kappa;
270838fd1498Szrj	_RealType _M_r;
270938fd1498Szrj      };
271038fd1498Szrj
271138fd1498Szrj      /**
271238fd1498Szrj       * @brief Constructs a von Mises distribution with parameters
271338fd1498Szrj       * @f$\mu@f$ and @f$\kappa@f$.
271438fd1498Szrj       */
271538fd1498Szrj      explicit
271638fd1498Szrj      von_mises_distribution(result_type __mu = result_type(0),
271738fd1498Szrj			     result_type __kappa = result_type(1))
271838fd1498Szrj	: _M_param(__mu, __kappa)
271938fd1498Szrj      { }
272038fd1498Szrj
272138fd1498Szrj      explicit
272238fd1498Szrj      von_mises_distribution(const param_type& __p)
272338fd1498Szrj      : _M_param(__p)
272438fd1498Szrj      { }
272538fd1498Szrj
272638fd1498Szrj      /**
272738fd1498Szrj       * @brief Resets the distribution state.
272838fd1498Szrj       */
272938fd1498Szrj      void
273038fd1498Szrj      reset()
273138fd1498Szrj      { }
273238fd1498Szrj
273338fd1498Szrj      /**
273438fd1498Szrj       * @brief Returns the @f$ \mu @f$ of the distribution.
273538fd1498Szrj       */
273638fd1498Szrj      result_type
273738fd1498Szrj      mu() const
273838fd1498Szrj      { return _M_param.mu(); }
273938fd1498Szrj
274038fd1498Szrj      /**
274138fd1498Szrj       * @brief Returns the @f$ \kappa @f$ of the distribution.
274238fd1498Szrj       */
274338fd1498Szrj      result_type
274438fd1498Szrj      kappa() const
274538fd1498Szrj      { return _M_param.kappa(); }
274638fd1498Szrj
274738fd1498Szrj      /**
274838fd1498Szrj       * @brief Returns the parameter set of the distribution.
274938fd1498Szrj       */
275038fd1498Szrj      param_type
275138fd1498Szrj      param() const
275238fd1498Szrj      { return _M_param; }
275338fd1498Szrj
275438fd1498Szrj      /**
275538fd1498Szrj       * @brief Sets the parameter set of the distribution.
275638fd1498Szrj       * @param __param The new parameter set of the distribution.
275738fd1498Szrj       */
275838fd1498Szrj      void
275938fd1498Szrj      param(const param_type& __param)
276038fd1498Szrj      { _M_param = __param; }
276138fd1498Szrj
276238fd1498Szrj      /**
276338fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
276438fd1498Szrj       */
276538fd1498Szrj      result_type
276638fd1498Szrj      min() const
276738fd1498Szrj      {
276838fd1498Szrj	return -__gnu_cxx::__math_constants<result_type>::__pi;
276938fd1498Szrj      }
277038fd1498Szrj
277138fd1498Szrj      /**
277238fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
277338fd1498Szrj       */
277438fd1498Szrj      result_type
277538fd1498Szrj      max() const
277638fd1498Szrj      {
277738fd1498Szrj	return __gnu_cxx::__math_constants<result_type>::__pi;
277838fd1498Szrj      }
277938fd1498Szrj
278038fd1498Szrj      /**
278138fd1498Szrj       * @brief Generating functions.
278238fd1498Szrj       */
278338fd1498Szrj      template<typename _UniformRandomNumberGenerator>
278438fd1498Szrj	result_type
278538fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
278638fd1498Szrj	{ return this->operator()(__urng, _M_param); }
278738fd1498Szrj
278838fd1498Szrj      template<typename _UniformRandomNumberGenerator>
278938fd1498Szrj	result_type
279038fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
279138fd1498Szrj		   const param_type& __p);
279238fd1498Szrj
279338fd1498Szrj      template<typename _ForwardIterator,
279438fd1498Szrj	       typename _UniformRandomNumberGenerator>
279538fd1498Szrj	void
279638fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
279738fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
279838fd1498Szrj	{ this->__generate(__f, __t, __urng, _M_param); }
279938fd1498Szrj
280038fd1498Szrj      template<typename _ForwardIterator,
280138fd1498Szrj	       typename _UniformRandomNumberGenerator>
280238fd1498Szrj	void
280338fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
280438fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
280538fd1498Szrj		   const param_type& __p)
280638fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
280738fd1498Szrj
280838fd1498Szrj      template<typename _UniformRandomNumberGenerator>
280938fd1498Szrj	void
281038fd1498Szrj	__generate(result_type* __f, result_type* __t,
281138fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
281238fd1498Szrj		   const param_type& __p)
281338fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
281438fd1498Szrj
281538fd1498Szrj      /**
281638fd1498Szrj       * @brief Return true if two von Mises distributions have the same
281738fd1498Szrj       *        parameters and the sequences that would be generated
281838fd1498Szrj       *        are equal.
281938fd1498Szrj       */
282038fd1498Szrj      friend bool
282138fd1498Szrj      operator==(const von_mises_distribution& __d1,
282238fd1498Szrj		 const von_mises_distribution& __d2)
282338fd1498Szrj      { return __d1._M_param == __d2._M_param; }
282438fd1498Szrj
282538fd1498Szrj      /**
282638fd1498Szrj       * @brief Inserts a %von_mises_distribution random number distribution
282738fd1498Szrj       * @p __x into the output stream @p __os.
282838fd1498Szrj       *
282938fd1498Szrj       * @param __os An output stream.
283038fd1498Szrj       * @param __x  A %von_mises_distribution random number distribution.
283138fd1498Szrj       *
283238fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
283338fd1498Szrj       * an error state.
283438fd1498Szrj       */
283538fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
283638fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
283738fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
283838fd1498Szrj		   const __gnu_cxx::von_mises_distribution<_RealType1>& __x);
283938fd1498Szrj
284038fd1498Szrj      /**
284138fd1498Szrj       * @brief Extracts a %von_mises_distribution random number distribution
284238fd1498Szrj       * @p __x from the input stream @p __is.
284338fd1498Szrj       *
284438fd1498Szrj       * @param __is An input stream.
284538fd1498Szrj       * @param __x  A %von_mises_distribution random number generator engine.
284638fd1498Szrj       *
284738fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
284838fd1498Szrj       */
284938fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
285038fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
285138fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
285238fd1498Szrj		   __gnu_cxx::von_mises_distribution<_RealType1>& __x);
285338fd1498Szrj
285438fd1498Szrj    private:
285538fd1498Szrj      template<typename _ForwardIterator,
285638fd1498Szrj	       typename _UniformRandomNumberGenerator>
285738fd1498Szrj	void
285838fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
285938fd1498Szrj			_UniformRandomNumberGenerator& __urng,
286038fd1498Szrj			const param_type& __p);
286138fd1498Szrj
286238fd1498Szrj      param_type _M_param;
286338fd1498Szrj    };
286438fd1498Szrj
286538fd1498Szrj  /**
286638fd1498Szrj   * @brief Return true if two von Mises distributions are different.
286738fd1498Szrj   */
286838fd1498Szrj  template<typename _RealType>
286938fd1498Szrj    inline bool
287038fd1498Szrj    operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1,
287138fd1498Szrj	       const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
287238fd1498Szrj    { return !(__d1 == __d2); }
287338fd1498Szrj
287438fd1498Szrj
287538fd1498Szrj  /**
287638fd1498Szrj   * @brief A discrete hypergeometric random number distribution.
287738fd1498Szrj   *
287838fd1498Szrj   * The hypergeometric distribution is a discrete probability distribution
287938fd1498Szrj   * that describes the probability of @p k successes in @p n draws @a without
288038fd1498Szrj   * replacement from a finite population of size @p N containing exactly @p K
288138fd1498Szrj   * successes.
288238fd1498Szrj   *
288338fd1498Szrj   * The formula for the hypergeometric probability density function is
288438fd1498Szrj   * @f[
288538fd1498Szrj   *   p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}}
288638fd1498Szrj   * @f]
288738fd1498Szrj   * where @f$N@f$ is the total population of the distribution,
288838fd1498Szrj   * @f$K@f$ is the total population of the distribution.
288938fd1498Szrj   *
289038fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
289138fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
289238fd1498Szrj   * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr>
289338fd1498Szrj   * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}
289438fd1498Szrj   *   @f$</td></tr>
289538fd1498Szrj   * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr>
289638fd1498Szrj   * </table>
289738fd1498Szrj   */
289838fd1498Szrj  template<typename _UIntType = unsigned int>
289938fd1498Szrj    class hypergeometric_distribution
290038fd1498Szrj    {
290138fd1498Szrj      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
290238fd1498Szrj		    "substituting _UIntType not an unsigned integral type");
290338fd1498Szrj
290438fd1498Szrj    public:
290538fd1498Szrj      /** The type of the range of the distribution. */
290638fd1498Szrj      typedef _UIntType  result_type;
290738fd1498Szrj
290838fd1498Szrj      /** Parameter type. */
290938fd1498Szrj      struct param_type
291038fd1498Szrj      {
291138fd1498Szrj	typedef hypergeometric_distribution<_UIntType> distribution_type;
291238fd1498Szrj	friend class hypergeometric_distribution<_UIntType>;
291338fd1498Szrj
291438fd1498Szrj	explicit
291538fd1498Szrj	param_type(result_type __N = 10, result_type __K = 5,
291638fd1498Szrj		   result_type __n = 1)
291738fd1498Szrj	: _M_N{__N}, _M_K{__K}, _M_n{__n}
291838fd1498Szrj	{
291938fd1498Szrj	  __glibcxx_assert(_M_N >= _M_K);
292038fd1498Szrj	  __glibcxx_assert(_M_N >= _M_n);
292138fd1498Szrj	}
292238fd1498Szrj
292338fd1498Szrj	result_type
292438fd1498Szrj	total_size() const
292538fd1498Szrj	{ return _M_N; }
292638fd1498Szrj
292738fd1498Szrj	result_type
292838fd1498Szrj	successful_size() const
292938fd1498Szrj	{ return _M_K; }
293038fd1498Szrj
293138fd1498Szrj	result_type
293238fd1498Szrj	unsuccessful_size() const
293338fd1498Szrj	{ return _M_N - _M_K; }
293438fd1498Szrj
293538fd1498Szrj	result_type
293638fd1498Szrj	total_draws() const
293738fd1498Szrj	{ return _M_n; }
293838fd1498Szrj
293938fd1498Szrj	friend bool
294038fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
294138fd1498Szrj	{ return (__p1._M_N == __p2._M_N)
294238fd1498Szrj	      && (__p1._M_K == __p2._M_K)
294338fd1498Szrj	      && (__p1._M_n == __p2._M_n); }
294438fd1498Szrj
294538fd1498Szrj	friend bool
294638fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
294738fd1498Szrj	{ return !(__p1 == __p2); }
294838fd1498Szrj
294938fd1498Szrj      private:
295038fd1498Szrj
295138fd1498Szrj	result_type _M_N;
295238fd1498Szrj	result_type _M_K;
295338fd1498Szrj	result_type _M_n;
295438fd1498Szrj      };
295538fd1498Szrj
295638fd1498Szrj      // constructors and member function
295738fd1498Szrj      explicit
295838fd1498Szrj      hypergeometric_distribution(result_type __N = 10, result_type __K = 5,
295938fd1498Szrj				  result_type __n = 1)
296038fd1498Szrj      : _M_param{__N, __K, __n}
296138fd1498Szrj      { }
296238fd1498Szrj
296338fd1498Szrj      explicit
296438fd1498Szrj      hypergeometric_distribution(const param_type& __p)
296538fd1498Szrj      : _M_param{__p}
296638fd1498Szrj      { }
296738fd1498Szrj
296838fd1498Szrj      /**
296938fd1498Szrj       * @brief Resets the distribution state.
297038fd1498Szrj       */
297138fd1498Szrj      void
297238fd1498Szrj      reset()
297338fd1498Szrj      { }
297438fd1498Szrj
297538fd1498Szrj      /**
297638fd1498Szrj       * @brief Returns the distribution parameter @p N,
297738fd1498Szrj       *	the total number of items.
297838fd1498Szrj       */
297938fd1498Szrj      result_type
298038fd1498Szrj      total_size() const
298138fd1498Szrj      { return this->_M_param.total_size(); }
298238fd1498Szrj
298338fd1498Szrj      /**
298438fd1498Szrj       * @brief Returns the distribution parameter @p K,
298538fd1498Szrj       *	the total number of successful items.
298638fd1498Szrj       */
298738fd1498Szrj      result_type
298838fd1498Szrj      successful_size() const
298938fd1498Szrj      { return this->_M_param.successful_size(); }
299038fd1498Szrj
299138fd1498Szrj      /**
299238fd1498Szrj       * @brief Returns the total number of unsuccessful items @f$ N - K @f$.
299338fd1498Szrj       */
299438fd1498Szrj      result_type
299538fd1498Szrj      unsuccessful_size() const
299638fd1498Szrj      { return this->_M_param.unsuccessful_size(); }
299738fd1498Szrj
299838fd1498Szrj      /**
299938fd1498Szrj       * @brief Returns the distribution parameter @p n,
300038fd1498Szrj       *	the total number of draws.
300138fd1498Szrj       */
300238fd1498Szrj      result_type
300338fd1498Szrj      total_draws() const
300438fd1498Szrj      { return this->_M_param.total_draws(); }
300538fd1498Szrj
300638fd1498Szrj      /**
300738fd1498Szrj       * @brief Returns the parameter set of the distribution.
300838fd1498Szrj       */
300938fd1498Szrj      param_type
301038fd1498Szrj      param() const
301138fd1498Szrj      { return this->_M_param; }
301238fd1498Szrj
301338fd1498Szrj      /**
301438fd1498Szrj       * @brief Sets the parameter set of the distribution.
301538fd1498Szrj       * @param __param The new parameter set of the distribution.
301638fd1498Szrj       */
301738fd1498Szrj      void
301838fd1498Szrj      param(const param_type& __param)
301938fd1498Szrj      { this->_M_param = __param; }
302038fd1498Szrj
302138fd1498Szrj      /**
302238fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
302338fd1498Szrj       */
302438fd1498Szrj      result_type
302538fd1498Szrj      min() const
302638fd1498Szrj      {
302738fd1498Szrj	using _IntType = typename std::make_signed<result_type>::type;
302838fd1498Szrj	return static_cast<result_type>(std::max(static_cast<_IntType>(0),
302938fd1498Szrj				static_cast<_IntType>(this->total_draws()
303038fd1498Szrj						- this->unsuccessful_size())));
303138fd1498Szrj      }
303238fd1498Szrj
303338fd1498Szrj      /**
303438fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
303538fd1498Szrj       */
303638fd1498Szrj      result_type
303738fd1498Szrj      max() const
303838fd1498Szrj      { return std::min(this->successful_size(), this->total_draws()); }
303938fd1498Szrj
304038fd1498Szrj      /**
304138fd1498Szrj       * @brief Generating functions.
304238fd1498Szrj       */
304338fd1498Szrj      template<typename _UniformRandomNumberGenerator>
304438fd1498Szrj	result_type
304538fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
304638fd1498Szrj	{ return this->operator()(__urng, this->_M_param); }
304738fd1498Szrj
304838fd1498Szrj      template<typename _UniformRandomNumberGenerator>
304938fd1498Szrj	result_type
305038fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
305138fd1498Szrj		   const param_type& __p);
305238fd1498Szrj
305338fd1498Szrj      template<typename _ForwardIterator,
305438fd1498Szrj	       typename _UniformRandomNumberGenerator>
305538fd1498Szrj	void
305638fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
305738fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
305838fd1498Szrj	{ this->__generate(__f, __t, __urng, this->_M_param); }
305938fd1498Szrj
306038fd1498Szrj      template<typename _ForwardIterator,
306138fd1498Szrj	       typename _UniformRandomNumberGenerator>
306238fd1498Szrj	void
306338fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
306438fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
306538fd1498Szrj		   const param_type& __p)
306638fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
306738fd1498Szrj
306838fd1498Szrj      template<typename _UniformRandomNumberGenerator>
306938fd1498Szrj	void
307038fd1498Szrj	__generate(result_type* __f, result_type* __t,
307138fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
307238fd1498Szrj		   const param_type& __p)
307338fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
307438fd1498Szrj
307538fd1498Szrj       /**
307638fd1498Szrj	* @brief Return true if two hypergeometric distributions have the same
307738fd1498Szrj	*        parameters and the sequences that would be generated
307838fd1498Szrj	*        are equal.
307938fd1498Szrj	*/
308038fd1498Szrj      friend bool
308138fd1498Szrj      operator==(const hypergeometric_distribution& __d1,
308238fd1498Szrj		 const hypergeometric_distribution& __d2)
308338fd1498Szrj      { return __d1._M_param == __d2._M_param; }
308438fd1498Szrj
308538fd1498Szrj      /**
308638fd1498Szrj       * @brief Inserts a %hypergeometric_distribution random number
308738fd1498Szrj       * distribution @p __x into the output stream @p __os.
308838fd1498Szrj       *
308938fd1498Szrj       * @param __os An output stream.
309038fd1498Szrj       * @param __x  A %hypergeometric_distribution random number
309138fd1498Szrj       *             distribution.
309238fd1498Szrj       *
309338fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
309438fd1498Szrj       * an error state.
309538fd1498Szrj       */
309638fd1498Szrj      template<typename _UIntType1, typename _CharT, typename _Traits>
309738fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
309838fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
309938fd1498Szrj		   const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
310038fd1498Szrj		   __x);
310138fd1498Szrj
310238fd1498Szrj      /**
310338fd1498Szrj       * @brief Extracts a %hypergeometric_distribution random number
310438fd1498Szrj       * distribution @p __x from the input stream @p __is.
310538fd1498Szrj       *
310638fd1498Szrj       * @param __is An input stream.
310738fd1498Szrj       * @param __x  A %hypergeometric_distribution random number generator
310838fd1498Szrj       *             distribution.
310938fd1498Szrj       *
311038fd1498Szrj       * @returns The input stream with @p __x extracted or in an error
311138fd1498Szrj       *          state.
311238fd1498Szrj       */
311338fd1498Szrj      template<typename _UIntType1, typename _CharT, typename _Traits>
311438fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
311538fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
311638fd1498Szrj		   __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x);
311738fd1498Szrj
311838fd1498Szrj    private:
311938fd1498Szrj
312038fd1498Szrj      template<typename _ForwardIterator,
312138fd1498Szrj	       typename _UniformRandomNumberGenerator>
312238fd1498Szrj	void
312338fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
312438fd1498Szrj			_UniformRandomNumberGenerator& __urng,
312538fd1498Szrj			const param_type& __p);
312638fd1498Szrj
312738fd1498Szrj      param_type _M_param;
312838fd1498Szrj    };
312938fd1498Szrj
313038fd1498Szrj  /**
313138fd1498Szrj   * @brief Return true if two hypergeometric distributions are different.
313238fd1498Szrj   */
313338fd1498Szrj  template<typename _UIntType>
313438fd1498Szrj    inline bool
313538fd1498Szrj    operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
313638fd1498Szrj	       const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
313738fd1498Szrj    { return !(__d1 == __d2); }
313838fd1498Szrj
313938fd1498Szrj  /**
314038fd1498Szrj   * @brief A logistic continuous distribution for random numbers.
314138fd1498Szrj   *
314238fd1498Szrj   * The formula for the logistic probability density function is
314338fd1498Szrj   * @f[
314438fd1498Szrj   *     p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2}
314538fd1498Szrj   * @f]
314638fd1498Szrj   * where @f$b > 0@f$.
314738fd1498Szrj   *
314838fd1498Szrj   * The formula for the logistic probability function is
314938fd1498Szrj   * @f[
315038fd1498Szrj   *     cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}}
315138fd1498Szrj   * @f]
315238fd1498Szrj   * where @f$b > 0@f$.
315338fd1498Szrj   *
315438fd1498Szrj   * <table border=1 cellpadding=10 cellspacing=0>
315538fd1498Szrj   * <caption align=top>Distribution Statistics</caption>
315638fd1498Szrj   * <tr><td>Mean</td><td>@f$a@f$</td></tr>
315738fd1498Szrj   * <tr><td>Variance</td><td>@f$b^2\pi^2/3@f$</td></tr>
315838fd1498Szrj   * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
315938fd1498Szrj   * </table>
316038fd1498Szrj   */
316138fd1498Szrj  template<typename _RealType = double>
316238fd1498Szrj    class
316338fd1498Szrj    logistic_distribution
316438fd1498Szrj    {
316538fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
316638fd1498Szrj		    "template argument not a floating point type");
316738fd1498Szrj
316838fd1498Szrj    public:
316938fd1498Szrj      /** The type of the range of the distribution. */
317038fd1498Szrj      typedef _RealType result_type;
317138fd1498Szrj
317238fd1498Szrj      /** Parameter type. */
317338fd1498Szrj      struct param_type
317438fd1498Szrj      {
317538fd1498Szrj	typedef logistic_distribution<result_type> distribution_type;
317638fd1498Szrj
317738fd1498Szrj	param_type(result_type __a = result_type(0),
317838fd1498Szrj		   result_type __b = result_type(1))
317938fd1498Szrj	: _M_a(__a), _M_b(__b)
318038fd1498Szrj	{
318138fd1498Szrj	  __glibcxx_assert(_M_b > result_type(0));
318238fd1498Szrj	}
318338fd1498Szrj
318438fd1498Szrj	result_type
318538fd1498Szrj	a() const
318638fd1498Szrj	{ return _M_a; }
318738fd1498Szrj
318838fd1498Szrj	result_type
318938fd1498Szrj	b() const
319038fd1498Szrj	{ return _M_b; }
319138fd1498Szrj
319238fd1498Szrj	friend bool
319338fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
319438fd1498Szrj	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
319538fd1498Szrj
319638fd1498Szrj	friend bool
319738fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
319838fd1498Szrj	{ return !(__p1 == __p2); }
319938fd1498Szrj
320038fd1498Szrj      private:
320138fd1498Szrj	void _M_initialize();
320238fd1498Szrj
320338fd1498Szrj	result_type _M_a;
320438fd1498Szrj	result_type _M_b;
320538fd1498Szrj      };
320638fd1498Szrj
320738fd1498Szrj      /**
320838fd1498Szrj       * @brief Constructors.
320938fd1498Szrj       */
321038fd1498Szrj      explicit
321138fd1498Szrj      logistic_distribution(result_type __a = result_type(0),
321238fd1498Szrj			    result_type __b = result_type(1))
321338fd1498Szrj      : _M_param(__a, __b)
321438fd1498Szrj      { }
321538fd1498Szrj
321638fd1498Szrj      explicit
321738fd1498Szrj      logistic_distribution(const param_type& __p)
321838fd1498Szrj      : _M_param(__p)
321938fd1498Szrj      { }
322038fd1498Szrj
322138fd1498Szrj      /**
322238fd1498Szrj       * @brief Resets the distribution state.
322338fd1498Szrj       */
322438fd1498Szrj      void
322538fd1498Szrj      reset()
322638fd1498Szrj      { }
322738fd1498Szrj
322838fd1498Szrj      /**
322938fd1498Szrj       * @brief Return the parameters of the distribution.
323038fd1498Szrj       */
323138fd1498Szrj      result_type
323238fd1498Szrj      a() const
323338fd1498Szrj      { return _M_param.a(); }
323438fd1498Szrj
323538fd1498Szrj      result_type
323638fd1498Szrj      b() const
323738fd1498Szrj      { return _M_param.b(); }
323838fd1498Szrj
323938fd1498Szrj      /**
324038fd1498Szrj       * @brief Returns the parameter set of the distribution.
324138fd1498Szrj       */
324238fd1498Szrj      param_type
324338fd1498Szrj      param() const
324438fd1498Szrj      { return _M_param; }
324538fd1498Szrj
324638fd1498Szrj      /**
324738fd1498Szrj       * @brief Sets the parameter set of the distribution.
324838fd1498Szrj       * @param __param The new parameter set of the distribution.
324938fd1498Szrj       */
325038fd1498Szrj      void
325138fd1498Szrj      param(const param_type& __param)
325238fd1498Szrj      { _M_param = __param; }
325338fd1498Szrj
325438fd1498Szrj      /**
325538fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
325638fd1498Szrj       */
325738fd1498Szrj      result_type
325838fd1498Szrj      min() const
325938fd1498Szrj      { return -std::numeric_limits<result_type>::max(); }
326038fd1498Szrj
326138fd1498Szrj      /**
326238fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
326338fd1498Szrj       */
326438fd1498Szrj      result_type
326538fd1498Szrj      max() const
326638fd1498Szrj      { return std::numeric_limits<result_type>::max(); }
326738fd1498Szrj
326838fd1498Szrj      /**
326938fd1498Szrj       * @brief Generating functions.
327038fd1498Szrj       */
327138fd1498Szrj      template<typename _UniformRandomNumberGenerator>
327238fd1498Szrj	result_type
327338fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
327438fd1498Szrj	{ return this->operator()(__urng, this->_M_param); }
327538fd1498Szrj
327638fd1498Szrj      template<typename _UniformRandomNumberGenerator>
327738fd1498Szrj	result_type
327838fd1498Szrj	operator()(_UniformRandomNumberGenerator&,
327938fd1498Szrj		   const param_type&);
328038fd1498Szrj
328138fd1498Szrj      template<typename _ForwardIterator,
328238fd1498Szrj	       typename _UniformRandomNumberGenerator>
328338fd1498Szrj	void
328438fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
328538fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
328638fd1498Szrj	{ this->__generate(__f, __t, __urng, this->param()); }
328738fd1498Szrj
328838fd1498Szrj      template<typename _ForwardIterator,
328938fd1498Szrj	       typename _UniformRandomNumberGenerator>
329038fd1498Szrj	void
329138fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
329238fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
329338fd1498Szrj		   const param_type& __p)
329438fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
329538fd1498Szrj
329638fd1498Szrj      template<typename _UniformRandomNumberGenerator>
329738fd1498Szrj	void
329838fd1498Szrj	__generate(result_type* __f, result_type* __t,
329938fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
330038fd1498Szrj		   const param_type& __p)
330138fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
330238fd1498Szrj
330338fd1498Szrj      /**
330438fd1498Szrj       * @brief Return true if two logistic distributions have
330538fd1498Szrj       *        the same parameters and the sequences that would
330638fd1498Szrj       *        be generated are equal.
330738fd1498Szrj       */
330838fd1498Szrj      template<typename _RealType1>
330938fd1498Szrj	friend bool
331038fd1498Szrj	operator==(const logistic_distribution<_RealType1>& __d1,
331138fd1498Szrj		   const logistic_distribution<_RealType1>& __d2)
331238fd1498Szrj	{ return __d1.param() == __d2.param(); }
331338fd1498Szrj
331438fd1498Szrj      /**
331538fd1498Szrj       * @brief Inserts a %logistic_distribution random number distribution
331638fd1498Szrj       * @p __x into the output stream @p __os.
331738fd1498Szrj       *
331838fd1498Szrj       * @param __os An output stream.
331938fd1498Szrj       * @param __x  A %logistic_distribution random number distribution.
332038fd1498Szrj       *
332138fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
332238fd1498Szrj       * an error state.
332338fd1498Szrj       */
332438fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
332538fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
332638fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>&,
332738fd1498Szrj		   const logistic_distribution<_RealType1>&);
332838fd1498Szrj
332938fd1498Szrj      /**
333038fd1498Szrj       * @brief Extracts a %logistic_distribution random number distribution
333138fd1498Szrj       * @p __x from the input stream @p __is.
333238fd1498Szrj       *
333338fd1498Szrj       * @param __is An input stream.
333438fd1498Szrj       * @param __x A %logistic_distribution random number
333538fd1498Szrj       *            generator engine.
333638fd1498Szrj       *
333738fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
333838fd1498Szrj       */
333938fd1498Szrj      template<typename _RealType1, typename _CharT, typename _Traits>
334038fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
334138fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>&,
334238fd1498Szrj		   logistic_distribution<_RealType1>&);
334338fd1498Szrj
334438fd1498Szrj    private:
334538fd1498Szrj      template<typename _ForwardIterator,
334638fd1498Szrj	       typename _UniformRandomNumberGenerator>
334738fd1498Szrj	void
334838fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
334938fd1498Szrj			_UniformRandomNumberGenerator& __urng,
335038fd1498Szrj			const param_type& __p);
335138fd1498Szrj
335238fd1498Szrj      param_type _M_param;
335338fd1498Szrj    };
335438fd1498Szrj
335538fd1498Szrj  /**
335638fd1498Szrj   * @brief Return true if two logistic distributions are not equal.
335738fd1498Szrj   */
335838fd1498Szrj  template<typename _RealType1>
335938fd1498Szrj    inline bool
336038fd1498Szrj    operator!=(const logistic_distribution<_RealType1>& __d1,
336138fd1498Szrj	       const logistic_distribution<_RealType1>& __d2)
336238fd1498Szrj    { return !(__d1 == __d2); }
336338fd1498Szrj
336438fd1498Szrj
336538fd1498Szrj  /**
336638fd1498Szrj   * @brief A distribution for random coordinates on a unit sphere.
336738fd1498Szrj   *
336838fd1498Szrj   * The method used in the generation function is attributed by Donald Knuth
336938fd1498Szrj   * to G. W. Brown, Modern Mathematics for the Engineer (1956).
337038fd1498Szrj   */
337138fd1498Szrj  template<std::size_t _Dimen, typename _RealType = double>
337238fd1498Szrj    class uniform_on_sphere_distribution
337338fd1498Szrj    {
337438fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
337538fd1498Szrj		    "template argument not a floating point type");
337638fd1498Szrj      static_assert(_Dimen != 0, "dimension is zero");
337738fd1498Szrj
337838fd1498Szrj    public:
337938fd1498Szrj      /** The type of the range of the distribution. */
338038fd1498Szrj      typedef std::array<_RealType, _Dimen> result_type;
338138fd1498Szrj
338238fd1498Szrj      /** Parameter type. */
338338fd1498Szrj      struct param_type
338438fd1498Szrj      {
338538fd1498Szrj	explicit
338638fd1498Szrj	param_type()
338738fd1498Szrj	{ }
338838fd1498Szrj
338938fd1498Szrj	friend bool
339038fd1498Szrj	operator==(const param_type&, const param_type&)
339138fd1498Szrj	{ return true; }
339238fd1498Szrj
339338fd1498Szrj	friend bool
339438fd1498Szrj	operator!=(const param_type&, const param_type&)
339538fd1498Szrj	{ return false; }
339638fd1498Szrj      };
339738fd1498Szrj
339838fd1498Szrj      /**
339938fd1498Szrj       * @brief Constructs a uniform on sphere distribution.
340038fd1498Szrj       */
340138fd1498Szrj      explicit
340238fd1498Szrj      uniform_on_sphere_distribution()
340338fd1498Szrj      : _M_param(), _M_nd()
340438fd1498Szrj      { }
340538fd1498Szrj
340638fd1498Szrj      explicit
340738fd1498Szrj      uniform_on_sphere_distribution(const param_type& __p)
340838fd1498Szrj      : _M_param(__p), _M_nd()
340938fd1498Szrj      { }
341038fd1498Szrj
341138fd1498Szrj      /**
341238fd1498Szrj       * @brief Resets the distribution state.
341338fd1498Szrj       */
341438fd1498Szrj      void
341538fd1498Szrj      reset()
341638fd1498Szrj      { _M_nd.reset(); }
341738fd1498Szrj
341838fd1498Szrj      /**
341938fd1498Szrj       * @brief Returns the parameter set of the distribution.
342038fd1498Szrj       */
342138fd1498Szrj      param_type
342238fd1498Szrj      param() const
342338fd1498Szrj      { return _M_param; }
342438fd1498Szrj
342538fd1498Szrj      /**
342638fd1498Szrj       * @brief Sets the parameter set of the distribution.
342738fd1498Szrj       * @param __param The new parameter set of the distribution.
342838fd1498Szrj       */
342938fd1498Szrj      void
343038fd1498Szrj      param(const param_type& __param)
343138fd1498Szrj      { _M_param = __param; }
343238fd1498Szrj
343338fd1498Szrj      /**
343438fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
343538fd1498Szrj       * This function makes no sense for this distribution.
343638fd1498Szrj       */
343738fd1498Szrj      result_type
343838fd1498Szrj      min() const
343938fd1498Szrj      {
344038fd1498Szrj	result_type __res;
344138fd1498Szrj	__res.fill(0);
344238fd1498Szrj	return __res;
344338fd1498Szrj      }
344438fd1498Szrj
344538fd1498Szrj      /**
344638fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
344738fd1498Szrj       * This function makes no sense for this distribution.
344838fd1498Szrj       */
344938fd1498Szrj      result_type
345038fd1498Szrj      max() const
345138fd1498Szrj      {
345238fd1498Szrj	result_type __res;
345338fd1498Szrj	__res.fill(0);
345438fd1498Szrj	return __res;
345538fd1498Szrj      }
345638fd1498Szrj
345738fd1498Szrj      /**
345838fd1498Szrj       * @brief Generating functions.
345938fd1498Szrj       */
346038fd1498Szrj      template<typename _UniformRandomNumberGenerator>
346138fd1498Szrj	result_type
346238fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
346338fd1498Szrj	{ return this->operator()(__urng, _M_param); }
346438fd1498Szrj
346538fd1498Szrj      template<typename _UniformRandomNumberGenerator>
346638fd1498Szrj	result_type
346738fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
346838fd1498Szrj		   const param_type& __p);
346938fd1498Szrj
347038fd1498Szrj      template<typename _ForwardIterator,
347138fd1498Szrj	       typename _UniformRandomNumberGenerator>
347238fd1498Szrj	void
347338fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
347438fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
347538fd1498Szrj	{ this->__generate(__f, __t, __urng, this->param()); }
347638fd1498Szrj
347738fd1498Szrj      template<typename _ForwardIterator,
347838fd1498Szrj	       typename _UniformRandomNumberGenerator>
347938fd1498Szrj	void
348038fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
348138fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
348238fd1498Szrj		   const param_type& __p)
348338fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
348438fd1498Szrj
348538fd1498Szrj      template<typename _UniformRandomNumberGenerator>
348638fd1498Szrj	void
348738fd1498Szrj	__generate(result_type* __f, result_type* __t,
348838fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
348938fd1498Szrj		   const param_type& __p)
349038fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
349138fd1498Szrj
349238fd1498Szrj      /**
349338fd1498Szrj       * @brief Return true if two uniform on sphere distributions have
349438fd1498Szrj       *        the same parameters and the sequences that would be
349538fd1498Szrj       *        generated are equal.
349638fd1498Szrj       */
349738fd1498Szrj      friend bool
349838fd1498Szrj      operator==(const uniform_on_sphere_distribution& __d1,
349938fd1498Szrj		 const uniform_on_sphere_distribution& __d2)
350038fd1498Szrj      { return __d1._M_nd == __d2._M_nd; }
350138fd1498Szrj
350238fd1498Szrj      /**
350338fd1498Szrj       * @brief Inserts a %uniform_on_sphere_distribution random number
350438fd1498Szrj       *        distribution @p __x into the output stream @p __os.
350538fd1498Szrj       *
350638fd1498Szrj       * @param __os An output stream.
350738fd1498Szrj       * @param __x  A %uniform_on_sphere_distribution random number
350838fd1498Szrj       *             distribution.
350938fd1498Szrj       *
351038fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
351138fd1498Szrj       * an error state.
351238fd1498Szrj       */
351338fd1498Szrj      template<size_t _Dimen1, typename _RealType1, typename _CharT,
351438fd1498Szrj	       typename _Traits>
351538fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
351638fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
351738fd1498Szrj		   const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
351838fd1498Szrj								   _RealType1>&
351938fd1498Szrj		   __x);
352038fd1498Szrj
352138fd1498Szrj      /**
352238fd1498Szrj       * @brief Extracts a %uniform_on_sphere_distribution random number
352338fd1498Szrj       *        distribution
352438fd1498Szrj       * @p __x from the input stream @p __is.
352538fd1498Szrj       *
352638fd1498Szrj       * @param __is An input stream.
352738fd1498Szrj       * @param __x  A %uniform_on_sphere_distribution random number
352838fd1498Szrj       *             generator engine.
352938fd1498Szrj       *
353038fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
353138fd1498Szrj       */
353238fd1498Szrj      template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
353338fd1498Szrj	       typename _Traits>
353438fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
353538fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
353638fd1498Szrj		   __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
353738fd1498Szrj							     _RealType1>& __x);
353838fd1498Szrj
353938fd1498Szrj    private:
354038fd1498Szrj      template<typename _ForwardIterator,
354138fd1498Szrj	       typename _UniformRandomNumberGenerator>
354238fd1498Szrj	void
354338fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
354438fd1498Szrj			_UniformRandomNumberGenerator& __urng,
354538fd1498Szrj			const param_type& __p);
354638fd1498Szrj
354738fd1498Szrj      param_type _M_param;
354838fd1498Szrj      std::normal_distribution<_RealType> _M_nd;
354938fd1498Szrj    };
355038fd1498Szrj
355138fd1498Szrj  /**
355238fd1498Szrj   * @brief Return true if two uniform on sphere distributions are different.
355338fd1498Szrj   */
355438fd1498Szrj  template<std::size_t _Dimen, typename _RealType>
355538fd1498Szrj    inline bool
355638fd1498Szrj    operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
355738fd1498Szrj	       _RealType>& __d1,
355838fd1498Szrj	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
355938fd1498Szrj	       _RealType>& __d2)
356038fd1498Szrj    { return !(__d1 == __d2); }
356138fd1498Szrj
356238fd1498Szrj
356338fd1498Szrj  /**
356438fd1498Szrj   * @brief A distribution for random coordinates inside a unit sphere.
356538fd1498Szrj   */
356638fd1498Szrj  template<std::size_t _Dimen, typename _RealType = double>
356738fd1498Szrj    class uniform_inside_sphere_distribution
356838fd1498Szrj    {
356938fd1498Szrj      static_assert(std::is_floating_point<_RealType>::value,
357038fd1498Szrj		    "template argument not a floating point type");
357138fd1498Szrj      static_assert(_Dimen != 0, "dimension is zero");
357238fd1498Szrj
357338fd1498Szrj    public:
357438fd1498Szrj      /** The type of the range of the distribution. */
357538fd1498Szrj      using result_type = std::array<_RealType, _Dimen>;
357638fd1498Szrj
357738fd1498Szrj      /** Parameter type. */
357838fd1498Szrj      struct param_type
357938fd1498Szrj      {
358038fd1498Szrj	using distribution_type
358138fd1498Szrj	  = uniform_inside_sphere_distribution<_Dimen, _RealType>;
358238fd1498Szrj	friend class uniform_inside_sphere_distribution<_Dimen, _RealType>;
358338fd1498Szrj
358438fd1498Szrj	explicit
358538fd1498Szrj	param_type(_RealType __radius = _RealType(1))
358638fd1498Szrj	: _M_radius(__radius)
358738fd1498Szrj	{
358838fd1498Szrj	  __glibcxx_assert(_M_radius > _RealType(0));
358938fd1498Szrj	}
359038fd1498Szrj
359138fd1498Szrj	_RealType
359238fd1498Szrj	radius() const
359338fd1498Szrj	{ return _M_radius; }
359438fd1498Szrj
359538fd1498Szrj	friend bool
359638fd1498Szrj	operator==(const param_type& __p1, const param_type& __p2)
359738fd1498Szrj	{ return __p1._M_radius == __p2._M_radius; }
359838fd1498Szrj
359938fd1498Szrj	friend bool
360038fd1498Szrj	operator!=(const param_type& __p1, const param_type& __p2)
360138fd1498Szrj	{ return !(__p1 == __p2); }
360238fd1498Szrj
360338fd1498Szrj      private:
360438fd1498Szrj	_RealType _M_radius;
360538fd1498Szrj      };
360638fd1498Szrj
360738fd1498Szrj      /**
360838fd1498Szrj       * @brief Constructors.
360938fd1498Szrj       */
361038fd1498Szrj      explicit
361138fd1498Szrj      uniform_inside_sphere_distribution(_RealType __radius = _RealType(1))
361238fd1498Szrj      : _M_param(__radius), _M_uosd()
361338fd1498Szrj      { }
361438fd1498Szrj
361538fd1498Szrj      explicit
361638fd1498Szrj      uniform_inside_sphere_distribution(const param_type& __p)
361738fd1498Szrj      : _M_param(__p), _M_uosd()
361838fd1498Szrj      { }
361938fd1498Szrj
362038fd1498Szrj      /**
362138fd1498Szrj       * @brief Resets the distribution state.
362238fd1498Szrj       */
362338fd1498Szrj      void
362438fd1498Szrj      reset()
362538fd1498Szrj      { _M_uosd.reset(); }
362638fd1498Szrj
362738fd1498Szrj      /**
362838fd1498Szrj       * @brief Returns the @f$radius@f$ of the distribution.
362938fd1498Szrj       */
363038fd1498Szrj      _RealType
363138fd1498Szrj      radius() const
363238fd1498Szrj      { return _M_param.radius(); }
363338fd1498Szrj
363438fd1498Szrj      /**
363538fd1498Szrj       * @brief Returns the parameter set of the distribution.
363638fd1498Szrj       */
363738fd1498Szrj      param_type
363838fd1498Szrj      param() const
363938fd1498Szrj      { return _M_param; }
364038fd1498Szrj
364138fd1498Szrj      /**
364238fd1498Szrj       * @brief Sets the parameter set of the distribution.
364338fd1498Szrj       * @param __param The new parameter set of the distribution.
364438fd1498Szrj       */
364538fd1498Szrj      void
364638fd1498Szrj      param(const param_type& __param)
364738fd1498Szrj      { _M_param = __param; }
364838fd1498Szrj
364938fd1498Szrj      /**
365038fd1498Szrj       * @brief Returns the greatest lower bound value of the distribution.
365138fd1498Szrj       * This function makes no sense for this distribution.
365238fd1498Szrj       */
365338fd1498Szrj      result_type
365438fd1498Szrj      min() const
365538fd1498Szrj      {
365638fd1498Szrj	result_type __res;
365738fd1498Szrj	__res.fill(0);
365838fd1498Szrj	return __res;
365938fd1498Szrj      }
366038fd1498Szrj
366138fd1498Szrj      /**
366238fd1498Szrj       * @brief Returns the least upper bound value of the distribution.
366338fd1498Szrj       * This function makes no sense for this distribution.
366438fd1498Szrj       */
366538fd1498Szrj      result_type
366638fd1498Szrj      max() const
366738fd1498Szrj      {
366838fd1498Szrj	result_type __res;
366938fd1498Szrj	__res.fill(0);
367038fd1498Szrj	return __res;
367138fd1498Szrj      }
367238fd1498Szrj
367338fd1498Szrj      /**
367438fd1498Szrj       * @brief Generating functions.
367538fd1498Szrj       */
367638fd1498Szrj      template<typename _UniformRandomNumberGenerator>
367738fd1498Szrj	result_type
367838fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng)
367938fd1498Szrj	{ return this->operator()(__urng, _M_param); }
368038fd1498Szrj
368138fd1498Szrj      template<typename _UniformRandomNumberGenerator>
368238fd1498Szrj	result_type
368338fd1498Szrj	operator()(_UniformRandomNumberGenerator& __urng,
368438fd1498Szrj		   const param_type& __p);
368538fd1498Szrj
368638fd1498Szrj      template<typename _ForwardIterator,
368738fd1498Szrj	       typename _UniformRandomNumberGenerator>
368838fd1498Szrj	void
368938fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
369038fd1498Szrj		   _UniformRandomNumberGenerator& __urng)
369138fd1498Szrj	{ this->__generate(__f, __t, __urng, this->param()); }
369238fd1498Szrj
369338fd1498Szrj      template<typename _ForwardIterator,
369438fd1498Szrj	       typename _UniformRandomNumberGenerator>
369538fd1498Szrj	void
369638fd1498Szrj	__generate(_ForwardIterator __f, _ForwardIterator __t,
369738fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
369838fd1498Szrj		   const param_type& __p)
369938fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
370038fd1498Szrj
370138fd1498Szrj      template<typename _UniformRandomNumberGenerator>
370238fd1498Szrj	void
370338fd1498Szrj	__generate(result_type* __f, result_type* __t,
370438fd1498Szrj		   _UniformRandomNumberGenerator& __urng,
370538fd1498Szrj		   const param_type& __p)
370638fd1498Szrj	{ this->__generate_impl(__f, __t, __urng, __p); }
370738fd1498Szrj
370838fd1498Szrj      /**
370938fd1498Szrj       * @brief Return true if two uniform on sphere distributions have
371038fd1498Szrj       *        the same parameters and the sequences that would be
371138fd1498Szrj       *        generated are equal.
371238fd1498Szrj       */
371338fd1498Szrj      friend bool
371438fd1498Szrj      operator==(const uniform_inside_sphere_distribution& __d1,
371538fd1498Szrj		 const uniform_inside_sphere_distribution& __d2)
371638fd1498Szrj      { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; }
371738fd1498Szrj
371838fd1498Szrj      /**
371938fd1498Szrj       * @brief Inserts a %uniform_inside_sphere_distribution random number
372038fd1498Szrj       *        distribution @p __x into the output stream @p __os.
372138fd1498Szrj       *
372238fd1498Szrj       * @param __os An output stream.
372338fd1498Szrj       * @param __x  A %uniform_inside_sphere_distribution random number
372438fd1498Szrj       *             distribution.
372538fd1498Szrj       *
372638fd1498Szrj       * @returns The output stream with the state of @p __x inserted or in
372738fd1498Szrj       * an error state.
372838fd1498Szrj       */
372938fd1498Szrj      template<size_t _Dimen1, typename _RealType1, typename _CharT,
373038fd1498Szrj	       typename _Traits>
373138fd1498Szrj	friend std::basic_ostream<_CharT, _Traits>&
373238fd1498Szrj	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
373338fd1498Szrj		   const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1,
373438fd1498Szrj								   _RealType1>&
373538fd1498Szrj		   );
373638fd1498Szrj
373738fd1498Szrj      /**
373838fd1498Szrj       * @brief Extracts a %uniform_inside_sphere_distribution random number
373938fd1498Szrj       *        distribution
374038fd1498Szrj       * @p __x from the input stream @p __is.
374138fd1498Szrj       *
374238fd1498Szrj       * @param __is An input stream.
374338fd1498Szrj       * @param __x  A %uniform_inside_sphere_distribution random number
374438fd1498Szrj       *             generator engine.
374538fd1498Szrj       *
374638fd1498Szrj       * @returns The input stream with @p __x extracted or in an error state.
374738fd1498Szrj       */
374838fd1498Szrj      template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
374938fd1498Szrj	       typename _Traits>
375038fd1498Szrj	friend std::basic_istream<_CharT, _Traits>&
375138fd1498Szrj	operator>>(std::basic_istream<_CharT, _Traits>& __is,
375238fd1498Szrj		   __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1,
375338fd1498Szrj								 _RealType1>&);
375438fd1498Szrj
375538fd1498Szrj    private:
375638fd1498Szrj      template<typename _ForwardIterator,
375738fd1498Szrj	       typename _UniformRandomNumberGenerator>
375838fd1498Szrj	void
375938fd1498Szrj	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
376038fd1498Szrj			_UniformRandomNumberGenerator& __urng,
376138fd1498Szrj			const param_type& __p);
376238fd1498Szrj
376338fd1498Szrj      param_type _M_param;
376438fd1498Szrj      uniform_on_sphere_distribution<_Dimen, _RealType> _M_uosd;
376538fd1498Szrj    };
376638fd1498Szrj
376738fd1498Szrj  /**
376838fd1498Szrj   * @brief Return true if two uniform on sphere distributions are different.
376938fd1498Szrj   */
377038fd1498Szrj  template<std::size_t _Dimen, typename _RealType>
377138fd1498Szrj    inline bool
377238fd1498Szrj    operator!=(const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen,
377338fd1498Szrj	       _RealType>& __d1,
377438fd1498Szrj	       const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen,
377538fd1498Szrj	       _RealType>& __d2)
377638fd1498Szrj    { return !(__d1 == __d2); }
377738fd1498Szrj
377838fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION
377938fd1498Szrj} // namespace __gnu_cxx
378038fd1498Szrj
3781*58e805e6Szrj#include <ext/opt_random.h>
3782*58e805e6Szrj#include <ext/random.tcc>
378338fd1498Szrj
378438fd1498Szrj#endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C
378538fd1498Szrj
378638fd1498Szrj#endif // C++11
378738fd1498Szrj
378838fd1498Szrj#endif // _EXT_RANDOM
3789