OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [ext/] [random] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// Random number extensions -*- C++ -*-
2
 
3
// Copyright (C) 2012 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
// .
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 
36
#else
37
 
38
#include 
39
#include 
40
#ifdef __SSE2__
41
# include 
42
#endif
43
 
44
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
45
 
46
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
47
{
48
_GLIBCXX_BEGIN_NAMESPACE_VERSION
49
 
50
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
51
 
52
  /* Mersenne twister implementation optimized for vector operations.
53
   *
54
   * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
55
   */
56
  template
57
           size_t __pos1, size_t __sl1, size_t __sl2,
58
           size_t __sr1, size_t __sr2,
59
           uint32_t __msk1, uint32_t __msk2,
60
           uint32_t __msk3, uint32_t __msk4,
61
           uint32_t __parity1, uint32_t __parity2,
62
           uint32_t __parity3, uint32_t __parity4>
63
    class simd_fast_mersenne_twister_engine
64
    {
65
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
66
                    "substituting _UIntType not an unsigned integral type");
67
      static_assert(__sr1 < 32, "first right shift too large");
68
      static_assert(__sr2 < 16, "second right shift too large");
69
      static_assert(__sl1 < 32, "first left shift too large");
70
      static_assert(__sl2 < 16, "second left shift too large");
71
 
72
    public:
73
      typedef _UIntType result_type;
74
 
75
    private:
76
      static constexpr size_t m_w = sizeof(result_type) * 8;
77
      static constexpr size_t _M_nstate = __m / 128 + 1;
78
      static constexpr size_t _M_nstate32 = _M_nstate * 4;
79
 
80
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
81
                    "substituting _UIntType not an unsigned integral type");
82
      static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size");
83
      static_assert(16 % sizeof(_UIntType) == 0,
84
                    "UIntType size must divide 16");
85
 
86
    public:
87
      static constexpr size_t state_size = _M_nstate * (16
88
                                                        / sizeof(result_type));
89
      static constexpr result_type default_seed = 5489u;
90
 
91
      // constructors and member function
92
      explicit
93
      simd_fast_mersenne_twister_engine(result_type __sd = default_seed)
94
      { seed(__sd); }
95
 
96
      template
97
        std::enable_if
98
                                     simd_fast_mersenne_twister_engine>::value>
99
               ::type>
100
        explicit
101
        simd_fast_mersenne_twister_engine(_Sseq& __q)
102
        { seed(__q); }
103
 
104
      void
105
      seed(result_type __sd = default_seed);
106
 
107
      template
108
        typename std::enable_if::value>::type
109
        seed(_Sseq& __q);
110
 
111
      static constexpr result_type
112
      min()
113
      { return 0; };
114
 
115
      static constexpr result_type
116
      max()
117
      { return std::numeric_limits::max(); }
118
 
119
      void
120
      discard(unsigned long long __z);
121
 
122
      result_type
123
      operator()()
124
      {
125
        if (__builtin_expect(_M_pos >= state_size, 0))
126
          _M_gen_rand();
127
 
128
        return _M_stateT[_M_pos++];
129
      }
130
 
131
      template
132
               size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
133
               size_t __sr1_2, size_t __sr2_2,
134
               uint32_t __msk1_2, uint32_t __msk2_2,
135
               uint32_t __msk3_2, uint32_t __msk4_2,
136
               uint32_t __parity1_2, uint32_t __parity2_2,
137
               uint32_t __parity3_2, uint32_t __parity4_2>
138
        friend bool
139
        operator==(const simd_fast_mersenne_twister_engine<_UIntType_2,
140
                   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
141
                   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
142
                   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs,
143
                   const simd_fast_mersenne_twister_engine<_UIntType_2,
144
                   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
145
                   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
146
                   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs);
147
 
148
      template
149
               size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
150
               size_t __sr1_2, size_t __sr2_2,
151
               uint32_t __msk1_2, uint32_t __msk2_2,
152
               uint32_t __msk3_2, uint32_t __msk4_2,
153
               uint32_t __parity1_2, uint32_t __parity2_2,
154
               uint32_t __parity3_2, uint32_t __parity4_2,
155
               typename _CharT, typename _Traits>
156
        friend std::basic_ostream<_CharT, _Traits>&
157
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
158
                   const __gnu_cxx::simd_fast_mersenne_twister_engine
159
                   <_UIntType_2,
160
                   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
161
                   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
162
                   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
163
 
164
      template
165
               size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
166
               size_t __sr1_2, size_t __sr2_2,
167
               uint32_t __msk1_2, uint32_t __msk2_2,
168
               uint32_t __msk3_2, uint32_t __msk4_2,
169
               uint32_t __parity1_2, uint32_t __parity2_2,
170
               uint32_t __parity3_2, uint32_t __parity4_2,
171
               typename _CharT, typename _Traits>
172
        friend std::basic_istream<_CharT, _Traits>&
173
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
174
                   __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2,
175
                   __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2,
176
                   __msk1_2, __msk2_2, __msk3_2, __msk4_2,
177
                   __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x);
178
 
179
    private:
180
      union
181
      {
182
#ifdef __SSE2__
183
        __m128i _M_state[_M_nstate];
184
#endif
185
        uint32_t _M_state32[_M_nstate32];
186
        result_type _M_stateT[state_size];
187
      } __attribute__ ((__aligned__ (16)));
188
      size_t _M_pos;
189
 
190
      void _M_gen_rand(void);
191
      void _M_period_certification();
192
  };
193
 
194
 
195
  template
196
           size_t __pos1, size_t __sl1, size_t __sl2,
197
           size_t __sr1, size_t __sr2,
198
           uint32_t __msk1, uint32_t __msk2,
199
           uint32_t __msk3, uint32_t __msk4,
200
           uint32_t __parity1, uint32_t __parity2,
201
           uint32_t __parity3, uint32_t __parity4>
202
    inline bool
203
    operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
204
               __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
205
               __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs,
206
               const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
207
               __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3,
208
               __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs)
209
    { return !(__lhs == __rhs); }
210
 
211
 
212
  /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined
213
   * in the C implementation by Daito and Matsumoto, as both a 32-bit
214
   * and 64-bit version.
215
   */
216
  typedef simd_fast_mersenne_twister_engine
217
                                            15, 3, 13, 3,
218
                                            0xfdff37ffU, 0xef7f3f7dU,
219
                                            0xff777b7dU, 0x7ff7fb2fU,
220
                                            0x00000001U, 0x00000000U,
221
                                            0x00000000U, 0x5986f054U>
222
    sfmt607;
223
 
224
  typedef simd_fast_mersenne_twister_engine
225
                                            15, 3, 13, 3,
226
                                            0xfdff37ffU, 0xef7f3f7dU,
227
                                            0xff777b7dU, 0x7ff7fb2fU,
228
                                            0x00000001U, 0x00000000U,
229
                                            0x00000000U, 0x5986f054U>
230
    sfmt607_64;
231
 
232
 
233
  typedef simd_fast_mersenne_twister_engine
234
                                            14, 3, 5, 1,
235
                                            0xf7fefffdU, 0x7fefcfffU,
236
                                            0xaff3ef3fU, 0xb5ffff7fU,
237
                                            0x00000001U, 0x00000000U,
238
                                            0x00000000U, 0x20000000U>
239
    sfmt1279;
240
 
241
  typedef simd_fast_mersenne_twister_engine
242
                                            14, 3, 5, 1,
243
                                            0xf7fefffdU, 0x7fefcfffU,
244
                                            0xaff3ef3fU, 0xb5ffff7fU,
245
                                            0x00000001U, 0x00000000U,
246
                                            0x00000000U, 0x20000000U>
247
    sfmt1279_64;
248
 
249
 
250
  typedef simd_fast_mersenne_twister_engine
251
                                            19, 1, 5, 1,
252
                                            0xbff7ffbfU, 0xfdfffffeU,
253
                                            0xf7ffef7fU, 0xf2f7cbbfU,
254
                                            0x00000001U, 0x00000000U,
255
                                            0x00000000U, 0x41dfa600U>
256
    sfmt2281;
257
 
258
  typedef simd_fast_mersenne_twister_engine
259
                                            19, 1, 5, 1,
260
                                            0xbff7ffbfU, 0xfdfffffeU,
261
                                            0xf7ffef7fU, 0xf2f7cbbfU,
262
                                            0x00000001U, 0x00000000U,
263
                                            0x00000000U, 0x41dfa600U>
264
    sfmt2281_64;
265
 
266
 
267
  typedef simd_fast_mersenne_twister_engine
268
                                            20, 1, 7, 1,
269
                                            0x9f7bffffU, 0x9fffff5fU,
270
                                            0x3efffffbU, 0xfffff7bbU,
271
                                            0xa8000001U, 0xaf5390a3U,
272
                                            0xb740b3f8U, 0x6c11486dU>
273
    sfmt4253;
274
 
275
  typedef simd_fast_mersenne_twister_engine
276
                                            20, 1, 7, 1,
277
                                            0x9f7bffffU, 0x9fffff5fU,
278
                                            0x3efffffbU, 0xfffff7bbU,
279
                                            0xa8000001U, 0xaf5390a3U,
280
                                            0xb740b3f8U, 0x6c11486dU>
281
    sfmt4253_64;
282
 
283
 
284
  typedef simd_fast_mersenne_twister_engine
285
                                            14, 3, 7, 3,
286
                                            0xeffff7fbU, 0xffffffefU,
287
                                            0xdfdfbfffU, 0x7fffdbfdU,
288
                                            0x00000001U, 0x00000000U,
289
                                            0xe8148000U, 0xd0c7afa3U>
