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/] [bits/] [random.h] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// random number generation -*- C++ -*-
2
 
3
// Copyright (C) 2009-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
// <http://www.gnu.org/licenses/>.
24
 
25
/**
26
 * @file bits/random.h
27
 *  This is an internal header file, included by other library headers.
28
 *  Do not attempt to use it directly. @headername{random}
29
 */
30
 
31
#ifndef _RANDOM_H
32
#define _RANDOM_H 1
33
 
34
#include <vector>
35
 
36
namespace std _GLIBCXX_VISIBILITY(default)
37
{
38
_GLIBCXX_BEGIN_NAMESPACE_VERSION
39
 
40
  // [26.4] Random number generation
41
 
42
  /**
43
   * @defgroup random Random Number Generation
44
   * @ingroup numerics
45
   *
46
   * A facility for generating random numbers on selected distributions.
47
   * @{
48
   */
49
 
50
  /**
51
   * @brief A function template for converting the output of a (integral)
52
   * uniform random number generator to a floatng point result in the range
53
   * [0-1).
54
   */
55
  template<typename _RealType, size_t __bits,
56
           typename _UniformRandomNumberGenerator>
57
    _RealType
58
    generate_canonical(_UniformRandomNumberGenerator& __g);
59
 
60
_GLIBCXX_END_NAMESPACE_VERSION
61
 
62
  /*
63
   * Implementation-space details.
64
   */
65
  namespace __detail
66
  {
67
  _GLIBCXX_BEGIN_NAMESPACE_VERSION
68
 
69
    template<typename _UIntType, size_t __w,
70
             bool = __w < static_cast<size_t>
71
                          (std::numeric_limits<_UIntType>::digits)>
72
      struct _Shift
73
      { static const _UIntType __value = 0; };
74
 
75
    template<typename _UIntType, size_t __w>
76
      struct _Shift<_UIntType, __w, true>
77
      { static const _UIntType __value = _UIntType(1) << __w; };
78
 
79
    template<int __s,
80
             int __which = ((__s <= __CHAR_BIT__ * sizeof (int))
81
                            + (__s <= __CHAR_BIT__ * sizeof (long))
82
                            + (__s <= __CHAR_BIT__ * sizeof (long long))
83
                            /* assume long long no bigger than __int128 */
84
                            + (__s <= 128))>
85
      struct _Select_uint_least_t
86
      {
87
        static_assert(__which < 0, /* needs to be dependent */
88
                      "sorry, would be too much trouble for a slow result");
89
      };
90
 
91
    template<int __s>
92
      struct _Select_uint_least_t<__s, 4>
93
      { typedef unsigned int type; };
94
 
95
    template<int __s>
96
      struct _Select_uint_least_t<__s, 3>
97
      { typedef unsigned long type; };
98
 
99
    template<int __s>
100
      struct _Select_uint_least_t<__s, 2>
101
      { typedef unsigned long long type; };
102
 
103
#ifdef _GLIBCXX_USE_INT128
104
    template<int __s>
105
      struct _Select_uint_least_t<__s, 1>
106
      { typedef unsigned __int128 type; };
107
#endif
108
 
109
    // Assume a != 0, a < m, c < m, x < m.
110
    template<typename _Tp, _Tp __m, _Tp __a, _Tp __c,
111
             bool __big_enough = (!(__m & (__m - 1))
112
                                  || (_Tp(-1) - __c) / __a >= __m - 1),
113
             bool __schrage_ok = __m % __a < __m / __a>
114
      struct _Mod
115
      {
116
        typedef typename _Select_uint_least_t<std::__lg(__a)
117
                                              + std::__lg(__m) + 2>::type _Tp2;
118
        static _Tp
119
        __calc(_Tp __x)
120
        { return static_cast<_Tp>((_Tp2(__a) * __x + __c) % __m); }
121
      };
122
 
123
    // Schrage.
124
    template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
125
      struct _Mod<_Tp, __m, __a, __c, false, true>
126
      {
127
        static _Tp
128
        __calc(_Tp __x);
129
      };
130
 
131
    // Special cases:
132
    // - for m == 2^n or m == 0, unsigned integer overflow is safe.
133
    // - a * (m - 1) + c fits in _Tp, there is no overflow.
134
    template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool __s>
135
      struct _Mod<_Tp, __m, __a, __c, true, __s>
136
      {
137
        static _Tp
138
        __calc(_Tp __x)
139
        {
140
          _Tp __res = __a * __x + __c;
141
          if (__m)
142
            __res %= __m;
143
          return __res;
144
        }
145
      };
146
 
147
    template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0>
148
      inline _Tp
149
      __mod(_Tp __x)
150
      { return _Mod<_Tp, __m, __a, __c>::__calc(__x); }
151
 
152
    /* Determine whether number is a power of 2.  */
153
    template<typename _Tp>
154
      inline bool
155
      _Power_of_2(_Tp __x)
156
      {
157
        return ((__x - 1) & __x) == 0;
158
      };
159
 
160
    /*
161
     * An adaptor class for converting the output of any Generator into
162
     * the input for a specific Distribution.
163
     */
164
    template<typename _Engine, typename _DInputType>
165
      struct _Adaptor
166
      {
167
 
168
      public:
169
        _Adaptor(_Engine& __g)
170
        : _M_g(__g) { }
171
 
172
        _DInputType
173
        min() const
174
        { return _DInputType(0); }
175
 
176
        _DInputType
177
        max() const
178
        { return _DInputType(1); }
179
 
180
        /*
181
         * Converts a value generated by the adapted random number generator
182
         * into a value in the input domain for the dependent random number
183
         * distribution.
184
         */
185
        _DInputType
186
        operator()()
187
        {
188
          return std::generate_canonical<_DInputType,
189
                                    std::numeric_limits<_DInputType>::digits,
190
                                    _Engine>(_M_g);
191
        }
192
 
193
      private:
194
        _Engine& _M_g;
195
      };
196
 
197
  _GLIBCXX_END_NAMESPACE_VERSION
198
  } // namespace __detail
199
 
200
_GLIBCXX_BEGIN_NAMESPACE_VERSION
201
 
202
  /**
203
   * @addtogroup random_generators Random Number Generators
204
   * @ingroup random
205
   *
206
   * These classes define objects which provide random or pseudorandom
207
   * numbers, either from a discrete or a continuous interval.  The
208
   * random number generator supplied as a part of this library are
209
   * all uniform random number generators which provide a sequence of
210
   * random number uniformly distributed over their range.
211
   *
212
   * A number generator is a function object with an operator() that
213
   * takes zero arguments and returns a number.
214
   *
215
   * A compliant random number generator must satisfy the following
216
   * requirements.  <table border=1 cellpadding=10 cellspacing=0>
217
   * <caption align=top>Random Number Generator Requirements</caption>
218
   * <tr><td>To be documented.</td></tr> </table>
219
   *
220
   * @{
221
   */
222
 
223
  /**
224
   * @brief A model of a linear congruential random number generator.
225
   *
226
   * A random number generator that produces pseudorandom numbers via
227
   * linear function:
228
   * @f[
229
   *     x_{i+1}\leftarrow(ax_{i} + c) \bmod m
230
   * @f]
231
   *
232
   * The template parameter @p _UIntType must be an unsigned integral type
233
   * large enough to store values up to (__m-1). If the template parameter
234
   * @p __m is 0, the modulus @p __m used is
235
   * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
236
   * parameters @p __a and @p __c must be less than @p __m.
237
   *
238
   * The size of the state is @f$1@f$.
239
   */
240
  template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
241
    class linear_congruential_engine
242
    {
243
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
244
                    "substituting _UIntType not an unsigned integral type");
245
      static_assert(__m == 0u || (__a < __m && __c < __m),
246
                    "template argument substituting __m out of bounds");
247
 
248
    public:
249
      /** The type of the generated random value. */
250
      typedef _UIntType result_type;
251
 
252
      /** The multiplier. */
253
      static constexpr result_type multiplier   = __a;
254
      /** An increment. */
255
      static constexpr result_type increment    = __c;
256
      /** The modulus. */
257
      static constexpr result_type modulus      = __m;
258
      static constexpr result_type default_seed = 1u;
259
 
260
      /**
261
       * @brief Constructs a %linear_congruential_engine random number
262
       *        generator engine with seed @p __s.  The default seed value
263
       *        is 1.
264
       *
265
       * @param __s The initial seed value.
266
       */
267
      explicit
268
      linear_congruential_engine(result_type __s = default_seed)
269
      { seed(__s); }
270
 
271
      /**
272
       * @brief Constructs a %linear_congruential_engine random number
273
       *        generator engine seeded from the seed sequence @p __q.
274
       *
275
       * @param __q the seed sequence.
276
       */
277
      template<typename _Sseq, typename = typename
278
        std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
279
               ::type>
280
        explicit
281
        linear_congruential_engine(_Sseq& __q)
282
        { seed(__q); }
283
 
284
      /**
285
       * @brief Reseeds the %linear_congruential_engine random number generator
286
       *        engine sequence to the seed @p __s.
287
       *
288
       * @param __s The new seed.
289
       */
290
      void
291
      seed(result_type __s = default_seed);
292
 
293
      /**
294
       * @brief Reseeds the %linear_congruential_engine random number generator
295
       *        engine
296
       * sequence using values from the seed sequence @p __q.
297
       *
298
       * @param __q the seed sequence.
299
       */
300
      template<typename _Sseq>
301
        typename std::enable_if<std::is_class<_Sseq>::value>::type
302
        seed(_Sseq& __q);
303
 
304
      /**
305
       * @brief Gets the smallest possible value in the output range.
306
       *
307
       * The minimum depends on the @p __c parameter: if it is zero, the
308
       * minimum generated must be > 0, otherwise 0 is allowed.
309
       */
310
      static constexpr result_type
311
      min()
312
      { return __c == 0u ? 1u : 0u; }
313
 
314
      /**
315
       * @brief Gets the largest possible value in the output range.
316
       */
317
      static constexpr result_type
318
      max()
319
      { return __m - 1u; }
320
 
321
      /**
322
       * @brief Discard a sequence of random numbers.
323
       */
324
      void
325
      discard(unsigned long long __z)
326
      {
327
        for (; __z != 0ULL; --__z)
328
          (*this)();
329
      }
330
 
331
      /**
332
       * @brief Gets the next random number in the sequence.
333
       */
334
      result_type
335
      operator()()
336
      {
337
        _M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x);
338
        return _M_x;
339
      }
340
 
341
      /**
342
       * @brief Compares two linear congruential random number generator
343
       * objects of the same type for equality.
344
       *
345
       * @param __lhs A linear congruential random number generator object.
346
       * @param __rhs Another linear congruential random number generator
347
       *              object.
348
       *
349
       * @returns true if the infinite sequences of generated values
350
       *          would be equal, false otherwise.
351
       */
352
      friend bool
353
      operator==(const linear_congruential_engine& __lhs,
354
                 const linear_congruential_engine& __rhs)
355
      { return __lhs._M_x == __rhs._M_x; }
356
 
357
      /**
358
       * @brief Writes the textual representation of the state x(i) of x to
359
       *        @p __os.
360
       *
361
       * @param __os  The output stream.
362
       * @param __lcr A % linear_congruential_engine random number generator.
363
       * @returns __os.
364
       */
365
      template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
366
               _UIntType1 __m1, typename _CharT, typename _Traits>
367
        friend std::basic_ostream<_CharT, _Traits>&
368
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
369
                   const std::linear_congruential_engine<_UIntType1,
370
                   __a1, __c1, __m1>& __lcr);
371
 
372
      /**
373
       * @brief Sets the state of the engine by reading its textual
374
       *        representation from @p __is.
375
       *
376
       * The textual representation must have been previously written using
377
       * an output stream whose imbued locale and whose type's template
378
       * specialization arguments _CharT and _Traits were the same as those
379
       * of @p __is.
380
       *
381
       * @param __is  The input stream.
382
       * @param __lcr A % linear_congruential_engine random number generator.
383
       * @returns __is.
384
       */
385
      template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
386
               _UIntType1 __m1, typename _CharT, typename _Traits>
387
        friend std::basic_istream<_CharT, _Traits>&
388
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
389
                   std::linear_congruential_engine<_UIntType1, __a1,
390
                   __c1, __m1>& __lcr);
391
 
392
    private:
393
      _UIntType _M_x;
394
    };
395
 
396
  /**
397
   * @brief Compares two linear congruential random number generator
398
   * objects of the same type for inequality.
399
   *
400
   * @param __lhs A linear congruential random number generator object.
401
   * @param __rhs Another linear congruential random number generator
402
   *              object.
403
   *
404
   * @returns true if the infinite sequences of generated values
405
   *          would be different, false otherwise.
406
   */
407
  template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
408
    inline bool
409
    operator!=(const std::linear_congruential_engine<_UIntType, __a,
410
               __c, __m>& __lhs,
411
               const std::linear_congruential_engine<_UIntType, __a,
412
               __c, __m>& __rhs)
413
    { return !(__lhs == __rhs); }
414
 
415
 
416
  /**
417
   * A generalized feedback shift register discrete random number generator.
418
   *
419
   * This algorithm avoids multiplication and division and is designed to be
420
   * friendly to a pipelined architecture.  If the parameters are chosen
421
   * correctly, this generator will produce numbers with a very long period and
422
   * fairly good apparent entropy, although still not cryptographically strong.
423
   *
424
   * The best way to use this generator is with the predefined mt19937 class.
425
   *
426
   * This algorithm was originally invented by Makoto Matsumoto and
427
   * Takuji Nishimura.
428
   *
429
   * @tparam __w  Word size, the number of bits in each element of
430
   *              the state vector.
431
   * @tparam __n  The degree of recursion.
432
   * @tparam __m  The period parameter.
433
   * @tparam __r  The separation point bit index.
434
   * @tparam __a  The last row of the twist matrix.
435
   * @tparam __u  The first right-shift tempering matrix parameter.
436
   * @tparam __d  The first right-shift tempering matrix mask.
437
   * @tparam __s  The first left-shift tempering matrix parameter.
438
   * @tparam __b  The first left-shift tempering matrix mask.
439
   * @tparam __t  The second left-shift tempering matrix parameter.
440
   * @tparam __c  The second left-shift tempering matrix mask.
441
   * @tparam __l  The second right-shift tempering matrix parameter.
442
   * @tparam __f  Initialization multiplier.
443
   */
444
  template<typename _UIntType, size_t __w,
445
           size_t __n, size_t __m, size_t __r,
446
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
447
           _UIntType __b, size_t __t,
448
           _UIntType __c, size_t __l, _UIntType __f>
449
    class mersenne_twister_engine
450
    {
451
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
452
                    "substituting _UIntType not an unsigned integral type");
453
      static_assert(1u <= __m && __m <= __n,
454
                    "template argument substituting __m out of bounds");
455
      static_assert(__r <= __w, "template argument substituting "
456
                    "__r out of bound");
457
      static_assert(__u <= __w, "template argument substituting "
458
                    "__u out of bound");
459
      static_assert(__s <= __w, "template argument substituting "
460
                    "__s out of bound");
461
      static_assert(__t <= __w, "template argument substituting "
462
                    "__t out of bound");
463
      static_assert(__l <= __w, "template argument substituting "
464
                    "__l out of bound");
465
      static_assert(__w <= std::numeric_limits<_UIntType>::digits,
466
                    "template argument substituting __w out of bound");
467
      static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
468
                    "template argument substituting __a out of bound");
469
      static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
470
                    "template argument substituting __b out of bound");
471
      static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
472
                    "template argument substituting __c out of bound");
473
      static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1),
474
                    "template argument substituting __d out of bound");
475
      static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
476
                    "template argument substituting __f out of bound");
477
 
478
    public:
479
      /** The type of the generated random value. */
480
      typedef _UIntType result_type;
481
 
482
      // parameter values
483
      static constexpr size_t      word_size                 = __w;
484
      static constexpr size_t      state_size                = __n;
485
      static constexpr size_t      shift_size                = __m;
486
      static constexpr size_t      mask_bits                 = __r;
487
      static constexpr result_type xor_mask                  = __a;
488
      static constexpr size_t      tempering_u               = __u;
489
      static constexpr result_type tempering_d               = __d;
490
      static constexpr size_t      tempering_s               = __s;
491
      static constexpr result_type tempering_b               = __b;
492
      static constexpr size_t      tempering_t               = __t;
493
      static constexpr result_type tempering_c               = __c;
494
      static constexpr size_t      tempering_l               = __l;
495
      static constexpr result_type initialization_multiplier = __f;
496
      static constexpr result_type default_seed = 5489u;
497
 
498
      // constructors and member function
499
      explicit
500
      mersenne_twister_engine(result_type __sd = default_seed)
501
      { seed(__sd); }
502
 
503
      /**
504
       * @brief Constructs a %mersenne_twister_engine random number generator
505
       *        engine seeded from the seed sequence @p __q.
506
       *
507
       * @param __q the seed sequence.
508
       */
509
      template<typename _Sseq, typename = typename
510
        std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
511
               ::type>
512
        explicit
513
        mersenne_twister_engine(_Sseq& __q)
514
        { seed(__q); }
515
 
516
      void
517
      seed(result_type __sd = default_seed);
518
 
519
      template<typename _Sseq>
520
        typename std::enable_if<std::is_class<_Sseq>::value>::type
521
        seed(_Sseq& __q);
522
 
523
      /**
524
       * @brief Gets the smallest possible value in the output range.
525
       */
526
      static constexpr result_type
527
      min()
528
      { return 0; };
529
 
530
      /**
531
       * @brief Gets the largest possible value in the output range.
532
       */
533
      static constexpr result_type
534
      max()
535
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }
536
 
537
      /**
538
       * @brief Discard a sequence of random numbers.
539
       */
540
      void
541
      discard(unsigned long long __z);
542
 
543
      result_type
544
      operator()();
545
 
546
      /**
547
       * @brief Compares two % mersenne_twister_engine random number generator
548
       *        objects of the same type for equality.
549
       *
550
       * @param __lhs A % mersenne_twister_engine random number generator
551
       *              object.
552
       * @param __rhs Another % mersenne_twister_engine random number
553
       *              generator object.
554
       *
555
       * @returns true if the infinite sequences of generated values
556
       *          would be equal, false otherwise.
557
       */
558
      friend bool
559
      operator==(const mersenne_twister_engine& __lhs,
560
                 const mersenne_twister_engine& __rhs)
561
      { return (std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x)
562
                && __lhs._M_p == __rhs._M_p); }
563
 
564
      /**
565
       * @brief Inserts the current state of a % mersenne_twister_engine
566
       *        random number generator engine @p __x into the output stream
567
       *        @p __os.
568
       *
569
       * @param __os An output stream.
570
       * @param __x  A % mersenne_twister_engine random number generator
571
       *             engine.
572
       *
573
       * @returns The output stream with the state of @p __x inserted or in
574
       * an error state.
575
       */
576
      template<typename _UIntType1,
577
               size_t __w1, size_t __n1,
578
               size_t __m1, size_t __r1,
579
               _UIntType1 __a1, size_t __u1,
580
               _UIntType1 __d1, size_t __s1,
581
               _UIntType1 __b1, size_t __t1,
582
               _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
583
               typename _CharT, typename _Traits>
584
        friend std::basic_ostream<_CharT, _Traits>&
585
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
586
                   const std::mersenne_twister_engine<_UIntType1, __w1, __n1,
587
                   __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
588
                   __l1, __f1>& __x);
589
 
590
      /**
591
       * @brief Extracts the current state of a % mersenne_twister_engine
592
       *        random number generator engine @p __x from the input stream
593
       *        @p __is.
594
       *
595
       * @param __is An input stream.
596
       * @param __x  A % mersenne_twister_engine random number generator
597
       *             engine.
598
       *
599
       * @returns The input stream with the state of @p __x extracted or in
600
       * an error state.
601
       */
602
      template<typename _UIntType1,
603
               size_t __w1, size_t __n1,
604
               size_t __m1, size_t __r1,
605
               _UIntType1 __a1, size_t __u1,
606
               _UIntType1 __d1, size_t __s1,
607
               _UIntType1 __b1, size_t __t1,
608
               _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
609
               typename _CharT, typename _Traits>
610
        friend std::basic_istream<_CharT, _Traits>&
611
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
612
                   std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1,
613
                   __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
614
                   __l1, __f1>& __x);
615
 
616
    private:
617
      void _M_gen_rand();
618
 
619
      _UIntType _M_x[state_size];
620
      size_t    _M_p;
621
    };
622
 
623
  /**
624
   * @brief Compares two % mersenne_twister_engine random number generator
625
   *        objects of the same type for inequality.
626
   *
627
   * @param __lhs A % mersenne_twister_engine random number generator
628
   *              object.
629
   * @param __rhs Another % mersenne_twister_engine random number
630
   *              generator object.
631
   *
632
   * @returns true if the infinite sequences of generated values
633
   *          would be different, false otherwise.
634
   */
635
  template<typename _UIntType, size_t __w,
636
           size_t __n, size_t __m, size_t __r,
637
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
638
           _UIntType __b, size_t __t,
639
           _UIntType __c, size_t __l, _UIntType __f>
640
    inline bool
641
    operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
642
               __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs,
643
               const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
644
               __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs)
645
    { return !(__lhs == __rhs); }
646
 
647
 
648
  /**
649
   * @brief The Marsaglia-Zaman generator.
650
   *
651
   * This is a model of a Generalized Fibonacci discrete random number
652
   * generator, sometimes referred to as the SWC generator.
653
   *
654
   * A discrete random number generator that produces pseudorandom
655
   * numbers using:
656
   * @f[
657
   *     x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m
658
   * @f]
659
   *
660
   * The size of the state is @f$r@f$
661
   * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$.
662
   *
663
   * @var _M_x     The state of the generator.  This is a ring buffer.
664
   * @var _M_carry The carry.
665
   * @var _M_p     Current index of x(i - r).
666
   */
667
  template<typename _UIntType, size_t __w, size_t __s, size_t __r>
668
    class subtract_with_carry_engine
669
    {
670
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
671
                    "substituting _UIntType not an unsigned integral type");
672
      static_assert(0u < __s && __s < __r,
673
                    "template argument substituting __s out of bounds");
674
      static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
675
                    "template argument substituting __w out of bounds");
676
 
677
    public:
678
      /** The type of the generated random value. */
679
      typedef _UIntType result_type;
680
 
681
      // parameter values
682
      static constexpr size_t      word_size    = __w;
683
      static constexpr size_t      short_lag    = __s;
684
      static constexpr size_t      long_lag     = __r;
685
      static constexpr result_type default_seed = 19780503u;
686
 
687
      /**
688
       * @brief Constructs an explicitly seeded % subtract_with_carry_engine
689
       *        random number generator.
690
       */
691
      explicit
692
      subtract_with_carry_engine(result_type __sd = default_seed)
693
      { seed(__sd); }
694
 
695
      /**
696
       * @brief Constructs a %subtract_with_carry_engine random number engine
697
       *        seeded from the seed sequence @p __q.
698
       *
699
       * @param __q the seed sequence.
700
       */
701
      template<typename _Sseq, typename = typename
702
        std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
703
               ::type>
704
        explicit
705
        subtract_with_carry_engine(_Sseq& __q)
706
        { seed(__q); }
707
 
708
      /**
709
       * @brief Seeds the initial state @f$x_0@f$ of the random number
710
       *        generator.
711
       *
712
       * N1688[4.19] modifies this as follows.  If @p __value == 0,
713
       * sets value to 19780503.  In any case, with a linear
714
       * congruential generator lcg(i) having parameters @f$ m_{lcg} =
715
       * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
716
       * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
717
       * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
718
       * set carry to 1, otherwise sets carry to 0.
719
       */
720
      void
721
      seed(result_type __sd = default_seed);
722
 
723
      /**
724
       * @brief Seeds the initial state @f$x_0@f$ of the
725
       * % subtract_with_carry_engine random number generator.
726
       */
727
      template<typename _Sseq>
728
        typename std::enable_if<std::is_class<_Sseq>::value>::type
729
        seed(_Sseq& __q);
730
 
731
      /**
732
       * @brief Gets the inclusive minimum value of the range of random
733
       * integers returned by this generator.
734
       */
735
      static constexpr result_type
736
      min()
737
      { return 0; }
738
 
739
      /**
740
       * @brief Gets the inclusive maximum value of the range of random
741
       * integers returned by this generator.
742
       */
743
      static constexpr result_type
744
      max()
745
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }
746
 
747
      /**
748
       * @brief Discard a sequence of random numbers.
749
       */
750
      void
751
      discard(unsigned long long __z)
752
      {
753
        for (; __z != 0ULL; --__z)
754
          (*this)();
755
      }
