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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [tr1/] [random.h] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// random number generation -*- C++ -*-
2
 
3
// Copyright (C) 2009, 2010 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 tr1/random.h
27
 *  This is an internal header file, included by other library headers.
28
 *  You should not attempt to use it directly.
29
 */
30
 
31
#ifndef _GLIBCXX_TR1_RANDOM_H
32
#define _GLIBCXX_TR1_RANDOM_H 1
33
 
34
#pragma GCC system_header
35
 
36
namespace std
37
{
38
namespace tr1
39
{
40
  // [5.1] Random number generation
41
 
42
  /**
43
   * @addtogroup tr1_random Random Number Generation
44
   * A facility for generating random numbers on selected distributions.
45
   * @{
46
   */
47
 
48
  /*
49
   * Implementation-space details.
50
   */
51
  namespace __detail
52
  {
53
    template<typename _UIntType, int __w,
54
             bool = __w < std::numeric_limits<_UIntType>::digits>
55
      struct _Shift
56
      { static const _UIntType __value = 0; };
57
 
58
    template<typename _UIntType, int __w>
59
      struct _Shift<_UIntType, __w, true>
60
      { static const _UIntType __value = _UIntType(1) << __w; };
61
 
62
    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
63
      struct _Mod;
64
 
65
    // Dispatch based on modulus value to prevent divide-by-zero compile-time
66
    // errors when m == 0.
67
    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
68
      inline _Tp
69
      __mod(_Tp __x)
70
      { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
71
 
72
    typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
73
                    unsigned, unsigned long>::__type _UInt32Type;
74
 
75
    /*
76
     * An adaptor class for converting the output of any Generator into
77
     * the input for a specific Distribution.
78
     */
79
    template<typename _Engine, typename _Distribution>
80
      struct _Adaptor
81
      {
82
        typedef typename remove_reference<_Engine>::type _BEngine;
83
        typedef typename _BEngine::result_type           _Engine_result_type;
84
        typedef typename _Distribution::input_type       result_type;
85
 
86
      public:
87
        _Adaptor(const _Engine& __g)
88
        : _M_g(__g) { }
89
 
90
        result_type
91
        min() const
92
        {
93
          result_type __return_value;
94
          if (is_integral<_Engine_result_type>::value
95
              && is_integral<result_type>::value)
96
            __return_value = _M_g.min();
97
          else
98
            __return_value = result_type(0);
99
          return __return_value;
100
        }
101
 
102
        result_type
103
        max() const
104
        {
105
          result_type __return_value;
106
          if (is_integral<_Engine_result_type>::value
107
              && is_integral<result_type>::value)
108
            __return_value = _M_g.max();
109
          else if (!is_integral<result_type>::value)
110
            __return_value = result_type(1);
111
          else
112
            __return_value = std::numeric_limits<result_type>::max() - 1;
113
          return __return_value;
114
        }
115
 
116
        /*
117
         * Converts a value generated by the adapted random number generator
118
         * into a value in the input domain for the dependent random number
119
         * distribution.
120
         *
121
         * Because the type traits are compile time constants only the
122
         * appropriate clause of the if statements will actually be emitted
123
         * by the compiler.
124
         */
125
        result_type
126
        operator()()
127
        {
128
          result_type __return_value;
129
          if (is_integral<_Engine_result_type>::value
130
              && is_integral<result_type>::value)
131
            __return_value = _M_g();
132
          else if (!is_integral<_Engine_result_type>::value
133
                   && !is_integral<result_type>::value)
134
            __return_value = result_type(_M_g() - _M_g.min())
135
              / result_type(_M_g.max() - _M_g.min());
136
          else if (is_integral<_Engine_result_type>::value
137
                   && !is_integral<result_type>::value)
138
            __return_value = result_type(_M_g() - _M_g.min())
139
              / result_type(_M_g.max() - _M_g.min() + result_type(1));
140
          else
141
            __return_value = (((_M_g() - _M_g.min())
142
                               / (_M_g.max() - _M_g.min()))
143
                              * std::numeric_limits<result_type>::max());
144
          return __return_value;
145
        }
146
 
147
      private:
148
        _Engine _M_g;
149
      };
150
 
151
    // Specialization for _Engine*.
152
    template<typename _Engine, typename _Distribution>
153
      struct _Adaptor<_Engine*, _Distribution>
154
      {
155
        typedef typename _Engine::result_type      _Engine_result_type;
156
        typedef typename _Distribution::input_type result_type;
157
 
158
      public:
159
        _Adaptor(_Engine* __g)
160
        : _M_g(__g) { }
161
 
162
        result_type
163
        min() const
164
        {
165
          result_type __return_value;
166
          if (is_integral<_Engine_result_type>::value
167
              && is_integral<result_type>::value)
168
            __return_value = _M_g->min();
169
          else
170
            __return_value = result_type(0);
171
          return __return_value;
172
        }
173
 
174
        result_type
175
        max() const
176
        {
177
          result_type __return_value;
178
          if (is_integral<_Engine_result_type>::value
179
              && is_integral<result_type>::value)
180
            __return_value = _M_g->max();
181
          else if (!is_integral<result_type>::value)
182
            __return_value = result_type(1);
183
          else
184
            __return_value = std::numeric_limits<result_type>::max() - 1;
185
          return __return_value;
186
        }
187
 
188
        result_type
189
        operator()()
190
        {
191
          result_type __return_value;
192
          if (is_integral<_Engine_result_type>::value
193
              && is_integral<result_type>::value)
194
            __return_value = (*_M_g)();
195
          else if (!is_integral<_Engine_result_type>::value
196
                   && !is_integral<result_type>::value)
197
            __return_value = result_type((*_M_g)() - _M_g->min())
198
              / result_type(_M_g->max() - _M_g->min());
199
          else if (is_integral<_Engine_result_type>::value
200
                   && !is_integral<result_type>::value)
201
            __return_value = result_type((*_M_g)() - _M_g->min())
202
              / result_type(_M_g->max() - _M_g->min() + result_type(1));
203
          else
204
            __return_value = ((((*_M_g)() - _M_g->min())
205
                               / (_M_g->max() - _M_g->min()))
206
                              * std::numeric_limits<result_type>::max());
207
          return __return_value;
208
        }
209
 
210
      private:
211
        _Engine* _M_g;
212
      };
213
  } // namespace __detail
214
 
215
  /**
216
   * Produces random numbers on a given distribution function using a
217
   * non-uniform random number generation engine.
218
   *
219
   * @todo the engine_value_type needs to be studied more carefully.
220
   */
221
  template<typename _Engine, typename _Dist>
222
    class variate_generator
223
    {
224
      // Concept requirements.
225
      __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
226
      //  __glibcxx_class_requires(_Engine, _EngineConcept)
227
      //  __glibcxx_class_requires(_Dist, _EngineConcept)
228
 
229
    public:
230
      typedef _Engine                                engine_type;
231
      typedef __detail::_Adaptor<_Engine, _Dist>     engine_value_type;
232
      typedef _Dist                                  distribution_type;
233
      typedef typename _Dist::result_type            result_type;
234
 
235
      // tr1:5.1.1 table 5.1 requirement
236
      typedef typename __gnu_cxx::__enable_if<
237
        is_arithmetic<result_type>::value, result_type>::__type _IsValidType;
238
 
239
      /**
240
       * Constructs a variate generator with the uniform random number
241
       * generator @p __eng for the random distribution @p __dist.
242
       *
243
       * @throws Any exceptions which may thrown by the copy constructors of
244
       * the @p _Engine or @p _Dist objects.
245
       */
246
      variate_generator(engine_type __eng, distribution_type __dist)
247
      : _M_engine(__eng), _M_dist(__dist) { }
248
 
249
      /**
250
       * Gets the next generated value on the distribution.
251
       */
252
      result_type
253
      operator()()
254
      { return _M_dist(_M_engine); }
255
 
256
      /**
257
       * WTF?
258
       */
259
      template<typename _Tp>
260
        result_type
261
        operator()(_Tp __value)
262
        { return _M_dist(_M_engine, __value); }
263
 
264
      /**
265
       * Gets a reference to the underlying uniform random number generator
266
       * object.
267
       */
268
      engine_value_type&
269
      engine()
270
      { return _M_engine; }
271
 
272
      /**
273
       * Gets a const reference to the underlying uniform random number
274
       * generator object.
275
       */
276
      const engine_value_type&
277
      engine() const
278
      { return _M_engine; }
279
 
280
      /**
281
       * Gets a reference to the underlying random distribution.
282
       */
283
      distribution_type&
284
      distribution()
285
      { return _M_dist; }
286
 
287
      /**
288
       * Gets a const reference to the underlying random distribution.
289
       */
290
      const distribution_type&
291
      distribution() const
292
      { return _M_dist; }
293
 
294
      /**
295
       * Gets the closed lower bound of the distribution interval.
296
       */
297
      result_type
298
      min() const
299
      { return this->distribution().min(); }
300
 
301
      /**
302
       * Gets the closed upper bound of the distribution interval.
303
       */
304
      result_type
305
      max() const
306
      { return this->distribution().max(); }
307
 
308
    private:
309
      engine_value_type _M_engine;
310
      distribution_type _M_dist;
311
    };
312
 
313
 
314
  /**
315
   * @addtogroup tr1_random_generators Random Number Generators
316
   * @ingroup tr1_random
317
   *
318
   * These classes define objects which provide random or pseudorandom
319
   * numbers, either from a discrete or a continuous interval.  The
320
   * random number generator supplied as a part of this library are
321
   * all uniform random number generators which provide a sequence of
322
   * random number uniformly distributed over their range.
323
   *
324
   * A number generator is a function object with an operator() that
325
   * takes zero arguments and returns a number.
326
   *
327
   * A compliant random number generator must satisfy the following
328
   * requirements.  <table border=1 cellpadding=10 cellspacing=0>
329
   * <caption align=top>Random Number Generator Requirements</caption>
330
   * <tr><td>To be documented.</td></tr> </table>
331
   *
332
   * @{
333
   */
334
 
335
  /**
336
   * @brief A model of a linear congruential random number generator.
337
   *
338
   * A random number generator that produces pseudorandom numbers using the
339
   * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
340
   *
341
   * The template parameter @p _UIntType must be an unsigned integral type
342
   * large enough to store values up to (__m-1). If the template parameter
343
   * @p __m is 0, the modulus @p __m used is
344
   * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
345
   * parameters @p __a and @p __c must be less than @p __m.
346
   *
347
   * The size of the state is @f$ 1 @f$.
348
   */
349
  template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
350
    class linear_congruential
351
    {
352
      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
353
      //  __glibcpp_class_requires(__a < __m && __c < __m)
354
 
355
    public:
356
      /** The type of the generated random value. */
357
      typedef _UIntType result_type;
358
 
359
      /** The multiplier. */
360
      static const _UIntType multiplier = __a;
361
      /** An increment. */
362
      static const _UIntType increment = __c;
363
      /** The modulus. */
364
      static const _UIntType modulus = __m;
365
 
366
      /**
367
       * Constructs a %linear_congruential random number generator engine with
368
       * seed @p __s.  The default seed value is 1.
369
       *
370
       * @param __s The initial seed value.
371
       */
372
      explicit
373
      linear_congruential(unsigned long __x0 = 1)
374
      { this->seed(__x0); }
375
 
376
      /**
377
       * Constructs a %linear_congruential random number generator engine
378
       * seeded from the generator function @p __g.
379
       *
380
       * @param __g The seed generator function.
381
       */
382
      template<class _Gen>
383
        linear_congruential(_Gen& __g)
384
        { this->seed(__g); }
385
 
386
      /**
387
       * Reseeds the %linear_congruential random number generator engine
388
       * sequence to the seed @g __s.
389
       *
390
       * @param __s The new seed.
391
       */
392
      void
393
      seed(unsigned long __s = 1);
394
 
395
      /**
396
       * Reseeds the %linear_congruential random number generator engine
397
       * sequence using values from the generator function @p __g.
398
       *
399
       * @param __g the seed generator function.
400
       */
401
      template<class _Gen>
402
        void
403
        seed(_Gen& __g)
404
        { seed(__g, typename is_fundamental<_Gen>::type()); }
405
 
406
      /**
407
       * Gets the smallest possible value in the output range.
408
       *
409
       * The minimum depends on the @p __c parameter: if it is zero, the
410
       * minimum generated must be > 0, otherwise 0 is allowed.
411
       */
412
      result_type
413
      min() const
414
      { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
415
 
416
      /**
417
       * Gets the largest possible value in the output range.
418
       */
419
      result_type
420
      max() const
421
      { return __m - 1; }
422
 
423
      /**
424
       * Gets the next random number in the sequence.
425
       */
426
      result_type
427
      operator()();
428
 
429
      /**
430
       * Compares two linear congruential random number generator
431
       * objects of the same type for equality.
432
       *
433
       * @param __lhs A linear congruential random number generator object.
434
       * @param __rhs Another linear congruential random number generator obj.
435
       *
436
       * @returns true if the two objects are equal, false otherwise.
437
       */
438
      friend bool
439
      operator==(const linear_congruential& __lhs,
440
                 const linear_congruential& __rhs)
441
      { return __lhs._M_x == __rhs._M_x; }
442
 
443
      /**
444
       * Compares two linear congruential random number generator
445
       * objects of the same type for inequality.
446
       *
447
       * @param __lhs A linear congruential random number generator object.
448
       * @param __rhs Another linear congruential random number generator obj.
449
       *
450
       * @returns true if the two objects are not equal, false otherwise.
451
       */
452
      friend bool
453
      operator!=(const linear_congruential& __lhs,
454
                 const linear_congruential& __rhs)
455
      { return !(__lhs == __rhs); }
456
 
457
      /**
458
       * Writes the textual representation of the state x(i) of x to @p __os.
459
       *
460
       * @param __os  The output stream.
461
       * @param __lcr A % linear_congruential random number generator.
462
       * @returns __os.
463
       */
464
      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
465
               _UIntType1 __m1,
466
               typename _CharT, typename _Traits>
467
        friend std::basic_ostream<_CharT, _Traits>&
468
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
469
                   const linear_congruential<_UIntType1, __a1, __c1,
470
                   __m1>& __lcr);
471
 
472
      /**
473
       * Sets the state of the engine by reading its textual
474
       * representation from @p __is.
475
       *
476
       * The textual representation must have been previously written using an
477
       * output stream whose imbued locale and whose type's template
478
       * specialization arguments _CharT and _Traits were the same as those of
479
       * @p __is.
480
       *
481
       * @param __is  The input stream.
482
       * @param __lcr A % linear_congruential random number generator.
483
       * @returns __is.
484
       */
485
      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
486
               _UIntType1 __m1,
487
               typename _CharT, typename _Traits>
488
        friend std::basic_istream<_CharT, _Traits>&
489
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
490
                   linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);
491
 
492
    private:
493
      template<class _Gen>
494
        void
495
        seed(_Gen& __g, true_type)
496
        { return seed(static_cast<unsigned long>(__g)); }
497
 
498
      template<class _Gen>
499
        void
500
        seed(_Gen& __g, false_type);
501
 
502
      _UIntType _M_x;
503
    };
504
 
505
  /**
506
   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
507
   */
508
  typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;
509
 
510
  /**
511
   * An alternative LCR (Lehmer Generator function) .
512
   */
513
  typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
514
 
515
 
516
  /**
517
   * A generalized feedback shift register discrete random number generator.
518
   *
519
   * This algorithm avoids multiplication and division and is designed to be
520
   * friendly to a pipelined architecture.  If the parameters are chosen
521
   * correctly, this generator will produce numbers with a very long period and
522
   * fairly good apparent entropy, although still not cryptographically strong.
523
   *
524
   * The best way to use this generator is with the predefined mt19937 class.
525
   *
526
   * This algorithm was originally invented by Makoto Matsumoto and
527
   * Takuji Nishimura.
528
   *
529
   * @var word_size   The number of bits in each element of the state vector.
530
   * @var state_size  The degree of recursion.
531
   * @var shift_size  The period parameter.
532
   * @var mask_bits   The separation point bit index.
533
   * @var parameter_a The last row of the twist matrix.
534
   * @var output_u    The first right-shift tempering matrix parameter.
535
   * @var output_s    The first left-shift tempering matrix parameter.
536
   * @var output_b    The first left-shift tempering matrix mask.
537
   * @var output_t    The second left-shift tempering matrix parameter.
538
   * @var output_c    The second left-shift tempering matrix mask.
539
   * @var output_l    The second right-shift tempering matrix parameter.
540
   */
541
  template<class _UIntType, int __w, int __n, int __m, int __r,
542
           _UIntType __a, int __u, int __s, _UIntType __b, int __t,
543
           _UIntType __c, int __l>
544
    class mersenne_twister
545
    {
546
      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
547
 
548
    public:
549
      // types
550
      typedef _UIntType result_type;
551
 
552
      // parameter values
553
      static const int       word_size   = __w;
554
      static const int       state_size  = __n;
555
      static const int       shift_size  = __m;
556
      static const int       mask_bits   = __r;
557
      static const _UIntType parameter_a = __a;
558
      static const int       output_u    = __u;
559
      static const int       output_s    = __s;
560
      static const _UIntType output_b    = __b;
561
      static const int       output_t    = __t;
562
      static const _UIntType output_c    = __c;
563
      static const int       output_l    = __l;
564
 
565
      // constructors and member function
566
      mersenne_twister()
567
      { seed(); }
568
 
569
      explicit
570
      mersenne_twister(unsigned long __value)
571
      { seed(__value); }
572
 
573
      template<class _Gen>
574
        mersenne_twister(_Gen& __g)
575
        { seed(__g); }
576
 
577
      void
578
      seed()
579
      { seed(5489UL); }
580
 
581
      void
582
      seed(unsigned long __value);
583
 
584
      template<class _Gen>
585
        void
586
        seed(_Gen& __g)
587
        { seed(__g, typename is_fundamental<_Gen>::type()); }
588
 
589
      result_type
590
      min() const
591
      { return 0; };
592
 
593
      result_type
594
      max() const
595
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }
596
 
597
      result_type
598
      operator()();
599
 
600
      /**
601
       * Compares two % mersenne_twister random number generator objects of
602
       * the same type for equality.
603
       *
604
       * @param __lhs A % mersenne_twister random number generator object.
605
       * @param __rhs Another % mersenne_twister random number generator
606
       *              object.
607
       *
608
       * @returns true if the two objects are equal, false otherwise.
609
       */
610
      friend bool
611
      operator==(const mersenne_twister& __lhs,
612
                 const mersenne_twister& __rhs)
613
      { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
614
 
615
      /**
616
       * Compares two % mersenne_twister random number generator objects of
617
       * the same type for inequality.
618
       *
619
       * @param __lhs A % mersenne_twister random number generator object.
620
       * @param __rhs Another % mersenne_twister random number generator
621
       *              object.
622
       *
623
       * @returns true if the two objects are not equal, false otherwise.
624
       */
625
      friend bool
626
      operator!=(const mersenne_twister& __lhs,
627
                 const mersenne_twister& __rhs)
628
      { return !(__lhs == __rhs); }
629
 
630
      /**
631
       * Inserts the current state of a % mersenne_twister random number
632
       * generator engine @p __x into the output stream @p __os.
633
       *
634
       * @param __os An output stream.
635
       * @param __x  A % mersenne_twister random number generator engine.
636
       *
637
       * @returns The output stream with the state of @p __x inserted or in
638
       * an error state.
639
       */
640
      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
641
               _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
642
               _UIntType1 __c1, int __l1,
643
               typename _CharT, typename _Traits>
644
        friend std::basic_ostream<_CharT, _Traits>&
645
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
646
                   const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
647
                   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
648
 
649
      /**
650
       * Extracts the current state of a % mersenne_twister random number
651
       * generator engine @p __x from the input stream @p __is.
652
       *
653
       * @param __is An input stream.
654
       * @param __x  A % mersenne_twister random number generator engine.
655
       *
656
       * @returns The input stream with the state of @p __x extracted or in
657
       * an error state.
658
       */
659
      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
660
               _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
661
               _UIntType1 __c1, int __l1,
662
               typename _CharT, typename _Traits>
663
        friend std::basic_istream<_CharT, _Traits>&
664
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
665
                   mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
666
                   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
667
 
668
    private:
669
      template<class _Gen>
670
        void
671
        seed(_Gen& __g, true_type)
672
        { return seed(static_cast<unsigned long>(__g)); }
673
 
674
      template<class _Gen>
675
        void
676
        seed(_Gen& __g, false_type);
677
 
678
      _UIntType _M_x[state_size];
679
      int       _M_p;
680
    };
681
 
682
  /**
683
   * The classic Mersenne Twister.
684
   *
685
   * Reference:
686
   * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
687
   * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
688
   * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
689
   */
690
  typedef mersenne_twister<
691
    unsigned long, 32, 624, 397, 31,
692
    0x9908b0dful, 11, 7,
693
    0x9d2c5680ul, 15,
694
    0xefc60000ul, 18
695
    > mt19937;
696
 
697
 
698
  /**
699
   * @brief The Marsaglia-Zaman generator.
700
   *
701
   * This is a model of a Generalized Fibonacci discrete random number
702
   * generator, sometimes referred to as the SWC generator.
703
   *
704
   * A discrete random number generator that produces pseudorandom
705
   * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
706
   * carry_{i-1}) \bmod m @f$.
707
   *
708
   * The size of the state is @f$ r @f$
709
   * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
710
   *
711
   * N1688[4.13] says <em>the template parameter _IntType shall denote
712
   * an integral type large enough to store values up to m</em>.
713
   *
714
   * @var _M_x     The state of the generator.  This is a ring buffer.
715
   * @var _M_carry The carry.
716
   * @var _M_p     Current index of x(i - r).
717
   */
718
  template<typename _IntType, _IntType __m, int __s, int __r>
719
    class subtract_with_carry
720
    {
721
      __glibcxx_class_requires(_IntType, _IntegerConcept)
722
 
723
    public:
724
      /** The type of the generated random value. */
725
      typedef _IntType result_type;
726
 
727
      // parameter values
728
      static const _IntType modulus   = __m;
729
      static const int      long_lag  = __r;
730
      static const int      short_lag = __s;
731
 
732
      /**
733
       * Constructs a default-initialized % subtract_with_carry random number
734
       * generator.
735
       */
736
      subtract_with_carry()
737
      { this->seed(); }
738
 
739
      /**
740
       * Constructs an explicitly seeded % subtract_with_carry random number
741
       * generator.
742
       */
743
      explicit
744
      subtract_with_carry(unsigned long __value)
745
      { this->seed(__value); }
746
 
747
      /**
748
       * Constructs a %subtract_with_carry random number generator engine
749
       * seeded from the generator function @p __g.
750
       *
751
       * @param __g The seed generator function.
752
       */
753
      template<class _Gen>
754
        subtract_with_carry(_Gen& __g)
755
        { this->seed(__g); }
756
 
757
      /**
758
       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
759
       *
760
       * N1688[4.19] modifies this as follows.  If @p __value == 0,
761
       * sets value to 19780503.  In any case, with a linear
762
       * congruential generator lcg(i) having parameters @f$ m_{lcg} =
763
       * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
764
       * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
765
       * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
766
       * set carry to 1, otherwise sets carry to 0.
767
       */
768
      void
769
      seed(unsigned long __value = 19780503);
770
 
771
      /**
772
       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
773
       * random number generator.
774
       */
775
      template<class _Gen>
776
        void
777
        seed(_Gen& __g)
778
        { seed(__g, typename is_fundamental<_Gen>::type()); }
779
 
780
      /**
781
       * Gets the inclusive minimum value of the range of random integers
782
       * returned by this generator.
783
       */
784
      result_type
785
      min() const
786
      { return 0; }
787
 
788
      /**
789
       * Gets the inclusive maximum value of the range of random integers
790
       * returned by this generator.
791
       */
792
      result_type
793
      max() const
794
      { return this->modulus - 1; }
795
 
796
      /**
797
       * Gets the next random number in the sequence.
798
       */
799
      result_type
800
      operator()();
801
 
802
      /**
803
       * Compares two % subtract_with_carry random number generator objects of
804
       * the same type for equality.
805
       *
806
       * @param __lhs A % subtract_with_carry random number generator object.
807
       * @param __rhs Another % subtract_with_carry random number generator
808
       *              object.
809
       *
810
       * @returns true if the two objects are equal, false otherwise.
811
       */
812
      friend bool
813
      operator==(const subtract_with_carry& __lhs,
814
                 const subtract_with_carry& __rhs)
815
      { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
816
 
817
      /**
818
       * Compares two % subtract_with_carry random number generator objects of
819
       * the same type for inequality.
820
       *
821
       * @param __lhs A % subtract_with_carry random number generator object.
822
       * @param __rhs Another % subtract_with_carry random number generator
823
       *              object.
824
       *
825
       * @returns true if the two objects are not equal, false otherwise.
826
       */
827
      friend bool
828
      operator!=(const subtract_with_carry& __lhs,
829
                 const subtract_with_carry& __rhs)
830
      { return !(__lhs == __rhs); }
831
 
832
      /**
833
       * Inserts the current state of a % subtract_with_carry random number
834
       * generator engine @p __x into the output stream @p __os.
835
       *
836
       * @param __os An output stream.
837
       * @param __x  A % subtract_with_carry random number generator engine.
838
       *
839
       * @returns The output stream with the state of @p __x inserted or in
840
       * an error state.
841
       */
842
      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
843
               typename _CharT, typename _Traits>
844
        friend std::basic_ostream<_CharT, _Traits>&
845
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
846
                   const subtract_with_carry<_IntType1, __m1, __s1,
847
                   __r1>& __x);
848
 
849
      /**
850
       * Extracts the current state of a % subtract_with_carry random number
851
       * generator engine @p __x from the input stream @p __is.
852
       *
853
       * @param __is An input stream.
854
       * @param __x  A % subtract_with_carry random number generator engine.
855
       *
856
       * @returns The input stream with the state of @p __x extracted or in
857
       * an error state.
858
       */
859
      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
860
               typename _CharT, typename _Traits>
861
        friend std::basic_istream<_CharT, _Traits>&
862
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
863
                   subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);
864
 
865
    private:
866
      template<class _Gen>
867
        void
868
        seed(_Gen& __g, true_type)
869
        { return seed(static_cast<unsigned long>(__g)); }
870
 
871
      template<class _Gen>
872
        void
873
        seed(_Gen& __g, false_type);
874
 
875
      typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;
876
 
877
      _UIntType  _M_x[long_lag];
878
      _UIntType  _M_carry;
879
      int        _M_p;
880
    };
881
 
882
 
883
  /**
884
   * @brief The Marsaglia-Zaman generator (floats version).
885
   *
886
   * @var _M_x     The state of the generator.  This is a ring buffer.
887
   * @var _M_carry The carry.
888
   * @var _M_p     Current index of x(i - r).
889
   * @var _M_npows Precomputed negative powers of 2.
890
   */
891
  template<typename _RealType, int __w, int __s, int __r>
892
    class subtract_with_carry_01
893
    {
894
    public:
895
      /** The type of the generated random value. */
896
      typedef _RealType result_type;
897
 
898
      // parameter values
899
      static const int      word_size = __w;
900
      static const int      long_lag  = __r;
901
      static const int      short_lag = __s;
902
 
903
      /**
904
       * Constructs a default-initialized % subtract_with_carry_01 random
905
       * number generator.
906
       */
907
      subtract_with_carry_01()
908
      {
909
        this->seed();
910
        _M_initialize_npows();
911
      }
912
 
913
      /**
914
       * Constructs an explicitly seeded % subtract_with_carry_01 random number
915
       * generator.
916
       */
917
      explicit
918
      subtract_with_carry_01(unsigned long __value)
919
      {
920
        this->seed(__value);
921
        _M_initialize_npows();
922
      }
923
 
924
      /**
925
       * Constructs a % subtract_with_carry_01 random number generator engine
926
       * seeded from the generator function @p __g.
927
       *
928
       * @param __g The seed generator function.
929
       */
930
      template<class _Gen>
931
        subtract_with_carry_01(_Gen& __g)
932
        {
933
          this->seed(__g);
934
          _M_initialize_npows();
935
        }
936
 
937
      /**
938
       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
939
       */
940
      void
941
      seed(unsigned long __value = 19780503);
942
 
943
      /**
944
       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
945
       * random number generator.
946
       */
947
      template<class _Gen>
948
        void
949
        seed(_Gen& __g)
950
        { seed(__g, typename is_fundamental<_Gen>::type()); }
951
 
952
      /**
953
       * Gets the minimum value of the range of random floats
954
       * returned by this generator.
955
       */
956
      result_type
957
      min() const
958
      { return 0.0; }
959
 
960
      /**
961
       * Gets the maximum value of the range of random floats
962
       * returned by this generator.
963
       */
964
      result_type
965
      max() const
966
      { return 1.0; }
967
 
968
      /**
969
       * Gets the next random number in the sequence.
970
       */
971
      result_type
972
      operator()();
973
 
974
      /**
975
       * Compares two % subtract_with_carry_01 random number generator objects
976
       * of the same type for equality.
977
       *
978
       * @param __lhs A % subtract_with_carry_01 random number
979
       *              generator object.
980
       * @param __rhs Another % subtract_with_carry_01 random number generator
981
       *              object.
982
       *
983
       * @returns true if the two objects are equal, false otherwise.
984
       */
985
      friend bool
986
      operator==(const subtract_with_carry_01& __lhs,
987
                 const subtract_with_carry_01& __rhs)
988
      {
989
        for (int __i = 0; __i < long_lag; ++__i)
990
          if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
991
                          __rhs._M_x[__i]))
992
            return false;
993
        return true;
994
      }