290
    sfmt11213;
291
 
292
  typedef simd_fast_mersenne_twister_engine
293
                                            14, 3, 7, 3,
294
                                            0xeffff7fbU, 0xffffffefU,
295
                                            0xdfdfbfffU, 0x7fffdbfdU,
296
                                            0x00000001U, 0x00000000U,
297
                                            0xe8148000U, 0xd0c7afa3U>
298
    sfmt11213_64;
299
 
300
 
301
  typedef simd_fast_mersenne_twister_engine
302
                                            18, 1, 11, 1,
303
                                            0xdfffffefU, 0xddfecb7fU,
304
                                            0xbffaffffU, 0xbffffff6U,
305
                                            0x00000001U, 0x00000000U,
306
                                            0x00000000U, 0x13c9e684U>
307
    sfmt19937;
308
 
309
  typedef simd_fast_mersenne_twister_engine
310
                                            18, 1, 11, 1,
311
                                            0xdfffffefU, 0xddfecb7fU,
312
                                            0xbffaffffU, 0xbffffff6U,
313
                                            0x00000001U, 0x00000000U,
314
                                            0x00000000U, 0x13c9e684U>
315
    sfmt19937_64;
316
 
317
 
318
  typedef simd_fast_mersenne_twister_engine
319
                                            5, 3, 9, 3,
320
                                            0xeffffffbU, 0xdfbebfffU,
321
                                            0xbfbf7befU, 0x9ffd7bffU,
322
                                            0x00000001U, 0x00000000U,
323
                                            0xa3ac4000U, 0xecc1327aU>
324
    sfmt44497;
325
 
326
  typedef simd_fast_mersenne_twister_engine
327
                                            5, 3, 9, 3,
328
                                            0xeffffffbU, 0xdfbebfffU,
329
                                            0xbfbf7befU, 0x9ffd7bffU,
330
                                            0x00000001U, 0x00000000U,
331
                                            0xa3ac4000U, 0xecc1327aU>
332
    sfmt44497_64;
333
 
334
 
335
  typedef simd_fast_mersenne_twister_engine
336
                                            6, 7, 19, 1,
337
                                            0xfdbffbffU, 0xbff7ff3fU,
338
                                            0xfd77efffU, 0xbf9ff3ffU,
339
                                            0x00000001U, 0x00000000U,
340
                                            0x00000000U, 0xe9528d85U>
341
    sfmt86243;
342
 
343
  typedef simd_fast_mersenne_twister_engine
344
                                            6, 7, 19, 1,
345
                                            0xfdbffbffU, 0xbff7ff3fU,
346
                                            0xfd77efffU, 0xbf9ff3ffU,
347
                                            0x00000001U, 0x00000000U,
348
                                            0x00000000U, 0xe9528d85U>
349
    sfmt86243_64;
350
 
351
 
352
  typedef simd_fast_mersenne_twister_engine
353
                                            19, 1, 21, 1,
354
                                            0xffffbb5fU, 0xfb6ebf95U,
355
                                            0xfffefffaU, 0xcff77fffU,
356
                                            0x00000001U, 0x00000000U,
357
                                            0xcb520000U, 0xc7e91c7dU>
358
    sfmt132049;
359
 
360
  typedef simd_fast_mersenne_twister_engine
361
                                            19, 1, 21, 1,
362
                                            0xffffbb5fU, 0xfb6ebf95U,
363
                                            0xfffefffaU, 0xcff77fffU,
364
                                            0x00000001U, 0x00000000U,
365
                                            0xcb520000U, 0xc7e91c7dU>
366
    sfmt132049_64;
367
 
368
 
369
  typedef simd_fast_mersenne_twister_engine
370
                                            11, 3, 10, 1,
371
                                            0xbff7bff7U, 0xbfffffffU,
372
                                            0xbffffa7fU, 0xffddfbfbU,
373
                                            0xf8000001U, 0x89e80709U,
374
                                            0x3bd2b64bU, 0x0c64b1e4U>
375
    sfmt216091;
376
 
377
  typedef simd_fast_mersenne_twister_engine
378
                                            11, 3, 10, 1,
379
                                            0xbff7bff7U, 0xbfffffffU,
380
                                            0xbffffa7fU, 0xffddfbfbU,
381
                                            0xf8000001U, 0x89e80709U,
382
                                            0x3bd2b64bU, 0x0c64b1e4U>
383
    sfmt216091_64;
384
 
385
#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
386
 
387
  /**
388
   * @brief A beta continuous distribution for random numbers.
389
   *
390
   * The formula for the beta probability density function is:
391
   * @f[
392
   *     p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)}
393
   *                         x^{\alpha - 1} (1 - x)^{\beta - 1}
394
   * @f]
395
   */
396
  template
397
    class beta_distribution
398
    {
399
      static_assert(std::is_floating_point<_RealType>::value,
400
                    "template argument not a floating point type");
401
 
402
    public:
403
      /** The type of the range of the distribution. */
404
      typedef _RealType result_type;
405
      /** Parameter type. */
406
      struct param_type
407
      {
408
        typedef beta_distribution<_RealType> distribution_type;
409
        friend class beta_distribution<_RealType>;
410
 
411
        explicit
412
        param_type(_RealType __alpha_val = _RealType(1),
413
                   _RealType __beta_val = _RealType(1))
414
        : _M_alpha(__alpha_val), _M_beta(__beta_val)
415
        {
416
          _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
417
          _GLIBCXX_DEBUG_ASSERT(_M_beta > _RealType(0));
418
        }
419
 
420
        _RealType
421
        alpha() const
422
        { return _M_alpha; }
423
 
424
        _RealType
425
        beta() const
426
        { return _M_beta; }
427
 
428
        friend bool
429
        operator==(const param_type& __p1, const param_type& __p2)
430
        { return (__p1._M_alpha == __p2._M_alpha
431
                  && __p1._M_beta == __p2._M_beta); }
432
 
433
      private:
434
        void
435
        _M_initialize();
436
 
437
        _RealType _M_alpha;
438
        _RealType _M_beta;
439
      };
440
 
441
    public:
442
      /**
443
       * @brief Constructs a beta distribution with parameters
444
       * @f$\alpha@f$ and @f$\beta@f$.
445
       */
446
      explicit
447
      beta_distribution(_RealType __alpha_val = _RealType(1),
448
                        _RealType __beta_val = _RealType(1))
449
      : _M_param(__alpha_val, __beta_val)
450
      { }
451
 
452
      explicit
453
      beta_distribution(const param_type& __p)
454
      : _M_param(__p)
455
      { }
456
 
457
      /**
458
       * @brief Resets the distribution state.
459
       */
460
      void
461
      reset()
462
      { }
463
 
464
      /**
465
       * @brief Returns the @f$\alpha@f$ of the distribution.
466
       */
467
      _RealType
468
      alpha() const
469
      { return _M_param.alpha(); }
470
 
471
      /**
472
       * @brief Returns the @f$\beta@f$ of the distribution.
473
       */
474
      _RealType
475
      beta() const
476
      { return _M_param.beta(); }
477
 
478
      /**
479
       * @brief Returns the parameter set of the distribution.
480
       */
481
      param_type
482
      param() const
483
      { return _M_param; }
484
 
485
      /**
486
       * @brief Sets the parameter set of the distribution.
487
       * @param __param The new parameter set of the distribution.
488
       */
489
      void
490
      param(const param_type& __param)
491
      { _M_param = __param; }
492
 
493
      /**
494
       * @brief Returns the greatest lower bound value of the distribution.
495
       */
496
      result_type
497
      min() const
498
      { return result_type(0); }
499
 
500
      /**
501
       * @brief Returns the least upper bound value of the distribution.
502
       */
503
      result_type
504
      max() const
505
      { return result_type(1); }
506
 
507
      /**
508
       * @brief Generating functions.
509
       */
510
      template
511
        result_type
512
        operator()(_UniformRandomNumberGenerator& __urng)
513
        { return this->operator()(__urng, _M_param); }
514
 
515
      template
516
        result_type
517
        operator()(_UniformRandomNumberGenerator& __urng,
518
                   const param_type& __p);
519
 
520
      template
521
               typename _UniformRandomNumberGenerator>
522
        void
523
        __generate(_ForwardIterator __f, _ForwardIterator __t,
524
                   _UniformRandomNumberGenerator& __urng)
525
        { this->__generate(__f, __t, __urng, _M_param); }
526
 
527
      template
528
               typename _UniformRandomNumberGenerator>
529
        void
530
        __generate(_ForwardIterator __f, _ForwardIterator __t,
531
                   _UniformRandomNumberGenerator& __urng,
532
                   const param_type& __p)
533
        { this->__generate_impl(__f, __t, __urng, __p); }
534
 
535
      template
536
        void
537
        __generate(result_type* __f, result_type* __t,
538
                   _UniformRandomNumberGenerator& __urng,
539
                   const param_type& __p)
540
        { this->__generate_impl(__f, __t, __urng, __p); }
541
 
542
      /**
543
       * @brief Return true if two beta distributions have the same
544
       *        parameters and the sequences that would be generated
545
       *        are equal.
546
       */
547
      friend bool
548
      operator==(const beta_distribution& __d1,
549
                 const beta_distribution& __d2)
550
      { return __d1._M_param == __d2._M_param; }
551
 
552
      /**
553
       * @brief Inserts a %beta_distribution random number distribution
554
       * @p __x into the output stream @p __os.
555
       *
556
       * @param __os An output stream.
557
       * @param __x  A %beta_distribution random number distribution.
558
       *
559
       * @returns The output stream with the state of @p __x inserted or in
560
       * an error state.
561
       */
562
      template
563
        friend std::basic_ostream<_CharT, _Traits>&
564
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
565
                   const __gnu_cxx::beta_distribution<_RealType1>& __x);
