pirndm.C

Go to the documentation of this file.
00001 //Test program for random number generators (spped and quality)
00002 //The program get n random number pairs x and y i [0,1]
00003 //It counts the ratio of pairs in the circle of diameter 1
00004 //compared to the total number of pairs.
00005 //This ratio must be Pi/4
00006 //The test shows the graph of the difference of this ratio compared to PI.
00007 //To test only the speed, call pirndm(1) (default)
00008 //To test quality and speed call pirndm(50)
00009 //    root pirndm.C+
00010 //or
00011 //    root "pirndm.C+(10)"
00012 //
00013 //Author: Rene Brun
00014       
00015 #include "TROOT.h"
00016 #include "TStopwatch.h"
00017 #include "TMath.h"
00018 #include "TRandom1.h"
00019 #include "TRandom2.h"
00020 #include "TRandom3.h"
00021 #include "TCanvas.h"
00022 #include "TH2.h"
00023 #include "TGraph.h"
00024 #include "TSystem.h"
00025 #include "TLegend.h"
00026 #include "TPaveLabel.h"
00027 #include "TSystem.h"
00028 #ifdef USE_MATHMORE
00029 #include "Math/Random.h"
00030 #include "Math/GSLRndmEngines.h"
00031 #endif
00032 #include <vector>
00033 #include <iostream>
00034    
00035 TLegend *legend = 0;
00036 TCanvas *c1 = 0;
00037 TStopwatch timer;
00038 Double_t cputot = 0;
00039 
00040 std::vector<TH2D *>  vh2; 
00041 
00042    
00043 //____________________________________________________________________
00044 template<class Random> 
00045 void piRandom(const char *name, Random *r, Long64_t n, Int_t color) {
00046 
00047    TH2D * h2 = new TH2D("h2",name,300,0,0.000003,300,0.,1.);
00048 
00049    timer.Start();
00050    TGraph *gr = new TGraph();
00051    gr->SetMarkerStyle(20);
00052    gr->SetMarkerSize(0.9);
00053    gr->SetMarkerColor(color);
00054    gr->SetLineColor(color);
00055    gr->SetLineWidth(2);
00056    
00057    Int_t k = 0;   
00058    Double_t diffpi;
00059    Long64_t npi   = 0;
00060    Double_t pi = TMath::Pi();
00061    const Int_t NR = 20000;
00062    const Int_t NR2 = NR/2;
00063    Double_t rn[NR];
00064    Long64_t i = 0;
00065    //double r1,r2; 
00066    while (i<=n) {
00067       i += NR2;
00068       r->RndmArray(NR,rn);
00069       for (Int_t j=0;j<NR;j+=2) {
00070           if (rn[j]*rn[j]+rn[j+1]*rn[j+1] <= 1) npi++;
00071           if (rn[j] < 0.001) h2->Fill(rn[j],rn[j+1]);
00072       }
00073 //       r1 = r->Rndm();
00074 //       r2 = r->Rndm();
00075       //  if (r1*r1+r2*r2 <= 1) npi++;
00076       if (i && i % (n/10) == 0) {
00077           gSystem->ProcessEvents();
00078          Double_t norm = 4./Double_t(i);
00079          diffpi   = norm*npi - pi;
00080          gr->SetPoint(k,i,diffpi);
00081          if (k ==0) gr->Draw("lp");
00082          else {
00083             c1->Modified();
00084             c1->Update();
00085          }
00086          k++;
00087       }
00088    }
00089    timer.Stop();
00090    Double_t cpu = timer.CpuTime();
00091    cputot += cpu;
00092    Double_t nanos = 1.e9*cpu/Double_t(2*n);
00093    legend->AddEntry(gr,Form("%-14s: %6.1f ns/call",name,nanos),"lp");
00094    c1->Modified();
00095    c1->Update();
00096    printf("RANDOM = %s : RT=%7.3f s, Cpu=%7.3f s\n",name,timer.RealTime(),cpu);
00097 
00098 //    TCanvas * c2 = new TCanvas(); 
00099 //    h2->Draw();
00100 //    c2->Update(); 
00101 
00102 //    c1->SetSelected(c1);
00103    vh2.push_back(h2);
00104 
00105 }
00106 
00107 //________________________________________________________________________
00108 void ErrorBand(Long64_t n) {
00109    Int_t np = 40;
00110    TGraph *g = new TGraph(2*np+2);
00111    Double_t xmax = Double_t(n)/Double_t(np);
00112    for (Int_t i=1;i<=np;i++) {
00113       Double_t x = i*xmax;
00114       //Double_t e = 1./TMath::Sqrt(x);
00115       Double_t e = TMath::Sqrt( 2 * TMath::Pi() * (4 - TMath::Pi() )/x );
00116       g->SetPoint(i,x,e);
00117       g->SetPoint(2*np-i+1,x,-e);
00118    }
00119    Double_t x0 = 0.1*xmax;
00120    Double_t e0 = 1./TMath::Sqrt(x0);
00121    g->SetPoint(0,x0,e0);
00122    g->SetPoint(2*np+1,0,-e0);
00123    g->SetPoint(2*np+2,0,e0);
00124    g->SetFillColor(1);
00125    g->SetFillStyle(3002);
00126    g->Draw("f");
00127 }
00128 
00129          
00130 //________________________________________________________________________
00131 void pirndm(Long64_t n1=1, unsigned int seed = 0) {
00132    Long64_t n = n1*20000000;
00133    c1 = new TCanvas("c1");
00134    c1->SetLeftMargin(0.12);
00135    c1->SetFrameFillColor(41);
00136    c1->SetFrameBorderSize(6);
00137    c1->SetGrid();
00138    Double_t dy = 10/TMath::Sqrt(n);
00139    //   Double_t dy = 1.5e-3;
00140    //if (n1 < 4) dy *=2;
00141    TH2F *frame = new TH2F("h","",100,0,1.1*n,100,-dy,dy);
00142    frame->GetXaxis()->SetTitle("Number of TRandom calls");
00143    frame->GetYaxis()->SetTitle("Difference with #pi");
00144    frame->GetYaxis()->SetTitleOffset(1.3);
00145    frame->GetYaxis()->SetDecimals();
00146    frame->SetStats(0);
00147    frame->Draw();
00148    legend = new TLegend(0.6,0.7,0.88,0.88);
00149    legend->Draw();
00150 
00151 
00152    ErrorBand(n);
00153    std::cout << "seed is " << seed << std::endl;
00154    
00155    piRandom("TRandom",new TRandom(seed),n,kYellow);
00156    piRandom("TRandom2",new TRandom2(seed),n,kBlue);
00157    piRandom("TRandom3",new TRandom3(seed),n,kRed);
00158    piRandom("TRandom1",new TRandom1(seed),n,kGreen);
00159 
00160 #ifdef USE_MATHMORE
00161 #define GSL2
00162 #ifdef GSL1
00163    piRandom("TRandom()",new TRandom(),n,kYellow);
00164    piRandom("TRandom3(0)",new TRandom3(0),n,kBlack);
00165    piRandom("MT",new ROOT::Math::Random<ROOT::Math::GSLRngMT>(),n,kRed);
00166    piRandom("Taus",new ROOT::Math::Random<ROOT::Math::GSLRngTaus>(),n,kMagenta);
00167    piRandom("GFSR4",new ROOT::Math::Random<ROOT::Math::GSLRngGFSR4>(),n,kGreen);
00168    piRandom("RanLux",new ROOT::Math::Random<ROOT::Math::GSLRngRanLux>(),n,kBlue);
00169 #endif
00170 #ifdef GSL2
00171    piRandom("TRandom(1)",new TRandom(1),n,kYellow);
00172    piRandom("TRandom(2^30)",new TRandom(1073741824),n,kRed);
00173    piRandom("TRandom(256)",new TRandom(256),n,kMagenta);
00174    piRandom("TRandom(2)",new TRandom(2),n,kBlue);
00175    piRandom("Rand",new ROOT::Math::Random<ROOT::Math::GSLRngRand>(),n,kGreen);
00176    //   piRandom("RANMAR",new ROOT::Math::Random<ROOT::Math::GSLRngRanMar>(),n,kBlue);
00177    //piRandom("MINSTD",new ROOT::Math::Random<ROOT::Math::GSLRngMinStd>(),n,kBlack);
00178    piRandom("new TRandom2",new TRandom2(),n,kCyan);
00179    //piRandom("TRandom3",new TRandom3(),n,kCyan);
00180 //    piRandom("CMRG",new ROOT::Math::Random<ROOT::Math::GSLRngCMRG>(),n,kRed);
00181 //    piRandom("MRG",new ROOT::Math::Random<ROOT::Math::GSLRngMRG>(),n,kMagenta);
00182 #else
00183    piRandom("new TRandom2",new TRandom2(std::rand()),n,kYellow);
00184    piRandom("new TRandom2",new TRandom2(std::rand()),n,kRed);
00185    piRandom("new TRandom2",new TRandom2(std::rand()),n,kMagenta);
00186    piRandom("new TRandom2",new TRandom2(std::rand()),n,kBlack);
00187    piRandom("new TRandom2",new TRandom2(std::rand()),n,kBlue);
00188    piRandom("new TRandom2",new TRandom2(std::rand()),n,kRed);
00189    piRandom("new TRandom2",new TRandom2(std::rand()),n,kGreen);
00190 #endif
00191 #endif
00192       
00193    // reftime calculated on MACOS Intel dualcore 2GHz
00194    // time for TRandom + TRandom2 + TRandom3 + TRandom1 for n = 10**7 (n1=5000)
00195    Double_t reftime = (4629.530 + 5358.100  + 5785.240 + 26012.17)/5000.;
00196    const Double_t rootmarks = 900*Double_t(n1)*reftime/cputot;
00197    TPaveLabel *pl = new TPaveLabel(0.2,0.92,0.8,0.98,Form("cpu time = %6.1fs - rootmarks = %6.1f",cputot,rootmarks),"brNDC");
00198    pl->Draw();  
00199    printf("******************************************************************\n");
00200    printf("*  ROOTMARKS =%6.1f   *  Root%-8s  %d/%d\n",rootmarks,gROOT->GetVersion(),
00201          gROOT->GetVersionDate(),gROOT->GetVersionTime());
00202    printf("******************************************************************\n");
00203 
00204    printf("Time at the end of job = %f seconds\n",cputot);
00205    c1->Print("pirndm.root");
00206    c1->Print("pirndm.gif");
00207 
00208 
00209    // draw 2D histos 
00210    TCanvas * c2 = new TCanvas();
00211    int nx = 0; 
00212    int ny = vh2.size(); 
00213    for ( nx = 1; nx < ny; nx++) { 
00214      double r = double(vh2.size())/nx; 
00215      ny = int(r - 0.01) + 1; 
00216    }
00217    nx--;
00218    std::cout << nx << "  " << ny << "  " << vh2.size() << std::endl;
00219    
00220    c2->Divide(ny,nx); 
00221    for (unsigned int i = 0; i < vh2.size(); ++i) { 
00222      c2->cd (i+1); 
00223      vh2[i]->Draw(); 
00224    }
00225    c2->Update(); 
00226    
00227 }

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