995
 
996
      /**
997
       * Compares two % subtract_with_carry_01 random number generator objects
998
       * of the same type for inequality.
999
       *
1000
       * @param __lhs A % subtract_with_carry_01 random number
1001
       *              generator object.
1002
       *
1003
       * @param __rhs Another % subtract_with_carry_01 random number generator
1004
       *              object.
1005
       *
1006
       * @returns true if the two objects are not equal, false otherwise.
1007
       */
1008
      friend bool
1009
      operator!=(const subtract_with_carry_01& __lhs,
1010
                 const subtract_with_carry_01& __rhs)
1011
      { return !(__lhs == __rhs); }
1012
 
1013
      /**
1014
       * Inserts the current state of a % subtract_with_carry_01 random number
1015
       * generator engine @p __x into the output stream @p __os.
1016
       *
1017
       * @param __os An output stream.
1018
       * @param __x  A % subtract_with_carry_01 random number generator engine.
1019
       *
1020
       * @returns The output stream with the state of @p __x inserted or in
1021
       * an error state.
1022
       */
1023
      template<typename _RealType1, int __w1, int __s1, int __r1,
1024
               typename _CharT, typename _Traits>
1025
        friend std::basic_ostream<_CharT, _Traits>&
1026
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1027
                   const subtract_with_carry_01<_RealType1, __w1, __s1,
