#include "Math/Random.h" #include "Math/GSLRndmEngines.h" #include "TStopwatch.h" #include "TRandom1.h" #include "TRandom2.h" #include "TRandom3.h" #include #include #include #include #include #include #include #ifdef HAVE_CLHEP #include "CLHEP/Random/RandFlat.h" #include "CLHEP/Random/RanluxEngine.h" #include "CLHEP/Random/Ranlux64Engine.h" #endif #ifndef PI #define PI 3.14159265358979323846264338328 /* pi */ #endif //#define NEVT 10000 #ifndef NEVT #define NEVT 10000000 #endif using namespace ROOT::Math; #ifdef HAVE_CLHEP using namespace CLHEP; #endif // wrapper for stdrand class RandomStd { public: RandomStd() { fScale = 1./(double(RAND_MAX) + 1.); } inline void RndmArray(int n, double * x) { for ( double * itr = x; itr != x+n; ++itr) *itr= fScale*double(std::rand()); } inline double Uniform() { return fScale*double(std::rand()); } std::string Type() const { return "std::rand"; } unsigned int EngineSize() const { return 0; } void SetSeed(int seed) { std::srand(seed); } private: double fScale; }; // wrapper for clhep template class RandomCLHEP { public: RandomCLHEP(Engine & e) : fRand(e) { } inline void RndmArray(int n, double * x) { fRand.flatArray(n,x); } inline double Uniform() { return fRand.flat(); } std::string Type() const { return std::string("CLHEP ") + Engine::engineName(); } unsigned int EngineSize() const { return 0; } void SetSeed(int seed) { fRand.setSeed(seed); } private: Engine & fRand; }; template void printName( const R & r) { std::cout << "\nRandom :\t " << r.Type() << " \t size of state = " << r.EngineSize() << std::endl; } // specializations for TRandom's void printName( const TRandom & r) { std::cout << "\nRandom :\t " << r.ClassName() << std::endl; } // specializations for TRandom's void printName( const TRandom1 & r) { std::cout << "\nRandom :\t " << r.ClassName() << std::endl; } // specializations for TRandom's void printName( const TRandom2 & r) { std::cout << "\nRandom :\t " << r.ClassName() << std::endl; } // specializations for TRandom's void printName( const TRandom3 & r) { std::cout << "\nRandom :\t " << r.ClassName() << std::endl; } template void generate( R & r, bool array=true) { TStopwatch w; int n = NEVT; // estimate PI double n1=0; double x,y; w.Start(); // use default seeds // r.SetSeed(0); //r.SetSeed(int(pow(2,28)) ); if (array) { double x[1000]; double y[1000]; for (int i = 0; i < n; i+=1000 ) { r.RndmArray(1000,x); r.RndmArray(1000,y); for (int j = 0; j < 1000; ++j) if ( ( x[j]*x[j] + y[j]*y[j] ) <= 1.0 ) n1++; } } else { for (int i = 0; i < n; ++i) { x=r.Uniform(); y=r.Uniform(); if ( ( x*x + y*y ) <= 1.0 ) n1++; } } w.Stop(); printName(r); std::cout << "\tTime = " << w.RealTime()*1.0E9/NEVT << " " << w.CpuTime()*1.0E9/NEVT << " (ns/call)" << std::endl; double piEstimate = 4.0 * double(n1)/double(n); double delta = piEstimate-PI; double sigma = std::sqrt( PI * (4 - PI)/double(n) ); std::cout << "\t\tDeltaPI = " << delta/sigma << " (sigma) " << std::endl; } int main() { std::cout << "***************************************************\n"; std::cout << " TEST RANDOM NEVT = " << NEVT << std::endl; std::cout << "***************************************************\n\n"; Random r1; Random r2; Random r3; Random r3s1; Random r3s2; Random r3d1; Random r3d2; Random r4; Random r5; Random r6; Random r7; Random r8; Random r9; RandomStd r10; TRandom tr0; TRandom1 tr1; TRandom1 tr1a(0,0); TRandom1 tr1b(0,1); TRandom1 tr1c(0,2); TRandom1 tr1d(0,3); TRandom1 tr1e(0,4); TRandom2 tr2; TRandom3 tr3; generate(tr0); generate(tr1); generate(tr1a); generate(tr1b); generate(tr1c); generate(tr1d); generate(tr1e); generate(tr2); generate(tr3); generate(r10); generate(r1); generate(r2); generate(r3); generate(r3s1); generate(r3s2); generate(r3d1); generate(r3d2); generate(r4); generate(r5); generate(r6); generate(r7); generate(r8); generate(r9); #ifdef HAVE_CLHEP RanluxEngine e1(1,3); RanluxEngine e2(1,4); Ranlux64Engine e3(1,0); Ranlux64Engine e4(1,1); Ranlux64Engine e5(1,2); RandomCLHEP crlx3(e1); RandomCLHEP crlx4(e2); RandomCLHEP crlx64a(e3); RandomCLHEP crlx64b(e4); RandomCLHEP crlx64c(e5); generate(crlx3); generate(crlx4); generate(crlx64a); generate(crlx64b); generate(crlx64c); #endif // generate 1000 number with GSL MT and check with TRandom3 int n = 1000; std::vector v1(n); std::vector v2(n); Random gslRndm(4357); TRandom3 rootRndm(4357); gslRndm.RndmArray(n,&v1[0]); rootRndm.RndmArray(n,&v2[0]); int nfail=0; for (int i = 0; i < n; ++i) { double d = std::fabs(v1[i] - v2[i] ); if (d > std::numeric_limits::epsilon()*v1[i] ) nfail++; } if (nfail > 0) { std::cout << "ERROR: Test failing comparing TRandom3 with GSL MT" << std::endl; return -1; } // save the generated number ofstream file("testRandom.out"); std::ostream & out = file; int j = 0; int prec = std::cout.precision(9); while ( j < n) { for (int l = 0; l < 8; ++l) { out << std::setw(12) << v1[j+l] << ","; // int nws = int(-log10(v1[j+l])); // for (int k = nws; k >= 0; --k) // out << " "; } out << std::endl; j+= 8; } std::cout.precision(prec); return 0; }