566
 
567
      /**
568
       * @brief Extracts a %beta_distribution random number distribution
569
       * @p __x from the input stream @p __is.
570
       *
571
       * @param __is An input stream.
572
       * @param __x  A %beta_distribution random number generator engine.
573
       *
574
       * @returns The input stream with @p __x extracted or in an error state.
575
       */
576
      template
577
        friend std::basic_istream<_CharT, _Traits>&
578
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
579
                   __gnu_cxx::beta_distribution<_RealType1>& __x);
580
 
581
    private:
582
      template
583
               typename _UniformRandomNumberGenerator>
584
        void
585
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
586
                        _UniformRandomNumberGenerator& __urng,
587
                        const param_type& __p);
588
 
589
      param_type _M_param;
590
    };
591
 
592
  /**
593
   * @brief Return true if two beta distributions are different.
594
   */
595
  template
596
    inline bool
597
    operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
598
               const __gnu_cxx::beta_distribution<_RealType>& __d2)
599
   { return !(__d1 == __d2); }
600
 
601
 
602
  /**
603
   * @brief A multi-variate normal continuous distribution for random numbers.
604
   *
605
   * The formula for the normal probability density function is
606
   * @f[
607
   *     p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) =
608
   *       \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}}
609
   *       e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T}
610
   *          \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})}
611
   * @f]
612
   *
613
   * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are
614
   * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance
615
   * matrix (which must be positive-definite).
616
   */
617
  template
618
    class normal_mv_distribution
619
    {
620
      static_assert(std::is_floating_point<_RealType>::value,
621
                    "template argument not a floating point type");
622
      static_assert(_Dimen != 0, "dimension is zero");
623
 
624
    public:
625
      /** The type of the range of the distribution. */
626
      typedef std::array<_RealType, _Dimen> result_type;
627
      /** Parameter type. */
628
      class param_type
629
      {
630
        static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2;
631
 
632
      public:
633
        typedef normal_mv_distribution<_Dimen, _RealType> distribution_type;
634
        friend class normal_mv_distribution<_Dimen, _RealType>;
635
 
636
        param_type()
637
        {
638
          std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0));
639
          auto __it = _M_t.begin();
640
          for (size_t __i = 0; __i < _Dimen; ++__i)
641
            {
642
              std::fill_n(__it, __i, _RealType(0));
643
              __it += __i;
644
              *__it++ = _RealType(1);
645
            }
646
        }
647
 
648
        template
649
          param_type(_ForwardIterator1 __meanbegin,
650
                     _ForwardIterator1 __meanend,
651
                     _ForwardIterator2 __varcovbegin,
652
                     _ForwardIterator2 __varcovend)
653
        {
654
          __glibcxx_function_requires(_ForwardIteratorConcept<
655
                                      _ForwardIterator1>)
656
          __glibcxx_function_requires(_ForwardIteratorConcept<
657
                                      _ForwardIterator2>)
658
          _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend)
659
                                <= _Dimen);
660
          const auto __dist = std::distance(__varcovbegin, __varcovend);
661
          _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen
662
                                || __dist == _Dimen * (_Dimen + 1) / 2
663
                                || __dist == _Dimen);
664
 
665
          if (__dist == _Dimen * _Dimen)
666
            _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend);
667
          else if (__dist == _Dimen * (_Dimen + 1) / 2)
668
            _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend);
669
          else
670
            _M_init_diagonal(__meanbegin, __meanend,
671
                             __varcovbegin, __varcovend);
672
        }
673
 
674
        param_type(std::initializer_list<_RealType> __mean,
675
                   std::initializer_list<_RealType> __varcov)
676
        {
677
          _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen);
678
          _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen
679
                                || __varcov.size() == _Dimen * (_Dimen + 1) / 2
680
                                || __varcov.size() == _Dimen);
681
 
682
          if (__varcov.size() == _Dimen * _Dimen)
683
            _M_init_full(__mean.begin(), __mean.end(),
684
                         __varcov.begin(), __varcov.end());
685
          else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2)
686
            _M_init_lower(__mean.begin(), __mean.end(),
687
                          __varcov.begin(), __varcov.end());
688
          else
689
            _M_init_diagonal(__mean.begin(), __mean.end(),
690
                             __varcov.begin(), __varcov.end());
691
        }
692
 
693
        std::array<_RealType, _Dimen>
694
        mean() const
695
        { return _M_mean; }
696
 
697
        std::array<_RealType, _M_t_size>
698
        varcov() const
699
        { return _M_t; }
700
 
701
        friend bool
702
        operator==(const param_type& __p1, const param_type& __p2)
703
        { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; }
704
 
705
      private:
706
        template 
707
          void _M_init_full(_InputIterator1 __meanbegin,
708
                            _InputIterator1 __meanend,
709
                            _InputIterator2 __varcovbegin,
710
                            _InputIterator2 __varcovend);
711
        template 
712
          void _M_init_lower(_InputIterator1 __meanbegin,
713
                             _InputIterator1 __meanend,
714
                             _InputIterator2 __varcovbegin,
715
                             _InputIterator2 __varcovend);
716
        template 
717
          void _M_init_diagonal(_InputIterator1 __meanbegin,
718
                                _InputIterator1 __meanend,
719
                                _InputIterator2 __varbegin,
720
                                _InputIterator2 __varend);
721
 
722
        std::array<_RealType, _Dimen> _M_mean;
723
        std::array<_RealType, _M_t_size> _M_t;
724
      };
725
 
726
    public:
727
      normal_mv_distribution()
728
      : _M_param(), _M_nd()
729
      { }
730
 
731
      template
732
        normal_mv_distribution(_ForwardIterator1 __meanbegin,
733
                               _ForwardIterator1 __meanend,
734
                               _ForwardIterator2 __varcovbegin,
735
                               _ForwardIterator2 __varcovend)
736
        : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend),
737
          _M_nd()
738
        { }
739
 
740
      normal_mv_distribution(std::initializer_list<_RealType> __mean,
741
                             std::initializer_list<_RealType> __varcov)
742
      : _M_param(__mean, __varcov), _M_nd()
743
      { }
744
 
745
      explicit
746
      normal_mv_distribution(const param_type& __p)
747
      : _M_param(__p), _M_nd()
748
      { }
749
 
750
      /**
751
       * @brief Resets the distribution state.
752
       */
753
      void
754
      reset()
755
      { _M_nd.reset(); }
756
 
757
      /**
758
       * @brief Returns the mean of the distribution.
759
       */
760
      result_type
761
      mean() const
762
      { return _M_param.mean(); }
763
 
764
      /**
765
       * @brief Returns the compact form of the variance/covariance
766
       * matrix of the distribution.
767
       */
768
      std::array<_RealType, _Dimen * (_Dimen + 1) / 2>
769
      varcov() const
770
      { return _M_param.varcov(); }
771
 
772
      /**
773
       * @brief Returns the parameter set of the distribution.
774
       */
775
      param_type
776
      param() const
777
      { return _M_param; }
778
 
779
      /**
780
       * @brief Sets the parameter set of the distribution.
781
       * @param __param The new parameter set of the distribution.
782
       */
783
      void
784
      param(const param_type& __param)
785
      { _M_param = __param; }
786
 
787
      /**
788
       * @brief Returns the greatest lower bound value of the distribution.
789
       */
790
      result_type
791
      min() const
792
      { result_type __res;
793
        __res.fill(std::numeric_limits<_RealType>::min());
794
        return __res; }
795
 
796
      /**
797
       * @brief Returns the least upper bound value of the distribution.
798
       */
799
      result_type
800
      max() const
801
      { result_type __res;
802
        __res.fill(std::numeric_limits<_RealType>::max());
803
        return __res; }
804
 
805
      /**
806
       * @brief Generating functions.
807
       */
808
      template
809
        result_type
810
        operator()(_UniformRandomNumberGenerator& __urng)
811
        { return this->operator()(__urng, _M_param); }
812
 
813
      template
814
        result_type
815
        operator()(_UniformRandomNumberGenerator& __urng,
816
                   const param_type& __p);
817
 
818
      template
819
               typename _UniformRandomNumberGenerator>
820
        void
821
        __generate(_ForwardIterator __f, _ForwardIterator __t,
822
                   _UniformRandomNumberGenerator& __urng)
823
        { return this->__generate_impl(__f, __t, __urng, _M_param); }
824
 
825
      template
826
               typename _UniformRandomNumberGenerator>
827
        void
828
        __generate(_ForwardIterator __f, _ForwardIterator __t,
829
                   _UniformRandomNumberGenerator& __urng,
830
                   const param_type& __p)
831
        { return this->__generate_impl(__f, __t, __urng, __p); }
832
 
833
      /**
834
       * @brief Return true if two multi-variant normal distributions have
835
       *        the same parameters and the sequences that would
836
       *        be generated are equal.
837
       */
838
      template
839
        friend bool
840
        operator==(const
841
                   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
842
                   __d1,
843
                   const
844
                   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
845
                   __d2);
846
 
847
      /**
848
       * @brief Inserts a %normal_mv_distribution random number distribution
849
       * @p __x into the output stream @p __os.
850
       *
851
       * @param __os An output stream.
852
       * @param __x  A %normal_mv_distribution random number distribution.
853
       *
854
       * @returns The output stream with the state of @p __x inserted or in
855
       * an error state.
856
       */
857
      template
858
               typename _CharT, typename _Traits>
