unuranMulti2D.cxx

Go to the documentation of this file.
00001 // test using Multi-dim (2D)  Distribution object interface
00002 // and compare results and CPU performances using TF2::GetRandom
00003 //
00004 // run within ROOT (.x unuranMulti2D.cxx+) or pass any extra parameter in the command line to get  
00005 // a graphics output 
00006 
00007 #include "TStopwatch.h"
00008 #include "TUnuran.h"
00009 #include "TUnuranMultiContDist.h"
00010 
00011 #include "TH2.h"
00012 #include "TF2.h"
00013 #include "TCanvas.h"
00014 #include "TMath.h"
00015 
00016 #include "TRandom3.h"
00017 #include "TSystem.h"
00018 #include "TApplication.h"
00019 #include "TError.h"
00020 
00021 #include "Math/Functor.h"
00022 
00023 // #include "Math/ProbFunc.h"
00024 // #include "Math/DistFunc.h"
00025 
00026 #define _USE_MATH_DEFINES // for Windows
00027 #include <cmath>
00028 #include <iostream> 
00029 
00030 //#define DEBUG 
00031 
00032 using std::cout; 
00033 using std::endl; 
00034 
00035 int n = 1000000;
00036 
00037 bool useRandomSeed = false;   // to use a random seed different every time
00038 
00039 double gaus2d(double *x, double *p) { 
00040 
00041    double sigma_x = p[0]; 
00042    double sigma_y = p[1];
00043    double rho = p[2]; 
00044    double u = x[0] / sigma_x ;
00045    double v = x[1] / sigma_y ;
00046    double c = 1 - rho*rho ;
00047    double result = (1 / (2 * TMath::Pi() * sigma_x * sigma_y * sqrt(c))) 
00048       * exp (-(u * u - 2 * rho * u * v + v * v ) / (2 * c));
00049    return result;
00050 }
00051 
00052 double log_gaus2d(double *x, double *p) { 
00053 
00054    return std::log( gaus2d(x,p) ); // should re-implement it
00055 }
00056 
00057 
00058 
00059 int testUnuran(TUnuran & unr, const std::string & method, const TUnuranMultiContDist & dist, TH2 * h1, const TH2 * href ) { 
00060 
00061 #ifdef DEBUG
00062    n = 1000;
00063 #endif
00064 
00065 
00066    // init unuran 
00067    bool ret =   unr.Init(dist,method); 
00068    if (!ret) { 
00069       std::cerr << "Error initializing unuran with method " << unr.MethodName() << endl; 
00070       return -1;
00071    } 
00072 
00073    h1->Reset();
00074 
00075    // test first the time
00076    TStopwatch w; 
00077 
00078    w.Start(); 
00079    double x[2]; 
00080    for (int i = 0; i < n; ++i) {
00081       unr.SampleMulti(x);
00082       h1->Fill(x[0],x[1]);
00083       if (method == "gibbs" && i < 100) 
00084          std::cout << x[0] << " , " << x[1] << std::endl; 
00085    }
00086 
00087    w.Stop(); 
00088    double time = w.CpuTime()*1.E9/n; 
00089 
00090    double prob = href->Chi2Test(h1,"UU");
00091    double ksprob = href->KolmogorovTest(h1);
00092    cout << "Time using Unuran  " << unr.MethodName() << "   \t=\t " << time << "\tns/call \t\tChi2 Prob = "
00093         << prob << "\tKS Prob = " << ksprob << std::endl;
00094    if (prob < 1E-06) { 
00095       std::cout << "Chi2 Test failed ! " << std::endl;
00096       href->Chi2Test(h1,"UUP"); // print all chi2 test info
00097       return 1;
00098    }
00099    return 0; 
00100 }  
00101 
00102 int testGetRandom(TF2 * f, TH1 * h1, const TH2 * href = 0) { 
00103 
00104 
00105    // test first the time
00106    h1->Reset();
00107    
00108    TStopwatch w; 
00109    w.Start();
00110    double x[2] = {0,0};
00111    for (int i = 0; i < n; ++i) {
00112       f->GetRandom2(x[0],x[1]);
00113       h1->Fill(x[0],x[1]); 
00114    }
00115 
00116    w.Stop(); 
00117    double time = w.CpuTime()*1.E9/n; 
00118 
00119 
00120    if (href != 0) { 
00121       double prob = href->Chi2Test(h1,"UU");
00122       std::cout << "Time using TF1::GetRandom()    \t=\t " << time << "\tns/call \t\tChi2 Prob = "<< prob << std::endl;
00123       if (prob < 1E-06) { 
00124          std::cout << "Chi2 Test failed ! " << std::endl;
00125          href->Chi2Test(h1,"UUP"); // print all chi2 test info
00126          return 2;
00127       }
00128    }
00129    else 
00130       std::cout << "Time using TF1::GetRandom()    \t=\t " << time << "\tns/call\n";
00131    return 0; 
00132 }  
00133 
00134 
00135 int unuranMulti2D() { 
00136 
00137    // check if using a random seed
00138    if (useRandomSeed) gRandom->SetSeed(0);
00139 
00140    // switch off printing of  info messages from chi2 test
00141    gErrorIgnoreLevel = 1001; 
00142 
00143 
00144    gSystem->Load("libMathCore");
00145    gSystem->Load("libUnuran");
00146 
00147    // simple test of unuran
00148 
00149    
00150 
00151    TH2D * h1 = new TH2D("h1","UNURAN gaussian 2D distribution",100,-10,10,100,-10,10);
00152    TH2D * h2 = new TH2D("h2","TF1::GetRandom gaussian 2D distribution",100,-10,10,100,-10,10);
00153 
00154    TH2D * h3 = new TH2D("h3","UNURAN truncated gaussian 2D distribution",100,-1,1,100,-1,1);
00155    TH2D * h4 = new TH2D("h4","TF1::GetRandom truncated gaussian 2D distribution",100,-1,1,100,-1,1);
00156    
00157 
00158    TF2 * f = new TF2("g2d",gaus2d,-10,10,-10,10,3); 
00159    double par[3] = {1,1,0.5}; 
00160    f->SetParameters(par); 
00161 
00162    TF2 * flog = new TF2("logg2d",log_gaus2d,-10,10,-10,10,3); 
00163    flog->SetParameters(par); 
00164 
00165 
00166    f->SetNpx(100);
00167    f->SetNpy(100);
00168    std::cout << " Nimber of function points in TF1, Npx = " << f->GetNpx() << " Npy =  "  << f->GetNpy() << std::endl;
00169 
00170 
00171    std::cout << "Test using an undefined domain :\n\n";
00172 
00173    // test first with getrandom
00174    testGetRandom(f,h2);
00175 
00176    // create multi-dim distribution
00177    TUnuranMultiContDist dist(f); 
00178 
00179    // use directly function interfaces
00180    //ROOT::Math::Functor f2( *f, 2);
00181    //TUnuranMultiContDist dist(f2); 
00182 
00183    TUnuran unr(gRandom,2);  // 2 is debug level 
00184    
00185    int iret = 0; 
00186    TH2 * href = h2; 
00187 
00188    //vnrou method (requires only pdf) 
00189    std::string method = "vnrou";
00190    iret |= testUnuran(unr, method, dist, h1, href);
00191 
00192 
00193    //hitro method (requires only pdf)
00194    method = "hitro";
00195    iret |= testUnuran(unr, method, dist, h1, href);
00196    
00197    //gibbs requires log of pdf and derivative
00198 //#define USE_GIBBS   
00199 #ifdef USE_GIBBS
00200    method = "gibbs";
00201    // need to create a new  multi-dim distribution with log of pdf
00202    TUnuranMultiContDist logdist(flog,0,true); 
00203    iret |= testUnuran(unr, method, logdist, h1, href);
00204 #endif
00205 
00206    // test setting the mode
00207    cout << "\nTest setting the mode in Unuran distribution:\n\n"; 
00208    double m[2] = {0,0};
00209    dist.SetMode(m);
00210 
00211    method = "vnrou";
00212    iret |= testUnuran(unr, method, dist, h1, href);
00213 
00214    method = "hitro";
00215    iret |= testUnuran(unr, method, dist, h1, href);
00216 
00217 #ifdef USE_GIBBS
00218    method = "gibbs";
00219    logdist.SetMode(m);
00220    iret |= testUnuran(unr, method, logdist, h1, href);
00221 #endif
00222 
00223 
00224 //    std::cout << " chi2 test of histogram generated with Unuran vs histogram generated with TF1::GetRandom " << std::endl;
00225 //    h1->Chi2Test(h2,"UUP");
00226 
00227 //#ifdef LATER
00228 
00229    double xmin[2] = { -1, -1 }; 
00230    double xmax[2] = { 1, 1 }; 
00231 
00232    f->SetRange(xmin[0],xmin[1],xmax[0],xmax[1]);
00233    // change function domain (not yet implemented in unuran for multidim functions)
00234    dist.SetDomain(xmin,xmax);
00235 
00236    const double *xlow = dist.GetLowerDomain(); 
00237    const double *xup = dist.GetUpperDomain(); 
00238    cout << "\nTest truncated distribution in domain [ " << xlow[0] << " : " << xup[0] 
00239         << " , " << xlow[1] << " : " << xup[1] << " ] :\n\n"; 
00240    
00241 
00242    testGetRandom(f,h4);
00243 
00244    method = "vnrou";
00245    iret |= testUnuran(unr, method, dist, h3, h4);
00246    method = "hitro";
00247    iret |= testUnuran(unr, method, dist, h3, h4);
00248 #ifdef USE_GIBBS
00249    logdist.SetDomain(xmin,xmax);
00250    method = "gibbs";      
00251    iret |= testUnuran(unr, method, logdist, h3, h4);
00252 #endif
00253 
00254 //#ifdef LATER
00255    TCanvas * c1 = new TCanvas("c1_unuran2D","Multidimensional distribution",10,10,900,900); 
00256    c1->Divide(2,2);
00257 #ifdef NO_TRUNC
00258    TCanvas * c1 = new TCanvas("c1_unuran2D","Multidimensional distribution",10,10,500,500); 
00259    c1->Divide(1,2);
00260 #endif
00261 
00262 
00263    c1->cd(1); 
00264    h1->Draw("col");
00265 
00266    
00267    c1->cd(2);
00268    h2->Draw("col");
00269 
00270    c1->cd(3); 
00271    h3->Draw("col");
00272    c1->cd(4); 
00273    h4->Draw("col");
00274 //#endif
00275 
00276    if (iret != 0) 
00277       std::cerr <<"\n\nUnuRan 2D Continous Distribution Test:\t  Failed !!!!!!!\n" << std::endl;
00278    else 
00279       std::cerr << "\n\nUnuRan 2D Continous Distribution Test:\t OK\n" << std::endl;
00280 
00281    return iret; 
00282 
00283 }
00284 
00285 #ifndef __CINT__
00286 int main(int argc, char **argv)
00287 {
00288    int iret = 0; 
00289    if (argc > 1) { 
00290       TApplication theApp("App",&argc,argv);
00291       iret =  unuranMulti2D();
00292       theApp.Run();
00293    } 
00294    else 
00295       iret =  unuranMulti2D();
00296    
00297    return iret; 
00298 }
00299 #endif

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