]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/tr1/random
libgcc.S: Correct my wrong previous commit.
[thirdparty/gcc.git] / libstdc++-v3 / include / tr1 / random
CommitLineData
86ad0dd6
PC
1// random number generation -*- C++ -*-
2
3// Copyright (C) 2006 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 2, 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// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING. If not, write to the Free
18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction. Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License. This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30#ifndef _STD_TR1_RANDOM
31#define _STD_TR1_RANDOM 1
32
33/**
34 * @file
35 * This is a TR1 C++ Library header.
36 */
37
38#include <algorithm>
39#include <bits/concept_check.h>
40#include <bits/cpp_type_traits.h>
41#include <cmath>
42#include <debug/debug.h>
43#include <iterator>
44#include <iosfwd>
45#include <limits>
46#include <tr1/type_traits>
d8bc9819 47#include <fstream>
86ad0dd6
PC
48
49namespace std
50{
51_GLIBCXX_BEGIN_NAMESPACE(tr1)
52
53 // [5.1] Random number generation
54
55 /**
56 * @addtogroup tr1_random Random Number Generation
57 * A facility for generating random numbers on selected distributions.
58 * @{
59 */
60
61 /*
62 * Implementation-space details.
63 */
64 namespace _Private
65 {
281864aa 66 // Type selectors -- are these already implemented elsewhere?
86ad0dd6
PC
67 template<bool, typename _TpTrue, typename _TpFalse>
68 struct _Select
69 {
281864aa 70 typedef _TpTrue _Type;
86ad0dd6
PC
71 };
72
73 template<typename _TpTrue, typename _TpFalse>
74 struct _Select<false, _TpTrue, _TpFalse>
75 {
281864aa 76 typedef _TpFalse _Type;
86ad0dd6
PC
77 };
78
79 /*
80 * An adaptor class for converting the output of any Generator into
81 * the input for a specific Distribution.
82 */
83 template<typename _Generator, typename _Distribution>
84 struct _Adaptor
85 {
86 typedef typename _Generator::result_type generated_type;
87 typedef typename _Distribution::input_type result_type;
88
89 public:
90 _Adaptor(const _Generator& __g)
91 : _M_g(__g) { }
92
93 result_type
94 operator()();
95
96 private:
97 _Generator _M_g;
98 };
99
100 /*
281864aa 101 * Converts a value generated by the adapted random number generator into a
86ad0dd6
PC
102 * value in the input domain for the dependent random number distribution.
103 *
104 * Because the type traits are compile time constants only the appropriate
105 * clause of the if statements will actually be emitted by the compiler.
106 */
107 template<typename _Generator, typename _Distribution>
108 typename _Adaptor<_Generator, _Distribution>::result_type
109 _Adaptor<_Generator, _Distribution>::
110 operator()()
111 {
112 result_type __return_value = 0;
113 if (is_integral<generated_type>::value
114 && is_integral<result_type>::value)
115 __return_value = _M_g();
116 else if (is_integral<generated_type>::value
117 && !is_integral<result_type>::value)
118 __return_value = result_type(_M_g())
119 / result_type(_M_g.max() - _M_g.min() + 1);
120 else if (!is_integral<generated_type>::value
121 && !is_integral<result_type>::value)
122 __return_value = result_type(_M_g())
123 / result_type(_M_g.max() - _M_g.min());
124 return __return_value;
125 }
126
127 } // namespace std::tr1::_Private
128
129
130 /**
131 * Produces random numbers on a given disribution function using a un uniform
132 * random number generation engine.
133 *
134 * @todo the engine_value_type needs to be studied more carefully.
135 */
136 template<typename _Generator, typename _Dist>
137 class variate_generator
138 {
139 // Concept requirements.
140 __glibcxx_class_requires(_Generator, _CopyConstructibleConcept)
141 // __glibcxx_class_requires(_Generator, _GeneratorConcept)
142 // __glibcxx_class_requires(_Dist, _GeneratorConcept)
143
144 public:
145 typedef _Generator engine_type;
146 typedef _Private::_Adaptor<_Generator, _Dist> engine_value_type;
147 typedef _Dist distribution_type;
148 typedef typename _Dist::result_type result_type;
149
150 // tr1:5.1.1 table 5.1 requirement
151 typedef typename std::__enable_if<result_type,
152 is_arithmetic<result_type>::value
153 >::__type _IsValidType;
154
155 public:
156 /**
157 * Constructs a variate generator with the uniform random number
281864aa 158 * generator @p __eng for the random distribution @p __dist.
86ad0dd6 159 *
281864aa
PC
160 * @throws Any exceptions which may thrown by the copy constructors of
161 * the @p _Generator or @p _Dist objects.
86ad0dd6
PC
162 */
163 variate_generator(engine_type __eng, distribution_type __dist)
164 : _M_engine(__eng), _M_dist(__dist) { }
165
166 /**
167 * Gets the next generated value on the distribution.
168 */
169 result_type
170 operator()();
171
172 template<typename _Tp>
173 result_type
174 operator()(_Tp __value);
175
176 /**
177 * Gets a reference to the underlying uniform random number generator
178 * object.
179 */
180 engine_value_type&
181 engine()
182 { return _M_engine; }
183
184 /**
185 * Gets a const reference to the underlying uniform random number
186 * generator object.
187 */
188 const engine_value_type&
189 engine() const
190 { return _M_engine; }
191
192 /**
193 * Gets a reference to the underlying random distribution.
194 */
195 distribution_type&
196 distribution()
197 { return _M_dist; }
198
199 /**
200 * Gets a const reference to the underlying random distribution.
201 */
202 const distribution_type&
203 distribution() const
204 { return _M_dist; }
205
206 /**
207 * Gets the closed lower bound of the distribution interval.
208 */
209 result_type
210 min() const
211 { return this->distribution().min(); }
212
213 /**
214 * Gets the closed upper bound of the distribution interval.
215 */
216 result_type
217 max() const
218 { return this->distribution().max(); }
219
220 private:
221 engine_value_type _M_engine;
222 distribution_type _M_dist;
223 };
224
225 /**
226 * Gets the next random value on the given distribution.
227 */
228 template<typename _Generator, typename _Dist>
229 typename variate_generator<_Generator, _Dist>::result_type
230 variate_generator<_Generator, _Dist>::
231 operator()()
232 { return _M_dist(_M_engine); }
233
234 /**
235 * WTF?
236 */
237 template<typename _Generator, typename _Dist>
238 template<typename _Tp>
239 typename variate_generator<_Generator, _Dist>::result_type
240 variate_generator<_Generator, _Dist>::
241 operator()(_Tp __value)
242 { return _M_dist(_M_engine, __value); }
243
244
245 /**
246 * @addtogroup tr1_random_generators Random Number Generators
247 * @ingroup tr1_random
248 *
249 * These classes define objects which provide random or pseudorandom numbers,
250 * either from a discrete or a continuous interval. The random number
251 * generator supplied as a part of this library are all uniform random number
252 * generators which provide a sequence of random number uniformly distributed
253 * over their range.
254 *
255 * A number generator is a function object with an operator() that takes zero
256 * arguments and returns a number.
257 *
258 * A compliant random number generator must satisy the following requirements.
259 * <table border=1 cellpadding=10 cellspacing=0>
260 * <caption align=top>Random Number Generator Requirements</caption>
261 * <tr><td>To be documented.</td></tr>
262 * </table>
263 *
264 * @{
265 */
266
267 /**
268 * @brief A model of a linear congruential random number generator.
269 *
270 * A random number generator that produces pseudorandom numbers using the
271 * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
272 *
281864aa
PC
273 * The template parameter @p _UIntType must be an unsigned integral type
274 * large enough to store values up to (__m-1). If the template parameter
275 * @p __m is 0, the modulus @p __m used is
276 * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
277 * parameters @p __a and @p __c must be less than @p __m.
86ad0dd6
PC
278 *
279 * The size of the state is @f$ 1 @f$.
280 */
281864aa 281 template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
86ad0dd6
PC
282 class linear_congruential
283 {
281864aa
PC
284 __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
285 // __glibcpp_class_requires(__a < __m && __c < __m)
86ad0dd6
PC
286
287 public:
288 /** The type of the generated random value. */
281864aa 289 typedef _UIntType result_type;
86ad0dd6
PC
290
291 /** The multiplier. */
281864aa 292 static const _UIntType multiplier = __a;
86ad0dd6 293 /** An increment. */
281864aa 294 static const _UIntType increment = __c;
86ad0dd6 295 /** The modulus. */
281864aa 296 static const _UIntType modulus = __m;
86ad0dd6
PC
297
298 /**
299 * Constructs a %linear_congruential random number generator engine with
281864aa 300 * seed @p __s. The default seed value is 1.
86ad0dd6 301 *
281864aa 302 * @param __s The initial seed value.
86ad0dd6 303 */
281864aa 304 explicit linear_congruential(unsigned long __s = 1);
86ad0dd6
PC
305
306 /**
307 * Constructs a %linear_congruential random number generator engine
281864aa 308 * seeded from the generator function @p __g.
86ad0dd6 309 *
281864aa 310 * @param __g The seed generator function.
86ad0dd6 311 */
281864aa
PC
312 template<class _Gen>
313 linear_congruential(_Gen& __g);
86ad0dd6
PC
314
315 /**
281864aa
PC
316 * Reseeds the %linear_congruential random number generator engine
317 * sequence to the seed @g __s.
86ad0dd6 318 *
281864aa 319 * @param __s The new seed.
86ad0dd6
PC
320 */
321 void
281864aa 322 seed(unsigned long __s = 1);
86ad0dd6
PC
323
324 /**
281864aa
PC
325 * Reseeds the %linear_congruential random number generator engine
326 * sequence using values from the generator function @p __g.
86ad0dd6 327 *
281864aa 328 * @param __g the seed generator function.
86ad0dd6 329 */
281864aa 330 template<class _Gen>
86ad0dd6 331 void
281864aa
PC
332 seed(_Gen& __g)
333 { seed(__g, typename is_fundamental<_Gen>::type()); }
86ad0dd6
PC
334
335 /**
336 * Gets the smallest possible value in the output range.
337 */
338 result_type
339 min() const;
340
341 /**
342 * Gets the largest possible value in the output range.
343 */
344 result_type
345 max() const;
346
347 /**
348 * Gets the next random number in the sequence.
349 */
350 result_type
351 operator()();
352
353 /**
354 * Compares two linear congruential random number generator objects of the
355 * same type for equality.
356 *
281864aa
PC
357 * @param __lhs A linear congruential random number generator object.
358 * @param __rhs Another linear congruential random number generator obj.
86ad0dd6
PC
359 *
360 * @returns true if the two objects are equal, false otherwise.
361 */
362 friend bool
281864aa
PC
363 operator==(const linear_congruential& __lhs,
364 const linear_congruential& __rhs)
365 { return __lhs._M_x == __rhs._M_x; }
86ad0dd6
PC
366
367 /**
368 * Compares two linear congruential random number generator objects of the
369 * same type for inequality.
370 *
281864aa
PC
371 * @param __lhs A linear congruential random number generator object.
372 * @param __rhs Another linear congruential random number generator obj.
86ad0dd6
PC
373 *
374 * @returns true if the two objects are not equal, false otherwise.
375 */
376 friend bool
281864aa
PC
377 operator!=(const linear_congruential& __lhs,
378 const linear_congruential& __rhs)
379 { return !(__lhs == __rhs); }
86ad0dd6
PC
380
381 /**
281864aa 382 * Writes the textual representation of the state x(i) of x to @p __os.
86ad0dd6 383 *
281864aa
PC
384 * @param __os The output stream.
385 * @param __lcr A linear_congruential random number generator.
386 * @returns __os.
86ad0dd6 387 */
281864aa
PC
388 template<typename _CharT, typename _Traits>
389 friend std::basic_ostream<_CharT, _Traits>&
390 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
391 const linear_congruential& __lcr)
392 { return __os << __lcr._M_x; }
86ad0dd6
PC
393
394 /**
395 * Sets the state of the engine by reading its textual
281864aa 396 * representation from @p __is.
86ad0dd6
PC
397 *
398 * The textual representation must have been previously written using an
399 * output stream whose imbued locale and whose type's template
281864aa
PC
400 * specialization arguments _CharT and _Traits were the same as those of
401 * @p __is.
86ad0dd6 402 *
281864aa
PC
403 * @param __is The input stream.
404 * @param __lcr A linear_congruential random number generator.
405 * @returns __is.
86ad0dd6 406 */
281864aa
PC
407 template<typename _CharT, typename _Traits>
408 friend std::basic_istream<_CharT, _Traits>&
409 operator>>(std::basic_istream<_CharT, _Traits>& __is,
410 linear_congruential& __lcr)
411 { return __is >> __lcr._M_x; }
86ad0dd6
PC
412
413 private:
281864aa 414 template<class _Gen>
86ad0dd6 415 void
281864aa
PC
416 seed(_Gen& __g, true_type)
417 { return seed(static_cast<unsigned long>(__g)); }
86ad0dd6 418
281864aa 419 template<class _Gen>
86ad0dd6 420 void
281864aa 421 seed(_Gen& __g, false_type);
86ad0dd6
PC
422
423 private:
281864aa 424 _UIntType _M_x;
86ad0dd6
PC
425 };
426
427 /**
428 * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
429 */
430 typedef linear_congruential<unsigned int, 16807, 0, 2147483647> minstd_rand0;
431
432 /**
433 * An alternative LCR (Lehmer Generator function) .
434 */
435 typedef linear_congruential<unsigned int, 48271, 0, 2147483647> minstd_rand;
436
437
438 /**
439 * A generalized feedback shift register discrete random number generator.
440 *
441 * This algorithm avoind multiplication and division and is designed to be
442 * friendly to a pipelined architecture. If the parameters are chosen
443 * correctly, this generator will produce numbers with a very long period and
444 * fairly good apparent entropy, although still not cryptographically strong.
445 *
446 * The best way to use this generator is with the predefined mt19937 class.
447 *
448 * This algorithm was originally invented by Makoto Matsumoto and
449 * Takuji Nishimura.
450 *
451 * @var word_size The number of bits in each element of the state vector.
452 * @var state_size The degree of recursion.
453 * @var shift_size The period parameter.
454 * @var mask_bits The separation point bit index.
455 * @var parameter_a The last row of the twist matrix.
456 * @var output_u The first right-shift tempering matrix parameter.
457 * @var output_s The first left-shift tempering matrix parameter.
458 * @var output_b The first left-shift tempering matrix mask.
459 * @var output_t The second left-shift tempering matrix parameter.
460 * @var output_c The second left-shift tempering matrix mask.
461 * @var output_l The second right-shift tempering matrix parameter.
462 */
281864aa
PC
463 template<class _UIntType, int __w, int __n, int __m, int __r,
464 _UIntType __a, int __u, int __s, _UIntType __b, int __t,
465 _UIntType __c, int __l>
86ad0dd6
PC
466 class mersenne_twister
467 {
281864aa 468 __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
86ad0dd6
PC
469
470 public:
471 // types
281864aa 472 typedef _UIntType result_type ;
86ad0dd6
PC
473
474 // parameter values
281864aa
PC
475 static const int word_size = __w;
476 static const int state_size = __n;
477 static const int shift_size = __m;
478 static const int mask_bits = __r;
479 static const _UIntType parameter_a = __a;
480 static const int output_u = __u;
481 static const int output_s = __s;
482 static const _UIntType output_b = __b;
483 static const int output_t = __t;
484 static const _UIntType output_c = __c;
485 static const int output_l = __l;
86ad0dd6
PC
486
487 // constructors and member function
488 mersenne_twister()
489 { seed(); }
490
491 explicit
281864aa
PC
492 mersenne_twister(unsigned long __value)
493 { seed(__value); }
86ad0dd6 494
281864aa
PC
495 template<class _Gen>
496 mersenne_twister(_Gen& __g)
497 { seed(__g); }
86ad0dd6
PC
498
499 void
500 seed()
36ac3ed6 501 { seed(5489UL); }
86ad0dd6
PC
502
503 void
281864aa 504 seed(unsigned long __value);
86ad0dd6 505
281864aa 506 template<class _Gen>
86ad0dd6 507 void
281864aa
PC
508 seed(_Gen& __g)
509 { seed(__g, typename is_fundamental<_Gen>::type()); }
86ad0dd6
PC
510
511 result_type
512 min() const
513 { return 0; };
514
515 result_type
516 max() const;
517
518 result_type
519 operator()();
520
d95c1c48
PC
521 /**
522 * Compares two % mersenne_twister random number generator objects of
523 * the same type for equality.
524 *
525 * @param __lhs A % mersenne_twister random number generator object.
526 * @param __rhs Another % mersenne_twister random number generator
527 * object.
528 *
529 * @returns true if the two objects are equal, false otherwise.
530 */
531 friend bool
532 operator==(const mersenne_twister& __lhs,
533 const mersenne_twister& __rhs)
534 { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
535
536 /**
537 * Compares two % mersenne_twister random number generator objects of
538 * the same type for inequality.
539 *
540 * @param __lhs A % mersenne_twister random number generator object.
541 * @param __rhs Another % mersenne_twister random number generator
542 * object.
543 *
544 * @returns true if the two objects are not equal, false otherwise.
545 */
546 friend bool
547 operator!=(const mersenne_twister& __lhs,
548 const mersenne_twister& __rhs)
549 { return !(__lhs == __rhs); }
550
551 /**
552 * Inserts the current state of a % mersenne_twister random number
553 * generator engine @p __x into the output stream @p __os.
554 *
555 * @param __os An output stream.
556 * @param __x A % mersenne_twister random number generator engine.
557 *
558 * @returns The output stream with the state of @p __x inserted or in
559 * an error state.
560 */
561 template<typename _CharT, typename _Traits>
410fce92
PC
562 friend std::basic_ostream<_CharT, _Traits>&
563 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
d95c1c48
PC
564 const mersenne_twister& __x)
565 {
566 std::copy(__x._M_x, __x._M_x + state_size,
567 std::ostream_iterator<_UIntType>(__os, " "));
568 return __os;
569 }
570
571 /**
572 * Extracts the current state of a % mersenne_twister random number
573 * generator engine @p __x from the input stream @p __is.
574 *
575 * @param __is An input stream.
576 * @param __x A % mersenne_twister random number generator engine.
577 *
578 * @returns The input stream with the state of @p __x extracted or in
579 * an error state.
580 */
581 template<typename _CharT, typename _Traits>
410fce92
PC
582 friend std::basic_istream<_CharT, _Traits>&
583 operator>>(std::basic_istream<_CharT, _Traits>& __is,
d95c1c48
PC
584 mersenne_twister& __x)
585 {
586 for (int __i = 0; __i < state_size; ++__i)
587 __is >> __x._M_x[__i];
588 return __is;
589 }
590
86ad0dd6 591 private:
281864aa 592 template<class _Gen>
86ad0dd6 593 void
281864aa
PC
594 seed(_Gen& __g, true_type)
595 { return seed(static_cast<unsigned long>(__g)); }
86ad0dd6 596
281864aa 597 template<class _Gen>
86ad0dd6 598 void
281864aa 599 seed(_Gen& __g, false_type);
86ad0dd6
PC
600
601 private:
281864aa
PC
602 _UIntType _M_x[state_size];
603 int _M_p;
86ad0dd6
PC
604 };
605
606 /**
607 * The classic Mersenne Twister.
608 *
609 * Reference:
610 * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
611 * Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions
612 * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
613 */
614 typedef mersenne_twister<
615 unsigned long, 32, 624, 397, 31,
616 0x9908b0dful, 11, 7,
617 0x9d2c5680ul, 15,
618 0xefc60000ul, 18
619 > mt19937;
620
621
622 /**
623 * @brief The Marsaglia-Zaman generator.
624 *
625 * This is a model of a Generalized Fibonacci discrete random number
626 * generator, sometimes referred to as the SWC generator.
627 *
628 * A discrete random number generator that produces pseudorandom numbers using
629 * @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m @f$.
630 *
631 * The size of the state is @f$ r @f$
632 * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
633 *
634 * N1688[4.13] says "the template parameter _IntType shall denote an integral
635 * type large enough to store values up to m."
636 *
637 * @if maint
638 * @var _M_x The state of te generator. This is a ring buffer.
639 * @var _M_carry The carry.
640 * @var _M_p Current index of x(i - r).
641 * @endif
642 */
281864aa 643 template<typename _IntType, _IntType __m, int __s, int __r>
86ad0dd6
PC
644 class subtract_with_carry
645 {
646 __glibcxx_class_requires(_IntType, _IntegerConcept)
647
648 public:
649 /** The type of the generated random value. */
650 typedef _IntType result_type;
651
652 // parameter values
281864aa
PC
653 static const _IntType modulus = __m;
654 static const int long_lag = __r;
655 static const int short_lag = __s;
86ad0dd6
PC
656
657 public:
658 /**
659 * Constructs a default-initialized % subtract_with_carry random number
660 * generator.
661 */
662 subtract_with_carry()
663 { this->seed(); }
664
665 /**
666 * Constructs an explicitly seeded % subtract_with_carry random number
667 * generator.
668 */
669 explicit
281864aa 670 subtract_with_carry(unsigned long __value)
86ad0dd6
PC
671 { this->seed(__value); }
672
673 /**
674 * Constructs a % subtract_with_carry random number generator seeded from
675 * the PAD iterated by [__first, last).
676 */
281864aa
PC
677 template<class _Gen>
678 subtract_with_carry(_Gen& __g)
679 { this->seed(__g); }
86ad0dd6
PC
680
681 /**
682 * Seeds the initial state @f$ x_0 @f$ of the random number generator.
683 *
684 * @note This implementation follows the tr1 specification but will
685 * obviously not work correctly on all platforms, since it has hardcoded
686 * values that may overflow ints on some platforms.
687 *
688 * N1688[4.19] modifies this as follows.
689 * If @p __value == 0, sets value to 19780503. In any case, with a linear
690 * congruential generator lcg(i) having parameters @f$ m_{lcg} =
691 * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value @f$, sets
692 * @f$ x_{-r} \dots x_{-1} @f$ to
693 * @f$ lcg(1) \bmod m \dots lcg(r) \bmod m @f$ respectively.
694 * If @f$ x_{-1} = 0 @f$ set carry to 1, otherwise sets carry to 0.
695 */
696 void
281864aa 697 seed(unsigned long __value = 19780503);
86ad0dd6
PC
698
699 /**
700 * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
701 * random number generator.
702 */
281864aa 703 template<class _Gen>
86ad0dd6 704 void
281864aa
PC
705 seed(_Gen& __g)
706 { seed(__g, typename is_fundamental<_Gen>::type()); }
86ad0dd6
PC
707
708 /**
709 * Gets the inclusive minimum value of the range of random integers
710 * returned by this generator.
711 */
712 result_type
713 min() const
714 { return 0; }
715
716 /**
717 * Gets the inclusive maximum value of the range of random integers
718 * returned by this generator.
719 */
720 result_type
721 max() const
722 { return this->modulus - 1; }
723
724 /**
725 * Gets the next random number in the sequence.
726 */
727 result_type
728 operator()();
729
730 /**
731 * Compares two % subtract_with_carry random number generator objects of
732 * the same type for equality.
733 *
734 * @param __lhs A % subtract_with_carry random number generator object.
735 * @param __rhs Another % subtract_with_carry random number generator
736 * object.
737 *
738 * @returns true if the two objects are equal, false otherwise.
739 */
740 friend bool
741 operator==(const subtract_with_carry& __lhs,
742 const subtract_with_carry& __rhs)
d95c1c48 743 { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
86ad0dd6
PC
744
745 /**
746 * Compares two % subtract_with_carry random number generator objects of
747 * the same type for inequality.
748 *
749 * @param __lhs A % subtract_with_carry random number generator object.
750 * @param __rhs Another % subtract_with_carry random number generator
751 * object.
752 *
753 * @returns true if the two objects are not equal, false otherwise.
754 */
755 friend bool
756 operator!=(const subtract_with_carry& __lhs,
757 const subtract_with_carry& __rhs)
758 { return !(__lhs == __rhs); }
759
760 /**
761 * Inserts the current state of a % subtract_with_carry random number
d95c1c48 762 * generator engine @p __x into the output stream @p __os.
86ad0dd6
PC
763 *
764 * @param __os An output stream.
765 * @param __x A % subtract_with_carry random number generator engine.
766 *
d95c1c48
PC
767 * @returns The output stream with the state of @p __x inserted or in
768 * an error state.
86ad0dd6
PC
769 */
770 template<typename _CharT, typename _Traits>
410fce92
PC
771 friend std::basic_ostream<_CharT, _Traits>&
772 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6
PC
773 const subtract_with_carry& __x)
774 {
d95c1c48 775 std::copy(__x._M_x, __x._M_x + long_lag,
86ad0dd6
PC
776 std::ostream_iterator<_IntType>(__os, " "));
777 return __os << __x._M_carry;
778 }
779
780 /**
781 * Extracts the current state of a % subtract_with_carry random number
d95c1c48 782 * generator engine @p __x from the input stream @p __is.
86ad0dd6
PC
783 *
784 * @param __is An input stream.
785 * @param __x A % subtract_with_carry random number generator engine.
786 *
d95c1c48
PC
787 * @returns The input stream with the state of @p __x extracted or in
788 * an error state.
86ad0dd6
PC
789 */
790 template<typename _CharT, typename _Traits>
410fce92
PC
791 friend std::basic_istream<_CharT, _Traits>&
792 operator>>(std::basic_istream<_CharT, _Traits>& __is,
86ad0dd6
PC
793 subtract_with_carry& __x)
794 {
d95c1c48 795 for (int __i = 0; __i < long_lag; ++__i)
86ad0dd6
PC
796 __is >> __x._M_x[__i];
797 __is >> __x._M_carry;
798 return __is;
799 }
800
801 private:
281864aa 802 template<class _Gen>
86ad0dd6 803 void
281864aa
PC
804 seed(_Gen& __g, true_type)
805 { return seed(static_cast<unsigned long>(__g)); }
86ad0dd6 806
281864aa 807 template<class _Gen>
86ad0dd6 808 void
281864aa 809 seed(_Gen& __g, false_type);
86ad0dd6
PC
810
811 private:
812 int _M_p;
813 result_type _M_x[long_lag];
814 result_type _M_carry;
815 };
816
817
818 /**
819 * Produces random numbers from some base engine by discarding blocks of
820 * data.
821 *
281864aa 822 * 0 <= @p __r <= @p __p
86ad0dd6 823 */
281864aa 824 template<class _UniformRandomNumberGenerator, int __p, int __r>
86ad0dd6
PC
825 class discard_block
826 {
827 // __glibcxx_class_requires(typename base_type::result_type,
e4ec6e19 828 // ArithmeticTypeConcept)
86ad0dd6
PC
829
830 public:
831 /** The type of the underlying generator engine. */
281864aa 832 typedef _UniformRandomNumberGenerator base_type;
86ad0dd6
PC
833 /** The type of the generated random value. */
834 typedef typename base_type::result_type result_type;
835
836 // parameter values
281864aa
PC
837 static const int block_size = __p;
838 static const int used_block = __r;
86ad0dd6
PC
839
840 /**
841 * Constructs a default %discard_block engine.
842 *
843 * The underlying engine is default constrcuted as well.
844 */
845 discard_block()
846 : _M_n(0) { }
847
848 /**
849 * Copy constructs a %discard_block engine.
850 *
851 * Copies an existing base class random number geenerator.
852 * @param rng An existing (base class) engine object.
853 */
281864aa
PC
854 explicit discard_block(const base_type& __rng)
855 : _M_b(__rng) , _M_n(0) { }
86ad0dd6
PC
856
857 /**
858 * Seed constructs a %discard_block engine.
859 *
281864aa
PC
860 * Constructs the underlying generator engine seeded with @p __s.
861 * @param __s A seed value for the base class engine.
86ad0dd6 862 */
281864aa
PC
863 explicit discard_block(unsigned long __s)
864 : _M_b(__s), _M_n(0) { }
86ad0dd6
PC
865
866 /**
867 * Generator constructs a %discard_block engine.
868 *
281864aa 869 * @param __g A seed generator function.
86ad0dd6 870 */
281864aa
PC
871 template<class _Gen>
872 discard_block(_Gen& __g)
873 : _M_b(__g), _M_n(0) { }
86ad0dd6
PC
874
875 /**
876 * Reseeds the %discard_block object with the default seed for the
877 * underlying base class generator engine.
878 */
879 void seed()
880 {
881 _M_b.seed();
882 _M_n = 0;
883 }
884
885 /**
886 * Reseeds the %discard_block object with the given seed generator
887 * function.
281864aa 888 * @param __g A seed generator function.
86ad0dd6 889 */
281864aa
PC
890 template<class _Gen>
891 void seed(_Gen& __g)
86ad0dd6 892 {
281864aa 893 _M_b.seed(__g);
86ad0dd6
PC
894 _M_n = 0;
895 }
896
897 /**
898 * Gets a const reference to the underlying generator engine object.
899 */
900 const base_type&
901 base() const
902 { return _M_b; }
903
904 /**
905 * Gets the minimum value in the generated random number range.
906 */
907 result_type
908 min() const
909 { return _M_b.min(); }
910
911 /**
912 * Gets the maximum value in the generated random number range.
913 */
914 result_type
915 max() const
916 { return _M_b.max(); }
917
918 /**
919 * Gets the next value in the generated random number sequence.
920 */
921 result_type
922 operator()();
923
924 /**
925 * Compares two %discard_block random number generator objects of
926 * the same type for equality.
927 *
928 * @param __lhs A %discard_block random number generator object.
929 * @param __rhs Another %discard_block random number generator
930 * object.
931 *
932 * @returns true if the two objects are equal, false otherwise.
933 */
934 friend bool
935 operator==(const discard_block& __lhs, const discard_block& __rhs)
d95c1c48 936 { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }
86ad0dd6
PC
937
938 /**
939 * Compares two %discard_block random number generator objects of
940 * the same type for inequality.
941 *
942 * @param __lhs A %discard_block random number generator object.
943 * @param __rhs Another %discard_block random number generator
944 * object.
945 *
946 * @returns true if the two objects are not equal, false otherwise.
947 */
948 friend bool
949 operator!=(const discard_block& __lhs, const discard_block& __rhs)
950 { return !(__lhs == __rhs); }
951
952 /**
953 * Inserts the current state of a %discard_block random number
d95c1c48 954 * generator engine @p __x into the output stream @p __os.
86ad0dd6
PC
955 *
956 * @param __os An output stream.
957 * @param __x A %discard_block random number generator engine.
958 *
d95c1c48
PC
959 * @returns The output stream with the state of @p __x inserted or in
960 * an error state.
86ad0dd6
PC
961 */
962 template<typename _CharT, typename _Traits>
410fce92
PC
963 friend std::basic_ostream<_CharT, _Traits>&
964 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6
PC
965 const discard_block& __x)
966 { return __os << __x._M_b << " " << __x._M_n; }
967
968 /**
969 * Extracts the current state of a % subtract_with_carry random number
d95c1c48 970 * generator engine @p __x from the input stream @p __is.
86ad0dd6
PC
971 *
972 * @param __is An input stream.
973 * @param __x A %discard_block random number generator engine.
974 *
d95c1c48
PC
975 * @returns The input stream with the state of @p __x extracted or in
976 * an error state.
86ad0dd6
PC
977 */
978 template<typename _CharT, typename _Traits>
410fce92
PC
979 friend std::basic_istream<_CharT, _Traits>&
980 operator>>(std::basic_istream<_CharT, _Traits>& __is,
86ad0dd6
PC
981 discard_block& __x)
982 { return __is >> __x._M_b >> __x._M_n; }
983
984 private:
985 base_type _M_b;
986 int _M_n;
987 };
988
989
990 /**
991 * James's luxury-level-3 integer adaptation of Luescher's generator.
992 */
993 typedef discard_block<
e4ec6e19 994 subtract_with_carry<int, (1 << 24), 10, 24>,
86ad0dd6
PC
995 223,
996 24
997 > ranlux3;
998
999 /**
1000 * James's luxury-level-4 integer adaptation of Luescher's generator.
1001 */
1002 typedef discard_block<
e4ec6e19 1003 subtract_with_carry<int, (1 << 24), 10, 24>,
86ad0dd6
PC
1004 389,
1005 24
1006 > ranlux4;
1007
1008
1009 /**
1010 * A random number generator adaptor class that combines two random number
1011 * generator engines into a single output sequence.
1012 */
281864aa
PC
1013 template<class _UniformRandomNumberGenerator1, int __s1,
1014 class _UniformRandomNumberGenerator2, int __s2>
86ad0dd6
PC
1015 class xor_combine
1016 {
281864aa 1017 // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
e4ec6e19 1018 // result_type, ArithmeticTypeConcept)
281864aa 1019 // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
e4ec6e19 1020 // result_type, ArithmeticTypeConcept)
86ad0dd6
PC
1021
1022 public:
1023 /** The type of the the first underlying generator engine. */
e4ec6e19 1024 typedef _UniformRandomNumberGenerator1 base1_type;
86ad0dd6 1025 /** The type of the the second underlying generator engine. */
e4ec6e19
PC
1026 typedef _UniformRandomNumberGenerator2 base2_type;
1027
1028 private:
1029 typedef typename base1_type::result_type _Result_type1;
1030 typedef typename base2_type::result_type _Result_type2;
1031
1032 public:
86ad0dd6
PC
1033 /** The type of the generated random value. */
1034 typedef typename _Private::_Select<
e4ec6e19
PC
1035 (sizeof(_Result_type1) > sizeof(_Result_type2)),
1036 _Result_type1, _Result_type2>::_Type result_type;
86ad0dd6
PC
1037
1038 // parameter values
281864aa
PC
1039 static const int shift1 = __s1;
1040 static const int shift2 = __s2;
86ad0dd6
PC
1041
1042 // constructors and member function
1043 xor_combine() { }
1044
281864aa
PC
1045 xor_combine(const base1_type& __rng1, const base2_type& __rng2)
1046 : _M_b1(__rng1), _M_b2(__rng2) { }
86ad0dd6 1047
281864aa
PC
1048 xor_combine(unsigned long __s)
1049 : _M_b1(__s), _M_b2(__s + 1) { }
86ad0dd6 1050
281864aa
PC
1051 template<class _Gen>
1052 xor_combine(_Gen& __g)
1053 : _M_b1(__g), _M_b2(__g) { }
86ad0dd6
PC
1054
1055 void
1056 seed()
1057 {
1058 _M_b1.seed();
1059 _M_b2.seed();
1060 }
1061
281864aa 1062 template<class _Gen>
86ad0dd6 1063 void
281864aa 1064 seed(_Gen& __g)
86ad0dd6 1065 {
281864aa
PC
1066 _M_b1.seed(__g);
1067 _M_b2.seed(__g);
86ad0dd6
PC
1068 }
1069
1070 const base1_type&
1071 base1() const
1072 { return _M_b1; }
1073
1074 const base2_type&
1075 base2() const
1076 { return _M_b2; }
1077
1078 result_type
1079 min() const
1080 { return _M_b1.min() ^ _M_b2.min(); }
1081
1082 result_type
1083 max() const
1084 { return _M_b1.max() | _M_b2.max(); }
1085
1086 /**
1087 * Gets the next random number in the sequence.
1088 */
1089 result_type
1090 operator()()
1091 { return ((_M_b1() << shift1) ^ (_M_b2() << shift2)); }
1092
1093 /**
1094 * Compares two %xor_combine random number generator objects of
1095 * the same type for equality.
1096 *
1097 * @param __lhs A %xor_combine random number generator object.
1098 * @param __rhs Another %xor_combine random number generator
1099 * object.
1100 *
1101 * @returns true if the two objects are equal, false otherwise.
1102 */
1103 friend bool
1104 operator==(const xor_combine& __lhs, const xor_combine& __rhs)
1105 {
1106 return (__lhs.base1() == __rhs.base1())
d95c1c48 1107 && (__lhs.base2() == __rhs.base2());
86ad0dd6
PC
1108 }
1109
1110 /**
1111 * Compares two %xor_combine random number generator objects of
1112 * the same type for inequality.
1113 *
1114 * @param __lhs A %xor_combine random number generator object.
1115 * @param __rhs Another %xor_combine random number generator
1116 * object.
1117 *
1118 * @returns true if the two objects are not equal, false otherwise.
1119 */
1120 friend bool
1121 operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
1122 { return !(__lhs == __rhs); }
1123
1124 /**
1125 * Inserts the current state of a %xor_combine random number
d95c1c48 1126 * generator engine @p __x into the output stream @p __os.
86ad0dd6
PC
1127 *
1128 * @param __os An output stream.
1129 * @param __x A %xor_combine random number generator engine.
1130 *
d95c1c48
PC
1131 * @returns The output stream with the state of @p __x inserted or in
1132 * an error state.
86ad0dd6
PC
1133 */
1134 template<typename _CharT, typename _Traits>
410fce92
PC
1135 friend std::basic_ostream<_CharT, _Traits>&
1136 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6
PC
1137 const xor_combine& __x)
1138 { return __os << __x.base1() << " " << __x.base1(); }
1139
1140 /**
1141 * Extracts the current state of a %xor_combine random number
d95c1c48 1142 * generator engine @p __x from the input stream @p __is.
86ad0dd6
PC
1143 *
1144 * @param __is An input stream.
1145 * @param __x A %xor_combine random number generator engine.
1146 *
d95c1c48
PC
1147 * @returns The input stream with the state of @p __x extracted or in
1148 * an error state.
86ad0dd6
PC
1149 */
1150 template<typename _CharT, typename _Traits>
410fce92
PC
1151 friend std::basic_istream<_CharT, _Traits>&
1152 operator>>(std::basic_istream<_CharT, _Traits>& __is,
86ad0dd6
PC
1153 xor_combine& __x)
1154 { return __is >> __x._M_b1 >> __x._M_b2; }
1155
1156 private:
1157 base1_type _M_b1;
1158 base2_type _M_b2;
1159 };
1160
1161
1162 /**
1163 * A standard interface to a platform-specific non-deterministic random number
1164 * generator (if any are available).
86ad0dd6
PC
1165 */
1166 class random_device
1167 {
1168 public:
1169 // types
1170 typedef unsigned int result_type;
410fce92 1171
86ad0dd6 1172 // constructors, destructors and member functions
d8bc9819
PC
1173
1174#ifdef _GLIBCXX_USE_RANDOM_TR1
410fce92 1175
d8bc9819
PC
1176 explicit
1177 random_device(const std::string& __token = "/dev/urandom")
1178 {
1179 if ((__token != "/dev/urandom" && __token != "/dev/random")
410fce92
PC
1180 || !_M_filebuf.open(__token.c_str(),
1181 std::ios_base::in | std::ios_base::binary))
d8bc9819
PC
1182 std::__throw_runtime_error(__N("random_device::"
1183 "random_device(const std::string&)"));
1184 }
1185
1186 ~random_device()
1187 { _M_filebuf.close(); }
1188
1189#else
410fce92 1190
d8bc9819 1191 explicit
e4ec6e19 1192 random_device(const std::string& __token = "mt19937")
410fce92
PC
1193 : _M_mt(_M_strtoul(__token)) { }
1194
1195 private:
1196 static unsigned long
1197 _M_strtoul(const std::string& __str)
d8bc9819 1198 {
410fce92 1199 unsigned long __ret = 5489UL;
e4ec6e19 1200 if (__str != "mt19937")
d8bc9819 1201 {
410fce92
PC
1202 const char* __nptr = __str.c_str();
1203 char* __endptr;
1204 __ret = std::strtoul(__nptr, &__endptr, 0);
1205 if (*__nptr == '\0' || *__endptr != '\0')
1206 std::__throw_runtime_error(__N("random_device::_M_strtoul"
d8bc9819 1207 "(const std::string&)"));
d8bc9819 1208 }
410fce92 1209 return __ret;
d8bc9819 1210 }
410fce92
PC
1211
1212 public:
1213
d8bc9819
PC
1214#endif
1215
1216 result_type
1217 min() const
1218 { return std::numeric_limits<result_type>::min(); }
1219
1220 result_type
1221 max() const
1222 { return std::numeric_limits<result_type>::max(); }
1223
1224 double
1225 entropy() const
1226 { return 0.0; }
1227
1228 result_type
1229 operator()()
1230 {
1231#ifdef _GLIBCXX_USE_RANDOM_TR1
1232 result_type __ret;
1233 _M_filebuf.sgetn(reinterpret_cast<char*>(&__ret), sizeof(result_type));
1234 return __ret;
1235#else
410fce92 1236 return _M_mt();
d8bc9819
PC
1237#endif
1238 }
86ad0dd6
PC
1239
1240 private:
281864aa
PC
1241 random_device(const random_device&);
1242 void operator=(const random_device&);
d8bc9819
PC
1243
1244#ifdef _GLIBCXX_USE_RANDOM_TR1
1245 std::filebuf _M_filebuf;
410fce92
PC
1246#else
1247 mt19937 _M_mt;
1248#endif
86ad0dd6
PC
1249 };
1250
1251 /* @} */ // group tr1_random_generators
1252
1253 /**
1254 * @addtogroup tr1_random_distributions Random Number Distributions
1255 * @ingroup tr1_random
1256 * @{
1257 */
1258
1259 /**
1260 * @addtogroup tr1_random_distributions_discrete Discrete Distributions
1261 * @ingroup tr1_random_distributions
1262 * @{
1263 */
1264
1265 /**
1266 * @brief Uniform discrete distribution for random numbers.
1267 * A discrete random distribution on the range @f$[min, max]@f$ with equal
1268 * probability throughout the range.
1269 */
1270 template<typename _IntType = int>
1271 class uniform_int
1272 {
1273 __glibcxx_class_requires(_IntType, _IntegerConcept)
1274
1275 public:
1276 /** The type of the parameters of the distribution. */
1277 typedef _IntType input_type;
1278 /** The type of the range of the distribution. */
1279 typedef _IntType result_type;
1280
1281 public:
1282 /**
1283 * Constructs a uniform distribution object.
1284 */
1285 explicit
1286 uniform_int(_IntType __min = 0, _IntType __max = 9)
1287 : _M_min(__min), _M_max(__max)
1288 {
1289 _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
1290 }
1291
1292 /**
1293 * Gets the inclusive lower bound of the distribution range.
1294 */
1295 result_type
1296 min() const
1297 { return _M_min; }
1298
1299 /**
1300 * Gets the inclusive upper bound of the distribution range.
1301 */
1302 result_type
1303 max() const
1304 { return _M_max; }
1305
1306 /**
1307 * Resets the distribution state.
1308 *
1309 * Does nothing for the uniform integer distribution.
1310 */
1311 void
1312 reset() { }
1313
1314 /**
1315 * Gets a uniformly distributed random number in the range
1316 * @f$(min, max)@f$.
1317 */
1318 template<typename _UniformRandomNumberGenerator>
1319 result_type
1320 operator()(_UniformRandomNumberGenerator& __urng)
1321 { return (__urng() % (_M_max - _M_min + 1)) + _M_min; }
1322
1323 /**
1324 * Gets a uniform random number in the range @f$[0, n)@f$.
1325 *
1326 * This function is aimed at use with std::random_shuffle.
1327 */
1328 template<typename _UniformRandomNumberGenerator>
1329 result_type
1330 operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
1331 { return __urng() % __n; }
1332
1333 /**
d95c1c48 1334 * Inserts a %uniform_int random number distribution @p __x into the
86ad0dd6
PC
1335 * output stream @p os.
1336 *
1337 * @param __os An output stream.
1338 * @param __x A %uniform_int random number distribution.
1339 *
d95c1c48
PC
1340 * @returns The output stream with the state of @p __x inserted or in
1341 * an error state.
86ad0dd6
PC
1342 */
1343 template<typename _CharT, typename _Traits>
410fce92
PC
1344 friend std::basic_ostream<_CharT, _Traits>&
1345 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6
PC
1346 const uniform_int& __x)
1347 { return __os << __x._M_min << " " << __x._M_max; }
1348
1349 /**
1350 * Extracts a %unform_int random number distribution
d95c1c48 1351 * @p __u from the input stream @p __is.
86ad0dd6
PC
1352 *
1353 * @param __is An input stream.
1354 * @param __u A %uniform_int random number generator engine.
1355 *
d95c1c48 1356 * @returns The input stream with @p __u extracted or in an error state.
86ad0dd6
PC
1357 */
1358 template<typename _CharT, typename _Traits>
410fce92
PC
1359 friend std::basic_istream<_CharT, _Traits>&
1360 operator>>(std::basic_istream<_CharT, _Traits>& __is, uniform_int& __u)
86ad0dd6
PC
1361 { return __is >> __u._M_min >> __u._M_max; }
1362
1363 private:
1364 _IntType _M_min;
1365 _IntType _M_max;
1366 };
1367
1368
1369 /**
1370 * @brief A Bernoulli random number distribution.
1371 *
1372 * Generates a sequence of true and false values with likelihood @f$ p @f$
1373 * that true will come up and @f$ (1 - p) @f$ that false will appear.
1374 */
1375 class bernoulli_distribution
1376 {
1377 public:
1378 typedef int input_type;
1379 typedef bool result_type;
1380
1381 public:
1382 /**
1383 * Constructs a Bernoulli distribution with likelihood @p p.
1384 *
281864aa 1385 * @param __p [IN] The likelihood of a true result being returned. Must
86ad0dd6
PC
1386 * be in the interval @f$ [0, 1] @f$.
1387 */
1388 explicit
1389 bernoulli_distribution(double __p = 0.5)
1390 : _M_p(__p)
1391 {
1392 _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
1393 }
1394
1395 /**
1396 * Gets the @p p parameter of the distribution.
1397 */
1398 double
1399 p() const
1400 { return _M_p; }
1401
1402 /**
1403 * Gets the inclusive lower bound of the distribution range.
1404 */
1405 result_type
1406 min() const
1407 { return false; }
1408
1409 /**
1410 * Gets the inclusive upper bound of the distribution range.
1411 */
1412 result_type
1413 max() const
1414 { return true; }
1415
1416 /**
1417 * Resets the distribution state.
1418 *
1419 * Does nothing for a bernoulli distribution.
1420 */
1421 void
1422 reset() { }
1423
1424 /**
1425 * Gets the next value in the Bernoullian sequence.
1426 */
1427 template<class UniformRandomNumberGenerator>
1428 result_type
1429 operator()(UniformRandomNumberGenerator& __urng)
1430 {
1431 if (__urng() < _M_p)
1432 return true;
1433 return false;
1434 }
1435
1436 /**
1437 * Inserts a %bernoulli_distribution random number distribution
d95c1c48 1438 * @p __x into the output stream @p __os.
86ad0dd6
PC
1439 *
1440 * @param __os An output stream.
1441 * @param __x A %bernoulli_distribution random number distribution.
1442 *
d95c1c48
PC
1443 * @returns The output stream with the state of @p __x inserted or in
1444 * an error state.
86ad0dd6
PC
1445 */
1446 template<typename _CharT, typename _Traits>
410fce92
PC
1447 friend std::basic_ostream<_CharT, _Traits>&
1448 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6
PC
1449 const bernoulli_distribution& __x)
1450 { return __os << __x.p(); }
1451
1452 /**
1453 * Extracts a %bernoulli_distribution random number distribution
d95c1c48 1454 * @p __u from the input stream @p __is.
86ad0dd6
PC
1455 *
1456 * @param __is An input stream.
1457 * @param __u A %bernoulli_distribution random number generator engine.
1458 *
d95c1c48 1459 * @returns The input stream with @p __u extracted or in an error state.
86ad0dd6
PC
1460 */
1461 template<typename _CharT, typename _Traits>
410fce92
PC
1462 friend std::basic_istream<_CharT, _Traits>&
1463 operator>>(std::basic_istream<_CharT, _Traits>& __is,
86ad0dd6
PC
1464 bernoulli_distribution& __u)
1465 { return __is >> __u._M_p; }
1466
1467 protected:
1468 double _M_p;
1469 };
1470
1471
1472 /**
1473 * @brief A discrete geometric random number distribution.
1474 *
1475 * The formula for the geometric probability mass function is
1476 * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
1477 * distribution.
1478 */
1479 template<typename _IntType = int, typename _RealType = double>
1480 class geometric_distribution
1481 {
1482 public:
1483 // types
1484 typedef _RealType input_type;
1485 typedef _IntType result_type;
1486
1487 // constructors and member function
1488
1489 explicit
1490 geometric_distribution(const _RealType& __p = _RealType(0.5))
1491 : _M_p(__p), _M_log_p(std::log(_M_p))
1492 {
1493 _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
1494 }
1495
1496 /**
281864aa 1497 * Gets the distribution parameter @p p.
86ad0dd6
PC
1498 */
1499 _RealType
1500 p() const
1501 { return _M_p; }
1502
1503 /**
1504 * Gets the inclusive lower bound of the distribution range.
1505 */
1506 result_type
1507 min() const;
1508
1509 /**
1510 * Gets the inclusive upper bound of the distribution range.
1511 */
1512 result_type
1513 max() const;
1514
1515 void
1516 reset() { }
1517
1518 template<class _UniformRandomNumberGenerator>
1519 result_type
1520 operator()(_UniformRandomNumberGenerator& __urng)
1521 {
1522 return result_type(std::floor(std::log(_RealType(1.0) - __urng())
1523 / _M_log_p)) + result_type(1);
1524 }
1525
1526 /**
1527 * Inserts a %geometric_distribution random number distribution
d95c1c48 1528 * @p __x into the output stream @p __os.
86ad0dd6
PC
1529 *
1530 * @param __os An output stream.
1531 * @param __x A %geometric_distribution random number distribution.
1532 *
d95c1c48
PC
1533 * @returns The output stream with the state of @p __x inserted or in
1534 * an error state.
86ad0dd6
PC
1535 */
1536 template<typename _CharT, typename _Traits>
410fce92
PC
1537 friend std::basic_ostream<_CharT, _Traits>&
1538 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6
PC
1539 const geometric_distribution& __x)
1540 { return __os << __x.p(); }
1541
1542 /**
1543 * Extracts a %geometric_distribution random number distribution
d95c1c48 1544 * @p __u from the input stream @p __is.
86ad0dd6
PC
1545 *
1546 * @param __is An input stream.
1547 * @param __u A %geometric_distribution random number generator engine.
1548 *
d95c1c48 1549 * @returns The input stream with @p __u extracted or in an error state.
86ad0dd6
PC
1550 */
1551 template<typename _CharT, typename _Traits>
410fce92
PC
1552 friend std::basic_istream<_CharT, _Traits>&
1553 operator>>(std::basic_istream<_CharT, _Traits>& __is,
86ad0dd6
PC
1554 geometric_distribution& __u)
1555 {
1556 __is >> __u._M_p;
1557 __u._M_log_p = std::log(__u._M_p);
1558 return __is;
1559 }
1560
1561 protected:
1562 _RealType _M_p;
1563 _RealType _M_log_p;
1564 };
1565
1566 /* @} */ // group tr1_random_distributions_discrete
1567
1568 /**
1569 * @addtogroup tr1_random_distributions_continuous Continuous Distributions
1570 * @ingroup tr1_random_distributions
1571 * @{
1572 */
1573
1574 /**
1575 * @brief Uniform continuous distribution for random numbers.
1576 *
1577 * A continuous random distribution on the range [min, max) with equal
1578 * probability throughout the range. The URNG should be real-valued and
1579 * deliver number in the range [0, 1).
1580 */
1581 template<typename _RealType = double>
1582 class uniform_real
1583 {
1584 public:
1585 // types
1586 typedef _RealType input_type;
1587 typedef _RealType result_type;
1588
1589 public:
1590 /**
1591 * Constructs a uniform_real object.
1592 *
281864aa
PC
1593 * @param __min [IN] The lower bound of the distribution.
1594 * @param __max [IN] The upper bound of the distribution.
86ad0dd6
PC
1595 */
1596 explicit
281864aa 1597 uniform_real(_RealType __min = _RealType(0),
0934c5ef
PC
1598 _RealType __max = _RealType(1))
1599 : _M_min(__min), _M_max(__max)
1600 {
1601 _GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
1602 }
86ad0dd6
PC
1603
1604 result_type
0934c5ef
PC
1605 min() const
1606 { return _M_min; }
86ad0dd6
PC
1607
1608 result_type
0934c5ef
PC
1609 max() const
1610 { return _M_max; }
86ad0dd6 1611
0934c5ef
PC
1612 void
1613 reset() { }
86ad0dd6
PC
1614
1615 template<class _UniformRandomNumberGenerator>
1616 result_type
1617 operator()(_UniformRandomNumberGenerator& __urng)
0934c5ef 1618 { return (__urng() * (_M_max - _M_min)) + _M_min; }
86ad0dd6
PC
1619
1620 /**
d95c1c48 1621 * Inserts a %uniform_real random number distribution @p __x into the
281864aa 1622 * output stream @p __os.
86ad0dd6
PC
1623 *
1624 * @param __os An output stream.
1625 * @param __x A %uniform_real random number distribution.
1626 *
d95c1c48
PC
1627 * @returns The output stream with the state of @p __x inserted or in
1628 * an error state.
86ad0dd6
PC
1629 */
1630 template<typename _CharT, typename _Traits>
410fce92
PC
1631 friend std::basic_ostream<_CharT, _Traits>&
1632 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6 1633 const uniform_real& __x)
0934c5ef 1634 { return __os << __x._M_min << " " << __x._M_max; }
86ad0dd6
PC
1635
1636 /**
1637 * Extracts a %unform_real random number distribution
d95c1c48 1638 * @p __u from the input stream @p __is.
86ad0dd6
PC
1639 *
1640 * @param __is An input stream.
1641 * @param __u A %uniform_real random number generator engine.
1642 *
d95c1c48 1643 * @returns The input stream with @p __u extracted or in an error state.
86ad0dd6
PC
1644 */
1645 template<typename _CharT, typename _Traits>
410fce92
PC
1646 friend std::basic_istream<_CharT, _Traits>&
1647 operator>>(std::basic_istream<_CharT, _Traits>& __is,
1648 uniform_real& __u)
86ad0dd6
PC
1649 { return __is >> __u._M_min >> __u._M_max; }
1650
1651 protected:
1652 _RealType _M_min;
1653 _RealType _M_max;
1654 };
1655
1656
1657 /**
1658 * @brief An exponential continuous distribution for random numbers.
1659 *
1660 * The formula for the exponential probability mass function is
1661 * @f$ p(x) = \lambda e^{-\lambda x} @f$.
1662 *
1663 * <table border=1 cellpadding=10 cellspacing=0>
1664 * <caption align=top>Distribution Statistics</caption>
1665 * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
1666 * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
1667 * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
1668 * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
1669 * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
1670 * </table>
1671 */
1672 template<typename _RealType = double>
1673 class exponential_distribution
1674 {
1675 public:
1676 // types
1677 typedef _RealType input_type;
1678 typedef _RealType result_type;
1679
1680 public:
1681 /**
1682 * Constructs an exponential distribution with inverse scale parameter
1683 * @f$ \lambda @f$.
1684 */
1685 explicit
1686 exponential_distribution(const result_type& __lambda = result_type(1))
1687 : _M_lambda(__lambda) { }
1688
1689 /**
1690 * Gets the inverse scale parameter of the distribution.
1691 */
1692 _RealType
1693 lambda() const
1694 { return _M_lambda; }
1695
1696 /**
1697 * Resets the distribution.
1698 *
1699 * Has no effect on exponential distributions.
1700 */
1701 void
1702 reset() { }
1703
1704 template<class _UniformRandomNumberGenerator>
1705 result_type
1706 operator()(_UniformRandomNumberGenerator& __urng)
36ac3ed6 1707 { return -std::log(__urng()) / _M_lambda; }
86ad0dd6
PC
1708
1709 /**
1710 * Inserts a %exponential_distribution random number distribution
d95c1c48 1711 * @p __x into the output stream @p __os.
86ad0dd6
PC
1712 *
1713 * @param __os An output stream.
1714 * @param __x A %exponential_distribution random number distribution.
1715 *
d95c1c48
PC
1716 * @returns The output stream with the state of @p __x inserted or in
1717 * an error state.
86ad0dd6
PC
1718 */
1719 template<typename _CharT, typename _Traits>
410fce92
PC
1720 friend std::basic_ostream<_CharT, _Traits>&
1721 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
86ad0dd6
PC
1722 const exponential_distribution& __x)
1723 { return __os << __x.lambda(); }
1724
1725 /**
1726 * Extracts a %exponential_distribution random number distribution
d95c1c48 1727 * @p __u from the input stream @p __is.
86ad0dd6
PC
1728 *
1729 * @param __is An input stream.
1730 * @param __u A %exponential_distribution random number generator engine.
1731 *
d95c1c48 1732 * @returns The input stream with @p __u extracted or in an error state.
86ad0dd6
PC
1733 */
1734 template<typename _CharT, typename _Traits>
410fce92
PC
1735 friend std::basic_istream<_CharT, _Traits>&
1736 operator>>(std::basic_istream<_CharT, _Traits>& __is,
86ad0dd6
PC
1737 exponential_distribution& __u)
1738 { return __is >> __u._M_lambda; }
1739
1740 private:
1741 result_type _M_lambda;
1742 };
1743
1744 /* @} */ // group tr1_random_distributions_continuous
1745 /* @} */ // group tr1_random_distributions
1746 /* @} */ // group tr1_random
1747
1748_GLIBCXX_END_NAMESPACE
1749}
1750
1751#include <tr1/random.tcc>
1752
1753#endif // _STD_TR1_RANDOM