756
 
757
      /**
758
       * @brief Gets the next random number in the sequence.
759
       */
760
      result_type
761
      operator()();
762
 
763
      /**
764
       * @brief Compares two % subtract_with_carry_engine random number
765
       *        generator objects of the same type for equality.
766
       *
767
       * @param __lhs A % subtract_with_carry_engine random number generator
768
       *              object.
769
       * @param __rhs Another % subtract_with_carry_engine random number
770
       *              generator object.
771
       *
772
       * @returns true if the infinite sequences of generated values
773
       *          would be equal, false otherwise.
774
      */
775
      friend bool
776
      operator==(const subtract_with_carry_engine& __lhs,
777
                 const subtract_with_carry_engine& __rhs)
778
      { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x)
779
                && __lhs._M_carry == __rhs._M_carry
780
                && __lhs._M_p == __rhs._M_p); }
781
 
782
      /**
783
       * @brief Inserts the current state of a % subtract_with_carry_engine
784
       *        random number generator engine @p __x into the output stream
785
       *        @p __os.
786
       *
787
       * @param __os An output stream.
788
       * @param __x  A % subtract_with_carry_engine random number generator
789
       *             engine.
790
       *
791
       * @returns The output stream with the state of @p __x inserted or in
792
       * an error state.
793
       */
794
      template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
795
               typename _CharT, typename _Traits>
796
        friend std::basic_ostream<_CharT, _Traits>&
797
        operator<<(std::basic_ostream<_CharT, _Traits>&,
798
                   const std::subtract_with_carry_engine<_UIntType1, __w1,
799
                   __s1, __r1>&);
800
 
801
      /**
802
       * @brief Extracts the current state of a % subtract_with_carry_engine
803
       *        random number generator engine @p __x from the input stream
804
       *        @p __is.
805
       *
806
       * @param __is An input stream.
807
       * @param __x  A % subtract_with_carry_engine random number generator
808
       *             engine.
809
       *
810
       * @returns The input stream with the state of @p __x extracted or in
811
       * an error state.
812
       */
813
      template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
814
               typename _CharT, typename _Traits>
815
        friend std::basic_istream<_CharT, _Traits>&
816
        operator>>(std::basic_istream<_CharT, _Traits>&,
817
                   std::subtract_with_carry_engine<_UIntType1, __w1,
818
                   __s1, __r1>&);
819
 
820
    private:
821
      _UIntType  _M_x[long_lag];
822
      _UIntType  _M_carry;
823
      size_t     _M_p;
824
    };
825
 
826
  /**
827
   * @brief Compares two % subtract_with_carry_engine random number
828
   *        generator objects of the same type for inequality.
829
   *
830
   * @param __lhs A % subtract_with_carry_engine random number generator
831
   *              object.
832
   * @param __rhs Another % subtract_with_carry_engine random number
833
   *              generator object.
834
   *
835
   * @returns true if the infinite sequences of generated values
836
   *          would be different, false otherwise.
837
   */
838
  template<typename _UIntType, size_t __w, size_t __s, size_t __r>
839
    inline bool
840
    operator!=(const std::subtract_with_carry_engine<_UIntType, __w,
841
               __s, __r>& __lhs,
842
               const std::subtract_with_carry_engine<_UIntType, __w,
843
               __s, __r>& __rhs)
844
    { return !(__lhs == __rhs); }
845
 
846
 
847
  /**
848
   * Produces random numbers from some base engine by discarding blocks of
849
   * data.
850
   *
851
   * 0 <= @p __r <= @p __p
852
   */
853
  template<typename _RandomNumberEngine, size_t __p, size_t __r>
854
    class discard_block_engine
855
    {
856
      static_assert(1 <= __r && __r <= __p,
857
                    "template argument substituting __r out of bounds");
858
 
859
    public:
860
      /** The type of the generated random value. */
861
      typedef typename _RandomNumberEngine::result_type result_type;
862
 
863
      // parameter values
864
      static constexpr size_t block_size = __p;
865
      static constexpr size_t used_block = __r;
866
 
867
      /**
868
       * @brief Constructs a default %discard_block_engine engine.
869
       *
870
       * The underlying engine is default constructed as well.
871
       */
872
      discard_block_engine()
873
      : _M_b(), _M_n(0) { }
874
 
875
      /**
876
       * @brief Copy constructs a %discard_block_engine engine.
877
       *
878
       * Copies an existing base class random number generator.
879
       * @param __rng An existing (base class) engine object.
880
       */
881
      explicit
882
      discard_block_engine(const _RandomNumberEngine& __rng)
883
      : _M_b(__rng), _M_n(0) { }
884
 
885
      /**
886
       * @brief Move constructs a %discard_block_engine engine.
887
       *
888
       * Copies an existing base class random number generator.
889
       * @param __rng An existing (base class) engine object.
890
       */
891
      explicit
892
      discard_block_engine(_RandomNumberEngine&& __rng)
893
      : _M_b(std::move(__rng)), _M_n(0) { }
894
 
895
      /**
896
       * @brief Seed constructs a %discard_block_engine engine.
897
       *
898
       * Constructs the underlying generator engine seeded with @p __s.
899
       * @param __s A seed value for the base class engine.
900
       */
901
      explicit
902
      discard_block_engine(result_type __s)
903
      : _M_b(__s), _M_n(0) { }
904
 
905
      /**
906
       * @brief Generator construct a %discard_block_engine engine.
907
       *
908
       * @param __q A seed sequence.
909
       */
910
      template<typename _Sseq, typename = typename
911
        std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
912
                       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
913
               ::type>
914
        explicit
915
        discard_block_engine(_Sseq& __q)
916
        : _M_b(__q), _M_n(0)
917
        { }
918
 
919
      /**
920
       * @brief Reseeds the %discard_block_engine object with the default
921
       *        seed for the underlying base class generator engine.
922
       */
923
      void
924
      seed()
925
      {
926
        _M_b.seed();
927
        _M_n = 0;
928
      }
929
 
930
      /**
931
       * @brief Reseeds the %discard_block_engine object with the default
932
       *        seed for the underlying base class generator engine.
933
       */
934
      void
935
      seed(result_type __s)
936
      {
937
        _M_b.seed(__s);
938
        _M_n = 0;
939
      }
940
 
941
      /**
942
       * @brief Reseeds the %discard_block_engine object with the given seed
943
       *        sequence.
944
       * @param __q A seed generator function.
945
       */
946
      template<typename _Sseq>
947
        void
948
        seed(_Sseq& __q)
949
        {
950
          _M_b.seed(__q);
951
          _M_n = 0;
952
        }
953
 
954
      /**
955
       * @brief Gets a const reference to the underlying generator engine
956
       *        object.
957
       */
958
      const _RandomNumberEngine&
959
      base() const noexcept
960
      { return _M_b; }
961
 
962
      /**
963
       * @brief Gets the minimum value in the generated random number range.
964
       */
965
      static constexpr result_type
966
      min()
967
      { return _RandomNumberEngine::min(); }
968
 
969
      /**
970
       * @brief Gets the maximum value in the generated random number range.
971
       */
972
      static constexpr result_type
973
      max()
974
      { return _RandomNumberEngine::max(); }
975
 
976
      /**
977
       * @brief Discard a sequence of random numbers.
978
       */
979
      void
980
      discard(unsigned long long __z)
981
      {
982
        for (; __z != 0ULL; --__z)
983
          (*this)();
984
      }
985
 
986
      /**
987
       * @brief Gets the next value in the generated random number sequence.
988
       */
989
      result_type
990
      operator()();
991
 
992
      /**
993
       * @brief Compares two %discard_block_engine random number generator
994
       *        objects of the same type for equality.
995
       *
996
       * @param __lhs A %discard_block_engine random number generator object.
997
       * @param __rhs Another %discard_block_engine random number generator
998
       *              object.
999
       *
1000
       * @returns true if the infinite sequences of generated values
1001
       *          would be equal, false otherwise.
1002
       */
1003
      friend bool
1004
      operator==(const discard_block_engine& __lhs,
1005
                 const discard_block_engine& __rhs)
1006
      { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; }
1007
 
1008
      /**
1009
       * @brief Inserts the current state of a %discard_block_engine random
1010
       *        number generator engine @p __x into the output stream
1011
       *        @p __os.
1012
       *
1013
       * @param __os An output stream.
1014
       * @param __x  A %discard_block_engine random number generator engine.
1015
       *
1016
       * @returns The output stream with the state of @p __x inserted or in
1017
       * an error state.
1018
       */
1019
      template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
1020
               typename _CharT, typename _Traits>
1021
        friend std::basic_ostream<_CharT, _Traits>&
1022
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1023
                   const std::discard_block_engine<_RandomNumberEngine1,
1024
                   __p1, __r1>& __x);
1025
 
1026
      /**
1027
       * @brief Extracts the current state of a % subtract_with_carry_engine
1028
       *        random number generator engine @p __x from the input stream
1029
       *        @p __is.
1030
       *
1031
       * @param __is An input stream.
1032
       * @param __x  A %discard_block_engine random number generator engine.
1033
       *
1034
       * @returns The input stream with the state of @p __x extracted or in
1035
       * an error state.
1036
       */
1037
      template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
1038
               typename _CharT, typename _Traits>
1039
        friend std::basic_istream<_CharT, _Traits>&
1040
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1041
                   std::discard_block_engine<_RandomNumberEngine1,
1042
                   __p1, __r1>& __x);
1043
 
1044
    private:
1045
      _RandomNumberEngine _M_b;
1046
      size_t _M_n;
1047
    };
1048
 
1049
  /**
1050
   * @brief Compares two %discard_block_engine random number generator
1051
   *        objects of the same type for inequality.
1052
   *
1053
   * @param __lhs A %discard_block_engine random number generator object.
1054
   * @param __rhs Another %discard_block_engine random number generator
1055
   *              object.
1056
   *
1057
   * @returns true if the infinite sequences of generated values
1058
   *          would be different, false otherwise.
1059
   */
1060
  template<typename _RandomNumberEngine, size_t __p, size_t __r>
1061
    inline bool
1062
    operator!=(const std::discard_block_engine<_RandomNumberEngine, __p,
1063
               __r>& __lhs,
1064
               const std::discard_block_engine<_RandomNumberEngine, __p,
1065
               __r>& __rhs)
1066
    { return !(__lhs == __rhs); }
1067
 
1068
 
1069
  /**
1070
   * Produces random numbers by combining random numbers from some base
1071
   * engine to produce random numbers with a specifies number of bits @p __w.
1072
   */
1073
  template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
1074
    class independent_bits_engine
1075
    {
1076
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
1077
                    "substituting _UIntType not an unsigned integral type");
1078
      static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
1079
                    "template argument substituting __w out of bounds");
1080
 
1081
    public:
1082
      /** The type of the generated random value. */
1083
      typedef _UIntType result_type;
1084
 
1085
      /**
1086
       * @brief Constructs a default %independent_bits_engine engine.
1087
       *
1088
       * The underlying engine is default constructed as well.
1089
       */
1090
      independent_bits_engine()
1091
      : _M_b() { }
1092
 
1093
      /**
1094
       * @brief Copy constructs a %independent_bits_engine engine.
1095
       *
1096
       * Copies an existing base class random number generator.
1097
       * @param __rng An existing (base class) engine object.
1098
       */
1099
      explicit
1100
      independent_bits_engine(const _RandomNumberEngine& __rng)
1101
      : _M_b(__rng) { }
1102
 
1103
      /**
1104
       * @brief Move constructs a %independent_bits_engine engine.
1105
       *
1106
       * Copies an existing base class random number generator.
1107
       * @param __rng An existing (base class) engine object.
1108
       */
1109
      explicit
1110
      independent_bits_engine(_RandomNumberEngine&& __rng)
1111
      : _M_b(std::move(__rng)) { }
1112
 
1113
      /**
1114
       * @brief Seed constructs a %independent_bits_engine engine.
1115
       *
1116
       * Constructs the underlying generator engine seeded with @p __s.
1117
       * @param __s A seed value for the base class engine.
1118
       */
1119
      explicit
1120
      independent_bits_engine(result_type __s)
1121
      : _M_b(__s) { }
1122
 
1123
      /**
1124
       * @brief Generator construct a %independent_bits_engine engine.
1125
       *
1126
       * @param __q A seed sequence.
1127
       */
1128
      template<typename _Sseq, typename = typename
1129
        std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
1130
                       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1131
               ::type>
1132
        explicit
1133
        independent_bits_engine(_Sseq& __q)
1134
        : _M_b(__q)
1135
        { }
1136
 
1137
      /**
1138
       * @brief Reseeds the %independent_bits_engine object with the default
1139
       *        seed for the underlying base class generator engine.
1140
       */
1141
      void
1142
      seed()
1143
      { _M_b.seed(); }
1144
 
1145
      /**
1146
       * @brief Reseeds the %independent_bits_engine object with the default
1147
       *        seed for the underlying base class generator engine.
1148
       */
1149
      void
1150
      seed(result_type __s)
1151
      { _M_b.seed(__s); }
1152
 
1153
      /**
1154
       * @brief Reseeds the %independent_bits_engine object with the given
1155
       *        seed sequence.
1156
       * @param __q A seed generator function.
1157
       */
1158
      template<typename _Sseq>
1159
        void
1160
        seed(_Sseq& __q)
1161
        { _M_b.seed(__q); }
1162
 
1163
      /**
1164
       * @brief Gets a const reference to the underlying generator engine
1165
       *        object.
1166
       */
1167
      const _RandomNumberEngine&
1168
      base() const noexcept
1169
      { return _M_b; }
1170
 
1171
      /**
1172
       * @brief Gets the minimum value in the generated random number range.
1173
       */
1174
      static constexpr result_type
1175
      min()
1176
      { return 0U; }
1177
 
1178
      /**
1179
       * @brief Gets the maximum value in the generated random number range.
1180
       */
1181
      static constexpr result_type
1182
      max()
1183
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }
1184
 
1185
      /**
1186
       * @brief Discard a sequence of random numbers.
1187
       */
1188
      void
1189
      discard(unsigned long long __z)
1190
      {
1191
        for (; __z != 0ULL; --__z)
1192
          (*this)();
1193
      }
1194
 
1195
      /**
1196
       * @brief Gets the next value in the generated random number sequence.
1197
       */
1198
      result_type
1199
      operator()();
1200
 
1201
      /**
1202
       * @brief Compares two %independent_bits_engine random number generator
1203
       * objects of the same type for equality.
1204
       *
1205
       * @param __lhs A %independent_bits_engine random number generator
1206
       *              object.
1207
       * @param __rhs Another %independent_bits_engine random number generator
1208
       *              object.
1209
       *
1210
       * @returns true if the infinite sequences of generated values
1211
       *          would be equal, false otherwise.
1212
       */
1213
      friend bool
1214
      operator==(const independent_bits_engine& __lhs,
1215
                 const independent_bits_engine& __rhs)
1216
      { return __lhs._M_b == __rhs._M_b; }
1217
 
1218
      /**
1219
       * @brief Extracts the current state of a % subtract_with_carry_engine
1220
       *        random number generator engine @p __x from the input stream
1221
       *        @p __is.
1222
       *
1223
       * @param __is An input stream.
1224
       * @param __x  A %independent_bits_engine random number generator
1225
       *             engine.
1226
       *
1227
       * @returns The input stream with the state of @p __x extracted or in
1228
       *          an error state.
1229
       */
1230
      template<typename _CharT, typename _Traits>
1231
        friend std::basic_istream<_CharT, _Traits>&
1232
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1233
                   std::independent_bits_engine<_RandomNumberEngine,
1234
                   __w, _UIntType>& __x)
1235
        {
1236
          __is >> __x._M_b;
1237
          return __is;
1238
        }
1239
 
1240
    private:
1241
      _RandomNumberEngine _M_b;
1242
    };
1243
 
1244
  /**
1245
   * @brief Compares two %independent_bits_engine random number generator
1246
   * objects of the same type for inequality.
1247
   *
1248
   * @param __lhs A %independent_bits_engine random number generator
1249
   *              object.
1250
   * @param __rhs Another %independent_bits_engine random number generator
1251
   *              object.
1252
   *
1253
   * @returns true if the infinite sequences of generated values
1254
   *          would be different, false otherwise.
1255
   */
1256
  template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
1257
    inline bool
1258
    operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w,
1259
               _UIntType>& __lhs,
1260
               const std::independent_bits_engine<_RandomNumberEngine, __w,
1261
               _UIntType>& __rhs)
1262
    { return !(__lhs == __rhs); }
1263
 
1264
  /**
1265
   * @brief Inserts the current state of a %independent_bits_engine random
1266
   *        number generator engine @p __x into the output stream @p __os.
1267
   *
1268
   * @param __os An output stream.
1269
   * @param __x  A %independent_bits_engine random number generator engine.
1270
   *
1271
   * @returns The output stream with the state of @p __x inserted or in
1272
   *          an error state.
1273
   */
1274
  template<typename _RandomNumberEngine, size_t __w, typename _UIntType,
1275
           typename _CharT, typename _Traits>
1276
    std::basic_ostream<_CharT, _Traits>&
1277
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1278
               const std::independent_bits_engine<_RandomNumberEngine,
1279
               __w, _UIntType>& __x)
1280
    {
1281
      __os << __x.base();
1282
      return __os;
1283
    }
1284
 
1285
 
1286
  /**
1287
   * @brief Produces random numbers by combining random numbers from some
1288
   * base engine to produce random numbers with a specifies number of bits
1289
   * @p __w.
1290
   */
1291
  template<typename _RandomNumberEngine, size_t __k>
1292
    class shuffle_order_engine
1293
    {
1294
      static_assert(1u <= __k, "template argument substituting "
1295
                    "__k out of bound");
1296
 
1297
    public:
1298
      /** The type of the generated random value. */
1299
      typedef typename _RandomNumberEngine::result_type result_type;
1300
 
1301
      static constexpr size_t table_size = __k;
1302
 
1303
      /**
1304
       * @brief Constructs a default %shuffle_order_engine engine.
1305
       *
1306
       * The underlying engine is default constructed as well.
1307
       */
1308
      shuffle_order_engine()
1309
      : _M_b()
1310
      { _M_initialize(); }
1311
 
1312
      /**
1313
       * @brief Copy constructs a %shuffle_order_engine engine.
1314
       *
1315
       * Copies an existing base class random number generator.
1316
       * @param __rng An existing (base class) engine object.
1317
       */
1318
      explicit
1319
      shuffle_order_engine(const _RandomNumberEngine& __rng)
1320
      : _M_b(__rng)
1321
      { _M_initialize(); }
1322
 
1323
      /**
1324
       * @brief Move constructs a %shuffle_order_engine engine.
1325
       *
1326
       * Copies an existing base class random number generator.
1327
       * @param __rng An existing (base class) engine object.
1328
       */
1329
      explicit
1330
      shuffle_order_engine(_RandomNumberEngine&& __rng)
1331
      : _M_b(std::move(__rng))
1332
      { _M_initialize(); }
1333
 
1334
      /**
1335
       * @brief Seed constructs a %shuffle_order_engine engine.
1336
       *
1337
       * Constructs the underlying generator engine seeded with @p __s.
1338
       * @param __s A seed value for the base class engine.
1339
       */
1340
      explicit
1341
      shuffle_order_engine(result_type __s)
1342
      : _M_b(__s)
1343
      { _M_initialize(); }
1344
 
1345
      /**
1346
       * @brief Generator construct a %shuffle_order_engine engine.
1347
       *
1348
       * @param __q A seed sequence.
1349
       */
1350
      template<typename _Sseq, typename = typename
1351
        std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
1352
                       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1353
               ::type>
1354
        explicit
1355
        shuffle_order_engine(_Sseq& __q)
1356
        : _M_b(__q)
1357
        { _M_initialize(); }
1358
 
1359
      /**
1360
       * @brief Reseeds the %shuffle_order_engine object with the default seed
1361
                for the underlying base class generator engine.
1362
       */
1363
      void
1364
      seed()
1365
      {
1366
        _M_b.seed();
1367
        _M_initialize();
1368
      }
1369
 
1370
      /**
1371
       * @brief Reseeds the %shuffle_order_engine object with the default seed
1372
       *        for the underlying base class generator engine.
1373
       */
1374
      void
1375
      seed(result_type __s)
1376
      {
1377
        _M_b.seed(__s);
1378
        _M_initialize();
1379
      }
1380
 
1381
      /**
1382
       * @brief Reseeds the %shuffle_order_engine object with the given seed
1383
       *        sequence.
1384
       * @param __q A seed generator function.
1385
       */
1386
      template<typename _Sseq>
1387
        void
1388
        seed(_Sseq& __q)
1389
        {
1390
          _M_b.seed(__q);
1391
          _M_initialize();
1392
        }
1393
 
1394
      /**
1395
       * Gets a const reference to the underlying generator engine object.
1396
       */
1397
      const _RandomNumberEngine&
1398
      base() const noexcept
1399
      { return _M_b; }
1400
 
1401
      /**
1402
       * Gets the minimum value in the generated random number range.
1403
       */
1404
      static constexpr result_type
1405
      min()
1406
      { return _RandomNumberEngine::min(); }
1407
 
1408
      /**
1409
       * Gets the maximum value in the generated random number range.
1410
       */
1411
      static constexpr result_type
1412
      max()
1413
      { return _RandomNumberEngine::max(); }
1414
 
1415
      /**
1416
       * Discard a sequence of random numbers.
1417
       */
1418
      void
1419
      discard(unsigned long long __z)
1420
      {
1421
        for (; __z != 0ULL; --__z)
1422
          (*this)();
1423
      }
1424
 
1425
      /**
1426
       * Gets the next value in the generated random number sequence.
1427
       */
1428
      result_type
1429
      operator()();
1430
 
1431
      /**
1432
       * Compares two %shuffle_order_engine random number generator objects
1433
       * of the same type for equality.
1434
       *
1435
       * @param __lhs A %shuffle_order_engine random number generator object.
1436
       * @param __rhs Another %shuffle_order_engine random number generator
1437
       *              object.
1438
       *
1439
       * @returns true if the infinite sequences of generated values
1440
       *          would be equal, false otherwise.
1441
      */
1442
      friend bool
1443
      operator==(const shuffle_order_engine& __lhs,
1444
                 const shuffle_order_engine& __rhs)
1445
      { return (__lhs._M_b == __rhs._M_b
1446
                && std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v)
1447
                && __lhs._M_y == __rhs._M_y); }
1448
 
1449
      /**
1450
       * @brief Inserts the current state of a %shuffle_order_engine random
1451
       *        number generator engine @p __x into the output stream
1452
        @p __os.
1453
       *
1454
       * @param __os An output stream.
1455
       * @param __x  A %shuffle_order_engine random number generator engine.
1456
       *
1457
       * @returns The output stream with the state of @p __x inserted or in
1458
       * an error state.
1459
       */
1460
      template<typename _RandomNumberEngine1, size_t __k1,
1461
               typename _CharT, typename _Traits>
1462
        friend std::basic_ostream<_CharT, _Traits>&
1463
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1464
                   const std::shuffle_order_engine<_RandomNumberEngine1,
1465
                   __k1>& __x);
1466
 
1467
      /**
1468
       * @brief Extracts the current state of a % subtract_with_carry_engine
1469
       *        random number generator engine @p __x from the input stream
1470
       *        @p __is.
1471
       *
1472
       * @param __is An input stream.
1473
       * @param __x  A %shuffle_order_engine random number generator engine.
1474
       *
1475
       * @returns The input stream with the state of @p __x extracted or in
1476
       * an error state.
1477
       */
1478
      template<typename _RandomNumberEngine1, size_t __k1,
1479
               typename _CharT, typename _Traits>
1480
        friend std::basic_istream<_CharT, _Traits>&
1481
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1482
                   std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x);
1483
 
1484
    private:
1485
      void _M_initialize()
1486
      {
1487
        for (size_t __i = 0; __i < __k; ++__i)
1488
          _M_v[__i] = _M_b();
1489
        _M_y = _M_b();
1490
      }
1491
 
1492
      _RandomNumberEngine _M_b;
1493
      result_type _M_v[__k];
1494
      result_type _M_y;
1495
    };
1496
 
1497
  /**
1498
   * Compares two %shuffle_order_engine random number generator objects
1499
   * of the same type for inequality.
1500
   *
1501
   * @param __lhs A %shuffle_order_engine random number generator object.
1502
   * @param __rhs Another %shuffle_order_engine random number generator
1503
   *              object.
1504
   *
1505
   * @returns true if the infinite sequences of generated values
1506
   *          would be different, false otherwise.
1507
   */
1508
  template<typename _RandomNumberEngine, size_t __k>
