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