1028
                   __r1>& __x);
1029
 
1030
      /**
1031
       * Extracts the current state of a % subtract_with_carry_01 random number
1032
       * generator engine @p __x from the input stream @p __is.
1033
       *
1034
       * @param __is An input stream.
1035
       * @param __x  A % subtract_with_carry_01 random number generator engine.
1036
       *
1037
       * @returns The input stream with the state of @p __x extracted or in
1038
       * an error state.
1039
       */
1040
      template<typename _RealType1, int __w1, int __s1, int __r1,
1041
               typename _CharT, typename _Traits>
1042
        friend std::basic_istream<_CharT, _Traits>&
1043
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1044
                   subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);
1045
 
1046
    private:
1047
      template<class _Gen>
1048
        void
1049
        seed(_Gen& __g, true_type)
1050
        { return seed(static_cast<unsigned long>(__g)); }
1051
 
1052
      template<class _Gen>
1053
        void
1054
        seed(_Gen& __g, false_type);
1055
 
1056
      void
1057
      _M_initialize_npows();
1058
 
1059
      static const int __n = (__w + 31) / 32;
1060
 
1061
      typedef __detail::_UInt32Type _UInt32Type;
1062
      _UInt32Type  _M_x[long_lag][__n];
1063
      _RealType    _M_npows[__n];