859
        friend std::basic_ostream<_CharT, _Traits>&
860
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
861
                   const
862
                   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
863
                   __x);
864
 
865
      /**
866
       * @brief Extracts a %normal_mv_distribution random number distribution
867
       * @p __x from the input stream @p __is.
868
       *
869
       * @param __is An input stream.
870
       * @param __x  A %normal_mv_distribution random number generator engine.
871
       *
872
       * @returns The input stream with @p __x extracted or in an error
873
       *          state.
874
       */
875
      template
876
               typename _CharT, typename _Traits>
877
        friend std::basic_istream<_CharT, _Traits>&
878
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
879
                   __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
880
                   __x);
881
 
882
    private:
883
      template
884
               typename _UniformRandomNumberGenerator>
885
        void
886
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
887
                        _UniformRandomNumberGenerator& __urng,
888
                        const param_type& __p);
889
 
890
      param_type _M_param;
891
      std::normal_distribution<_RealType> _M_nd;
892
  };
893
 
894
  /**
895
   * @brief Return true if two multi-variate normal distributions are
896
   * different.
897
   */
898
  template
899
    inline bool
900
    operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
901
               __d1,
902
               const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
903
               __d2)
904
    { return !(__d1 == __d2); }
905
 
906
 
907
  /**
908
   * @brief A Rice continuous distribution for random numbers.
909
   *
910
   * The formula for the Rice probability density function is
911
   * @f[
912
   *     p(x|\nu,\sigma) = \frac{x}{\sigma^2}
913
   *                       \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right)
914
   *                       I_0\left(\frac{x \nu}{\sigma^2}\right)
915
   * @f]
916
   * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
917
   * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$.
918
   *
919
   * 
920
   * 
Distribution Statistics
921
   * 
Mean@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$
922
   * 
Variance@f$2\sigma^2 + \nu^2
923
   *                   + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$
924
   * 
Range@f$[0, \infty)@f$
925
   * 
926
   * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2.
927
   */
928
  template
929
    class
930
    rice_distribution
931
    {
932
      static_assert(std::is_floating_point<_RealType>::value,
933
                    "template argument not a floating point type");
934
    public:
935
      /** The type of the range of the distribution. */
936
      typedef _RealType result_type;
937
      /** Parameter type. */
938
      struct param_type
939
      {
940
        typedef rice_distribution distribution_type;
941
 
942
        param_type(result_type __nu_val = result_type(0),
943
                   result_type __sigma_val = result_type(1))
944
        : _M_nu(__nu_val), _M_sigma(__sigma_val)
945
        {
946
          _GLIBCXX_DEBUG_ASSERT(_M_nu >= result_type(0));
947
          _GLIBCXX_DEBUG_ASSERT(_M_sigma > result_type(0));
948
        }
949
 
950
        result_type
951
        nu() const
952
        { return _M_nu; }
953
 
954
        result_type
955
        sigma() const
956
        { return _M_sigma; }
957
 
958
        friend bool
959
        operator==(const param_type& __p1, const param_type& __p2)
960
        { return __p1._M_nu == __p2._M_nu
961
              && __p1._M_sigma == __p2._M_sigma; }
962
 
963
      private:
964
        void _M_initialize();
965
 
966
        result_type _M_nu;
967
        result_type _M_sigma;
968
      };
969
 
970
      /**
971
       * @brief Constructors.
972
       */
973
      explicit
974
      rice_distribution(result_type __nu_val = result_type(0),
975
                        result_type __sigma_val = result_type(1))
976
      : _M_param(__nu_val, __sigma_val),
977
        _M_ndx(__nu_val, __sigma_val),
978
        _M_ndy(result_type(0), __sigma_val)
979
      { }
980
 
981
      explicit
982
      rice_distribution(const param_type& __p)
983
      : _M_param(__p),
984
        _M_ndx(__p.nu(), __p.sigma()),
985
        _M_ndy(result_type(0), __p.sigma())
986
      { }
987
 
988
      /**
989
       * @brief Resets the distribution state.
990
       */
991
      void
992
      reset()
993
      {
994
        _M_ndx.reset();
995
        _M_ndy.reset();
996
      }
997
 
998
      /**
999
       * @brief Return the parameters of the distribution.
1000
       */
1001
      result_type
1002
      nu() const
1003
      { return _M_param.nu(); }
1004
 
1005
      result_type
1006
      sigma() const
1007
      { return _M_param.sigma(); }
1008
 
1009
      /**
1010
       * @brief Returns the parameter set of the distribution.
1011
       */
1012
      param_type
1013
      param() const
1014
      { return _M_param; }
1015
 
1016
      /**
1017
       * @brief Sets the parameter set of the distribution.
1018
       * @param __param The new parameter set of the distribution.
1019
       */
1020
      void
1021
      param(const param_type& __param)
1022
      { _M_param = __param; }
1023
 
1024
      /**
1025
       * @brief Returns the greatest lower bound value of the distribution.
1026
       */
1027
      result_type
1028
      min() const
1029
      { return result_type(0); }
1030
 
1031
      /**
1032
       * @brief Returns the least upper bound value of the distribution.
1033
       */
1034
      result_type
1035
      max() const
1036
      { return std::numeric_limits::max(); }
1037
 
1038
      /**
1039
       * @brief Generating functions.
1040
       */
1041
      template
1042
        result_type
1043
        operator()(_UniformRandomNumberGenerator& __urng)
1044
        {
1045
          result_type __x = this->_M_ndx(__urng);
1046
          result_type __y = this->_M_ndy(__urng);
1047
#if _GLIBCXX_USE_C99_MATH_TR1
1048
          return std::hypot(__x, __y);
1049
#else
1050
          return std::sqrt(__x * __x + __y * __y);
1051
#endif
1052
        }
1053
 
1054
      template
1055
        result_type
1056
        operator()(_UniformRandomNumberGenerator& __urng,
1057
                   const param_type& __p)
1058
        {
1059
          typename std::normal_distribution::param_type
1060
            __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
1061
          result_type __x = this->_M_ndx(__px, __urng);
1062
          result_type __y = this->_M_ndy(__py, __urng);
1063
#if _GLIBCXX_USE_C99_MATH_TR1
1064
          return std::hypot(__x, __y);
1065
#else
1066
          return std::sqrt(__x * __x + __y * __y);
1067
#endif
1068
        }
1069
 
1070
      template
1071
               typename _UniformRandomNumberGenerator>
1072
        void
1073
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1074
                   _UniformRandomNumberGenerator& __urng)
1075
        { this->__generate(__f, __t, __urng, _M_param); }
1076
 
1077
      template
1078
               typename _UniformRandomNumberGenerator>
1079
        void
1080
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1081
                   _UniformRandomNumberGenerator& __urng,
1082
                   const param_type& __p)
1083
        { this->__generate_impl(__f, __t, __urng, __p); }
1084
 
1085
      template
1086
        void
1087
        __generate(result_type* __f, result_type* __t,
1088
                   _UniformRandomNumberGenerator& __urng,
1089
                   const param_type& __p)
1090
        { this->__generate_impl(__f, __t, __urng, __p); }
1091
 
1092
      /**
1093
       * @brief Return true if two Rice distributions have
1094
       *        the same parameters and the sequences that would
1095
       *        be generated are equal.
1096
       */
1097
      friend bool
1098
      operator==(const rice_distribution& __d1,
1099
                 const rice_distribution& __d2)
1100
      { return (__d1._M_param == __d2._M_param
1101
                && __d1._M_ndx == __d2._M_ndx
1102
                && __d1._M_ndy == __d2._M_ndy); }
1103
 
1104
      /**
1105
       * @brief Inserts a %rice_distribution random number distribution
1106
       * @p __x into the output stream @p __os.
1107
       *
1108
       * @param __os An output stream.
1109
       * @param __x  A %rice_distribution random number distribution.
1110
       *
1111
       * @returns The output stream with the state of @p __x inserted or in
1112
       * an error state.
1113
       */
1114
      template
1115
        friend std::basic_ostream<_CharT, _Traits>&
1116
        operator<<(std::basic_ostream<_CharT, _Traits>&,
1117
                   const rice_distribution<_RealType1>&);
1118
 
1119
      /**
1120
       * @brief Extracts a %rice_distribution random number distribution
1121
       * @p __x from the input stream @p __is.
1122
       *
1123
       * @param __is An input stream.
1124
       * @param __x A %rice_distribution random number
1125
       *            generator engine.
1126
       *
1127
       * @returns The input stream with @p __x extracted or in an error state.
1128
       */
1129
      template
1130
        friend std::basic_istream<_CharT, _Traits>&
1131
        operator>>(std::basic_istream<_CharT, _Traits>&,
1132
                   rice_distribution<_RealType1>&);
1133
 
1134
    private:
1135
      template
1136
               typename _UniformRandomNumberGenerator>
1137
        void
1138
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1139
                        _UniformRandomNumberGenerator& __urng,
1140
                        const param_type& __p);
1141
 
1142
      param_type _M_param;
1143
 
1144
      std::normal_distribution _M_ndx;
1145
      std::normal_distribution _M_ndy;
1146
    };
1147
 
1148
  /**
1149
   * @brief Return true if two Rice distributions are not equal.
1150
   */
1151
  template
1152
    inline bool
1153
    operator!=(const rice_distribution<_RealType1>& __d1,
1154
               const rice_distribution<_RealType1>& __d2)
1155
    { return !(__d1 == __d2); }
1156
 
1157
 
