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