1 // Random number extensions -*- C++ -*-
3 // Copyright (C) 2012 Free Software Foundation, Inc.
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)
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.
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.
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/>.
26 * This file is a GNU extension to the Standard C++ Library.
32 #pragma GCC system_header
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
41 # include <x86intrin.h>
44 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
46 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
52 /* Mersenne twister implementation optimized for vector operations.
54 * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
56 template<typename _UIntType, size_t __m,
57 size_t __pos1, size_t __sl1, size_t __sl2,
58 size_t __sr1, size_t __sr2,
59 uint32_t __msk1, uint32_t __msk2,
60 uint32_t __msk3, uint32_t __msk4,
61 uint32_t __parity1, uint32_t __parity2,
62 uint32_t __parity3, uint32_t __parity4>
63 class simd_fast_mersenne_twister_engine
65 static_assert(std::is_unsigned<_UIntType>::value, "template argument "
66 "substituting _UIntType not an unsigned integral type");
67 static_assert(__sr1 < 32, "first right shift too large");
68 static_assert(__sr2 < 16, "second right shift too large");
69 static_assert(__sl1 < 32, "first left shift too large");
70 static_assert(__sl2 < 16, "second left shift too large");
73 typedef _UIntType result_type;
76 static constexpr size_t m_w = sizeof(result_type) * 8;
77 static constexpr size_t _M_nstate = __m / 128 + 1;
78 static constexpr size_t _M_nstate32 = _M_nstate * 4;
80 static_assert(std::is_unsigned<_UIntType>::value, "template argument "
81 "substituting _UIntType not an unsigned integral type");
82 static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size");
83 static_assert(16 % sizeof(_UIntType) == 0,
84 "UIntType size must divide 16");
87 static constexpr size_t state_size = _M_nstate * (16
88 / sizeof(result_type));
89 static constexpr result_type default_seed = 5489u;
91 // constructors and member function
93 simd_fast_mersenne_twister_engine(result_type __sd = default_seed)
96 template<typename _Sseq, typename = typename
97 std::enable_if<!std::is_same<_Sseq,
98 simd_fast_mersenne_twister_engine>::value>
101 simd_fast_mersenne_twister_engine(_Sseq& __q)
105 seed(result_type __sd = default_seed);
107 template<typename _Sseq>
108 typename std::enable_if<std::is_class<_Sseq>::value>::type
111 static constexpr result_type
115 static constexpr result_type
117 { return std::numeric_limits<result_type>::max(); }
120 discard(unsigned long long __z);
125 if (__builtin_expect(_M_pos >= state_size, 0))
128 return _M_stateT[_M_pos++];
131 template<typename _UIntType_2, size_t __m_2,
132 size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
133 size_t __sr1_2, size_t __sr2_2,
134 uint32_t __msk1_2, uint32_t __msk2_2,
135 uint32_t __msk3_2, uint32_t __msk4_2,
136 uint32_t __parity1_2, uint32_t __parity2_2,
137 uint32_t __parity3_2, uint32_t __parity4_2>
139 operator==(const simd_fast_mersenne_twister_engine<_UIntType_2,
140 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
141 __msk1_2, __msk2_2, __msk3_2, __msk4_2,
142 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs,
143 const simd_fast_mersenne_twister_engine<_UIntType_2,
144 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
145 __msk1_2, __msk2_2, __msk3_2, __msk4_2,
146 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs);
148 template<typename _UIntType_2, size_t __m_2,
149 size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
150 size_t __sr1_2, size_t __sr2_2,
151 uint32_t __msk1_2, uint32_t __msk2_2,
152 uint32_t __msk3_2, uint32_t __msk4_2,
153 uint32_t __parity1_2, uint32_t __parity2_2,
154 uint32_t __parity3_2, uint32_t __parity4_2,
155 typename _CharT, typename _Traits>
156 friend std::basic_ostream<_CharT, _Traits>&
157 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
158 const __gnu_cxx::simd_fast_mersenne_twister_engine
160 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
161 __msk1_2, __msk2_2, __msk3_2, __msk4_2,
162 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
164 template<typename _UIntType_2, size_t __m_2,
165 size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
166 size_t __sr1_2, size_t __sr2_2,
167 uint32_t __msk1_2, uint32_t __msk2_2,
168 uint32_t __msk3_2, uint32_t __msk4_2,
169 uint32_t __parity1_2, uint32_t __parity2_2,
170 uint32_t __parity3_2, uint32_t __parity4_2,
171 typename _CharT, typename _Traits>
172 friend std::basic_istream<_CharT, _Traits>&
173 operator>>(std::basic_istream<_CharT, _Traits>& __is,
174 __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2,
175 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
176 __msk1_2, __msk2_2, __msk3_2, __msk4_2,
177 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
183 __m128i _M_state[_M_nstate];
185 uint32_t _M_state32[_M_nstate32];
186 result_type _M_stateT[state_size];
187 } __attribute__ ((__aligned__ (16)));
190 void _M_gen_rand(void);
191 void _M_period_certification();
195 template<typename _UIntType, size_t __m,
196 size_t __pos1, size_t __sl1, size_t __sl2,
197 size_t __sr1, size_t __sr2,
198 uint32_t __msk1, uint32_t __msk2,
199 uint32_t __msk3, uint32_t __msk4,
200 uint32_t __parity1, uint32_t __parity2,
201 uint32_t __parity3, uint32_t __parity4>
203 operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
204 __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
205 __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs,
206 const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
207 __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
208 __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs)
209 { return !(__lhs == __rhs); }
212 /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined
213 * in the C implementation by Daito and Matsumoto, as both a 32-bit
214 * and 64-bit version.
216 typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2,
218 0xfdff37ffU, 0xef7f3f7dU,
219 0xff777b7dU, 0x7ff7fb2fU,
220 0x00000001U, 0x00000000U,
221 0x00000000U, 0x5986f054U>
224 typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2,
226 0xfdff37ffU, 0xef7f3f7dU,
227 0xff777b7dU, 0x7ff7fb2fU,
228 0x00000001U, 0x00000000U,
229 0x00000000U, 0x5986f054U>
233 typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7,
235 0xf7fefffdU, 0x7fefcfffU,
236 0xaff3ef3fU, 0xb5ffff7fU,
237 0x00000001U, 0x00000000U,
238 0x00000000U, 0x20000000U>
241 typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7,
243 0xf7fefffdU, 0x7fefcfffU,
244 0xaff3ef3fU, 0xb5ffff7fU,
245 0x00000001U, 0x00000000U,
246 0x00000000U, 0x20000000U>
250 typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12,
252 0xbff7ffbfU, 0xfdfffffeU,
253 0xf7ffef7fU, 0xf2f7cbbfU,
254 0x00000001U, 0x00000000U,
255 0x00000000U, 0x41dfa600U>
258 typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12,
260 0xbff7ffbfU, 0xfdfffffeU,
261 0xf7ffef7fU, 0xf2f7cbbfU,
262 0x00000001U, 0x00000000U,
263 0x00000000U, 0x41dfa600U>
267 typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17,
269 0x9f7bffffU, 0x9fffff5fU,
270 0x3efffffbU, 0xfffff7bbU,
271 0xa8000001U, 0xaf5390a3U,
272 0xb740b3f8U, 0x6c11486dU>
275 typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17,
277 0x9f7bffffU, 0x9fffff5fU,
278 0x3efffffbU, 0xfffff7bbU,
279 0xa8000001U, 0xaf5390a3U,
280 0xb740b3f8U, 0x6c11486dU>
284 typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68,
286 0xeffff7fbU, 0xffffffefU,
287 0xdfdfbfffU, 0x7fffdbfdU,
288 0x00000001U, 0x00000000U,
289 0xe8148000U, 0xd0c7afa3U>
292 typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68,
294 0xeffff7fbU, 0xffffffefU,
295 0xdfdfbfffU, 0x7fffdbfdU,
296 0x00000001U, 0x00000000U,
297 0xe8148000U, 0xd0c7afa3U>
301 typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122,
303 0xdfffffefU, 0xddfecb7fU,
304 0xbffaffffU, 0xbffffff6U,
305 0x00000001U, 0x00000000U,
306 0x00000000U, 0x13c9e684U>
309 typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122,
311 0xdfffffefU, 0xddfecb7fU,
312 0xbffaffffU, 0xbffffff6U,
313 0x00000001U, 0x00000000U,
314 0x00000000U, 0x13c9e684U>
318 typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330,
320 0xeffffffbU, 0xdfbebfffU,
321 0xbfbf7befU, 0x9ffd7bffU,
322 0x00000001U, 0x00000000U,
323 0xa3ac4000U, 0xecc1327aU>
326 typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330,
328 0xeffffffbU, 0xdfbebfffU,
329 0xbfbf7befU, 0x9ffd7bffU,
330 0x00000001U, 0x00000000U,
331 0xa3ac4000U, 0xecc1327aU>
335 typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366,
337 0xfdbffbffU, 0xbff7ff3fU,
338 0xfd77efffU, 0xbf9ff3ffU,
339 0x00000001U, 0x00000000U,
340 0x00000000U, 0xe9528d85U>
343 typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366,
345 0xfdbffbffU, 0xbff7ff3fU,
346 0xfd77efffU, 0xbf9ff3ffU,
347 0x00000001U, 0x00000000U,
348 0x00000000U, 0xe9528d85U>
352 typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110,
354 0xffffbb5fU, 0xfb6ebf95U,
355 0xfffefffaU, 0xcff77fffU,
356 0x00000001U, 0x00000000U,
357 0xcb520000U, 0xc7e91c7dU>
360 typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110,
362 0xffffbb5fU, 0xfb6ebf95U,
363 0xfffefffaU, 0xcff77fffU,
364 0x00000001U, 0x00000000U,
365 0xcb520000U, 0xc7e91c7dU>
369 typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627,
371 0xbff7bff7U, 0xbfffffffU,
372 0xbffffa7fU, 0xffddfbfbU,
373 0xf8000001U, 0x89e80709U,
374 0x3bd2b64bU, 0x0c64b1e4U>
377 typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627,
379 0xbff7bff7U, 0xbfffffffU,
380 0xbffffa7fU, 0xffddfbfbU,
381 0xf8000001U, 0x89e80709U,
382 0x3bd2b64bU, 0x0c64b1e4U>
385 #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
388 * @brief A beta continuous distribution for random numbers.
390 * The formula for the beta probability density function is:
392 * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)}
393 * x^{\alpha - 1} (1 - x)^{\beta - 1}
396 template<typename _RealType = double>
397 class beta_distribution
399 static_assert(std::is_floating_point<_RealType>::value,
400 "template argument not a floating point type");
403 /** The type of the range of the distribution. */
404 typedef _RealType result_type;
405 /** Parameter type. */
408 typedef beta_distribution<_RealType> distribution_type;
409 friend class beta_distribution<_RealType>;
412 param_type(_RealType __alpha_val = _RealType(1),
413 _RealType __beta_val = _RealType(1))
414 : _M_alpha(__alpha_val), _M_beta(__beta_val)
416 _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
417 _GLIBCXX_DEBUG_ASSERT(_M_beta > _RealType(0));
429 operator==(const param_type& __p1, const param_type& __p2)
430 { return (__p1._M_alpha == __p2._M_alpha
431 && __p1._M_beta == __p2._M_beta); }
443 * @brief Constructs a beta distribution with parameters
444 * @f$\alpha@f$ and @f$\beta@f$.
447 beta_distribution(_RealType __alpha_val = _RealType(1),
448 _RealType __beta_val = _RealType(1))
449 : _M_param(__alpha_val, __beta_val)
453 beta_distribution(const param_type& __p)
458 * @brief Resets the distribution state.
465 * @brief Returns the @f$\alpha@f$ of the distribution.
469 { return _M_param.alpha(); }
472 * @brief Returns the @f$\beta@f$ of the distribution.
476 { return _M_param.beta(); }
479 * @brief Returns the parameter set of the distribution.
486 * @brief Sets the parameter set of the distribution.
487 * @param __param The new parameter set of the distribution.
490 param(const param_type& __param)
491 { _M_param = __param; }
494 * @brief Returns the greatest lower bound value of the distribution.
498 { return result_type(0); }
501 * @brief Returns the least upper bound value of the distribution.
505 { return result_type(1); }
508 * @brief Generating functions.
510 template<typename _UniformRandomNumberGenerator>
512 operator()(_UniformRandomNumberGenerator& __urng)
513 { return this->operator()(__urng, this->param()); }
515 template<typename _UniformRandomNumberGenerator>
517 operator()(_UniformRandomNumberGenerator& __urng,
518 const param_type& __p);
520 template<typename _ForwardIterator,
521 typename _UniformRandomNumberGenerator>
523 __generate(_ForwardIterator __f, _ForwardIterator __t,
524 _UniformRandomNumberGenerator& __urng)
525 { this->__generate(__f, __t, __urng, this->param()); }
527 template<typename _ForwardIterator,
528 typename _UniformRandomNumberGenerator>
530 __generate(_ForwardIterator __f, _ForwardIterator __t,
531 _UniformRandomNumberGenerator& __urng,
532 const param_type& __p)
533 { this->__generate_impl(__f, __t, __urng, __p); }
535 template<typename _UniformRandomNumberGenerator>
537 __generate(result_type* __f, result_type* __t,
538 _UniformRandomNumberGenerator& __urng,
539 const param_type& __p)
540 { this->__generate_impl(__f, __t, __urng, __p); }
543 * @brief Inserts a %beta_distribution random number distribution
544 * @p __x into the output stream @p __os.
546 * @param __os An output stream.
547 * @param __x A %beta_distribution random number distribution.
549 * @returns The output stream with the state of @p __x inserted or in
552 template<typename _RealType1, typename _CharT, typename _Traits>
553 friend std::basic_ostream<_CharT, _Traits>&
554 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
555 const __gnu_cxx::beta_distribution<_RealType1>& __x);
558 * @brief Extracts a %beta_distribution random number distribution
559 * @p __x from the input stream @p __is.
561 * @param __is An input stream.
562 * @param __x A %beta_distribution random number generator engine.
564 * @returns The input stream with @p __x extracted or in an error state.
566 template<typename _RealType1, typename _CharT, typename _Traits>
567 friend std::basic_istream<_CharT, _Traits>&
568 operator>>(std::basic_istream<_CharT, _Traits>& __is,
569 __gnu_cxx::beta_distribution<_RealType1>& __x);
572 template<typename _ForwardIterator,
573 typename _UniformRandomNumberGenerator>
575 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
576 _UniformRandomNumberGenerator& __urng,
577 const param_type& __p);
583 * @brief Return true if two beta distributions have the same
584 * parameters and the sequences that would be generated
587 template<typename _RealType>
589 operator==(const __gnu_cxx::beta_distribution<_RealType>& __d1,
590 const __gnu_cxx::beta_distribution<_RealType>& __d2)
591 { return __d1.param() == __d2.param(); }
594 * @brief Return true if two beta distributions are different.
596 template<typename _RealType>
598 operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
599 const __gnu_cxx::beta_distribution<_RealType>& __d2)
600 { return !(__d1 == __d2); }
604 * @brief A multi-variate normal continuous distribution for random numbers.
606 * The formula for the normal probability density function is
608 * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) =
609 * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}}
610 * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T}
611 * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})}
614 * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are
615 * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance
616 * matrix (which must be positive-definite).
618 template<std::size_t _Dimen, typename _RealType = double>
619 class normal_mv_distribution
621 static_assert(std::is_floating_point<_RealType>::value,
622 "template argument not a floating point type");
623 static_assert(_Dimen != 0, "dimension is zero");
626 /** The type of the range of the distribution. */
627 typedef std::array<_RealType, _Dimen> result_type;
628 /** Parameter type. */
631 static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2;
634 typedef normal_mv_distribution<_Dimen, _RealType> distribution_type;
635 friend class normal_mv_distribution<_Dimen, _RealType>;
639 std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0));
640 auto __it = _M_t.begin();
641 for (size_t __i = 0; __i < _Dimen; ++__i)
643 std::fill_n(__it, __i, _RealType(0));
645 *__it++ = _RealType(1);
649 template<typename _ForwardIterator1, typename _ForwardIterator2>
650 param_type(_ForwardIterator1 __meanbegin,
651 _ForwardIterator1 __meanend,
652 _ForwardIterator2 __varcovbegin,
653 _ForwardIterator2 __varcovend)
655 __glibcxx_function_requires(_ForwardIteratorConcept<
657 __glibcxx_function_requires(_ForwardIteratorConcept<
659 _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend)
661 const auto __dist = std::distance(__varcovbegin, __varcovend);
662 _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen
663 || __dist == _Dimen * (_Dimen + 1) / 2
664 || __dist == _Dimen);
666 if (__dist == _Dimen * _Dimen)
667 _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend);
668 else if (__dist == _Dimen * (_Dimen + 1) / 2)
669 _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend);
671 _M_init_diagonal(__meanbegin, __meanend,
672 __varcovbegin, __varcovend);
675 param_type(std::initializer_list<_RealType> __mean,
676 std::initializer_list<_RealType> __varcov)
678 _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen);
679 _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen
680 || __varcov.size() == _Dimen * (_Dimen + 1) / 2
681 || __varcov.size() == _Dimen);
683 if (__varcov.size() == _Dimen * _Dimen)
684 _M_init_full(__mean.begin(), __mean.end(),
685 __varcov.begin(), __varcov.end());
686 else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2)
687 _M_init_lower(__mean.begin(), __mean.end(),
688 __varcov.begin(), __varcov.end());
690 _M_init_diagonal(__mean.begin(), __mean.end(),
691 __varcov.begin(), __varcov.end());
694 std::array<_RealType, _Dimen>
698 std::array<_RealType, _M_t_size>
703 operator==(const param_type& __p1, const param_type& __p2)
704 { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; }
707 template <typename _InputIterator1, typename _InputIterator2>
708 void _M_init_full(_InputIterator1 __meanbegin,
709 _InputIterator1 __meanend,
710 _InputIterator2 __varcovbegin,
711 _InputIterator2 __varcovend);
712 template <typename _InputIterator1, typename _InputIterator2>
713 void _M_init_lower(_InputIterator1 __meanbegin,
714 _InputIterator1 __meanend,
715 _InputIterator2 __varcovbegin,
716 _InputIterator2 __varcovend);
717 template <typename _InputIterator1, typename _InputIterator2>
718 void _M_init_diagonal(_InputIterator1 __meanbegin,
719 _InputIterator1 __meanend,
720 _InputIterator2 __varbegin,
721 _InputIterator2 __varend);
723 std::array<_RealType, _Dimen> _M_mean;
724 std::array<_RealType, _M_t_size> _M_t;
728 normal_mv_distribution()
729 : _M_param(), _M_nd()
732 template<typename _ForwardIterator1, typename _ForwardIterator2>
733 normal_mv_distribution(_ForwardIterator1 __meanbegin,
734 _ForwardIterator1 __meanend,
735 _ForwardIterator2 __varcovbegin,
736 _ForwardIterator2 __varcovend)
737 : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend),
741 normal_mv_distribution(std::initializer_list<_RealType> __mean,
742 std::initializer_list<_RealType> __varcov)
743 : _M_param(__mean, __varcov), _M_nd()
747 normal_mv_distribution(const param_type& __p)
748 : _M_param(__p), _M_nd()
752 * @brief Resets the distribution state.
759 * @brief Returns the mean of the distribution.
763 { return _M_param.mean(); }
766 * @brief Returns the compact form of the variance/covariance
767 * matrix of the distribution.
769 std::array<_RealType, _Dimen * (_Dimen + 1) / 2>
771 { return _M_param.varcov(); }
774 * @brief Returns the parameter set of the distribution.
781 * @brief Sets the parameter set of the distribution.
782 * @param __param The new parameter set of the distribution.
785 param(const param_type& __param)
786 { _M_param = __param; }
789 * @brief Returns the greatest lower bound value of the distribution.
794 __res.fill(std::numeric_limits<_RealType>::min());
798 * @brief Returns the least upper bound value of the distribution.
803 __res.fill(std::numeric_limits<_RealType>::max());
807 * @brief Generating functions.
809 template<typename _UniformRandomNumberGenerator>
811 operator()(_UniformRandomNumberGenerator& __urng)
812 { return this->operator()(__urng, this->param()); }
814 template<typename _UniformRandomNumberGenerator>
816 operator()(_UniformRandomNumberGenerator& __urng,
817 const param_type& __p);
819 template<typename _ForwardIterator,
820 typename _UniformRandomNumberGenerator>
822 __generate(_ForwardIterator __f, _ForwardIterator __t,
823 _UniformRandomNumberGenerator& __urng)
824 { return this->__generate_impl(__f, __t, __urng, this->param()); }
826 template<typename _ForwardIterator,
827 typename _UniformRandomNumberGenerator>
829 __generate(_ForwardIterator __f, _ForwardIterator __t,
830 _UniformRandomNumberGenerator& __urng,
831 const param_type& __p)
832 { return this->__generate_impl(__f, __t, __urng, __p); }
835 * @brief Return true if two multi-variant normal distributions have
836 * the same parameters and the sequences that would
837 * be generated are equal.
839 template<size_t _Dimen1, typename _RealType1>
842 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
845 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
849 * @brief Inserts a %normal_mv_distribution random number distribution
850 * @p __x into the output stream @p __os.
852 * @param __os An output stream.
853 * @param __x A %normal_mv_distribution random number distribution.
855 * @returns The output stream with the state of @p __x inserted or in
858 template<size_t _Dimen1, typename _RealType1,
859 typename _CharT, typename _Traits>
860 friend std::basic_ostream<_CharT, _Traits>&
861 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
863 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
867 * @brief Extracts a %normal_mv_distribution random number distribution
868 * @p __x from the input stream @p __is.
870 * @param __is An input stream.
871 * @param __x A %normal_mv_distribution random number generator engine.
873 * @returns The input stream with @p __x extracted or in an error
876 template<size_t _Dimen1, typename _RealType1,
877 typename _CharT, typename _Traits>
878 friend std::basic_istream<_CharT, _Traits>&
879 operator>>(std::basic_istream<_CharT, _Traits>& __is,
880 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
884 template<typename _ForwardIterator,
885 typename _UniformRandomNumberGenerator>
887 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
888 _UniformRandomNumberGenerator& __urng,
889 const param_type& __p);
892 std::normal_distribution<_RealType> _M_nd;
896 * @brief Return true if two multi-variate normal distributions are
899 template<size_t _Dimen, typename _RealType>
901 operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
903 const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
905 { return !(__d1 == __d2); }
909 * @brief A Rice continuous distribution for random numbers.
911 * The formula for the Rice probability density function is
913 * p(x|\nu,\sigma) = \frac{x}{\sigma^2}
914 * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right)
915 * I_0\left(\frac{x \nu}{\sigma^2}\right)
917 * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
918 * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$.
920 * <table border=1 cellpadding=10 cellspacing=0>
921 * <caption align=top>Distribution Statistics</caption>
922 * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
923 * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2
924 * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
925 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
927 * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2.
929 template<typename _RealType = double>
933 static_assert(std::is_floating_point<_RealType>::value,
934 "template argument not a floating point type");
936 /** The type of the range of the distribution. */
937 typedef _RealType result_type;
938 /** Parameter type. */
941 typedef rice_distribution<result_type> distribution_type;
943 param_type(result_type __nu_val = result_type(0),
944 result_type __sigma_val = result_type(1))
945 : _M_nu(__nu_val), _M_sigma(__sigma_val)
947 _GLIBCXX_DEBUG_ASSERT(_M_nu >= result_type(0));
948 _GLIBCXX_DEBUG_ASSERT(_M_sigma > result_type(0));
960 operator==(const param_type& __p1, const param_type& __p2)
961 { return __p1._M_nu == __p2._M_nu
962 && __p1._M_sigma == __p2._M_sigma; }
965 void _M_initialize();
968 result_type _M_sigma;
972 * @brief Constructors.
975 rice_distribution(result_type __nu_val = result_type(0),
976 result_type __sigma_val = result_type(1))
977 : _M_param(__nu_val, __sigma_val),
978 _M_ndx(__nu_val, __sigma_val),
979 _M_ndy(result_type(0), __sigma_val)
983 rice_distribution(const param_type& __p)
985 _M_ndx(__p.nu(), __p.sigma()),
986 _M_ndy(result_type(0), __p.sigma())
990 * @brief Resets the distribution state.
1000 * @brief Return the parameters of the distribution.
1004 { return _M_param.nu(); }
1008 { return _M_param.sigma(); }
1011 * @brief Returns the parameter set of the distribution.
1015 { return _M_param; }
1018 * @brief Sets the parameter set of the distribution.
1019 * @param __param The new parameter set of the distribution.
1022 param(const param_type& __param)
1023 { _M_param = __param; }
1026 * @brief Returns the greatest lower bound value of the distribution.
1030 { return result_type(0); }
1033 * @brief Returns the least upper bound value of the distribution.
1037 { return std::numeric_limits<result_type>::max(); }
1040 * @brief Generating functions.
1042 template<typename _UniformRandomNumberGenerator>
1044 operator()(_UniformRandomNumberGenerator& __urng)
1046 result_type __x = this->_M_ndx(__urng);
1047 result_type __y = this->_M_ndy(__urng);
1048 #if _GLIBCXX_USE_C99_MATH_TR1
1049 return std::hypot(__x, __y);
1051 return std::sqrt(__x * __x + __y * __y);
1055 template<typename _UniformRandomNumberGenerator>
1057 operator()(_UniformRandomNumberGenerator& __urng,
1058 const param_type& __p)
1060 typename std::normal_distribution<result_type>::param_type
1061 __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
1062 result_type __x = this->_M_ndx(__px, __urng);
1063 result_type __y = this->_M_ndy(__py, __urng);
1064 #if _GLIBCXX_USE_C99_MATH_TR1
1065 return std::hypot(__x, __y);
1067 return std::sqrt(__x * __x + __y * __y);
1071 template<typename _ForwardIterator,
1072 typename _UniformRandomNumberGenerator>
1074 __generate(_ForwardIterator __f, _ForwardIterator __t,
1075 _UniformRandomNumberGenerator& __urng)
1076 { this->__generate(__f, __t, __urng, this->param()); }
1078 template<typename _ForwardIterator,
1079 typename _UniformRandomNumberGenerator>
1081 __generate(_ForwardIterator __f, _ForwardIterator __t,
1082 _UniformRandomNumberGenerator& __urng,
1083 const param_type& __p)
1084 { this->__generate_impl(__f, __t, __urng, __p); }
1086 template<typename _UniformRandomNumberGenerator>
1088 __generate(result_type* __f, result_type* __t,
1089 _UniformRandomNumberGenerator& __urng,
1090 const param_type& __p)
1091 { this->__generate_impl(__f, __t, __urng, __p); }
1094 * @brief Return true if two Rice distributions have
1095 * the same parameters and the sequences that would
1096 * be generated are equal.
1099 operator==(const rice_distribution& __d1,
1100 const rice_distribution& __d2)
1101 { return (__d1.param() == __d2.param()
1102 && __d1._M_ndx == __d2._M_ndx
1103 && __d1._M_ndy == __d2._M_ndy); }
1106 * @brief Inserts a %rice_distribution random number distribution
1107 * @p __x into the output stream @p __os.
1109 * @param __os An output stream.
1110 * @param __x A %rice_distribution random number distribution.
1112 * @returns The output stream with the state of @p __x inserted or in
1115 template<typename _RealType1, typename _CharT, typename _Traits>
1116 friend std::basic_ostream<_CharT, _Traits>&
1117 operator<<(std::basic_ostream<_CharT, _Traits>&,
1118 const rice_distribution<_RealType1>&);
1121 * @brief Extracts a %rice_distribution random number distribution
1122 * @p __x from the input stream @p __is.
1124 * @param __is An input stream.
1125 * @param __x A %rice_distribution random number
1128 * @returns The input stream with @p __x extracted or in an error state.
1130 template<typename _RealType1, typename _CharT, typename _Traits>
1131 friend std::basic_istream<_CharT, _Traits>&
1132 operator>>(std::basic_istream<_CharT, _Traits>&,
1133 rice_distribution<_RealType1>&);
1136 template<typename _ForwardIterator,
1137 typename _UniformRandomNumberGenerator>
1139 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1140 _UniformRandomNumberGenerator& __urng,
1141 const param_type& __p);
1143 param_type _M_param;
1145 std::normal_distribution<result_type> _M_ndx;
1146 std::normal_distribution<result_type> _M_ndy;
1150 * @brief Return true if two Rice distributions are not equal.
1152 template<typename _RealType1>
1154 operator!=(const rice_distribution<_RealType1>& __d1,
1155 const rice_distribution<_RealType1>& __d2)
1156 { return !(__d1 == __d2); }
1160 * @brief A Nakagami continuous distribution for random numbers.
1162 * The formula for the Nakagami probability density function is
1164 * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu}
1165 * x^{2\mu-1}e^{-\mu x / \omega}
1167 * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$
1168 * and @f$\omega > 0@f$.
1170 template<typename _RealType = double>
1172 nakagami_distribution
1174 static_assert(std::is_floating_point<_RealType>::value,
1175 "template argument not a floating point type");
1178 /** The type of the range of the distribution. */
1179 typedef _RealType result_type;
1180 /** Parameter type. */
1183 typedef nakagami_distribution<result_type> distribution_type;
1185 param_type(result_type __mu_val = result_type(1),
1186 result_type __omega_val = result_type(1))
1187 : _M_mu(__mu_val), _M_omega(__omega_val)
1189 _GLIBCXX_DEBUG_ASSERT(_M_mu >= result_type(0.5L));
1190 _GLIBCXX_DEBUG_ASSERT(_M_omega > result_type(0));
1199 { return _M_omega; }
1202 operator==(const param_type& __p1, const param_type& __p2)
1203 { return __p1._M_mu == __p2._M_mu
1204 && __p1._M_omega == __p2._M_omega; }
1207 void _M_initialize();
1210 result_type _M_omega;
1214 * @brief Constructors.
1217 nakagami_distribution(result_type __mu_val = result_type(1),
1218 result_type __omega_val = result_type(1))
1219 : _M_param(__mu_val, __omega_val),
1220 _M_gd(__mu_val, __omega_val / __mu_val)
1224 nakagami_distribution(const param_type& __p)
1226 _M_gd(__p.mu(), __p.omega() / __p.mu())
1230 * @brief Resets the distribution state.
1237 * @brief Return the parameters of the distribution.
1241 { return _M_param.mu(); }
1245 { return _M_param.omega(); }
1248 * @brief Returns the parameter set of the distribution.
1252 { return _M_param; }
1255 * @brief Sets the parameter set of the distribution.
1256 * @param __param The new parameter set of the distribution.
1259 param(const param_type& __param)
1260 { _M_param = __param; }
1263 * @brief Returns the greatest lower bound value of the distribution.
1267 { return result_type(0); }
1270 * @brief Returns the least upper bound value of the distribution.
1274 { return std::numeric_limits<result_type>::max(); }
1277 * @brief Generating functions.
1279 template<typename _UniformRandomNumberGenerator>
1281 operator()(_UniformRandomNumberGenerator& __urng)
1282 { return std::sqrt(this->_M_gd(__urng)); }
1284 template<typename _UniformRandomNumberGenerator>
1286 operator()(_UniformRandomNumberGenerator& __urng,
1287 const param_type& __p)
1289 typename std::gamma_distribution<result_type>::param_type
1290 __pg(__p.mu(), __p.omega() / __p.mu());
1291 return std::sqrt(this->_M_gd(__pg, __urng));
1294 template<typename _ForwardIterator,
1295 typename _UniformRandomNumberGenerator>
1297 __generate(_ForwardIterator __f, _ForwardIterator __t,
1298 _UniformRandomNumberGenerator& __urng)
1299 { this->__generate(__f, __t, __urng, this->param()); }
1301 template<typename _ForwardIterator,
1302 typename _UniformRandomNumberGenerator>
1304 __generate(_ForwardIterator __f, _ForwardIterator __t,
1305 _UniformRandomNumberGenerator& __urng,
1306 const param_type& __p)
1307 { this->__generate_impl(__f, __t, __urng, __p); }
1309 template<typename _UniformRandomNumberGenerator>
1311 __generate(result_type* __f, result_type* __t,
1312 _UniformRandomNumberGenerator& __urng,
1313 const param_type& __p)
1314 { this->__generate_impl(__f, __t, __urng, __p); }
1317 * @brief Return true if two Nakagami distributions have
1318 * the same parameters and the sequences that would
1319 * be generated are equal.
1322 operator==(const nakagami_distribution& __d1,
1323 const nakagami_distribution& __d2)
1324 { return (__d1.param() == __d2.param()
1325 && __d1._M_gd == __d2._M_gd); }
1328 * @brief Inserts a %nakagami_distribution random number distribution
1329 * @p __x into the output stream @p __os.
1331 * @param __os An output stream.
1332 * @param __x A %nakagami_distribution random number distribution.
1334 * @returns The output stream with the state of @p __x inserted or in
1337 template<typename _RealType1, typename _CharT, typename _Traits>
1338 friend std::basic_ostream<_CharT, _Traits>&
1339 operator<<(std::basic_ostream<_CharT, _Traits>&,
1340 const nakagami_distribution<_RealType1>&);
1343 * @brief Extracts a %nakagami_distribution random number distribution
1344 * @p __x from the input stream @p __is.
1346 * @param __is An input stream.
1347 * @param __x A %nakagami_distribution random number
1350 * @returns The input stream with @p __x extracted or in an error state.
1352 template<typename _RealType1, typename _CharT, typename _Traits>
1353 friend std::basic_istream<_CharT, _Traits>&
1354 operator>>(std::basic_istream<_CharT, _Traits>&,
1355 nakagami_distribution<_RealType1>&);
1358 template<typename _ForwardIterator,
1359 typename _UniformRandomNumberGenerator>
1361 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1362 _UniformRandomNumberGenerator& __urng,
1363 const param_type& __p);
1365 param_type _M_param;
1367 std::gamma_distribution<result_type> _M_gd;
1371 * @brief Return true if two Nakagami distributions are not equal.
1373 template<typename _RealType>
1375 operator!=(const nakagami_distribution<_RealType>& __d1,
1376 const nakagami_distribution<_RealType>& __d2)
1377 { return !(__d1 == __d2); }
1381 * @brief A Pareto continuous distribution for random numbers.
1383 * The formula for the Pareto cumulative probability function is
1385 * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha
1387 * The formula for the Pareto probability density function is
1389 * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu}
1390 * \left(\frac{\mu}{x}\right)^{\alpha + 1}
1392 * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$.
1394 * <table border=1 cellpadding=10 cellspacing=0>
1395 * <caption align=top>Distribution Statistics</caption>
1396 * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$
1397 * for @f$\alpha > 1@f$</td></tr>
1398 * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$
1399 * for @f$\alpha > 2@f$</td></tr>
1400 * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr>
1403 template<typename _RealType = double>
1407 static_assert(std::is_floating_point<_RealType>::value,
1408 "template argument not a floating point type");
1411 /** The type of the range of the distribution. */
1412 typedef _RealType result_type;
1413 /** Parameter type. */
1416 typedef pareto_distribution<result_type> distribution_type;
1418 param_type(result_type __alpha_val = result_type(1),
1419 result_type __mu_val = result_type(1))
1420 : _M_alpha(__alpha_val), _M_mu(__mu_val)
1422 _GLIBCXX_DEBUG_ASSERT(_M_alpha > result_type(0));
1423 _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0));
1428 { return _M_alpha; }
1435 operator==(const param_type& __p1, const param_type& __p2)
1436 { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; }
1439 void _M_initialize();
1441 result_type _M_alpha;
1446 * @brief Constructors.
1449 pareto_distribution(result_type __alpha_val = result_type(1),
1450 result_type __mu_val = result_type(1))
1451 : _M_param(__alpha_val, __mu_val),
1456 pareto_distribution(const param_type& __p)
1462 * @brief Resets the distribution state.
1471 * @brief Return the parameters of the distribution.
1475 { return _M_param.alpha(); }
1479 { return _M_param.mu(); }
1482 * @brief Returns the parameter set of the distribution.
1486 { return _M_param; }
1489 * @brief Sets the parameter set of the distribution.
1490 * @param __param The new parameter set of the distribution.
1493 param(const param_type& __param)
1494 { _M_param = __param; }
1497 * @brief Returns the greatest lower bound value of the distribution.
1501 { return this->mu(); }
1504 * @brief Returns the least upper bound value of the distribution.
1508 { return std::numeric_limits<result_type>::max(); }
1511 * @brief Generating functions.
1513 template<typename _UniformRandomNumberGenerator>
1515 operator()(_UniformRandomNumberGenerator& __urng)
1517 return this->mu() * std::pow(this->_M_ud(__urng),
1518 -result_type(1) / this->alpha());
1521 template<typename _UniformRandomNumberGenerator>
1523 operator()(_UniformRandomNumberGenerator& __urng,
1524 const param_type& __p)
1526 return __p.mu() * std::pow(this->_M_ud(__urng),
1527 -result_type(1) / __p.alpha());
1530 template<typename _ForwardIterator,
1531 typename _UniformRandomNumberGenerator>
1533 __generate(_ForwardIterator __f, _ForwardIterator __t,
1534 _UniformRandomNumberGenerator& __urng)
1535 { this->__generate(__f, __t, __urng, this->param()); }
1537 template<typename _ForwardIterator,
1538 typename _UniformRandomNumberGenerator>
1540 __generate(_ForwardIterator __f, _ForwardIterator __t,
1541 _UniformRandomNumberGenerator& __urng,
1542 const param_type& __p)
1543 { this->__generate_impl(__f, __t, __urng, __p); }
1545 template<typename _UniformRandomNumberGenerator>
1547 __generate(result_type* __f, result_type* __t,
1548 _UniformRandomNumberGenerator& __urng,
1549 const param_type& __p)
1550 { this->__generate_impl(__f, __t, __urng, __p); }
1553 * @brief Return true if two Pareto distributions have
1554 * the same parameters and the sequences that would
1555 * be generated are equal.
1558 operator==(const pareto_distribution& __d1,
1559 const pareto_distribution& __d2)
1560 { return (__d1.param() == __d2.param()
1561 && __d1._M_ud == __d2._M_ud); }
1564 * @brief Inserts a %pareto_distribution random number distribution
1565 * @p __x into the output stream @p __os.
1567 * @param __os An output stream.
1568 * @param __x A %pareto_distribution random number distribution.
1570 * @returns The output stream with the state of @p __x inserted or in
1573 template<typename _RealType1, typename _CharT, typename _Traits>
1574 friend std::basic_ostream<_CharT, _Traits>&
1575 operator<<(std::basic_ostream<_CharT, _Traits>&,
1576 const pareto_distribution<_RealType1>&);
1579 * @brief Extracts a %pareto_distribution random number distribution
1580 * @p __x from the input stream @p __is.
1582 * @param __is An input stream.
1583 * @param __x A %pareto_distribution random number
1586 * @returns The input stream with @p __x extracted or in an error state.
1588 template<typename _RealType1, typename _CharT, typename _Traits>
1589 friend std::basic_istream<_CharT, _Traits>&
1590 operator>>(std::basic_istream<_CharT, _Traits>&,
1591 pareto_distribution<_RealType1>&);
1594 template<typename _ForwardIterator,
1595 typename _UniformRandomNumberGenerator>
1597 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1598 _UniformRandomNumberGenerator& __urng,
1599 const param_type& __p);
1601 param_type _M_param;
1603 std::uniform_real_distribution<result_type> _M_ud;
1607 * @brief Return true if two Pareto distributions are not equal.
1609 template<typename _RealType>
1611 operator!=(const pareto_distribution<_RealType>& __d1,
1612 const pareto_distribution<_RealType>& __d2)
1613 { return !(__d1 == __d2); }
1617 * @brief A K continuous distribution for random numbers.
1619 * The formula for the K probability density function is
1621 * p(x|\lambda, \mu, \nu) = \frac{2}{x}
1622 * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}}
1623 * \frac{1}{\Gamma(\lambda)\Gamma(\nu)}
1624 * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right)
1626 * where @f$I_0(z)@f$ is the modified Bessel function of the second kind
1627 * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$
1628 * and @f$\nu > 0@f$.
1630 * <table border=1 cellpadding=10 cellspacing=0>
1631 * <caption align=top>Distribution Statistics</caption>
1632 * <tr><td>Mean</td><td>@f$\mu@f$</td></tr>
1633 * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr>
1634 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
1637 template<typename _RealType = double>
1641 static_assert(std::is_floating_point<_RealType>::value,
1642 "template argument not a floating point type");
1645 /** The type of the range of the distribution. */
1646 typedef _RealType result_type;
1647 /** Parameter type. */
1650 typedef k_distribution<result_type> distribution_type;
1652 param_type(result_type __lambda_val = result_type(1),
1653 result_type __mu_val = result_type(1),
1654 result_type __nu_val = result_type(1))
1655 : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val)
1657 _GLIBCXX_DEBUG_ASSERT(_M_lambda > result_type(0));
1658 _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0));
1659 _GLIBCXX_DEBUG_ASSERT(_M_nu > result_type(0));
1664 { return _M_lambda; }
1675 operator==(const param_type& __p1, const param_type& __p2)
1676 { return __p1._M_lambda == __p2._M_lambda
1677 && __p1._M_mu == __p2._M_mu
1678 && __p1._M_nu == __p2._M_nu; }
1681 void _M_initialize();
1683 result_type _M_lambda;
1689 * @brief Constructors.
1692 k_distribution(result_type __lambda_val = result_type(1),
1693 result_type __mu_val = result_type(1),
1694 result_type __nu_val = result_type(1))
1695 : _M_param(__lambda_val, __mu_val, __nu_val),
1696 _M_gd1(__lambda_val, result_type(1) / __lambda_val),
1697 _M_gd2(__nu_val, __mu_val / __nu_val)
1701 k_distribution(const param_type& __p)
1703 _M_gd1(__p.lambda(), result_type(1) / __p.lambda()),
1704 _M_gd2(__p.nu(), __p.mu() / __p.nu())
1708 * @brief Resets the distribution state.
1718 * @brief Return the parameters of the distribution.
1722 { return _M_param.lambda(); }
1726 { return _M_param.mu(); }
1730 { return _M_param.nu(); }
1733 * @brief Returns the parameter set of the distribution.
1737 { return _M_param; }
1740 * @brief Sets the parameter set of the distribution.
1741 * @param __param The new parameter set of the distribution.
1744 param(const param_type& __param)
1745 { _M_param = __param; }
1748 * @brief Returns the greatest lower bound value of the distribution.
1752 { return result_type(0); }
1755 * @brief Returns the least upper bound value of the distribution.
1759 { return std::numeric_limits<result_type>::max(); }
1762 * @brief Generating functions.
1764 template<typename _UniformRandomNumberGenerator>
1766 operator()(_UniformRandomNumberGenerator&);
1768 template<typename _UniformRandomNumberGenerator>
1770 operator()(_UniformRandomNumberGenerator&, const param_type&);
1772 template<typename _ForwardIterator,
1773 typename _UniformRandomNumberGenerator>
1775 __generate(_ForwardIterator __f, _ForwardIterator __t,
1776 _UniformRandomNumberGenerator& __urng)
1777 { this->__generate(__f, __t, __urng, this->param()); }
1779 template<typename _ForwardIterator,
1780 typename _UniformRandomNumberGenerator>
1782 __generate(_ForwardIterator __f, _ForwardIterator __t,
1783 _UniformRandomNumberGenerator& __urng,
1784 const param_type& __p)
1785 { this->__generate_impl(__f, __t, __urng, __p); }
1787 template<typename _UniformRandomNumberGenerator>
1789 __generate(result_type* __f, result_type* __t,
1790 _UniformRandomNumberGenerator& __urng,
1791 const param_type& __p)
1792 { this->__generate_impl(__f, __t, __urng, __p); }
1795 * @brief Return true if two K distributions have
1796 * the same parameters and the sequences that would
1797 * be generated are equal.
1800 operator==(const k_distribution& __d1,
1801 const k_distribution& __d2)
1802 { return (__d1.param() == __d2.param()
1803 && __d1._M_gd1 == __d2._M_gd1
1804 && __d1._M_gd2 == __d2._M_gd2); }
1807 * @brief Inserts a %k_distribution random number distribution
1808 * @p __x into the output stream @p __os.
1810 * @param __os An output stream.
1811 * @param __x A %k_distribution random number distribution.
1813 * @returns The output stream with the state of @p __x inserted or in
1816 template<typename _RealType1, typename _CharT, typename _Traits>
1817 friend std::basic_ostream<_CharT, _Traits>&
1818 operator<<(std::basic_ostream<_CharT, _Traits>&,
1819 const k_distribution<_RealType1>&);
1822 * @brief Extracts a %k_distribution random number distribution
1823 * @p __x from the input stream @p __is.
1825 * @param __is An input stream.
1826 * @param __x A %k_distribution random number
1829 * @returns The input stream with @p __x extracted or in an error state.
1831 template<typename _RealType1, typename _CharT, typename _Traits>
1832 friend std::basic_istream<_CharT, _Traits>&
1833 operator>>(std::basic_istream<_CharT, _Traits>&,
1834 k_distribution<_RealType1>&);
1837 template<typename _ForwardIterator,
1838 typename _UniformRandomNumberGenerator>
1840 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1841 _UniformRandomNumberGenerator& __urng,
1842 const param_type& __p);
1844 param_type _M_param;
1846 std::gamma_distribution<result_type> _M_gd1;
1847 std::gamma_distribution<result_type> _M_gd2;
1851 * @brief Return true if two K distributions are not equal.
1853 template<typename _RealType>
1855 operator!=(const k_distribution<_RealType>& __d1,
1856 const k_distribution<_RealType>& __d2)
1857 { return !(__d1 == __d2); }
1861 * @brief An arcsine continuous distribution for random numbers.
1863 * The formula for the arcsine probability density function is
1865 * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
1867 * where @f$x >= a@f$ and @f$x <= b@f$.
1869 * <table border=1 cellpadding=10 cellspacing=0>
1870 * <caption align=top>Distribution Statistics</caption>
1871 * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr>
1872 * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr>
1873 * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr>
1876 template<typename _RealType = double>
1878 arcsine_distribution
1880 static_assert(std::is_floating_point<_RealType>::value,
1881 "template argument not a floating point type");
1884 /** The type of the range of the distribution. */
1885 typedef _RealType result_type;
1886 /** Parameter type. */
1889 typedef arcsine_distribution<result_type> distribution_type;
1891 param_type(result_type __a = result_type(0),
1892 result_type __b = result_type(1))
1893 : _M_a(__a), _M_b(__b)
1895 _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1907 operator==(const param_type& __p1, const param_type& __p2)
1908 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1911 void _M_initialize();
1918 * @brief Constructors.
1921 arcsine_distribution(result_type __a = result_type(0),
1922 result_type __b = result_type(1))
1923 : _M_param(__a, __b),
1924 _M_ud(-1.5707963267948966192313216916397514L,
1925 +1.5707963267948966192313216916397514L)
1929 arcsine_distribution(const param_type& __p)
1931 _M_ud(-1.5707963267948966192313216916397514L,
1932 +1.5707963267948966192313216916397514L)
1936 * @brief Resets the distribution state.
1943 * @brief Return the parameters of the distribution.
1947 { return _M_param.a(); }
1951 { return _M_param.b(); }
1954 * @brief Returns the parameter set of the distribution.
1958 { return _M_param; }
1961 * @brief Sets the parameter set of the distribution.
1962 * @param __param The new parameter set of the distribution.
1965 param(const param_type& __param)
1966 { _M_param = __param; }
1969 * @brief Returns the greatest lower bound value of the distribution.
1973 { return this->a(); }
1976 * @brief Returns the least upper bound value of the distribution.
1980 { return this->b(); }
1983 * @brief Generating functions.
1985 template<typename _UniformRandomNumberGenerator>
1987 operator()(_UniformRandomNumberGenerator& __urng)
1989 result_type __x = std::sin(this->_M_ud(__urng));
1990 return (__x * (this->b() - this->a())
1991 + this->a() + this->b()) / result_type(2);
1994 template<typename _UniformRandomNumberGenerator>
1996 operator()(_UniformRandomNumberGenerator& __urng,
1997 const param_type& __p)
1999 result_type __x = std::sin(this->_M_ud(__urng));
2000 return (__x * (__p.b() - __p.a())
2001 + __p.a() + __p.b()) / result_type(2);
2004 template<typename _ForwardIterator,
2005 typename _UniformRandomNumberGenerator>
2007 __generate(_ForwardIterator __f, _ForwardIterator __t,
2008 _UniformRandomNumberGenerator& __urng)
2009 { this->__generate(__f, __t, __urng, this->param()); }
2011 template<typename _ForwardIterator,
2012 typename _UniformRandomNumberGenerator>
2014 __generate(_ForwardIterator __f, _ForwardIterator __t,
2015 _UniformRandomNumberGenerator& __urng,
2016 const param_type& __p)
2017 { this->__generate_impl(__f, __t, __urng, __p); }
2019 template<typename _UniformRandomNumberGenerator>
2021 __generate(result_type* __f, result_type* __t,
2022 _UniformRandomNumberGenerator& __urng,
2023 const param_type& __p)
2024 { this->__generate_impl(__f, __t, __urng, __p); }
2027 * @brief Return true if two arcsine distributions have
2028 * the same parameters and the sequences that would
2029 * be generated are equal.
2032 operator==(const arcsine_distribution& __d1,
2033 const arcsine_distribution& __d2)
2034 { return (__d1.param() == __d2.param()
2035 && __d1._M_ud == __d2._M_ud); }
2038 * @brief Inserts a %arcsine_distribution random number distribution
2039 * @p __x into the output stream @p __os.
2041 * @param __os An output stream.
2042 * @param __x A %arcsine_distribution random number distribution.
2044 * @returns The output stream with the state of @p __x inserted or in
2047 template<typename _RealType1, typename _CharT, typename _Traits>
2048 friend std::basic_ostream<_CharT, _Traits>&
2049 operator<<(std::basic_ostream<_CharT, _Traits>&,
2050 const arcsine_distribution<_RealType1>&);
2053 * @brief Extracts a %arcsine_distribution random number distribution
2054 * @p __x from the input stream @p __is.
2056 * @param __is An input stream.
2057 * @param __x A %arcsine_distribution random number
2060 * @returns The input stream with @p __x extracted or in an error state.
2062 template<typename _RealType1, typename _CharT, typename _Traits>
2063 friend std::basic_istream<_CharT, _Traits>&
2064 operator>>(std::basic_istream<_CharT, _Traits>&,
2065 arcsine_distribution<_RealType1>&);
2068 template<typename _ForwardIterator,
2069 typename _UniformRandomNumberGenerator>
2071 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2072 _UniformRandomNumberGenerator& __urng,
2073 const param_type& __p);
2075 param_type _M_param;
2077 std::uniform_real_distribution<result_type> _M_ud;
2081 * @brief Return true if two arcsine distributions are not equal.
2083 template<typename _RealType>
2085 operator!=(const arcsine_distribution<_RealType>& __d1,
2086 const arcsine_distribution<_RealType>& __d2)
2087 { return !(__d1 == __d2); }
2091 * @brief A Hoyt continuous distribution for random numbers.
2093 * The formula for the Hoyt probability density function is
2095 * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
2096 * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
2097 * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
2099 * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
2100 * of order 0 and @f$0 < q < 1@f$.
2102 * <table border=1 cellpadding=10 cellspacing=0>
2103 * <caption align=top>Distribution Statistics</caption>
2104 * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
2105 * E(1 - q^2) @f$</td></tr>
2106 * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
2107 * {\pi (1 + q^2)}\right) @f$</td></tr>
2108 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
2110 * where @f$E(x)@f$ is the elliptic function of the second kind.
2112 template<typename _RealType = double>
2116 static_assert(std::is_floating_point<_RealType>::value,
2117 "template argument not a floating point type");
2120 /** The type of the range of the distribution. */
2121 typedef _RealType result_type;
2122 /** Parameter type. */
2125 typedef hoyt_distribution<result_type> distribution_type;
2127 param_type(result_type __q = result_type(0.5L),
2128 result_type __omega = result_type(1))
2129 : _M_q(__q), _M_omega(__omega)
2131 _GLIBCXX_DEBUG_ASSERT(_M_q > result_type(0));
2132 _GLIBCXX_DEBUG_ASSERT(_M_q < result_type(1));
2141 { return _M_omega; }
2144 operator==(const param_type& __p1, const param_type& __p2)
2145 { return __p1._M_q == __p2._M_q
2146 && __p1._M_omega == __p2._M_omega; }
2149 void _M_initialize();
2152 result_type _M_omega;
2156 * @brief Constructors.
2159 hoyt_distribution(result_type __q = result_type(0.5L),
2160 result_type __omega = result_type(1))
2161 : _M_param(__q, __omega),
2162 _M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
2163 result_type(0.5L) * (result_type(1) + __q * __q)
2165 _M_ed(result_type(1))
2169 hoyt_distribution(const param_type& __p)
2171 _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
2172 result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
2173 / (__p.q() * __p.q())),
2174 _M_ed(result_type(1))
2178 * @brief Resets the distribution state.
2188 * @brief Return the parameters of the distribution.
2192 { return _M_param.q(); }
2196 { return _M_param.omega(); }
2199 * @brief Returns the parameter set of the distribution.
2203 { return _M_param; }
2206 * @brief Sets the parameter set of the distribution.
2207 * @param __param The new parameter set of the distribution.
2210 param(const param_type& __param)
2211 { _M_param = __param; }
2214 * @brief Returns the greatest lower bound value of the distribution.
2218 { return result_type(0); }
2221 * @brief Returns the least upper bound value of the distribution.
2225 { return std::numeric_limits<result_type>::max(); }
2228 * @brief Generating functions.
2230 template<typename _UniformRandomNumberGenerator>
2232 operator()(_UniformRandomNumberGenerator& __urng);
2234 template<typename _UniformRandomNumberGenerator>
2236 operator()(_UniformRandomNumberGenerator& __urng,
2237 const param_type& __p);
2239 template<typename _ForwardIterator,
2240 typename _UniformRandomNumberGenerator>
2242 __generate(_ForwardIterator __f, _ForwardIterator __t,
2243 _UniformRandomNumberGenerator& __urng)
2244 { this->__generate(__f, __t, __urng, this->param()); }
2246 template<typename _ForwardIterator,
2247 typename _UniformRandomNumberGenerator>
2249 __generate(_ForwardIterator __f, _ForwardIterator __t,
2250 _UniformRandomNumberGenerator& __urng,
2251 const param_type& __p)
2252 { this->__generate_impl(__f, __t, __urng, __p); }
2254 template<typename _UniformRandomNumberGenerator>
2256 __generate(result_type* __f, result_type* __t,
2257 _UniformRandomNumberGenerator& __urng,
2258 const param_type& __p)
2259 { this->__generate_impl(__f, __t, __urng, __p); }
2262 * @brief Return true if two Hoyt distributions have
2263 * the same parameters and the sequences that would
2264 * be generated are equal.
2267 operator==(const hoyt_distribution& __d1,
2268 const hoyt_distribution& __d2)
2269 { return (__d1.param() == __d2.param()
2270 && __d1._M_ad == __d2._M_ad
2271 && __d1._M_ed == __d2._M_ed); }
2274 * @brief Inserts a %hoyt_distribution random number distribution
2275 * @p __x into the output stream @p __os.
2277 * @param __os An output stream.
2278 * @param __x A %hoyt_distribution random number distribution.
2280 * @returns The output stream with the state of @p __x inserted or in
2283 template<typename _RealType1, typename _CharT, typename _Traits>
2284 friend std::basic_ostream<_CharT, _Traits>&
2285 operator<<(std::basic_ostream<_CharT, _Traits>&,
2286 const hoyt_distribution<_RealType1>&);
2289 * @brief Extracts a %hoyt_distribution random number distribution
2290 * @p __x from the input stream @p __is.
2292 * @param __is An input stream.
2293 * @param __x A %hoyt_distribution random number
2296 * @returns The input stream with @p __x extracted or in an error state.
2298 template<typename _RealType1, typename _CharT, typename _Traits>
2299 friend std::basic_istream<_CharT, _Traits>&
2300 operator>>(std::basic_istream<_CharT, _Traits>&,
2301 hoyt_distribution<_RealType1>&);
2304 template<typename _ForwardIterator,
2305 typename _UniformRandomNumberGenerator>
2307 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2308 _UniformRandomNumberGenerator& __urng,
2309 const param_type& __p);
2311 param_type _M_param;
2313 __gnu_cxx::arcsine_distribution<result_type> _M_ad;
2314 std::exponential_distribution<result_type> _M_ed;
2318 * @brief Return true if two Hoyt distributions are not equal.
2320 template<typename _RealType>
2322 operator!=(const hoyt_distribution<_RealType>& __d1,
2323 const hoyt_distribution<_RealType>& __d2)
2324 { return !(__d1 == __d2); }
2326 _GLIBCXX_END_NAMESPACE_VERSION
2327 } // namespace __gnu_cxx
2329 #include "opt_random.h"
2330 #include "random.tcc"
2332 #endif // _GLIBCXX_USE_C99_STDINT_TR1
2334 #endif // __GXX_EXPERIMENTAL_CXX0X__
2336 #endif // _EXT_RANDOM