1064
      _UInt32Type  _M_carry;
1065
      int          _M_p;
1066
    };
1067
 
1068
  typedef subtract_with_carry_01<float, 24, 10, 24>   ranlux_base_01;
1069
 
1070
  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1071
  // 508. Bad parameters for ranlux64_base_01.
1072
  typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;
1073
 
1074
 
1075
  /**
1076
   * Produces random numbers from some base engine by discarding blocks of
1077
   * data.
1078
   *
1079
   * 0 <= @p __r <= @p __p
1080
   */
1081
  template<class _UniformRandomNumberGenerator, int __p, int __r>
1082
    class discard_block
1083
    {
1084
      // __glibcxx_class_requires(typename base_type::result_type,
1085
      //                          ArithmeticTypeConcept)
1086
 
1087
    public:
1088
      /** The type of the underlying generator engine. */
1089
      typedef _UniformRandomNumberGenerator   base_type;
1090
      /** The type of the generated random value. */
1091
      typedef typename base_type::result_type result_type;
1092
 
1093
      // parameter values
1094
      static const int block_size = __p;
1095
      static const int used_block = __r;
1096
 
1097
      /**
1098
       * Constructs a default %discard_block engine.
1099
       *
1100
       * The underlying engine is default constructed as well.
1101
       */
1102
      discard_block()
1103
      : _M_n(0) { }
1104
 
1105
      /**
1106
       * Copy constructs a %discard_block engine.
1107
       *
1108
       * Copies an existing base class random number generator.
1109
       * @param rng An existing (base class) engine object.
1110
       */
1111
      explicit
1112
      discard_block(const base_type& __rng)
1113
      : _M_b(__rng), _M_n(0) { }
1114
 
1115
      /**
1116
       * Seed constructs a %discard_block engine.
1117
       *
1118
       * Constructs the underlying generator engine seeded with @p __s.
1119
       * @param __s A seed value for the base class engine.
1120
       */
1121
      explicit
1122
      discard_block(unsigned long __s)
1123
      : _M_b(__s), _M_n(0) { }
1124
 
1125
      /**
1126
       * Generator construct a %discard_block engine.
1127
       *
1128
       * @param __g A seed generator function.
1129
       */
1130
      template<class _Gen>
1131
        discard_block(_Gen& __g)
1132
        : _M_b(__g), _M_n(0) { }
1133
 
1134
      /**
1135
       * Reseeds the %discard_block object with the default seed for the
1136
       * underlying base class generator engine.
1137
       */
1138
      void seed()
1139
      {
1140
        _M_b.seed();
1141
        _M_n = 0;
1142
      }
1143
 
1144
      /**
1145
       * Reseeds the %discard_block object with the given seed generator
1146
       * function.
1147
       * @param __g A seed generator function.
1148
       */
1149
      template<class _Gen>
1150
        void seed(_Gen& __g)
1151
        {
1152
          _M_b.seed(__g);
1153
          _M_n = 0;
1154
        }
1155
 
1156
      /**
1157
       * Gets a const reference to the underlying generator engine object.
1158
       */
1159
      const base_type&
1160
      base() const
1161
      { return _M_b; }
1162
 
1163
      /**
1164
       * Gets the minimum value in the generated random number range.
1165
       */
1166
      result_type
1167
      min() const
1168
      { return _M_b.min(); }
1169
 
1170
      /**
1171
       * Gets the maximum value in the generated random number range.
1172
       */
1173
      result_type
1174
      max() const
1175
      { return _M_b.max(); }
1176
 
1177
      /**
1178
       * Gets the next value in the generated random number sequence.
1179
       */
1180
      result_type
1181
      operator()();
1182
 
1183
      /**
1184
       * Compares two %discard_block random number generator objects of
1185
       * the same type for equality.
1186
       *
1187
       * @param __lhs A %discard_block random number generator object.
1188
       * @param __rhs Another %discard_block random number generator
1189
       *              object.
1190
       *
1191
       * @returns true if the two objects are equal, false otherwise.
1192
       */
1193
      friend bool
1194
      operator==(const discard_block& __lhs, const discard_block& __rhs)
1195
      { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }
1196
 
1197
      /**
1198
       * Compares two %discard_block random number generator objects of
1199
       * the same type for inequality.
1200
       *
1201
       * @param __lhs A %discard_block random number generator object.
1202
       * @param __rhs Another %discard_block random number generator
1203
       *              object.
1204
       *
1205
       * @returns true if the two objects are not equal, false otherwise.
1206
       */
1207
      friend bool
1208
      operator!=(const discard_block& __lhs, const discard_block& __rhs)
1209
      { return !(__lhs == __rhs); }
1210
 
1211
      /**
1212
       * Inserts the current state of a %discard_block random number
1213
       * generator engine @p __x into the output stream @p __os.
1214
       *
1215
       * @param __os An output stream.
1216
       * @param __x  A %discard_block random number generator engine.
1217
       *
1218
       * @returns The output stream with the state of @p __x inserted or in
1219
       * an error state.
1220
       */
1221
      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1222
               typename _CharT, typename _Traits>
1223
        friend std::basic_ostream<_CharT, _Traits>&
1224
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1225
                   const discard_block<_UniformRandomNumberGenerator1,
1226
                   __p1, __r1>& __x);
1227
 
1228
      /**
1229
       * Extracts the current state of a % subtract_with_carry random number
1230
       * generator engine @p __x from the input stream @p __is.
1231
       *
1232
       * @param __is An input stream.
1233
       * @param __x  A %discard_block random number generator engine.
1234
       *
1235
       * @returns The input stream with the state of @p __x extracted or in
1236
       * an error state.
1237
       */