1158
  /**
1159
   * @brief A Nakagami continuous distribution for random numbers.
1160
   *
1161
   * The formula for the Nakagami probability density function is
1162
   * @f[
1163
   *     p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu}
1164
   *                       x^{2\mu-1}e^{-\mu x / \omega}
1165
   * @f]
1166
   * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$
1167
   * and @f$\omega > 0@f$.
1168
   */
1169
  template
1170
    class
1171
    nakagami_distribution
1172
    {
1173
      static_assert(std::is_floating_point<_RealType>::value,
1174
                    "template argument not a floating point type");
1175
 
1176
    public:
1177
      /** The type of the range of the distribution. */
1178
      typedef _RealType result_type;
1179
      /** Parameter type. */
1180
      struct param_type
1181
      {
1182
        typedef nakagami_distribution distribution_type;
1183
 
1184
        param_type(result_type __mu_val = result_type(1),
1185
                   result_type __omega_val = result_type(1))
1186
        : _M_mu(__mu_val), _M_omega(__omega_val)
1187
        {
1188
          _GLIBCXX_DEBUG_ASSERT(_M_mu >= result_type(0.5L));
1189
          _GLIBCXX_DEBUG_ASSERT(_M_omega > result_type(0));
1190
        }
1191
 
1192
        result_type
1193
        mu() const
1194
        { return _M_mu; }
1195
 
1196
        result_type
1197
        omega() const
1198
        { return _M_omega; }
1199
 
1200
        friend bool
1201
        operator==(const param_type& __p1, const param_type& __p2)
1202
        { return __p1._M_mu == __p2._M_mu
1203
              && __p1._M_omega == __p2._M_omega; }
1204
 
1205
      private:
1206
        void _M_initialize();
1207
 
1208
        result_type _M_mu;
1209
        result_type _M_omega;
1210
      };
1211
 
1212
      /**
1213
       * @brief Constructors.
1214
       */
1215
      explicit
1216
      nakagami_distribution(result_type __mu_val = result_type(1),
1217
                            result_type __omega_val = result_type(1))
1218
      : _M_param(__mu_val, __omega_val),
1219
        _M_gd(__mu_val, __omega_val / __mu_val)
1220
      { }
1221
 
1222
      explicit
1223
      nakagami_distribution(const param_type& __p)
1224
      : _M_param(__p),
1225
        _M_gd(__p.mu(), __p.omega() / __p.mu())
1226
      { }
1227
 
1228
      /**
1229
       * @brief Resets the distribution state.
1230
       */
1231
      void
1232
      reset()
1233
      { _M_gd.reset(); }
1234
 
1235
      /**
1236
       * @brief Return the parameters of the distribution.
1237
       */
1238
      result_type
1239
      mu() const
1240
      { return _M_param.mu(); }
1241
 
1242
      result_type
1243
      omega() const
1244
      { return _M_param.omega(); }
1245
 
1246
      /**
1247
       * @brief Returns the parameter set of the distribution.
1248
       */
1249
      param_type
1250
      param() const
1251
      { return _M_param; }
1252
 
1253
      /**
1254
       * @brief Sets the parameter set of the distribution.
1255
       * @param __param The new parameter set of the distribution.
1256
       */
1257
      void
1258
      param(const param_type& __param)
1259
      { _M_param = __param; }
1260
 
1261
      /**
1262
       * @brief Returns the greatest lower bound value of the distribution.
1263
       */
1264
      result_type
1265
      min() const
1266
      { return result_type(0); }
1267
 
1268
      /**
1269
       * @brief Returns the least upper bound value of the distribution.
1270
       */
1271
      result_type
1272
      max() const
1273
      { return std::numeric_limits::max(); }
1274
 
1275
      /**
1276
       * @brief Generating functions.
1277
       */
1278
      template
1279
        result_type
1280
        operator()(_UniformRandomNumberGenerator& __urng)
1281
        { return std::sqrt(this->_M_gd(__urng)); }
1282
 
1283
      template
1284
        result_type
1285
        operator()(_UniformRandomNumberGenerator& __urng,
1286
                   const param_type& __p)
1287
        {
1288
          typename std::gamma_distribution::param_type
1289
            __pg(__p.mu(), __p.omega() / __p.mu());
1290
          return std::sqrt(this->_M_gd(__pg, __urng));
1291
        }
1292
 
1293
      template
1294
               typename _UniformRandomNumberGenerator>
1295
        void
1296
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1297
                   _UniformRandomNumberGenerator& __urng)
1298
        { this->__generate(__f, __t, __urng, _M_param); }
1299
 
1300
      template
1301
               typename _UniformRandomNumberGenerator>
1302
        void
1303
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1304
                   _UniformRandomNumberGenerator& __urng,
1305
                   const param_type& __p)
1306
        { this->__generate_impl(__f, __t, __urng, __p); }
1307
 
1308
      template
1309
        void
1310
        __generate(result_type* __f, result_type* __t,
1311
                   _UniformRandomNumberGenerator& __urng,
1312
                   const param_type& __p)
1313
        { this->__generate_impl(__f, __t, __urng, __p); }
1314
 
1315
      /**
1316
       * @brief Return true if two Nakagami distributions have
1317
       *        the same parameters and the sequences that would
1318
       *        be generated are equal.
1319
       */
1320
      friend bool
1321
      operator==(const nakagami_distribution& __d1,
1322
                 const nakagami_distribution& __d2)
1323
      { return (__d1._M_param == __d2._M_param
1324
                && __d1._M_gd == __d2._M_gd); }
1325
 
1326
      /**
1327
       * @brief Inserts a %nakagami_distribution random number distribution
1328
       * @p __x into the output stream @p __os.
1329
       *
1330
       * @param __os An output stream.
1331
       * @param __x  A %nakagami_distribution random number distribution.
1332
       *
1333
       * @returns The output stream with the state of @p __x inserted or in
1334
       * an error state.
1335
       */
1336
      template
1337
        friend std::basic_ostream<_CharT, _Traits>&
1338
        operator<<(std::basic_ostream<_CharT, _Traits>&,
1339
                   const nakagami_distribution<_RealType1>&);
1340
 
1341
      /**
1342
       * @brief Extracts a %nakagami_distribution random number distribution
1343
       * @p __x from the input stream @p __is.
1344
       *
1345
       * @param __is An input stream.
1346
       * @param __x A %nakagami_distribution random number
1347
       *            generator engine.
1348
       *
1349
       * @returns The input stream with @p __x extracted or in an error state.
1350
       */
1351
      template
1352
        friend std::basic_istream<_CharT, _Traits>&
1353
        operator>>(std::basic_istream<_CharT, _Traits>&,
1354
                   nakagami_distribution<_RealType1>&);
1355
 
1356
    private:
1357
      template
1358
               typename _UniformRandomNumberGenerator>
1359
        void
1360
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1361
                        _UniformRandomNumberGenerator& __urng,
1362
                        const param_type& __p);
1363
 
1364
      param_type _M_param;
1365
 
1366
      std::gamma_distribution _M_gd;
1367
    };
1368
 
1369
  /**
1370
   * @brief Return true if two Nakagami distributions are not equal.
1371
   */
1372
  template
1373
    inline bool
1374
    operator!=(const nakagami_distribution<_RealType>& __d1,
1375
               const nakagami_distribution<_RealType>& __d2)
1376
    { return !(__d1 == __d2); }
1377
 
1378
 
1379
  /**
1380
   * @brief A Pareto continuous distribution for random numbers.
1381
   *
1382
   * The formula for the Pareto cumulative probability function is
1383
   * @f[
1384
   *     P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha
1385
   * @f]
1386
   * The formula for the Pareto probability density function is
1387
   * @f[
1388
   *     p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu}
1389
   *                       \left(\frac{\mu}{x}\right)^{\alpha + 1}
1390
   * @f]
1391
   * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$.
1392
   *
1393
   * 
1394
   * 
Distribution Statistics
1395
   * 
Mean@f$\alpha \mu / (\alpha - 1)@f$
1396
   *              for @f$\alpha > 1@f$
1397
   * 
Variance@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$
1398
   *              for @f$\alpha > 2@f$
1399
   * 
Range@f$[\mu, \infty)@f$
1400
   * 
1401
   */
1402
  template
1403
    class
1404
    pareto_distribution
1405
    {
1406
      static_assert(std::is_floating_point<_RealType>::value,
1407
                    "template argument not a floating point type");
1408
 
1409
    public:
1410
      /** The type of the range of the distribution. */
1411
      typedef _RealType result_type;
1412
      /** Parameter type. */
1413
      struct param_type
1414
      {
1415
        typedef pareto_distribution distribution_type;
1416
 
1417
        param_type(result_type __alpha_val = result_type(1),
1418
                   result_type __mu_val = result_type(1))
1419
        : _M_alpha(__alpha_val), _M_mu(__mu_val)
1420
        {
1421
          _GLIBCXX_DEBUG_ASSERT(_M_alpha > result_type(0));
1422
          _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0));
1423
        }
1424
 
1425
        result_type
1426
        alpha() const
1427
        { return _M_alpha; }
1428
 
1429
        result_type
1430
        mu() const
1431
        { return _M_mu; }
1432
 
1433
        friend bool
1434
        operator==(const param_type& __p1, const param_type& __p2)
1435
        { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; }
1436
 
1437
      private:
1438
        void _M_initialize();
1439
 
1440
        result_type _M_alpha;
1441
        result_type _M_mu;
1442
      };
1443
 
1444
      /**
1445
       * @brief Constructors.
1446
       */
1447
      explicit
1448
      pareto_distribution(result_type __alpha_val = result_type(1),
1449
                          result_type __mu_val = result_type(1))
1450
      : _M_param(__alpha_val, __mu_val),
1451
        _M_ud()
