Home || Visual Search || Applications || Architecture || Important Messages || OGL || Src

Random.h

Go to the documentation of this file.
00001 #ifndef Impala_Util_NewRandom_h
00002 #define Impala_Util_NewRandom_h
00003 
00004 #include <ctime>
00005 #include <cstdlib>
00006 #include <set>
00007 
00008 #include "Basis/ILog.h"
00009 #include "Basis/NativeTypes.h"
00010 
00011 namespace Impala
00012 {
00013 namespace Util
00014 {
00015 
00028 class Random
00029 {
00030 public:
00031     static Random&
00032     GetGlobal()
00033     {
00034         static Random globalInstance;
00035         return globalInstance;
00036     }
00037 
00038 
00039     Random()
00040     {
00041         SetSeed(1);
00042     }
00043     
00044     ~Random()
00045     {
00046     }
00047     
00048     void
00049     SetSeed(long seed)
00050     {
00051         mSeed = (seed ^ 0x5DEECE66DLL) & ((1LL << 48) - 1);
00052     }
00053     
00054     void
00055     RandomizeSeed()
00056     {
00057         SetSeed(time(0));
00058     }
00059 
00061     int
00062     GetRandMax()
00063     {
00064         return (1LL << cRandomIntBits) -1;
00065     }
00066 
00068     int
00069     GetInt()
00070     {
00071         return Next(cRandomIntBits);
00072     }
00073 
00075     int
00076     GetInt(int upperBound)
00077     {
00078         if(upperBound < 0)
00079         {
00080             ILOG_ERROR("upperbound must be positive");
00081             return 0;
00082         }
00083         if(upperBound > GetRandMax())
00084             ILOG_WARNING(upperBound <<" upperBound > rand max "<< GetRandMax());
00085         
00086         // special case for when upperBound is a power of two: return the
00087         // higher-order bits in stead of the lower order. These have better
00088         // statistical properties.
00089         if(!((upperBound -1) & upperBound)) // (x-1)&x is 0 iff x is a power of two
00090             return (int)((upperBound * (UInt64)Next(31)) >> 31);
00091 
00092         // Because of the modulo some values would be returned more than
00093         // others. This loop rejects these numbers
00094         int bits, val;
00095         do {
00096             bits = Next(31);
00097             val = bits % upperBound;
00098         } while(bits - val + (upperBound-1) < 0); // this check works because of
00099                                                   // overflow
00100         return val;
00101     }
00102 
00105     double
00106     GetDouble()
00107     {
00108         return (((UInt64)Next(26) << 27) + Next(27)) / (double)(1LL << 53);
00109 
00110     }
00111 
00113     std::set<int>
00114     RandomUniqueNumbers(int count, int upperBound)
00115     {
00116         std::set<int> set;
00117         if(count > upperBound)
00118         {
00119             ILOG_ERROR("count > upperBound:"<< count <<" "<< upperBound);
00120             for(int i=0 ; i<count ; ++i)
00121                 set.insert(i);
00122             return set;
00123         }
00124         if(count >= GetRandMax())
00125         {
00126             ILOG_ERROR("count >= GetRandMax:"<< count <<" "<< GetRandMax());
00127             for(int i=0 ; i<count ; ++i)
00128                 set.insert(i);
00129             return set;
00130         }
00131         while(set.size() < count)
00132         {
00133             int draw = GetInt(upperBound);
00134             if(set.find(draw) == set.end())
00135                 set.insert(draw);
00136         }
00137         return set;
00138     }
00139 
00141     int
00142     operator() (int upperBound)
00143     {
00144         return GetInt(upperBound);
00145     }
00146     
00147 private:
00148     Int64 mSeed;
00149     static const int cRandomIntBits = 31;
00150     ILOG_CLASS;
00151 
00152     Int64
00153     Next(int bits)
00154     {
00155         mSeed = (mSeed * 0x5DEECE66DLL + 0xBL) & ((1LL << 48) - 1);
00156         return (mSeed >> (48 - bits));
00157     }
00158 };
00159 
00160 ILOG_CLASS_INIT(Random, Impala.Util);   
00161 
00162     
00163 } // namespace Util
00164 } // namespace Impala
00165 
00166 #endif

Generated on Thu Jan 13 09:05:16 2011 for ImpalaSrc by  doxygen 1.5.1