#ifndef RANDOMGENERATOR_H #define RANDOMGENERATOR_H ///////////////////////////////////////////////// // Random Generators // created : AGoTH // date : 01/12/01 ///////////////////////////////////////////////// #include // template float GaussianDistribution(const R& iRG, float iMean, float iDeviation) { // Generic form of the Box-Muller transformation // float x1 = iRG(); // float x2 = iRG(); // float y1 = XSqrt( -2.0f * logf(x1) ) * cos( 2 * 3.14f * x2 ); // float y2 = XSqrt( -2.0f * logf(x1) ) * sin( 2 * 3.14f * x2 ); // We will use the Polar form for efficiency static int useLast = 0; static float y2; float y1; if (useLast) { y1 = y2; useLast = 0; } else { float x1, x2, w; do { x1 = 2.0f * iRG() - 1.0f; x2 = 2.0f * iRG() - 1.0f; w = x1 * x1 + x2 * x2; } while ( w >= 1.0f ); // I need to /4 otherwise it pass the bounds ! w = 0.25f * XSqrt( (-2.0f * logf(w) )/w); y1 = x1 * w; y2 = x2 * w; useLast = 1; } return (iMean + y1 * iDeviation); } // class StandardRandomGenerator { public: StandardRandomGenerator() { } // Initialize the random generator // for a given seed, the sequence // of generated number will be the same void Init(unsigned int iSeed) const { // sets a random starting point srand(iSeed); } // Returns an uniformely distribued float // value : [0,1) float operator ()() const { return (INVRANDMAX*rand()); } // returns a random number distribued // "gaussianly" with a mean and a deviation // value : [iMean-iDeviation,iMean+iDeviation) float Gaussian(float iMean, float iDeviation) const { return GaussianDistribution(*this,iMean,iDeviation); } private: static const float INVRANDMAX; }; const float StandardRandomGenerator::INVRANDMAX = 1.0f/RAND_MAX; // class QuasiRandomGenerator { public: QuasiRandomGenerator() { Init(); } // Returns an uniformely distribued float // value : [0,1) float operator ()() const { unsigned int im = m_Index++; // find rightmost zero bit int j; for (j = 0; j < s_MaxBit; j++, im >>= 1) { if ( (im & 1L) == 0 ) break; } m_IX ^= s_IV[j + 0]; // integer values return (float) ( s_Factor * m_IX ); } // returns a random number distribued // "gaussianly" with a mean and a deviation // value : [iMean-iDeviation,iMean+iDeviation) float Gaussian(float iMean, float iDeviation) const { return GaussianDistribution(*this,iMean,iDeviation); } private: // Methods void Init() { #define INDEX(k,j) [(k) + (j-1)] int j, k, l, ipp, niv; unsigned int i, mval; s_IV = new unsigned int[niv = 1 * s_MaxBit]; for (k = 0; k < niv; k++) s_IV[k] = 0; for (k = 0; k < 1; k++) s_IV[k] = 1; mval = 4; ipp = 1; for (k = 1, j = 0; k < niv-1; k += 2) { s_IV[k] = ipp; if (++j == 1) { mval *= 2; ipp += 2; j = 0; } if ( ipp > (int)mval ) ipp = 1; s_IV[k+1] = ipp; if (++j == 1) { mval *= 2; ipp += 2; j = 0; } else { ipp += 2; if ( ipp > (int)mval ) ipp = 1; } } for (k = 0; k < 1; k++) { // normalize the set s_IV values for (j = 1; j <= mdeg[k]; j++) s_IV INDEX(k,j) *= (1L << (s_MaxBit - j)); // calcululate the rest of the s_IV values for (j = mdeg[k] + 1; j <= s_MaxBit; j++) { ipp = ip[k]; // calculate Gray code of s_IV i = s_IV INDEX(k, j - mdeg[k]); i ^= i / (1L << mdeg[k]); for (l = mdeg[k] - 1; l >= 1; l--) { if ( ipp & 1 ) i ^= s_IV INDEX(k, j-l); ipp /= 2; } s_IV INDEX(k,j) = i; } } s_Factor = 1.0 / (1L << s_MaxBit); } // Members static const int s_MaxBit; static unsigned int* s_IV; static double s_Factor; static const int ip[]; static const int mdeg[]; mutable unsigned int m_Index; mutable unsigned int m_IX; }; const int QuasiRandomGenerator::s_MaxBit = 30; unsigned int* QuasiRandomGenerator::s_IV; double QuasiRandomGenerator::s_Factor; // the primitive polynomial coefficients for up to degree 8 const int QuasiRandomGenerator::ip[] = { 0, 1, 1, 2, 1, 4, 2, 4, 7, 11, 13, 14, 1, 13, 16, 19, 22, 25, 1, 4, 7, 8, 14, 19, 21, 28, 31, 32, 37, 41, 42, 50, 55, 56, 59, 62, 14, 21, 22, 38, 47, 49, 50, 52, 56, 67, 70, 84, 97, 103, 115, 122 }; const int QuasiRandomGenerator::mdeg[] = { 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; // const QuasiRandomGenerator& GetQuasiRandomGenerator() { static QuasiRandomGenerator qrg; return qrg; } #endif // RANDOMGENERATOR_H