1452
      { }
1453
 
1454
      explicit
1455
      pareto_distribution(const param_type& __p)
1456
      : _M_param(__p),
1457
        _M_ud()
1458
      { }
1459
 
1460
      /**
1461
       * @brief Resets the distribution state.
1462
       */
1463
      void
1464
      reset()
1465
      {
1466
        _M_ud.reset();
1467
      }
1468
 
1469
      /**
1470
       * @brief Return the parameters of the distribution.
1471
       */
1472
      result_type
1473
      alpha() const
1474
      { return _M_param.alpha(); }
1475
 
1476
      result_type
1477
      mu() const
1478
      { return _M_param.mu(); }
1479
 
1480
      /**
1481
       * @brief Returns the parameter set of the distribution.
1482
       */
1483
      param_type
1484
      param() const
1485
      { return _M_param; }
1486
 
1487
      /**
1488
       * @brief Sets the parameter set of the distribution.
1489
       * @param __param The new parameter set of the distribution.
1490
       */
1491
      void
1492
      param(const param_type& __param)
1493
      { _M_param = __param; }
1494
 
1495
      /**
1496
       * @brief Returns the greatest lower bound value of the distribution.
1497
       */
1498
      result_type
1499
      min() const
1500
      { return this->mu(); }
1501
 
1502
      /**
1503
       * @brief Returns the least upper bound value of the distribution.
1504
       */
1505
      result_type
1506
      max() const
1507
      { return std::numeric_limits::max(); }
1508
 
1509
      /**
1510
       * @brief Generating functions.
1511
       */
1512
      template
1513
        result_type
1514
        operator()(_UniformRandomNumberGenerator& __urng)
1515
        {
1516
          return this->mu() * std::pow(this->_M_ud(__urng),
1517
                                       -result_type(1) / this->alpha());
1518
        }
1519
 
1520
      template
1521
        result_type
1522
        operator()(_UniformRandomNumberGenerator& __urng,
1523
                   const param_type& __p)
1524
        {
1525
          return __p.mu() * std::pow(this->_M_ud(__urng),
1526
                                           -result_type(1) / __p.alpha());
1527
        }
1528
 
1529
      template
1530
               typename _UniformRandomNumberGenerator>
1531
        void
1532
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1533
                   _UniformRandomNumberGenerator& __urng)
1534
        { this->__generate(__f, __t, __urng, _M_param); }
1535
 
1536
      template
1537
               typename _UniformRandomNumberGenerator>
1538
        void
1539
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1540
                   _UniformRandomNumberGenerator& __urng,
1541
                   const param_type& __p)
1542
        { this->__generate_impl(__f, __t, __urng, __p); }
1543
 
1544
      template
1545
        void
1546
        __generate(result_type* __f, result_type* __t,
1547
                   _UniformRandomNumberGenerator& __urng,
1548
                   const param_type& __p)
1549
        { this->__generate_impl(__f, __t, __urng, __p); }
1550
 
1551
      /**
1552
       * @brief Return true if two Pareto distributions have
1553
       *        the same parameters and the sequences that would
1554
       *        be generated are equal.
1555
       */
1556
      friend bool
1557
      operator==(const pareto_distribution& __d1,
1558
                 const pareto_distribution& __d2)
1559
      { return (__d1._M_param == __d2._M_param
1560
                && __d1._M_ud == __d2._M_ud); }
1561
 
1562
      /**
1563
       * @brief Inserts a %pareto_distribution random number distribution
1564
       * @p __x into the output stream @p __os.
1565
       *
1566
       * @param __os An output stream.
1567
       * @param __x  A %pareto_distribution random number distribution.
1568
       *
1569
       * @returns The output stream with the state of @p __x inserted or in
1570
       * an error state.
1571
       */
1572
      template
1573
        friend std::basic_ostream<_CharT, _Traits>&
1574
        operator<<(std::basic_ostream<_CharT, _Traits>&,
1575
                   const pareto_distribution<_RealType1>&);
1576
 
1577
      /**
1578
       * @brief Extracts a %pareto_distribution random number distribution
1579
       * @p __x from the input stream @p __is.
1580
       *
1581
       * @param __is An input stream.
1582
       * @param __x A %pareto_distribution random number
1583
       *            generator engine.
1584
       *
1585
       * @returns The input stream with @p __x extracted or in an error state.
1586
       */
1587
      template
1588
        friend std::basic_istream<_CharT, _Traits>&
1589
        operator>>(std::basic_istream<_CharT, _Traits>&,
1590
                   pareto_distribution<_RealType1>&);
1591
 
1592
    private:
1593
      template
1594
               typename _UniformRandomNumberGenerator>
1595
        void
1596
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1597
                        _UniformRandomNumberGenerator& __urng,
1598
                        const param_type& __p);
1599
 
1600
      param_type _M_param;
1601
 
1602
      std::uniform_real_distribution _M_ud;
1603
    };
1604
 
1605
  /**
1606
   * @brief Return true if two Pareto distributions are not equal.
1607
   */
1608
  template
1609
    inline bool
1610
    operator!=(const pareto_distribution<_RealType>& __d1,
1611
               const pareto_distribution<_RealType>& __d2)
1612
    { return !(__d1 == __d2); }
1613
 
1614
 
1615
  /**
1616
   * @brief A K continuous distribution for random numbers.
1617
   *
1618
   * The formula for the K probability density function is
1619
   * @f[
1620
   *     p(x|\lambda, \mu, \nu) = \frac{2}{x}
1621
   *             \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}}
1622
   *             \frac{1}{\Gamma(\lambda)\Gamma(\nu)}
1623
   *             K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right)
1624
   * @f]
1625
   * where @f$I_0(z)@f$ is the modified Bessel function of the second kind
1626
   * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$
1627
   * and @f$\nu > 0@f$.
1628
   *
1629
   * 
1630
   * 
Distribution Statistics
1631
   * 
Mean@f$\mu@f$
1632
   * 
Variance@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$
1633
   * 
Range@f$[0, \infty)@f$
1634
   * 
1635
   */
1636
  template
1637
    class
1638
    k_distribution
1639
    {
1640
      static_assert(std::is_floating_point<_RealType>::value,
1641
                    "template argument not a floating point type");
1642
 
1643
    public:
1644
      /** The type of the range of the distribution. */
1645
      typedef _RealType result_type;
1646
      /** Parameter type. */
1647
      struct param_type
1648
      {
1649
        typedef k_distribution distribution_type;
1650
 
1651
        param_type(result_type __lambda_val = result_type(1),
1652
                   result_type __mu_val = result_type(1),
1653
                   result_type __nu_val = result_type(1))
1654
        : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val)
1655
        {
1656
          _GLIBCXX_DEBUG_ASSERT(_M_lambda > result_type(0));
1657
          _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0));
1658
          _GLIBCXX_DEBUG_ASSERT(_M_nu > result_type(0));
1659
        }
1660
 
1661
        result_type
1662
        lambda() const
1663
        { return _M_lambda; }
1664
 
1665
        result_type
1666
        mu() const
1667
        { return _M_mu; }
1668
 
1669
        result_type
1670
        nu() const
1671
        { return _M_nu; }
1672
 
1673
        friend bool
1674
        operator==(const param_type& __p1, const param_type& __p2)
1675
        { return __p1._M_lambda == __p2._M_lambda
1676
              && __p1._M_mu == __p2._M_mu
1677
              && __p1._M_nu == __p2._M_nu; }
1678
 
1679
      private:
1680
        void _M_initialize();
1681
 
1682
        result_type _M_lambda;
1683
        result_type _M_mu;
1684
        result_type _M_nu;
1685
      };
1686
 
1687
      /**
1688
       * @brief Constructors.
1689
       */
1690
      explicit
1691
      k_distribution(result_type __lambda_val = result_type(1),
1692
                     result_type __mu_val = result_type(1),
1693
                     result_type __nu_val = result_type(1))
1694
      : _M_param(__lambda_val, __mu_val, __nu_val),
1695
        _M_gd1(__lambda_val, result_type(1) / __lambda_val),
1696
        _M_gd2(__nu_val, __mu_val / __nu_val)
1697
      { }
1698
 
1699
      explicit
1700
      k_distribution(const param_type& __p)
1701
      : _M_param(__p),
1702
        _M_gd1(__p.lambda(), result_type(1) / __p.lambda()),
1703
        _M_gd2(__p.nu(), __p.mu() / __p.nu())
1704
      { }
1705
 
1706
      /**
1707
       * @brief Resets the distribution state.
1708
       */
1709
      void
1710
      reset()
1711
      {
1712
        _M_gd1.reset();
1713
        _M_gd2.reset();
1714
      }
1715
 
1716
      /**
1717
       * @brief Return the parameters of the distribution.
1718
       */
1719
      result_type
1720
      lambda() const
1721
      { return _M_param.lambda(); }
1722
 
1723
      result_type
1724
      mu() const
1725
      { return _M_param.mu(); }
1726
 
1727
      result_type
1728
      nu() const
1729
      { return _M_param.nu(); }
1730
 
1731
      /**
1732
       * @brief Returns the parameter set of the distribution.
1733
       */
1734
      param_type
1735
      param() const
1736
      { return _M_param; }
1737
 
1738
      /**
1739
       * @brief Sets the parameter set of the distribution.
1740
       * @param __param The new parameter set of the distribution.
1741
       */
1742
      void
1743
      param(const param_type& __param)
1744
      { _M_param = __param; }
1745
 
1746
      /**
1747
       * @brief Returns the greatest lower bound value of the distribution.
1748
       */
1749
      result_type
1750
      min() const
