unuranFoamTest.C

Go to the documentation of this file.
00001 // This program must be compiled and executed with Aclic as follows
00002 //     
00003 // .x unuranFoamTest.C+
00004 //
00005 // it is an extension of tutorials foam_kanwa.C to compare 
00006 // generation of a 2D distribution with unuran and Foam
00007 //_____________________________________________________________________________
00008 
00009 #include "TH2.h"
00010 #include "TF2.h"
00011 #include "TSystem.h"
00012 #include "TCanvas.h"
00013 #include "TMath.h"
00014 #include "TRandom3.h"
00015 #include "TFoam.h"
00016 #include "TFoamIntegrand.h"
00017 #include "TStopwatch.h"
00018 #include "TROOT.h"
00019 
00020 
00021 #include "TUnuran.h"
00022 #include "TUnuranMultiContDist.h"
00023 
00024 #include <iostream>
00025 
00026 //_____________________________________________________________________________
00027 Double_t sqr(Double_t x){return x*x;};
00028 //_____________________________________________________________________________
00029 //_____________________________________________________________________________
00030 
00031 
00032 Double_t Camel2(Int_t nDim, Double_t *Xarg){
00033 // 2-dimensional distribution for Foam, normalized to one (within 1e-5)
00034   Double_t x=Xarg[0];
00035   Double_t y=Xarg[1];
00036   Double_t GamSq= sqr(0.100e0);
00037   Double_t Dist= 0;
00038   Dist +=exp(-(sqr(x-1./3) +sqr(y-1./3))/GamSq)/GamSq/TMath::Pi();
00039   Dist +=exp(-(sqr(x-2./3) +sqr(y-2./3))/GamSq)/GamSq/TMath::Pi();
00040   return 0.5*Dist;
00041 }// Camel2
00042 
00043 class FoamFunction : public TFoamIntegrand { 
00044    public:
00045    virtual ~FoamFunction() {}
00046    double Density(int nDim, double * x) { 
00047       return Camel2(nDim,x); 
00048    }
00049    ClassDef(FoamFunction,1);
00050    
00051 };
00052 
00053 TH2 * hFoam; 
00054 TH2 * hUnr; 
00055 
00056 
00057 Int_t run_foam(int nev){
00058   cout<<"--- kanwa started ---"<<endl;
00059   gSystem->Load("libFoam.so");
00060   TH2D  *hst_xy = new TH2D("foam_hst_xy" ,  "FOAM x-y plot", 50,0,1.0, 50,0,1.0); 
00061   hFoam = hst_xy;
00062   
00063   Double_t *MCvect =new Double_t[2]; // 2-dim vector generated in the MC run
00064   //
00065   TRandom     *PseRan   = new TRandom3();  // Create random number generator
00066   PseRan->SetSeed(4357);
00067   TFoam   *FoamX    = new TFoam("FoamX");   // Create Simulator
00068   FoamX->SetkDim(2);         // No. of dimensions, obligatory!
00069   FoamX->SetnCells(500);     // Optionally No. of cells, default=2000
00070   FoamX->SetRho(new FoamFunction() );  // Set 2-dim distribution, included below
00071   FoamX->SetPseRan(PseRan);  // Set random number generator
00072   //
00073   // From now on FoamX is ready to generate events
00074 
00075    // test first the time
00076    TStopwatch w; 
00077 
00078   w.Start(); 
00079   FoamX->Initialize();       // Initialize simulator, may take time...
00080 
00081   //int nshow=5000;
00082   int nshow=nev;
00083 
00084   for(long loop=0; loop<nev; loop++){
00085     FoamX->MakeEvent();            // generate MC event
00086     FoamX->GetMCvect( MCvect);     // get generated vector (x,y)
00087     Double_t x=MCvect[0];
00088     Double_t y=MCvect[1];
00089     //if(loop<10) cout<<"(x,y) =  ( "<< x <<", "<< y <<" )"<<endl;
00090     hst_xy->Fill(x,y);
00091     // live plot
00092     if(loop == nshow){
00093       nshow += 5000;
00094       hst_xy->Draw("lego2");
00095       //cKanwa->Update();
00096     }
00097   }// loop
00098   w.Stop();
00099 
00100   double time = w.CpuTime()*1.E9/nev; 
00101   cout << "Time using FOAM \t\t " << "   \t=\t " << time << "\tns/call" << endl;
00102 
00103   //
00104   hst_xy->Draw("lego2");  // final plot
00105   //
00106   Double_t MCresult, MCerror;
00107   FoamX->GetIntegMC( MCresult, MCerror);  // get MC integral, should be one
00108   cout << " MCresult= " << MCresult << " +- " << MCerror <<endl;
00109   cout<<"--- kanwa ended ---"<<endl;
00110   
00111   return 0;
00112 }//kanwa
00113 
00114 
00115 
00116 double UCamel2(double * x, double *) {
00117    return Camel2(2,x); 
00118 } 
00119 
00120 int run_unuran(int nev, std::string method = "hitro") { 
00121    // use unuran 
00122 
00123    std::cout << "run unuran " << std::endl;
00124 
00125    gSystem->Load("libUnuran.so");
00126 
00127    TH2D  *h1 = new TH2D("unr_hst_xy" ,  "UNURAN x-y plot", 50,0,1.0, 50,0,1.0);
00128    hUnr= h1;
00129 
00130    TF2 * f = new TF2("f",UCamel2,0,1,0,1,0);
00131 
00132    TUnuranMultiContDist dist(f);
00133 
00134    TRandom3 r; 
00135  
00136    TUnuran unr(&r,2);  // 2 is debug level 
00137 
00138 
00139    // test first the time
00140    TStopwatch w; 
00141 
00142    w.Start(); 
00143 
00144    // init unuran 
00145    bool ret =   unr.Init(dist,method); 
00146    if (!ret) { 
00147       std::cerr << "Error initializing unuran with method " << unr.MethodName() << endl; 
00148       return -1;
00149    } 
00150 
00151    double x[2]; 
00152    for (int i = 0; i < nev; ++i) {
00153       unr.SampleMulti(x);
00154       h1->Fill(x[0],x[1]);
00155 //       if (method == "gibbs" && i < 100) 
00156 //          std::cout << x[0] << " , " << x[1] << std::endl; 
00157    }
00158 
00159    w.Stop(); 
00160    double time = w.CpuTime()*1.E9/nev; 
00161    cout << "Time using Unuran  " << unr.MethodName() << "   \t=\t " << time << "\tns/call" << endl;
00162    h1->Draw("lego2");
00163    return 0;
00164 }
00165 
00166 Int_t unuranFoamTest(){
00167 
00168   // visualising generated distribution
00169   TCanvas *cKanwa = new TCanvas("cKanwa","Canvas for plotting",600,1000);
00170   cKanwa->Divide(1,2);
00171   cKanwa->cd(1);
00172   int n = 100000;
00173 
00174 
00175   run_unuran(n,"hitro");
00176   cKanwa->Update();
00177 
00178   cKanwa->cd(2);
00179 
00180   run_foam(n);
00181   cKanwa->Update();
00182 
00183 
00184   std::cout <<"\nChi2 Test Results (UNURAN-FOAM):\t";
00185   // test chi2 
00186   hFoam->Chi2Test(hUnr,"UUP");
00187 
00188   return 0;
00189 }  

Generated on Tue Jul 5 15:45:12 2011 for ROOT_528-00b_version by  doxygen 1.5.1