1509
    inline bool
1510
    operator!=(const std::shuffle_order_engine<_RandomNumberEngine,
1511
               __k>& __lhs,
1512
               const std::shuffle_order_engine<_RandomNumberEngine,
1513
               __k>& __rhs)
1514
    { return !(__lhs == __rhs); }
1515
 
1516
 
1517
  /**
1518
   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
1519
   */
1520
  typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>
1521
  minstd_rand0;
1522
 
1523
  /**
1524
   * An alternative LCR (Lehmer Generator function).
1525
   */
1526
  typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL>
1527
  minstd_rand;
1528
 
1529
  /**
1530
   * The classic Mersenne Twister.
1531
   *
1532
   * Reference:
1533
   * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
1534
   * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
1535
   * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
1536
   */
1537
  typedef mersenne_twister_engine<
1538
    uint_fast32_t,
1539
    32, 624, 397, 31,
1540
    0x9908b0dfUL, 11,
1541
    0xffffffffUL, 7,
1542
    0x9d2c5680UL, 15,
1543
    0xefc60000UL, 18, 1812433253UL> mt19937;
1544
 
1545
  /**
1546
   * An alternative Mersenne Twister.
1547
   */
1548
  typedef mersenne_twister_engine<
1549
    uint_fast64_t,
1550
    64, 312, 156, 31,
1551
    0xb5026f5aa96619e9ULL, 29,
1552
    0x5555555555555555ULL, 17,
1553
    0x71d67fffeda60000ULL, 37,
1554
    0xfff7eee000000000ULL, 43,
1555
    6364136223846793005ULL> mt19937_64;
1556
 
1557
  typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
1558
    ranlux24_base;
1559
 
1560
  typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
1561
    ranlux48_base;
1562
 
1563
  typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
1564
 
1565
  typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
1566
 
1567
  typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
1568
 
1569
  typedef minstd_rand0 default_random_engine;
1570
 
1571
  /**
1572
   * A standard interface to a platform-specific non-deterministic
1573
   * random number generator (if any are available).
1574
   */
1575
  class random_device
1576
  {
1577
  public:
1578
    /** The type of the generated random value. */
1579
    typedef unsigned int result_type;
1580
 
1581
    // constructors, destructors and member functions
1582
 
1583
#ifdef _GLIBCXX_USE_RANDOM_TR1
1584
 
1585
    explicit
1586
    random_device(const std::string& __token = "default")
1587
    {
1588
      _M_init(__token);
1589
    }
1590
 
1591
    ~random_device()
1592
    { _M_fini(); }
1593
 
1594
#else
1595
 
1596
    explicit
1597
    random_device(const std::string& __token = "mt19937")
1598
    { _M_init_pretr1(__token); }
1599
 
1600
  public:
1601
 
1602
#endif
1603
 
1604
    static constexpr result_type
1605
    min()
1606
    { return std::numeric_limits<result_type>::min(); }
1607
 
1608
    static constexpr result_type
1609
    max()
1610
    { return std::numeric_limits<result_type>::max(); }
1611
 
1612
    double
1613
    entropy() const noexcept
1614
    { return 0.0; }
1615
 
1616
    result_type
1617
    operator()()
1618
    {
1619
#ifdef _GLIBCXX_USE_RANDOM_TR1
1620
      return this->_M_getval();
1621
#else
1622
      return this->_M_getval_pretr1();
1623
#endif
1624
    }
1625
 
1626
    // No copy functions.
1627
    random_device(const random_device&) = delete;
1628
    void operator=(const random_device&) = delete;
1629
 
1630
  private:
1631
 
1632
    void _M_init(const std::string& __token);
1633
    void _M_init_pretr1(const std::string& __token);
1634
    void _M_fini();
1635
 
1636
    result_type _M_getval();
1637
    result_type _M_getval_pretr1();
1638
 
1639
    union
1640
    {
1641
    FILE*        _M_file;
1642
    mt19937      _M_mt;
1643
  };
1644
  };
1645
 
1646
  /* @} */ // group random_generators
1647
 
1648
  /**
1649
   * @addtogroup random_distributions Random Number Distributions
1650
   * @ingroup random
1651
   * @{
1652
   */
1653
 
1654
  /**
1655
   * @addtogroup random_distributions_uniform Uniform Distributions
1656
   * @ingroup random_distributions
1657
   * @{
1658
   */
1659
 
1660
  /**
1661
   * @brief Uniform discrete distribution for random numbers.
1662
   * A discrete random distribution on the range @f$[min, max]@f$ with equal
1663
   * probability throughout the range.
1664
   */
1665
  template<typename _IntType = int>
1666
    class uniform_int_distribution
1667
    {
1668
      static_assert(std::is_integral<_IntType>::value,
1669
                    "template argument not an integral type");
1670
 
1671
    public:
1672
      /** The type of the range of the distribution. */
1673
      typedef _IntType result_type;
1674
      /** Parameter type. */
1675
      struct param_type
1676
      {
1677
        typedef uniform_int_distribution<_IntType> distribution_type;
1678
 
1679
        explicit
1680
        param_type(_IntType __a = 0,
1681
                   _IntType __b = std::numeric_limits<_IntType>::max())
1682
        : _M_a(__a), _M_b(__b)
1683
        {
1684
          _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1685
        }
1686
 
1687
        result_type
1688
        a() const
1689
        { return _M_a; }
1690
 
1691
        result_type
1692
        b() const
1693
        { return _M_b; }
1694
 
1695
        friend bool
1696
        operator==(const param_type& __p1, const param_type& __p2)
1697
        { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1698
 
1699
      private:
1700
        _IntType _M_a;
1701
        _IntType _M_b;
1702
      };
1703
 
1704
    public:
1705
      /**
1706
       * @brief Constructs a uniform distribution object.
1707
       */
1708
      explicit
1709
      uniform_int_distribution(_IntType __a = 0,
1710
                           _IntType __b = std::numeric_limits<_IntType>::max())
1711
      : _M_param(__a, __b)
1712
      { }
1713
 
1714
      explicit
1715
      uniform_int_distribution(const param_type& __p)
1716
      : _M_param(__p)
1717
      { }
1718
 
1719
      /**
1720
       * @brief Resets the distribution state.
1721
       *
1722
       * Does nothing for the uniform integer distribution.
1723
       */
1724
      void
1725
      reset() { }
1726
 
1727
      result_type
1728
      a() const
1729
      { return _M_param.a(); }
1730
 
1731
      result_type
1732
      b() const
1733
      { return _M_param.b(); }
1734
 
1735
      /**
1736
       * @brief Returns the parameter set of the distribution.
1737
       */
1738
      param_type
1739
      param() const
1740
      { return _M_param; }
1741
 
1742
      /**
1743
       * @brief Sets the parameter set of the distribution.
1744
       * @param __param The new parameter set of the distribution.
1745
       */
1746
      void
1747
      param(const param_type& __param)
1748
      { _M_param = __param; }
1749
 
1750
      /**
1751
       * @brief Returns the inclusive lower bound of the distribution range.
1752
       */
1753
      result_type
1754
      min() const
1755
      { return this->a(); }
1756
 
1757
      /**
1758
       * @brief Returns the inclusive upper bound of the distribution range.
1759
       */
1760
      result_type
1761
      max() const
1762
      { return this->b(); }
1763
 
1764
      /**
1765
       * @brief Generating functions.
1766
       */
1767
      template<typename _UniformRandomNumberGenerator>
1768
        result_type
1769
        operator()(_UniformRandomNumberGenerator& __urng)
1770
        { return this->operator()(__urng, _M_param); }
1771
 
1772
      template<typename _UniformRandomNumberGenerator>
1773
        result_type
1774
        operator()(_UniformRandomNumberGenerator& __urng,
1775
                   const param_type& __p);
1776
 
1777
      template<typename _ForwardIterator,
1778
               typename _UniformRandomNumberGenerator>
1779
        void
1780
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1781
                   _UniformRandomNumberGenerator& __urng)
1782
        { this->__generate(__f, __t, __urng, _M_param); }
1783
 
1784
      template<typename _ForwardIterator,
1785
               typename _UniformRandomNumberGenerator>
1786
        void
1787
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1788
                   _UniformRandomNumberGenerator& __urng,
1789
                   const param_type& __p)
1790
        { this->__generate_impl(__f, __t, __urng, __p); }
1791
 
1792
      template<typename _UniformRandomNumberGenerator>
1793
        void
1794
        __generate(result_type* __f, result_type* __t,
1795
                   _UniformRandomNumberGenerator& __urng,
1796
                   const param_type& __p)
1797
        { this->__generate_impl(__f, __t, __urng, __p); }
1798
 
1799
      /**
1800
       * @brief Return true if two uniform integer distributions have
1801
       *        the same parameters.
1802
       */
1803
      friend bool
1804
      operator==(const uniform_int_distribution& __d1,
1805
                 const uniform_int_distribution& __d2)
1806
      { return __d1._M_param == __d2._M_param; }
1807
 
1808
    private:
1809
      template<typename _ForwardIterator,
1810
               typename _UniformRandomNumberGenerator>
1811
        void
1812
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1813
                        _UniformRandomNumberGenerator& __urng,
1814
                        const param_type& __p);
1815
 
1816
      param_type _M_param;
1817
    };
1818
 
1819
  /**
1820
   * @brief Return true if two uniform integer distributions have
1821
   *        different parameters.
1822
   */
1823
  template<typename _IntType>
1824
    inline bool
1825
    operator!=(const std::uniform_int_distribution<_IntType>& __d1,
1826
               const std::uniform_int_distribution<_IntType>& __d2)
1827
    { return !(__d1 == __d2); }
1828
 
1829
  /**
1830
   * @brief Inserts a %uniform_int_distribution random number
1831
   *        distribution @p __x into the output stream @p os.
1832
   *
1833
   * @param __os An output stream.
1834
   * @param __x  A %uniform_int_distribution random number distribution.
1835
   *
1836
   * @returns The output stream with the state of @p __x inserted or in
1837
   * an error state.
1838
   */
1839
  template<typename _IntType, typename _CharT, typename _Traits>
1840
    std::basic_ostream<_CharT, _Traits>&
1841
    operator<<(std::basic_ostream<_CharT, _Traits>&,
1842
               const std::uniform_int_distribution<_IntType>&);
1843
 
1844
  /**
1845
   * @brief Extracts a %uniform_int_distribution random number distribution
1846
   * @p __x from the input stream @p __is.
1847
   *
1848
   * @param __is An input stream.
1849
   * @param __x  A %uniform_int_distribution random number generator engine.
1850
   *
1851
   * @returns The input stream with @p __x extracted or in an error state.
1852
   */
1853
  template<typename _IntType, typename _CharT, typename _Traits>
1854
    std::basic_istream<_CharT, _Traits>&
1855
    operator>>(std::basic_istream<_CharT, _Traits>&,
1856
               std::uniform_int_distribution<_IntType>&);
1857
 
1858
 
1859
  /**
1860
   * @brief Uniform continuous distribution for random numbers.
1861
   *
1862
   * A continuous random distribution on the range [min, max) with equal
1863
   * probability throughout the range.  The URNG should be real-valued and
1864
   * deliver number in the range [0, 1).
1865
   */
1866
  template<typename _RealType = double>
1867
    class uniform_real_distribution
1868
    {
1869
      static_assert(std::is_floating_point<_RealType>::value,
1870
                    "template argument not a floating point type");
1871
 
1872
    public:
1873
      /** The type of the range of the distribution. */
1874
      typedef _RealType result_type;
1875
      /** Parameter type. */
1876
      struct param_type
1877
      {
1878
        typedef uniform_real_distribution<_RealType> distribution_type;
1879
 
1880
        explicit
1881
        param_type(_RealType __a = _RealType(0),
1882
                   _RealType __b = _RealType(1))
1883
        : _M_a(__a), _M_b(__b)
1884
        {
1885
          _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1886
        }
1887
 
1888
        result_type
1889
        a() const
1890
        { return _M_a; }
1891
 
1892
        result_type
1893
        b() const
1894
        { return _M_b; }
1895
 
1896
        friend bool
1897
        operator==(const param_type& __p1, const param_type& __p2)
1898
        { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1899
 
1900
      private:
1901
        _RealType _M_a;
1902
        _RealType _M_b;
1903
      };
1904
 
1905
    public:
1906
      /**
1907
       * @brief Constructs a uniform_real_distribution object.
1908
       *
1909
       * @param __a [IN]  The lower bound of the distribution.
1910
       * @param __b [IN]  The upper bound of the distribution.
1911
       */
1912
      explicit
1913
      uniform_real_distribution(_RealType __a = _RealType(0),
1914
                                _RealType __b = _RealType(1))
1915
      : _M_param(__a, __b)
1916
      { }
1917
 
1918
      explicit
1919
      uniform_real_distribution(const param_type& __p)
1920
      : _M_param(__p)
1921
      { }
1922
 
1923
      /**
1924
       * @brief Resets the distribution state.
1925
       *
1926
       * Does nothing for the uniform real distribution.
1927
       */
1928
      void
1929
      reset() { }
1930
 
1931
      result_type
1932
      a() const
1933
      { return _M_param.a(); }
1934
 
1935
      result_type
1936
      b() const
1937
      { return _M_param.b(); }
1938
 
1939
      /**
1940
       * @brief Returns the parameter set of the distribution.
1941
       */
1942
      param_type
1943
      param() const
1944
      { return _M_param; }
1945
 
1946
      /**
1947
       * @brief Sets the parameter set of the distribution.
1948
       * @param __param The new parameter set of the distribution.
1949
       */
1950
      void
1951
      param(const param_type& __param)
1952
      { _M_param = __param; }
1953
 
1954
      /**
1955
       * @brief Returns the inclusive lower bound of the distribution range.
1956
       */
1957
      result_type
1958
      min() const
1959
      { return this->a(); }
1960
 
1961
      /**
1962
       * @brief Returns the inclusive upper bound of the distribution range.
1963
       */
1964
      result_type
1965
      max() const
1966
      { return this->b(); }
1967
 
1968
      /**
1969
       * @brief Generating functions.
1970
       */
1971
      template<typename _UniformRandomNumberGenerator>
1972
        result_type
1973
        operator()(_UniformRandomNumberGenerator& __urng)
1974
        { return this->operator()(__urng, _M_param); }
1975
 
1976
      template<typename _UniformRandomNumberGenerator>
1977
        result_type
1978
        operator()(_UniformRandomNumberGenerator& __urng,
1979
                   const param_type& __p)
1980
        {
1981
          __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1982
            __aurng(__urng);
1983
          return (__aurng() * (__p.b() - __p.a())) + __p.a();
1984
        }
1985
 
1986
      template<typename _ForwardIterator,
1987
               typename _UniformRandomNumberGenerator>
1988
        void
1989
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1990
                   _UniformRandomNumberGenerator& __urng)
1991
        { this->__generate(__f, __t, __urng, _M_param); }
1992
 
1993
      template<typename _ForwardIterator,
1994
               typename _UniformRandomNumberGenerator>
1995
        void
1996
        __generate(_ForwardIterator __f, _ForwardIterator __t,
1997
                   _UniformRandomNumberGenerator& __urng,
1998
                   const param_type& __p)
1999
        { this->__generate_impl(__f, __t, __urng, __p); }
2000
 
2001
      template<typename _UniformRandomNumberGenerator>
2002
        void
2003
        __generate(result_type* __f, result_type* __t,
2004
                   _UniformRandomNumberGenerator& __urng,
2005
                   const param_type& __p)
2006
        { this->__generate_impl(__f, __t, __urng, __p); }
2007
 
2008
      /**
2009
       * @brief Return true if two uniform real distributions have
2010
       *        the same parameters.
2011
       */
2012
      friend bool
2013
      operator==(const uniform_real_distribution& __d1,
2014
                 const uniform_real_distribution& __d2)
2015
      { return __d1._M_param == __d2._M_param; }
2016
 
2017
    private:
2018
      template<typename _ForwardIterator,
2019
               typename _UniformRandomNumberGenerator>
2020
        void
2021
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2022
                        _UniformRandomNumberGenerator& __urng,
2023
                        const param_type& __p);
2024
 
2025
      param_type _M_param;
2026
    };
2027
 
2028
  /**
2029
   * @brief Return true if two uniform real distributions have
2030
   *        different parameters.
2031
   */
2032
  template<typename _IntType>
2033
    inline bool
2034
    operator!=(const std::uniform_real_distribution<_IntType>& __d1,
2035
               const std::uniform_real_distribution<_IntType>& __d2)
2036
    { return !(__d1 == __d2); }
2037
 
2038
  /**
2039
   * @brief Inserts a %uniform_real_distribution random number
2040
   *        distribution @p __x into the output stream @p __os.
2041
   *
2042
   * @param __os An output stream.
2043
   * @param __x  A %uniform_real_distribution random number distribution.
2044
   *
2045
   * @returns The output stream with the state of @p __x inserted or in
2046
   *          an error state.
2047
   */
2048
  template<typename _RealType, typename _CharT, typename _Traits>
2049
    std::basic_ostream<_CharT, _Traits>&
2050
    operator<<(std::basic_ostream<_CharT, _Traits>&,
2051
               const std::uniform_real_distribution<_RealType>&);
2052
 
2053
  /**
2054
   * @brief Extracts a %uniform_real_distribution random number distribution
2055
   * @p __x from the input stream @p __is.
2056
   *
2057
   * @param __is An input stream.
2058
   * @param __x  A %uniform_real_distribution random number generator engine.
2059
   *
2060
   * @returns The input stream with @p __x extracted or in an error state.
2061
   */
2062
  template<typename _RealType, typename _CharT, typename _Traits>
2063
    std::basic_istream<_CharT, _Traits>&
2064
    operator>>(std::basic_istream<_CharT, _Traits>&,
2065
               std::uniform_real_distribution<_RealType>&);
2066
 
2067
  /* @} */ // group random_distributions_uniform
2068
 
2069
  /**
2070
   * @addtogroup random_distributions_normal Normal Distributions
2071
   * @ingroup random_distributions
2072
   * @{
2073
   */
2074
 
2075
  /**
2076
   * @brief A normal continuous distribution for random numbers.
2077
   *
2078
   * The formula for the normal probability density function is
2079
   * @f[
2080
   *     p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
2081
   *            e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} }
2082
   * @f]
2083
   */
2084
  template<typename _RealType = double>
2085
    class normal_distribution
2086
    {
2087
      static_assert(std::is_floating_point<_RealType>::value,
2088
                    "template argument not a floating point type");
2089
 
2090
    public:
2091
      /** The type of the range of the distribution. */
2092
      typedef _RealType result_type;
2093
      /** Parameter type. */
2094
      struct param_type
2095
      {
2096
        typedef normal_distribution<_RealType> distribution_type;
2097
 
2098
        explicit
2099
        param_type(_RealType __mean = _RealType(0),
2100
                   _RealType __stddev = _RealType(1))
2101
        : _M_mean(__mean), _M_stddev(__stddev)
2102
        {
2103
          _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
2104
        }
2105
 
2106
        _RealType
2107
        mean() const
2108
        { return _M_mean; }
2109
 
2110
        _RealType
2111
        stddev() const
2112
        { return _M_stddev; }
2113
 
2114
        friend bool
2115
        operator==(const param_type& __p1, const param_type& __p2)
2116
        { return (__p1._M_mean == __p2._M_mean
2117
                  && __p1._M_stddev == __p2._M_stddev); }
2118
 
2119
      private:
2120
        _RealType _M_mean;
2121
        _RealType _M_stddev;
2122
      };
2123
 
2124
    public:
2125
      /**
2126
       * Constructs a normal distribution with parameters @f$mean@f$ and
2127
       * standard deviation.
2128
       */
2129
      explicit
2130
      normal_distribution(result_type __mean = result_type(0),
2131
                          result_type __stddev = result_type(1))
2132
      : _M_param(__mean, __stddev), _M_saved_available(false)
2133
      { }
2134
 
2135
      explicit
2136
      normal_distribution(const param_type& __p)
2137
      : _M_param(__p), _M_saved_available(false)
2138
      { }
2139
 
2140
      /**
2141
       * @brief Resets the distribution state.
2142
       */
2143
      void
2144
      reset()
2145
      { _M_saved_available = false; }
2146
 
2147
      /**
2148
       * @brief Returns the mean of the distribution.
2149
       */
2150
      _RealType
2151
      mean() const
2152
      { return _M_param.mean(); }
2153
 
2154
      /**
2155
       * @brief Returns the standard deviation of the distribution.
2156
       */
2157
      _RealType
2158
      stddev() const
2159
      { return _M_param.stddev(); }
2160
 
2161
      /**
2162
       * @brief Returns the parameter set of the distribution.
2163
       */
2164
      param_type
2165
      param() const
2166
      { return _M_param; }
2167
 
2168
      /**
2169
       * @brief Sets the parameter set of the distribution.
2170
       * @param __param The new parameter set of the distribution.
2171
       */
2172
      void
2173
      param(const param_type& __param)
2174
      { _M_param = __param; }
2175
 
2176
      /**
2177
       * @brief Returns the greatest lower bound value of the distribution.
2178
       */
2179
      result_type
2180
      min() const
2181
      { return std::numeric_limits<result_type>::min(); }
2182
 
2183
      /**
2184
       * @brief Returns the least upper bound value of the distribution.
2185
       */
2186
      result_type
2187
      max() const
2188
      { return std::numeric_limits<result_type>::max(); }
2189
 
2190
      /**
2191
       * @brief Generating functions.
2192
       */
2193
      template<typename _UniformRandomNumberGenerator>
2194
        result_type
2195
        operator()(_UniformRandomNumberGenerator& __urng)
2196
        { return this->operator()(__urng, _M_param); }
2197
 
2198
      template<typename _UniformRandomNumberGenerator>
2199
        result_type
2200
        operator()(_UniformRandomNumberGenerator& __urng,
2201
                   const param_type& __p);
2202
 
2203
      template<typename _ForwardIterator,
2204
               typename _UniformRandomNumberGenerator>
2205
        void
2206
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2207
                   _UniformRandomNumberGenerator& __urng)
2208
        { this->__generate(__f, __t, __urng, _M_param); }
2209
 
2210
      template<typename _ForwardIterator,
2211
               typename _UniformRandomNumberGenerator>
2212
        void
2213
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2214
                   _UniformRandomNumberGenerator& __urng,
2215
                   const param_type& __p)
2216
        { this->__generate_impl(__f, __t, __urng, __p); }
2217
 
2218
      template<typename _UniformRandomNumberGenerator>
2219
        void
2220
        __generate(result_type* __f, result_type* __t,
2221
                   _UniformRandomNumberGenerator& __urng,
2222
                   const param_type& __p)
2223
        { this->__generate_impl(__f, __t, __urng, __p); }
2224
 
2225
      /**
2226
       * @brief Return true if two normal distributions have
2227
       *        the same parameters and the sequences that would
2228
       *        be generated are equal.
2229
       */
2230
      template<typename _RealType1>
2231
        friend bool
2232
        operator==(const std::normal_distribution<_RealType1>& __d1,
2233
                   const std::normal_distribution<_RealType1>& __d2);
2234
 
2235
      /**
2236
       * @brief Inserts a %normal_distribution random number distribution
2237
       * @p __x into the output stream @p __os.
2238
       *
2239
       * @param __os An output stream.
2240
       * @param __x  A %normal_distribution random number distribution.
2241
       *
2242
       * @returns The output stream with the state of @p __x inserted or in
2243
       * an error state.
2244
       */
2245
      template<typename _RealType1, typename _CharT, typename _Traits>
2246
        friend std::basic_ostream<_CharT, _Traits>&
2247
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2248
                   const std::normal_distribution<_RealType1>& __x);
2249
 
2250
      /**
2251
       * @brief Extracts a %normal_distribution random number distribution
2252
       * @p __x from the input stream @p __is.
2253
       *
2254
       * @param __is An input stream.
2255
       * @param __x  A %normal_distribution random number generator engine.
2256
       *
2257
       * @returns The input stream with @p __x extracted or in an error
2258
       *          state.
2259
       */
2260
      template<typename _RealType1, typename _CharT, typename _Traits>
2261
        friend std::basic_istream<_CharT, _Traits>&
2262
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2263
                   std::normal_distribution<_RealType1>& __x);
2264
 
2265
    private:
2266
      template<typename _ForwardIterator,
2267
               typename _UniformRandomNumberGenerator>
2268
        void
2269
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2270
                        _UniformRandomNumberGenerator& __urng,
2271
                        const param_type& __p);
2272
 
2273
      param_type  _M_param;
2274
      result_type _M_saved;
2275
      bool        _M_saved_available;
