1 // Random number extensions -*- C++ -*-
3 // Copyright (C) 2012-2015 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 #if __cplusplus < 201103L
35 # include <bits/c++0x_warning.h>
43 # include <x86intrin.h>
46 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
48 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
50 _GLIBCXX_BEGIN_NAMESPACE_VERSION
52 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
54 /* Mersenne twister implementation optimized for vector operations.
56 * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
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
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");
75 typedef _UIntType result_type;
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;
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");
89 static constexpr size_t state_size = _M_nstate * (16
90 / sizeof(result_type));
91 static constexpr result_type default_seed = 5489u;
93 // constructors and member function
95 simd_fast_mersenne_twister_engine(result_type __sd = default_seed)
98 template<typename _Sseq, typename = typename
99 std::enable_if<!std::is_same<_Sseq,
100 simd_fast_mersenne_twister_engine>::value>
103 simd_fast_mersenne_twister_engine(_Sseq& __q)
107 seed(result_type __sd = default_seed);
109 template<typename _Sseq>
110 typename std::enable_if<std::is_class<_Sseq>::value>::type
113 static constexpr result_type
117 static constexpr result_type
119 { return std::numeric_limits<result_type>::max(); }
122 discard(unsigned long long __z);
127 if (__builtin_expect(_M_pos >= state_size, 0))
130 return _M_stateT[_M_pos++];
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>
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);
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
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);
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);
185 __m128i _M_state[_M_nstate];
187 uint32_t _M_state32[_M_nstate32];
188 result_type _M_stateT[state_size];
189 } __attribute__ ((__aligned__ (16)));
192 void _M_gen_rand(void);
193 void _M_period_certification();
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>
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); }
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.
218 typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2,
220 0xfdff37ffU, 0xef7f3f7dU,
221 0xff777b7dU, 0x7ff7fb2fU,
222 0x00000001U, 0x00000000U,
223 0x00000000U, 0x5986f054U>
226 typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2,
228 0xfdff37ffU, 0xef7f3f7dU,
229 0xff777b7dU, 0x7ff7fb2fU,
230 0x00000001U, 0x00000000U,
231 0x00000000U, 0x5986f054U>
235 typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7,
237 0xf7fefffdU, 0x7fefcfffU,
238 0xaff3ef3fU, 0xb5ffff7fU,
239 0x00000001U, 0x00000000U,
240 0x00000000U, 0x20000000U>
243 typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7,
245 0xf7fefffdU, 0x7fefcfffU,
246 0xaff3ef3fU, 0xb5ffff7fU,
247 0x00000001U, 0x00000000U,
248 0x00000000U, 0x20000000U>
252 typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12,
254 0xbff7ffbfU, 0xfdfffffeU,
255 0xf7ffef7fU, 0xf2f7cbbfU,
256 0x00000001U, 0x00000000U,
257 0x00000000U, 0x41dfa600U>
260 typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12,
262 0xbff7ffbfU, 0xfdfffffeU,
263 0xf7ffef7fU, 0xf2f7cbbfU,
264 0x00000001U, 0x00000000U,
265 0x00000000U, 0x41dfa600U>
269 typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17,
271 0x9f7bffffU, 0x9fffff5fU,
272 0x3efffffbU, 0xfffff7bbU,
273 0xa8000001U, 0xaf5390a3U,
274 0xb740b3f8U, 0x6c11486dU>
277 typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17,
279 0x9f7bffffU, 0x9fffff5fU,
280 0x3efffffbU, 0xfffff7bbU,
281 0xa8000001U, 0xaf5390a3U,
282 0xb740b3f8U, 0x6c11486dU>
286 typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68,
288 0xeffff7fbU, 0xffffffefU,
289 0xdfdfbfffU, 0x7fffdbfdU,
290 0x00000001U, 0x00000000U,
291 0xe8148000U, 0xd0c7afa3U>
294 typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68,
296 0xeffff7fbU, 0xffffffefU,
297 0xdfdfbfffU, 0x7fffdbfdU,
298 0x00000001U, 0x00000000U,
299 0xe8148000U, 0xd0c7afa3U>
303 typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122,
305 0xdfffffefU, 0xddfecb7fU,
306 0xbffaffffU, 0xbffffff6U,
307 0x00000001U, 0x00000000U,
308 0x00000000U, 0x13c9e684U>
311 typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122,
313 0xdfffffefU, 0xddfecb7fU,
314 0xbffaffffU, 0xbffffff6U,
315 0x00000001U, 0x00000000U,
316 0x00000000U, 0x13c9e684U>
320 typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330,
322 0xeffffffbU, 0xdfbebfffU,
323 0xbfbf7befU, 0x9ffd7bffU,
324 0x00000001U, 0x00000000U,
325 0xa3ac4000U, 0xecc1327aU>
328 typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330,
330 0xeffffffbU, 0xdfbebfffU,
331 0xbfbf7befU, 0x9ffd7bffU,
332 0x00000001U, 0x00000000U,
333 0xa3ac4000U, 0xecc1327aU>
337 typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366,
339 0xfdbffbffU, 0xbff7ff3fU,
340 0xfd77efffU, 0xbf9ff3ffU,
341 0x00000001U, 0x00000000U,
342 0x00000000U, 0xe9528d85U>
345 typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366,
347 0xfdbffbffU, 0xbff7ff3fU,
348 0xfd77efffU, 0xbf9ff3ffU,
349 0x00000001U, 0x00000000U,
350 0x00000000U, 0xe9528d85U>
354 typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110,
356 0xffffbb5fU, 0xfb6ebf95U,
357 0xfffefffaU, 0xcff77fffU,
358 0x00000001U, 0x00000000U,
359 0xcb520000U, 0xc7e91c7dU>
362 typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110,
364 0xffffbb5fU, 0xfb6ebf95U,
365 0xfffefffaU, 0xcff77fffU,
366 0x00000001U, 0x00000000U,
367 0xcb520000U, 0xc7e91c7dU>
371 typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627,
373 0xbff7bff7U, 0xbfffffffU,
374 0xbffffa7fU, 0xffddfbfbU,
375 0xf8000001U, 0x89e80709U,
376 0x3bd2b64bU, 0x0c64b1e4U>
379 typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627,
381 0xbff7bff7U, 0xbfffffffU,
382 0xbffffa7fU, 0xffddfbfbU,
383 0xf8000001U, 0x89e80709U,
384 0x3bd2b64bU, 0x0c64b1e4U>
387 #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
390 * @brief A beta continuous distribution for random numbers.
392 * The formula for the beta probability density function is:
394 * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)}
395 * x^{\alpha - 1} (1 - x)^{\beta - 1}
398 template<typename _RealType = double>
399 class beta_distribution
401 static_assert(std::is_floating_point<_RealType>::value,
402 "template argument not a floating point type");
405 /** The type of the range of the distribution. */
406 typedef _RealType result_type;
407 /** Parameter type. */
410 typedef beta_distribution<_RealType> distribution_type;
411 friend class beta_distribution<_RealType>;
414 param_type(_RealType __alpha_val = _RealType(1),
415 _RealType __beta_val = _RealType(1))
416 : _M_alpha(__alpha_val), _M_beta(__beta_val)
418 _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
419 _GLIBCXX_DEBUG_ASSERT(_M_beta > _RealType(0));
431 operator==(const param_type& __p1, const param_type& __p2)
432 { return (__p1._M_alpha == __p2._M_alpha
433 && __p1._M_beta == __p2._M_beta); }
445 * @brief Constructs a beta distribution with parameters
446 * @f$\alpha@f$ and @f$\beta@f$.
449 beta_distribution(_RealType __alpha_val = _RealType(1),
450 _RealType __beta_val = _RealType(1))
451 : _M_param(__alpha_val, __beta_val)
455 beta_distribution(const param_type& __p)
460 * @brief Resets the distribution state.
467 * @brief Returns the @f$\alpha@f$ of the distribution.
471 { return _M_param.alpha(); }
474 * @brief Returns the @f$\beta@f$ of the distribution.
478 { return _M_param.beta(); }
481 * @brief Returns the parameter set of the distribution.
488 * @brief Sets the parameter set of the distribution.
489 * @param __param The new parameter set of the distribution.
492 param(const param_type& __param)
493 { _M_param = __param; }
496 * @brief Returns the greatest lower bound value of the distribution.
500 { return result_type(0); }
503 * @brief Returns the least upper bound value of the distribution.
507 { return result_type(1); }
510 * @brief Generating functions.
512 template<typename _UniformRandomNumberGenerator>
514 operator()(_UniformRandomNumberGenerator& __urng)
515 { return this->operator()(__urng, _M_param); }
517 template<typename _UniformRandomNumberGenerator>
519 operator()(_UniformRandomNumberGenerator& __urng,
520 const param_type& __p);
522 template<typename _ForwardIterator,
523 typename _UniformRandomNumberGenerator>
525 __generate(_ForwardIterator __f, _ForwardIterator __t,
526 _UniformRandomNumberGenerator& __urng)
527 { this->__generate(__f, __t, __urng, _M_param); }
529 template<typename _ForwardIterator,
530 typename _UniformRandomNumberGenerator>
532 __generate(_ForwardIterator __f, _ForwardIterator __t,
533 _UniformRandomNumberGenerator& __urng,
534 const param_type& __p)
535 { this->__generate_impl(__f, __t, __urng, __p); }
537 template<typename _UniformRandomNumberGenerator>
539 __generate(result_type* __f, result_type* __t,
540 _UniformRandomNumberGenerator& __urng,
541 const param_type& __p)
542 { this->__generate_impl(__f, __t, __urng, __p); }
545 * @brief Return true if two beta distributions have the same
546 * parameters and the sequences that would be generated
550 operator==(const beta_distribution& __d1,
551 const beta_distribution& __d2)
552 { return __d1._M_param == __d2._M_param; }
555 * @brief Inserts a %beta_distribution random number distribution
556 * @p __x into the output stream @p __os.
558 * @param __os An output stream.
559 * @param __x A %beta_distribution random number distribution.
561 * @returns The output stream with the state of @p __x inserted or in
564 template<typename _RealType1, typename _CharT, typename _Traits>
565 friend std::basic_ostream<_CharT, _Traits>&
566 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
567 const __gnu_cxx::beta_distribution<_RealType1>& __x);
570 * @brief Extracts a %beta_distribution random number distribution
571 * @p __x from the input stream @p __is.
573 * @param __is An input stream.
574 * @param __x A %beta_distribution random number generator engine.
576 * @returns The input stream with @p __x extracted or in an error state.
578 template<typename _RealType1, typename _CharT, typename _Traits>
579 friend std::basic_istream<_CharT, _Traits>&
580 operator>>(std::basic_istream<_CharT, _Traits>& __is,
581 __gnu_cxx::beta_distribution<_RealType1>& __x);
584 template<typename _ForwardIterator,
585 typename _UniformRandomNumberGenerator>
587 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
588 _UniformRandomNumberGenerator& __urng,
589 const param_type& __p);
595 * @brief Return true if two beta distributions are different.
597 template<typename _RealType>
599 operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
600 const __gnu_cxx::beta_distribution<_RealType>& __d2)
601 { return !(__d1 == __d2); }
605 * @brief A multi-variate normal continuous distribution for random numbers.
607 * The formula for the normal probability density function is
609 * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) =
610 * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}}
611 * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T}
612 * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})}
615 * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are
616 * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance
617 * matrix (which must be positive-definite).
619 template<std::size_t _Dimen, typename _RealType = double>
620 class normal_mv_distribution
622 static_assert(std::is_floating_point<_RealType>::value,
623 "template argument not a floating point type");
624 static_assert(_Dimen != 0, "dimension is zero");
627 /** The type of the range of the distribution. */
628 typedef std::array<_RealType, _Dimen> result_type;
629 /** Parameter type. */
632 static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2;
635 typedef normal_mv_distribution<_Dimen, _RealType> distribution_type;
636 friend class normal_mv_distribution<_Dimen, _RealType>;
640 std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0));
641 auto __it = _M_t.begin();
642 for (size_t __i = 0; __i < _Dimen; ++__i)
644 std::fill_n(__it, __i, _RealType(0));
646 *__it++ = _RealType(1);
650 template<typename _ForwardIterator1, typename _ForwardIterator2>
651 param_type(_ForwardIterator1 __meanbegin,
652 _ForwardIterator1 __meanend,
653 _ForwardIterator2 __varcovbegin,
654 _ForwardIterator2 __varcovend)
656 __glibcxx_function_requires(_ForwardIteratorConcept<
658 __glibcxx_function_requires(_ForwardIteratorConcept<
660 _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend)
662 const auto __dist = std::distance(__varcovbegin, __varcovend);
663 _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen
664 || __dist == _Dimen * (_Dimen + 1) / 2
665 || __dist == _Dimen);
667 if (__dist == _Dimen * _Dimen)
668 _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend);
669 else if (__dist == _Dimen * (_Dimen + 1) / 2)
670 _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend);
672 _M_init_diagonal(__meanbegin, __meanend,
673 __varcovbegin, __varcovend);
676 param_type(std::initializer_list<_RealType> __mean,
677 std::initializer_list<_RealType> __varcov)
679 _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen);
680 _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen
681 || __varcov.size() == _Dimen * (_Dimen + 1) / 2
682 || __varcov.size() == _Dimen);
684 if (__varcov.size() == _Dimen * _Dimen)
685 _M_init_full(__mean.begin(), __mean.end(),
686 __varcov.begin(), __varcov.end());
687 else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2)
688 _M_init_lower(__mean.begin(), __mean.end(),
689 __varcov.begin(), __varcov.end());
691 _M_init_diagonal(__mean.begin(), __mean.end(),
692 __varcov.begin(), __varcov.end());
695 std::array<_RealType, _Dimen>
699 std::array<_RealType, _M_t_size>
704 operator==(const param_type& __p1, const param_type& __p2)
705 { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; }
708 template <typename _InputIterator1, typename _InputIterator2>
709 void _M_init_full(_InputIterator1 __meanbegin,
710 _InputIterator1 __meanend,
711 _InputIterator2 __varcovbegin,
712 _InputIterator2 __varcovend);
713 template <typename _InputIterator1, typename _InputIterator2>
714 void _M_init_lower(_InputIterator1 __meanbegin,
715 _InputIterator1 __meanend,
716 _InputIterator2 __varcovbegin,
717 _InputIterator2 __varcovend);
718 template <typename _InputIterator1, typename _InputIterator2>
719 void _M_init_diagonal(_InputIterator1 __meanbegin,
720 _InputIterator1 __meanend,
721 _InputIterator2 __varbegin,
722 _InputIterator2 __varend);
724 std::array<_RealType, _Dimen> _M_mean;
725 std::array<_RealType, _M_t_size> _M_t;
729 normal_mv_distribution()
730 : _M_param(), _M_nd()
733 template<typename _ForwardIterator1, typename _ForwardIterator2>
734 normal_mv_distribution(_ForwardIterator1 __meanbegin,
735 _ForwardIterator1 __meanend,
736 _ForwardIterator2 __varcovbegin,
737 _ForwardIterator2 __varcovend)
738 : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend),
742 normal_mv_distribution(std::initializer_list<_RealType> __mean,
743 std::initializer_list<_RealType> __varcov)
744 : _M_param(__mean, __varcov), _M_nd()
748 normal_mv_distribution(const param_type& __p)
749 : _M_param(__p), _M_nd()
753 * @brief Resets the distribution state.
760 * @brief Returns the mean of the distribution.
764 { return _M_param.mean(); }
767 * @brief Returns the compact form of the variance/covariance
768 * matrix of the distribution.
770 std::array<_RealType, _Dimen * (_Dimen + 1) / 2>
772 { return _M_param.varcov(); }
775 * @brief Returns the parameter set of the distribution.
782 * @brief Sets the parameter set of the distribution.
783 * @param __param The new parameter set of the distribution.
786 param(const param_type& __param)
787 { _M_param = __param; }
790 * @brief Returns the greatest lower bound value of the distribution.
795 __res.fill(std::numeric_limits<_RealType>::lowest());
799 * @brief Returns the least upper bound value of the distribution.
804 __res.fill(std::numeric_limits<_RealType>::max());
808 * @brief Generating functions.
810 template<typename _UniformRandomNumberGenerator>
812 operator()(_UniformRandomNumberGenerator& __urng)
813 { return this->operator()(__urng, _M_param); }
815 template<typename _UniformRandomNumberGenerator>
817 operator()(_UniformRandomNumberGenerator& __urng,
818 const param_type& __p);
820 template<typename _ForwardIterator,
821 typename _UniformRandomNumberGenerator>
823 __generate(_ForwardIterator __f, _ForwardIterator __t,
824 _UniformRandomNumberGenerator& __urng)
825 { return this->__generate_impl(__f, __t, __urng, _M_param); }
827 template<typename _ForwardIterator,
828 typename _UniformRandomNumberGenerator>
830 __generate(_ForwardIterator __f, _ForwardIterator __t,
831 _UniformRandomNumberGenerator& __urng,
832 const param_type& __p)
833 { return this->__generate_impl(__f, __t, __urng, __p); }
836 * @brief Return true if two multi-variant normal distributions have
837 * the same parameters and the sequences that would
838 * be generated are equal.
840 template<size_t _Dimen1, typename _RealType1>
843 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
846 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
850 * @brief Inserts a %normal_mv_distribution random number distribution
851 * @p __x into the output stream @p __os.
853 * @param __os An output stream.
854 * @param __x A %normal_mv_distribution random number distribution.
856 * @returns The output stream with the state of @p __x inserted or in
859 template<size_t _Dimen1, typename _RealType1,
860 typename _CharT, typename _Traits>
861 friend std::basic_ostream<_CharT, _Traits>&
862 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
864 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
868 * @brief Extracts a %normal_mv_distribution random number distribution
869 * @p __x from the input stream @p __is.
871 * @param __is An input stream.
872 * @param __x A %normal_mv_distribution random number generator engine.
874 * @returns The input stream with @p __x extracted or in an error
877 template<size_t _Dimen1, typename _RealType1,
878 typename _CharT, typename _Traits>
879 friend std::basic_istream<_CharT, _Traits>&
880 operator>>(std::basic_istream<_CharT, _Traits>& __is,
881 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
885 template<typename _ForwardIterator,
886 typename _UniformRandomNumberGenerator>
888 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
889 _UniformRandomNumberGenerator& __urng,
890 const param_type& __p);
893 std::normal_distribution<_RealType> _M_nd;
897 * @brief Return true if two multi-variate normal distributions are
900 template<size_t _Dimen, typename _RealType>
902 operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
904 const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
906 { return !(__d1 == __d2); }
910 * @brief A Rice continuous distribution for random numbers.
912 * The formula for the Rice probability density function is
914 * p(x|\nu,\sigma) = \frac{x}{\sigma^2}
915 * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right)
916 * I_0\left(\frac{x \nu}{\sigma^2}\right)
918 * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
919 * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$.
921 * <table border=1 cellpadding=10 cellspacing=0>
922 * <caption align=top>Distribution Statistics</caption>
923 * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
924 * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2
925 * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
926 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
928 * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2.
930 template<typename _RealType = double>
934 static_assert(std::is_floating_point<_RealType>::value,
935 "template argument not a floating point type");
937 /** The type of the range of the distribution. */
938 typedef _RealType result_type;
939 /** Parameter type. */
942 typedef rice_distribution<result_type> distribution_type;
944 param_type(result_type __nu_val = result_type(0),
945 result_type __sigma_val = result_type(1))
946 : _M_nu(__nu_val), _M_sigma(__sigma_val)
948 _GLIBCXX_DEBUG_ASSERT(_M_nu >= result_type(0));
949 _GLIBCXX_DEBUG_ASSERT(_M_sigma > result_type(0));
961 operator==(const param_type& __p1, const param_type& __p2)
962 { return __p1._M_nu == __p2._M_nu
963 && __p1._M_sigma == __p2._M_sigma; }
966 void _M_initialize();
969 result_type _M_sigma;
973 * @brief Constructors.
976 rice_distribution(result_type __nu_val = result_type(0),
977 result_type __sigma_val = result_type(1))
978 : _M_param(__nu_val, __sigma_val),
979 _M_ndx(__nu_val, __sigma_val),
980 _M_ndy(result_type(0), __sigma_val)
984 rice_distribution(const param_type& __p)
986 _M_ndx(__p.nu(), __p.sigma()),
987 _M_ndy(result_type(0), __p.sigma())
991 * @brief Resets the distribution state.
1001 * @brief Return the parameters of the distribution.
1005 { return _M_param.nu(); }
1009 { return _M_param.sigma(); }
1012 * @brief Returns the parameter set of the distribution.
1016 { return _M_param; }
1019 * @brief Sets the parameter set of the distribution.
1020 * @param __param The new parameter set of the distribution.
1023 param(const param_type& __param)
1024 { _M_param = __param; }
1027 * @brief Returns the greatest lower bound value of the distribution.
1031 { return result_type(0); }
1034 * @brief Returns the least upper bound value of the distribution.
1038 { return std::numeric_limits<result_type>::max(); }
1041 * @brief Generating functions.
1043 template<typename _UniformRandomNumberGenerator>
1045 operator()(_UniformRandomNumberGenerator& __urng)
1047 result_type __x = this->_M_ndx(__urng);
1048 result_type __y = this->_M_ndy(__urng);
1049 #if _GLIBCXX_USE_C99_MATH_TR1
1050 return std::hypot(__x, __y);
1052 return std::sqrt(__x * __x + __y * __y);
1056 template<typename _UniformRandomNumberGenerator>
1058 operator()(_UniformRandomNumberGenerator& __urng,
1059 const param_type& __p)
1061 typename std::normal_distribution<result_type>::param_type
1062 __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
1063 result_type __x = this->_M_ndx(__px, __urng);
1064 result_type __y = this->_M_ndy(__py, __urng);
1065 #if _GLIBCXX_USE_C99_MATH_TR1
1066 return std::hypot(__x, __y);
1068 return std::sqrt(__x * __x + __y * __y);
1072 template<typename _ForwardIterator,
1073 typename _UniformRandomNumberGenerator>
1075 __generate(_ForwardIterator __f, _ForwardIterator __t,
1076 _UniformRandomNumberGenerator& __urng)
1077 { this->__generate(__f, __t, __urng, _M_param); }
1079 template<typename _ForwardIterator,
1080 typename _UniformRandomNumberGenerator>
1082 __generate(_ForwardIterator __f, _ForwardIterator __t,
1083 _UniformRandomNumberGenerator& __urng,
1084 const param_type& __p)
1085 { this->__generate_impl(__f, __t, __urng, __p); }
1087 template<typename _UniformRandomNumberGenerator>
1089 __generate(result_type* __f, result_type* __t,
1090 _UniformRandomNumberGenerator& __urng,
1091 const param_type& __p)
1092 { this->__generate_impl(__f, __t, __urng, __p); }
1095 * @brief Return true if two Rice distributions have
1096 * the same parameters and the sequences that would
1097 * be generated are equal.
1100 operator==(const rice_distribution& __d1,
1101 const rice_distribution& __d2)
1102 { return (__d1._M_param == __d2._M_param
1103 && __d1._M_ndx == __d2._M_ndx
1104 && __d1._M_ndy == __d2._M_ndy); }
1107 * @brief Inserts a %rice_distribution random number distribution
1108 * @p __x into the output stream @p __os.
1110 * @param __os An output stream.
1111 * @param __x A %rice_distribution random number distribution.
1113 * @returns The output stream with the state of @p __x inserted or in
1116 template<typename _RealType1, typename _CharT, typename _Traits>
1117 friend std::basic_ostream<_CharT, _Traits>&
1118 operator<<(std::basic_ostream<_CharT, _Traits>&,
1119 const rice_distribution<_RealType1>&);
1122 * @brief Extracts a %rice_distribution random number distribution
1123 * @p __x from the input stream @p __is.
1125 * @param __is An input stream.
1126 * @param __x A %rice_distribution random number
1129 * @returns The input stream with @p __x extracted or in an error state.
1131 template<typename _RealType1, typename _CharT, typename _Traits>
1132 friend std::basic_istream<_CharT, _Traits>&
1133 operator>>(std::basic_istream<_CharT, _Traits>&,
1134 rice_distribution<_RealType1>&);
1137 template<typename _ForwardIterator,
1138 typename _UniformRandomNumberGenerator>
1140 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1141 _UniformRandomNumberGenerator& __urng,
1142 const param_type& __p);
1144 param_type _M_param;
1146 std::normal_distribution<result_type> _M_ndx;
1147 std::normal_distribution<result_type> _M_ndy;
1151 * @brief Return true if two Rice distributions are not equal.
1153 template<typename _RealType1>
1155 operator!=(const rice_distribution<_RealType1>& __d1,
1156 const rice_distribution<_RealType1>& __d2)
1157 { return !(__d1 == __d2); }
1161 * @brief A Nakagami continuous distribution for random numbers.
1163 * The formula for the Nakagami probability density function is
1165 * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu}
1166 * x^{2\mu-1}e^{-\mu x / \omega}
1168 * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$
1169 * and @f$\omega > 0@f$.
1171 template<typename _RealType = double>
1173 nakagami_distribution
1175 static_assert(std::is_floating_point<_RealType>::value,
1176 "template argument not a floating point type");
1179 /** The type of the range of the distribution. */
1180 typedef _RealType result_type;
1181 /** Parameter type. */
1184 typedef nakagami_distribution<result_type> distribution_type;
1186 param_type(result_type __mu_val = result_type(1),
1187 result_type __omega_val = result_type(1))
1188 : _M_mu(__mu_val), _M_omega(__omega_val)
1190 _GLIBCXX_DEBUG_ASSERT(_M_mu >= result_type(0.5L));
1191 _GLIBCXX_DEBUG_ASSERT(_M_omega > result_type(0));
1200 { return _M_omega; }
1203 operator==(const param_type& __p1, const param_type& __p2)
1204 { return __p1._M_mu == __p2._M_mu
1205 && __p1._M_omega == __p2._M_omega; }
1208 void _M_initialize();
1211 result_type _M_omega;
1215 * @brief Constructors.
1218 nakagami_distribution(result_type __mu_val = result_type(1),
1219 result_type __omega_val = result_type(1))
1220 : _M_param(__mu_val, __omega_val),
1221 _M_gd(__mu_val, __omega_val / __mu_val)
1225 nakagami_distribution(const param_type& __p)
1227 _M_gd(__p.mu(), __p.omega() / __p.mu())
1231 * @brief Resets the distribution state.
1238 * @brief Return the parameters of the distribution.
1242 { return _M_param.mu(); }
1246 { return _M_param.omega(); }
1249 * @brief Returns the parameter set of the distribution.
1253 { return _M_param; }
1256 * @brief Sets the parameter set of the distribution.
1257 * @param __param The new parameter set of the distribution.
1260 param(const param_type& __param)
1261 { _M_param = __param; }
1264 * @brief Returns the greatest lower bound value of the distribution.
1268 { return result_type(0); }
1271 * @brief Returns the least upper bound value of the distribution.
1275 { return std::numeric_limits<result_type>::max(); }
1278 * @brief Generating functions.
1280 template<typename _UniformRandomNumberGenerator>
1282 operator()(_UniformRandomNumberGenerator& __urng)
1283 { return std::sqrt(this->_M_gd(__urng)); }
1285 template<typename _UniformRandomNumberGenerator>
1287 operator()(_UniformRandomNumberGenerator& __urng,
1288 const param_type& __p)
1290 typename std::gamma_distribution<result_type>::param_type
1291 __pg(__p.mu(), __p.omega() / __p.mu());
1292 return std::sqrt(this->_M_gd(__pg, __urng));
1295 template<typename _ForwardIterator,
1296 typename _UniformRandomNumberGenerator>
1298 __generate(_ForwardIterator __f, _ForwardIterator __t,
1299 _UniformRandomNumberGenerator& __urng)
1300 { this->__generate(__f, __t, __urng, _M_param); }
1302 template<typename _ForwardIterator,
1303 typename _UniformRandomNumberGenerator>
1305 __generate(_ForwardIterator __f, _ForwardIterator __t,
1306 _UniformRandomNumberGenerator& __urng,
1307 const param_type& __p)
1308 { this->__generate_impl(__f, __t, __urng, __p); }
1310 template<typename _UniformRandomNumberGenerator>
1312 __generate(result_type* __f, result_type* __t,
1313 _UniformRandomNumberGenerator& __urng,
1314 const param_type& __p)
1315 { this->__generate_impl(__f, __t, __urng, __p); }
1318 * @brief Return true if two Nakagami distributions have
1319 * the same parameters and the sequences that would
1320 * be generated are equal.
1323 operator==(const nakagami_distribution& __d1,
1324 const nakagami_distribution& __d2)
1325 { return (__d1._M_param == __d2._M_param
1326 && __d1._M_gd == __d2._M_gd); }
1329 * @brief Inserts a %nakagami_distribution random number distribution
1330 * @p __x into the output stream @p __os.
1332 * @param __os An output stream.
1333 * @param __x A %nakagami_distribution random number distribution.
1335 * @returns The output stream with the state of @p __x inserted or in
1338 template<typename _RealType1, typename _CharT, typename _Traits>
1339 friend std::basic_ostream<_CharT, _Traits>&
1340 operator<<(std::basic_ostream<_CharT, _Traits>&,
1341 const nakagami_distribution<_RealType1>&);
1344 * @brief Extracts a %nakagami_distribution random number distribution
1345 * @p __x from the input stream @p __is.
1347 * @param __is An input stream.
1348 * @param __x A %nakagami_distribution random number
1351 * @returns The input stream with @p __x extracted or in an error state.
1353 template<typename _RealType1, typename _CharT, typename _Traits>
1354 friend std::basic_istream<_CharT, _Traits>&
1355 operator>>(std::basic_istream<_CharT, _Traits>&,
1356 nakagami_distribution<_RealType1>&);
1359 template<typename _ForwardIterator,
1360 typename _UniformRandomNumberGenerator>
1362 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1363 _UniformRandomNumberGenerator& __urng,
1364 const param_type& __p);
1366 param_type _M_param;
1368 std::gamma_distribution<result_type> _M_gd;
1372 * @brief Return true if two Nakagami distributions are not equal.
1374 template<typename _RealType>
1376 operator!=(const nakagami_distribution<_RealType>& __d1,
1377 const nakagami_distribution<_RealType>& __d2)
1378 { return !(__d1 == __d2); }
1382 * @brief A Pareto continuous distribution for random numbers.
1384 * The formula for the Pareto cumulative probability function is
1386 * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha
1388 * The formula for the Pareto probability density function is
1390 * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu}
1391 * \left(\frac{\mu}{x}\right)^{\alpha + 1}
1393 * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$.
1395 * <table border=1 cellpadding=10 cellspacing=0>
1396 * <caption align=top>Distribution Statistics</caption>
1397 * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$
1398 * for @f$\alpha > 1@f$</td></tr>
1399 * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$
1400 * for @f$\alpha > 2@f$</td></tr>
1401 * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr>
1404 template<typename _RealType = double>
1408 static_assert(std::is_floating_point<_RealType>::value,
1409 "template argument not a floating point type");
1412 /** The type of the range of the distribution. */
1413 typedef _RealType result_type;
1414 /** Parameter type. */
1417 typedef pareto_distribution<result_type> distribution_type;
1419 param_type(result_type __alpha_val = result_type(1),
1420 result_type __mu_val = result_type(1))
1421 : _M_alpha(__alpha_val), _M_mu(__mu_val)
1423 _GLIBCXX_DEBUG_ASSERT(_M_alpha > result_type(0));
1424 _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0));
1429 { return _M_alpha; }
1436 operator==(const param_type& __p1, const param_type& __p2)
1437 { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; }
1440 void _M_initialize();
1442 result_type _M_alpha;
1447 * @brief Constructors.
1450 pareto_distribution(result_type __alpha_val = result_type(1),
1451 result_type __mu_val = result_type(1))
1452 : _M_param(__alpha_val, __mu_val),
1457 pareto_distribution(const param_type& __p)
1463 * @brief Resets the distribution state.
1472 * @brief Return the parameters of the distribution.
1476 { return _M_param.alpha(); }
1480 { return _M_param.mu(); }
1483 * @brief Returns the parameter set of the distribution.
1487 { return _M_param; }
1490 * @brief Sets the parameter set of the distribution.
1491 * @param __param The new parameter set of the distribution.
1494 param(const param_type& __param)
1495 { _M_param = __param; }
1498 * @brief Returns the greatest lower bound value of the distribution.
1502 { return this->mu(); }
1505 * @brief Returns the least upper bound value of the distribution.
1509 { return std::numeric_limits<result_type>::max(); }
1512 * @brief Generating functions.
1514 template<typename _UniformRandomNumberGenerator>
1516 operator()(_UniformRandomNumberGenerator& __urng)
1518 return this->mu() * std::pow(this->_M_ud(__urng),
1519 -result_type(1) / this->alpha());
1522 template<typename _UniformRandomNumberGenerator>
1524 operator()(_UniformRandomNumberGenerator& __urng,
1525 const param_type& __p)
1527 return __p.mu() * std::pow(this->_M_ud(__urng),
1528 -result_type(1) / __p.alpha());
1531 template<typename _ForwardIterator,
1532 typename _UniformRandomNumberGenerator>
1534 __generate(_ForwardIterator __f, _ForwardIterator __t,
1535 _UniformRandomNumberGenerator& __urng)
1536 { this->__generate(__f, __t, __urng, _M_param); }
1538 template<typename _ForwardIterator,
1539 typename _UniformRandomNumberGenerator>
1541 __generate(_ForwardIterator __f, _ForwardIterator __t,
1542 _UniformRandomNumberGenerator& __urng,
1543 const param_type& __p)
1544 { this->__generate_impl(__f, __t, __urng, __p); }
1546 template<typename _UniformRandomNumberGenerator>
1548 __generate(result_type* __f, result_type* __t,
1549 _UniformRandomNumberGenerator& __urng,
1550 const param_type& __p)
1551 { this->__generate_impl(__f, __t, __urng, __p); }
1554 * @brief Return true if two Pareto distributions have
1555 * the same parameters and the sequences that would
1556 * be generated are equal.
1559 operator==(const pareto_distribution& __d1,
1560 const pareto_distribution& __d2)
1561 { return (__d1._M_param == __d2._M_param
1562 && __d1._M_ud == __d2._M_ud); }
1565 * @brief Inserts a %pareto_distribution random number distribution
1566 * @p __x into the output stream @p __os.
1568 * @param __os An output stream.
1569 * @param __x A %pareto_distribution random number distribution.
1571 * @returns The output stream with the state of @p __x inserted or in
1574 template<typename _RealType1, typename _CharT, typename _Traits>
1575 friend std::basic_ostream<_CharT, _Traits>&
1576 operator<<(std::basic_ostream<_CharT, _Traits>&,
1577 const pareto_distribution<_RealType1>&);
1580 * @brief Extracts a %pareto_distribution random number distribution
1581 * @p __x from the input stream @p __is.
1583 * @param __is An input stream.
1584 * @param __x A %pareto_distribution random number
1587 * @returns The input stream with @p __x extracted or in an error state.
1589 template<typename _RealType1, typename _CharT, typename _Traits>
1590 friend std::basic_istream<_CharT, _Traits>&
1591 operator>>(std::basic_istream<_CharT, _Traits>&,
1592 pareto_distribution<_RealType1>&);
1595 template<typename _ForwardIterator,
1596 typename _UniformRandomNumberGenerator>
1598 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1599 _UniformRandomNumberGenerator& __urng,
1600 const param_type& __p);
1602 param_type _M_param;
1604 std::uniform_real_distribution<result_type> _M_ud;
1608 * @brief Return true if two Pareto distributions are not equal.
1610 template<typename _RealType>
1612 operator!=(const pareto_distribution<_RealType>& __d1,
1613 const pareto_distribution<_RealType>& __d2)
1614 { return !(__d1 == __d2); }
1618 * @brief A K continuous distribution for random numbers.
1620 * The formula for the K probability density function is
1622 * p(x|\lambda, \mu, \nu) = \frac{2}{x}
1623 * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}}
1624 * \frac{1}{\Gamma(\lambda)\Gamma(\nu)}
1625 * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right)
1627 * where @f$I_0(z)@f$ is the modified Bessel function of the second kind
1628 * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$
1629 * and @f$\nu > 0@f$.
1631 * <table border=1 cellpadding=10 cellspacing=0>
1632 * <caption align=top>Distribution Statistics</caption>
1633 * <tr><td>Mean</td><td>@f$\mu@f$</td></tr>
1634 * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr>
1635 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
1638 template<typename _RealType = double>
1642 static_assert(std::is_floating_point<_RealType>::value,
1643 "template argument not a floating point type");
1646 /** The type of the range of the distribution. */
1647 typedef _RealType result_type;
1648 /** Parameter type. */
1651 typedef k_distribution<result_type> distribution_type;
1653 param_type(result_type __lambda_val = result_type(1),
1654 result_type __mu_val = result_type(1),
1655 result_type __nu_val = result_type(1))
1656 : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val)
1658 _GLIBCXX_DEBUG_ASSERT(_M_lambda > result_type(0));
1659 _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0));
1660 _GLIBCXX_DEBUG_ASSERT(_M_nu > result_type(0));
1665 { return _M_lambda; }
1676 operator==(const param_type& __p1, const param_type& __p2)
1677 { return __p1._M_lambda == __p2._M_lambda
1678 && __p1._M_mu == __p2._M_mu
1679 && __p1._M_nu == __p2._M_nu; }
1682 void _M_initialize();
1684 result_type _M_lambda;
1690 * @brief Constructors.
1693 k_distribution(result_type __lambda_val = result_type(1),
1694 result_type __mu_val = result_type(1),
1695 result_type __nu_val = result_type(1))
1696 : _M_param(__lambda_val, __mu_val, __nu_val),
1697 _M_gd1(__lambda_val, result_type(1) / __lambda_val),
1698 _M_gd2(__nu_val, __mu_val / __nu_val)
1702 k_distribution(const param_type& __p)
1704 _M_gd1(__p.lambda(), result_type(1) / __p.lambda()),
1705 _M_gd2(__p.nu(), __p.mu() / __p.nu())
1709 * @brief Resets the distribution state.
1719 * @brief Return the parameters of the distribution.
1723 { return _M_param.lambda(); }
1727 { return _M_param.mu(); }
1731 { return _M_param.nu(); }
1734 * @brief Returns the parameter set of the distribution.
1738 { return _M_param; }
1741 * @brief Sets the parameter set of the distribution.
1742 * @param __param The new parameter set of the distribution.
1745 param(const param_type& __param)
1746 { _M_param = __param; }
1749 * @brief Returns the greatest lower bound value of the distribution.
1753 { return result_type(0); }
1756 * @brief Returns the least upper bound value of the distribution.
1760 { return std::numeric_limits<result_type>::max(); }
1763 * @brief Generating functions.
1765 template<typename _UniformRandomNumberGenerator>
1767 operator()(_UniformRandomNumberGenerator&);
1769 template<typename _UniformRandomNumberGenerator>
1771 operator()(_UniformRandomNumberGenerator&, const param_type&);
1773 template<typename _ForwardIterator,
1774 typename _UniformRandomNumberGenerator>
1776 __generate(_ForwardIterator __f, _ForwardIterator __t,
1777 _UniformRandomNumberGenerator& __urng)
1778 { this->__generate(__f, __t, __urng, _M_param); }
1780 template<typename _ForwardIterator,
1781 typename _UniformRandomNumberGenerator>
1783 __generate(_ForwardIterator __f, _ForwardIterator __t,
1784 _UniformRandomNumberGenerator& __urng,
1785 const param_type& __p)
1786 { this->__generate_impl(__f, __t, __urng, __p); }
1788 template<typename _UniformRandomNumberGenerator>
1790 __generate(result_type* __f, result_type* __t,
1791 _UniformRandomNumberGenerator& __urng,
1792 const param_type& __p)
1793 { this->__generate_impl(__f, __t, __urng, __p); }
1796 * @brief Return true if two K distributions have
1797 * the same parameters and the sequences that would
1798 * be generated are equal.
1801 operator==(const k_distribution& __d1,
1802 const k_distribution& __d2)
1803 { return (__d1._M_param == __d2._M_param
1804 && __d1._M_gd1 == __d2._M_gd1
1805 && __d1._M_gd2 == __d2._M_gd2); }
1808 * @brief Inserts a %k_distribution random number distribution
1809 * @p __x into the output stream @p __os.
1811 * @param __os An output stream.
1812 * @param __x A %k_distribution random number distribution.
1814 * @returns The output stream with the state of @p __x inserted or in
1817 template<typename _RealType1, typename _CharT, typename _Traits>
1818 friend std::basic_ostream<_CharT, _Traits>&
1819 operator<<(std::basic_ostream<_CharT, _Traits>&,
1820 const k_distribution<_RealType1>&);
1823 * @brief Extracts a %k_distribution random number distribution
1824 * @p __x from the input stream @p __is.
1826 * @param __is An input stream.
1827 * @param __x A %k_distribution random number
1830 * @returns The input stream with @p __x extracted or in an error state.
1832 template<typename _RealType1, typename _CharT, typename _Traits>
1833 friend std::basic_istream<_CharT, _Traits>&
1834 operator>>(std::basic_istream<_CharT, _Traits>&,
1835 k_distribution<_RealType1>&);
1838 template<typename _ForwardIterator,
1839 typename _UniformRandomNumberGenerator>
1841 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1842 _UniformRandomNumberGenerator& __urng,
1843 const param_type& __p);
1845 param_type _M_param;
1847 std::gamma_distribution<result_type> _M_gd1;
1848 std::gamma_distribution<result_type> _M_gd2;
1852 * @brief Return true if two K distributions are not equal.
1854 template<typename _RealType>
1856 operator!=(const k_distribution<_RealType>& __d1,
1857 const k_distribution<_RealType>& __d2)
1858 { return !(__d1 == __d2); }
1862 * @brief An arcsine continuous distribution for random numbers.
1864 * The formula for the arcsine probability density function is
1866 * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
1868 * where @f$x >= a@f$ and @f$x <= b@f$.
1870 * <table border=1 cellpadding=10 cellspacing=0>
1871 * <caption align=top>Distribution Statistics</caption>
1872 * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr>
1873 * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr>
1874 * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr>
1877 template<typename _RealType = double>
1879 arcsine_distribution
1881 static_assert(std::is_floating_point<_RealType>::value,
1882 "template argument not a floating point type");
1885 /** The type of the range of the distribution. */
1886 typedef _RealType result_type;
1887 /** Parameter type. */
1890 typedef arcsine_distribution<result_type> distribution_type;
1892 param_type(result_type __a = result_type(0),
1893 result_type __b = result_type(1))
1894 : _M_a(__a), _M_b(__b)
1896 _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1908 operator==(const param_type& __p1, const param_type& __p2)
1909 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1912 void _M_initialize();
1919 * @brief Constructors.
1922 arcsine_distribution(result_type __a = result_type(0),
1923 result_type __b = result_type(1))
1924 : _M_param(__a, __b),
1925 _M_ud(-1.5707963267948966192313216916397514L,
1926 +1.5707963267948966192313216916397514L)
1930 arcsine_distribution(const param_type& __p)
1932 _M_ud(-1.5707963267948966192313216916397514L,
1933 +1.5707963267948966192313216916397514L)
1937 * @brief Resets the distribution state.
1944 * @brief Return the parameters of the distribution.
1948 { return _M_param.a(); }
1952 { return _M_param.b(); }
1955 * @brief Returns the parameter set of the distribution.
1959 { return _M_param; }
1962 * @brief Sets the parameter set of the distribution.
1963 * @param __param The new parameter set of the distribution.
1966 param(const param_type& __param)
1967 { _M_param = __param; }
1970 * @brief Returns the greatest lower bound value of the distribution.
1974 { return this->a(); }
1977 * @brief Returns the least upper bound value of the distribution.
1981 { return this->b(); }
1984 * @brief Generating functions.
1986 template<typename _UniformRandomNumberGenerator>
1988 operator()(_UniformRandomNumberGenerator& __urng)
1990 result_type __x = std::sin(this->_M_ud(__urng));
1991 return (__x * (this->b() - this->a())
1992 + this->a() + this->b()) / result_type(2);
1995 template<typename _UniformRandomNumberGenerator>
1997 operator()(_UniformRandomNumberGenerator& __urng,
1998 const param_type& __p)
2000 result_type __x = std::sin(this->_M_ud(__urng));
2001 return (__x * (__p.b() - __p.a())
2002 + __p.a() + __p.b()) / result_type(2);
2005 template<typename _ForwardIterator,
2006 typename _UniformRandomNumberGenerator>
2008 __generate(_ForwardIterator __f, _ForwardIterator __t,
2009 _UniformRandomNumberGenerator& __urng)
2010 { this->__generate(__f, __t, __urng, _M_param); }
2012 template<typename _ForwardIterator,
2013 typename _UniformRandomNumberGenerator>
2015 __generate(_ForwardIterator __f, _ForwardIterator __t,
2016 _UniformRandomNumberGenerator& __urng,
2017 const param_type& __p)
2018 { this->__generate_impl(__f, __t, __urng, __p); }
2020 template<typename _UniformRandomNumberGenerator>
2022 __generate(result_type* __f, result_type* __t,
2023 _UniformRandomNumberGenerator& __urng,
2024 const param_type& __p)
2025 { this->__generate_impl(__f, __t, __urng, __p); }
2028 * @brief Return true if two arcsine distributions have
2029 * the same parameters and the sequences that would
2030 * be generated are equal.
2033 operator==(const arcsine_distribution& __d1,
2034 const arcsine_distribution& __d2)
2035 { return (__d1._M_param == __d2._M_param
2036 && __d1._M_ud == __d2._M_ud); }
2039 * @brief Inserts a %arcsine_distribution random number distribution
2040 * @p __x into the output stream @p __os.
2042 * @param __os An output stream.
2043 * @param __x A %arcsine_distribution random number distribution.
2045 * @returns The output stream with the state of @p __x inserted or in
2048 template<typename _RealType1, typename _CharT, typename _Traits>
2049 friend std::basic_ostream<_CharT, _Traits>&
2050 operator<<(std::basic_ostream<_CharT, _Traits>&,
2051 const arcsine_distribution<_RealType1>&);
2054 * @brief Extracts a %arcsine_distribution random number distribution
2055 * @p __x from the input stream @p __is.
2057 * @param __is An input stream.
2058 * @param __x A %arcsine_distribution random number
2061 * @returns The input stream with @p __x extracted or in an error state.
2063 template<typename _RealType1, typename _CharT, typename _Traits>
2064 friend std::basic_istream<_CharT, _Traits>&
2065 operator>>(std::basic_istream<_CharT, _Traits>&,
2066 arcsine_distribution<_RealType1>&);
2069 template<typename _ForwardIterator,
2070 typename _UniformRandomNumberGenerator>
2072 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2073 _UniformRandomNumberGenerator& __urng,
2074 const param_type& __p);
2076 param_type _M_param;
2078 std::uniform_real_distribution<result_type> _M_ud;
2082 * @brief Return true if two arcsine distributions are not equal.
2084 template<typename _RealType>
2086 operator!=(const arcsine_distribution<_RealType>& __d1,
2087 const arcsine_distribution<_RealType>& __d2)
2088 { return !(__d1 == __d2); }
2092 * @brief A Hoyt continuous distribution for random numbers.
2094 * The formula for the Hoyt probability density function is
2096 * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
2097 * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
2098 * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
2100 * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
2101 * of order 0 and @f$0 < q < 1@f$.
2103 * <table border=1 cellpadding=10 cellspacing=0>
2104 * <caption align=top>Distribution Statistics</caption>
2105 * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
2106 * E(1 - q^2) @f$</td></tr>
2107 * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
2108 * {\pi (1 + q^2)}\right) @f$</td></tr>
2109 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
2111 * where @f$E(x)@f$ is the elliptic function of the second kind.
2113 template<typename _RealType = double>
2117 static_assert(std::is_floating_point<_RealType>::value,
2118 "template argument not a floating point type");
2121 /** The type of the range of the distribution. */
2122 typedef _RealType result_type;
2123 /** Parameter type. */
2126 typedef hoyt_distribution<result_type> distribution_type;
2128 param_type(result_type __q = result_type(0.5L),
2129 result_type __omega = result_type(1))
2130 : _M_q(__q), _M_omega(__omega)
2132 _GLIBCXX_DEBUG_ASSERT(_M_q > result_type(0));
2133 _GLIBCXX_DEBUG_ASSERT(_M_q < result_type(1));
2142 { return _M_omega; }
2145 operator==(const param_type& __p1, const param_type& __p2)
2146 { return __p1._M_q == __p2._M_q
2147 && __p1._M_omega == __p2._M_omega; }
2150 void _M_initialize();
2153 result_type _M_omega;
2157 * @brief Constructors.
2160 hoyt_distribution(result_type __q = result_type(0.5L),
2161 result_type __omega = result_type(1))
2162 : _M_param(__q, __omega),
2163 _M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
2164 result_type(0.5L) * (result_type(1) + __q * __q)
2166 _M_ed(result_type(1))
2170 hoyt_distribution(const param_type& __p)
2172 _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
2173 result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
2174 / (__p.q() * __p.q())),
2175 _M_ed(result_type(1))
2179 * @brief Resets the distribution state.
2189 * @brief Return the parameters of the distribution.
2193 { return _M_param.q(); }
2197 { return _M_param.omega(); }
2200 * @brief Returns the parameter set of the distribution.
2204 { return _M_param; }
2207 * @brief Sets the parameter set of the distribution.
2208 * @param __param The new parameter set of the distribution.
2211 param(const param_type& __param)
2212 { _M_param = __param; }
2215 * @brief Returns the greatest lower bound value of the distribution.
2219 { return result_type(0); }
2222 * @brief Returns the least upper bound value of the distribution.
2226 { return std::numeric_limits<result_type>::max(); }
2229 * @brief Generating functions.
2231 template<typename _UniformRandomNumberGenerator>
2233 operator()(_UniformRandomNumberGenerator& __urng);
2235 template<typename _UniformRandomNumberGenerator>
2237 operator()(_UniformRandomNumberGenerator& __urng,
2238 const param_type& __p);
2240 template<typename _ForwardIterator,
2241 typename _UniformRandomNumberGenerator>
2243 __generate(_ForwardIterator __f, _ForwardIterator __t,
2244 _UniformRandomNumberGenerator& __urng)
2245 { this->__generate(__f, __t, __urng, _M_param); }
2247 template<typename _ForwardIterator,
2248 typename _UniformRandomNumberGenerator>
2250 __generate(_ForwardIterator __f, _ForwardIterator __t,
2251 _UniformRandomNumberGenerator& __urng,
2252 const param_type& __p)
2253 { this->__generate_impl(__f, __t, __urng, __p); }
2255 template<typename _UniformRandomNumberGenerator>
2257 __generate(result_type* __f, result_type* __t,
2258 _UniformRandomNumberGenerator& __urng,
2259 const param_type& __p)
2260 { this->__generate_impl(__f, __t, __urng, __p); }
2263 * @brief Return true if two Hoyt distributions have
2264 * the same parameters and the sequences that would
2265 * be generated are equal.
2268 operator==(const hoyt_distribution& __d1,
2269 const hoyt_distribution& __d2)
2270 { return (__d1._M_param == __d2._M_param
2271 && __d1._M_ad == __d2._M_ad
2272 && __d1._M_ed == __d2._M_ed); }
2275 * @brief Inserts a %hoyt_distribution random number distribution
2276 * @p __x into the output stream @p __os.
2278 * @param __os An output stream.
2279 * @param __x A %hoyt_distribution random number distribution.
2281 * @returns The output stream with the state of @p __x inserted or in
2284 template<typename _RealType1, typename _CharT, typename _Traits>
2285 friend std::basic_ostream<_CharT, _Traits>&
2286 operator<<(std::basic_ostream<_CharT, _Traits>&,
2287 const hoyt_distribution<_RealType1>&);
2290 * @brief Extracts a %hoyt_distribution random number distribution
2291 * @p __x from the input stream @p __is.
2293 * @param __is An input stream.
2294 * @param __x A %hoyt_distribution random number
2297 * @returns The input stream with @p __x extracted or in an error state.
2299 template<typename _RealType1, typename _CharT, typename _Traits>
2300 friend std::basic_istream<_CharT, _Traits>&
2301 operator>>(std::basic_istream<_CharT, _Traits>&,
2302 hoyt_distribution<_RealType1>&);
2305 template<typename _ForwardIterator,
2306 typename _UniformRandomNumberGenerator>
2308 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2309 _UniformRandomNumberGenerator& __urng,
2310 const param_type& __p);
2312 param_type _M_param;
2314 __gnu_cxx::arcsine_distribution<result_type> _M_ad;
2315 std::exponential_distribution<result_type> _M_ed;
2319 * @brief Return true if two Hoyt distributions are not equal.
2321 template<typename _RealType>
2323 operator!=(const hoyt_distribution<_RealType>& __d1,
2324 const hoyt_distribution<_RealType>& __d2)
2325 { return !(__d1 == __d2); }
2329 * @brief A triangular distribution for random numbers.
2331 * The formula for the triangular probability density function is
2334 * p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)} for a <= x <= b
2335 * | \frac{2(c-x)}{(c-a)(c-b)} for b < x <= c
2339 * <table border=1 cellpadding=10 cellspacing=0>
2340 * <caption align=top>Distribution Statistics</caption>
2341 * <tr><td>Mean</td><td>@f$ \frac{a+b+c}{2} @f$</td></tr>
2342 * <tr><td>Variance</td><td>@f$ \frac{a^2+b^2+c^2-ab-ac-bc}
2344 * <tr><td>Range</td><td>@f$[a, c]@f$</td></tr>
2347 template<typename _RealType = double>
2348 class triangular_distribution
2350 static_assert(std::is_floating_point<_RealType>::value,
2351 "template argument not a floating point type");
2354 /** The type of the range of the distribution. */
2355 typedef _RealType result_type;
2356 /** Parameter type. */
2359 friend class triangular_distribution<_RealType>;
2362 param_type(_RealType __a = _RealType(0),
2363 _RealType __b = _RealType(0.5),
2364 _RealType __c = _RealType(1))
2365 : _M_a(__a), _M_b(__b), _M_c(__c)
2367 _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
2368 _GLIBCXX_DEBUG_ASSERT(_M_b <= _M_c);
2369 _GLIBCXX_DEBUG_ASSERT(_M_a < _M_c);
2371 _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a);
2372 _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a);
2373 _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a);
2389 operator==(const param_type& __p1, const param_type& __p2)
2390 { return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b
2391 && __p1._M_c == __p2._M_c); }
2399 _RealType _M_f_ab_ac;
2400 _RealType _M_f_bc_ac;
2404 * @brief Constructs a triangle distribution with parameters
2405 * @f$ a @f$, @f$ b @f$ and @f$ c @f$.
2408 triangular_distribution(result_type __a = result_type(0),
2409 result_type __b = result_type(0.5),
2410 result_type __c = result_type(1))
2411 : _M_param(__a, __b, __c)
2415 triangular_distribution(const param_type& __p)
2420 * @brief Resets the distribution state.
2427 * @brief Returns the @f$ a @f$ of the distribution.
2431 { return _M_param.a(); }
2434 * @brief Returns the @f$ b @f$ of the distribution.
2438 { return _M_param.b(); }
2441 * @brief Returns the @f$ c @f$ of the distribution.
2445 { return _M_param.c(); }
2448 * @brief Returns the parameter set of the distribution.
2452 { return _M_param; }
2455 * @brief Sets the parameter set of the distribution.
2456 * @param __param The new parameter set of the distribution.
2459 param(const param_type& __param)
2460 { _M_param = __param; }
2463 * @brief Returns the greatest lower bound value of the distribution.
2467 { return _M_param._M_a; }
2470 * @brief Returns the least upper bound value of the distribution.
2474 { return _M_param._M_c; }
2477 * @brief Generating functions.
2479 template<typename _UniformRandomNumberGenerator>
2481 operator()(_UniformRandomNumberGenerator& __urng)
2482 { return this->operator()(__urng, _M_param); }
2484 template<typename _UniformRandomNumberGenerator>
2486 operator()(_UniformRandomNumberGenerator& __urng,
2487 const param_type& __p)
2489 std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2491 result_type __rnd = __aurng();
2492 if (__rnd <= __p._M_r_ab)
2493 return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac);
2495 return __p.c() - std::sqrt((result_type(1) - __rnd)
2499 template<typename _ForwardIterator,
2500 typename _UniformRandomNumberGenerator>
2502 __generate(_ForwardIterator __f, _ForwardIterator __t,
2503 _UniformRandomNumberGenerator& __urng)
2504 { this->__generate(__f, __t, __urng, _M_param); }
2506 template<typename _ForwardIterator,
2507 typename _UniformRandomNumberGenerator>
2509 __generate(_ForwardIterator __f, _ForwardIterator __t,
2510 _UniformRandomNumberGenerator& __urng,
2511 const param_type& __p)
2512 { this->__generate_impl(__f, __t, __urng, __p); }
2514 template<typename _UniformRandomNumberGenerator>
2516 __generate(result_type* __f, result_type* __t,
2517 _UniformRandomNumberGenerator& __urng,
2518 const param_type& __p)
2519 { this->__generate_impl(__f, __t, __urng, __p); }
2522 * @brief Return true if two triangle distributions have the same
2523 * parameters and the sequences that would be generated
2527 operator==(const triangular_distribution& __d1,
2528 const triangular_distribution& __d2)
2529 { return __d1._M_param == __d2._M_param; }
2532 * @brief Inserts a %triangular_distribution random number distribution
2533 * @p __x into the output stream @p __os.
2535 * @param __os An output stream.
2536 * @param __x A %triangular_distribution random number distribution.
2538 * @returns The output stream with the state of @p __x inserted or in
2541 template<typename _RealType1, typename _CharT, typename _Traits>
2542 friend std::basic_ostream<_CharT, _Traits>&
2543 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2544 const __gnu_cxx::triangular_distribution<_RealType1>& __x);
2547 * @brief Extracts a %triangular_distribution random number distribution
2548 * @p __x from the input stream @p __is.
2550 * @param __is An input stream.
2551 * @param __x A %triangular_distribution random number generator engine.
2553 * @returns The input stream with @p __x extracted or in an error state.
2555 template<typename _RealType1, typename _CharT, typename _Traits>
2556 friend std::basic_istream<_CharT, _Traits>&
2557 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2558 __gnu_cxx::triangular_distribution<_RealType1>& __x);
2561 template<typename _ForwardIterator,
2562 typename _UniformRandomNumberGenerator>
2564 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2565 _UniformRandomNumberGenerator& __urng,
2566 const param_type& __p);
2568 param_type _M_param;
2572 * @brief Return true if two triangle distributions are different.
2574 template<typename _RealType>
2576 operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1,
2577 const __gnu_cxx::triangular_distribution<_RealType>& __d2)
2578 { return !(__d1 == __d2); }
2582 * @brief A von Mises distribution for random numbers.
2584 * The formula for the von Mises probability density function is
2586 * p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}}
2587 * {2\pi I_0(\kappa)}
2590 * The generating functions use the method according to:
2592 * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the
2593 * von Mises Distribution", Journal of the Royal Statistical Society.
2594 * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157.
2596 * <table border=1 cellpadding=10 cellspacing=0>
2597 * <caption align=top>Distribution Statistics</caption>
2598 * <tr><td>Mean</td><td>@f$ \mu @f$</td></tr>
2599 * <tr><td>Variance</td><td>@f$ 1-I_1(\kappa)/I_0(\kappa) @f$</td></tr>
2600 * <tr><td>Range</td><td>@f$[-\pi, \pi]@f$</td></tr>
2603 template<typename _RealType = double>
2604 class von_mises_distribution
2606 static_assert(std::is_floating_point<_RealType>::value,
2607 "template argument not a floating point type");
2610 /** The type of the range of the distribution. */
2611 typedef _RealType result_type;
2612 /** Parameter type. */
2615 friend class von_mises_distribution<_RealType>;
2618 param_type(_RealType __mu = _RealType(0),
2619 _RealType __kappa = _RealType(1))
2620 : _M_mu(__mu), _M_kappa(__kappa)
2622 const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi;
2623 _GLIBCXX_DEBUG_ASSERT(_M_mu >= -__pi && _M_mu <= __pi);
2624 _GLIBCXX_DEBUG_ASSERT(_M_kappa >= _RealType(0));
2626 auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa
2627 + _RealType(1)) + _RealType(1);
2628 auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau))
2629 / (_RealType(2) * _M_kappa));
2630 _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho);
2639 { return _M_kappa; }
2642 operator==(const param_type& __p1, const param_type& __p2)
2643 { return (__p1._M_mu == __p2._M_mu
2644 && __p1._M_kappa == __p2._M_kappa); }
2653 * @brief Constructs a von Mises distribution with parameters
2654 * @f$\mu@f$ and @f$\kappa@f$.
2657 von_mises_distribution(result_type __mu = result_type(0),
2658 result_type __kappa = result_type(1))
2659 : _M_param(__mu, __kappa)
2663 von_mises_distribution(const param_type& __p)
2668 * @brief Resets the distribution state.
2675 * @brief Returns the @f$ \mu @f$ of the distribution.
2679 { return _M_param.mu(); }
2682 * @brief Returns the @f$ \kappa @f$ of the distribution.
2686 { return _M_param.kappa(); }
2689 * @brief Returns the parameter set of the distribution.
2693 { return _M_param; }
2696 * @brief Sets the parameter set of the distribution.
2697 * @param __param The new parameter set of the distribution.
2700 param(const param_type& __param)
2701 { _M_param = __param; }
2704 * @brief Returns the greatest lower bound value of the distribution.
2709 return -__gnu_cxx::__math_constants<result_type>::__pi;
2713 * @brief Returns the least upper bound value of the distribution.
2718 return __gnu_cxx::__math_constants<result_type>::__pi;
2722 * @brief Generating functions.
2724 template<typename _UniformRandomNumberGenerator>
2726 operator()(_UniformRandomNumberGenerator& __urng)
2727 { return this->operator()(__urng, _M_param); }
2729 template<typename _UniformRandomNumberGenerator>
2731 operator()(_UniformRandomNumberGenerator& __urng,
2732 const param_type& __p);
2734 template<typename _ForwardIterator,
2735 typename _UniformRandomNumberGenerator>
2737 __generate(_ForwardIterator __f, _ForwardIterator __t,
2738 _UniformRandomNumberGenerator& __urng)
2739 { this->__generate(__f, __t, __urng, _M_param); }
2741 template<typename _ForwardIterator,
2742 typename _UniformRandomNumberGenerator>
2744 __generate(_ForwardIterator __f, _ForwardIterator __t,
2745 _UniformRandomNumberGenerator& __urng,
2746 const param_type& __p)
2747 { this->__generate_impl(__f, __t, __urng, __p); }
2749 template<typename _UniformRandomNumberGenerator>
2751 __generate(result_type* __f, result_type* __t,
2752 _UniformRandomNumberGenerator& __urng,
2753 const param_type& __p)
2754 { this->__generate_impl(__f, __t, __urng, __p); }
2757 * @brief Return true if two von Mises distributions have the same
2758 * parameters and the sequences that would be generated
2762 operator==(const von_mises_distribution& __d1,
2763 const von_mises_distribution& __d2)
2764 { return __d1._M_param == __d2._M_param; }
2767 * @brief Inserts a %von_mises_distribution random number distribution
2768 * @p __x into the output stream @p __os.
2770 * @param __os An output stream.
2771 * @param __x A %von_mises_distribution random number distribution.
2773 * @returns The output stream with the state of @p __x inserted or in
2776 template<typename _RealType1, typename _CharT, typename _Traits>
2777 friend std::basic_ostream<_CharT, _Traits>&
2778 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2779 const __gnu_cxx::von_mises_distribution<_RealType1>& __x);
2782 * @brief Extracts a %von_mises_distribution random number distribution
2783 * @p __x from the input stream @p __is.
2785 * @param __is An input stream.
2786 * @param __x A %von_mises_distribution random number generator engine.
2788 * @returns The input stream with @p __x extracted or in an error state.
2790 template<typename _RealType1, typename _CharT, typename _Traits>
2791 friend std::basic_istream<_CharT, _Traits>&
2792 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2793 __gnu_cxx::von_mises_distribution<_RealType1>& __x);
2796 template<typename _ForwardIterator,
2797 typename _UniformRandomNumberGenerator>
2799 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2800 _UniformRandomNumberGenerator& __urng,
2801 const param_type& __p);
2803 param_type _M_param;
2807 * @brief Return true if two von Mises distributions are different.
2809 template<typename _RealType>
2811 operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1,
2812 const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
2813 { return !(__d1 == __d2); }
2817 * @brief A discrete hypergeometric random number distribution.
2819 * The hypergeometric distribution is a discrete probability distribution
2820 * that describes the probability of @p k successes in @p n draws @a without
2821 * replacement from a finite population of size @p N containing exactly @p K
2824 * The formula for the hypergeometric probability density function is
2826 * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}}
2828 * where @f$N@f$ is the total population of the distribution,
2829 * @f$K@f$ is the total population of the distribution.
2831 * <table border=1 cellpadding=10 cellspacing=0>
2832 * <caption align=top>Distribution Statistics</caption>
2833 * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr>
2834 * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}
2836 * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr>
2839 template<typename _UIntType = unsigned int>
2840 class hypergeometric_distribution
2842 static_assert(std::is_unsigned<_UIntType>::value, "template argument "
2843 "substituting _UIntType not an unsigned integral type");
2846 /** The type of the range of the distribution. */
2847 typedef _UIntType result_type;
2849 /** Parameter type. */
2852 typedef hypergeometric_distribution<_UIntType> distribution_type;
2853 friend class hypergeometric_distribution<_UIntType>;
2856 param_type(result_type __N = 10, result_type __K = 5,
2857 result_type __n = 1)
2858 : _M_N{__N}, _M_K{__K}, _M_n{__n}
2860 _GLIBCXX_DEBUG_ASSERT(_M_N >= _M_K);
2861 _GLIBCXX_DEBUG_ASSERT(_M_N >= _M_n);
2869 successful_size() const
2873 unsuccessful_size() const
2874 { return _M_N - _M_K; }
2881 operator==(const param_type& __p1, const param_type& __p2)
2882 { return (__p1._M_N == __p2._M_N)
2883 && (__p1._M_K == __p2._M_K)
2884 && (__p1._M_n == __p2._M_n); }
2893 // constructors and member function
2895 hypergeometric_distribution(result_type __N = 10, result_type __K = 5,
2896 result_type __n = 1)
2897 : _M_param{__N, __K, __n}
2901 hypergeometric_distribution(const param_type& __p)
2906 * @brief Resets the distribution state.
2913 * @brief Returns the distribution parameter @p N,
2914 * the total number of items.
2918 { return this->_M_param.total_size(); }
2921 * @brief Returns the distribution parameter @p K,
2922 * the total number of successful items.
2925 successful_size() const
2926 { return this->_M_param.successful_size(); }
2929 * @brief Returns the total number of unsuccessful items @f$ N - K @f$.
2932 unsuccessful_size() const
2933 { return this->_M_param.unsuccessful_size(); }
2936 * @brief Returns the distribution parameter @p n,
2937 * the total number of draws.
2941 { return this->_M_param.total_draws(); }
2944 * @brief Returns the parameter set of the distribution.
2948 { return this->_M_param; }
2951 * @brief Sets the parameter set of the distribution.
2952 * @param __param The new parameter set of the distribution.
2955 param(const param_type& __param)
2956 { this->_M_param = __param; }
2959 * @brief Returns the greatest lower bound value of the distribution.
2964 using _IntType = typename std::make_signed<result_type>::type;
2965 return static_cast<result_type>(std::max(static_cast<_IntType>(0),
2966 static_cast<_IntType>(this->total_draws()
2967 - this->unsuccessful_size())));
2971 * @brief Returns the least upper bound value of the distribution.
2975 { return std::min(this->successful_size(), this->total_draws()); }
2978 * @brief Generating functions.
2980 template<typename _UniformRandomNumberGenerator>
2982 operator()(_UniformRandomNumberGenerator& __urng)
2983 { return this->operator()(__urng, this->_M_param); }
2985 template<typename _UniformRandomNumberGenerator>
2987 operator()(_UniformRandomNumberGenerator& __urng,
2988 const param_type& __p);
2990 template<typename _ForwardIterator,
2991 typename _UniformRandomNumberGenerator>
2993 __generate(_ForwardIterator __f, _ForwardIterator __t,
2994 _UniformRandomNumberGenerator& __urng)
2995 { this->__generate(__f, __t, __urng, this->_M_param); }
2997 template<typename _ForwardIterator,
2998 typename _UniformRandomNumberGenerator>
3000 __generate(_ForwardIterator __f, _ForwardIterator __t,
3001 _UniformRandomNumberGenerator& __urng,
3002 const param_type& __p)
3003 { this->__generate_impl(__f, __t, __urng, __p); }
3005 template<typename _UniformRandomNumberGenerator>
3007 __generate(result_type* __f, result_type* __t,
3008 _UniformRandomNumberGenerator& __urng,
3009 const param_type& __p)
3010 { this->__generate_impl(__f, __t, __urng, __p); }
3013 * @brief Return true if two hypergeometric distributions have the same
3014 * parameters and the sequences that would be generated
3018 operator==(const hypergeometric_distribution& __d1,
3019 const hypergeometric_distribution& __d2)
3020 { return __d1._M_param == __d2._M_param; }
3023 * @brief Inserts a %hypergeometric_distribution random number
3024 * distribution @p __x into the output stream @p __os.
3026 * @param __os An output stream.
3027 * @param __x A %hypergeometric_distribution random number
3030 * @returns The output stream with the state of @p __x inserted or in
3033 template<typename _UIntType1, typename _CharT, typename _Traits>
3034 friend std::basic_ostream<_CharT, _Traits>&
3035 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3036 const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
3040 * @brief Extracts a %hypergeometric_distribution random number
3041 * distribution @p __x from the input stream @p __is.
3043 * @param __is An input stream.
3044 * @param __x A %hypergeometric_distribution random number generator
3047 * @returns The input stream with @p __x extracted or in an error
3050 template<typename _UIntType1, typename _CharT, typename _Traits>
3051 friend std::basic_istream<_CharT, _Traits>&
3052 operator>>(std::basic_istream<_CharT, _Traits>& __is,
3053 __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x);
3057 template<typename _ForwardIterator,
3058 typename _UniformRandomNumberGenerator>
3060 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3061 _UniformRandomNumberGenerator& __urng,
3062 const param_type& __p);
3064 param_type _M_param;
3068 * @brief Return true if two hypergeometric distributions are different.
3070 template<typename _UIntType>
3072 operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
3073 const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
3074 { return !(__d1 == __d2); }
3077 * @brief A logistic continuous distribution for random numbers.
3079 * The formula for the logistic probability density function is
3081 * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2}
3083 * where @f$b > 0@f$.
3085 * The formula for the logistic probability function is
3087 * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}}
3089 * where @f$b > 0@f$.
3091 * <table border=1 cellpadding=10 cellspacing=0>
3092 * <caption align=top>Distribution Statistics</caption>
3093 * <tr><td>Mean</td><td>@f$a@f$</td></tr>
3094 * <tr><td>Variance</td><td>@f$b^2\pi^2/3@f$</td></tr>
3095 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
3098 template<typename _RealType = double>
3100 logistic_distribution
3102 static_assert(std::is_floating_point<_RealType>::value,
3103 "template argument not a floating point type");
3106 /** The type of the range of the distribution. */
3107 typedef _RealType result_type;
3108 /** Parameter type. */
3111 typedef logistic_distribution<result_type> distribution_type;
3113 param_type(result_type __a = result_type(0),
3114 result_type __b = result_type(1))
3115 : _M_a(__a), _M_b(__b)
3117 _GLIBCXX_DEBUG_ASSERT(_M_b > result_type(0));
3129 operator==(const param_type& __p1, const param_type& __p2)
3130 { return __p1._M_a == __p2._M_a
3131 && __p1._M_b == __p2._M_b; }
3134 void _M_initialize();
3141 * @brief Constructors.
3144 logistic_distribution(result_type __a = result_type(0),
3145 result_type __b = result_type(1))
3146 : _M_param(__a, __b)
3150 logistic_distribution(const param_type& __p)
3155 * @brief Resets the distribution state.
3162 * @brief Return the parameters of the distribution.
3166 { return _M_param.a(); }
3170 { return _M_param.b(); }
3173 * @brief Returns the parameter set of the distribution.
3177 { return _M_param; }
3180 * @brief Sets the parameter set of the distribution.
3181 * @param __param The new parameter set of the distribution.
3184 param(const param_type& __param)
3185 { _M_param = __param; }
3188 * @brief Returns the greatest lower bound value of the distribution.
3192 { return -std::numeric_limits<result_type>::max(); }
3195 * @brief Returns the least upper bound value of the distribution.
3199 { return std::numeric_limits<result_type>::max(); }
3202 * @brief Generating functions.
3204 template<typename _UniformRandomNumberGenerator>
3206 operator()(_UniformRandomNumberGenerator& __urng)
3207 { return this->operator()(__urng, this->_M_param); }
3209 template<typename _UniformRandomNumberGenerator>
3211 operator()(_UniformRandomNumberGenerator&,
3214 template<typename _ForwardIterator,
3215 typename _UniformRandomNumberGenerator>
3217 __generate(_ForwardIterator __f, _ForwardIterator __t,
3218 _UniformRandomNumberGenerator& __urng)
3219 { this->__generate(__f, __t, __urng, this->param()); }
3221 template<typename _ForwardIterator,
3222 typename _UniformRandomNumberGenerator>
3224 __generate(_ForwardIterator __f, _ForwardIterator __t,
3225 _UniformRandomNumberGenerator& __urng,
3226 const param_type& __p)
3227 { this->__generate_impl(__f, __t, __urng, __p); }
3229 template<typename _UniformRandomNumberGenerator>
3231 __generate(result_type* __f, result_type* __t,
3232 _UniformRandomNumberGenerator& __urng,
3233 const param_type& __p)
3234 { this->__generate_impl(__f, __t, __urng, __p); }
3237 * @brief Return true if two logistic distributions have
3238 * the same parameters and the sequences that would
3239 * be generated are equal.
3241 template<typename _RealType1>
3243 operator==(const logistic_distribution<_RealType1>& __d1,
3244 const logistic_distribution<_RealType1>& __d2)
3245 { return __d1.param() == __d2.param(); }
3248 * @brief Inserts a %logistic_distribution random number distribution
3249 * @p __x into the output stream @p __os.
3251 * @param __os An output stream.
3252 * @param __x A %logistic_distribution random number distribution.
3254 * @returns The output stream with the state of @p __x inserted or in
3257 template<typename _RealType1, typename _CharT, typename _Traits>
3258 friend std::basic_ostream<_CharT, _Traits>&
3259 operator<<(std::basic_ostream<_CharT, _Traits>&,
3260 const logistic_distribution<_RealType1>&);
3263 * @brief Extracts a %logistic_distribution random number distribution
3264 * @p __x from the input stream @p __is.
3266 * @param __is An input stream.
3267 * @param __x A %logistic_distribution random number
3270 * @returns The input stream with @p __x extracted or in an error state.
3272 template<typename _RealType1, typename _CharT, typename _Traits>
3273 friend std::basic_istream<_CharT, _Traits>&
3274 operator>>(std::basic_istream<_CharT, _Traits>&,
3275 logistic_distribution<_RealType1>&);
3278 template<typename _ForwardIterator,
3279 typename _UniformRandomNumberGenerator>
3281 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3282 _UniformRandomNumberGenerator& __urng,
3283 const param_type& __p);
3285 param_type _M_param;
3289 * @brief Return true if two logistic distributions are not equal.
3291 template<typename _RealType1>
3293 operator!=(const logistic_distribution<_RealType1>& __d1,
3294 const logistic_distribution<_RealType1>& __d2)
3295 { return !(__d1 == __d2); }
3299 * @brief A distribution for random coordinates on a unit sphere.
3301 * The method used in the generation function is attributed by Donald Knuth
3302 * to G. W. Brown, Modern Mathematics for the Engineer (1956).
3304 template<std::size_t _Dimen, typename _RealType = double>
3305 class uniform_on_sphere_distribution
3307 static_assert(std::is_floating_point<_RealType>::value,
3308 "template argument not a floating point type");
3309 static_assert(_Dimen != 0, "dimension is zero");
3312 /** The type of the range of the distribution. */
3313 typedef std::array<_RealType, _Dimen> result_type;
3314 /** Parameter type. */
3322 operator==(const param_type& __p1, const param_type& __p2)
3327 * @brief Constructs a uniform on sphere distribution.
3330 uniform_on_sphere_distribution()
3331 : _M_param(), _M_nd()
3335 uniform_on_sphere_distribution(const param_type& __p)
3336 : _M_param(__p), _M_nd()
3340 * @brief Resets the distribution state.
3347 * @brief Returns the parameter set of the distribution.
3351 { return _M_param; }
3354 * @brief Sets the parameter set of the distribution.
3355 * @param __param The new parameter set of the distribution.
3358 param(const param_type& __param)
3359 { _M_param = __param; }
3362 * @brief Returns the greatest lower bound value of the distribution.
3363 * This function makes no sense for this distribution.
3374 * @brief Returns the least upper bound value of the distribution.
3375 * This function makes no sense for this distribution.
3386 * @brief Generating functions.
3388 template<typename _UniformRandomNumberGenerator>
3390 operator()(_UniformRandomNumberGenerator& __urng)
3391 { return this->operator()(__urng, _M_param); }
3393 template<typename _UniformRandomNumberGenerator>
3395 operator()(_UniformRandomNumberGenerator& __urng,
3396 const param_type& __p);
3398 template<typename _ForwardIterator,
3399 typename _UniformRandomNumberGenerator>
3401 __generate(_ForwardIterator __f, _ForwardIterator __t,
3402 _UniformRandomNumberGenerator& __urng)
3403 { this->__generate(__f, __t, __urng, this->param()); }
3405 template<typename _ForwardIterator,
3406 typename _UniformRandomNumberGenerator>
3408 __generate(_ForwardIterator __f, _ForwardIterator __t,
3409 _UniformRandomNumberGenerator& __urng,
3410 const param_type& __p)
3411 { this->__generate_impl(__f, __t, __urng, __p); }
3413 template<typename _UniformRandomNumberGenerator>
3415 __generate(result_type* __f, result_type* __t,
3416 _UniformRandomNumberGenerator& __urng,
3417 const param_type& __p)
3418 { this->__generate_impl(__f, __t, __urng, __p); }
3421 * @brief Return true if two uniform on sphere distributions have
3422 * the same parameters and the sequences that would be
3423 * generated are equal.
3426 operator==(const uniform_on_sphere_distribution& __d1,
3427 const uniform_on_sphere_distribution& __d2)
3428 { return __d1._M_nd == __d2._M_nd; }
3431 * @brief Inserts a %uniform_on_sphere_distribution random number
3432 * distribution @p __x into the output stream @p __os.
3434 * @param __os An output stream.
3435 * @param __x A %uniform_on_sphere_distribution random number
3438 * @returns The output stream with the state of @p __x inserted or in
3441 template<size_t _Dimen1, typename _RealType1, typename _CharT,
3443 friend std::basic_ostream<_CharT, _Traits>&
3444 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3445 const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
3450 * @brief Extracts a %uniform_on_sphere_distribution random number
3452 * @p __x from the input stream @p __is.
3454 * @param __is An input stream.
3455 * @param __x A %uniform_on_sphere_distribution random number
3458 * @returns The input stream with @p __x extracted or in an error state.
3460 template<std::size_t _Dimen1, typename _RealType1, typename _CharT,
3462 friend std::basic_istream<_CharT, _Traits>&
3463 operator>>(std::basic_istream<_CharT, _Traits>& __is,
3464 __gnu_cxx::uniform_on_sphere_distribution<_Dimen1,
3468 template<typename _ForwardIterator,
3469 typename _UniformRandomNumberGenerator>
3471 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3472 _UniformRandomNumberGenerator& __urng,
3473 const param_type& __p);
3475 param_type _M_param;
3476 std::normal_distribution<_RealType> _M_nd;
3480 * @brief Return true if two uniform on sphere distributions are different.
3482 template<std::size_t _Dimen, typename _RealType>
3484 operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
3486 const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
3488 { return !(__d1 == __d2); }
3490 _GLIBCXX_END_NAMESPACE_VERSION
3491 } // namespace __gnu_cxx
3493 #include "ext/opt_random.h"
3494 #include "random.tcc"
3496 #endif // _GLIBCXX_USE_C99_STDINT_TR1
3500 #endif // _EXT_RANDOM