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
00026 #endif
00027
00028
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
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
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
00105 void printName( const TRandom & r) {
00106 std::cout << "\nRandom :\t " << r.ClassName() << std::endl;
00107 }
00108
00109 void printName( const TRandom1 & r) {
00110 std::cout << "\nRandom :\t " << r.ClassName() << std::endl;
00111 }
00112
00113 void printName( const TRandom2 & r) {
00114 std::cout << "\nRandom :\t " << r.ClassName() << std::endl;
00115 }
00116
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
00128 double n1=0;
00129 double x,y;
00130 w.Start();
00131
00132
00133
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
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
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
00277
00278
00279 }
00280 out << std::endl;
00281 j+= 8;
00282 }
00283 std::cout.precision(prec);
00284
00285 return 0;
00286
00287 }