2276
    };
2277
 
2278
  /**
2279
   * @brief Return true if two normal distributions are different.
2280
   */
2281
  template<typename _RealType>
2282
    inline bool
2283
    operator!=(const std::normal_distribution<_RealType>& __d1,
2284
               const std::normal_distribution<_RealType>& __d2)
2285
    { return !(__d1 == __d2); }
2286
 
2287
 
2288
  /**
2289
   * @brief A lognormal_distribution random number distribution.
2290
   *
2291
   * The formula for the normal probability mass function is
2292
   * @f[
2293
   *     p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
2294
   *                \exp{-\frac{(\ln{x} - m)^2}{2s^2}}
2295
   * @f]
2296
   */
2297
  template<typename _RealType = double>
2298
    class lognormal_distribution
2299
    {
2300
      static_assert(std::is_floating_point<_RealType>::value,
2301
                    "template argument not a floating point type");
2302
 
2303
    public:
2304
      /** The type of the range of the distribution. */
2305
      typedef _RealType result_type;
2306
      /** Parameter type. */
2307
      struct param_type
2308
      {
2309
        typedef lognormal_distribution<_RealType> distribution_type;
2310
 
2311
        explicit
2312
        param_type(_RealType __m = _RealType(0),
2313
                   _RealType __s = _RealType(1))
2314
        : _M_m(__m), _M_s(__s)
2315
        { }
2316
 
2317
        _RealType
2318
        m() const
2319
        { return _M_m; }
2320
 
2321
        _RealType
2322
        s() const
2323
        { return _M_s; }
2324
 
2325
        friend bool
2326
        operator==(const param_type& __p1, const param_type& __p2)
2327
        { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
2328
 
2329
      private:
2330
        _RealType _M_m;
2331
        _RealType _M_s;
2332
      };
2333
 
2334
      explicit
2335
      lognormal_distribution(_RealType __m = _RealType(0),
2336
                             _RealType __s = _RealType(1))
2337
      : _M_param(__m, __s), _M_nd()
2338
      { }
2339
 
2340
      explicit
2341
      lognormal_distribution(const param_type& __p)
2342
      : _M_param(__p), _M_nd()
2343
      { }
2344
 
2345
      /**
2346
       * Resets the distribution state.
2347
       */
2348
      void
2349
      reset()
2350
      { _M_nd.reset(); }
2351
 
2352
      /**
2353
       *
2354
       */
2355
      _RealType
2356
      m() const
2357
      { return _M_param.m(); }
2358
 
2359
      _RealType
2360
      s() const
2361
      { return _M_param.s(); }
2362
 
2363
      /**
2364
       * @brief Returns the parameter set of the distribution.
2365
       */
2366
      param_type
2367
      param() const
2368
      { return _M_param; }
2369
 
2370
      /**
2371
       * @brief Sets the parameter set of the distribution.
2372
       * @param __param The new parameter set of the distribution.
2373
       */
2374
      void
2375
      param(const param_type& __param)
2376
      { _M_param = __param; }
2377
 
2378
      /**
2379
       * @brief Returns the greatest lower bound value of the distribution.
2380
       */
2381
      result_type
2382
      min() const
2383
      { return result_type(0); }
2384
 
2385
      /**
2386
       * @brief Returns the least upper bound value of the distribution.
2387
       */
2388
      result_type
2389
      max() const
2390
      { return std::numeric_limits<result_type>::max(); }
2391
 
2392
      /**
2393
       * @brief Generating functions.
2394
       */
2395
      template<typename _UniformRandomNumberGenerator>
2396
        result_type
2397
        operator()(_UniformRandomNumberGenerator& __urng)
2398
        { return this->operator()(__urng, _M_param); }
2399
 
2400
      template<typename _UniformRandomNumberGenerator>
2401
        result_type
2402
        operator()(_UniformRandomNumberGenerator& __urng,
2403
                   const param_type& __p)
2404
        { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
2405
 
2406
      template<typename _ForwardIterator,
2407
               typename _UniformRandomNumberGenerator>
2408
        void
2409
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2410
                   _UniformRandomNumberGenerator& __urng)
2411
        { this->__generate(__f, __t, __urng, _M_param); }
2412
 
2413
      template<typename _ForwardIterator,
2414
               typename _UniformRandomNumberGenerator>
2415
        void
2416
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2417
                   _UniformRandomNumberGenerator& __urng,
2418
                   const param_type& __p)
2419
        { this->__generate_impl(__f, __t, __urng, __p); }
2420
 
2421
      template<typename _UniformRandomNumberGenerator>
2422
        void
2423
        __generate(result_type* __f, result_type* __t,
2424
                   _UniformRandomNumberGenerator& __urng,
2425
                   const param_type& __p)
2426
        { this->__generate_impl(__f, __t, __urng, __p); }
2427
 
2428
      /**
2429
       * @brief Return true if two lognormal distributions have
2430
       *        the same parameters and the sequences that would
2431
       *        be generated are equal.
2432
       */
2433
      friend bool
2434
      operator==(const lognormal_distribution& __d1,
2435
                 const lognormal_distribution& __d2)
2436
      { return (__d1._M_param == __d2._M_param
2437
                && __d1._M_nd == __d2._M_nd); }
2438
 
2439
      /**
2440
       * @brief Inserts a %lognormal_distribution random number distribution
2441
       * @p __x into the output stream @p __os.
2442
       *
2443
       * @param __os An output stream.
2444
       * @param __x  A %lognormal_distribution random number distribution.
2445
       *
2446
       * @returns The output stream with the state of @p __x inserted or in
2447
       * an error state.
2448
       */
2449
      template<typename _RealType1, typename _CharT, typename _Traits>
2450
        friend std::basic_ostream<_CharT, _Traits>&
2451
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2452
                   const std::lognormal_distribution<_RealType1>& __x);
2453
 
2454
      /**
2455
       * @brief Extracts a %lognormal_distribution random number distribution
2456
       * @p __x from the input stream @p __is.
2457
       *
2458
       * @param __is An input stream.
2459
       * @param __x A %lognormal_distribution random number
2460
       *            generator engine.
2461
       *
2462
       * @returns The input stream with @p __x extracted or in an error state.
2463
       */
2464
      template<typename _RealType1, typename _CharT, typename _Traits>
2465
        friend std::basic_istream<_CharT, _Traits>&
2466
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2467
                   std::lognormal_distribution<_RealType1>& __x);
2468
 
2469
    private:
2470
      template<typename _ForwardIterator,
2471
               typename _UniformRandomNumberGenerator>
2472
        void
2473
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2474
                        _UniformRandomNumberGenerator& __urng,
2475
                        const param_type& __p);
2476
 
2477
      param_type _M_param;
2478
 
2479
      std::normal_distribution<result_type> _M_nd;
2480
    };
2481
 
2482
  /**
2483
   * @brief Return true if two lognormal distributions are different.
2484
   */
2485
  template<typename _RealType>
2486
    inline bool
2487
    operator!=(const std::lognormal_distribution<_RealType>& __d1,
2488
               const std::lognormal_distribution<_RealType>& __d2)
2489
    { return !(__d1 == __d2); }
2490
 
2491
 
2492
  /**
2493
   * @brief A gamma continuous distribution for random numbers.
2494
   *
2495
   * The formula for the gamma probability density function is:
2496
   * @f[
2497
   *     p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
2498
   *                         (x/\beta)^{\alpha - 1} e^{-x/\beta}
2499
   * @f]
2500
   */
2501
  template<typename _RealType = double>
2502
    class gamma_distribution
2503
    {
2504
      static_assert(std::is_floating_point<_RealType>::value,
2505
                    "template argument not a floating point type");
2506
 
2507
    public:
2508
      /** The type of the range of the distribution. */
2509
      typedef _RealType result_type;
2510
      /** Parameter type. */
2511
      struct param_type
2512
      {
2513
        typedef gamma_distribution<_RealType> distribution_type;
2514
        friend class gamma_distribution<_RealType>;
2515
 
2516
        explicit
2517
        param_type(_RealType __alpha_val = _RealType(1),
2518
                   _RealType __beta_val = _RealType(1))
2519
        : _M_alpha(__alpha_val), _M_beta(__beta_val)
2520
        {
2521
          _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
2522
          _M_initialize();
2523
        }
2524
 
2525
        _RealType
2526
        alpha() const
2527
        { return _M_alpha; }
2528
 
2529
        _RealType
2530
        beta() const
2531
        { return _M_beta; }
2532
 
2533
        friend bool
2534
        operator==(const param_type& __p1, const param_type& __p2)
2535
        { return (__p1._M_alpha == __p2._M_alpha
2536
                  && __p1._M_beta == __p2._M_beta); }
2537
 
2538
      private:
2539
        void
2540
        _M_initialize();
2541
 
2542
        _RealType _M_alpha;
2543
        _RealType _M_beta;
2544
 
2545
        _RealType _M_malpha, _M_a2;
2546
      };
2547
 
2548
    public:
2549
      /**
2550
       * @brief Constructs a gamma distribution with parameters
2551
       * @f$\alpha@f$ and @f$\beta@f$.
2552
       */
2553
      explicit
2554
      gamma_distribution(_RealType __alpha_val = _RealType(1),
2555
                         _RealType __beta_val = _RealType(1))
2556
      : _M_param(__alpha_val, __beta_val), _M_nd()
2557
      { }
2558
 
2559
      explicit
2560
      gamma_distribution(const param_type& __p)
2561
      : _M_param(__p), _M_nd()
2562
      { }
2563
 
2564
      /**
2565
       * @brief Resets the distribution state.
2566
       */
2567
      void
2568
      reset()
2569
      { _M_nd.reset(); }
2570
 
2571
      /**
2572
       * @brief Returns the @f$\alpha@f$ of the distribution.
2573
       */
2574
      _RealType
2575
      alpha() const
2576
      { return _M_param.alpha(); }
2577
 
2578
      /**
2579
       * @brief Returns the @f$\beta@f$ of the distribution.
2580
       */
2581
      _RealType
2582
      beta() const
2583
      { return _M_param.beta(); }
2584
 
2585
      /**
2586
       * @brief Returns the parameter set of the distribution.
2587
       */
2588
      param_type
2589
      param() const
2590
      { return _M_param; }
2591
 
2592
      /**
2593
       * @brief Sets the parameter set of the distribution.
2594
       * @param __param The new parameter set of the distribution.
2595
       */
2596
      void
2597
      param(const param_type& __param)
2598
      { _M_param = __param; }
2599
 
2600
      /**
2601
       * @brief Returns the greatest lower bound value of the distribution.
2602
       */
2603
      result_type
2604
      min() const
2605
      { return result_type(0); }
2606
 
2607
      /**
2608
       * @brief Returns the least upper bound value of the distribution.
2609
       */
2610
      result_type
2611
      max() const
2612
      { return std::numeric_limits<result_type>::max(); }
2613
 
2614
      /**
2615
       * @brief Generating functions.
2616
       */
2617
      template<typename _UniformRandomNumberGenerator>
2618
        result_type
2619
        operator()(_UniformRandomNumberGenerator& __urng)
2620
        { return this->operator()(__urng, _M_param); }
2621
 
2622
      template<typename _UniformRandomNumberGenerator>
2623
        result_type
2624
        operator()(_UniformRandomNumberGenerator& __urng,
2625
                   const param_type& __p);
2626
 
2627
      template<typename _ForwardIterator,
2628
               typename _UniformRandomNumberGenerator>
2629
        void
2630
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2631
                   _UniformRandomNumberGenerator& __urng)
2632
        { this->__generate(__f, __t, __urng, _M_param); }
2633
 
2634
      template<typename _ForwardIterator,
2635
               typename _UniformRandomNumberGenerator>
2636
        void
2637
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2638
                   _UniformRandomNumberGenerator& __urng,
2639
                   const param_type& __p)
2640
        { this->__generate_impl(__f, __t, __urng, __p); }
2641
 
2642
      template<typename _UniformRandomNumberGenerator>
2643
        void
2644
        __generate(result_type* __f, result_type* __t,
2645
                   _UniformRandomNumberGenerator& __urng,
2646
                   const param_type& __p)
2647
        { this->__generate_impl(__f, __t, __urng, __p); }
2648
 
2649
      /**
2650
       * @brief Return true if two gamma distributions have the same
2651
       *        parameters and the sequences that would be generated
2652
       *        are equal.
2653
       */
2654
      friend bool
2655
      operator==(const gamma_distribution& __d1,
2656
                 const gamma_distribution& __d2)
2657
      { return (__d1._M_param == __d2._M_param
2658
                && __d1._M_nd == __d2._M_nd); }
2659
 
2660
      /**
2661
       * @brief Inserts a %gamma_distribution random number distribution
2662
       * @p __x into the output stream @p __os.
2663
       *
2664
       * @param __os An output stream.
2665
       * @param __x  A %gamma_distribution random number distribution.
2666
       *
2667
       * @returns The output stream with the state of @p __x inserted or in
2668
       * an error state.
2669
       */
2670
      template<typename _RealType1, typename _CharT, typename _Traits>
2671
        friend std::basic_ostream<_CharT, _Traits>&
2672
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2673
                   const std::gamma_distribution<_RealType1>& __x);
2674
 
2675
      /**
2676
       * @brief Extracts a %gamma_distribution random number distribution
2677
       * @p __x from the input stream @p __is.
2678
       *
2679
       * @param __is An input stream.
2680
       * @param __x  A %gamma_distribution random number generator engine.
2681
       *
2682
       * @returns The input stream with @p __x extracted or in an error state.
2683
       */
2684
      template<typename _RealType1, typename _CharT, typename _Traits>
2685
        friend std::basic_istream<_CharT, _Traits>&
2686
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2687
                   std::gamma_distribution<_RealType1>& __x);
2688
 
2689
    private:
2690
      template<typename _ForwardIterator,
2691
               typename _UniformRandomNumberGenerator>
2692
        void
2693
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2694
                        _UniformRandomNumberGenerator& __urng,
2695
                        const param_type& __p);
2696
 
2697
      param_type _M_param;
2698
 
2699
      std::normal_distribution<result_type> _M_nd;
2700
    };
2701
 
2702
  /**
2703
   * @brief Return true if two gamma distributions are different.
2704
   */
2705
   template<typename _RealType>
2706
     inline bool
2707
     operator!=(const std::gamma_distribution<_RealType>& __d1,
2708
                const std::gamma_distribution<_RealType>& __d2)
2709
    { return !(__d1 == __d2); }
2710
 
2711
 
2712
  /**
2713
   * @brief A chi_squared_distribution random number distribution.
2714
   *
2715
   * The formula for the normal probability mass function is
2716
   * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
2717
   */
2718
  template<typename _RealType = double>
2719
    class chi_squared_distribution
2720
    {
2721
      static_assert(std::is_floating_point<_RealType>::value,
2722
                    "template argument not a floating point type");
2723
 
2724
    public:
2725
      /** The type of the range of the distribution. */
2726
      typedef _RealType result_type;
2727
      /** Parameter type. */
2728
      struct param_type
2729
      {
2730
        typedef chi_squared_distribution<_RealType> distribution_type;
2731
 
2732
        explicit
2733
        param_type(_RealType __n = _RealType(1))
2734
        : _M_n(__n)
2735
        { }
2736
 
2737
        _RealType
2738
        n() const
2739
        { return _M_n; }
2740
 
2741
        friend bool
2742
        operator==(const param_type& __p1, const param_type& __p2)
2743
        { return __p1._M_n == __p2._M_n; }
2744
 
2745
      private:
2746
        _RealType _M_n;
2747
      };
2748
 
2749
      explicit
2750
      chi_squared_distribution(_RealType __n = _RealType(1))
2751
      : _M_param(__n), _M_gd(__n / 2)
2752
      { }
2753
 
2754
      explicit
2755
      chi_squared_distribution(const param_type& __p)
2756
      : _M_param(__p), _M_gd(__p.n() / 2)
2757
      { }
2758
 
2759
      /**
2760
       * @brief Resets the distribution state.
2761
       */
2762
      void
2763
      reset()
2764
      { _M_gd.reset(); }
2765
 
2766
      /**
2767
       *
2768
       */
2769
      _RealType
2770
      n() const
2771
      { return _M_param.n(); }
2772
 
2773
      /**
2774
       * @brief Returns the parameter set of the distribution.
2775
       */
2776
      param_type
2777
      param() const
2778
      { return _M_param; }
2779
 
2780
      /**
2781
       * @brief Sets the parameter set of the distribution.
2782
       * @param __param The new parameter set of the distribution.
2783
       */
2784
      void
2785
      param(const param_type& __param)
2786
      { _M_param = __param; }
2787
 
2788
      /**
2789
       * @brief Returns the greatest lower bound value of the distribution.
2790
       */
2791
      result_type
2792
      min() const
2793
      { return result_type(0); }
2794
 
2795
      /**
2796
       * @brief Returns the least upper bound value of the distribution.
2797
       */
2798
      result_type
2799
      max() const
2800
      { return std::numeric_limits<result_type>::max(); }
2801
 
2802
      /**
2803
       * @brief Generating functions.
2804
       */
2805
      template<typename _UniformRandomNumberGenerator>
2806
        result_type
2807
        operator()(_UniformRandomNumberGenerator& __urng)
2808
        { return 2 * _M_gd(__urng); }
2809
 
2810
      template<typename _UniformRandomNumberGenerator>
2811
        result_type
2812
        operator()(_UniformRandomNumberGenerator& __urng,
2813
                   const param_type& __p)
2814
        {
2815
          typedef typename std::gamma_distribution<result_type>::param_type
2816
            param_type;
2817
          return 2 * _M_gd(__urng, param_type(__p.n() / 2));
2818
        }
2819
 
2820
      template<typename _ForwardIterator,
2821
               typename _UniformRandomNumberGenerator>
2822
        void
2823
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2824
                   _UniformRandomNumberGenerator& __urng)
2825
        { this->__generate_impl(__f, __t, __urng); }
2826
 
2827
      template<typename _ForwardIterator,
2828
               typename _UniformRandomNumberGenerator>
2829
        void
2830
        __generate(_ForwardIterator __f, _ForwardIterator __t,
2831
                   _UniformRandomNumberGenerator& __urng,
2832
                   const param_type& __p)
2833
        { typename std::gamma_distribution<result_type>::param_type
2834
            __p2(__p.n() / 2);
2835
          this->__generate_impl(__f, __t, __urng, __p2); }
2836
 
2837
      template<typename _UniformRandomNumberGenerator>
2838
        void
2839
        __generate(result_type* __f, result_type* __t,
2840
                   _UniformRandomNumberGenerator& __urng)
2841
        { this->__generate_impl(__f, __t, __urng); }
2842
 
2843
      template<typename _UniformRandomNumberGenerator>
2844
        void
2845
        __generate(result_type* __f, result_type* __t,
2846
                   _UniformRandomNumberGenerator& __urng,
2847
                   const param_type& __p)
2848
        { typename std::gamma_distribution<result_type>::param_type
2849
            __p2(__p.n() / 2);
2850
          this->__generate_impl(__f, __t, __urng, __p2); }
2851
 
2852
      /**
2853
       * @brief Return true if two Chi-squared distributions have
2854
       *        the same parameters and the sequences that would be
2855
       *        generated are equal.
2856
       */
2857
      friend bool
2858
      operator==(const chi_squared_distribution& __d1,
2859
                 const chi_squared_distribution& __d2)
2860
      { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
2861
 
2862
      /**
2863
       * @brief Inserts a %chi_squared_distribution random number distribution
2864
       * @p __x into the output stream @p __os.
2865
       *
2866
       * @param __os An output stream.
2867
       * @param __x  A %chi_squared_distribution random number distribution.
2868
       *
2869
       * @returns The output stream with the state of @p __x inserted or in
2870
       * an error state.
2871
       */
2872
      template<typename _RealType1, typename _CharT, typename _Traits>
2873
        friend std::basic_ostream<_CharT, _Traits>&
2874
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2875
                   const std::chi_squared_distribution<_RealType1>& __x);
2876
 
2877
      /**
2878
       * @brief Extracts a %chi_squared_distribution random number distribution
2879
       * @p __x from the input stream @p __is.
2880
       *
2881
       * @param __is An input stream.
2882
       * @param __x A %chi_squared_distribution random number
2883
       *            generator engine.
2884
       *
2885
       * @returns The input stream with @p __x extracted or in an error state.
2886
       */
2887
      template<typename _RealType1, typename _CharT, typename _Traits>
2888
        friend std::basic_istream<_CharT, _Traits>&
2889
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2890
                   std::chi_squared_distribution<_RealType1>& __x);
2891
 
2892
    private:
2893
      template<typename _ForwardIterator,
2894
               typename _UniformRandomNumberGenerator>
2895
        void
2896
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2897
                        _UniformRandomNumberGenerator& __urng);
2898
 
2899
      template<typename _ForwardIterator,
2900
               typename _UniformRandomNumberGenerator>
2901
        void
2902
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2903
                        _UniformRandomNumberGenerator& __urng,
2904
                        const typename
2905
                        std::gamma_distribution<result_type>::param_type& __p);
2906
 
2907
      param_type _M_param;
2908
 
2909
      std::gamma_distribution<result_type> _M_gd;
2910
    };
2911
 
2912
  /**
2913
   * @brief Return true if two Chi-squared distributions are different.
2914
   */
2915
  template<typename _RealType>
2916
    inline bool
2917
    operator!=(const std::chi_squared_distribution<_RealType>& __d1,
2918
               const std::chi_squared_distribution<_RealType>& __d2)
2919
    { return !(__d1 == __d2); }
2920
 
2921
 
2922
  /**
2923
   * @brief A cauchy_distribution random number distribution.
2924
   *
2925
   * The formula for the normal probability mass function is
2926
   * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
2927
   */
2928
  template<typename _RealType = double>
2929
    class cauchy_distribution
2930
    {
2931
      static_assert(std::is_floating_point<_RealType>::value,
2932
                    "template argument not a floating point type");
2933
 
2934
    public:
2935
      /** The type of the range of the distribution. */
2936
      typedef _RealType result_type;
2937
      /** Parameter type. */
2938
      struct param_type
2939
      {
2940
        typedef cauchy_distribution<_RealType> distribution_type;
2941
 
2942
        explicit
2943
        param_type(_RealType __a = _RealType(0),
2944
                   _RealType __b = _RealType(1))
2945
        : _M_a(__a), _M_b(__b)
2946
        { }
2947
 
2948
        _RealType
2949
        a() const
2950
        { return _M_a; }
2951
 
2952
        _RealType
2953
        b() const
2954
        { return _M_b; }
2955
 
2956
        friend bool
2957
        operator==(const param_type& __p1, const param_type& __p2)
2958
        { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
2959
 
2960
      private:
2961
        _RealType _M_a;
2962
        _RealType _M_b;
2963
      };
2964
 
2965
      explicit
2966
      cauchy_distribution(_RealType __a = _RealType(0),
2967
                          _RealType __b = _RealType(1))
2968
      : _M_param(__a, __b)
2969
      { }
2970
 
2971
      explicit
2972
      cauchy_distribution(const param_type& __p)
2973
      : _M_param(__p)
2974
      { }
2975
 
2976
      /**
2977
       * @brief Resets the distribution state.
2978
       */
2979
      void
2980
      reset()
2981
      { }
2982
 
2983
      /**
2984
       *
2985
       */
2986
      _RealType
2987
      a() const
2988
      { return _M_param.a(); }
2989
 
2990
      _RealType
2991
      b() const
2992
      { return _M_param.b(); }
2993
 
2994
      /**
2995
       * @brief Returns the parameter set of the distribution.
2996
       */
2997
      param_type
2998
      param() const
2999
      { return _M_param; }
3000
 
3001
      /**
3002
       * @brief Sets the parameter set of the distribution.
3003
       * @param __param The new parameter set of the distribution.
3004
       */
3005
      void
3006
      param(const param_type& __param)
3007
      { _M_param = __param; }
3008
 
3009
      /**
3010
       * @brief Returns the greatest lower bound value of the distribution.
3011
       */
3012
      result_type
3013
      min() const
3014
      { return std::numeric_limits<result_type>::min(); }
3015
 
3016
      /**
3017
       * @brief Returns the least upper bound value of the distribution.
3018
       */
3019
      result_type
3020
      max() const
3021
      { return std::numeric_limits<result_type>::max(); }
3022
 
3023
      /**
3024
       * @brief Generating functions.
3025
       */
3026
      template<typename _UniformRandomNumberGenerator>
3027
        result_type
3028
        operator()(_UniformRandomNumberGenerator& __urng)
3029
        { return this->operator()(__urng, _M_param); }
3030
 
3031
      template<typename _UniformRandomNumberGenerator>
3032
        result_type
3033
        operator()(_UniformRandomNumberGenerator& __urng,
3034
                   const param_type& __p);
3035
 
3036
      template<typename _ForwardIterator,
3037
               typename _UniformRandomNumberGenerator>
3038
        void
3039
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3040
                   _UniformRandomNumberGenerator& __urng)
3041
        { this->__generate(__f, __t, __urng, _M_param); }
3042
 
3043
      template<typename _ForwardIterator,
3044
               typename _UniformRandomNumberGenerator>
3045
        void
3046
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3047
                   _UniformRandomNumberGenerator& __urng,
3048
                   const param_type& __p)
