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