1238
      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
1239
               typename _CharT, typename _Traits>
1240
        friend std::basic_istream<_CharT, _Traits>&
1241
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1242
                   discard_block<_UniformRandomNumberGenerator1,
1243
                   __p1, __r1>& __x);
1244
 
1245
    private:
1246
      base_type _M_b;
1247
      int       _M_n;
1248
    };
1249
 
1250
 
1251
  /**
1252
   * James's luxury-level-3 integer adaptation of Luescher's generator.
1253
   */
1254
  typedef discard_block<
1255
    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1256
      223,
1257
      24
1258
      > ranlux3;
1259
 
1260
  /**
1261
   * James's luxury-level-4 integer adaptation of Luescher's generator.
1262
   */
1263
  typedef discard_block<
1264
    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
1265
      389,
1266
      24
1267
      > ranlux4;
1268
 
1269
  typedef discard_block<
1270
    subtract_with_carry_01<float, 24, 10, 24>,
1271
      223,
1272
      24
1273
      > ranlux3_01;
1274
 
1275
  typedef discard_block<
1276
    subtract_with_carry_01<float, 24, 10, 24>,
1277
      389,
1278
      24
1279
      > ranlux4_01;
1280
 
1281
 
1282
  /**
1283
   * A random number generator adaptor class that combines two random number
1284
   * generator engines into a single output sequence.
1285
   */
1286
  template<class _UniformRandomNumberGenerator1, int __s1,
1287
           class _UniformRandomNumberGenerator2, int __s2>
1288
    class xor_combine
1289
    {
1290
      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
1291
      //                          result_type, ArithmeticTypeConcept)
1292
      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
1293
      //                          result_type, ArithmeticTypeConcept)
1294
 
1295
    public:
1296
      /** The type of the first underlying generator engine. */
1297
      typedef _UniformRandomNumberGenerator1   base1_type;
1298
      /** The type of the second underlying generator engine. */
1299
      typedef _UniformRandomNumberGenerator2   base2_type;
1300
 
1301
    private:
1302
      typedef typename base1_type::result_type _Result_type1;
1303
      typedef typename base2_type::result_type _Result_type2;
1304
 
1305
    public:
1306
      /** The type of the generated random value. */
1307
      typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
1308
                                                      > sizeof(_Result_type2)),
1309
        _Result_type1, _Result_type2>::__type result_type;
1310
 
1311
      // parameter values
1312
      static const int shift1 = __s1;
1313
      static const int shift2 = __s2;
1314
 
1315
      // constructors and member function
1316
      xor_combine()
1317
      : _M_b1(), _M_b2()
1318
      { _M_initialize_max(); }
1319
 
1320
      xor_combine(const base1_type& __rng1, const base2_type& __rng2)
1321
      : _M_b1(__rng1), _M_b2(__rng2)
1322
      { _M_initialize_max(); }
1323
 
1324
      xor_combine(unsigned long __s)
1325
      : _M_b1(__s), _M_b2(__s + 1)
1326
      { _M_initialize_max(); }
1327
 
1328
      template<class _Gen>
1329
        xor_combine(_Gen& __g)
1330
        : _M_b1(__g), _M_b2(__g)
1331
        { _M_initialize_max(); }
1332
 
1333
      void
1334
      seed()
1335
      {
1336
        _M_b1.seed();
1337
        _M_b2.seed();
1338
      }
1339
 
1340
      template<class _Gen>
1341
        void
1342
        seed(_Gen& __g)
1343
        {
1344
          _M_b1.seed(__g);
1345
          _M_b2.seed(__g);
1346
        }
1347
 
1348
      const base1_type&
1349
      base1() const
1350
      { return _M_b1; }
1351
 
1352
      const base2_type&
1353
      base2() const
1354
      { return _M_b2; }
1355
 
1356
      result_type
1357
      min() const
1358
      { return 0; }
1359
 
1360
      result_type
1361
      max() const
1362
      { return _M_max; }
1363
 
1364
      /**
1365
       * Gets the next random number in the sequence.
1366
       */
1367
      // NB: Not exactly the TR1 formula, per N2079 instead.
1368
      result_type
1369
      operator()()
1370
      {
1371
        return ((result_type(_M_b1() - _M_b1.min()) << shift1)
1372
                ^ (result_type(_M_b2() - _M_b2.min()) << shift2));
1373
      }
1374
 
1375
      /**
1376
       * Compares two %xor_combine random number generator objects of
1377
       * the same type for equality.
1378
       *
1379
       * @param __lhs A %xor_combine random number generator object.
1380
       * @param __rhs Another %xor_combine random number generator
1381
       *              object.
1382
       *
1383
       * @returns true if the two objects are equal, false otherwise.
1384
       */
1385
      friend bool
1386
      operator==(const xor_combine& __lhs, const xor_combine& __rhs)
1387
      {
1388
        return (__lhs.base1() == __rhs.base1())
1389
                && (__lhs.base2() == __rhs.base2());
1390
      }
1391
 
1392
      /**
1393
       * Compares two %xor_combine random number generator objects of
1394
       * the same type for inequality.
1395
       *
1396
       * @param __lhs A %xor_combine random number generator object.
1397
       * @param __rhs Another %xor_combine random number generator
1398
       *              object.
1399
       *
1400
       * @returns true if the two objects are not equal, false otherwise.
1401
       */
1402
      friend bool
1403
      operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
1404
      { return !(__lhs == __rhs); }
1405
 
1406
      /**
1407
       * Inserts the current state of a %xor_combine random number
1408
       * generator engine @p __x into the output stream @p __os.
1409
       *
1410
       * @param __os An output stream.
1411
       * @param __x  A %xor_combine random number generator engine.
1412
       *
1413
       * @returns The output stream with the state of @p __x inserted or in
1414
       * an error state.
1415
       */
1416
      template<class _UniformRandomNumberGenerator11, int __s11,
1417
               class _UniformRandomNumberGenerator21, int __s21,
1418
               typename _CharT, typename _Traits>
1419
        friend std::basic_ostream<_CharT, _Traits>&
1420
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1421
                   const xor_combine<_UniformRandomNumberGenerator11, __s11,
1422
                   _UniformRandomNumberGenerator21, __s21>& __x);
1423
 
1424
      /**
1425
       * Extracts the current state of a %xor_combine random number
1426
       * generator engine @p __x from the input stream @p __is.
1427
       *
1428
       * @param __is An input stream.
1429
       * @param __x  A %xor_combine random number generator engine.
1430
       *
1431
       * @returns The input stream with the state of @p __x extracted or in
1432
       * an error state.
1433
       */
1434
      template<class _UniformRandomNumberGenerator11, int __s11,
1435
               class _UniformRandomNumberGenerator21, int __s21,
1436
               typename _CharT, typename _Traits>
1437
        friend std::basic_istream<_CharT, _Traits>&
1438
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1439
                   xor_combine<_UniformRandomNumberGenerator11, __s11,
1440
                   _UniformRandomNumberGenerator21, __s21>& __x);
1441
 
1442
    private:
1443
      void
1444
      _M_initialize_max();
1445
 
1446
      result_type
1447
      _M_initialize_max_aux(result_type, result_type, int);
1448
 
1449
      base1_type  _M_b1;
1450
      base2_type  _M_b2;
1451
      result_type _M_max;
1452
    };
1453
 
1454
 
1455
  /**
1456
   * A standard interface to a platform-specific non-deterministic
1457
   * random number generator (if any are available).
1458
   */
1459
  class random_device
1460
  {
1461
  public:
1462
    // types
1463
    typedef unsigned int result_type;
1464
 
1465
    // constructors, destructors and member functions
1466
 
1467
#ifdef _GLIBCXX_USE_RANDOM_TR1
1468
 
1469
    explicit
1470
    random_device(const std::string& __token = "/dev/urandom")
1471
    {
1472
      if ((__token != "/dev/urandom" && __token != "/dev/random")
1473
          || !(_M_file = std::fopen(__token.c_str(), "rb")))
1474
        std::__throw_runtime_error(__N("random_device::"
1475
                                       "random_device(const std::string&)"));
1476
    }
1477
 
1478
    ~random_device()
1479
    { std::fclose(_M_file); }
1480
 
1481
#else
1482
 
1483
    explicit
1484
    random_device(const std::string& __token = "mt19937")
1485
    : _M_mt(_M_strtoul(__token)) { }
1486
 
1487
  private:
1488
    static unsigned long
1489
    _M_strtoul(const std::string& __str)
1490
    {
1491
      unsigned long __ret = 5489UL;
1492
      if (__str != "mt19937")
1493
        {
1494
          const char* __nptr = __str.c_str();
1495
          char* __endptr;
1496
          __ret = std::strtoul(__nptr, &__endptr, 0);
1497
          if (*__nptr == '\0' || *__endptr != '\0')
1498
            std::__throw_runtime_error(__N("random_device::_M_strtoul"
1499
                                           "(const std::string&)"));
1500
        }
1501
      return __ret;
1502
    }
1503
 
1504
  public:
1505
 
1506
#endif
1507
 
1508
    result_type
1509
    min() const
1510
    { return std::numeric_limits<result_type>::min(); }
1511
 
1512
    result_type
1513
    max() const
1514
    { return std::numeric_limits<result_type>::max(); }
1515
 
1516
    double
1517
    entropy() const
1518
    { return 0.0; }
1519
 
1520
    result_type
1521
    operator()()
1522
    {
1523
#ifdef _GLIBCXX_USE_RANDOM_TR1
1524
      result_type __ret;
1525
      std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
1526
                 1, _M_file);
1527
      return __ret;
1528
#else
1529
      return _M_mt();
1530
#endif
1531
    }