3049
        { this->__generate_impl(__f, __t, __urng, __p); }
3050
 
3051
      template<typename _UniformRandomNumberGenerator>
3052
        void
3053
        __generate(result_type* __f, result_type* __t,
3054
                   _UniformRandomNumberGenerator& __urng,
3055
                   const param_type& __p)
3056
        { this->__generate_impl(__f, __t, __urng, __p); }
3057
 
3058
      /**
3059
       * @brief Return true if two Cauchy distributions have
3060
       *        the same parameters.
3061
       */
3062
      friend bool
3063
      operator==(const cauchy_distribution& __d1,
3064
                 const cauchy_distribution& __d2)
3065
      { return __d1._M_param == __d2._M_param; }
3066
 
3067
    private:
3068
      template<typename _ForwardIterator,
3069
               typename _UniformRandomNumberGenerator>
3070
        void
3071
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3072
                        _UniformRandomNumberGenerator& __urng,
3073
                        const param_type& __p);
3074
 
3075
      param_type _M_param;
3076
    };
3077
 
3078
  /**
3079
   * @brief Return true if two Cauchy distributions have
3080
   *        different parameters.
3081
   */
3082
  template<typename _RealType>
3083
    inline bool
3084
    operator!=(const std::cauchy_distribution<_RealType>& __d1,
3085
               const std::cauchy_distribution<_RealType>& __d2)
3086
    { return !(__d1 == __d2); }
3087
 
3088
  /**
3089
   * @brief Inserts a %cauchy_distribution random number distribution
3090
   * @p __x into the output stream @p __os.
3091
   *
3092
   * @param __os An output stream.
3093
   * @param __x  A %cauchy_distribution random number distribution.
3094
   *
3095
   * @returns The output stream with the state of @p __x inserted or in
3096
   * an error state.
3097
   */
3098
  template<typename _RealType, typename _CharT, typename _Traits>
3099
    std::basic_ostream<_CharT, _Traits>&
3100
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3101
               const std::cauchy_distribution<_RealType>& __x);
3102
 
3103
  /**
3104
   * @brief Extracts a %cauchy_distribution random number distribution
3105
   * @p __x from the input stream @p __is.
3106
   *
3107
   * @param __is An input stream.
3108
   * @param __x A %cauchy_distribution random number
3109
   *            generator engine.
3110
   *
3111
   * @returns The input stream with @p __x extracted or in an error state.
3112
   */
3113
  template<typename _RealType, typename _CharT, typename _Traits>
3114
    std::basic_istream<_CharT, _Traits>&
3115
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
3116
               std::cauchy_distribution<_RealType>& __x);
3117
 
3118
 
3119
  /**
3120
   * @brief A fisher_f_distribution random number distribution.
3121
   *
3122
   * The formula for the normal probability mass function is
3123
   * @f[
3124
   *     p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
3125
   *                (\frac{m}{n})^{m/2} x^{(m/2)-1}
3126
   *                (1 + \frac{mx}{n})^{-(m+n)/2}
3127
   * @f]
3128
   */
3129
  template<typename _RealType = double>
3130
    class fisher_f_distribution
3131
    {
3132
      static_assert(std::is_floating_point<_RealType>::value,
3133
                    "template argument not a floating point type");
3134
 
3135
    public:
3136
      /** The type of the range of the distribution. */
3137
      typedef _RealType result_type;
3138
      /** Parameter type. */
3139
      struct param_type
3140
      {
3141
        typedef fisher_f_distribution<_RealType> distribution_type;
3142
 
3143
        explicit
3144
        param_type(_RealType __m = _RealType(1),
3145
                   _RealType __n = _RealType(1))
3146
        : _M_m(__m), _M_n(__n)
3147
        { }
3148
 
3149
        _RealType
3150
        m() const
3151
        { return _M_m; }
3152
 
3153
        _RealType
3154
        n() const
3155
        { return _M_n; }
3156
 
3157
        friend bool
3158
        operator==(const param_type& __p1, const param_type& __p2)
3159
        { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
3160
 
3161
      private:
3162
        _RealType _M_m;
3163
        _RealType _M_n;
3164
      };
3165
 
3166
      explicit
3167
      fisher_f_distribution(_RealType __m = _RealType(1),
3168
                            _RealType __n = _RealType(1))
3169
      : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
3170
      { }
3171
 
3172
      explicit
3173
      fisher_f_distribution(const param_type& __p)
3174
      : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
3175
      { }
3176
 
3177
      /**
3178
       * @brief Resets the distribution state.
3179
       */
3180
      void
3181
      reset()
3182
      {
3183
        _M_gd_x.reset();
3184
        _M_gd_y.reset();
3185
      }
3186
 
3187
      /**
3188
       *
3189
       */
3190
      _RealType
3191
      m() const
3192
      { return _M_param.m(); }
3193
 
3194
      _RealType
3195
      n() const
3196
      { return _M_param.n(); }
3197
 
3198
      /**
3199
       * @brief Returns the parameter set of the distribution.
3200
       */
3201
      param_type
3202
      param() const
3203
      { return _M_param; }
3204
 
3205
      /**
3206
       * @brief Sets the parameter set of the distribution.
3207
       * @param __param The new parameter set of the distribution.
3208
       */
3209
      void
3210
      param(const param_type& __param)
3211
      { _M_param = __param; }
3212
 
3213
      /**
3214
       * @brief Returns the greatest lower bound value of the distribution.
3215
       */
3216
      result_type
3217
      min() const
3218
      { return result_type(0); }
3219
 
3220
      /**
3221
       * @brief Returns the least upper bound value of the distribution.
3222
       */
3223
      result_type
3224
      max() const
3225
      { return std::numeric_limits<result_type>::max(); }
3226
 
3227
      /**
3228
       * @brief Generating functions.
3229
       */
3230
      template<typename _UniformRandomNumberGenerator>
3231
        result_type
3232
        operator()(_UniformRandomNumberGenerator& __urng)
3233
        { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
3234
 
3235
      template<typename _UniformRandomNumberGenerator>
3236
        result_type
3237
        operator()(_UniformRandomNumberGenerator& __urng,
3238
                   const param_type& __p)
3239
        {
3240
          typedef typename std::gamma_distribution<result_type>::param_type
3241
            param_type;
3242
          return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
3243
                  / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
3244
        }
3245
 
3246
      template<typename _ForwardIterator,
3247
               typename _UniformRandomNumberGenerator>
3248
        void
3249
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3250
                   _UniformRandomNumberGenerator& __urng)
3251
        { this->__generate_impl(__f, __t, __urng); }
3252
 
3253
      template<typename _ForwardIterator,
3254
               typename _UniformRandomNumberGenerator>
3255
        void
3256
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3257
                   _UniformRandomNumberGenerator& __urng,
3258
                   const param_type& __p)
3259
        { this->__generate_impl(__f, __t, __urng, __p); }
3260
 
3261
      template<typename _UniformRandomNumberGenerator>
3262
        void
3263
        __generate(result_type* __f, result_type* __t,
3264
                   _UniformRandomNumberGenerator& __urng)
3265
        { this->__generate_impl(__f, __t, __urng); }
3266
 
3267
      template<typename _UniformRandomNumberGenerator>
3268
        void
3269
        __generate(result_type* __f, result_type* __t,
3270
                   _UniformRandomNumberGenerator& __urng,
3271
                   const param_type& __p)
3272
        { this->__generate_impl(__f, __t, __urng, __p); }
3273
 
3274
      /**
3275
       * @brief Return true if two Fisher f distributions have
3276
       *        the same parameters and the sequences that would
3277
       *        be generated are equal.
3278
       */
3279
      friend bool
3280
      operator==(const fisher_f_distribution& __d1,
3281
                 const fisher_f_distribution& __d2)
3282
      { return (__d1._M_param == __d2._M_param
3283
                && __d1._M_gd_x == __d2._M_gd_x
3284
                && __d1._M_gd_y == __d2._M_gd_y); }
3285
 
3286
      /**
3287
       * @brief Inserts a %fisher_f_distribution random number distribution
3288
       * @p __x into the output stream @p __os.
3289
       *
3290
       * @param __os An output stream.
3291
       * @param __x  A %fisher_f_distribution random number distribution.
3292
       *
3293
       * @returns The output stream with the state of @p __x inserted or in
3294
       * an error state.
3295
       */
3296
      template<typename _RealType1, typename _CharT, typename _Traits>
3297
        friend std::basic_ostream<_CharT, _Traits>&
3298
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3299
                   const std::fisher_f_distribution<_RealType1>& __x);
3300
 
3301
      /**
3302
       * @brief Extracts a %fisher_f_distribution random number distribution
3303
       * @p __x from the input stream @p __is.
3304
       *
3305
       * @param __is An input stream.
3306
       * @param __x A %fisher_f_distribution random number
3307
       *            generator engine.
3308
       *
3309
       * @returns The input stream with @p __x extracted or in an error state.
3310
       */
3311
      template<typename _RealType1, typename _CharT, typename _Traits>
3312
        friend std::basic_istream<_CharT, _Traits>&
3313
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
3314
                   std::fisher_f_distribution<_RealType1>& __x);
3315
 
3316
    private:
3317
      template<typename _ForwardIterator,
3318
               typename _UniformRandomNumberGenerator>
3319
        void
3320
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3321
                        _UniformRandomNumberGenerator& __urng);
3322
 
3323
      template<typename _ForwardIterator,
3324
               typename _UniformRandomNumberGenerator>
3325
        void
3326
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3327
                        _UniformRandomNumberGenerator& __urng,
3328
                        const param_type& __p);
3329
 
3330
      param_type _M_param;
3331
 
3332
      std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
3333
    };
3334
 
3335
  /**
3336
   * @brief Return true if two Fisher f distributions are diferent.
3337
   */
3338
  template<typename _RealType>
3339
    inline bool
3340
    operator!=(const std::fisher_f_distribution<_RealType>& __d1,
3341
               const std::fisher_f_distribution<_RealType>& __d2)
3342
    { return !(__d1 == __d2); }
3343
 
3344
  /**
3345
   * @brief A student_t_distribution random number distribution.
3346
   *
3347
   * The formula for the normal probability mass function is:
3348
   * @f[
3349
   *     p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
3350
   *              (1 + \frac{x^2}{n}) ^{-(n+1)/2}
3351
   * @f]
3352
   */
3353
  template<typename _RealType = double>
3354
    class student_t_distribution
3355
    {
3356
      static_assert(std::is_floating_point<_RealType>::value,
3357
                    "template argument not a floating point type");
3358
 
3359
    public:
3360
      /** The type of the range of the distribution. */
3361
      typedef _RealType result_type;
3362
      /** Parameter type. */
3363
      struct param_type
3364
      {
3365
        typedef student_t_distribution<_RealType> distribution_type;
3366
 
3367
        explicit
3368
        param_type(_RealType __n = _RealType(1))
3369
        : _M_n(__n)
3370
        { }
3371
 
3372
        _RealType
3373
        n() const
3374
        { return _M_n; }
3375
 
3376
        friend bool
3377
        operator==(const param_type& __p1, const param_type& __p2)
3378
        { return __p1._M_n == __p2._M_n; }
3379
 
3380
      private:
3381
        _RealType _M_n;
3382
      };
3383
 
3384
      explicit
3385
      student_t_distribution(_RealType __n = _RealType(1))
3386
      : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
3387
      { }
3388
 
3389
      explicit
3390
      student_t_distribution(const param_type& __p)
3391
      : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
3392
      { }
3393
 
3394
      /**
3395
       * @brief Resets the distribution state.
3396
       */
3397
      void
3398
      reset()
3399
      {
3400
        _M_nd.reset();
3401
        _M_gd.reset();
3402
      }
3403
 
3404
      /**
3405
       *
3406
       */
3407
      _RealType
3408
      n() const
3409
      { return _M_param.n(); }
3410
 
3411
      /**
3412
       * @brief Returns the parameter set of the distribution.
3413
       */
3414
      param_type
3415
      param() const
3416
      { return _M_param; }
3417
 
3418
      /**
3419
       * @brief Sets the parameter set of the distribution.
3420
       * @param __param The new parameter set of the distribution.
3421
       */
3422
      void
3423
      param(const param_type& __param)
3424
      { _M_param = __param; }
3425
 
3426
      /**
3427
       * @brief Returns the greatest lower bound value of the distribution.
3428
       */
3429
      result_type
3430
      min() const
3431
      { return std::numeric_limits<result_type>::min(); }
3432
 
3433
      /**
3434
       * @brief Returns the least upper bound value of the distribution.
3435
       */
3436
      result_type
3437
      max() const
3438
      { return std::numeric_limits<result_type>::max(); }
3439
 
3440
      /**
3441
       * @brief Generating functions.
3442
       */
3443
      template<typename _UniformRandomNumberGenerator>
3444
        result_type
3445
        operator()(_UniformRandomNumberGenerator& __urng)
3446
        { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
3447
 
3448
      template<typename _UniformRandomNumberGenerator>
3449
        result_type
3450
        operator()(_UniformRandomNumberGenerator& __urng,
3451
                   const param_type& __p)
3452
        {
3453
          typedef typename std::gamma_distribution<result_type>::param_type
3454
            param_type;
3455
 
3456
          const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
3457
          return _M_nd(__urng) * std::sqrt(__p.n() / __g);
3458
        }
3459
 
3460
      template<typename _ForwardIterator,
3461
               typename _UniformRandomNumberGenerator>
3462
        void
3463
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3464
                   _UniformRandomNumberGenerator& __urng)
3465
        { this->__generate_impl(__f, __t, __urng); }
3466
 
3467
      template<typename _ForwardIterator,
3468
               typename _UniformRandomNumberGenerator>
3469
        void
3470
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3471
                   _UniformRandomNumberGenerator& __urng,
3472
                   const param_type& __p)
3473
        { this->__generate_impl(__f, __t, __urng, __p); }
3474
 
3475
      template<typename _UniformRandomNumberGenerator>
3476
        void
3477
        __generate(result_type* __f, result_type* __t,
3478
                   _UniformRandomNumberGenerator& __urng)
3479
        { this->__generate_impl(__f, __t, __urng); }
3480
 
3481
      template<typename _UniformRandomNumberGenerator>
3482
        void
3483
        __generate(result_type* __f, result_type* __t,
3484
                   _UniformRandomNumberGenerator& __urng,
3485
                   const param_type& __p)
3486
        { this->__generate_impl(__f, __t, __urng, __p); }
3487
 
3488
      /**
3489
       * @brief Return true if two Student t distributions have
3490
       *        the same parameters and the sequences that would
3491
       *        be generated are equal.
3492
       */
3493
      friend bool
3494
      operator==(const student_t_distribution& __d1,
3495
                 const student_t_distribution& __d2)
3496
      { return (__d1._M_param == __d2._M_param
3497
                && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
3498
 
3499
      /**
3500
       * @brief Inserts a %student_t_distribution random number distribution
3501
       * @p __x into the output stream @p __os.
3502
       *
3503
       * @param __os An output stream.
3504
       * @param __x  A %student_t_distribution random number distribution.
3505
       *
3506
       * @returns The output stream with the state of @p __x inserted or in
3507
       * an error state.
3508
       */
3509
      template<typename _RealType1, typename _CharT, typename _Traits>
3510
        friend std::basic_ostream<_CharT, _Traits>&
3511
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3512
                   const std::student_t_distribution<_RealType1>& __x);
3513
 
3514
      /**
3515
       * @brief Extracts a %student_t_distribution random number distribution
3516
       * @p __x from the input stream @p __is.
3517
       *
3518
       * @param __is An input stream.
3519
       * @param __x A %student_t_distribution random number
3520
       *            generator engine.
3521
       *
3522
       * @returns The input stream with @p __x extracted or in an error state.
3523
       */
3524
      template<typename _RealType1, typename _CharT, typename _Traits>
3525
        friend std::basic_istream<_CharT, _Traits>&
3526
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
3527
                   std::student_t_distribution<_RealType1>& __x);
3528
 
3529
    private:
3530
      template<typename _ForwardIterator,
3531
               typename _UniformRandomNumberGenerator>
3532
        void
3533
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3534
                        _UniformRandomNumberGenerator& __urng);
3535
      template<typename _ForwardIterator,
3536
               typename _UniformRandomNumberGenerator>
3537
        void
3538
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3539
                        _UniformRandomNumberGenerator& __urng,
3540
                        const param_type& __p);
3541
 
3542
      param_type _M_param;
3543
 
3544
      std::normal_distribution<result_type> _M_nd;
3545
      std::gamma_distribution<result_type> _M_gd;
3546
    };
3547
 
3548
  /**
3549
   * @brief Return true if two Student t distributions are different.
3550
   */
3551
  template<typename _RealType>
3552
    inline bool
3553
    operator!=(const std::student_t_distribution<_RealType>& __d1,
3554
               const std::student_t_distribution<_RealType>& __d2)
3555
    { return !(__d1 == __d2); }
3556
 
3557
 
3558
  /* @} */ // group random_distributions_normal
3559
 
3560
  /**
3561
   * @addtogroup random_distributions_bernoulli Bernoulli Distributions
3562
   * @ingroup random_distributions
3563
   * @{
3564
   */
3565
 
3566
  /**
3567
   * @brief A Bernoulli random number distribution.
3568
   *
3569
   * Generates a sequence of true and false values with likelihood @f$p@f$
3570
   * that true will come up and @f$(1 - p)@f$ that false will appear.
3571
   */
3572
  class bernoulli_distribution
3573
  {
3574
  public:
3575
    /** The type of the range of the distribution. */
3576
    typedef bool result_type;
3577
    /** Parameter type. */
3578
    struct param_type
3579
    {
3580
      typedef bernoulli_distribution distribution_type;
3581
 
3582
      explicit
3583
      param_type(double __p = 0.5)
3584
      : _M_p(__p)
3585
      {
3586
        _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
3587
      }
3588
 
3589
      double
3590
      p() const
3591
      { return _M_p; }
3592
 
3593
      friend bool
3594
      operator==(const param_type& __p1, const param_type& __p2)
3595
      { return __p1._M_p == __p2._M_p; }
3596
 
3597
    private:
3598
      double _M_p;
3599
    };
3600
 
3601
  public:
3602
    /**
3603
     * @brief Constructs a Bernoulli distribution with likelihood @p p.
3604
     *
3605
     * @param __p  [IN]  The likelihood of a true result being returned.
3606
     *                   Must be in the interval @f$[0, 1]@f$.
3607
     */
3608
    explicit
3609
    bernoulli_distribution(double __p = 0.5)
3610
    : _M_param(__p)
3611
    { }
3612
 
3613
    explicit
3614
    bernoulli_distribution(const param_type& __p)
3615
    : _M_param(__p)
3616
    { }
3617
 
3618
    /**
3619
     * @brief Resets the distribution state.
3620
     *
3621
     * Does nothing for a Bernoulli distribution.
3622
     */
3623
    void
3624
    reset() { }
3625
 
3626
    /**
3627
     * @brief Returns the @p p parameter of the distribution.
3628
     */
3629
    double
3630
    p() const
3631
    { return _M_param.p(); }
3632
 
3633
    /**
3634
     * @brief Returns the parameter set of the distribution.
3635
     */
3636
    param_type
3637
    param() const
3638
    { return _M_param; }
3639
 
3640
    /**
3641
     * @brief Sets the parameter set of the distribution.
3642
     * @param __param The new parameter set of the distribution.
3643
     */
3644
    void
3645
    param(const param_type& __param)
3646
    { _M_param = __param; }
3647
 
3648
    /**
3649
     * @brief Returns the greatest lower bound value of the distribution.
3650
     */
3651
    result_type
3652
    min() const
3653
    { return std::numeric_limits<result_type>::min(); }
3654
 
3655
    /**
3656
     * @brief Returns the least upper bound value of the distribution.
3657
     */
3658
    result_type
3659
    max() const
3660
    { return std::numeric_limits<result_type>::max(); }
3661
 
3662
    /**
3663
     * @brief Generating functions.
3664
     */
3665
    template<typename _UniformRandomNumberGenerator>
3666
      result_type
3667
      operator()(_UniformRandomNumberGenerator& __urng)
3668
      { return this->operator()(__urng, _M_param); }
3669
 
3670
    template<typename _UniformRandomNumberGenerator>
3671
      result_type
3672
      operator()(_UniformRandomNumberGenerator& __urng,
3673
                 const param_type& __p)
3674
      {
3675
        __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3676
          __aurng(__urng);
3677
        if ((__aurng() - __aurng.min())
3678
             < __p.p() * (__aurng.max() - __aurng.min()))
3679
          return true;
3680
        return false;
3681
      }
3682
 
3683
    template<typename _ForwardIterator,
3684
             typename _UniformRandomNumberGenerator>
3685
      void
3686
      __generate(_ForwardIterator __f, _ForwardIterator __t,
3687
                 _UniformRandomNumberGenerator& __urng)
3688
      { this->__generate(__f, __t, __urng, _M_param); }
3689
 
3690
    template<typename _ForwardIterator,
3691
             typename _UniformRandomNumberGenerator>
3692
      void
3693
      __generate(_ForwardIterator __f, _ForwardIterator __t,
3694
                 _UniformRandomNumberGenerator& __urng, const param_type& __p)
3695
      { this->__generate_impl(__f, __t, __urng, __p); }
3696
 
3697
    template<typename _UniformRandomNumberGenerator>
3698
      void
3699
      __generate(result_type* __f, result_type* __t,
3700
                 _UniformRandomNumberGenerator& __urng,
3701
                 const param_type& __p)
3702
      { this->__generate_impl(__f, __t, __urng, __p); }
3703
 
3704
    /**
3705
     * @brief Return true if two Bernoulli distributions have
3706
     *        the same parameters.
3707
     */
3708
    friend bool
3709
    operator==(const bernoulli_distribution& __d1,
3710
               const bernoulli_distribution& __d2)
3711
    { return __d1._M_param == __d2._M_param; }
3712
 
3713
  private:
3714
    template<typename _ForwardIterator,
3715
             typename _UniformRandomNumberGenerator>
3716
      void
3717
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3718
                      _UniformRandomNumberGenerator& __urng,
3719
                      const param_type& __p);
3720
 
3721
    param_type _M_param;
3722
  };
3723
 
3724
  /**
3725
   * @brief Return true if two Bernoulli distributions have
3726
   *        different parameters.
3727
   */
3728
  inline bool
3729
  operator!=(const std::bernoulli_distribution& __d1,
3730
             const std::bernoulli_distribution& __d2)
3731
  { return !(__d1 == __d2); }
3732
 
3733
  /**
3734
   * @brief Inserts a %bernoulli_distribution random number distribution
3735
   * @p __x into the output stream @p __os.
3736
   *
3737
   * @param __os An output stream.
3738
   * @param __x  A %bernoulli_distribution random number distribution.
3739
   *
3740
   * @returns The output stream with the state of @p __x inserted or in
3741
   * an error state.
3742
   */
3743
  template<typename _CharT, typename _Traits>
3744
    std::basic_ostream<_CharT, _Traits>&
3745
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3746
               const std::bernoulli_distribution& __x);
3747
 
3748
  /**
3749
   * @brief Extracts a %bernoulli_distribution random number distribution
3750
   * @p __x from the input stream @p __is.
3751
   *
3752
   * @param __is An input stream.
3753
   * @param __x  A %bernoulli_distribution random number generator engine.
3754
   *
3755
   * @returns The input stream with @p __x extracted or in an error state.
3756
   */
3757
  template<typename _CharT, typename _Traits>
3758
    std::basic_istream<_CharT, _Traits>&
3759
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
3760
               std::bernoulli_distribution& __x)
3761
    {
3762
      double __p;
3763
      __is >> __p;
3764
      __x.param(bernoulli_distribution::param_type(__p));
3765
      return __is;
3766
    }
3767
 
3768
 
3769
  /**
3770
   * @brief A discrete binomial random number distribution.
3771
   *
3772
   * The formula for the binomial probability density function is
3773
   * @f$p(i|t,p) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
3774
   * and @f$p@f$ are the parameters of the distribution.
3775
   */