1751
      { return result_type(0); }
1752
 
1753
      /**
1754
       * @brief Returns the least upper bound value of the distribution.
1755
       */
1756
      result_type
1757
      max() const
1758
      { return std::numeric_limits::max(); }
1759
 
1760
      /**
1761
       * @brief Generating functions.
1762
       */
1763
      template
1764
        result_type
1765
        operator()(_UniformRandomNumberGenerator&);
1766
 
1767
      template
1768
        result_type
1769
        operator()(_UniformRandomNumberGenerator&, const param_type&);
1770
 
1771
      template
1772
               typename _UniformRandomNumberGenerator>
1773
        void
1774
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1775
                   _UniformRandomNumberGenerator& __urng)
1776
        { this->__generate(__f, __t, __urng, _M_param); }
1777
 
1778
      template
1779
               typename _UniformRandomNumberGenerator>
1780
        void
1781
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1782
                   _UniformRandomNumberGenerator& __urng,
1783
                   const param_type& __p)
1784
        { this->__generate_impl(__f, __t, __urng, __p); }
1785
 
1786
      template
1787
        void
1788
        __generate(result_type* __f, result_type* __t,
1789
                   _UniformRandomNumberGenerator& __urng,
1790
                   const param_type& __p)
1791
        { this->__generate_impl(__f, __t, __urng, __p); }
1792
 
1793
      /**
1794
       * @brief Return true if two K distributions have
1795
       *        the same parameters and the sequences that would
1796
       *        be generated are equal.
1797
       */
1798
      friend bool
1799
      operator==(const k_distribution& __d1,
1800
                 const k_distribution& __d2)
1801
      { return (__d1._M_param == __d2._M_param
1802
                && __d1._M_gd1 == __d2._M_gd1
1803
                && __d1._M_gd2 == __d2._M_gd2); }
1804
 
1805
      /**
1806
       * @brief Inserts a %k_distribution random number distribution
1807
       * @p __x into the output stream @p __os.
1808
       *
1809
       * @param __os An output stream.
1810
       * @param __x  A %k_distribution random number distribution.
1811
       *
1812
       * @returns The output stream with the state of @p __x inserted or in
1813
       * an error state.
1814
       */
1815
      template
1816
        friend std::basic_ostream<_CharT, _Traits>&
1817
        operator<<(std::basic_ostream<_CharT, _Traits>&,
1818
                   const k_distribution<_RealType1>&);
1819
 
1820
      /**
1821
       * @brief Extracts a %k_distribution random number distribution
1822
       * @p __x from the input stream @p __is.
1823
       *
1824
       * @param __is An input stream.
1825
       * @param __x A %k_distribution random number
1826
       *            generator engine.
1827
       *
1828
       * @returns The input stream with @p __x extracted or in an error state.
1829
       */
1830
      template
1831
        friend std::basic_istream<_CharT, _Traits>&
1832
        operator>>(std::basic_istream<_CharT, _Traits>&,
1833
                   k_distribution<_RealType1>&);
1834
 
1835
    private:
1836
      template
1837
               typename _UniformRandomNumberGenerator>
1838
        void
1839
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1840
                        _UniformRandomNumberGenerator& __urng,
1841
                        const param_type& __p);
1842
 
1843
      param_type _M_param;
1844
 
1845
      std::gamma_distribution _M_gd1;
1846
      std::gamma_distribution _M_gd2;
1847
    };
1848
 
1849
  /**
1850
   * @brief Return true if two K distributions are not equal.
1851
   */
1852
  template
1853
    inline bool
1854
    operator!=(const k_distribution<_RealType>& __d1,
1855
               const k_distribution<_RealType>& __d2)
1856
    { return !(__d1 == __d2); }
1857
 
1858
 
1859
  /**
1860
   * @brief An arcsine continuous distribution for random numbers.
1861
   *
1862
   * The formula for the arcsine probability density function is
1863
   * @f[
1864
   *     p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
1865
   * @f]
1866
   * where @f$x >= a@f$ and @f$x <= b@f$.
1867
   *
1868
   * 
1869
   * 
Distribution Statistics
1870
   * 
Mean@f$ (a + b) / 2 @f$
1871
   * 
Variance@f$ (b - a)^2 / 8 @f$
1872
   * 
Range@f$[a, b]@f$
1873
   * 
1874
   */
1875
  template
1876
    class
1877
    arcsine_distribution
1878
    {
1879
      static_assert(std::is_floating_point<_RealType>::value,
1880
                    "template argument not a floating point type");
1881
 
1882
    public:
1883
      /** The type of the range of the distribution. */
1884
      typedef _RealType result_type;
1885
      /** Parameter type. */
1886
      struct param_type
1887
      {
1888
        typedef arcsine_distribution distribution_type;
1889
 
1890
        param_type(result_type __a = result_type(0),
1891
                   result_type __b = result_type(1))
1892
        : _M_a(__a), _M_b(__b)
1893
        {
1894
          _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1895
        }
1896
 
1897
        result_type
1898
        a() const
1899
        { return _M_a; }
1900
 
1901
        result_type
1902
        b() const
1903
        { return _M_b; }
1904
 
1905
        friend bool
1906
        operator==(const param_type& __p1, const param_type& __p2)
1907
        { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1908
 
1909
      private:
1910
        void _M_initialize();
1911
 
1912
        result_type _M_a;
1913
        result_type _M_b;
1914
      };
1915
 
1916
      /**
1917
       * @brief Constructors.
1918
       */
1919
      explicit
1920
      arcsine_distribution(result_type __a = result_type(0),
1921
                           result_type __b = result_type(1))
1922
      : _M_param(__a, __b),
1923
        _M_ud(-1.5707963267948966192313216916397514L,
1924
              +1.5707963267948966192313216916397514L)
1925
      { }
1926
 
1927
      explicit
1928
      arcsine_distribution(const param_type& __p)
1929
      : _M_param(__p),
1930
        _M_ud(-1.5707963267948966192313216916397514L,
1931
              +1.5707963267948966192313216916397514L)
1932
      { }
1933
 
1934
      /**
1935
       * @brief Resets the distribution state.
1936
       */
1937
      void
1938
      reset()
1939
      { _M_ud.reset(); }
1940
 
1941
      /**
1942
       * @brief Return the parameters of the distribution.
1943
       */
1944
      result_type
1945
      a() const
1946
      { return _M_param.a(); }
1947
 
1948
      result_type
1949
      b() const
1950
      { return _M_param.b(); }
1951
 
1952
      /**
1953
       * @brief Returns the parameter set of the distribution.
1954
       */
1955
      param_type
1956
      param() const
1957
      { return _M_param; }
1958
 
1959
      /**
1960
       * @brief Sets the parameter set of the distribution.
1961
       * @param __param The new parameter set of the distribution.
1962
       */
1963
      void
1964
      param(const param_type& __param)
1965
      { _M_param = __param; }
1966
 
1967
      /**
1968
       * @brief Returns the greatest lower bound value of the distribution.
1969
       */
1970
      result_type
1971
      min() const
1972
      { return this->a(); }
1973
 
1974
      /**
1975
       * @brief Returns the least upper bound value of the distribution.
1976
       */
1977
      result_type
1978
      max() const
1979
      { return this->b(); }
1980
 
1981
      /**
1982
       * @brief Generating functions.
1983
       */
1984
      template
1985
        result_type
1986
        operator()(_UniformRandomNumberGenerator& __urng)
1987
        {
1988
          result_type __x = std::sin(this->_M_ud(__urng));
1989
          return (__x * (this->b() - this->a())
1990
                  + this->a() + this->b()) / result_type(2);
1991
        }
1992
 
1993
      template
1994
        result_type
1995
        operator()(_UniformRandomNumberGenerator& __urng,
1996
                   const param_type& __p)
1997
        {
1998
          result_type __x = std::sin(this->_M_ud(__urng));
1999
          return (__x * (__p.b() - __p.a())
2000
                  + __p.a() + __p.b()) / result_type(2);
2001
        }
2002
 
2003
      template
2004
               typename _UniformRandomNumberGenerator>
2005
        void
2006
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2007
                   _UniformRandomNumberGenerator& __urng)
2008
        { this->__generate(__f, __t, __urng, _M_param); }
2009
 
2010
      template
2011
               typename _UniformRandomNumberGenerator>
2012
        void
2013
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2014
                   _UniformRandomNumberGenerator& __urng,
2015
                   const param_type& __p)
2016
        { this->__generate_impl(__f, __t, __urng, __p); }
2017
 
2018
      template
2019
        void
2020
        __generate(result_type* __f, result_type* __t,
2021
                   _UniformRandomNumberGenerator& __urng,
2022
                   const param_type& __p)
2023
        { this->__generate_impl(__f, __t, __urng, __p); }
2024
 
2025
      /**
2026
       * @brief Return true if two arcsine distributions have
2027
       *        the same parameters and the sequences that would
2028
       *        be generated are equal.
2029
       */
2030
      friend bool
2031
      operator==(const arcsine_distribution& __d1,
2032
                 const arcsine_distribution& __d2)
2033
      { return (__d1._M_param == __d2._M_param
2034
                && __d1._M_ud == __d2._M_ud); }
2035
 
2036
      /**
2037
       * @brief Inserts a %arcsine_distribution random number distribution
2038
       * @p __x into the output stream @p __os.
2039
       *
2040
       * @param __os An output stream.
2041
       * @param __x  A %arcsine_distribution random number distribution.
2042
       *
2043
       * @returns The output stream with the state of @p __x inserted or in
2044
       * an error state.
2045
       */
2046
      template
2047
        friend std::basic_ostream<_CharT, _Traits>&
