00001
00002
00003
00004
00005
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;
00037
00038 double par[1] = {1};
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
00061
00062
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
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
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");
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
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
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");
00135 return 2;
00136 }
00137 return 0;
00138 }
00139
00140 private:
00141
00142 TF1 * fCdf;
00143 TH1 * fHref;
00144
00145 };
00146
00147 int unuranDistr() {
00148
00149 int iret = 0;
00150
00151
00152 gErrorIgnoreLevel = 1001;
00153
00154
00155 if (useRandomSeed) gRandom->SetSeed(0);
00156
00157
00158 gSystem->Load("libUnuran");
00159
00160
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
00179 DistTest t(fc);
00180
00181
00182
00183 TUnuranContDist dist(f);
00184
00185
00186 TUnuran unr(gRandom,2);
00187
00188
00189 bool ret = false;
00190
00191
00192
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
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
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
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
00234 ret = unr.Init(dist,"ninv");
00235 n/= 10;
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
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
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
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
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
00305 dist.SetDomain(0,0);
00306
00307 f->SetRange(-10,10);
00308
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