3776
  template<typename _IntType = int>
3777
    class binomial_distribution
3778
    {
3779
      static_assert(std::is_integral<_IntType>::value,
3780
                    "template argument not an integral type");
3781
 
3782
    public:
3783
      /** The type of the range of the distribution. */
3784
      typedef _IntType result_type;
3785
      /** Parameter type. */
3786
      struct param_type
3787
      {
3788
        typedef binomial_distribution<_IntType> distribution_type;
3789
        friend class binomial_distribution<_IntType>;
3790
 
3791
        explicit
3792
        param_type(_IntType __t = _IntType(1), double __p = 0.5)
3793
        : _M_t(__t), _M_p(__p)
3794
        {
3795
          _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
3796
                                && (_M_p >= 0.0)
3797
                                && (_M_p <= 1.0));
3798
          _M_initialize();
3799
        }
3800
 
3801
        _IntType
3802
        t() const
3803
        { return _M_t; }
3804
 
3805
        double
3806
        p() const
3807
        { return _M_p; }
3808
 
3809
        friend bool
3810
        operator==(const param_type& __p1, const param_type& __p2)
3811
        { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
3812
 
3813
      private:
3814
        void
3815
        _M_initialize();
3816
 
3817
        _IntType _M_t;
3818
        double _M_p;
3819
 
3820
        double _M_q;
3821
#if _GLIBCXX_USE_C99_MATH_TR1
3822
        double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
3823
               _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
3824
#endif
3825
        bool   _M_easy;
3826
      };
3827
 
3828
      // constructors and member function
3829
      explicit
3830
      binomial_distribution(_IntType __t = _IntType(1),
3831
                            double __p = 0.5)
3832
      : _M_param(__t, __p), _M_nd()
3833
      { }
3834
 
3835
      explicit
3836
      binomial_distribution(const param_type& __p)
3837
      : _M_param(__p), _M_nd()
3838
      { }
3839
 
3840
      /**
3841
       * @brief Resets the distribution state.
3842
       */
3843
      void
3844
      reset()
3845
      { _M_nd.reset(); }
3846
 
3847
      /**
3848
       * @brief Returns the distribution @p t parameter.
3849
       */
3850
      _IntType
3851
      t() const
3852
      { return _M_param.t(); }
3853
 
3854
      /**
3855
       * @brief Returns the distribution @p p parameter.
3856
       */
3857
      double
3858
      p() const
3859
      { return _M_param.p(); }
3860
 
3861
      /**
3862
       * @brief Returns the parameter set of the distribution.
3863
       */
3864
      param_type
3865
      param() const
3866
      { return _M_param; }
3867
 
3868
      /**
3869
       * @brief Sets the parameter set of the distribution.
3870
       * @param __param The new parameter set of the distribution.
3871
       */
3872
      void
3873
      param(const param_type& __param)
3874
      { _M_param = __param; }
3875
 
3876
      /**
3877
       * @brief Returns the greatest lower bound value of the distribution.
3878
       */
3879
      result_type
3880
      min() const
3881
      { return 0; }
3882
 
3883
      /**
3884
       * @brief Returns the least upper bound value of the distribution.
3885
       */
3886
      result_type
3887
      max() const
3888
      { return _M_param.t(); }
3889
 
3890
      /**
3891
       * @brief Generating functions.
3892
       */
3893
      template<typename _UniformRandomNumberGenerator>
3894
        result_type
3895
        operator()(_UniformRandomNumberGenerator& __urng)
3896
        { return this->operator()(__urng, _M_param); }
3897
 
3898
      template<typename _UniformRandomNumberGenerator>
3899
        result_type
3900
        operator()(_UniformRandomNumberGenerator& __urng,
3901
                   const param_type& __p);
3902
 
3903
      template<typename _ForwardIterator,
3904
               typename _UniformRandomNumberGenerator>
3905
        void
3906
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3907
                   _UniformRandomNumberGenerator& __urng)
3908
        { this->__generate(__f, __t, __urng, _M_param); }
3909
 
3910
      template<typename _ForwardIterator,
3911
               typename _UniformRandomNumberGenerator>
3912
        void
3913
        __generate(_ForwardIterator __f, _ForwardIterator __t,
3914
                   _UniformRandomNumberGenerator& __urng,
3915
                   const param_type& __p)
3916
        { this->__generate_impl(__f, __t, __urng, __p); }
3917
 
3918
      template<typename _UniformRandomNumberGenerator>
3919
        void
3920
        __generate(result_type* __f, result_type* __t,
3921
                   _UniformRandomNumberGenerator& __urng,
3922
                   const param_type& __p)
3923
        { this->__generate_impl(__f, __t, __urng, __p); }
3924
 
3925
      /**
3926
       * @brief Return true if two binomial distributions have
3927
       *        the same parameters and the sequences that would
3928
       *        be generated are equal.
3929
       */
3930
        friend bool
3931
        operator==(const binomial_distribution& __d1,
3932
                   const binomial_distribution& __d2)
3933
#ifdef _GLIBCXX_USE_C99_MATH_TR1
3934
        { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
3935
#else
3936
        { return __d1._M_param == __d2._M_param; }
3937
#endif
3938
 
3939
      /**
3940
       * @brief Inserts a %binomial_distribution random number distribution
3941
       * @p __x into the output stream @p __os.
3942
       *
3943
       * @param __os An output stream.
3944
       * @param __x  A %binomial_distribution random number distribution.
3945
       *
3946
       * @returns The output stream with the state of @p __x inserted or in
3947
       * an error state.
3948
       */
3949
      template<typename _IntType1,
3950
               typename _CharT, typename _Traits>
3951
        friend std::basic_ostream<_CharT, _Traits>&
3952
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3953
                   const std::binomial_distribution<_IntType1>& __x);
3954
 
3955
      /**
3956
       * @brief Extracts a %binomial_distribution random number distribution
3957
       * @p __x from the input stream @p __is.
3958
       *
3959
       * @param __is An input stream.
3960
       * @param __x  A %binomial_distribution random number generator engine.
3961
       *
3962
       * @returns The input stream with @p __x extracted or in an error
3963
       *          state.
3964
       */
3965
      template<typename _IntType1,
3966
               typename _CharT, typename _Traits>
3967
        friend std::basic_istream<_CharT, _Traits>&
3968
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
3969
                   std::binomial_distribution<_IntType1>& __x);
3970
 
3971
    private:
3972
      template<typename _ForwardIterator,
3973
               typename _UniformRandomNumberGenerator>
3974
        void
3975
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3976
                        _UniformRandomNumberGenerator& __urng,
3977
                        const param_type& __p);
3978
 
3979
      template<typename _UniformRandomNumberGenerator>
3980
        result_type
3981
        _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
3982
 
3983
      param_type _M_param;
3984
 
3985
      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
3986
      std::normal_distribution<double> _M_nd;
3987
    };
3988
 
3989
  /**
3990
   * @brief Return true if two binomial distributions are different.
3991
   */
3992
  template<typename _IntType>
3993
    inline bool
3994
    operator!=(const std::binomial_distribution<_IntType>& __d1,
3995
               const std::binomial_distribution<_IntType>& __d2)
3996
    { return !(__d1 == __d2); }
3997
 
3998
 
3999
  /**
4000
   * @brief A discrete geometric random number distribution.
4001
   *
4002
   * The formula for the geometric probability density function is
4003
   * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
4004
   * distribution.
4005
   */
4006
  template<typename _IntType = int>
4007
    class geometric_distribution
4008
    {
4009
      static_assert(std::is_integral<_IntType>::value,
4010
                    "template argument not an integral type");
4011
 
4012
    public:
4013
      /** The type of the range of the distribution. */
4014
      typedef _IntType  result_type;
4015
      /** Parameter type. */
4016
      struct param_type
4017
      {
4018
        typedef geometric_distribution<_IntType> distribution_type;
4019
        friend class geometric_distribution<_IntType>;
4020
 
4021
        explicit
4022
        param_type(double __p = 0.5)
4023
        : _M_p(__p)
4024
        {
4025
          _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
4026
          _M_initialize();
4027
        }
4028
 
4029
        double
4030
        p() const
4031
        { return _M_p; }
4032
 
4033
        friend bool
4034
        operator==(const param_type& __p1, const param_type& __p2)
4035
        { return __p1._M_p == __p2._M_p; }
4036
 
4037
      private:
4038
        void
4039
        _M_initialize()
4040
        { _M_log_1_p = std::log(1.0 - _M_p); }
4041
 
4042
        double _M_p;
4043
 
4044
        double _M_log_1_p;
4045
      };
4046
 
4047
      // constructors and member function
4048
      explicit
4049
      geometric_distribution(double __p = 0.5)
4050
      : _M_param(__p)
4051
      { }
4052
 
4053
      explicit
4054
      geometric_distribution(const param_type& __p)
4055
      : _M_param(__p)
4056
      { }
4057
 
4058
      /**
4059
       * @brief Resets the distribution state.
4060
       *
4061
       * Does nothing for the geometric distribution.
4062
       */
4063
      void
4064
      reset() { }
4065
 
4066
      /**
4067
       * @brief Returns the distribution parameter @p p.
4068
       */
4069
      double
4070
      p() const
4071
      { return _M_param.p(); }
4072
 
4073
      /**
4074
       * @brief Returns the parameter set of the distribution.
4075
       */
4076
      param_type
4077
      param() const
4078
      { return _M_param; }
4079
 
4080
      /**
4081
       * @brief Sets the parameter set of the distribution.
4082
       * @param __param The new parameter set of the distribution.
4083
       */
4084
      void
4085
      param(const param_type& __param)
4086
      { _M_param = __param; }
4087
 
4088
      /**
4089
       * @brief Returns the greatest lower bound value of the distribution.
4090
       */
4091
      result_type
4092
      min() const
4093
      { return 0; }
4094
 
4095
      /**
4096
       * @brief Returns the least upper bound value of the distribution.
4097
       */
4098
      result_type
4099
      max() const
4100
      { return std::numeric_limits<result_type>::max(); }
4101
 
4102
      /**
4103
       * @brief Generating functions.
4104
       */
4105
      template<typename _UniformRandomNumberGenerator>
4106
        result_type
4107
        operator()(_UniformRandomNumberGenerator& __urng)
4108
        { return this->operator()(__urng, _M_param); }
4109
 
4110
      template<typename _UniformRandomNumberGenerator>
4111
        result_type
4112
        operator()(_UniformRandomNumberGenerator& __urng,
4113
                   const param_type& __p);
4114
 
4115
      template<typename _ForwardIterator,
4116
               typename _UniformRandomNumberGenerator>
4117
        void
4118
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4119
                   _UniformRandomNumberGenerator& __urng)
4120
        { this->__generate(__f, __t, __urng, _M_param); }
4121
 
4122
      template<typename _ForwardIterator,
4123
               typename _UniformRandomNumberGenerator>
4124
        void
4125
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4126
                   _UniformRandomNumberGenerator& __urng,
4127
                   const param_type& __p)
4128
        { this->__generate_impl(__f, __t, __urng, __p); }
4129
 
4130
      template<typename _UniformRandomNumberGenerator>
4131
        void
4132
        __generate(result_type* __f, result_type* __t,
4133
                   _UniformRandomNumberGenerator& __urng,
4134
                   const param_type& __p)
4135
        { this->__generate_impl(__f, __t, __urng, __p); }
4136
 
4137
      /**
4138
       * @brief Return true if two geometric distributions have
4139
       *        the same parameters.
4140
       */
4141
      friend bool
4142
      operator==(const geometric_distribution& __d1,
4143
                 const geometric_distribution& __d2)
4144
      { return __d1._M_param == __d2._M_param; }
4145
 
4146
    private:
4147
      template<typename _ForwardIterator,
4148
               typename _UniformRandomNumberGenerator>
4149
        void
4150
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4151
                        _UniformRandomNumberGenerator& __urng,
4152
                        const param_type& __p);
4153
 
4154
      param_type _M_param;
4155
    };
4156
 
4157
  /**
4158
   * @brief Return true if two geometric distributions have
4159
   *        different parameters.
4160
   */
4161
  template<typename _IntType>
4162
    inline bool
4163
    operator!=(const std::geometric_distribution<_IntType>& __d1,
4164
               const std::geometric_distribution<_IntType>& __d2)
4165
    { return !(__d1 == __d2); }
4166
 
4167
  /**
4168
   * @brief Inserts a %geometric_distribution random number distribution
4169
   * @p __x into the output stream @p __os.
4170
   *
4171
   * @param __os An output stream.
4172
   * @param __x  A %geometric_distribution random number distribution.
4173
   *
4174
   * @returns The output stream with the state of @p __x inserted or in
4175
   * an error state.
4176
   */
4177
  template<typename _IntType,
4178
           typename _CharT, typename _Traits>
4179
    std::basic_ostream<_CharT, _Traits>&
4180
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4181
               const std::geometric_distribution<_IntType>& __x);
4182
 
4183
  /**
4184
   * @brief Extracts a %geometric_distribution random number distribution
4185
   * @p __x from the input stream @p __is.
4186
   *
4187
   * @param __is An input stream.
4188
   * @param __x  A %geometric_distribution random number generator engine.
4189
   *
4190
   * @returns The input stream with @p __x extracted or in an error state.
4191
   */
4192
  template<typename _IntType,
4193
           typename _CharT, typename _Traits>
4194
    std::basic_istream<_CharT, _Traits>&
4195
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
4196
               std::geometric_distribution<_IntType>& __x);
4197
 
4198
 
4199
  /**
4200
   * @brief A negative_binomial_distribution random number distribution.
4201
   *
4202
   * The formula for the negative binomial probability mass function is
4203
   * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
4204
   * and @f$p@f$ are the parameters of the distribution.
4205
   */
4206
  template<typename _IntType = int>
4207
    class negative_binomial_distribution
4208
    {
4209
      static_assert(std::is_integral<_IntType>::value,
4210
                    "template argument not an integral type");
4211
 
4212
    public:
4213
      /** The type of the range of the distribution. */
4214
      typedef _IntType result_type;
4215
      /** Parameter type. */
4216
      struct param_type
4217
      {
4218
        typedef negative_binomial_distribution<_IntType> distribution_type;
4219
 
4220
        explicit
4221
        param_type(_IntType __k = 1, double __p = 0.5)
4222
        : _M_k(__k), _M_p(__p)
4223
        {
4224
          _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
4225
        }
4226
 
4227
        _IntType
4228
        k() const
4229
        { return _M_k; }
4230
 
4231
        double
4232
        p() const
4233
        { return _M_p; }
4234
 
4235
        friend bool
4236
        operator==(const param_type& __p1, const param_type& __p2)
4237
        { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
4238
 
4239
      private:
4240
        _IntType _M_k;
4241
        double _M_p;
4242
      };
4243
 
4244
      explicit
4245
      negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
4246
      : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
4247
      { }
4248
 
4249
      explicit
4250
      negative_binomial_distribution(const param_type& __p)
4251
      : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
4252
      { }
4253
 
4254
      /**
4255
       * @brief Resets the distribution state.
4256
       */
4257
      void
4258
      reset()
4259
      { _M_gd.reset(); }
4260
 
4261
      /**
4262
       * @brief Return the @f$k@f$ parameter of the distribution.
4263
       */
4264
      _IntType
4265
      k() const
4266
      { return _M_param.k(); }
4267
 
4268
      /**
4269
       * @brief Return the @f$p@f$ parameter of the distribution.
4270
       */
4271
      double
4272
      p() const
4273
      { return _M_param.p(); }
4274
 
4275
      /**
4276
       * @brief Returns the parameter set of the distribution.
4277
       */
4278
      param_type
4279
      param() const
4280
      { return _M_param; }
4281
 
4282
      /**
4283
       * @brief Sets the parameter set of the distribution.
4284
       * @param __param The new parameter set of the distribution.
4285
       */
4286
      void
4287
      param(const param_type& __param)
4288
      { _M_param = __param; }
4289
 
4290
      /**
4291
       * @brief Returns the greatest lower bound value of the distribution.
4292
       */
4293
      result_type
4294
      min() const
4295
      { return result_type(0); }
4296
 
4297
      /**
4298
       * @brief Returns the least upper bound value of the distribution.
4299
       */
4300
      result_type
4301
      max() const
4302
      { return std::numeric_limits<result_type>::max(); }
4303
 
4304
      /**
4305
       * @brief Generating functions.
4306
       */
4307
      template<typename _UniformRandomNumberGenerator>
4308
        result_type
4309
        operator()(_UniformRandomNumberGenerator& __urng);
4310
 
4311
      template<typename _UniformRandomNumberGenerator>
4312
        result_type
4313
        operator()(_UniformRandomNumberGenerator& __urng,
4314
                   const param_type& __p);
4315
 
4316
      template<typename _ForwardIterator,
4317
               typename _UniformRandomNumberGenerator>
4318
        void
4319
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4320
                   _UniformRandomNumberGenerator& __urng)
4321
        { this->__generate_impl(__f, __t, __urng); }
4322
 
4323
      template<typename _ForwardIterator,
4324
               typename _UniformRandomNumberGenerator>
4325
        void
4326
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4327
                   _UniformRandomNumberGenerator& __urng,
4328
                   const param_type& __p)
4329
        { this->__generate_impl(__f, __t, __urng, __p); }
4330
 
4331
      template<typename _UniformRandomNumberGenerator>
4332
        void
4333
        __generate(result_type* __f, result_type* __t,
4334
                   _UniformRandomNumberGenerator& __urng)
4335
        { this->__generate_impl(__f, __t, __urng); }
4336
 
4337
      template<typename _UniformRandomNumberGenerator>
4338
        void
4339
        __generate(result_type* __f, result_type* __t,
4340
                   _UniformRandomNumberGenerator& __urng,
4341
                   const param_type& __p)
4342
        { this->__generate_impl(__f, __t, __urng, __p); }
4343
 
4344
      /**
4345
       * @brief Return true if two negative binomial distributions have
4346
       *        the same parameters and the sequences that would be
4347
       *        generated are equal.
4348
       */
4349
      friend bool
4350
      operator==(const negative_binomial_distribution& __d1,
4351
                 const negative_binomial_distribution& __d2)
4352
      { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
4353
 
4354
      /**
4355
       * @brief Inserts a %negative_binomial_distribution random
4356
       *        number distribution @p __x into the output stream @p __os.
4357
       *
4358
       * @param __os An output stream.
4359
       * @param __x  A %negative_binomial_distribution random number
4360
       *             distribution.
4361
       *
4362
       * @returns The output stream with the state of @p __x inserted or in
4363
       *          an error state.
4364
       */
4365
      template<typename _IntType1, typename _CharT, typename _Traits>
4366
        friend std::basic_ostream<_CharT, _Traits>&
4367
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4368
                   const std::negative_binomial_distribution<_IntType1>& __x);
4369
 
4370
      /**
4371
       * @brief Extracts a %negative_binomial_distribution random number
4372
       *        distribution @p __x from the input stream @p __is.
4373
       *
4374
       * @param __is An input stream.
4375
       * @param __x A %negative_binomial_distribution random number
4376
       *            generator engine.
4377
       *
4378
       * @returns The input stream with @p __x extracted or in an error state.
4379
       */
4380
      template<typename _IntType1, typename _CharT, typename _Traits>
4381
        friend std::basic_istream<_CharT, _Traits>&
4382
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
4383
                   std::negative_binomial_distribution<_IntType1>& __x);
4384
 
4385
    private:
4386
      template<typename _ForwardIterator,
4387
               typename _UniformRandomNumberGenerator>
4388
        void
4389
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4390
                        _UniformRandomNumberGenerator& __urng);
4391
      template<typename _ForwardIterator,
4392
               typename _UniformRandomNumberGenerator>
4393
        void
4394
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4395
                        _UniformRandomNumberGenerator& __urng,
4396
                        const param_type& __p);
4397
 
4398
      param_type _M_param;
4399
 
4400
      std::gamma_distribution<double> _M_gd;
4401
    };
4402
 
4403
  /**
4404
   * @brief Return true if two negative binomial distributions are different.
4405
   */
4406
  template<typename _IntType>
4407
    inline bool
4408
    operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
4409
               const std::negative_binomial_distribution<_IntType>& __d2)
4410
    { return !(__d1 == __d2); }
4411
 
4412
 
4413
  /* @} */ // group random_distributions_bernoulli
4414
 
4415
  /**
4416
   * @addtogroup random_distributions_poisson Poisson Distributions
4417
   * @ingroup random_distributions
4418
   * @{
4419
   */
4420
 
4421
  /**
4422
   * @brief A discrete Poisson random number distribution.
4423
   *
4424
   * The formula for the Poisson probability density function is
4425
   * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
4426
   * parameter of the distribution.
4427
   */
4428
  template<typename _IntType = int>
4429
    class poisson_distribution
4430
    {
4431
      static_assert(std::is_integral<_IntType>::value,
4432
                    "template argument not an integral type");
4433
 
4434
    public:
4435
      /** The type of the range of the distribution. */
4436
      typedef _IntType  result_type;
4437
      /** Parameter type. */
4438
      struct param_type
4439
      {
4440
        typedef poisson_distribution<_IntType> distribution_type;
4441
        friend class poisson_distribution<_IntType>;
4442
 
4443
        explicit
4444
        param_type(double __mean = 1.0)
4445
        : _M_mean(__mean)
4446
        {
4447
          _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
4448
          _M_initialize();
4449
        }
4450
 
4451
        double
4452
        mean() const
4453
        { return _M_mean; }
4454
 
4455
        friend bool
4456
        operator==(const param_type& __p1, const param_type& __p2)
4457
        { return __p1._M_mean == __p2._M_mean; }
4458
 
4459
      private:
4460
        // Hosts either log(mean) or the threshold of the simple method.
4461
        void
4462
        _M_initialize();
4463
 
4464
        double _M_mean;
4465
 
4466
        double _M_lm_thr;
4467
#if _GLIBCXX_USE_C99_MATH_TR1
4468
        double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
4469
#endif
4470
      };
4471
 
4472
      // constructors and member function
4473
      explicit
4474
      poisson_distribution(double __mean = 1.0)
4475
      : _M_param(__mean), _M_nd()
4476
      { }
4477
 
4478
      explicit
4479
      poisson_distribution(const param_type& __p)
4480
      : _M_param(__p), _M_nd()
4481
      { }
4482
 
4483
      /**
4484
       * @brief Resets the distribution state.
4485
       */
4486
      void
4487
      reset()
4488
      { _M_nd.reset(); }
4489
 
4490
      /**
4491
       * @brief Returns the distribution parameter @p mean.
4492
       */
4493
      double
4494
      mean() const
4495
      { return _M_param.mean(); }
4496
 
4497
      /**
4498
       * @brief Returns the parameter set of the distribution.
4499
       */
4500
      param_type
4501
      param() const
4502
      { return _M_param; }
4503
 
4504
      /**
4505
       * @brief Sets the parameter set of the distribution.
4506
       * @param __param The new parameter set of the distribution.
4507
       */
4508
      void
4509
      param(const param_type& __param)
4510
      { _M_param = __param; }
4511
 
4512
      /**
4513
       * @brief Returns the greatest lower bound value of the distribution.
4514
       */
4515
      result_type
4516
      min() const
4517
      { return 0; }
4518
 
4519
      /**
4520
       * @brief Returns the least upper bound value of the distribution.
4521
       */
4522
      result_type
4523
      max() const
4524
      { return std::numeric_limits<result_type>::max(); }
4525
 
4526
      /**
4527
       * @brief Generating functions.
4528
       */
4529
      template<typename _UniformRandomNumberGenerator>
4530
        result_type
4531
        operator()(_UniformRandomNumberGenerator& __urng)
4532
        { return this->operator()(__urng, _M_param); }
4533
 
4534
      template<typename _UniformRandomNumberGenerator>
4535
        result_type
4536
        operator()(_UniformRandomNumberGenerator& __urng,
4537
                   const param_type& __p);
4538
 
4539
      template<typename _ForwardIterator,
4540
               typename _UniformRandomNumberGenerator>
4541
        void
4542
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4543
                   _UniformRandomNumberGenerator& __urng)
4544
        { this->__generate(__f, __t, __urng, _M_param); }
4545
 
4546
      template<typename _ForwardIterator,
4547
               typename _UniformRandomNumberGenerator>
4548
        void
4549
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4550
                   _UniformRandomNumberGenerator& __urng,
4551
                   const param_type& __p)
4552
        { this->__generate_impl(__f, __t, __urng, __p); }
4553
 
4554
      template<typename _UniformRandomNumberGenerator>
4555
        void
4556
        __generate(result_type* __f, result_type* __t,
4557
                   _UniformRandomNumberGenerator& __urng,
4558
                   const param_type& __p)
