// random number generation -*- C++ -*-

// Copyright (C) 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

/**
 * @file tr1/random
 * This is a TR1 C++ Library header. 
 */

#ifndef _TR1_RANDOM
#define _TR1_RANDOM 1

#include <cmath>
#include <cstdio>
#include <string>
#include <iosfwd>
#include <limits>
#include <tr1/type_traits>
#include <tr1/cmath>
#include <ext/type_traits.h>
#include <ext/numeric_traits.h>
#include <bits/concept_check.h>
#include <debug/debug.h>

namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(tr1)

  // [5.1] Random number generation

  /**
   * @addtogroup tr1_random Random Number Generation
   * A facility for generating random numbers on selected distributions.
   * @{
   */

  /*
   * Implementation-space details.
   */
  namespace __detail
  {
    template<typename _UIntType, int __w, 
	     bool = __w < std::numeric_limits<_UIntType>::digits>
      struct _Shift
      { static const _UIntType __value = 0; };

    template<typename _UIntType, int __w>
      struct _Shift<_UIntType, __w, true>
      { static const _UIntType __value = _UIntType(1) << __w; };

    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
      struct _Mod;

    // Dispatch based on modulus value to prevent divide-by-zero compile-time
    // errors when m == 0.
    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
      inline _Tp
      __mod(_Tp __x)
      { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }

    typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
		    unsigned, unsigned long>::__type _UInt32Type;

    /*
     * An adaptor class for converting the output of any Generator into
     * the input for a specific Distribution.
     */
    template<typename _Engine, typename _Distribution>
      struct _Adaptor
      { 
	typedef typename _Engine::result_type        _Engine_result_type;
	typedef typename _Distribution::input_type   result_type;

      public:
	_Adaptor(const _Engine& __g)
	: _M_g(__g) { }

	result_type
	min() const
	{
	  result_type __return_value = 0;
	  if (is_integral<_Engine_result_type>::value
	      && is_integral<result_type>::value)
	    __return_value = _M_g.min();
	  else if (!is_integral<result_type>::value)
	    __return_value = result_type(0);
	  return __return_value;
	}

	result_type
	max() const
	{
	  result_type __return_value = 0;
	  if (is_integral<_Engine_result_type>::value
	      && is_integral<result_type>::value)
	    __return_value = _M_g.max();
	  else if (!is_integral<result_type>::value)
	    __return_value = result_type(1);
	  return __return_value;
	}

	result_type
	operator()();

      private:
	_Engine _M_g;
      };

    /*
     * Converts a value generated by the adapted random number generator into a
     * value in the input domain for the dependent random number distribution.
     *
     * Because the type traits are compile time constants only the appropriate
     * clause of the if statements will actually be emitted by the compiler.
     */
    template<typename _Engine, typename _Distribution>
      typename _Adaptor<_Engine, _Distribution>::result_type
      _Adaptor<_Engine, _Distribution>::
      operator()()
      {
	result_type __return_value = 0;
	if (is_integral<_Engine_result_type>::value
	    && is_integral<result_type>::value)
	  __return_value = _M_g();
      	else if (is_integral<_Engine_result_type>::value
		 && !is_integral<result_type>::value)
	  __return_value = result_type(_M_g() - _M_g.min())
	    / result_type(_M_g.max() - _M_g.min() + result_type(1));
	else if (!is_integral<_Engine_result_type>::value
		 && !is_integral<result_type>::value)
	  __return_value = result_type(_M_g() - _M_g.min())
	    / result_type(_M_g.max() - _M_g.min());
      	return __return_value;
      }
  } // namespace __detail

  /**
   * Produces random numbers on a given disribution function using a un uniform
   * random number generation engine.
   *
   * @todo the engine_value_type needs to be studied more carefully.
   */
  template<typename _Engine, typename _Dist>
    class variate_generator
    {
      // Concept requirements.
      __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
      //  __glibcxx_class_requires(_Engine, _EngineConcept)
      //  __glibcxx_class_requires(_Dist, _EngineConcept)

    public:
      typedef _Engine                                engine_type;
      typedef __detail::_Adaptor<_Engine, _Dist>     engine_value_type;
      typedef _Dist                                  distribution_type;
      typedef typename _Dist::result_type            result_type;

      // tr1:5.1.1 table 5.1 requirement
      typedef typename __gnu_cxx::__enable_if<
	is_arithmetic<result_type>::value, result_type>::__type _IsValidType;

      /**
       * Constructs a variate generator with the uniform random number
       * generator @p __eng for the random distribution @p __dist.
       *
       * @throws Any exceptions which may thrown by the copy constructors of
       * the @p _Engine or @p _Dist objects.
       */
      variate_generator(engine_type __eng, distribution_type __dist)
      : _M_engine(__eng), _M_dist(__dist) { }

      /**
       * Gets the next generated value on the distribution.
       */
      result_type
      operator()()
      { return _M_dist(_M_engine); }

      /**
       * WTF?
       */
      template<typename _Tp>
        result_type
        operator()(_Tp __value)
        { return _M_dist(_M_engine, __value); }

      /**
       * Gets a reference to the underlying uniform random number generator
       * object.
       */
      engine_value_type&
      engine()
      { return _M_engine; }

      /**
       * Gets a const reference to the underlying uniform random number
       * generator object.
       */
      const engine_value_type&
      engine() const
      { return _M_engine; }

      /**
       * Gets a reference to the underlying random distribution.
       */
      distribution_type&
      distribution()
      { return _M_dist; }

      /**
       * Gets a const reference to the underlying random distribution.
       */
      const distribution_type&
      distribution() const
      { return _M_dist; }

      /**
       * Gets the closed lower bound of the distribution interval.
       */
      result_type
      min() const
      { return this->distribution().min(); }

      /**
       * Gets the closed upper bound of the distribution interval.
       */
      result_type
      max() const
      { return this->distribution().max(); }

    private:
      engine_value_type _M_engine;
      distribution_type _M_dist;
    };


  /**
   * @addtogroup tr1_random_generators Random Number Generators
   * @ingroup tr1_random
   *
   * These classes define objects which provide random or pseudorandom
   * numbers, either from a discrete or a continuous interval.  The
   * random number generator supplied as a part of this library are
   * all uniform random number generators which provide a sequence of
   * random number uniformly distributed over their range.
   *
   * A number generator is a function object with an operator() that
   * takes zero arguments and returns a number.
   *
   * A compliant random number generator must satisy the following
   * requirements.  <table border=1 cellpadding=10 cellspacing=0>
   * <caption align=top>Random Number Generator Requirements</caption>
   * <tr><td>To be documented.</td></tr> </table>
   * 
   * @{
   */

  /**
   * @brief A model of a linear congruential random number generator.
   *
   * A random number generator that produces pseudorandom numbers using the
   * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
   *
   * The template parameter @p _UIntType must be an unsigned integral type
   * large enough to store values up to (__m-1). If the template parameter
   * @p __m is 0, the modulus @p __m used is
   * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
   * parameters @p __a and @p __c must be less than @p __m.
   *
   * The size of the state is @f$ 1 @f$.
   */
  template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    class linear_congruential
    {
      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
      //  __glibcpp_class_requires(__a < __m && __c < __m)

    public:
      /** The type of the generated random value. */
      typedef _UIntType result_type;

      /** The multiplier. */
      static const _UIntType multiplier = __a;
      /** An increment. */
      static const _UIntType increment = __c;
      /** The modulus. */
      static const _UIntType modulus = __m;

      /**
       * Constructs a %linear_congruential random number generator engine with
       * seed @p __s.  The default seed value is 1.
       *
       * @param __s The initial seed value.
       */
      explicit
      linear_congruential(unsigned long __x0 = 1)
      { this->seed(__x0); }

      /**
       * Constructs a %linear_congruential random number generator engine
       * seeded from the generator function @p __g.
       *
       * @param __g The seed generator function.
       */
      template<class _Gen>
        linear_congruential(_Gen& __g)
        { this->seed(__g); }

      /**
       * Reseeds the %linear_congruential random number generator engine
       * sequence to the seed @g __s.
       *
       * @param __s The new seed.
       */
      void
      seed(unsigned long __s = 1);

      /**
       * Reseeds the %linear_congruential random number generator engine
       * sequence using values from the generator function @p __g.
       *
       * @param __g the seed generator function.
       */
      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      /**
       * Gets the smallest possible value in the output range.
       *
       * The minumum depends on the @p __c parameter: if it is zero, the
       * minimum generated must be > 0, otherwise 0 is allowed.
       */
      result_type
      min() const
      { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }

      /**
       * Gets the largest possible value in the output range.
       */
      result_type
      max() const
      { return __m - 1; }

      /**
       * Gets the next random number in the sequence.
       */
      result_type
      operator()();

      /**
       * Compares two linear congruential random number generator
       * objects of the same type for equality.
       *  
       * @param __lhs A linear congruential random number generator object.
       * @param __rhs Another linear congruential random number generator obj.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const linear_congruential& __lhs,
		 const linear_congruential& __rhs)
      { return __lhs._M_x == __rhs._M_x; }

      /**
       * Compares two linear congruential random number generator
       * objects of the same type for inequality.
       *
       * @param __lhs A linear congruential random number generator object.
       * @param __rhs Another linear congruential random number generator obj.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const linear_congruential& __lhs,
		 const linear_congruential& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Writes the textual representation of the state x(i) of x to @p __os.
       *
       * @param __os  The output stream.
       * @param __lcr A % linear_congruential random number generator.
       * @returns __os.
       */
      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
	       _UIntType1 __m1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const linear_congruential<_UIntType1, __a1, __c1,
		   __m1>& __lcr);

      /**
       * Sets the state of the engine by reading its textual
       * representation from @p __is.
       *
       * The textual representation must have been previously written using an
       * output stream whose imbued locale and whose type's template
       * specialization arguments _CharT and _Traits were the same as those of
       * @p __is.
       *
       * @param __is  The input stream.
       * @param __lcr A % linear_congruential random number generator.
       * @returns __is.
       */
      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
	       _UIntType1 __m1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      _UIntType _M_x;
    };

  /**
   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
   */
  typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;

  /**
   * An alternative LCR (Lehmer Generator function) .
   */
  typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;


  /**
   * A generalized feedback shift register discrete random number generator.
   *
   * This algorithm avoind multiplication and division and is designed to be
   * friendly to a pipelined architecture.  If the parameters are chosen
   * correctly, this generator will produce numbers with a very long period and
   * fairly good apparent entropy, although still not cryptographically strong.
   *
   * The best way to use this generator is with the predefined mt19937 class.
   *
   * This algorithm was originally invented by Makoto Matsumoto and
   * Takuji Nishimura.
   *
   * @var word_size   The number of bits in each element of the state vector.
   * @var state_size  The degree of recursion.
   * @var shift_size  The period parameter.
   * @var mask_bits   The separation point bit index.
   * @var parameter_a The last row of the twist matrix.
   * @var output_u    The first right-shift tempering matrix parameter.
   * @var output_s    The first left-shift tempering matrix parameter.
   * @var output_b    The first left-shift tempering matrix mask.
   * @var output_t    The second left-shift tempering matrix parameter.
   * @var output_c    The second left-shift tempering matrix mask.
   * @var output_l    The second right-shift tempering matrix parameter.
   */
  template<class _UIntType, int __w, int __n, int __m, int __r,
	   _UIntType __a, int __u, int __s, _UIntType __b, int __t,
	   _UIntType __c, int __l>
    class mersenne_twister
    {
      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)

    public:
      // types
      typedef _UIntType result_type;

      // parameter values
      static const int       word_size   = __w;
      static const int       state_size  = __n;
      static const int       shift_size  = __m;
      static const int       mask_bits   = __r;
      static const _UIntType parameter_a = __a;
      static const int       output_u    = __u;
      static const int       output_s    = __s;
      static const _UIntType output_b    = __b;
      static const int       output_t    = __t;
      static const _UIntType output_c    = __c;
      static const int       output_l    = __l;

      // constructors and member function
      mersenne_twister()
      { seed(); }

      explicit
      mersenne_twister(unsigned long __value)
      { seed(__value); }

      template<class _Gen>
        mersenne_twister(_Gen& __g)
        { seed(__g); }

      void
      seed()
      { seed(5489UL); }

      void
      seed(unsigned long __value);

      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      result_type
      min() const
      { return 0; };

      result_type
      max() const
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }

      result_type
      operator()();

      /**
       * Compares two % mersenne_twister random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A % mersenne_twister random number generator object.
       * @param __rhs Another % mersenne_twister random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const mersenne_twister& __lhs,
		 const mersenne_twister& __rhs)
      { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }

      /**
       * Compares two % mersenne_twister random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A % mersenne_twister random number generator object.
       * @param __rhs Another % mersenne_twister random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const mersenne_twister& __lhs,
		 const mersenne_twister& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a % mersenne_twister random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A % mersenne_twister random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
	       _UIntType1 __c1, int __l1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);

      /**
       * Extracts the current state of a % mersenne_twister random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A % mersenne_twister random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
	       _UIntType1 __c1, int __l1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      _UIntType _M_x[state_size];
      int       _M_p;
    };

  /**
   * The classic Mersenne Twister.
   *
   * Reference:
   * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
   * Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions
   * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
   */
  typedef mersenne_twister<
    unsigned long, 32, 624, 397, 31,
    0x9908b0dful, 11, 7,
    0x9d2c5680ul, 15,
    0xefc60000ul, 18
    > mt19937;


  /**
   * @brief The Marsaglia-Zaman generator.
   * 
   * This is a model of a Generalized Fibonacci discrete random number
   * generator, sometimes referred to as the SWC generator.
   *
   * A discrete random number generator that produces pseudorandom
   * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
   * carry_{i-1}) \bmod m @f$.
   *
   * The size of the state is @f$ r @f$
   * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
   *
   * N1688[4.13] says "the template parameter _IntType shall denote an integral
   * type large enough to store values up to m."
   *
   * @if maint
   * @var _M_x     The state of the generator.  This is a ring buffer.
   * @var _M_carry The carry.
   * @var _M_p     Current index of x(i - r).
   * @endif
   */
  template<typename _IntType, _IntType __m, int __s, int __r>
    class subtract_with_carry
    {
      __glibcxx_class_requires(_IntType, _IntegerConcept)

    public:
      /** The type of the generated random value. */
      typedef _IntType result_type;
      
      // parameter values
      static const _IntType modulus   = __m;
      static const int      long_lag  = __r;
      static const int      short_lag = __s;

      /**
       * Constructs a default-initialized % subtract_with_carry random number
       * generator.
       */
      subtract_with_carry()
      { this->seed(); }

      /**
       * Constructs an explicitly seeded % subtract_with_carry random number
       * generator.
       */
      explicit
      subtract_with_carry(unsigned long __value)
      { this->seed(__value); }

      /**
       * Constructs a %subtract_with_carry random number generator engine
       * seeded from the generator function @p __g.
       *
       * @param __g The seed generator function.
       */
      template<class _Gen>
        subtract_with_carry(_Gen& __g)
        { this->seed(__g); }

      /**
       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
       *
       * N1688[4.19] modifies this as follows.  If @p __value == 0,
       * sets value to 19780503.  In any case, with a linear
       * congruential generator lcg(i) having parameters @f$ m_{lcg} =
       * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
       * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
       * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
       * set carry to 1, otherwise sets carry to 0.
       */
      void
      seed(unsigned long __value = 19780503);

      /**
       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
       * random number generator.
       */
      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      /**
       * Gets the inclusive minimum value of the range of random integers
       * returned by this generator.
       */
      result_type
      min() const
      { return 0; }

      /**
       * Gets the inclusive maximum value of the range of random integers
       * returned by this generator.
       */
      result_type
      max() const
      { return this->modulus - 1; }

      /**
       * Gets the next random number in the sequence.
       */
      result_type
      operator()();

      /**
       * Compares two % subtract_with_carry random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A % subtract_with_carry random number generator object.
       * @param __rhs Another % subtract_with_carry random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const subtract_with_carry& __lhs,
		 const subtract_with_carry& __rhs)
      { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }

      /**
       * Compares two % subtract_with_carry random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A % subtract_with_carry random number generator object.
       * @param __rhs Another % subtract_with_carry random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const subtract_with_carry& __lhs,
		 const subtract_with_carry& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a % subtract_with_carry random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A % subtract_with_carry random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const subtract_with_carry<_IntType1, __m1, __s1,
		   __r1>& __x);

      /**
       * Extracts the current state of a % subtract_with_carry random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A % subtract_with_carry random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;

      _UIntType  _M_x[long_lag];
      _UIntType  _M_carry;
      int        _M_p;
    };


  /**
   * @brief The Marsaglia-Zaman generator (floats version).
   *
   * @if maint
   * @var _M_x     The state of the generator.  This is a ring buffer.
   * @var _M_carry The carry.
   * @var _M_p     Current index of x(i - r).
   * @var _M_npows Precomputed negative powers of 2.   
   * @endif
   */
  template<typename _RealType, int __w, int __s, int __r>
    class subtract_with_carry_01
    {
    public:
      /** The type of the generated random value. */
      typedef _RealType result_type;
      
      // parameter values
      static const int      word_size = __w;
      static const int      long_lag  = __r;
      static const int      short_lag = __s;

      /**
       * Constructs a default-initialized % subtract_with_carry_01 random
       * number generator.
       */
      subtract_with_carry_01()
      {
	this->seed();
	_M_initialize_npows();
      }

      /**
       * Constructs an explicitly seeded % subtract_with_carry_01 random number
       * generator.
       */
      explicit
      subtract_with_carry_01(unsigned long __value)
      {
	this->seed(__value);
	_M_initialize_npows();
      }

      /**
       * Constructs a % subtract_with_carry_01 random number generator engine
       * seeded from the generator function @p __g.
       *
       * @param __g The seed generator function.
       */
      template<class _Gen>
        subtract_with_carry_01(_Gen& __g)
        {
	  this->seed(__g);
	  _M_initialize_npows();	  
	}

      /**
       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
       */
      void
      seed(unsigned long __value = 19780503);

      /**
       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
       * random number generator.
       */
      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      /**
       * Gets the minimum value of the range of random floats
       * returned by this generator.
       */
      result_type
      min() const
      { return 0.0; }

      /**
       * Gets the maximum value of the range of random floats
       * returned by this generator.
       */
      result_type
      max() const
      { return 1.0; }

      /**
       * Gets the next random number in the sequence.
       */
      result_type
      operator()();

      /**
       * Compares two % subtract_with_carry_01 random number generator objects
       * of the same type for equality.
       *
       * @param __lhs A % subtract_with_carry_01 random number
       *              generator object.
       * @param __rhs Another % subtract_with_carry_01 random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const subtract_with_carry_01& __lhs,
		 const subtract_with_carry_01& __rhs)
      {
	for (int __i = 0; __i < long_lag; ++__i)
	  if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
			  __rhs._M_x[__i]))
	    return false;
	return true;
      }

      /**
       * Compares two % subtract_with_carry_01 random number generator objects
       * of the same type for inequality.
       *
       * @param __lhs A % subtract_with_carry_01 random number
       *              generator object.
       *
       * @param __rhs Another % subtract_with_carry_01 random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const subtract_with_carry_01& __lhs,
		 const subtract_with_carry_01& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a % subtract_with_carry_01 random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A % subtract_with_carry_01 random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, int __w1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const subtract_with_carry_01<_RealType1, __w1, __s1,
		   __r1>& __x);

      /**
       * Extracts the current state of a % subtract_with_carry_01 random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A % subtract_with_carry_01 random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<typename _RealType1, int __w1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      void
      _M_initialize_npows();

      static const int __n = (__w + 31) / 32;

      typedef __detail::_UInt32Type _UInt32Type;
      _UInt32Type  _M_x[long_lag][__n];
      _RealType    _M_npows[__n];
      _UInt32Type  _M_carry;
      int          _M_p;
    };

  typedef subtract_with_carry_01<float, 24, 10, 24>   ranlux_base_01;

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 508. Bad parameters for ranlux64_base_01.
  typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;  


  /**
   * Produces random numbers from some base engine by discarding blocks of
   * data.
   *
   * 0 <= @p __r <= @p __p
   */
  template<class _UniformRandomNumberGenerator, int __p, int __r>
    class discard_block
    {
      // __glibcxx_class_requires(typename base_type::result_type,
      //                          ArithmeticTypeConcept)

    public:
      /** The type of the underlying generator engine. */
      typedef _UniformRandomNumberGenerator   base_type;
      /** The type of the generated random value. */
      typedef typename base_type::result_type result_type;

      // parameter values
      static const int block_size = __p;
      static const int used_block = __r;

      /**
       * Constructs a default %discard_block engine.
       *
       * The underlying engine is default constructed as well.
       */
      discard_block()
      : _M_n(0) { }

      /**
       * Copy constructs a %discard_block engine.
       *
       * Copies an existing base class random number geenerator.
       * @param rng An existing (base class) engine object.
       */
      explicit
      discard_block(const base_type& __rng)
      : _M_b(__rng), _M_n(0) { }

      /**
       * Seed constructs a %discard_block engine.
       *
       * Constructs the underlying generator engine seeded with @p __s.
       * @param __s A seed value for the base class engine.
       */
      explicit
      discard_block(unsigned long __s)
      : _M_b(__s), _M_n(0) { }

      /**
       * Generator construct a %discard_block engine.
       *
       * @param __g A seed generator function.
       */
      template<class _Gen>
        discard_block(_Gen& __g)
	: _M_b(__g), _M_n(0) { }

      /**
       * Reseeds the %discard_block object with the default seed for the
       * underlying base class generator engine.
       */
      void seed()
      {
	_M_b.seed();
	_M_n = 0;
      }

      /**
       * Reseeds the %discard_block object with the given seed generator
       * function.
       * @param __g A seed generator function.
       */
      template<class _Gen>
        void seed(_Gen& __g)
        {
	  _M_b.seed(__g);
	  _M_n = 0;
	}

      /**
       * Gets a const reference to the underlying generator engine object.
       */
      const base_type&
      base() const
      { return _M_b; }

      /**
       * Gets the minimum value in the generated random number range.
       */
      result_type
      min() const
      { return _M_b.min(); }

      /**
       * Gets the maximum value in the generated random number range.
       */
      result_type
      max() const
      { return _M_b.max(); }

      /**
       * Gets the next value in the generated random number sequence.
       */
      result_type
      operator()();

      /**
       * Compares two %discard_block random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A %discard_block random number generator object.
       * @param __rhs Another %discard_block random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const discard_block& __lhs, const discard_block& __rhs)
      { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }

      /**
       * Compares two %discard_block random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A %discard_block random number generator object.
       * @param __rhs Another %discard_block random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const discard_block& __lhs, const discard_block& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a %discard_block random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %discard_block random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const discard_block<_UniformRandomNumberGenerator1,
		   __p1, __r1>& __x);

      /**
       * Extracts the current state of a % subtract_with_carry random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %discard_block random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   discard_block<_UniformRandomNumberGenerator1,
		   __p1, __r1>& __x);

    private:
      base_type _M_b;
      int       _M_n;
    };


  /**
   * James's luxury-level-3 integer adaptation of Luescher's generator.
   */
  typedef discard_block<
    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
      223,
      24
      > ranlux3;

  /**
   * James's luxury-level-4 integer adaptation of Luescher's generator.
   */
  typedef discard_block<
    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
      389,
      24
      > ranlux4;

  typedef discard_block<
    subtract_with_carry_01<float, 24, 10, 24>,
      223,
      24
      > ranlux3_01;

  typedef discard_block<
    subtract_with_carry_01<float, 24, 10, 24>,
      389,
      24
      > ranlux4_01;


  /**
   * A random number generator adaptor class that combines two random number
   * generator engines into a single output sequence.
   */
  template<class _UniformRandomNumberGenerator1, int __s1,
	   class _UniformRandomNumberGenerator2, int __s2>
    class xor_combine
    {
      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
      //                          result_type, ArithmeticTypeConcept)
      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
      //                          result_type, ArithmeticTypeConcept)

    public:
      /** The type of the the first underlying generator engine. */
      typedef _UniformRandomNumberGenerator1   base1_type;
      /** The type of the the second underlying generator engine. */
      typedef _UniformRandomNumberGenerator2   base2_type;

    private:
      typedef typename base1_type::result_type _Result_type1;
      typedef typename base2_type::result_type _Result_type2;

    public:
      /** The type of the generated random value. */
      typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
						      > sizeof(_Result_type2)),
	_Result_type1, _Result_type2>::__type result_type;

      // parameter values
      static const int shift1 = __s1;
      static const int shift2 = __s2;

      // constructors and member function
      xor_combine()
      : _M_b1(), _M_b2()	
      { _M_initialize_max(); }

      xor_combine(const base1_type& __rng1, const base2_type& __rng2)
      : _M_b1(__rng1), _M_b2(__rng2)
      { _M_initialize_max(); }

      xor_combine(unsigned long __s)
      : _M_b1(__s), _M_b2(__s + 1)
      { _M_initialize_max(); }

      template<class _Gen>
        xor_combine(_Gen& __g)
	: _M_b1(__g), _M_b2(__g)
        { _M_initialize_max(); }

      void
      seed()
      {
	_M_b1.seed();
	_M_b2.seed();
      }

      template<class _Gen>
        void
        seed(_Gen& __g)
        {
	  _M_b1.seed(__g);
	  _M_b2.seed(__g);
	}

      const base1_type&
      base1() const
      { return _M_b1; }

      const base2_type&
      base2() const
      { return _M_b2; }

      result_type
      min() const
      { return 0; }

      result_type
      max() const
      { return _M_max; }

      /**
       * Gets the next random number in the sequence.
       */
      // NB: Not exactly the TR1 formula, per N2079 instead.
      result_type
      operator()()
      {
	return ((result_type(_M_b1() - _M_b1.min()) << shift1)
		^ (result_type(_M_b2() - _M_b2.min()) << shift2));
      }

      /**
       * Compares two %xor_combine random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A %xor_combine random number generator object.
       * @param __rhs Another %xor_combine random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const xor_combine& __lhs, const xor_combine& __rhs)
      {
	return (__lhs.base1() == __rhs.base1())
	        && (__lhs.base2() == __rhs.base2());
      }

      /**
       * Compares two %xor_combine random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A %xor_combine random number generator object.
       * @param __rhs Another %xor_combine random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a %xor_combine random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %xor_combine random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator11, int __s11,
	       class _UniformRandomNumberGenerator21, int __s21,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const xor_combine<_UniformRandomNumberGenerator11, __s11,
		   _UniformRandomNumberGenerator21, __s21>& __x);

      /**
       * Extracts the current state of a %xor_combine random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %xor_combine random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator11, int __s11,
	       class _UniformRandomNumberGenerator21, int __s21,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   xor_combine<_UniformRandomNumberGenerator11, __s11,
		   _UniformRandomNumberGenerator21, __s21>& __x);

    private:
      void
      _M_initialize_max();

      result_type
      _M_initialize_max_aux(result_type, result_type, int);

      base1_type  _M_b1;
      base2_type  _M_b2;
      result_type _M_max;
    };


  /**
   * A standard interface to a platform-specific non-deterministic
   * random number generator (if any are available).
   */
  class random_device
  {
  public:
    // types
    typedef unsigned int result_type;

    // constructors, destructors and member functions

#ifdef _GLIBCXX_USE_RANDOM_TR1

    explicit
    random_device(const std::string& __token = "/dev/urandom")
    {
      if ((__token != "/dev/urandom" && __token != "/dev/random")
	  || !(_M_file = std::fopen(__token.c_str(), "rb")))
	std::__throw_runtime_error(__N("random_device::"
				       "random_device(const std::string&)"));
    }

    ~random_device()
    { std::fclose(_M_file); }

#else

    explicit
    random_device(const std::string& __token = "mt19937")
    : _M_mt(_M_strtoul(__token)) { }

  private:
    static unsigned long
    _M_strtoul(const std::string& __str)
    {
      unsigned long __ret = 5489UL;
      if (__str != "mt19937")
	{
	  const char* __nptr = __str.c_str();
	  char* __endptr;
	  __ret = std::strtoul(__nptr, &__endptr, 0);
	  if (*__nptr == '\0' || *__endptr != '\0')
	    std::__throw_runtime_error(__N("random_device::_M_strtoul"
					   "(const std::string&)"));
	}
      return __ret;
    }

  public:

#endif

    result_type
    min() const
    { return std::numeric_limits<result_type>::min(); }

    result_type
    max() const
    { return std::numeric_limits<result_type>::max(); }

    double
    entropy() const
    { return 0.0; }

    result_type
    operator()()
    {
#ifdef _GLIBCXX_USE_RANDOM_TR1
      result_type __ret;
      std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
		 1, _M_file);
      return __ret;
#else
      return _M_mt();
#endif
    }

  private:
    random_device(const random_device&);
    void operator=(const random_device&);

#ifdef _GLIBCXX_USE_RANDOM_TR1
    FILE*        _M_file;
#else
    mt19937      _M_mt;
#endif
  };

  /* @} */ // group tr1_random_generators

  /**
   * @addtogroup tr1_random_distributions Random Number Distributions
   * @ingroup tr1_random
   * @{
   */

  /**
   * @addtogroup tr1_random_distributions_discrete Discrete Distributions
   * @ingroup tr1_random_distributions
   * @{
   */

  /**
   * @brief Uniform discrete distribution for random numbers.
   * A discrete random distribution on the range @f$[min, max]@f$ with equal
   * probability throughout the range.
   */
  template<typename _IntType = int>
    class uniform_int
    {
      __glibcxx_class_requires(_IntType, _IntegerConcept)
 
    public:
      /** The type of the parameters of the distribution. */
      typedef _IntType input_type;
      /** The type of the range of the distribution. */
      typedef _IntType result_type;

    public:
      /**
       * Constructs a uniform distribution object.
       */
      explicit
      uniform_int(_IntType __min = 0, _IntType __max = 9)
      : _M_min(__min), _M_max(__max)
      {
	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
      }

      /**
       * Gets the inclusive lower bound of the distribution range.
       */
      result_type
      min() const
      { return _M_min; }

      /**
       * Gets the inclusive upper bound of the distribution range.
       */
      result_type
      max() const
      { return _M_max; }

      /**
       * Resets the distribution state.
       *
       * Does nothing for the uniform integer distribution.
       */
      void
      reset() { }

      /**
       * Gets a uniformly distributed random number in the range
       * @f$(min, max)@f$.
       */
      template<typename _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng)
        {
	  typedef typename _UniformRandomNumberGenerator::result_type
	    _UResult_type;
	  return _M_call(__urng, _M_min, _M_max,
			 typename is_integral<_UResult_type>::type());
	}

      /**
       * Gets a uniform random number in the range @f$[0, n)@f$.
       *
       * This function is aimed at use with std::random_shuffle.
       */
      template<typename _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
        {
	  typedef typename _UniformRandomNumberGenerator::result_type
	    _UResult_type;
	  return _M_call(__urng, 0, __n - 1,
			 typename is_integral<_UResult_type>::type());
	}

      /**
       * Inserts a %uniform_int random number distribution @p __x into the
       * output stream @p os.
       *
       * @param __os An output stream.
       * @param __x  A %uniform_int random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const uniform_int<_IntType1>& __x);

      /**
       * Extracts a %unform_int random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %uniform_int random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _IntType1, typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   uniform_int<_IntType1>& __x);

    private:
      template<typename _UniformRandomNumberGenerator>
        result_type
        _M_call(_UniformRandomNumberGenerator& __urng,
		result_type __min, result_type __max, true_type)
        { return result_type(__urng() % (__max - __min + 1)) + __min; }

      template<typename _UniformRandomNumberGenerator>
        result_type
        _M_call(_UniformRandomNumberGenerator& __urng,
		result_type __min, result_type __max, false_type)
        {
	  return result_type((__urng() - __urng.min())
			     / (__urng.max() - __urng.min())
			     * (__max - __min + 1)) + __min;
	}

      _IntType _M_min;
      _IntType _M_max;
    };


  /**
   * @brief A Bernoulli random number distribution.
   *
   * Generates a sequence of true and false values with likelihood @f$ p @f$
   * that true will come up and @f$ (1 - p) @f$ that false will appear.
   */
  class bernoulli_distribution
  {
  public:
    typedef int  input_type;
    typedef bool result_type;

  public:
    /**
     * Constructs a Bernoulli distribution with likelihood @p p.
     *
     * @param __p  [IN]  The likelihood of a true result being returned.  Must
     * be in the interval @f$ [0, 1] @f$.
     */
    explicit
    bernoulli_distribution(double __p = 0.5)
    : _M_p(__p)
    { 
      _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
    }

    /**
     * Gets the @p p parameter of the distribution.
     */
    double
    p() const
    { return _M_p; }

    /**
     * Resets the distribution state.
     *
     * Does nothing for a bernoulli distribution.
     */
    void
    reset() { }

    /**
     * Gets the next value in the Bernoullian sequence.
     */
    template<class _UniformRandomNumberGenerator>
      result_type
      operator()(_UniformRandomNumberGenerator& __urng)
      {
	if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
	  return true;
	return false;
      }

    /**
     * Inserts a %bernoulli_distribution random number distribution
     * @p __x into the output stream @p __os.
     *
     * @param __os An output stream.
     * @param __x  A %bernoulli_distribution random number distribution.
     *
     * @returns The output stream with the state of @p __x inserted or in
     * an error state.
     */
    template<typename _CharT, typename _Traits>
      friend std::basic_ostream<_CharT, _Traits>&
      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		 const bernoulli_distribution& __x);

    /**
     * Extracts a %bernoulli_distribution random number distribution
     * @p __x from the input stream @p __is.
     *
     * @param __is An input stream.
     * @param __x  A %bernoulli_distribution random number generator engine.
     *
     * @returns The input stream with @p __x extracted or in an error state.
     */
    template<typename _CharT, typename _Traits>
      friend std::basic_istream<_CharT, _Traits>&
      operator>>(std::basic_istream<_CharT, _Traits>& __is,
		 bernoulli_distribution& __x)
      { return __is >> __x._M_p; }

  private:
    double _M_p;
  };


  /**
   * @brief A discrete geometric random number distribution.
   *
   * The formula for the geometric probability mass function is 
   * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
   * distribution.
   */
  template<typename _IntType = int, typename _RealType = double>
    class geometric_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _IntType  result_type;

      // constructors and member function
      explicit
      geometric_distribution(const _RealType& __p = _RealType(0.5))
      : _M_p(__p)
      {
	_GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
	_M_initialize();
      }

      /**
       * Gets the distribution parameter @p p.
       */
      _RealType
      p() const
      { return _M_p; }

      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %geometric_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %geometric_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const geometric_distribution<_IntType1, _RealType1>& __x);

      /**
       * Extracts a %geometric_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %geometric_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   geometric_distribution& __x)
        {
	  __is >> __x._M_p;
	  __x._M_initialize();
	  return __is;
	}

    private:
      void
      _M_initialize()
      { _M_log_p = std::log(_M_p); }

      _RealType _M_p;
      _RealType _M_log_p;
    };


  template<typename _RealType>
    class normal_distribution;

  /**
   * @brief A discrete Poisson random number distribution.
   *
   * The formula for the poisson probability mass function is 
   * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
   * parameter of the distribution.
   */
  template<typename _IntType = int, typename _RealType = double>
    class poisson_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _IntType  result_type;

      // constructors and member function
      explicit
      poisson_distribution(const _RealType& __mean = _RealType(1))
      : _M_mean(__mean), _M_nd()
      {
	_GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
	_M_initialize();
      }

      /**
       * Gets the distribution parameter @p mean.
       */
      _RealType
      mean() const
      { return _M_mean; }

      void
      reset()
      { _M_nd.reset(); }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %poisson_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %poisson_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const poisson_distribution<_IntType1, _RealType1>& __x);

      /**
       * Extracts a %poisson_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %poisson_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   poisson_distribution<_IntType1, _RealType1>& __x);

    private:
      void
      _M_initialize();

      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
      normal_distribution<_RealType> _M_nd;

      _RealType _M_mean;

      // Hosts either log(mean) or the threshold of the simple method.
      _RealType _M_lm_thr;
#if _GLIBCXX_USE_C99_MATH_TR1
      _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
#endif
    };


  /**
   * @brief A discrete binomial random number distribution.
   *
   * The formula for the binomial probability mass function is 
   * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
   * and @f$ p @f$ are the parameters of the distribution.
   */
  template<typename _IntType = int, typename _RealType = double>
    class binomial_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _IntType  result_type;

      // constructors and member function
      explicit
      binomial_distribution(_IntType __t = 1,
			    const _RealType& __p = _RealType(0.5))
      : _M_t(__t), _M_p(__p), _M_nd()
      {
	_GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
	_M_initialize();
      }

      /**
       * Gets the distribution @p t parameter.
       */
      _IntType
      t() const
      { return _M_t; }
      
      /**
       * Gets the distribution @p p parameter.
       */
      _RealType
      p() const
      { return _M_p; }

      void
      reset()
      { _M_nd.reset(); }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %binomial_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %binomial_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const binomial_distribution<_IntType1, _RealType1>& __x);

      /**
       * Extracts a %binomial_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %binomial_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   binomial_distribution<_IntType1, _RealType1>& __x);

    private:
      void
      _M_initialize();

      template<class _UniformRandomNumberGenerator>
        result_type
        _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);

      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
      normal_distribution<_RealType> _M_nd;

      _RealType _M_q;
#if _GLIBCXX_USE_C99_MATH_TR1
      _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
	        _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
#endif
      _RealType _M_p;
      _IntType  _M_t;

      bool      _M_easy;
    };

  /* @} */ // group tr1_random_distributions_discrete

  /**
   * @addtogroup tr1_random_distributions_continuous Continuous Distributions
   * @ingroup tr1_random_distributions
   * @{
   */

  /**
   * @brief Uniform continuous distribution for random numbers.
   *
   * A continuous random distribution on the range [min, max) with equal
   * probability throughout the range.  The URNG should be real-valued and
   * deliver number in the range [0, 1).
   */
  template<typename _RealType = double>
    class uniform_real
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs a uniform_real object.
       *
       * @param __min [IN]  The lower bound of the distribution.
       * @param __max [IN]  The upper bound of the distribution.
       */
      explicit
      uniform_real(_RealType __min = _RealType(0),
		   _RealType __max = _RealType(1))
      : _M_min(__min), _M_max(__max)
      {
	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
      }

      result_type
      min() const
      { return _M_min; }

      result_type
      max() const
      { return _M_max; }

      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng)
        { return (__urng() * (_M_max - _M_min)) + _M_min; }

      /**
       * Inserts a %uniform_real random number distribution @p __x into the
       * output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %uniform_real random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const uniform_real<_RealType1>& __x);

      /**
       * Extracts a %unform_real random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %uniform_real random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   uniform_real<_RealType1>& __x);

    private:
      _RealType _M_min;
      _RealType _M_max;
    };


  /**
   * @brief An exponential continuous distribution for random numbers.
   *
   * The formula for the exponential probability mass function is 
   * @f$ p(x) = \lambda e^{-\lambda x} @f$.
   *
   * <table border=1 cellpadding=10 cellspacing=0>
   * <caption align=top>Distribution Statistics</caption>
   * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
   * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
   * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
   * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
   * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
   * </table>
   */
  template<typename _RealType = double>
    class exponential_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs an exponential distribution with inverse scale parameter
       * @f$ \lambda @f$.
       */
      explicit
      exponential_distribution(const result_type& __lambda = result_type(1))
      : _M_lambda(__lambda)
      { 
	_GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
      }

      /**
       * Gets the inverse scale parameter of the distribution.
       */
      _RealType
      lambda() const
      { return _M_lambda; }

      /**
       * Resets the distribution.
       *
       * Has no effect on exponential distributions.
       */
      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng)
        { return -std::log(__urng()) / _M_lambda; }

      /**
       * Inserts a %exponential_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %exponential_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const exponential_distribution<_RealType1>& __x);

      /**
       * Extracts a %exponential_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %exponential_distribution random number
       *            generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   exponential_distribution& __x)
        { return __is >> __x._M_lambda; }

    private:
      result_type _M_lambda;
    };


  /**
   * @brief A normal continuous distribution for random numbers.
   *
   * The formula for the normal probability mass function is 
   * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}} 
   *            e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
   */
  template<typename _RealType = double>
    class normal_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs a normal distribution with parameters @f$ mean @f$ and
       * @f$ \sigma @f$.
       */
      explicit
      normal_distribution(const result_type& __mean = result_type(0),
			  const result_type& __sigma = result_type(1))
      : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
      { 
	_GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
      }

      /**
       * Gets the mean of the distribution.
       */
      _RealType
      mean() const
      { return _M_mean; }

      /**
       * Gets the @f$ \sigma @f$ of the distribution.
       */
      _RealType
      sigma() const
      { return _M_sigma; }

      /**
       * Resets the distribution.
       */
      void
      reset()
      { _M_saved_available = false; }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %normal_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %normal_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const normal_distribution<_RealType1>& __x);

      /**
       * Extracts a %normal_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %normal_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   normal_distribution<_RealType1>& __x);

    private:
      result_type _M_mean;
      result_type _M_sigma;
      result_type _M_saved;
      bool        _M_saved_available;     
    };


  /**
   * @brief A gamma continuous distribution for random numbers.
   *
   * The formula for the gamma probability mass function is 
   * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
   */
  template<typename _RealType = double>
    class gamma_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs a gamma distribution with parameters @f$ \alpha @f$.
       */
      explicit
      gamma_distribution(const result_type& __alpha_val = result_type(1))
      : _M_alpha(__alpha_val)
      { 
	_GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
	_M_initialize();
      }

      /**
       * Gets the @f$ \alpha @f$ of the distribution.
       */
      _RealType
      alpha() const
      { return _M_alpha; }

      /**
       * Resets the distribution.
       */
      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %gamma_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %gamma_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const gamma_distribution<_RealType1>& __x);

      /**
       * Extracts a %gamma_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %gamma_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   gamma_distribution& __x)
        {
	  __is >> __x._M_alpha;
	  __x._M_initialize();
	  return __is;
	}

    private:
      void
      _M_initialize();

      result_type _M_alpha;

      // Hosts either lambda of GB or d of modified Vaduva's.
      result_type _M_l_d;
    };

  /* @} */ // group tr1_random_distributions_continuous
  /* @} */ // group tr1_random_distributions
  /* @} */ // group tr1_random

_GLIBCXX_END_NAMESPACE
}

#include <tr1/random.tcc>

#endif // _TR1_RANDOM
