unuranDistr.cxx

Go to the documentation of this file.
00001 // test using 1D Distribution object interface
00002 // and compare results and CPU performances using TF1::GetRandom
00003 //
00004 // run within ROOT (.x unuranDistr.cxx+) or pass any extra parameter in the command line to get  
00005 // a graphics output 
00006 
00007 
00008 #include "TStopwatch.h"
00009 
00010 #include "TUnuran.h"
00011 #include "TUnuranContDist.h"
00012 
00013 #include "TH1.h"
00014 #include "TF1.h"
00015 
00016 #include "TRandom3.h"
00017 #include "TSystem.h"
00018 #include "TStyle.h"
00019 
00020 #include "TApplication.h"
00021 #include "TCanvas.h"
00022 
00023 #include "Math/DistFunc.h"
00024 #include <cmath>
00025 #include <cassert>
00026 
00027 #include "TError.h"
00028 
00029 #include <iostream> 
00030 
00031 using std::cout; 
00032 using std::endl; 
00033 
00034 int n = 5000000;
00035 
00036 bool useRandomSeed = false;   // to use a random seed different every time
00037 
00038 double par[1] = {1}; // function parameters
00039 
00040 double norm(double *x, double *p) { 
00041    return ROOT::Math::normal_pdf(x[0],p[0]); 
00042 }
00043 
00044 double cdf(double *x, double *p) { 
00045    return ROOT::Math::normal_cdf(x[0],p[0]); 
00046 }
00047 double cdf_trunc(double *x, double *p) { 
00048    double a1 = ROOT::Math::normal_cdf(p[1],p[0]); 
00049    double a2 = ROOT::Math::normal_cdf(p[2],p[0]); 
00050    
00051    return ( ROOT::Math::normal_cdf(x[0],p[0]) - a1 )/(a2-a1); 
00052 }
00053 
00054 class DistTest { 
00055 public: 
00056    DistTest(TF1 * f) : 
00057       fCdf(f), 
00058       fHref(0)
00059    { 
00060       // generate reference histo for distribution using cdf 
00061 
00062       // make ref histo (uniform histo between 0,1
00063       fHref = new TH1D("Href","uniform ref histo",100,0,1);
00064       for (int i = 0; i < n; ++i) 
00065          fHref->Fill(gRandom->Rndm() );
00066    }
00067 
00068    void SetCdf(TF1 *f) { 
00069       fCdf = f; 
00070    }
00071 
00072    int testUnuran(TUnuran & unr) { 
00073 
00074       assert(fHref != 0);
00075       assert(fCdf != 0);
00076 
00077       // test first the time
00078       TStopwatch w; 
00079 
00080       w.Start(); 
00081       for (int i = 0; i < n; ++i) 
00082          unr.Sample(); 
00083 
00084       w.Stop(); 
00085       double time = w.CpuTime()*1.E9/n; 
00086 
00087 
00088       TH1D htmp("htmp","gaussian generated cdf",100,0,1.);   
00089       // test quality (use cdf to avoid zero bins)
00090       int n2 = n/100;
00091       double x;
00092       for (int i = 0; i<n2; ++i) { 
00093          x =  unr.Sample(); 
00094          htmp.Fill( fCdf->Eval(x) ); 
00095       } 
00096       double prob = fHref->Chi2Test(&htmp,"UU");
00097       cout << "Time using Unuran  " << unr.MethodName() << "   \t=\t " << time << "\tns/call \t\tChi2 Prob = "<< prob << endl;
00098       if (prob < 1E-06) { 
00099          std::cout << "Chi2 Test failed ! " << std::endl;
00100          fHref->Chi2Test(&htmp,"UUP"); // print all chi2 test info
00101          return 1;
00102       }
00103       return 0; 
00104    }  
00105 
00106    int testGetRandom(TF1 * f) { 
00107 
00108       assert(fHref != 0);
00109       assert(fCdf != 0);
00110 
00111       // test first the time
00112 
00113       TStopwatch w; 
00114       w.Start();
00115       for (int i = 0; i < n; ++i) {
00116          f->GetRandom(); 
00117       }
00118 
00119       w.Stop(); 
00120       double time = w.CpuTime()*1.E9/n; 
00121 
00122 
00123       TH1D htmp("htmp","gaussian generated cdf",100,0,1.);   
00124       // test quality (use cdf to avoid zero bins)
00125       int n2 = n/100;
00126       for (int i = 0; i<n2; ++i) { 
00127          double x =  f->GetRandom(); 
00128          htmp.Fill( fCdf->Eval(x) ); 
00129       } 
00130       double prob = fHref->Chi2Test(&htmp,"UU");
00131       cout << "Time using TF1::GetRandom()    \t=\t " << time << "\tns/call \t\tChi2 Prob = "<< prob << endl;
00132       if (prob < 1E-06) { 
00133          std::cout << "Chi2 Test failed ! " << std::endl;
00134          fHref->Chi2Test(&htmp,"UUP"); // print all chi2 test info
00135          return 2;
00136       }
00137       return 0; 
00138    }  
00139 
00140 private: 
00141 
00142    TF1 * fCdf; // cumulative distribution
00143    TH1 * fHref; // reference histo
00144 
00145 }; 
00146 
00147 int unuranDistr() { 
00148 
00149    int iret = 0;
00150 
00151    // switch off printing of  info messages from chi2 test
00152    gErrorIgnoreLevel = 1001; 
00153 
00154    // check if using a random seed
00155    if (useRandomSeed) gRandom->SetSeed(0);
00156 
00157 
00158    gSystem->Load("libUnuran");
00159 
00160    // simple test of unuran
00161 
00162 
00163    TH1D * h1 = new TH1D("h1","gaussian distribution",100,-10,10);
00164    TH1D * h2 = new TH1D("h2","gaussian distribution",100,-10,10);
00165 
00166    TH1D * h1u = new TH1D("h1u","test gaussian dist",100,0,1);
00167    TH1D * h2u = new TH1D("h2u","test gaussian dist",100,0,1);
00168 
00169    
00170 
00171    TF1 * f = new TF1("n",norm,-10,10,1); 
00172    f->SetParameters(par); 
00173 
00174    TF1 * fc = new TF1("c",cdf,0,1,1); 
00175    fc->SetParameters(par); 
00176 
00177       
00178    // tester class
00179    DistTest t(fc);
00180 
00181 
00182    // create unuran 1D distribution
00183    TUnuranContDist dist(f); 
00184 
00185    // create unuran class 
00186    TUnuran unr(gRandom,2); 
00187 
00188    // test all unuran methods
00189    bool ret = false; 
00190 
00191 
00192    // arou: needs pdf and dpdf (estimated numerically in dist class)
00193    ret = unr.Init(dist,"arou"); 
00194    if (!ret) { 
00195       std::cerr << "Error initializing unuran with method " << unr.MethodName() << endl; 
00196       iret = -1;
00197    } 
00198    else 
00199       iret |= t.testUnuran(unr); 
00200 
00201    // nrou (needs only pdf , mode is an option) 
00202    ret = unr.Init(dist,"nrou"); 
00203    if (!ret) { 
00204       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00205       iret =  -2;
00206    } 
00207    else 
00208       iret |= t.testUnuran(unr); 
00209 
00210 
00211    // tdr: needs pdf and dpdf (estimated numerically in dist class)
00212    ret = unr.Init(dist,"tdr"); 
00213    if (!ret) { 
00214       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00215       iret =  -3;
00216    } 
00217    else 
00218       iret |= t.testUnuran(unr); 
00219 
00220 
00221    dist.SetCdf(fc);
00222 
00223    // hinv (needs cdf , pdf and dpdf are  optionally)
00224    ret = unr.Init(dist,"hinv"); 
00225    if (!ret) { 
00226       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00227       iret =  -4;
00228    } 
00229    else 
00230       iret |= t.testUnuran(unr); 
00231    
00232 
00233    // ninv (needs cdf, pdf is an option) 
00234    ret = unr.Init(dist,"ninv"); 
00235    n/= 10; // method is too slow
00236    if (!ret) { 
00237       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00238       iret =  -5;
00239    } 
00240    else 
00241       iret |= t.testUnuran(unr); 
00242 
00243 
00244    dist.SetMode( 0.0 );
00245    dist.SetPdfArea(1. );
00246 
00247    // srou (need pdf mode sand area)
00248    ret = unr.Init(dist,"srou"); 
00249    if (!ret) { 
00250       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00251       iret =  -6;
00252    } 
00253    else 
00254       iret |= t.testUnuran(unr); 
00255 
00256    // srou (need pdf mode sand area)
00257    ret = unr.Init(dist,"ssr"); 
00258    if (!ret) { 
00259       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00260       iret =  -7;
00261    } 
00262    else 
00263       iret |= t.testUnuran(unr); 
00264 
00265    n*= 10;
00266    ret = unr.Init(dist,"utdr"); 
00267    if (!ret) { 
00268       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00269       iret =  -8;
00270    } 
00271    else 
00272       iret |= t.testUnuran(unr); 
00273 
00274 
00275    // test with TF1::GetRandom
00276    std::cout << "\n";
00277    iret |= t.testGetRandom(f);
00278 
00279    std::cout << "\nTest truncated distribution:\n\n";
00280    
00281    dist.SetDomain(-1.,1.);
00282    // change cdf for tester
00283    TF1 * fc2 = new TF1("fc2",cdf_trunc,-1,1,3);
00284    fc2->SetParameters(par[0],-1,1.);
00285    t.SetCdf(fc2);
00286 
00287    ret = unr.Init(dist,"auto"); 
00288    if (!ret) { 
00289       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00290       iret =  -10;
00291    } 
00292    else 
00293       iret |= t.testUnuran(unr); 
00294 
00295    f->SetRange(-1,1);
00296    iret |= t.testGetRandom(f);
00297 
00298 
00299 
00300    TCanvas * c1 = new TCanvas("c1_unuran1D","Onedimensional distribution",10,10,1000,1000); 
00301    c1->Divide(2,2);
00302    gStyle->SetOptFit();
00303 
00304    // remove the domain
00305    dist.SetDomain(0,0);
00306    //f->SetRange(1,-1);
00307    f->SetRange(-10,10); // set verly low and large values is enough
00308    // show now some plots 
00309    ret = unr.Init(dist,"auto"); 
00310    if (!ret) { 
00311       std::cerr << "Error initializing unuran with method " << unr.MethodName()  << endl; 
00312       iret =  -20;
00313    } 
00314    int n2 = n/10;
00315    for (int i = 0; i < n2; ++i) {
00316       double x1 = unr.Sample();
00317       h1->Fill(  x1 ); 
00318       h1u->Fill( fc->Eval( x1 ) ); 
00319       double x2 = f->GetRandom();
00320       h2->Fill(  x2 ); 
00321       h2u->Fill( fc->Eval( x2 ) ); 
00322    }
00323   
00324    c1->cd(1);
00325    h1->Draw();
00326    h1->Fit("gaus","Q");
00327    std::cout << "\nFit result on data with unuran: " << std::endl;
00328    TF1 * f1 = h1->GetFunction("gaus");
00329    std::cout << "Gaus Fit chi2 = " << f1->GetChisquare() << " ndf = " << f1->GetNDF() << std::endl;
00330    std::cout << "Gaus Fit Prob = " << f1->GetProb() << std::endl;
00331    if (  f1->GetProb() < 1.E-6) iret = 11; 
00332    c1->cd(2);
00333    h1u->Draw("Error");
00334    h1u->Fit("pol0","Q");
00335    TF1 * f1u = h1u->GetFunction("pol0");
00336    std::cout << "CDF Fit chi2 = " << f1u->GetChisquare() << " ndf = " << f1u->GetNDF() << std::endl;
00337    std::cout << "CDF Fit Prob = " << f1u->GetProb() << std::endl;
00338    if (  f1u->GetProb() < 1.E-6) iret = 12; 
00339    
00340 
00341 
00342 
00343    c1->cd(3);
00344    h2->Draw("same");
00345    h2->Fit("gaus","Q");
00346    std::cout << "\nFit result on data  with GetRandom: " << std::endl;
00347    f1 = h2->GetFunction("gaus");
00348    std::cout << "Gaus Fit chi2 = " << f1->GetChisquare() << " ndf = " << f1->GetNDF() << std::endl;
00349    std::cout << "Gaus Fit Prob = " << f1->GetProb() << std::endl;
00350    if (  f1->GetProb() < 1.E-6) iret = 13;    
00351    c1->cd(4);
00352 
00353    h2u->Draw("Error");
00354    h2u->Fit("pol0","Q");
00355    f1 = h2u->GetFunction("pol0");
00356    std::cout << "Fit chi2 = " << f1->GetChisquare() << " ndf = " << f1->GetNDF() << std::endl;
00357    std::cout << "Fit Prob = " << f1->GetProb() << std::endl;
00358    if (  f1->GetProb() < 1.E-6) iret = 14;    
00359 
00360 
00361    std::cout << "Chi2 test Gaussian histograms :\t";
00362    h1->Chi2Test(h2,"UUP");
00363    std::cout << "Chi2 test Uniform histograms  :\t";
00364    h1u->Chi2Test(h2u,"UUP");
00365 
00366    if (iret != 0) 
00367       std::cerr <<"\n\nUnuRan Continous Distribution Test:\t  Failed !!!!!!!\n" << std::endl;
00368    else 
00369       std::cerr << "\n\nUnuRan  Continous Distribution Test:\t OK\n" << std::endl;
00370    return iret; 
00371    
00372 
00373    return iret; 
00374 
00375 }
00376 
00377 #ifndef __CINT__
00378 int main(int argc, char **argv)
00379 {
00380    int iret = 0; 
00381    if (argc > 1) { 
00382       TApplication theApp("App",&argc,argv);
00383       iret =  unuranDistr();
00384       theApp.Run();
00385    } 
00386    else 
00387       iret =  unuranDistr();
00388    
00389 }
00390 #endif

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