4559
        { this->__generate_impl(__f, __t, __urng, __p); }
4560
 
4561
       /**
4562
        * @brief Return true if two Poisson distributions have the same
4563
        *        parameters and the sequences that would be generated
4564
        *        are equal.
4565
        */
4566
      friend bool
4567
      operator==(const poisson_distribution& __d1,
4568
                 const poisson_distribution& __d2)
4569
#ifdef _GLIBCXX_USE_C99_MATH_TR1
4570
      { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
4571
#else
4572
      { return __d1._M_param == __d2._M_param; }
4573
#endif
4574
 
4575
      /**
4576
       * @brief Inserts a %poisson_distribution random number distribution
4577
       * @p __x into the output stream @p __os.
4578
       *
4579
       * @param __os An output stream.
4580
       * @param __x  A %poisson_distribution random number distribution.
4581
       *
4582
       * @returns The output stream with the state of @p __x inserted or in
4583
       * an error state.
4584
       */
4585
      template<typename _IntType1, typename _CharT, typename _Traits>
4586
        friend std::basic_ostream<_CharT, _Traits>&
4587
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4588
                   const std::poisson_distribution<_IntType1>& __x);
4589
 
4590
      /**
4591
       * @brief Extracts a %poisson_distribution random number distribution
4592
       * @p __x from the input stream @p __is.
4593
       *
4594
       * @param __is An input stream.
4595
       * @param __x  A %poisson_distribution random number generator engine.
4596
       *
4597
       * @returns The input stream with @p __x extracted or in an error
4598
       *          state.
4599
       */
4600
      template<typename _IntType1, typename _CharT, typename _Traits>
4601
        friend std::basic_istream<_CharT, _Traits>&
4602
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
4603
                   std::poisson_distribution<_IntType1>& __x);
4604
 
4605
    private:
4606
      template<typename _ForwardIterator,
4607
               typename _UniformRandomNumberGenerator>
4608
        void
4609
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4610
                        _UniformRandomNumberGenerator& __urng,
4611
                        const param_type& __p);
4612
 
4613
      param_type _M_param;
4614
 
4615
      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
4616
      std::normal_distribution<double> _M_nd;
4617
    };
4618
 
4619
  /**
4620
   * @brief Return true if two Poisson distributions are different.
4621
   */
4622
  template<typename _IntType>
4623
    inline bool
4624
    operator!=(const std::poisson_distribution<_IntType>& __d1,
4625
               const std::poisson_distribution<_IntType>& __d2)
4626
    { return !(__d1 == __d2); }
4627
 
4628
 
4629
  /**
4630
   * @brief An exponential continuous distribution for random numbers.
4631
   *
4632
   * The formula for the exponential probability density function is
4633
   * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
4634
   *
4635
   * <table border=1 cellpadding=10 cellspacing=0>
4636
   * <caption align=top>Distribution Statistics</caption>
4637
   * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4638
   * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
4639
   * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
4640
   * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
4641
   * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4642
   * </table>
4643
   */
4644
  template<typename _RealType = double>
4645
    class exponential_distribution
4646
    {
4647
      static_assert(std::is_floating_point<_RealType>::value,
4648
                    "template argument not a floating point type");
4649
 
4650
    public:
4651
      /** The type of the range of the distribution. */
4652
      typedef _RealType result_type;
4653
      /** Parameter type. */
4654
      struct param_type
4655
      {
4656
        typedef exponential_distribution<_RealType> distribution_type;
4657
 
4658
        explicit
4659
        param_type(_RealType __lambda = _RealType(1))
4660
        : _M_lambda(__lambda)
4661
        {
4662
          _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
4663
        }
4664
 
4665
        _RealType
4666
        lambda() const
4667
        { return _M_lambda; }
4668
 
4669
        friend bool
4670
        operator==(const param_type& __p1, const param_type& __p2)
4671
        { return __p1._M_lambda == __p2._M_lambda; }
4672
 
4673
      private:
4674
        _RealType _M_lambda;
4675
      };
4676
 
4677
    public:
4678
      /**
4679
       * @brief Constructs an exponential distribution with inverse scale
4680
       *        parameter @f$\lambda@f$.
4681
       */
4682
      explicit
4683
      exponential_distribution(const result_type& __lambda = result_type(1))
4684
      : _M_param(__lambda)
4685
      { }
4686
 
4687
      explicit
4688
      exponential_distribution(const param_type& __p)
4689
      : _M_param(__p)
4690
      { }
4691
 
4692
      /**
4693
       * @brief Resets the distribution state.
4694
       *
4695
       * Has no effect on exponential distributions.
4696
       */
4697
      void
4698
      reset() { }
4699
 
4700
      /**
4701
       * @brief Returns the inverse scale parameter of the distribution.
4702
       */
4703
      _RealType
4704
      lambda() const
4705
      { return _M_param.lambda(); }
4706
 
4707
      /**
4708
       * @brief Returns the parameter set of the distribution.
4709
       */
4710
      param_type
4711
      param() const
4712
      { return _M_param; }
4713
 
4714
      /**
4715
       * @brief Sets the parameter set of the distribution.
4716
       * @param __param The new parameter set of the distribution.
4717
       */
4718
      void
4719
      param(const param_type& __param)
4720
      { _M_param = __param; }
4721
 
4722
      /**
4723
       * @brief Returns the greatest lower bound value of the distribution.
4724
       */
4725
      result_type
4726
      min() const
4727
      { return result_type(0); }
4728
 
4729
      /**
4730
       * @brief Returns the least upper bound value of the distribution.
4731
       */
4732
      result_type
4733
      max() const
4734
      { return std::numeric_limits<result_type>::max(); }
4735
 
4736
      /**
4737
       * @brief Generating functions.
4738
       */
4739
      template<typename _UniformRandomNumberGenerator>
4740
        result_type
4741
        operator()(_UniformRandomNumberGenerator& __urng)
4742
        { return this->operator()(__urng, _M_param); }
4743
 
4744
      template<typename _UniformRandomNumberGenerator>
4745
        result_type
4746
        operator()(_UniformRandomNumberGenerator& __urng,
4747
                   const param_type& __p)
4748
        {
4749
          __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
4750
            __aurng(__urng);
4751
          return -std::log(result_type(1) - __aurng()) / __p.lambda();
4752
        }
4753
 
4754
      template<typename _ForwardIterator,
4755
               typename _UniformRandomNumberGenerator>
4756
        void
4757
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4758
                   _UniformRandomNumberGenerator& __urng)
4759
        { this->__generate(__f, __t, __urng, _M_param); }
4760
 
4761
      template<typename _ForwardIterator,
4762
               typename _UniformRandomNumberGenerator>
4763
        void
4764
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4765
                   _UniformRandomNumberGenerator& __urng,
4766
                   const param_type& __p)
4767
        { this->__generate_impl(__f, __t, __urng, __p); }
4768
 
4769
      template<typename _UniformRandomNumberGenerator>
4770
        void
4771
        __generate(result_type* __f, result_type* __t,
4772
                   _UniformRandomNumberGenerator& __urng,
4773
                   const param_type& __p)
4774
        { this->__generate_impl(__f, __t, __urng, __p); }
4775
 
4776
      /**
4777
       * @brief Return true if two exponential distributions have the same
4778
       *        parameters.
4779
       */
4780
      friend bool
4781
      operator==(const exponential_distribution& __d1,
4782
                 const exponential_distribution& __d2)
4783
      { return __d1._M_param == __d2._M_param; }
4784
 
4785
    private:
4786
      template<typename _ForwardIterator,
4787
               typename _UniformRandomNumberGenerator>
4788
        void
4789
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4790
                        _UniformRandomNumberGenerator& __urng,
4791
                        const param_type& __p);
4792
 
4793
      param_type _M_param;
4794
    };
4795
 
4796
  /**
4797
   * @brief Return true if two exponential distributions have different
4798
   *        parameters.
4799
   */
4800
  template<typename _RealType>
4801
    inline bool
4802
    operator!=(const std::exponential_distribution<_RealType>& __d1,
4803
               const std::exponential_distribution<_RealType>& __d2)
4804
    { return !(__d1 == __d2); }
4805
 
4806
  /**
4807
   * @brief Inserts a %exponential_distribution random number distribution
4808
   * @p __x into the output stream @p __os.
4809
   *
4810
   * @param __os An output stream.
4811
   * @param __x  A %exponential_distribution random number distribution.
4812
   *
4813
   * @returns The output stream with the state of @p __x inserted or in
4814
   * an error state.
4815
   */
4816
  template<typename _RealType, typename _CharT, typename _Traits>
4817
    std::basic_ostream<_CharT, _Traits>&
4818
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4819
               const std::exponential_distribution<_RealType>& __x);
4820
 
4821
  /**
4822
   * @brief Extracts a %exponential_distribution random number distribution
4823
   * @p __x from the input stream @p __is.
4824
   *
4825
   * @param __is An input stream.
4826
   * @param __x A %exponential_distribution random number
4827
   *            generator engine.
4828
   *
4829
   * @returns The input stream with @p __x extracted or in an error state.
4830
   */
4831
  template<typename _RealType, typename _CharT, typename _Traits>
4832
    std::basic_istream<_CharT, _Traits>&
4833
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
4834
               std::exponential_distribution<_RealType>& __x);
4835
 
4836
 
4837
  /**
4838
   * @brief A weibull_distribution random number distribution.
4839
   *
4840
   * The formula for the normal probability density function is:
4841
   * @f[
4842
   *     p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
4843
   *                         \exp{(-(\frac{x}{\beta})^\alpha)}
4844
   * @f]
4845
   */
4846
  template<typename _RealType = double>
4847
    class weibull_distribution
4848
    {
4849
      static_assert(std::is_floating_point<_RealType>::value,
4850
                    "template argument not a floating point type");
4851
 
4852
    public:
4853
      /** The type of the range of the distribution. */
4854
      typedef _RealType result_type;
4855
      /** Parameter type. */
4856
      struct param_type
4857
      {
4858
        typedef weibull_distribution<_RealType> distribution_type;
4859
 
4860
        explicit
4861
        param_type(_RealType __a = _RealType(1),
4862
                   _RealType __b = _RealType(1))
4863
        : _M_a(__a), _M_b(__b)
4864
        { }
4865
 
4866
        _RealType
4867
        a() const
4868
        { return _M_a; }
4869
 
4870
        _RealType
4871
        b() const
4872
        { return _M_b; }
4873
 
4874
        friend bool
4875
        operator==(const param_type& __p1, const param_type& __p2)
4876
        { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
4877
 
4878
      private:
4879
        _RealType _M_a;
4880
        _RealType _M_b;
4881
      };
4882
 
4883
      explicit
4884
      weibull_distribution(_RealType __a = _RealType(1),
4885
                           _RealType __b = _RealType(1))
4886
      : _M_param(__a, __b)
4887
      { }
4888
 
4889
      explicit
4890
      weibull_distribution(const param_type& __p)
4891
      : _M_param(__p)
4892
      { }
4893
 
4894
      /**
4895
       * @brief Resets the distribution state.
4896
       */
4897
      void
4898
      reset()
4899
      { }
4900
 
4901
      /**
4902
       * @brief Return the @f$a@f$ parameter of the distribution.
4903
       */
4904
      _RealType
4905
      a() const
4906
      { return _M_param.a(); }
4907
 
4908
      /**
4909
       * @brief Return the @f$b@f$ parameter of the distribution.
4910
       */
4911
      _RealType
4912
      b() const
4913
      { return _M_param.b(); }
4914
 
4915
      /**
4916
       * @brief Returns the parameter set of the distribution.
4917
       */
4918
      param_type
4919
      param() const
4920
      { return _M_param; }
4921
 
4922
      /**
4923
       * @brief Sets the parameter set of the distribution.
4924
       * @param __param The new parameter set of the distribution.
4925
       */
4926
      void
4927
      param(const param_type& __param)
4928
      { _M_param = __param; }
4929
 
4930
      /**
4931
       * @brief Returns the greatest lower bound value of the distribution.
4932
       */
4933
      result_type
4934
      min() const
4935
      { return result_type(0); }
4936
 
4937
      /**
4938
       * @brief Returns the least upper bound value of the distribution.
4939
       */
4940
      result_type
4941
      max() const
4942
      { return std::numeric_limits<result_type>::max(); }
4943
 
4944
      /**
4945
       * @brief Generating functions.
4946
       */
4947
      template<typename _UniformRandomNumberGenerator>
4948
        result_type
4949
        operator()(_UniformRandomNumberGenerator& __urng)
4950
        { return this->operator()(__urng, _M_param); }
4951
 
4952
      template<typename _UniformRandomNumberGenerator>
4953
        result_type
4954
        operator()(_UniformRandomNumberGenerator& __urng,
4955
                   const param_type& __p);
4956
 
4957
      template<typename _ForwardIterator,
4958
               typename _UniformRandomNumberGenerator>
4959
        void
4960
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4961
                   _UniformRandomNumberGenerator& __urng)
4962
        { this->__generate(__f, __t, __urng, _M_param); }
4963
 
4964
      template<typename _ForwardIterator,
4965
               typename _UniformRandomNumberGenerator>
4966
        void
4967
        __generate(_ForwardIterator __f, _ForwardIterator __t,
4968
                   _UniformRandomNumberGenerator& __urng,
4969
                   const param_type& __p)
4970
        { this->__generate_impl(__f, __t, __urng, __p); }
4971
 
4972
      template<typename _UniformRandomNumberGenerator>
4973
        void
4974
        __generate(result_type* __f, result_type* __t,
4975
                   _UniformRandomNumberGenerator& __urng,
4976
                   const param_type& __p)
4977
        { this->__generate_impl(__f, __t, __urng, __p); }
4978
 
4979
      /**
4980
       * @brief Return true if two Weibull distributions have the same
4981
       *        parameters.
4982
       */
4983
      friend bool
4984
      operator==(const weibull_distribution& __d1,
4985
                 const weibull_distribution& __d2)
4986
      { return __d1._M_param == __d2._M_param; }
4987
 
4988
    private:
4989
      template<typename _ForwardIterator,
4990
               typename _UniformRandomNumberGenerator>
4991
        void
4992
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4993
                        _UniformRandomNumberGenerator& __urng,
4994
                        const param_type& __p);
4995
 
4996
      param_type _M_param;
4997
    };
4998
 
4999
   /**
5000
    * @brief Return true if two Weibull distributions have different
5001
    *        parameters.
5002
    */
5003
  template<typename _RealType>
5004
    inline bool
5005
    operator!=(const std::weibull_distribution<_RealType>& __d1,
5006
               const std::weibull_distribution<_RealType>& __d2)
5007
    { return !(__d1 == __d2); }
5008
 
5009
  /**
5010
   * @brief Inserts a %weibull_distribution random number distribution
5011
   * @p __x into the output stream @p __os.
5012
   *
5013
   * @param __os An output stream.
5014
   * @param __x  A %weibull_distribution random number distribution.
5015
   *
5016
   * @returns The output stream with the state of @p __x inserted or in
5017
   * an error state.
5018
   */
5019
  template<typename _RealType, typename _CharT, typename _Traits>
5020
    std::basic_ostream<_CharT, _Traits>&
5021
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5022
               const std::weibull_distribution<_RealType>& __x);
5023
 
5024
  /**
5025
   * @brief Extracts a %weibull_distribution random number distribution
5026
   * @p __x from the input stream @p __is.
5027
   *
5028
   * @param __is An input stream.
5029
   * @param __x A %weibull_distribution random number
5030
   *            generator engine.
5031
   *
5032
   * @returns The input stream with @p __x extracted or in an error state.
5033
   */
5034
  template<typename _RealType, typename _CharT, typename _Traits>
5035
    std::basic_istream<_CharT, _Traits>&
5036
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
5037
               std::weibull_distribution<_RealType>& __x);
5038
 
5039
 
5040
  /**
5041
   * @brief A extreme_value_distribution random number distribution.
5042
   *
5043
   * The formula for the normal probability mass function is
5044
   * @f[
5045
   *     p(x|a,b) = \frac{1}{b}
5046
   *                \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b}))
5047
   * @f]
5048
   */
5049
  template<typename _RealType = double>
5050
    class extreme_value_distribution
5051
    {
5052
      static_assert(std::is_floating_point<_RealType>::value,
5053
                    "template argument not a floating point type");
5054
 
5055
    public:
5056
      /** The type of the range of the distribution. */
5057
      typedef _RealType result_type;
5058
      /** Parameter type. */
5059
      struct param_type
5060
      {
5061
        typedef extreme_value_distribution<_RealType> distribution_type;
5062
 
5063
        explicit
5064
        param_type(_RealType __a = _RealType(0),
5065
                   _RealType __b = _RealType(1))
5066
        : _M_a(__a), _M_b(__b)
5067
        { }
5068
 
5069
        _RealType
5070
        a() const
5071
        { return _M_a; }
5072
 
5073
        _RealType
5074
        b() const
5075
        { return _M_b; }
5076
 
5077
        friend bool
5078
        operator==(const param_type& __p1, const param_type& __p2)
5079
        { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
5080
 
5081
      private:
5082
        _RealType _M_a;
5083
        _RealType _M_b;
5084
      };
5085
 
5086
      explicit
5087
      extreme_value_distribution(_RealType __a = _RealType(0),
5088
                                 _RealType __b = _RealType(1))
5089
      : _M_param(__a, __b)
5090
      { }
5091
 
5092
      explicit
5093
      extreme_value_distribution(const param_type& __p)
5094
      : _M_param(__p)
5095
      { }
5096
 
5097
      /**
5098
       * @brief Resets the distribution state.
5099
       */
5100
      void
5101
      reset()
5102
      { }
5103
 
5104
      /**
5105
       * @brief Return the @f$a@f$ parameter of the distribution.
5106
       */
5107
      _RealType
5108
      a() const
5109
      { return _M_param.a(); }
5110
 
5111
      /**
5112
       * @brief Return the @f$b@f$ parameter of the distribution.
5113
       */
5114
      _RealType
5115
      b() const
5116
      { return _M_param.b(); }
5117
 
5118
      /**
5119
       * @brief Returns the parameter set of the distribution.
5120
       */
5121
      param_type
5122
      param() const
5123
      { return _M_param; }
5124
 
5125
      /**
5126
       * @brief Sets the parameter set of the distribution.
5127
       * @param __param The new parameter set of the distribution.
5128
       */
5129
      void
5130
      param(const param_type& __param)
5131
      { _M_param = __param; }
5132
 
5133
      /**
5134
       * @brief Returns the greatest lower bound value of the distribution.
5135
       */
5136
      result_type
5137
      min() const
5138
      { return std::numeric_limits<result_type>::min(); }
5139
 
5140
      /**
5141
       * @brief Returns the least upper bound value of the distribution.
5142
       */
5143
      result_type
5144
      max() const
5145
      { return std::numeric_limits<result_type>::max(); }
5146
 
5147
      /**
5148
       * @brief Generating functions.
5149
       */
5150
      template<typename _UniformRandomNumberGenerator>
5151
        result_type
5152
        operator()(_UniformRandomNumberGenerator& __urng)
5153
        { return this->operator()(__urng, _M_param); }
5154
 
5155
      template<typename _UniformRandomNumberGenerator>
5156
        result_type
5157
        operator()(_UniformRandomNumberGenerator& __urng,
5158
                   const param_type& __p);
5159
 
5160
      template<typename _ForwardIterator,
5161
               typename _UniformRandomNumberGenerator>
5162
        void
5163
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5164
                   _UniformRandomNumberGenerator& __urng)
5165
        { this->__generate(__f, __t, __urng, _M_param); }
5166
 
5167
      template<typename _ForwardIterator,
5168
               typename _UniformRandomNumberGenerator>
5169
        void
5170
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5171
                   _UniformRandomNumberGenerator& __urng,
5172
                   const param_type& __p)
5173
        { this->__generate_impl(__f, __t, __urng, __p); }
5174
 
5175
      template<typename _UniformRandomNumberGenerator>
5176
        void
5177
        __generate(result_type* __f, result_type* __t,
5178
                   _UniformRandomNumberGenerator& __urng,
5179
                   const param_type& __p)
5180
        { this->__generate_impl(__f, __t, __urng, __p); }
5181
 
5182
      /**
5183
       * @brief Return true if two extreme value distributions have the same
5184
       *        parameters.
5185
       */
5186
      friend bool
5187
      operator==(const extreme_value_distribution& __d1,
5188
                 const extreme_value_distribution& __d2)
5189
      { return __d1._M_param == __d2._M_param; }
5190
 
5191
    private:
5192
      template<typename _ForwardIterator,
5193
               typename _UniformRandomNumberGenerator>
5194
        void
5195
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5196
                        _UniformRandomNumberGenerator& __urng,
5197
                        const param_type& __p);
5198
 
5199
      param_type _M_param;
5200
    };
5201
 
5202
  /**
5203
    * @brief Return true if two extreme value distributions have different
5204
    *        parameters.
5205
   */
5206
  template<typename _RealType>
5207
    inline bool
5208
    operator!=(const std::extreme_value_distribution<_RealType>& __d1,
5209
               const std::extreme_value_distribution<_RealType>& __d2)
5210
    { return !(__d1 == __d2); }
5211
 
5212
  /**
5213
   * @brief Inserts a %extreme_value_distribution random number distribution
5214
   * @p __x into the output stream @p __os.
5215
   *
5216
   * @param __os An output stream.
5217
   * @param __x  A %extreme_value_distribution random number distribution.
5218
   *
5219
   * @returns The output stream with the state of @p __x inserted or in
5220
   * an error state.
5221
   */
5222
  template<typename _RealType, typename _CharT, typename _Traits>
5223
    std::basic_ostream<_CharT, _Traits>&
5224
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5225
               const std::extreme_value_distribution<_RealType>& __x);
5226
 
5227
  /**
5228
   * @brief Extracts a %extreme_value_distribution random number
5229
   *        distribution @p __x from the input stream @p __is.
5230
   *
5231
   * @param __is An input stream.
5232
   * @param __x A %extreme_value_distribution random number
5233
   *            generator engine.
5234
   *
5235
   * @returns The input stream with @p __x extracted or in an error state.
5236
   */
5237
  template<typename _RealType, typename _CharT, typename _Traits>
5238
    std::basic_istream<_CharT, _Traits>&
5239
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
5240
               std::extreme_value_distribution<_RealType>& __x);
5241
 
5242
 
5243
  /**
5244
   * @brief A discrete_distribution random number distribution.
5245
   *
5246
   * The formula for the discrete probability mass function is
5247
   *
5248
   */
5249
  template<typename _IntType = int>
5250
    class discrete_distribution