1532
 
1533
  private:
1534
    random_device(const random_device&);
1535
    void operator=(const random_device&);
1536
 
1537
#ifdef _GLIBCXX_USE_RANDOM_TR1
1538
    FILE*        _M_file;
1539
#else
1540
    mt19937      _M_mt;
1541
#endif
1542
  };
1543
 
1544
  /* @} */ // group tr1_random_generators
1545
 
1546
  /**
1547
   * @addtogroup tr1_random_distributions Random Number Distributions
1548
   * @ingroup tr1_random
1549
   * @{
1550
   */
1551
 
1552
  /**
1553
   * @addtogroup tr1_random_distributions_discrete Discrete Distributions
1554
   * @ingroup tr1_random_distributions
1555
   * @{
1556
   */
1557
 
1558
  /**
1559
   * @brief Uniform discrete distribution for random numbers.
1560
   * A discrete random distribution on the range @f$[min, max]@f$ with equal
1561
   * probability throughout the range.
1562
   */
1563
  template<typename _IntType = int>
1564
    class uniform_int
1565
    {
1566
      __glibcxx_class_requires(_IntType, _IntegerConcept)
1567
 
1568
    public:
1569
      /** The type of the parameters of the distribution. */
1570
      typedef _IntType input_type;
1571
      /** The type of the range of the distribution. */
1572
      typedef _IntType result_type;
1573
 
1574
    public:
1575
      /**
1576
       * Constructs a uniform distribution object.
1577
       */
1578
      explicit
1579
      uniform_int(_IntType __min = 0, _IntType __max = 9)
1580
      : _M_min(__min), _M_max(__max)
1581
      {
1582
        _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
1583
      }
1584
 
1585
      /**
1586
       * Gets the inclusive lower bound of the distribution range.
1587
       */
1588
      result_type
1589
      min() const
1590
      { return _M_min; }
1591
 
1592
      /**
1593
       * Gets the inclusive upper bound of the distribution range.
1594
       */
1595
      result_type
1596
      max() const
1597
      { return _M_max; }
1598
 
1599
      /**
1600
       * Resets the distribution state.
1601
       *
1602
       * Does nothing for the uniform integer distribution.
1603
       */
1604
      void
1605
      reset() { }
1606
 
1607
      /**
1608
       * Gets a uniformly distributed random number in the range
1609
       * @f$(min, max)@f$.
1610
       */
1611
      template<typename _UniformRandomNumberGenerator>
1612
        result_type
1613
        operator()(_UniformRandomNumberGenerator& __urng)
1614
        {
1615
          typedef typename _UniformRandomNumberGenerator::result_type
1616
            _UResult_type;
1617
          return _M_call(__urng, _M_min, _M_max,
1618
                         typename is_integral<_UResult_type>::type());
1619
        }
1620
 
1621
      /**
1622
       * Gets a uniform random number in the range @f$[0, n)@f$.
1623
       *
1624
       * This function is aimed at use with std::random_shuffle.
1625
       */
1626
      template<typename _UniformRandomNumberGenerator>
1627
        result_type
1628
        operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
1629
        {
1630
          typedef typename _UniformRandomNumberGenerator::result_type
1631
            _UResult_type;
1632
          return _M_call(__urng, 0, __n - 1,
1633
                         typename is_integral<_UResult_type>::type());
1634
        }
1635
 
1636
      /**
1637
       * Inserts a %uniform_int random number distribution @p __x into the
1638
       * output stream @p os.
1639
       *
1640
       * @param __os An output stream.
1641
       * @param __x  A %uniform_int random number distribution.
1642
       *
1643
       * @returns The output stream with the state of @p __x inserted or in
1644
       * an error state.
1645
       */
1646
      template<typename _IntType1, typename _CharT, typename _Traits>
1647
        friend std::basic_ostream<_CharT, _Traits>&
1648
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1649
                   const uniform_int<_IntType1>& __x);
1650
 
1651
      /**
1652
       * Extracts a %uniform_int random number distribution
1653
       * @p __x from the input stream @p __is.
1654
       *
1655
       * @param __is An input stream.
1656
       * @param __x  A %uniform_int random number generator engine.
1657
       *
1658
       * @returns The input stream with @p __x extracted or in an error state.
1659
       */
1660
      template<typename _IntType1, typename _CharT, typename _Traits>
1661
        friend std::basic_istream<_CharT, _Traits>&
1662
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1663
                   uniform_int<_IntType1>& __x);
1664
 
1665
    private:
1666
      template<typename _UniformRandomNumberGenerator>
1667
        result_type
1668
        _M_call(_UniformRandomNumberGenerator& __urng,
1669
                result_type __min, result_type __max, true_type);
1670
 
1671
      template<typename _UniformRandomNumberGenerator>
1672
        result_type
1673
        _M_call(_UniformRandomNumberGenerator& __urng,
1674
                result_type __min, result_type __max, false_type)
1675
        {
1676
          return result_type((__urng() - __urng.min())
1677
                             / (__urng.max() - __urng.min())
1678
                             * (__max - __min + 1)) + __min;
1679
        }
1680
 
1681
      _IntType _M_min;
1682
      _IntType _M_max;
1683
    };
1684
 
1685
 
1686
  /**
1687
   * @brief A Bernoulli random number distribution.
1688
   *
1689
   * Generates a sequence of true and false values with likelihood @f$ p @f$
1690
   * that true will come up and @f$ (1 - p) @f$ that false will appear.
1691
   */
1692
  class bernoulli_distribution
1693
  {
1694
  public:
1695
    typedef int  input_type;
1696
    typedef bool result_type;
1697
 
1698
  public:
1699
    /**
1700
     * Constructs a Bernoulli distribution with likelihood @p p.
1701
     *
1702
     * @param __p  [IN]  The likelihood of a true result being returned.  Must
1703
     * be in the interval @f$ [0, 1] @f$.
1704
     */
1705
    explicit
1706
    bernoulli_distribution(double __p = 0.5)
1707
    : _M_p(__p)
1708
    {
1709
      _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
1710
    }
1711
 
1712
    /**
1713
     * Gets the @p p parameter of the distribution.
1714
     */
1715
    double
1716
    p() const
1717
    { return _M_p; }
1718
 
1719
    /**
1720
     * Resets the distribution state.
1721
     *
1722
     * Does nothing for a Bernoulli distribution.
1723
     */
1724
    void
1725
    reset() { }
1726
 
1727
    /**
1728
     * Gets the next value in the Bernoullian sequence.
1729
     */
1730
    template<class _UniformRandomNumberGenerator>
1731
      result_type
1732
      operator()(_UniformRandomNumberGenerator& __urng)
1733
      {
1734
        if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
1735
          return true;
1736
        return false;
1737
      }
1738
 
1739
    /**
1740
     * Inserts a %bernoulli_distribution random number distribution
1741
     * @p __x into the output stream @p __os.
1742
     *
1743
     * @param __os An output stream.
1744
     * @param __x  A %bernoulli_distribution random number distribution.
1745
     *
1746
     * @returns The output stream with the state of @p __x inserted or in
1747
     * an error state.
1748
     */
1749
    template<typename _CharT, typename _Traits>
1750
      friend std::basic_ostream<_CharT, _Traits>&
1751
      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1752
                 const bernoulli_distribution& __x);
1753
 
1754
    /**
1755
     * Extracts a %bernoulli_distribution random number distribution
1756
     * @p __x from the input stream @p __is.
1757
     *
1758
     * @param __is An input stream.
1759
     * @param __x  A %bernoulli_distribution random number generator engine.
1760
     *
1761
     * @returns The input stream with @p __x extracted or in an error state.
1762
     */
1763
    template<typename _CharT, typename _Traits>
1764
      friend std::basic_istream<_CharT, _Traits>&
1765
      operator>>(std::basic_istream<_CharT, _Traits>& __is,
1766
                 bernoulli_distribution& __x)
1767
      { return __is >> __x._M_p; }
1768
 
1769
  private:
1770
    double _M_p;
1771
  };
1772
 
1773
 
1774
  /**
1775
   * @brief A discrete geometric random number distribution.
1776
   *
1777
   * The formula for the geometric probability mass function is
1778
   * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
1779
   * distribution.
1780
   */
1781
  template<typename _IntType = int, typename _RealType = double>
1782
    class geometric_distribution
1783
    {
1784
    public:
1785
      // types
1786
      typedef _RealType input_type;
1787
      typedef _IntType  result_type;
1788
 
1789
      // constructors and member function
1790
      explicit
1791
      geometric_distribution(const _RealType& __p = _RealType(0.5))
1792
      : _M_p(__p)
1793
      {
1794
        _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
1795
        _M_initialize();
1796
      }
1797
 
1798
      /**
1799
       * Gets the distribution parameter @p p.
1800
       */
1801
      _RealType
1802
      p() const
1803
      { return _M_p; }
1804
 
1805
      void
1806
      reset() { }
1807
 
1808
      template<class _UniformRandomNumberGenerator>
1809
        result_type
1810
        operator()(_UniformRandomNumberGenerator& __urng);
1811
 
1812
      /**
1813
       * Inserts a %geometric_distribution random number distribution
1814
       * @p __x into the output stream @p __os.
1815
       *
1816
       * @param __os An output stream.
1817
       * @param __x  A %geometric_distribution random number distribution.
1818
       *
1819
       * @returns The output stream with the state of @p __x inserted or in
1820
       * an error state.
1821
       */
1822
      template<typename _IntType1, typename _RealType1,
1823
               typename _CharT, typename _Traits>
1824
        friend std::basic_ostream<_CharT, _Traits>&
1825
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1826
                   const geometric_distribution<_IntType1, _RealType1>& __x);