2048
        operator<<(std::basic_ostream<_CharT, _Traits>&,
2049
                   const arcsine_distribution<_RealType1>&);
2050
 
2051
      /**
2052
       * @brief Extracts a %arcsine_distribution random number distribution
2053
       * @p __x from the input stream @p __is.
2054
       *
2055
       * @param __is An input stream.
2056
       * @param __x A %arcsine_distribution random number
2057
       *            generator engine.
2058
       *
2059
       * @returns The input stream with @p __x extracted or in an error state.
2060
       */
2061
      template
2062
        friend std::basic_istream<_CharT, _Traits>&
2063
        operator>>(std::basic_istream<_CharT, _Traits>&,
2064
                   arcsine_distribution<_RealType1>&);
2065
 
2066
    private:
2067
      template
2068
               typename _UniformRandomNumberGenerator>
2069
        void
2070
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2071
                        _UniformRandomNumberGenerator& __urng,
2072
                        const param_type& __p);
2073
 
2074
      param_type _M_param;
2075
 
2076
      std::uniform_real_distribution _M_ud;
2077
    };
2078
 
2079
  /**
2080
   * @brief Return true if two arcsine distributions are not equal.
2081
   */
2082
  template
2083
    inline bool
2084
    operator!=(const arcsine_distribution<_RealType>& __d1,
2085
               const arcsine_distribution<_RealType>& __d2)
2086
    { return !(__d1 == __d2); }
2087
 
2088
 
2089
  /**
2090
   * @brief A Hoyt continuous distribution for random numbers.
2091
   *
2092
   * The formula for the Hoyt probability density function is
2093
   * @f[
2094
   *     p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
2095
   *                     \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
2096
   *                       I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
2097
   * @f]
2098
   * where @f$I_0(z)@f$ is the modified Bessel function of the first kind
2099
   * of order 0 and @f$0 < q < 1@f$.
2100
   *
2101
   * 
2102
   * 
Distribution Statistics
2103
   * 
Mean@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
2104
   *                       E(1 - q^2) @f$
2105
   * 
Variance@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
2106
   *                                      {\pi (1 + q^2)}\right) @f$
2107
   * 
Range@f$[0, \infty)@f$
2108
   * 
2109
   * where @f$E(x)@f$ is the elliptic function of the second kind.
2110
   */
2111
  template
2112
    class
2113
    hoyt_distribution
2114
    {
2115
      static_assert(std::is_floating_point<_RealType>::value,
2116
                    "template argument not a floating point type");
2117
 
2118
    public:
2119
      /** The type of the range of the distribution. */
2120
      typedef _RealType result_type;
2121
      /** Parameter type. */
2122
      struct param_type
2123
      {
2124
        typedef hoyt_distribution distribution_type;
2125
 
2126
        param_type(result_type __q = result_type(0.5L),
2127
                   result_type __omega = result_type(1))
2128
        : _M_q(__q), _M_omega(__omega)
2129
        {
2130
          _GLIBCXX_DEBUG_ASSERT(_M_q > result_type(0));
2131
          _GLIBCXX_DEBUG_ASSERT(_M_q < result_type(1));
2132
        }
2133
 
2134
        result_type
2135
        q() const
2136
        { return _M_q; }
2137
 
2138
        result_type
2139
        omega() const
2140
        { return _M_omega; }
2141
 
2142
        friend bool
2143
        operator==(const param_type& __p1, const param_type& __p2)
2144
        { return __p1._M_q == __p2._M_q
2145
              && __p1._M_omega == __p2._M_omega; }
2146
 
2147
      private:
2148
        void _M_initialize();
2149
 
2150
        result_type _M_q;
2151
        result_type _M_omega;
2152
      };
2153
 
2154
      /**
2155
       * @brief Constructors.
2156
       */
2157
      explicit
2158
      hoyt_distribution(result_type __q = result_type(0.5L),
2159
                        result_type __omega = result_type(1))
2160
      : _M_param(__q, __omega),
2161
        _M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
2162
              result_type(0.5L) * (result_type(1) + __q * __q)
2163
                                / (__q * __q)),
2164
        _M_ed(result_type(1))
2165
      { }
2166
 
2167
      explicit
2168
      hoyt_distribution(const param_type& __p)
2169
      : _M_param(__p),
2170
        _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
2171
              result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
2172
                                / (__p.q() * __p.q())),
2173
        _M_ed(result_type(1))
2174
      { }
2175
 
2176
      /**
2177
       * @brief Resets the distribution state.
2178
       */
2179
      void
2180
      reset()
2181
      {
2182
        _M_ad.reset();
2183
        _M_ed.reset();
2184
      }
2185
 
2186
      /**
2187
       * @brief Return the parameters of the distribution.
2188
       */
2189
      result_type
2190
      q() const
2191
      { return _M_param.q(); }
2192
 
2193
      result_type
2194
      omega() const
2195
      { return _M_param.omega(); }
2196
 
2197
      /**
2198
       * @brief Returns the parameter set of the distribution.
2199
       */
2200
      param_type
2201
      param() const
2202
      { return _M_param; }
2203
 
2204
      /**
2205
       * @brief Sets the parameter set of the distribution.
2206
       * @param __param The new parameter set of the distribution.
2207
       */
2208
      void
2209
      param(const param_type& __param)
2210
      { _M_param = __param; }
2211
 
2212
      /**
2213
       * @brief Returns the greatest lower bound value of the distribution.
2214
       */
2215
      result_type
2216
      min() const
2217
      { return result_type(0); }
2218
 
2219
      /**
2220
       * @brief Returns the least upper bound value of the distribution.
2221
       */
2222
      result_type
2223
      max() const
2224
      { return std::numeric_limits::max(); }
2225
 
2226
      /**
2227
       * @brief Generating functions.
2228
       */
2229
      template
2230
        result_type
2231
        operator()(_UniformRandomNumberGenerator& __urng);
2232
 
2233
      template
2234
        result_type
2235
        operator()(_UniformRandomNumberGenerator& __urng,
2236
                   const param_type& __p);
2237
 
2238
      template
2239
               typename _UniformRandomNumberGenerator>
2240
        void
2241
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2242
                   _UniformRandomNumberGenerator& __urng)
2243
        { this->__generate(__f, __t, __urng, _M_param); }
2244
 
2245
      template
2246
               typename _UniformRandomNumberGenerator>
2247
        void
2248
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2249
                   _UniformRandomNumberGenerator& __urng,
2250
                   const param_type& __p)
2251
        { this->__generate_impl(__f, __t, __urng, __p); }
2252
 
2253
      template
2254
        void
2255
        __generate(result_type* __f, result_type* __t,
2256
                   _UniformRandomNumberGenerator& __urng,
2257
                   const param_type& __p)
2258
        { this->__generate_impl(__f, __t, __urng, __p); }
2259
 
2260
      /**
2261
       * @brief Return true if two Hoyt distributions have
2262
       *        the same parameters and the sequences that would
2263
       *        be generated are equal.
2264
       */
2265
      friend bool
2266
      operator==(const hoyt_distribution& __d1,
2267
                 const hoyt_distribution& __d2)
2268
      { return (__d1._M_param == __d2._M_param
2269
                && __d1._M_ad == __d2._M_ad
2270
                && __d1._M_ed == __d2._M_ed); }
2271
 
2272
      /**
2273
       * @brief Inserts a %hoyt_distribution random number distribution
2274
       * @p __x into the output stream @p __os.
2275
       *
2276
       * @param __os An output stream.
2277
       * @param __x  A %hoyt_distribution random number distribution.
2278
       *
2279
       * @returns The output stream with the state of @p __x inserted or in
2280
       * an error state.
2281
       */
2282
      template
2283
        friend std::basic_ostream<_CharT, _Traits>&
2284
        operator<<(std::basic_ostream<_CharT, _Traits>&,
2285
                   const hoyt_distribution<_RealType1>&);
2286
 
2287
      /**
2288
       * @brief Extracts a %hoyt_distribution random number distribution
2289
       * @p __x from the input stream @p __is.
2290
       *
2291
       * @param __is An input stream.
2292
       * @param __x A %hoyt_distribution random number
2293
       *            generator engine.
2294
       *
2295
       * @returns The input stream with @p __x extracted or in an error state.
2296
       */
2297
      template
2298
        friend std::basic_istream<_CharT, _Traits>&
2299
        operator>>(std::basic_istream<_CharT, _Traits>&,
2300
                   hoyt_distribution<_RealType1>&);
2301
 
2302
    private:
2303
      template
2304
               typename _UniformRandomNumberGenerator>
2305
        void
2306
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2307
                        _UniformRandomNumberGenerator& __urng,
2308
                        const param_type& __p);
2309
 
2310
      param_type _M_param;
2311
 
2312
      __gnu_cxx::arcsine_distribution _M_ad;
2313
      std::exponential_distribution _M_ed;
2314
    };
2315
 
2316
  /**
2317
   * @brief Return true if two Hoyt distributions are not equal.
2318
   */
2319
  template
2320
    inline bool
2321
    operator!=(const hoyt_distribution<_RealType>& __d1,
2322
               const hoyt_distribution<_RealType>& __d2)
2323
    { return !(__d1 == __d2); }
2324
 
2325
_GLIBCXX_END_NAMESPACE_VERSION
2326
} // namespace __gnu_cxx
2327
 
2328
#include "opt_random.h"
2329
#include "random.tcc"
2330
 
2331
#endif // _GLIBCXX_USE_C99_STDINT_TR1
2332
 
2333
#endif // C++11
2334
 
2335
#endif // _EXT_RANDOM

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.