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