1827
 
1828
      /**
1829
       * Extracts a %geometric_distribution random number distribution
1830
       * @p __x from the input stream @p __is.
1831
       *
1832
       * @param __is An input stream.
1833
       * @param __x  A %geometric_distribution random number generator engine.
1834
       *
1835
       * @returns The input stream with @p __x extracted or in an error state.
1836
       */
1837
      template<typename _CharT, typename _Traits>
1838
        friend std::basic_istream<_CharT, _Traits>&
1839
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1840
                   geometric_distribution& __x)
1841
        {
1842
          __is >> __x._M_p;
1843
          __x._M_initialize();
1844
          return __is;
1845
        }
1846
 
1847
    private:
1848
      void
1849
      _M_initialize()
1850
      { _M_log_p = std::log(_M_p); }
1851
 
1852
      _RealType _M_p;
1853
      _RealType _M_log_p;
1854
    };
1855
 
1856
 
1857
  template<typename _RealType>
1858
    class normal_distribution;
1859
 
1860
  /**
1861
   * @brief A discrete Poisson random number distribution.
1862
   *
1863
   * The formula for the Poisson probability mass function is
1864
   * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
1865
   * parameter of the distribution.
1866
   */
1867
  template<typename _IntType = int, typename _RealType = double>
1868
    class poisson_distribution
1869
    {
1870
    public:
1871
      // types
1872
      typedef _RealType input_type;
1873
      typedef _IntType  result_type;
1874
 
1875
      // constructors and member function
1876
      explicit
1877
      poisson_distribution(const _RealType& __mean = _RealType(1))
1878
      : _M_mean(__mean), _M_nd()
1879
      {
1880
        _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
1881
        _M_initialize();
1882
      }
1883
 
1884
      /**
1885
       * Gets the distribution parameter @p mean.
1886
       */
1887
      _RealType
1888
      mean() const
1889
      { return _M_mean; }
1890
 
1891
      void
1892
      reset()
1893
      { _M_nd.reset(); }
1894
 
1895
      template<class _UniformRandomNumberGenerator>
1896
        result_type
1897
        operator()(_UniformRandomNumberGenerator& __urng);
1898
 
1899
      /**
1900
       * Inserts a %poisson_distribution random number distribution
1901
       * @p __x into the output stream @p __os.
1902
       *
1903
       * @param __os An output stream.
1904
       * @param __x  A %poisson_distribution random number distribution.
1905
       *
1906
       * @returns The output stream with the state of @p __x inserted or in
1907
       * an error state.
1908
       */
1909
      template<typename _IntType1, typename _RealType1,
1910
               typename _CharT, typename _Traits>
1911
        friend std::basic_ostream<_CharT, _Traits>&
1912
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1913
                   const poisson_distribution<_IntType1, _RealType1>& __x);
1914
 
1915
      /**
1916
       * Extracts a %poisson_distribution random number distribution
1917
       * @p __x from the input stream @p __is.
1918
       *
1919
       * @param __is An input stream.
1920
       * @param __x  A %poisson_distribution random number generator engine.
1921
       *
1922
       * @returns The input stream with @p __x extracted or in an error state.
1923
       */
1924
      template<typename _IntType1, typename _RealType1,
1925
               typename _CharT, typename _Traits>
1926
        friend std::basic_istream<_CharT, _Traits>&
1927
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
1928
                   poisson_distribution<_IntType1, _RealType1>& __x);
1929
 
1930
    private:
1931
      void
1932
      _M_initialize();
1933
 
1934
      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
1935
      normal_distribution<_RealType> _M_nd;
1936
 
1937
      _RealType _M_mean;
1938
 
1939
      // Hosts either log(mean) or the threshold of the simple method.
1940
      _RealType _M_lm_thr;
1941
#if _GLIBCXX_USE_C99_MATH_TR1
1942
      _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
1943
#endif
1944
    };
1945
 
1946
 
1947
  /**
1948
   * @brief A discrete binomial random number distribution.
1949
   *
1950
   * The formula for the binomial probability mass function is
1951
   * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
1952
   * and @f$ p @f$ are the parameters of the distribution.
1953
   */
1954
  template<typename _IntType = int, typename _RealType = double>
1955
    class binomial_distribution
1956
    {
1957
    public:
1958
      // types
1959
      typedef _RealType input_type;
1960
      typedef _IntType  result_type;
1961
 
1962
      // constructors and member function
1963
      explicit
1964
      binomial_distribution(_IntType __t = 1,
1965
                            const _RealType& __p = _RealType(0.5))
1966
      : _M_t(__t), _M_p(__p), _M_nd()
1967
      {
1968
        _GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
1969
        _M_initialize();
1970
      }
1971
 
1972
      /**
1973
       * Gets the distribution @p t parameter.
1974
       */
1975
      _IntType
1976
      t() const
1977
      { return _M_t; }
1978
 
1979
      /**
1980
       * Gets the distribution @p p parameter.
1981
       */
1982
      _RealType
1983
      p() const
1984
      { return _M_p; }
1985
 
1986
      void
1987
      reset()
1988
      { _M_nd.reset(); }
1989
 
1990
      template<class _UniformRandomNumberGenerator>
1991
        result_type
1992
        operator()(_UniformRandomNumberGenerator& __urng);
1993
 
1994
      /**
1995
       * Inserts a %binomial_distribution random number distribution
1996
       * @p __x into the output stream @p __os.
1997
       *
1998
       * @param __os An output stream.
1999
       * @param __x  A %binomial_distribution random number distribution.
2000
       *
2001
       * @returns The output stream with the state of @p __x inserted or in
2002
       * an error state.
2003
       */
2004
      template<typename _IntType1, typename _RealType1,
2005
               typename _CharT, typename _Traits>
2006
        friend std::basic_ostream<_CharT, _Traits>&
2007
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2008
                   const binomial_distribution<_IntType1, _RealType1>& __x);
2009
 
2010
      /**
2011
       * Extracts a %binomial_distribution random number distribution
2012
       * @p __x from the input stream @p __is.
2013
       *
2014
       * @param __is An input stream.
2015
       * @param __x  A %binomial_distribution random number generator engine.
2016
       *
2017
       * @returns The input stream with @p __x extracted or in an error state.
2018
       */
2019
      template<typename _IntType1, typename _RealType1,
2020
               typename _CharT, typename _Traits>
2021
        friend std::basic_istream<_CharT, _Traits>&
2022
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2023
                   binomial_distribution<_IntType1, _RealType1>& __x);
2024
 
2025
    private:
2026
      void
2027
      _M_initialize();
2028
 
2029
      template<class _UniformRandomNumberGenerator>
2030
        result_type
2031
        _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
2032
 
2033
      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
2034
      normal_distribution<_RealType> _M_nd;
2035
 
2036
      _RealType _M_q;
2037
#if _GLIBCXX_USE_C99_MATH_TR1
2038
      _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
2039
                _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
2040
#endif
2041
      _RealType _M_p;
2042
      _IntType  _M_t;
2043
 
2044
      bool      _M_easy;
2045
    };
2046
 
2047
  /* @} */ // group tr1_random_distributions_discrete
2048
 
2049
  /**
2050
   * @addtogroup tr1_random_distributions_continuous Continuous Distributions
2051
   * @ingroup tr1_random_distributions
2052
   * @{
2053
   */
2054
 
2055
  /**
2056
   * @brief Uniform continuous distribution for random numbers.
2057
   *
2058
   * A continuous random distribution on the range [min, max) with equal
2059
   * probability throughout the range.  The URNG should be real-valued and
2060
   * deliver number in the range [0, 1).
2061
   */
2062
  template<typename _RealType = double>
2063
    class uniform_real
2064
    {
2065
    public:
2066
      // types
2067
      typedef _RealType input_type;
2068
      typedef _RealType result_type;
2069
 
2070
    public:
2071
      /**
2072
       * Constructs a uniform_real object.
2073
       *
2074
       * @param __min [IN]  The lower bound of the distribution.
2075
       * @param __max [IN]  The upper bound of the distribution.
2076
       */
2077
      explicit
2078
      uniform_real(_RealType __min = _RealType(0),
2079
                   _RealType __max = _RealType(1))
2080
      : _M_min(__min), _M_max(__max)
2081
      {
2082
        _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
2083
      }
2084
 
2085
      result_type
2086
      min() const
2087
      { return _M_min; }
2088
 
2089
      result_type
2090
      max() const
2091
      { return _M_max; }
2092
 
2093
      void
2094
      reset() { }
2095
 
2096
      template<class _UniformRandomNumberGenerator>
2097
        result_type
2098
        operator()(_UniformRandomNumberGenerator& __urng)
2099
        { return (__urng() * (_M_max - _M_min)) + _M_min; }
2100
 
2101
      /**
2102
       * Inserts a %uniform_real random number distribution @p __x into the
2103
       * output stream @p __os.
2104
       *
2105
       * @param __os An output stream.
2106
       * @param __x  A %uniform_real random number distribution.
2107
       *
2108
       * @returns The output stream with the state of @p __x inserted or in
2109
       * an error state.
2110
       */
2111
      template<typename _RealType1, typename _CharT, typename _Traits>
2112
        friend std::basic_ostream<_CharT, _Traits>&
2113
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2114
                   const uniform_real<_RealType1>& __x);