5251
    {
5252
      static_assert(std::is_integral<_IntType>::value,
5253
                    "template argument not an integral type");
5254
 
5255
    public:
5256
      /** The type of the range of the distribution. */
5257
      typedef _IntType result_type;
5258
      /** Parameter type. */
5259
      struct param_type
5260
      {
5261
        typedef discrete_distribution<_IntType> distribution_type;
5262
        friend class discrete_distribution<_IntType>;
5263
 
5264
        param_type()
5265
        : _M_prob(), _M_cp()
5266
        { }
5267
 
5268
        template<typename _InputIterator>
5269
          param_type(_InputIterator __wbegin,
5270
                     _InputIterator __wend)
5271
          : _M_prob(__wbegin, __wend), _M_cp()
5272
          { _M_initialize(); }
5273
 
5274
        param_type(initializer_list<double> __wil)
5275
        : _M_prob(__wil.begin(), __wil.end()), _M_cp()
5276
        { _M_initialize(); }
5277
 
5278
        template<typename _Func>
5279
          param_type(size_t __nw, double __xmin, double __xmax,
5280
                     _Func __fw);
5281
 
5282
        // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5283
        param_type(const param_type&) = default;
5284
        param_type& operator=(const param_type&) = default;
5285
 
5286
        std::vector<double>
5287
        probabilities() const
5288
        { return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
5289
 
5290
        friend bool
5291
        operator==(const param_type& __p1, const param_type& __p2)
5292
        { return __p1._M_prob == __p2._M_prob; }
5293
 
5294
      private:
5295
        void
5296
        _M_initialize();
5297
 
5298
        std::vector<double> _M_prob;
5299
        std::vector<double> _M_cp;
5300
      };
5301
 
5302
      discrete_distribution()
5303
      : _M_param()
5304
      { }
5305
 
5306
      template<typename _InputIterator>
5307
        discrete_distribution(_InputIterator __wbegin,
5308
                              _InputIterator __wend)
5309
        : _M_param(__wbegin, __wend)
5310
        { }
5311
 
5312
      discrete_distribution(initializer_list<double> __wl)
5313
      : _M_param(__wl)
5314
      { }
5315
 
5316
      template<typename _Func>
5317
        discrete_distribution(size_t __nw, double __xmin, double __xmax,
5318
                              _Func __fw)
5319
        : _M_param(__nw, __xmin, __xmax, __fw)
5320
        { }
5321
 
5322
      explicit
5323
      discrete_distribution(const param_type& __p)
5324
      : _M_param(__p)
5325
      { }
5326
 
5327
      /**
5328
       * @brief Resets the distribution state.
5329
       */
5330
      void
5331
      reset()
5332
      { }
5333
 
5334
      /**
5335
       * @brief Returns the probabilities of the distribution.
5336
       */
5337
      std::vector<double>
5338
      probabilities() const
5339
      {
5340
        return _M_param._M_prob.empty()
5341
          ? std::vector<double>(1, 1.0) : _M_param._M_prob;
5342
      }
5343
 
5344
      /**
5345
       * @brief Returns the parameter set of the distribution.
5346
       */
5347
      param_type
5348
      param() const
5349
      { return _M_param; }
5350
 
5351
      /**
5352
       * @brief Sets the parameter set of the distribution.
5353
       * @param __param The new parameter set of the distribution.
5354
       */
5355
      void
5356
      param(const param_type& __param)
5357
      { _M_param = __param; }
5358
 
5359
      /**
5360
       * @brief Returns the greatest lower bound value of the distribution.
5361
       */
5362
      result_type
5363
      min() const
5364
      { return result_type(0); }
5365
 
5366
      /**
5367
       * @brief Returns the least upper bound value of the distribution.
5368
       */
5369
      result_type
5370
      max() const
5371
      {
5372
        return _M_param._M_prob.empty()
5373
          ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
5374
      }
5375
 
5376
      /**
5377
       * @brief Generating functions.
5378
       */
5379
      template<typename _UniformRandomNumberGenerator>
5380
        result_type
5381
        operator()(_UniformRandomNumberGenerator& __urng)
5382
        { return this->operator()(__urng, _M_param); }
5383
 
5384
      template<typename _UniformRandomNumberGenerator>
5385
        result_type
5386
        operator()(_UniformRandomNumberGenerator& __urng,
5387
                   const param_type& __p);
5388
 
5389
      template<typename _ForwardIterator,
5390
               typename _UniformRandomNumberGenerator>
5391
        void
5392
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5393
                   _UniformRandomNumberGenerator& __urng)
5394
        { this->__generate(__f, __t, __urng, _M_param); }
5395
 
5396
      template<typename _ForwardIterator,
5397
               typename _UniformRandomNumberGenerator>
5398
        void
5399
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5400
                   _UniformRandomNumberGenerator& __urng,
5401
                   const param_type& __p)
5402
        { this->__generate_impl(__f, __t, __urng, __p); }
5403
 
5404
      template<typename _UniformRandomNumberGenerator>
5405
        void
5406
        __generate(result_type* __f, result_type* __t,
5407
                   _UniformRandomNumberGenerator& __urng,
5408
                   const param_type& __p)
5409
        { this->__generate_impl(__f, __t, __urng, __p); }
5410
 
5411
      /**
5412
       * @brief Return true if two discrete distributions have the same
5413
       *        parameters.
5414
       */
5415
      friend bool
5416
      operator==(const discrete_distribution& __d1,
5417
                 const discrete_distribution& __d2)
5418
      { return __d1._M_param == __d2._M_param; }
5419
 
5420
      /**
5421
       * @brief Inserts a %discrete_distribution random number distribution
5422
       * @p __x into the output stream @p __os.
5423
       *
5424
       * @param __os An output stream.
5425
       * @param __x  A %discrete_distribution random number distribution.
5426
       *
5427
       * @returns The output stream with the state of @p __x inserted or in
5428
       * an error state.
5429
       */
5430
      template<typename _IntType1, typename _CharT, typename _Traits>
5431
        friend std::basic_ostream<_CharT, _Traits>&
5432
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5433
                   const std::discrete_distribution<_IntType1>& __x);
5434
 
5435
      /**
5436
       * @brief Extracts a %discrete_distribution random number distribution
5437
       * @p __x from the input stream @p __is.
5438
       *
5439
       * @param __is An input stream.
5440
       * @param __x A %discrete_distribution random number
5441
       *            generator engine.
5442
       *
5443
       * @returns The input stream with @p __x extracted or in an error
5444
       *          state.
5445
       */
5446
      template<typename _IntType1, typename _CharT, typename _Traits>
5447
        friend std::basic_istream<_CharT, _Traits>&
5448
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
5449
                   std::discrete_distribution<_IntType1>& __x);
5450
 
5451
    private:
5452
      template<typename _ForwardIterator,
5453
               typename _UniformRandomNumberGenerator>
5454
        void
5455
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5456
                        _UniformRandomNumberGenerator& __urng,
5457
                        const param_type& __p);
5458
 
5459
      param_type _M_param;
5460
    };
5461
 
5462
  /**
5463
    * @brief Return true if two discrete distributions have different
5464
    *        parameters.
5465
    */
5466
  template<typename _IntType>
5467
    inline bool
5468
    operator!=(const std::discrete_distribution<_IntType>& __d1,
5469
               const std::discrete_distribution<_IntType>& __d2)
5470
    { return !(__d1 == __d2); }
5471
 
5472
 
5473
  /**
5474
   * @brief A piecewise_constant_distribution random number distribution.
5475
   *
5476
   * The formula for the piecewise constant probability mass function is
5477
   *
5478
   */
5479
  template<typename _RealType = double>
5480
    class piecewise_constant_distribution
5481
    {
5482
      static_assert(std::is_floating_point<_RealType>::value,
5483
                    "template argument not a floating point type");
5484
 
5485
    public:
5486
      /** The type of the range of the distribution. */
5487
      typedef _RealType result_type;
5488
      /** Parameter type. */
5489
      struct param_type
5490
      {
5491
        typedef piecewise_constant_distribution<_RealType> distribution_type;
5492
        friend class piecewise_constant_distribution<_RealType>;
5493
 
5494
        param_type()
5495
        : _M_int(), _M_den(), _M_cp()
5496
        { }
5497
 
5498
        template<typename _InputIteratorB, typename _InputIteratorW>
5499
          param_type(_InputIteratorB __bfirst,
5500
                     _InputIteratorB __bend,
5501
                     _InputIteratorW __wbegin);
5502
 
5503
        template<typename _Func>
5504
          param_type(initializer_list<_RealType> __bi, _Func __fw);
5505
 
5506
        template<typename _Func>
5507
          param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5508
                     _Func __fw);
5509
 
5510
        // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5511
        param_type(const param_type&) = default;
5512
        param_type& operator=(const param_type&) = default;
5513
 
5514
        std::vector<_RealType>
5515
        intervals() const
5516
        {
5517
          if (_M_int.empty())
5518
            {
5519
              std::vector<_RealType> __tmp(2);
5520
              __tmp[1] = _RealType(1);
5521
              return __tmp;
5522
            }
5523
          else
5524
            return _M_int;
5525
        }
5526
 
5527
        std::vector<double>
5528
        densities() const
5529
        { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
5530
 
5531
        friend bool
5532
        operator==(const param_type& __p1, const param_type& __p2)
5533
        { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
5534
 
5535
      private:
5536
        void
5537
        _M_initialize();
5538
 
5539
        std::vector<_RealType> _M_int;
5540
        std::vector<double> _M_den;
5541
        std::vector<double> _M_cp;
5542
      };
5543
 
5544
      explicit
5545
      piecewise_constant_distribution()
5546
      : _M_param()
5547
      { }
5548
 
5549
      template<typename _InputIteratorB, typename _InputIteratorW>
5550
        piecewise_constant_distribution(_InputIteratorB __bfirst,
5551
                                        _InputIteratorB __bend,
5552
                                        _InputIteratorW __wbegin)
5553
        : _M_param(__bfirst, __bend, __wbegin)
5554
        { }
5555
 
5556
      template<typename _Func>
5557
        piecewise_constant_distribution(initializer_list<_RealType> __bl,
5558
                                        _Func __fw)
5559
        : _M_param(__bl, __fw)
5560
        { }
5561
 
5562
      template<typename _Func>
5563
        piecewise_constant_distribution(size_t __nw,
5564
                                        _RealType __xmin, _RealType __xmax,
5565
                                        _Func __fw)
5566
        : _M_param(__nw, __xmin, __xmax, __fw)
5567
        { }
5568
 
5569
      explicit
5570
      piecewise_constant_distribution(const param_type& __p)
5571
      : _M_param(__p)
5572
      { }
5573
 
5574
      /**
5575
       * @brief Resets the distribution state.
5576
       */
5577
      void
5578
      reset()
5579
      { }
5580
 
5581
      /**
5582
       * @brief Returns a vector of the intervals.
5583
       */
5584
      std::vector<_RealType>
5585
      intervals() const
5586
      {
5587
        if (_M_param._M_int.empty())
5588
          {
5589
            std::vector<_RealType> __tmp(2);
5590
            __tmp[1] = _RealType(1);
5591
            return __tmp;
5592
          }
5593
        else
5594
          return _M_param._M_int;
5595
      }
5596
 
5597
      /**
5598
       * @brief Returns a vector of the probability densities.
5599
       */
5600
      std::vector<double>
5601
      densities() const
5602
      {
5603
        return _M_param._M_den.empty()
5604
          ? std::vector<double>(1, 1.0) : _M_param._M_den;
5605
      }
5606
 
5607
      /**
5608
       * @brief Returns the parameter set of the distribution.
5609
       */
5610
      param_type
5611
      param() const
5612
      { return _M_param; }
5613
 
5614
      /**
5615
       * @brief Sets the parameter set of the distribution.
5616
       * @param __param The new parameter set of the distribution.
5617
       */
5618
      void
5619
      param(const param_type& __param)
5620
      { _M_param = __param; }
5621
 
5622
      /**
5623
       * @brief Returns the greatest lower bound value of the distribution.
5624
       */
5625
      result_type
5626
      min() const
5627
      {
5628
        return _M_param._M_int.empty()
5629
          ? result_type(0) : _M_param._M_int.front();
5630
      }
5631
 
5632
      /**
5633
       * @brief Returns the least upper bound value of the distribution.
5634
       */
5635
      result_type
5636
      max() const
5637
      {
5638
        return _M_param._M_int.empty()
5639
          ? result_type(1) : _M_param._M_int.back();
5640
      }
5641
 
5642
      /**
5643
       * @brief Generating functions.
5644
       */
5645
      template<typename _UniformRandomNumberGenerator>
5646
        result_type
5647
        operator()(_UniformRandomNumberGenerator& __urng)
5648
        { return this->operator()(__urng, _M_param); }
5649
 
5650
      template<typename _UniformRandomNumberGenerator>
5651
        result_type
5652
        operator()(_UniformRandomNumberGenerator& __urng,
5653
                   const param_type& __p);
5654
 
5655
      template<typename _ForwardIterator,
5656
               typename _UniformRandomNumberGenerator>
5657
        void
5658
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5659
                   _UniformRandomNumberGenerator& __urng)
5660
        { this->__generate(__f, __t, __urng, _M_param); }
5661
 
5662
      template<typename _ForwardIterator,
5663
               typename _UniformRandomNumberGenerator>
5664
        void
5665
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5666
                   _UniformRandomNumberGenerator& __urng,
5667
                   const param_type& __p)
5668
        { this->__generate_impl(__f, __t, __urng, __p); }
5669
 
5670
      template<typename _UniformRandomNumberGenerator>
5671
        void
5672
        __generate(result_type* __f, result_type* __t,
5673
                   _UniformRandomNumberGenerator& __urng,
5674
                   const param_type& __p)
5675
        { this->__generate_impl(__f, __t, __urng, __p); }
5676
 
5677
      /**
5678
       * @brief Return true if two piecewise constant distributions have the
5679
       *        same parameters.
5680
       */
5681
      friend bool
5682
      operator==(const piecewise_constant_distribution& __d1,
5683
                 const piecewise_constant_distribution& __d2)
5684
      { return __d1._M_param == __d2._M_param; }
5685
 
5686
      /**
5687
       * @brief Inserts a %piecewise_constan_distribution random
5688
       *        number distribution @p __x into the output stream @p __os.
5689
       *
5690
       * @param __os An output stream.
5691
       * @param __x  A %piecewise_constan_distribution random number
5692
       *             distribution.
5693
       *
5694
       * @returns The output stream with the state of @p __x inserted or in
5695
       * an error state.
5696
       */
5697
      template<typename _RealType1, typename _CharT, typename _Traits>
5698
        friend std::basic_ostream<_CharT, _Traits>&
5699
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5700
                   const std::piecewise_constant_distribution<_RealType1>& __x);
5701
 
5702
      /**
5703
       * @brief Extracts a %piecewise_constan_distribution random
5704
       *        number distribution @p __x from the input stream @p __is.
5705
       *
5706
       * @param __is An input stream.
5707
       * @param __x A %piecewise_constan_distribution random number
5708
       *            generator engine.
5709
       *
5710
       * @returns The input stream with @p __x extracted or in an error
5711
       *          state.
5712
       */
5713
      template<typename _RealType1, typename _CharT, typename _Traits>
5714
        friend std::basic_istream<_CharT, _Traits>&
5715
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
5716
                   std::piecewise_constant_distribution<_RealType1>& __x);
5717
 
5718
    private:
5719
      template<typename _ForwardIterator,
5720
               typename _UniformRandomNumberGenerator>
5721
        void
5722
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5723
                        _UniformRandomNumberGenerator& __urng,
5724
                        const param_type& __p);
5725
 
5726
      param_type _M_param;
5727
    };
5728
 
5729
  /**
5730
    * @brief Return true if two piecewise constant distributions have
5731
    *        different parameters.
5732
   */
5733
  template<typename _RealType>
5734
    inline bool
5735
    operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
5736
               const std::piecewise_constant_distribution<_RealType>& __d2)
5737
    { return !(__d1 == __d2); }
5738
 
5739
 
5740
  /**
5741
   * @brief A piecewise_linear_distribution random number distribution.
5742
   *
5743
   * The formula for the piecewise linear probability mass function is
5744
   *
5745
   */
5746
  template<typename _RealType = double>
5747
    class piecewise_linear_distribution
5748
    {
5749
      static_assert(std::is_floating_point<_RealType>::value,
5750
                    "template argument not a floating point type");
5751
 
5752
    public:
5753
      /** The type of the range of the distribution. */
5754
      typedef _RealType result_type;
5755
      /** Parameter type. */
5756
      struct param_type
5757
      {
5758
        typedef piecewise_linear_distribution<_RealType> distribution_type;
5759
        friend class piecewise_linear_distribution<_RealType>;
5760
 
5761
        param_type()
5762
        : _M_int(), _M_den(), _M_cp(), _M_m()
5763
        { }
5764
 
5765
        template<typename _InputIteratorB, typename _InputIteratorW>
5766
          param_type(_InputIteratorB __bfirst,
5767
                     _InputIteratorB __bend,
5768
                     _InputIteratorW __wbegin);
5769
 
5770
        template<typename _Func>
5771
          param_type(initializer_list<_RealType> __bl, _Func __fw);
5772
 
5773
        template<typename _Func>
5774
          param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5775
                     _Func __fw);
5776
 
5777
        // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5778
        param_type(const param_type&) = default;
5779
        param_type& operator=(const param_type&) = default;
5780
 
5781
        std::vector<_RealType>
5782
        intervals() const
5783
        {
5784
          if (_M_int.empty())
5785
            {
5786
              std::vector<_RealType> __tmp(2);
5787
              __tmp[1] = _RealType(1);
5788
              return __tmp;
5789
            }
5790
          else
5791
            return _M_int;
5792
        }
5793
 
5794
        std::vector<double>
5795
        densities() const
5796
        { return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
5797
 
5798
        friend bool
5799
        operator==(const param_type& __p1, const param_type& __p2)
5800
        { return (__p1._M_int == __p2._M_int
5801
                  && __p1._M_den == __p2._M_den); }
5802
 
5803
      private:
5804
        void
5805
        _M_initialize();
5806
 
5807
        std::vector<_RealType> _M_int;
5808
        std::vector<double> _M_den;
5809
        std::vector<double> _M_cp;
5810
        std::vector<double> _M_m;
5811
      };
5812
 
5813
      explicit
5814
      piecewise_linear_distribution()
5815
      : _M_param()
5816
      { }
5817
 
5818
      template<typename _InputIteratorB, typename _InputIteratorW>
5819
        piecewise_linear_distribution(_InputIteratorB __bfirst,
5820
                                      _InputIteratorB __bend,
5821
                                      _InputIteratorW __wbegin)
5822
        : _M_param(__bfirst, __bend, __wbegin)
5823
        { }
5824
 
5825
      template<typename _Func>
5826
        piecewise_linear_distribution(initializer_list<_RealType> __bl,
5827
                                      _Func __fw)
5828
        : _M_param(__bl, __fw)
5829
        { }
5830
 
5831
      template<typename _Func>
5832
        piecewise_linear_distribution(size_t __nw,
5833
                                      _RealType __xmin, _RealType __xmax,
5834
                                      _Func __fw)
5835
        : _M_param(__nw, __xmin, __xmax, __fw)
5836
        { }
5837
 
5838
      explicit
5839
      piecewise_linear_distribution(const param_type& __p)
5840
      : _M_param(__p)
5841
      { }
5842
 
5843
      /**
5844
       * Resets the distribution state.
5845
       */
5846
      void
5847
      reset()
5848
      { }
5849
 
5850
      /**
5851
       * @brief Return the intervals of the distribution.
5852
       */
5853
      std::vector<_RealType>
5854
      intervals() const
5855
      {
5856
        if (_M_param._M_int.empty())
5857
          {
5858
            std::vector<_RealType> __tmp(2);
5859
            __tmp[1] = _RealType(1);
5860
            return __tmp;
5861
          }
5862
        else
5863
          return _M_param._M_int;
5864
      }
5865
 
5866
      /**
5867
       * @brief Return a vector of the probability densities of the
5868
       *        distribution.
5869
       */
5870
      std::vector<double>
5871
      densities() const
5872
      {
5873
        return _M_param._M_den.empty()
5874
          ? std::vector<double>(2, 1.0) : _M_param._M_den;
5875
      }
5876
 
5877
      /**
5878
       * @brief Returns the parameter set of the distribution.
5879
       */
5880
      param_type
5881
      param() const
5882
      { return _M_param; }
5883
 
5884
      /**
5885
       * @brief Sets the parameter set of the distribution.
5886
       * @param __param The new parameter set of the distribution.
5887
       */
5888
      void
5889
      param(const param_type& __param)
5890
      { _M_param = __param; }
5891
 
5892
      /**
5893
       * @brief Returns the greatest lower bound value of the distribution.
5894
       */
5895
      result_type
5896
      min() const
5897
      {
5898
        return _M_param._M_int.empty()
5899
          ? result_type(0) : _M_param._M_int.front();
5900
      }
5901
 
5902
      /**
5903
       * @brief Returns the least upper bound value of the distribution.
5904
       */
5905
      result_type
5906
      max() const
5907
      {
5908
        return _M_param._M_int.empty()
5909
          ? result_type(1) : _M_param._M_int.back();
5910
      }
5911
 
5912
      /**
5913
       * @brief Generating functions.
5914
       */
5915
      template<typename _UniformRandomNumberGenerator>
5916
        result_type
5917
        operator()(_UniformRandomNumberGenerator& __urng)
5918
        { return this->operator()(__urng, _M_param); }
5919
 
5920
      template<typename _UniformRandomNumberGenerator>
5921
        result_type
5922
        operator()(_UniformRandomNumberGenerator& __urng,
5923
                   const param_type& __p);
5924
 
5925
      template<typename _ForwardIterator,
5926
               typename _UniformRandomNumberGenerator>
5927
        void
5928
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5929
                   _UniformRandomNumberGenerator& __urng)
5930
        { this->__generate(__f, __t, __urng, _M_param); }
5931
 
5932
      template<typename _ForwardIterator,
5933
               typename _UniformRandomNumberGenerator>
5934
        void
5935
        __generate(_ForwardIterator __f, _ForwardIterator __t,
5936
                   _UniformRandomNumberGenerator& __urng,
5937
                   const param_type& __p)
5938
        { this->__generate_impl(__f, __t, __urng, __p); }
5939
 
5940
      template<typename _UniformRandomNumberGenerator>
5941
        void
5942
        __generate(result_type* __f, result_type* __t,
5943
                   _UniformRandomNumberGenerator& __urng,
5944
                   const param_type& __p)
5945
        { this->__generate_impl(__f, __t, __urng, __p); }
5946
 
5947
      /**
5948
       * @brief Return true if two piecewise linear distributions have the
5949
       *        same parameters.
5950
       */
5951
      friend bool
5952
      operator==(const piecewise_linear_distribution& __d1,
5953
                 const piecewise_linear_distribution& __d2)
5954
      { return __d1._M_param == __d2._M_param; }
5955
 
5956
      /**
5957
       * @brief Inserts a %piecewise_linear_distribution random number
5958
       *        distribution @p __x into the output stream @p __os.
5959
       *
5960
       * @param __os An output stream.
5961
       * @param __x  A %piecewise_linear_distribution random number
5962
       *             distribution.
5963
       *
5964
       * @returns The output stream with the state of @p __x inserted or in
5965
       *          an error state.
5966
       */
5967
      template<typename _RealType1, typename _CharT, typename _Traits>
5968
        friend std::basic_ostream<_CharT, _Traits>&
5969
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5970
                   const std::piecewise_linear_distribution<_RealType1>& __x);
5971
 
5972
      /**
5973
       * @brief Extracts a %piecewise_linear_distribution random number
5974
       *        distribution @p __x from the input stream @p __is.
5975
       *
5976
       * @param __is An input stream.
5977
       * @param __x  A %piecewise_linear_distribution random number
5978
       *             generator engine.
5979
       *
5980
       * @returns The input stream with @p __x extracted or in an error
5981
       *          state.
5982
       */
5983
      template<typename _RealType1, typename _CharT, typename _Traits>
5984
        friend std::basic_istream<_CharT, _Traits>&
5985
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
5986
                   std::piecewise_linear_distribution<_RealType1>& __x);
5987
 
5988
    private:
5989
      template<typename _ForwardIterator,
5990
               typename _UniformRandomNumberGenerator>
5991
        void
5992
        __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5993
                        _UniformRandomNumberGenerator& __urng,
5994
                        const param_type& __p);
5995
 
5996
      param_type _M_param;
5997
    };
5998
 
5999
  /**
6000
    * @brief Return true if two piecewise linear distributions have
6001
    *        different parameters.
6002
   */
6003
  template<typename _RealType>
6004
    inline bool
6005
    operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
6006
               const std::piecewise_linear_distribution<_RealType>& __d2)
6007
    { return !(__d1 == __d2); }
6008
 
6009
 
6010
  /* @} */ // group random_distributions_poisson
6011
 
6012
  /* @} */ // group random_distributions
6013
 
6014
  /**
6015
   * @addtogroup random_utilities Random Number Utilities
6016
   * @ingroup random
6017
   * @{
6018
   */
6019
 
6020
  /**
6021
   * @brief The seed_seq class generates sequences of seeds for random
6022
   *        number generators.
6023
   */
6024
  class seed_seq
6025
  {
6026
 
6027
  public:
6028
    /** The type of the seed vales. */
6029
    typedef uint_least32_t result_type;
6030
 
6031
    /** Default constructor. */
6032
    seed_seq()
6033
    : _M_v()
6034
    { }
6035
 
6036
    template<typename _IntType>
6037
      seed_seq(std::initializer_list<_IntType> il);
6038
 
6039
    template<typename _InputIterator>
6040
      seed_seq(_InputIterator __begin, _InputIterator __end);
6041
 
6042
    // generating functions
6043
    template<typename _RandomAccessIterator>
6044
      void
6045
      generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
6046
 
6047
    // property functions
6048
    size_t size() const
6049
    { return _M_v.size(); }
6050
 
6051
    template<typename OutputIterator>
6052
      void
6053
      param(OutputIterator __dest) const
6054
      { std::copy(_M_v.begin(), _M_v.end(), __dest); }
6055
 
6056
  private:
6057
    ///
6058
    std::vector<result_type> _M_v;
6059
  };
6060
 
6061
  /* @} */ // group random_utilities
6062
 
6063
  /* @} */ // group random
6064
 
6065
_GLIBCXX_END_NAMESPACE_VERSION
6066
} // namespace std
6067
 
6068
#endif

powered by: WebSVN 2.1.0

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