• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files

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