RandomCanonical.hpp
Go to the documentation of this file.
00001 /**
00002  * \file RandomCanonical.hpp
00003  * \brief Header for RandomCanonical.
00004  *
00005  * Use the random bits from Generator to produce random integers of various
00006  * sizes, random reals with various precisions, a random probability, etc.
00007  *
00008  * Written by Charles Karney <charles@karney.com> and licensed under the LGPL.
00009  * For more information, see http://randomlib.sourceforge.net/
00010  **********************************************************************/
00011 
00012 #if !defined(RANDOMCANONICAL_HPP)
00013 #define RANDOMCANONICAL_HPP "$Id: RandomCanonical.hpp 6723 2010-01-11 14:20:10Z ckarney $"
00014 
00015 #include <bitset>
00016 #include "RandomLib/RandomPower2.hpp"
00017 #include "RandomLib/RandomEngine.hpp"
00018 
00019 namespace RandomLib {
00020   /**
00021    * \brief Generate random integers, reals, and booleans.
00022    *
00023    * Use the random bits from Generator to produce random integers of various
00024    * sizes, random reals with various precisions, a random probability, etc.
00025    * RandomCanonical assumes that Generator produces random results as 32-bit
00026    * quantities (of type uint32_t) via Generator::Ran32(), 64-bit quantities
00027    * (of type uint64_t) via Generator::Ran64(), and in "natural" units of
00028    * Generator::width bits (of type Generator::result_type) via
00029    * Generator::Ran().
00030    *
00031    * For the most part this class uses Ran() when needing \a width or fewer
00032    * bits, otherwise it uses Ran64().  However, when \a width = 64, the
00033    * resulting code is RandomCanonical::Unsigned(\e n) is inefficient because
00034    * of the 64-bit arithmetic.  For this reason RandomCanonical::Unsigned(\e n)
00035    * uses Ran32() if less than 32 bits are required (even though this results
00036    * in more numbers being produced by the Generator).
00037    *
00038    * This class has been tested with the 32-bit and 64-bit versions of MT19937
00039    * and SFMT19937.  Other random number generators could be used provided that
00040    * they provide a whole number of random bits so that Ran() is uniformly
00041    * distributed in [0,2<sup><i>w</i></sup>).  Probably some modifications
00042    * would be needed if \e w is not 32 or 64.
00043    **********************************************************************/
00044   template<class Generator>
00045   class RandomCanonical : public Generator {
00046   public:
00047     /**
00048      * The type of operator()().
00049      **********************************************************************/
00050     typedef typename Generator::result_type result_type;
00051     /**
00052      * The type of elements of Seed().
00053      **********************************************************************/
00054     typedef typename RandomSeed::seed_type seed_type;
00055     enum {
00056       /**
00057        * The number of random bits in result_type.
00058        **********************************************************************/
00059       width = Generator::width
00060     };
00061 
00062     /** \name Constructors which set the seed
00063      **********************************************************************/
00064     ///@{
00065     /**
00066      * Initialize from a vector.
00067      **********************************************************************/
00068     template<typename IntType>
00069     explicit RandomCanonical(const std::vector<IntType>& v)
00070       throw(std::bad_alloc) : Generator(v) {}
00071     /**
00072      * Initialize from a pair of iterator setting seed to [\a a, \a b)
00073      **********************************************************************/
00074     template<typename InputIterator>
00075     RandomCanonical(InputIterator a, InputIterator b) : Generator(a, b) {}
00076     /**
00077      * Initialize with seed [\a n]
00078      **********************************************************************/
00079     explicit RandomCanonical(seed_type n) throw(std::bad_alloc);
00080     /**
00081      * Initialize with seed [SeedVector()]
00082      **********************************************************************/
00083     RandomCanonical() throw(std::bad_alloc) : Generator() {}
00084     /**
00085      * Initialize from a string.  See RandomCanonical::StringToVector
00086      **********************************************************************/
00087     explicit RandomCanonical(const std::string& s) throw(std::bad_alloc)
00088       : Generator(s) {}
00089     ///@}
00090 
00091     /** \name Member functions returning integers
00092      **********************************************************************/
00093     ///@{
00094     /**
00095      * Return a raw result in [0, 2<sup><i>w</i></sup>) from the
00096      * underlying Generator.
00097      **********************************************************************/
00098     result_type operator()() throw() { return Generator::Ran(); }
00099 
00100     /**
00101      * A random integer in [0, \a n).  This allows a RandomCanonical object to
00102      * be passed to those standard template library routines that require
00103      * random numbers.  E.g.,
00104      * \code
00105      *   RandomCanonical r;
00106      *   int a[] = {0, 1, 2, 3, 4};
00107      *   std::random_shuffle(a, a+5, r);
00108      * \endcode
00109      **********************************************************************/
00110     result_type operator()(result_type n) throw()
00111     { return Integer<result_type>(n); }
00112 
00113     // Integer results (binary range)
00114 
00115     /**
00116      * A random integer of type IntType in [0, 2<sup><i>b</i></sup>).
00117      **********************************************************************/
00118     template<typename IntType, int bits> IntType Integer() throw() {
00119       // A random integer of type IntType in [0, 2^bits)
00120       STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
00121                     std::numeric_limits<IntType>::radix == 2,
00122                     "Integer<T,b>(): bad integer type IntType");
00123       // Check that we have enough digits in Ran64
00124       STATIC_ASSERT(bits > 0 && bits <= std::numeric_limits<IntType>::digits &&
00125                     bits <= 64, "Integer<T,b>(): invalid value for bits");
00126       // Prefer masking to shifting so that we don't have to worry about sign
00127       // extension (a non-issue, because Ran/64 are unsigned?).
00128       return bits <= width ?
00129         IntType(Generator::Ran() & Generator::mask
00130                 >> (bits <= width ? width - bits : 0)) :
00131         IntType(Generator::Ran64() & u64::mask >> (64 - bits));
00132     }
00133 
00134     /**
00135      * A random integer in [0, 2<sup><i>b</i></sup>).
00136      **********************************************************************/
00137     template<int bits>
00138     result_type Integer() throw() { return Integer<result_type, bits>(); }
00139 
00140     /**
00141      * A random integer of type IntType in
00142      * [std::numeric_limits<IntType>::min(), std::numeric_limits::max()].
00143      **********************************************************************/
00144     template<typename IntType> IntType Integer() throw();
00145 
00146     /**
00147      * A random result_type in [0, std::numeric_limits<result_type>::max()].
00148      **********************************************************************/
00149     result_type Integer() throw()
00150     { return Integer<result_type>(); }
00151 
00152     // Integer results (finite range)
00153 
00154     /**
00155      * A random integer of type IntType in [0, \a n). \e Excludes \a n.  If \a
00156      * n == 0, treat as std::numeric_limits::max() + 1.  If \a n < 0, return 0.
00157      * Compare RandomCanonical::Integer<int>(0) which returns a result in
00158      * [0,2<sup>31</sup>) with RandomCanonical::Integer<int>() which returns a
00159      * result in [-2<sup>31</sup>,2<sup>31</sup>).
00160      **********************************************************************/
00161     template<typename IntType> IntType Integer(IntType n) throw();
00162     /**
00163      * A random integer of type IntType in Closed interval [0, \a n].  \e
00164      * Includes \a n.  If \a n < 0, return 0.
00165      **********************************************************************/
00166     template<typename IntType> IntType IntegerC(IntType n) throw();
00167     /**
00168      * A random integer of type IntType in Closed interval [\a m, \a n].  \e
00169      * Includes both endpoints.  If \a n < \a m, return \a m.
00170      **********************************************************************/
00171     template<typename IntType> IntType IntegerC(IntType m, IntType n) throw();
00172     ///@}
00173 
00174     /** \name Member functions returning real fixed-point numbers
00175      **********************************************************************/
00176     ///@{
00177     /**
00178      * In the description of the functions FixedX returning \ref fixed
00179      * "fixed-point" numbers, \e u is a random real number uniformly
00180      * distributed in (0, 1), \e p is the precision, and \e h =
00181      * 1/2<sup><i>p</i></sup>.  Each of the functions come in three variants,
00182      * e.g.,
00183      *   - RandomCanonical::Fixed<RealType,p>() --- return \ref fixed
00184      *    "fixed-point" real of type RealType, precision \e p;
00185 
00186      *   - RandomCanonical::Fixed<RealType>() --- as above with \e p =
00187      *     std::numeric_limits<RealType>::digits;
00188      *   - RandomCanonical::Fixed() --- as above with RealType = double.
00189      *
00190      * See the \ref reals "summary" for a comparison of the functions.
00191      *
00192      * Return \e i \e h with \e i in [0,2<sup><i>p</i></sup>) by rounding \e u
00193      * down to the previous \ref fixed "fixed" real.  Result is in default
00194      * interval [0,1).
00195      **********************************************************************/
00196     template<typename RealType, int prec> RealType Fixed() throw() {
00197       // RandomCanonical reals in [0, 1).  Results are of the form i/2^prec for
00198       // integer i in [0,2^prec).
00199       STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
00200                     std::numeric_limits<RealType>::radix == 2,
00201                     "Fixed(): bad real type RealType");
00202       STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
00203                     "Fixed(): invalid precision");
00204       RealType x = 0;           // Accumulator
00205       int s = 0;                // How many bits so far
00206       // Let n be the loop count.  Typically prec = 24, n = 1 for float; prec =
00207       // 53, n = 2 for double; prec = 64, n = 2 for long double.  For Sun
00208       // Sparc's, we have prec = 113, n = 4 for long double.  For Windows, long
00209       // double is the same as double (prec = 53).
00210       do {
00211         s += width;
00212         x += RandomPower2::shiftf<RealType>
00213           (RealType(Generator::Ran() >> (s > prec ? s - prec : 0)),
00214            -(s > prec ? prec : s));
00215       } while (s < prec);
00216       return x;
00217     }
00218     /**
00219      * See documentation for RandomCanonical::Fixed<RealType,prec>().
00220      **********************************************************************/
00221     template<typename RealType> RealType Fixed() throw()
00222     { return Fixed<RealType, std::numeric_limits<RealType>::digits>(); }
00223     /**
00224      * See documentation for RandomCanonical::Fixed<RealType,prec>().
00225      **********************************************************************/
00226     double Fixed() throw() { return Fixed<double>(); }
00227 
00228     /**
00229      * An alias for RandomCanonical::Fixed<RealType>().  Returns a random
00230      * number of type RealType in [0,1).
00231      **********************************************************************/
00232     template<typename RealType> RealType Real() throw()
00233     { return Fixed<RealType>(); }
00234     /**
00235      * An alias for RandomCanonical::Fixed().  Returns a random double in
00236      * [0,1).
00237      **********************************************************************/
00238     double Real() throw() { return Fixed(); }
00239 
00240     /**
00241      * Return \e i \e h with \e i in (0,2<sup><i>p</i></sup>] by rounding \e u
00242      * up to the next \ref fixed "fixed" real.  Result is in upper interval
00243      * (0,1].
00244      **********************************************************************/
00245     template<typename RealType, int prec> RealType FixedU() throw()
00246     { return RealType(1) - Fixed<RealType, prec>(); }
00247     /**
00248      * See documentation for RandomCanonical::FixedU<RealType,prec>().
00249      **********************************************************************/
00250     template<typename RealType> RealType FixedU() throw()
00251     { return FixedU<RealType, std::numeric_limits<RealType>::digits>(); }
00252     /**
00253      * See documentation for RandomCanonical::FixedU<RealType,prec>().
00254      **********************************************************************/
00255     double FixedU() throw() { return FixedU<double>(); }
00256 
00257     /**
00258      * Return \e i \e h with \e i in [0,2<sup><i>p</i></sup>] by rounding \e u
00259      * to the nearest \ref fixed "fixed" real.  Result is in nearest interval
00260      * [0,1].  The probability of returning interior values is <i>h</i> while
00261      * the probability of returning the endpoints is <i>h</i>/2.
00262      **********************************************************************/
00263     template<typename RealType, int prec> RealType FixedN() throw() {
00264       const RealType x = Fixed<RealType, prec>();
00265       return x || Boolean() ? x : RealType(1);
00266     }
00267     /**
00268      * See documentation for RandomCanonical::FixedN<RealType,prec>().
00269      **********************************************************************/
00270     template<typename RealType> RealType FixedN() throw()
00271     { return FixedN<RealType, std::numeric_limits<RealType>::digits>(); }
00272     /**
00273      * See documentation for RandomCanonical::FixedN<RealType,prec>().
00274      **********************************************************************/
00275     double FixedN() throw() { return FixedN<double>(); }
00276 
00277     /**
00278      * Return \e i \e h with \e i in [-2<sup><i>p</i></sup>,
00279      * 2<sup><i>p</i></sup>] by rounding 2\e u - 1 to the nearest \ref fixed
00280      * "fixed" real.  Result is in wide interval [-1,1].  The probability of
00281      * returning interior values is <i>h</i>/2 while the probability of
00282      * returning the endpoints is <i>h</i>/4.
00283      **********************************************************************/
00284     template<typename RealType, int prec> RealType FixedW() throw() {
00285       // Random reals in [-1, 1].  Round random in [-1, 1] to nearest multiple
00286       // of 1/2^prec.  Results are of the form i/2^prec for integer i in
00287       // [-2^prec,2^prec].
00288       STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
00289                     std::numeric_limits<RealType>::radix == 2,
00290                     "FixedW(): bad real type RealType");
00291       STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
00292                     "FixedW(): invalid precision");
00293       RealType x = -RealType(1); // Accumulator
00294       int s = -1;               // How many bits so far
00295       do {
00296         s += width;
00297         x += RandomPower2::shiftf<RealType>
00298           (RealType(Generator::Ran() >> (s > prec ? s - prec : 0)),
00299            -(s > prec ? prec : s));
00300       } while (s < prec);
00301       return (x + RealType(1) != RealType(0)) || Boolean() ? x : RealType(1);
00302     }
00303     /**
00304      * See documentation for RandomCanonical::FixedW<RealType,prec>().
00305      **********************************************************************/
00306     template<typename RealType> RealType FixedW() throw()
00307     { return FixedW<RealType, std::numeric_limits<RealType>::digits>(); }
00308     /**
00309      * See documentation for RandomCanonical::FixedW<RealType,prec>().
00310      **********************************************************************/
00311     double FixedW() throw() { return FixedW<double>(); }
00312 
00313     /**
00314      * Return (<i>i</i>+1/2)\e h with \e i in [2<sup><i>p</i>-1</sup>,
00315      * 2<sup><i>p</i>-1</sup>) by rounding \e u - 1/2 to nearest offset \ref
00316      * fixed "fixed" real.  Result is in symmetric interval (-1/2,1/2).
00317      **********************************************************************/
00318     template<typename RealType, int prec> RealType FixedS() throw()
00319     { return Fixed<RealType, prec>() -
00320         ( RealType(1) - RandomPower2::pow2<RealType>(-prec) ) / 2; }
00321     /**
00322      * See documentation for RandomCanonical::FixedS<RealType,prec>().
00323      **********************************************************************/
00324     template<typename RealType> RealType FixedS() throw()
00325     { return FixedS<RealType, std::numeric_limits<RealType>::digits>(); }
00326     /**
00327      * See documentation for RandomCanonical::FixedS<RealType,prec>().
00328      **********************************************************************/
00329     double FixedS() throw() { return FixedS<double>(); }
00330 
00331     /**
00332      * Return \e i \e h with \e i in (0,2<sup><i>p</i></sup>) by rounding (1 -
00333      * \e h)\e u up to next \ref fixed "fixed" real.  Result is in open
00334      * interval (0,1).
00335      **********************************************************************/
00336     template<typename RealType, int prec> RealType FixedO() throw() {
00337       // A real of type RealType in (0, 1) with precision prec
00338       STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
00339                     std::numeric_limits<RealType>::radix == 2,
00340                     "FixedO(): bad real type RealType");
00341       STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
00342                     "FixedO(): invalid precision");
00343       RealType x;
00344       // Loop executed 2^prec/(2^prec-1) times on average.
00345       do
00346         x = Fixed<RealType, prec>();
00347       while (x == 0);
00348       return x;
00349     }
00350     /**
00351      * See documentation for RandomCanonical::FixedO<RealType,prec>().
00352      **********************************************************************/
00353     template<typename RealType> RealType FixedO() throw()
00354     { return FixedO<RealType, std::numeric_limits<RealType>::digits>(); }
00355     /**
00356      * See documentation for RandomCanonical::FixedO<RealType,prec>().
00357      **********************************************************************/
00358     double FixedO() throw() { return FixedO<double>(); }
00359 
00360     /**
00361      * Return \e i \e h with \e i in [0,2<sup><i>p</i></sup>] by rounding (1 +
00362      * \e h)\e u down to previous \ref fixed "fixed" real.  Result is in closed
00363      * interval [0,1].
00364      **********************************************************************/
00365     template<typename RealType, int prec> RealType FixedC() throw() {
00366       // A real of type RealType in [0, 1] with precision prec
00367       STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
00368                     std::numeric_limits<RealType>::radix == 2,
00369                     "FixedC(): bad real type RealType");
00370       STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
00371                     "FixedC(): invalid precision");
00372       if (prec < width) {
00373         // Sample an integer in [0, n) where n = 2^prec + 1.  This uses the
00374         // same logic as Unsigned(n - 1).  However, unlike Unsigned, there
00375         // doesn't seem to be much of a penalty for the 64-bit arithmetic here
00376         // when result_type = unsigned long long.  Presumably this is because
00377         // the compiler can do some of the arithmetic.
00378         const result_type
00379           n = (result_type(1) << (prec < width ? prec : 0)) + 1,
00380           // Computing this instead of 2^width/n suffices, because of the form
00381           // of n.
00382           r = Generator::mask / n,
00383           m = r * n;
00384         result_type u;
00385         do
00386           u = Generator::Ran();
00387         while (u >= m);
00388         // u is rv in [0, r * n)
00389         return RandomPower2::shiftf<RealType>(RealType(u / r), -prec);
00390         // Could also special case prec < 64, using Ran64().  However the
00391         // general code below is faster.
00392       } else {                  // prec >= width
00393         // Synthesize a prec+1 bit random, Y, width bits at a time.  If number
00394         // is odd, return Fixed<RealType, prec>() (w prob 1/2); else if number
00395         // is zero, return 1 (w prob 1/2^(prec+1)); else repeat.  Normalizing
00396         // probabilities on returned results we find that Fixed<RealType,
00397         // prec>() is returned with prob 2^prec/(2^prec+1), and 1 is return
00398         // with prob 1/(2^prec+1), as required.  Loop executed twice on average
00399         // and so consumes 2rvs more than rvs for Fixed<RealType, prec>().  As
00400         // in FloatZ, do NOT try to save on calls to Ran() by using the
00401         // leftover bits from Fixed.
00402         while (true) {
00403           // If prec + 1 < width then mask x with (1 << prec + 1) - 1
00404           const result_type x = Generator::Ran(); // Low width bits of Y
00405           if (x & 1u)           // Y odd?
00406             return Fixed<RealType, prec>(); // Prob 1/2 on each loop iteration
00407           if (x)
00408             continue;           // Y nonzero
00409           int s = prec + 1 - width; // Bits left to check (s >= 0)
00410           while (true) {
00411             if (s <= 0)         // We're done.  Y = 0
00412               // Prob 1/2^(prec+1) on each loop iteration
00413               return RealType(1); // We get here once every 60000 yrs (p = 64)!
00414             // Check the next min(s, width) bits.
00415             if (Generator::Ran() >> (s > width ? 0 : width - s))
00416               break;
00417             s -= width; // Decrement s
00418           }
00419         }
00420       }
00421     }
00422     /**
00423      * See documentation for RandomCanonical::FixedC<RealType,prec>().
00424      **********************************************************************/
00425     template<typename RealType> RealType FixedC() throw()
00426     { return FixedC<RealType, std::numeric_limits<RealType>::digits>(); }
00427     /**
00428      * See documentation for RandomCanonical::FixedC<RealType,prec>().
00429      **********************************************************************/
00430     double FixedC() throw() { return FixedC<double>(); }
00431     ///@}
00432 
00433     /** \name Member functions returning real floating-point numbers
00434      **********************************************************************/
00435     ///@{
00436 
00437     // The floating results produces results on a floating scale.  Here the
00438     // separation between possible results is smaller for smaller numbers.
00439 
00440     /**
00441      * In the description of the functions FloatX returning \ref floating
00442      * "floating-point" numbers, \e u is a random real number uniformly
00443      * distributed in (0, 1), \e p is the precision, and \e e is the exponent
00444      * range.  Each of the functions come in three variants, e.g.,
00445      *   - RandomCanonical::Float<RealType,p,e>() --- return \ref floating
00446      *    "floating-point" real of type RealType, precision \e p, and exponent
00447      *    range \e e;
00448      *   - RandomCanonical::Float<RealType>() --- as above with \e p =
00449      *     std::numeric_limits<RealType>::digits and \e e =
00450      *     -std::numeric_limits<RealType>::min_exponent;
00451      *   - RandomCanonical::Float() --- as above with RealType = double.
00452      *
00453      * See the \ref reals "summary" for a comparison of the functions.
00454      *
00455      * Return result is in default interval [0,1) by rounding \e u down
00456      * to the previous \ref floating "floating" real.
00457      **********************************************************************/
00458     template<typename RealType, int prec, int erange> RealType Float() throw()
00459     { return FloatZ<RealType, prec, erange, false>(0, 0); }
00460     /**
00461      * See documentation for RandomCanonical::Float<RealType,prec,erange>().
00462      **********************************************************************/
00463     template<typename RealType> RealType Float() throw() {
00464       return Float<RealType, std::numeric_limits<RealType>::digits,
00465         -std::numeric_limits<RealType>::min_exponent>();
00466     }
00467     /**
00468      * See documentation for RandomCanonical::Float<RealType,prec,erange>().
00469      **********************************************************************/
00470     double Float() throw() { return Float<double>(); }
00471 
00472     /**
00473      * Return result is in upper interval (0,1] by round \e u up to the
00474      * next \ref floating "floating" real.
00475      **********************************************************************/
00476     template<typename RealType, int prec, int erange> RealType FloatU() throw()
00477     { return FloatZ<RealType, prec, erange, true>(0, 0); }
00478     /**
00479      * See documentation for RandomCanonical::FloatU<RealType,prec,erange>().
00480      **********************************************************************/
00481     template<typename RealType> RealType FloatU() throw() {
00482       return FloatU<RealType, std::numeric_limits<RealType>::digits,
00483         -std::numeric_limits<RealType>::min_exponent>();
00484     }
00485     /**
00486      * See documentation for RandomCanonical::FloatU<RealType,prec,erange>().
00487      **********************************************************************/
00488     double FloatU() throw() { return FloatU<double>(); }
00489 
00490     /**
00491      * Return result is in nearest interval [0,1] by rounding \e u to
00492      * the nearest \ref floating "floating" real.
00493      **********************************************************************/
00494     template<typename RealType, int prec, int erange> RealType FloatN()
00495       throw() {
00496       // Use Float or FloatU each with prob 1/2, i.e., return Boolean()
00497       // ?  Float() : FloatU().  However, rather than use Boolean(), we
00498       // pick the high bit off a Ran() and pass the rest of the number
00499       // to FloatZ to use.  This saves 1/2 a call to Ran().
00500       const result_type x = Generator::Ran();
00501       return x >> width - 1 ?   // equivalent to Boolean()
00502         // Float<RealType, prec, erange>()
00503         FloatZ<RealType, prec, erange, false>(width - 1, x) :
00504         // FloatU<RealType, prec, erange>()
00505         FloatZ<RealType, prec, erange, true>(width - 1, x);
00506     }
00507     /**
00508      * See documentation for RandomCanonical::FloatN<RealType,prec,erange>().
00509      **********************************************************************/
00510     template<typename RealType> RealType FloatN() throw() {
00511       return FloatN<RealType, std::numeric_limits<RealType>::digits,
00512         -std::numeric_limits<RealType>::min_exponent>();
00513     }
00514     /**
00515      * See documentation for RandomCanonical::FloatN<RealType,prec,erange>().
00516      **********************************************************************/
00517     double FloatN() throw() { return FloatN<double>(); }
00518 
00519     /**
00520      * Return result is in wide interval [-1,1], by rounding 2\e u - 1 to the
00521      * nearest \ref floating "floating" real.
00522      **********************************************************************/
00523     template<typename RealType, int prec, int erange>
00524     RealType FloatW() throw() {
00525       const result_type x = Generator::Ran();
00526       const int y = int(x >> (width - 2));
00527       return (1 - (y & 2)) *    // Equiv to (Boolean() ? -1 : 1) *
00528         ( y & 1 ?               // equivalent to Boolean()
00529           // Float<RealType, prec, erange>()
00530           FloatZ<RealType, prec, erange, false>(width - 2, x) :
00531           // FloatU<RealType, prec, erange>()
00532           FloatZ<RealType, prec, erange, true>(width - 2, x) );
00533     }
00534     /**
00535      * See documentation for RandomCanonical::FloatW<RealType,prec,erange>().
00536      **********************************************************************/
00537     template<typename RealType> RealType FloatW() throw() {
00538       return FloatW<RealType, std::numeric_limits<RealType>::digits,
00539         -std::numeric_limits<RealType>::min_exponent>();
00540     }
00541     /**
00542      * See documentation for RandomCanonical::FloatW<RealType,prec,erange>().
00543      **********************************************************************/
00544     double FloatW() throw() { return FloatW<double>(); }
00545     ///@}
00546 
00547     /** \name Member functions returning booleans
00548      **********************************************************************/
00549     ///@{
00550     /**
00551      * A coin toss.  Equivalent to RandomCanonical::Integer<bool>().
00552      **********************************************************************/
00553     bool Boolean() throw() { return Generator::Ran() & 1u; }
00554 
00555     /**
00556      * The Bernoulli distribution, true with probability \a p.  False if \a p
00557      * <= 0; true if \a p >= 1.  Equivalent to RandomCanonical::Float() < \e p,
00558      * but typically faster.
00559      **********************************************************************/
00560     template<typename NumericType> bool Prob(NumericType p) throw();
00561 
00562     /**
00563      * True with probability \a m/n.  False if \a m <= 0 or \a n < 0; true if
00564      * \a m >= \a n.  With real types, Prob(\a x, \a y) is exact but slower
00565      * than Prob(\a x/y).
00566      **********************************************************************/
00567     template<typename NumericType>
00568     bool Prob(NumericType m, NumericType n) throw();
00569     ///@}
00570 
00571     // Bits
00572 
00573     /** \name Functions returning bitsets
00574      *  These return random bits in a std::bitset.
00575      **********************************************************************/
00576     ///@{
00577 
00578     /**
00579      * Return \e nbits random bits
00580      **********************************************************************/
00581     template<int nbits> std::bitset<nbits> Bits() throw();
00582 
00583     ///@}
00584 
00585     /**
00586      * A "global" random number generator (not thread-safe!), initialized with
00587      * a fixed seed [].
00588      **********************************************************************/
00589     static RandomCanonical Global;
00590 
00591   private:
00592     typedef RandomSeed::u32 u32;
00593     typedef RandomSeed::u64 u64;
00594     /**
00595      * A helper for Integer(\a n).  A random unsigned integer in [0, \a n].  If
00596      * \a n >= 2<sup>32</sup>, this \e must be invoked with \a onep = false.
00597      * Otherwise, it \e should be invoked with \a onep = true.
00598      **********************************************************************/
00599     template<typename UIntT>
00600     typename UIntT::type Unsigned(typename UIntT::type n) throw();
00601 
00602     /**
00603      * A helper for Float and FloatU.  Produces \a up ? FloatU() : Float().  On
00604      * entry the low \a b bits of \a m are usable random bits.
00605      **********************************************************************/
00606     template<typename RealType, int prec, int erange, bool up>
00607     RealType FloatZ(int b, result_type m) throw();
00608 
00609     /**
00610      * The one-argument version of Prob for real types
00611      **********************************************************************/
00612     template<typename RealType> bool ProbF(RealType z) throw();
00613     /**
00614      * The two-argument version of Prob for real types
00615      **********************************************************************/
00616     template<typename RealType> bool ProbF(RealType x, RealType y) throw();
00617   };
00618 
00619   template<class Generator>
00620   inline RandomCanonical<Generator>::RandomCanonical(seed_type n)
00621     throw(std::bad_alloc) : Generator(n) {
00622     // Compile-time checks on real types
00623     STATIC_ASSERT(std::numeric_limits<float>::radix == 2 &&
00624                   std::numeric_limits<double>::radix == 2 &&
00625                   std::numeric_limits<long double>::radix == 2,
00626                   "RandomCanonical: illegal floating type");
00627     STATIC_ASSERT(0 <= std::numeric_limits<float>::digits &&
00628                   std::numeric_limits<float>::digits <=
00629                   std::numeric_limits<double>::digits &&
00630                   std::numeric_limits<double>::digits <=
00631                   std::numeric_limits<long double>::digits,
00632                   "RandomCanonical: inconsisten floating precision");
00633 #if RANDOM_POWERTABLE
00634     // Checks on power2
00635     STATIC_ASSERT(std::numeric_limits<long double>::digits ==
00636                   RANDOM_LONGDOUBLEPREC,
00637                   "RandomPower2: RANDOM_LONGDOUBLEPREC incorrect");
00638     // Make sure table hasn't underflowed
00639     STATIC_ASSERT(RandomPower2::minpow >=
00640                   std::numeric_limits<float>::min_exponent -
00641                   (RANDOM_HASDENORM(float) ?
00642                    std::numeric_limits<float>::digits : 1),
00643                   "RandomPower2 table underflow");
00644     STATIC_ASSERT(RandomPower2::maxpow >= RandomPower2::minpow + 1,
00645                   "RandomPower2 table empty");
00646     // Needed by RandomCanonical::Fixed<long double>()
00647     STATIC_ASSERT(RandomPower2::minpow <=
00648                   -std::numeric_limits<long double>::digits,
00649                   "RandomPower2 minpow not small enough for long double");
00650     // Needed by ProbF
00651     STATIC_ASSERT(RandomPower2::maxpow - width >= 0,
00652                   "RandomPower2 maxpow not large enough for ProbF");
00653 #endif
00654     // Needed for RandomCanonical::Bits()
00655     STATIC_ASSERT(2 * std::numeric_limits<unsigned long>::digits - width >= 0,
00656                   "Bits<n>(): unsigned long too small");
00657   }
00658 
00659   template<class Generator> template<typename IntType>
00660   inline IntType RandomCanonical<Generator>::Integer() throw() {
00661     // A random integer of type IntType in [min(IntType), max(IntType)].
00662     STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
00663                   std::numeric_limits<IntType>::radix == 2,
00664                   "Integer: bad integer type IntType");
00665     const int d = std::numeric_limits<IntType>::digits +
00666       std::numeric_limits<IntType>::is_signed; // Include the sign bit
00667     // Check that we have enough digits in Ran64
00668     STATIC_ASSERT(d > 0 && d <= 64, "Integer: bad bit-size");
00669     if (d <= width)
00670       return IntType(Generator::Ran());
00671     else                        // d <= 64
00672       return IntType(Generator::Ran64());
00673   }
00674 
00675   template<class Generator> template<typename UIntT>
00676   inline typename UIntT::type
00677   RandomCanonical<Generator>::Unsigned(typename UIntT::type n) throw() {
00678     // A random unsigned in [0, n].  In n fits in 32-bits, call with UIntType =
00679     // u32 and onep = true else call with UIntType = u64 and onep = false.
00680     // There are a few cases (e.g., n = 0x80000000) where on a 64-bit machine
00681     // with a 64-bit Generator it would be quicker to call this with UIntType =
00682     // result_type and invoke Ran().  However this speed advantage disappears
00683     // if the argument isn't a compile time constsnt.
00684     //
00685     // Special case n == 0 is handled by the callers of Unsigned.  The
00686     // following is to guard against a division by 0 in the return statement
00687     // (but it shouldn't happen).
00688     n = n ? n : 1U;             // n >= 1
00689     // n1 = n + 1, but replace overflowed value by 1.  Overflow occurs, e.g.,
00690     // when n = u32::mask and then we have r1 = 0, m = u32::mask.
00691     const typename UIntT::type n1 = ~n ? n + 1U : 1U;
00692     // "Ratio method".  Find m = r * n1 - 1, s.t., 0 < (q - n1 ) < m <= q,
00693     // where q = max(UIntType), and sample in u in [0, m] and return u / r.  If
00694     // onep then we use Ran32() else Rand64().
00695     const typename UIntT::type
00696       // r = floor((q + 1)/n1), r1 = r - 1, avoiding overflow.  Actually
00697       // overflow can occur if std::numeric_limits<u32>::digits == 64, because
00698       // then we can have onep && n > U32_MASK.  This is however ruled out by
00699       // the callers to Unsigned.  (If Unsigned is called in this way, the
00700       // results are bogus, but there is no error condition.)
00701       r1 = ((UIntT::width == 32 ? typename UIntT::type(u32::mask) :
00702              typename UIntT::type(u64::mask)) - n) / n1,
00703       m = r1 * n1 + n;          // m = r * n1 - 1, avoiding overflow
00704     // Here r1 in [0, (q-1)/2], m in [(q+1)/2, q]
00705     typename UIntT::type u;     // Find a random number in [0, m]
00706     do
00707       // For small n1, this is executed once (since m is nearly q).  In the
00708       // worst case the loop is executed slightly less than twice on average.
00709       u = UIntT::width == 32 ? typename UIntT::type(Generator::Ran32()) :
00710         typename UIntT::type(Generator::Ran64());
00711     while (u > m);
00712     // Now u is in [0, m] = [0, r * n1), so u / r is in [0, n1) = [0, n].  An
00713     // alternative unbiased method would be u % n1; but / appears to be faster.
00714     return u / (r1 + 1U);
00715   }
00716 
00717   template<class Generator> template<typename IntType>
00718   inline IntType RandomCanonical<Generator>::Integer(IntType n) throw() {
00719     // A random integer of type IntType in [0, n).  If n == 0, treat as
00720     // max(IntType) + 1.  If n < 0, treat as 1 and return 0.
00721     // N.B. Integer<IntType>(0) is equivalent to Integer<IntType>() for
00722     // unsigned types.  For signed types, the former returns a non-negative
00723     // result and the latter returns a result in the full range.
00724     STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
00725                   std::numeric_limits<IntType>::radix == 2,
00726                   "Integer(n): bad integer type IntType");
00727     const int d = std::numeric_limits<IntType>::digits;
00728     // Check that we have enough digits in Ran64
00729     STATIC_ASSERT(d > 0 && d <= 64, "Integer(n): bad bit-size");
00730     return n > IntType(1) ?
00731       (d <= 32 || n - 1 <= IntType(u32::mask) ?
00732        IntType(Unsigned<u32>(u32::type(n - 1))) :
00733        IntType(Unsigned<u64>(u64::type(n - 1)))) :
00734       ( n ? IntType(0) :        // n == 1 || n < 0
00735         Integer<IntType, d>()); // n == 0
00736   }
00737 
00738   template<class Generator> template<typename IntType>
00739   inline IntType RandomCanonical<Generator>::IntegerC(IntType n) throw() {
00740     // A random integer of type IntType in [0, n]
00741     STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
00742                   std::numeric_limits<IntType>::radix == 2,
00743                   "IntegerC(n): bad integer type IntType");
00744     const int d = std::numeric_limits<IntType>::digits;
00745     // Check that we have enough digits in Ran64
00746     STATIC_ASSERT(d > 0 && d <= 64, "IntegerC(n): bad bit-size");
00747     return n > IntType(0) ?
00748       (d <= 32 || n <= IntType(u32::mask) ?
00749        IntType(Unsigned<u32>(u32::type(n))) :
00750        IntType(Unsigned<u64>(u64::type(n))))
00751       : IntType(0);             // n <= 0
00752   }
00753 
00754   template<class Generator> template<typename IntType>
00755   inline IntType RandomCanonical<Generator>::IntegerC(IntType m, IntType n)
00756     throw() {
00757     // A random integer of type IntType in [m, n]
00758     STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
00759                   std::numeric_limits<IntType>::radix == 2,
00760                   "IntegerC(m,n): bad integer type IntType");
00761     const int d = std::numeric_limits<IntType>::digits +
00762       std::numeric_limits<IntType>::is_signed; // Include sign bit
00763     // Check that we have enough digits in Ran64
00764     STATIC_ASSERT(d > 0 && d <= 64, "IntegerC(m,n): bad bit-size");
00765     // The unsigned subtraction, n - m, avoids the underflow that is possible
00766     // in the signed operation.
00767     return m + (n <= m ? 0 :
00768                 d <= 32 ?
00769                 IntType(IntegerC<u32::type>(u32::type(n) - u32::type(m))) :
00770                 IntType(IntegerC<u64::type>(u64::type(n) - u64::type(m))));
00771   }
00772 
00773   template<class Generator>
00774   template<typename RealType, int prec, int erange, bool up> inline
00775   RealType RandomCanonical<Generator>::FloatZ(int b, result_type m) throw() {
00776     // Produce up ? FloatU() : Float().  On entry the low b bits of m are
00777     // usable random bits.
00778     STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
00779                   std::numeric_limits<RealType>::radix == 2,
00780                   "FloatZ: bad real type RealType");
00781     STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
00782                   "FloatZ: invalid precision");
00783     STATIC_ASSERT(erange >= 0, "FloatZ: invalid exponent range");
00784     // With subnormals: condition that smallest number is representable
00785     STATIC_ASSERT(!RANDOM_HASDENORM(RealType) ||
00786                   // Need 1/2^(erange+prec) > 0
00787                   prec + erange <= std::numeric_limits<RealType>::digits -
00788                   std::numeric_limits<RealType>::min_exponent,
00789                   "FloatZ: smallest number cannot be represented");
00790     // Without subnormals :condition for no underflow in while loop
00791     STATIC_ASSERT(RANDOM_HASDENORM(RealType) ||
00792                   // Need 1/2^(erange+1) > 0
00793                   erange <= - std::numeric_limits<RealType>::min_exponent,
00794                   "FloatZ: underflow possible");
00795 
00796     // Simpler (but slower) version of FloatZ.  However this method cannot
00797     // handle the full range of exponents and, in addition, is slower on
00798     // average.
00799     // template<typename RealType, int prec, int erange, bool up>
00800     // RealType FloatZ() {
00801     //   RealType x = Fixed<RealType, erange + 1>();
00802     //   int s;                 // Determine exponent (-erange <= s <= 0)
00803     //   frexp(x, &s);          // Prob(s) = 2^(s-1)
00804     //   // Scale number in [1,2) by 2^(s-1).  If x == 0 scale number in [0,1).
00805     //   return ((up ? FixedU<RealType, prec - 1>() :
00806     //            Fixed<RealType, prec - 1>()) + (x ? 1 : 0)) *
00807     //     RandomPower2::pow2<RealType>(s - 1);
00808     // }
00809     //
00810     // Use {a, b} to denote the inteval: up ? (a, b] : [a, b)
00811     //
00812     // The code produces the number as
00813     //
00814     // Interval             count       prob = spacing
00815     // {1,2} / 2            2^(prec-1)  1/2^prec
00816     // {1,2} / 2^s          2^(prec-1)  1/2^(prec+s-1)      for s = 2..erange+1
00817     // {0,1} / 2^(erange+1) 2^(prec-1)  1/2^(prec+erange)
00818 
00819     // Generate prec bits in {0, 1}
00820     RealType x = up ? FixedU<RealType, prec>() : Fixed<RealType, prec>();
00821     // Use whole interval if erange == 0 and handle the interval {1/2, 1}
00822     if (erange == 0 || (up ? x > RealType(0.5) : x >= RealType(0.5)))
00823       return x;
00824     x += RealType(0.5);         // Shift remaining portion to {1/2, 1}
00825     if (b == 0) {
00826       m = Generator::Ran();     // Random bits
00827       b = width;        // Bits available in m
00828     }
00829     int sm = erange;            // sm = erange - s + 2
00830     // Here x in {1, 2} / 2, prob 1/2
00831     do {                        // s = 2 thru erange+1, sm = erange thru 1
00832       x /= 2;
00833       if (m & 1u)
00834         return x;               // x in {1, 2} / 2^s, prob 1/2^s
00835       if (--b)
00836         m >>= 1;
00837       else {
00838         m = Generator::Ran();
00839         b = width;
00840       }
00841     } while (--sm);
00842     // x in {1, 2} / 2^(erange+1), prob 1/2^(erange+1).  Don't worry about the
00843     // possible overhead of the calls to pow here.  We rarely get here.
00844     if (RANDOM_HASDENORM(RealType) || // subnormals allowed
00845         // No subnormals but smallest number still representable
00846         prec + erange <= -std::numeric_limits<RealType>::min_exponent + 1 ||
00847         // Possibility of underflow, so have to test on x.  Here, we have -prec
00848         // + 1 < erange + min_exp <= 0 so pow2 can be used
00849         x >= (RealType(1) +
00850               RandomPower2::pow2<RealType>
00851               (erange + std::numeric_limits<RealType>::min_exponent)) *
00852         (erange + 1 > -RandomPower2::minpow ?
00853          std::pow(RealType(2), - erange - 1) :
00854          RandomPower2::pow2<RealType>(- erange - 1)))
00855       // shift x to {0, 1} / 2^(erange+1)
00856       // Use product of pow's since max(erange + 1) =
00857       // std::numeric_limits<RealType>::digits -
00858       // std::numeric_limits<RealType>::min_exponent and pow may underflow
00859       return x -
00860         (erange + 1 > -RandomPower2::minpow ?
00861          std::pow(RealType(2), -(erange + 1)/2) *
00862          std::pow(RealType(2), -(erange + 1) + (erange + 1)/2) :
00863          RandomPower2::pow2<RealType>(- erange - 1));
00864     else
00865       return up ?               // Underflow to up ? min() : 0
00866         // pow is OK here.
00867         std::pow(RealType(2), std::numeric_limits<RealType>::min_exponent - 1)
00868         : RealType(0);
00869   }
00870 
00871   /// \cond SKIP
00872   // True with probability n.  Since n is an integer this is equivalent to n >
00873   // 0.
00874   template<class Generator> template<typename IntType>
00875   inline bool RandomCanonical<Generator>::Prob(IntType n) throw() {
00876     STATIC_ASSERT(std::numeric_limits<IntType>::is_integer,
00877                   "Prob(n): invalid integer type IntType");
00878     return n > 0;
00879   }
00880   /// \endcond
00881 
00882   // True with probability p.  true if p >= 1, false if p <= 0 or isnan(p).
00883   template<class Generator> template<typename RealType>
00884   inline bool RandomCanonical<Generator>::ProbF(RealType p) throw() {
00885     // Simulate Float<RealType>() < p.  The definition involves < (instead of
00886     // <=) because Float<RealType>() is in [0,1) so it is "biased downwards".
00887     // Instead of calling Float<RealType>(), we generate only as many bits as
00888     // necessary to determine the result.  This makes the routine considerably
00889     // faster than Float<RealType>() < x even for type float.  Compared with
00890     // the inexact Fixed<RealType>() < p, this is about 20% slower with floats
00891     // and 20% faster with doubles and long doubles.
00892     STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
00893                   std::numeric_limits<RealType>::radix == 2,
00894                   "ProbF(p): invalid real type RealType");
00895     // Generate Real() c bits at a time where c is chosen so that cast doesn't
00896     // loose any bits and so that it uses up just one rv.
00897     const int c = std::numeric_limits<RealType>::digits > width ?
00898       width : std::numeric_limits<RealType>::digits;
00899     STATIC_ASSERT(c > 0, "ProbF(p): Illegal chunk size");
00900     const RealType mult = RandomPower2::pow2<RealType>(c);
00901     // A recursive definition:
00902     //
00903     // return p > RealType(0) &&
00904     //   (p >= RealType(1) ||
00905     //    ProbF(mult * p - RealType(Integer<result_type, c>())));
00906     //
00907     // Pre-loop tests needed to avoid overflow
00908     if (!(p > RealType(0)))     // Ensure false if isnan(p)
00909       return false;
00910     else if (p >= RealType(1))
00911       return true;
00912     do {                        // Loop executed slightly more than once.
00913       // Here p is in (0,1).  Write Fixed() = (X + y)/mult where X is an
00914       // integer in [0, mult) and y is a real in [0,1).  Then Fixed() < p
00915       // becomes p' > y where p' = p * mult - X.
00916       p *= mult;                // Form p'.  Multiplication is exact
00917       p -= RealType(Integer<result_type, c>()); // Also exact
00918       if (p <= RealType(0))
00919         return false;           // If p' <= 0 the result is definitely false.
00920       // Exit if p' >= 1; the result is definitely true.  Otherwise p' is in
00921       // (0,1) and the result is true with probability p'.
00922     } while (p < RealType(1));
00923     return true;
00924   }
00925 
00926   /// \cond SKIP
00927   // True with probability m/n (ratio of integers)
00928   template<class Generator> template<typename IntType>
00929   inline bool RandomCanonical<Generator>::Prob(IntType m, IntType n) throw() {
00930     STATIC_ASSERT(std::numeric_limits<IntType>::is_integer,
00931                   "Prob(m,n): invalid integer type IntType");
00932     // Test n >= 0 without triggering compiler warning when n = unsigned
00933     return m > 0 && (n > 0 || n == 0) && (m >= n || Integer<IntType>(n) < m);
00934   }
00935   /// \endcond
00936 
00937   // True with probability x/y (ratio of reals)
00938   template<class Generator> template<typename RealType>
00939   inline bool RandomCanonical<Generator>::ProbF(RealType x, RealType y)
00940     throw() {
00941     STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
00942                   std::numeric_limits<RealType>::radix == 2,
00943                   "ProbF(x,y): invalid real type RealType");
00944     if (!(x > RealType(0) && y >= RealType(0))) // Do the trivial cases
00945       return false;             // Also if either x or y is a nan
00946     else if (x >= y)
00947       return true;
00948     // Now 0 < x < y
00949     int ex, ey;                 // Extract exponents
00950     x = std::frexp(x, &ex);
00951     y = std::frexp(y, &ey);
00952     // Now 0.5 <= x,y < 1
00953     if (x > y) {
00954       x *= RealType(0.5);
00955       ++ex;
00956     }
00957     int s = ey - ex;
00958     // Now 0.25 < x < y < 1, s >= 0, 0.5 < x/y <= 1
00959     // Return true with prob 2^-s * x/y
00960     while (s > 0) {             // With prob 1 - 2^-s return false
00961       // Check the next min(s, width) bits.
00962       if (Generator::Ran() >> (s > width ? 0 : width - s))
00963         return false;
00964       s -= width;
00965     }
00966     // Here with prob 2^-s
00967     const int c = std::numeric_limits<RealType>::digits > width ?
00968       width : std::numeric_limits<RealType>::digits;
00969     STATIC_ASSERT(c > 0, "ProbF(x,y): invalid chunk size");
00970     const RealType mult = RandomPower2::pow2<RealType>(c);
00971     // Generate infinite precision z = Real().
00972     // As soon as we know z > y, start again
00973     // As soon as we know z < x, return true
00974     // As soon as we know x < z < y, return false
00975     while (true) {              // Loop executed 1/x on average
00976       double xa = x, ya = y;
00977       while (true) {            // Loop executed slightly more than once
00978         // xa <= ya, ya > 0, xa < 1.
00979         // Here (xa,ya) are in (0,1).  Write Fixed() = (X + y)/mult where X is
00980         // an integer in [0, mult) and y is a real in [0,1).  Then Fixed() < z
00981         // becomes z' > y where z' = z * mult - X.
00982         const RealType d = RealType(Integer<result_type, c>());
00983         if (ya < RealType(1)) {
00984           ya *= mult;           // Form ya'
00985           ya -= d;
00986           if (ya <= RealType(0))
00987             break;              // z > y, start again
00988         }
00989         if (xa > RealType(0)) {
00990           xa *= mult;           // From xa'
00991           xa -= d;
00992           if (xa >= RealType(1))
00993             return true;        // z < x
00994         }
00995         if (xa <= RealType(0) && ya >= RealType(1))
00996           return false;         // x < z < y
00997       }
00998     }
00999   }
01000 
01001   template<class Generator> template<int nbits>
01002   inline std::bitset<nbits> RandomCanonical<Generator>::Bits() throw() {
01003     // Return nbits random bits
01004     STATIC_ASSERT(nbits >= 0, "Bits<n>(): invalid nbits");
01005     const int ulbits = std::numeric_limits<unsigned long>::digits;
01006     std::bitset<nbits> b;
01007     int m = nbits;
01008 
01009     while (m > 0) {
01010       result_type x = Generator::Ran();
01011       if (m < nbits)
01012         b <<= (width > ulbits ? width - ulbits : width);
01013       if (width > ulbits &&     // x doesn't fit into an unsigned long
01014           // But on the first time through the loop the most significant bits
01015           // may not be needed.
01016           (nbits > ((nbits-1)/width) * width + ulbits ||
01017            m < nbits)) {
01018         // Handle most significant width - ulbits bits.
01019         b |= (unsigned long)(x >> (width > ulbits ? ulbits : 0));
01020         b <<= ulbits;
01021       }
01022       // Bitsets can be constructed from an unsigned long.
01023       b |= (unsigned long)(x);
01024       m -= width;
01025     }
01026     return b;
01027   }
01028 
01029 #if 0
01030   /**
01031    * MRandom32 is RandomCanonical using 32-bit version of MT19937
01032    **********************************************************************/
01033   typedef RandomCanonical<MRandomGenerator32> MRandom32;
01034   /**
01035    * MRandom64 is RandomCanonical using 64-bit version of MT19937
01036    **********************************************************************/
01037   typedef RandomCanonical<MRandomGenerator64> MRandom64;
01038 
01039   /**
01040    * SRandom32 is RandomCanonical using 32-bit version of SFMT19937
01041    **********************************************************************/
01042   typedef RandomCanonical<SRandomGenerator32> SRandom32;
01043   /**
01044    * SRandom64 is RandomCanonical using 64-bit version of SFMT19937
01045    **********************************************************************/
01046   typedef RandomCanonical<SRandomGenerator64> SRandom64;
01047 #endif
01048   /// \cond SKIP
01049 
01050   // The specialization of Integer<bool> is required because bool(int) in the
01051   // template definition will test for non-zeroness instead of returning the
01052   // low bit.
01053 #define RANDOMCANONICAL_SPECIALIZE(RandomType)                          \
01054   template<> template<>                                                 \
01055   inline bool RandomType::Integer<bool>()                               \
01056     throw() { return Boolean(); }                                       \
01057   RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, float)                    \
01058   RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, double)                   \
01059   RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, long double)
01060 
01061   // Connect Prob(p) with ProbF(p) for all real types
01062   // Connect Prob(x, y) with ProbF(x, y) for all real types
01063 #define RANDOMCANONICAL_SPECIALIZE_PROB(RandomType,RealType)            \
01064   template<> template<>                                                 \
01065   inline bool RandomType::Prob<RealType>(RealType p)                    \
01066     throw() { return ProbF<RealType>(p); }                              \
01067   template<> template<>                                                 \
01068   inline bool RandomType::Prob<RealType>(RealType x, RealType y)        \
01069     throw() { return ProbF<RealType>(x, y); }
01070 
01071   RANDOMCANONICAL_SPECIALIZE(RandomCanonical<MRandomGenerator32>)
01072   RANDOMCANONICAL_SPECIALIZE(RandomCanonical<MRandomGenerator64>)
01073   RANDOMCANONICAL_SPECIALIZE(RandomCanonical<SRandomGenerator32>)
01074   RANDOMCANONICAL_SPECIALIZE(RandomCanonical<SRandomGenerator64>)
01075 
01076 #undef RANDOMCANONICAL_SPECIALIZE
01077 #undef RANDOMCANONICAL_SPECIALIZE_PROB
01078 
01079   /// \endcond
01080 } // namespace RandomLib
01081 
01082 #endif  // RANDOMCANONICAL_HPP