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