2115
 
2116
      /**
2117
       * Extracts a %uniform_real random number distribution
2118
       * @p __x from the input stream @p __is.
2119
       *
2120
       * @param __is An input stream.
2121
       * @param __x  A %uniform_real random number generator engine.
2122
       *
2123
       * @returns The input stream with @p __x extracted or in an error state.
2124
       */
2125
      template<typename _RealType1, typename _CharT, typename _Traits>
2126
        friend std::basic_istream<_CharT, _Traits>&
2127
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2128
                   uniform_real<_RealType1>& __x);
2129
 
2130
    private:
2131
      _RealType _M_min;
2132
      _RealType _M_max;
2133
    };
2134
 
2135
 
2136
  /**
2137
   * @brief An exponential continuous distribution for random numbers.
2138
   *
2139
   * The formula for the exponential probability mass function is
2140
   * @f$ p(x) = \lambda e^{-\lambda x} @f$.
2141
   *
2142
   * <table border=1 cellpadding=10 cellspacing=0>
2143
   * <caption align=top>Distribution Statistics</caption>
2144
   * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2145
   * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
2146
   * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
2147
   * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
2148
   * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
2149
   * </table>
2150
   */
2151
  template<typename _RealType = double>
2152
    class exponential_distribution
2153
    {
2154
    public:
2155
      // types
2156
      typedef _RealType input_type;
2157
      typedef _RealType result_type;
2158
 
2159
    public:
2160
      /**
2161
       * Constructs an exponential distribution with inverse scale parameter
2162
       * @f$ \lambda @f$.
2163
       */
2164
      explicit
2165
      exponential_distribution(const result_type& __lambda = result_type(1))
2166
      : _M_lambda(__lambda)
2167
      {
2168
        _GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
2169
      }
2170
 
2171
      /**
2172
       * Gets the inverse scale parameter of the distribution.
2173
       */
2174
      _RealType
2175
      lambda() const
2176
      { return _M_lambda; }
2177
 
2178
      /**
2179
       * Resets the distribution.
2180
       *
2181
       * Has no effect on exponential distributions.
2182
       */
2183
      void
2184
      reset() { }
2185
 
2186
      template<class _UniformRandomNumberGenerator>
2187
        result_type
2188
        operator()(_UniformRandomNumberGenerator& __urng)
2189
        { return -std::log(__urng()) / _M_lambda; }
2190
 
2191
      /**
2192
       * Inserts a %exponential_distribution random number distribution
2193
       * @p __x into the output stream @p __os.
2194
       *
2195
       * @param __os An output stream.
2196
       * @param __x  A %exponential_distribution random number distribution.
2197
       *
2198
       * @returns The output stream with the state of @p __x inserted or in
2199
       * an error state.
2200
       */
2201
      template<typename _RealType1, typename _CharT, typename _Traits>
2202
        friend std::basic_ostream<_CharT, _Traits>&
2203
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2204
                   const exponential_distribution<_RealType1>& __x);
2205
 
2206
      /**
2207
       * Extracts a %exponential_distribution random number distribution
2208
       * @p __x from the input stream @p __is.
2209
       *
2210
       * @param __is An input stream.
2211
       * @param __x A %exponential_distribution random number
2212
       *            generator engine.
2213
       *
2214
       * @returns The input stream with @p __x extracted or in an error state.
2215
       */
2216
      template<typename _CharT, typename _Traits>
2217
        friend std::basic_istream<_CharT, _Traits>&
2218
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2219
                   exponential_distribution& __x)
2220
        { return __is >> __x._M_lambda; }
2221
 
2222
    private:
2223
      result_type _M_lambda;
2224
    };
2225
 
2226
 
2227
  /**
2228
   * @brief A normal continuous distribution for random numbers.
2229
   *
2230
   * The formula for the normal probability mass function is
2231
   * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}}
2232
   *            e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
2233
   */
2234
  template<typename _RealType = double>
2235
    class normal_distribution
2236
    {
2237
    public:
2238
      // types
2239
      typedef _RealType input_type;
2240
      typedef _RealType result_type;
2241
 
2242
    public:
2243
      /**
2244
       * Constructs a normal distribution with parameters @f$ mean @f$ and
2245
       * @f$ \sigma @f$.
2246
       */
2247
      explicit
2248
      normal_distribution(const result_type& __mean = result_type(0),
2249
                          const result_type& __sigma = result_type(1))
2250
      : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
2251
      {
2252
        _GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
2253
      }
2254
 
2255
      /**
2256
       * Gets the mean of the distribution.
2257
       */
2258
      _RealType
2259
      mean() const
2260
      { return _M_mean; }
2261
 
2262
      /**
2263
       * Gets the @f$ \sigma @f$ of the distribution.
2264
       */
2265
      _RealType
2266
      sigma() const
2267
      { return _M_sigma; }
2268
 
2269
      /**
2270
       * Resets the distribution.
2271
       */
2272
      void
2273
      reset()
2274
      { _M_saved_available = false; }
2275
 
2276
      template<class _UniformRandomNumberGenerator>
2277
        result_type
2278
        operator()(_UniformRandomNumberGenerator& __urng);
2279
 
2280
      /**
2281
       * Inserts a %normal_distribution random number distribution
2282
       * @p __x into the output stream @p __os.
2283
       *
2284
       * @param __os An output stream.
2285
       * @param __x  A %normal_distribution random number distribution.
2286
       *
2287
       * @returns The output stream with the state of @p __x inserted or in
2288
       * an error state.
2289
       */
2290
      template<typename _RealType1, typename _CharT, typename _Traits>
2291
        friend std::basic_ostream<_CharT, _Traits>&
2292
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2293
                   const normal_distribution<_RealType1>& __x);
2294
 
2295
      /**
2296
       * Extracts a %normal_distribution random number distribution
2297
       * @p __x from the input stream @p __is.
2298
       *
2299
       * @param __is An input stream.
2300
       * @param __x  A %normal_distribution random number generator engine.
2301
       *
2302
       * @returns The input stream with @p __x extracted or in an error state.
2303
       */
2304
      template<typename _RealType1, typename _CharT, typename _Traits>
2305
        friend std::basic_istream<_CharT, _Traits>&
2306
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2307
                   normal_distribution<_RealType1>& __x);
2308
 
2309
    private:
2310
      result_type _M_mean;
2311
      result_type _M_sigma;
2312
      result_type _M_saved;
2313
      bool        _M_saved_available;
2314
    };
2315
 
2316
 
2317
  /**
2318
   * @brief A gamma continuous distribution for random numbers.
2319
   *
2320
   * The formula for the gamma probability mass function is
2321
   * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
2322
   */
2323
  template<typename _RealType = double>
2324
    class gamma_distribution
2325
    {
2326
    public:
2327
      // types
2328
      typedef _RealType input_type;
2329
      typedef _RealType result_type;
2330
 
2331
    public:
2332
      /**
2333
       * Constructs a gamma distribution with parameters @f$ \alpha @f$.
2334
       */
2335
      explicit
2336
      gamma_distribution(const result_type& __alpha_val = result_type(1))
2337
      : _M_alpha(__alpha_val)
2338
      {
2339
        _GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
2340
        _M_initialize();
2341
      }
2342
 
2343
      /**
2344
       * Gets the @f$ \alpha @f$ of the distribution.
2345
       */
2346
      _RealType
2347
      alpha() const
2348
      { return _M_alpha; }
2349
 
2350
      /**
2351
       * Resets the distribution.
2352
       */
2353
      void
2354
      reset() { }
2355
 
2356
      template<class _UniformRandomNumberGenerator>
2357
        result_type
2358
        operator()(_UniformRandomNumberGenerator& __urng);
2359
 
2360
      /**
2361
       * Inserts a %gamma_distribution random number distribution
2362
       * @p __x into the output stream @p __os.
2363
       *
2364
       * @param __os An output stream.
2365
       * @param __x  A %gamma_distribution random number distribution.
2366
       *
2367
       * @returns The output stream with the state of @p __x inserted or in
2368
       * an error state.
2369
       */
2370
      template<typename _RealType1, typename _CharT, typename _Traits>
2371
        friend std::basic_ostream<_CharT, _Traits>&
2372
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2373
                   const gamma_distribution<_RealType1>& __x);
2374
 
2375
      /**
2376
       * Extracts a %gamma_distribution random number distribution
2377
       * @p __x from the input stream @p __is.
2378
       *
2379
       * @param __is An input stream.
2380
       * @param __x  A %gamma_distribution random number generator engine.
2381
       *
2382
       * @returns The input stream with @p __x extracted or in an error state.
2383
       */
2384
      template<typename _CharT, typename _Traits>
2385
        friend std::basic_istream<_CharT, _Traits>&
2386
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
2387
                   gamma_distribution& __x)
2388
        {
2389
          __is >> __x._M_alpha;
2390
          __x._M_initialize();
2391
          return __is;
2392
        }
2393
 
2394
    private:
2395
      void
2396
      _M_initialize();
2397
 
2398
      result_type _M_alpha;
2399
 
2400
      // Hosts either lambda of GB or d of modified Vaduva's.
2401
      result_type _M_l_d;
2402
    };
2403
 
2404
  /* @} */ // group tr1_random_distributions_continuous
2405
  /* @} */ // group tr1_random_distributions
2406
  /* @} */ // group tr1_random
2407
}
2408
}
2409
 
2410
#endif // _GLIBCXX_TR1_RANDOM_H

powered by: WebSVN 2.1.0

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