testRandom.cxx

Go to the documentation of this file.
00001 #include "Math/Random.h"
00002 #include "Math/GSLRndmEngines.h"
00003 #include "TStopwatch.h"
00004 #include "TRandom1.h"
00005 #include "TRandom2.h"
00006 #include "TRandom3.h"
00007 #include <iostream>
00008 #include <cmath>
00009 #include <cstdlib>
00010 #include <typeinfo>
00011 #include <iomanip>
00012 #include <fstream> 
00013 
00014 #include <limits>
00015 
00016 #ifdef HAVE_CLHEP
00017 #include "CLHEP/Random/RandFlat.h"
00018 #include "CLHEP/Random/RanluxEngine.h"
00019 #include "CLHEP/Random/Ranlux64Engine.h"
00020 #endif
00021 
00022 
00023 
00024 #ifndef PI
00025 #define PI       3.14159265358979323846264338328      /* pi */
00026 #endif
00027 
00028 //#define NEVT 10000
00029 #ifndef NEVT
00030 #define NEVT 10000000
00031 #endif
00032 
00033 using namespace ROOT::Math;
00034 
00035 #ifdef HAVE_CLHEP
00036 using namespace CLHEP;
00037 #endif
00038 
00039 
00040 // wrapper for stdrand
00041 
00042 class RandomStd { 
00043 public: 
00044   RandomStd() { 
00045     fScale = 1./(double(RAND_MAX) + 1.); 
00046   }
00047 
00048   inline void RndmArray(int n, double * x) {
00049     for ( double * itr = x; itr != x+n; ++itr) 
00050       *itr= fScale*double(std::rand()); 
00051   }
00052   inline double Uniform() { 
00053     return fScale*double(std::rand()); 
00054   }
00055 
00056   std::string Type() const { return "std::rand"; }
00057   unsigned int EngineSize() const { return 0; }
00058 
00059   void SetSeed(int seed) { std::srand(seed); }
00060 
00061 private: 
00062   double fScale; 
00063 
00064 }; 
00065 
00066 
00067 
00068 // wrapper for clhep
00069 
00070 template <class Engine> 
00071 class RandomCLHEP { 
00072 public: 
00073    RandomCLHEP(Engine & e) : 
00074       fRand(e)
00075    { 
00076    }
00077 
00078   inline void RndmArray(int n, double * x) {
00079      fRand.flatArray(n,x);
00080   }
00081   inline double Uniform() { 
00082      return fRand.flat();
00083   }
00084 
00085    std::string Type() const { return std::string("CLHEP ") + Engine::engineName(); }
00086    unsigned int EngineSize() const { return 0; }
00087 
00088   void SetSeed(int seed) { fRand.setSeed(seed); }
00089 
00090 private: 
00091    Engine & fRand; 
00092 
00093 }; 
00094 
00095 
00096 
00097 
00098 
00099 template <class R> 
00100 void printName( const R & r) { 
00101   std::cout << "\nRandom :\t " << r.Type() << " \t size of state = " << r.EngineSize() << std::endl;
00102 }
00103 
00104 // specializations for TRandom's
00105 void printName( const TRandom & r) { 
00106   std::cout << "\nRandom :\t " << r.ClassName() << std::endl;
00107 }
00108 // specializations for TRandom's
00109 void printName( const TRandom1 & r) { 
00110   std::cout << "\nRandom :\t " << r.ClassName() << std::endl;
00111 }
00112 // specializations for TRandom's
00113 void printName( const TRandom2 & r) { 
00114   std::cout << "\nRandom :\t " << r.ClassName() << std::endl;
00115 }
00116 // specializations for TRandom's
00117 void printName( const TRandom3 & r) { 
00118   std::cout << "\nRandom :\t " << r.ClassName() << std::endl;
00119 }
00120 
00121 template <class R> 
00122 void generate( R & r, bool array=true) { 
00123 
00124   TStopwatch w; 
00125 
00126   int n = NEVT;
00127   // estimate PI
00128   double n1=0; 
00129   double x,y; 
00130   w.Start();
00131   // use default seeds
00132   // r.SetSeed(0);
00133   //r.SetSeed(int(pow(2,28)) );
00134   if (array) { 
00135     double x[1000];
00136     double y[1000];
00137     for (int i = 0; i < n; i+=1000 ) {  
00138       r.RndmArray(1000,x);
00139       r.RndmArray(1000,y);
00140       for (int j = 0; j < 1000; ++j) 
00141         if ( ( x[j]*x[j] + y[j]*y[j] ) <= 1.0 ) n1++;
00142     }
00143   }     
00144   else {
00145     for (int i = 0; i < n; ++i) { 
00146       x=r.Uniform();
00147       y=r.Uniform();
00148       if ( ( x*x + y*y ) <= 1.0 ) n1++;
00149     }
00150   }
00151   w.Stop();
00152 
00153   printName(r); 
00154   std::cout << "\tTime = " << w.RealTime()*1.0E9/NEVT << "  " 
00155             << w.CpuTime()*1.0E9/NEVT 
00156             << " (ns/call)" << std::endl;   
00157   double piEstimate = 4.0 * double(n1)/double(n);
00158   double delta = piEstimate-PI; 
00159   double sigma = std::sqrt( PI * (4 - PI)/double(n) );
00160   std::cout << "\t\tDeltaPI = " << delta/sigma << " (sigma) " << std::endl; 
00161 }
00162 
00163 int main() {
00164 
00165   std::cout << "***************************************************\n"; 
00166   std::cout << " TEST RANDOM    NEVT = " << NEVT << std::endl;
00167   std::cout << "***************************************************\n\n"; 
00168 
00169 
00170 
00171   Random<GSLRngMT>         r1;
00172   Random<GSLRngTaus>       r2;
00173   Random<GSLRngRanLux>     r3;
00174   Random<GSLRngRanLuxS1>   r3s1;
00175   Random<GSLRngRanLuxS2>   r3s2;
00176   Random<GSLRngRanLuxD1>   r3d1;
00177   Random<GSLRngRanLuxD2>   r3d2;
00178   Random<GSLRngGFSR4>      r4;
00179   Random<GSLRngCMRG>       r5;
00180   Random<GSLRngMRG>        r6;
00181   Random<GSLRngRand>       r7;
00182   Random<GSLRngRanMar>     r8;
00183   Random<GSLRngMinStd>     r9;
00184   RandomStd                r10; 
00185 
00186   TRandom                  tr0;
00187   TRandom1                 tr1;
00188   TRandom1                 tr1a(0,0);
00189   TRandom1                 tr1b(0,1);
00190   TRandom1                 tr1c(0,2);
00191   TRandom1                 tr1d(0,3);
00192   TRandom1                 tr1e(0,4);
00193   TRandom2                 tr2;
00194   TRandom3                 tr3;
00195 
00196 
00197   generate(tr0);
00198   generate(tr1);
00199   generate(tr1a);
00200   generate(tr1b);
00201   generate(tr1c);
00202   generate(tr1d);
00203   generate(tr1e);
00204   generate(tr2);
00205   generate(tr3);
00206 
00207   generate(r10);
00208 
00209   generate(r1);
00210   generate(r2);
00211   generate(r3);
00212   generate(r3s1);
00213   generate(r3s2);
00214   generate(r3d1);
00215   generate(r3d2);
00216   generate(r4);
00217   generate(r5);
00218   generate(r6);
00219   generate(r7);
00220   generate(r8);
00221   generate(r9);
00222 
00223 
00224 #ifdef HAVE_CLHEP
00225   RanluxEngine             e1(1,3);
00226   RanluxEngine             e2(1,4);
00227   Ranlux64Engine           e3(1,0);
00228   Ranlux64Engine           e4(1,1);
00229   Ranlux64Engine           e5(1,2);
00230 
00231   RandomCLHEP<RanluxEngine>  crlx3(e1);
00232   RandomCLHEP<RanluxEngine>  crlx4(e2);
00233 
00234   RandomCLHEP<Ranlux64Engine>  crlx64a(e3);
00235   RandomCLHEP<Ranlux64Engine>  crlx64b(e4);
00236   RandomCLHEP<Ranlux64Engine>  crlx64c(e5);
00237 
00238   generate(crlx3);
00239   generate(crlx4);
00240 
00241   generate(crlx64a);
00242   generate(crlx64b);
00243   generate(crlx64c);
00244 
00245 #endif
00246 
00247   // generate 1000 number with GSL MT and check with TRandom3
00248   int n = 1000;
00249   std::vector<double> v1(n);
00250   std::vector<double> v2(n);
00251 
00252   Random<GSLRngMT>         gslRndm(4357);
00253   TRandom3                 rootRndm(4357);
00254 
00255   
00256   gslRndm.RndmArray(n,&v1[0]); 
00257   rootRndm.RndmArray(n,&v2[0]); 
00258 
00259   int nfail=0; 
00260   for (int i = 0; i < n; ++i) { 
00261      double d = std::fabs(v1[i] - v2[i] );
00262       if (d > std::numeric_limits<double>::epsilon()*v1[i] ) nfail++;
00263   }
00264   if (nfail > 0) { 
00265      std::cout << "ERROR: Test failing comparing TRandom3 with GSL MT" << std::endl;
00266      return -1;
00267   }
00268   // save the generated number
00269   ofstream file("testRandom.out");
00270   std::ostream & out = file; 
00271   int  j = 0; 
00272   int prec = std::cout.precision(9);
00273   while ( j < n) { 
00274      for (int l = 0; l < 8; ++l) {
00275         out << std::setw(12) << v1[j+l] << ","; 
00276 //         int nws = int(-log10(v1[j+l])); 
00277 //         for (int k = nws; k >= 0; --k)
00278 //            out << " "; 
00279      }
00280      out << std::endl; 
00281      j+= 8; 
00282   }
00283   std::cout.precision(prec);
00284 
00285   return 0;
00286 
00287 }

Generated on Tue Jul 5 14:34:59 2011 for ROOT_528-00b_version by  doxygen 1.5.1