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