Logo ROOT   6.10/09
Reference Guide
unuranMulti2D.cxx
Go to the documentation of this file.
1 // test using Multi-dim (2D) Distribution object interface
2 // and compare results and CPU performances using TF2::GetRandom
3 //
4 // run within ROOT (.x unuranMulti2D.cxx+) or pass any extra parameter in the command line to get
5 // a graphics output
6 
7 #include "TStopwatch.h"
8 #include "TUnuran.h"
9 #include "TUnuranMultiContDist.h"
10 
11 #include "TH2.h"
12 #include "TF2.h"
13 #include "TCanvas.h"
14 #include "TMath.h"
15 
16 #include "TRandom3.h"
17 #include "TSystem.h"
18 #include "TApplication.h"
19 #include "TError.h"
20 
21 #include "Math/Functor.h"
22 
23 // #include "Math/ProbFunc.h"
24 // #include "Math/DistFunc.h"
25 
26 #define _USE_MATH_DEFINES // for Windows
27 #include <cmath>
28 #include <iostream>
29 
30 //#define DEBUG
31 
32 using std::cout;
33 using std::endl;
34 
35 int n = 1000000;
36 
37 bool useRandomSeed = false; // to use a random seed different every time
38 
39 double gaus2d(double *x, double *p) {
40 
41  double sigma_x = p[0];
42  double sigma_y = p[1];
43  double rho = p[2];
44  double u = x[0] / sigma_x ;
45  double v = x[1] / sigma_y ;
46  double c = 1 - rho*rho ;
47  double result = (1 / (2 * TMath::Pi() * sigma_x * sigma_y * sqrt(c)))
48  * exp (-(u * u - 2 * rho * u * v + v * v ) / (2 * c));
49  return result;
50 }
51 
52 double log_gaus2d(double *x, double *p) {
53 
54  return std::log( gaus2d(x,p) ); // should re-implement it
55 }
56 
57 
58 
59 int testUnuran(TUnuran & unr, const std::string & method, const TUnuranMultiContDist & dist, TH2 * h1, const TH2 * href ) {
60 
61 #ifdef DEBUG
62  n = 1000;
63 #endif
64 
65 
66  // init unuran
67  bool ret = unr.Init(dist,method);
68  if (!ret) {
69  std::cerr << "Error initializing unuran with method " << unr.MethodName() << std::endl;
70  return -1;
71  }
72 
73  h1->Reset();
74 
75  // test first the time
76  TStopwatch w;
77 
78  w.Start();
79  double x[2];
80  for (int i = 0; i < n; ++i) {
81  unr.SampleMulti(x);
82  h1->Fill(x[0],x[1]);
83  if (method == "gibbs" && i < 100)
84  std::cout << x[0] << " , " << x[1] << std::endl;
85  }
86 
87  w.Stop();
88  double time = w.CpuTime()*1.E9/n;
89 
90  double prob = href->Chi2Test(h1,"UU");
91  double ksprob = href->KolmogorovTest(h1);
92  std::cout << "Time using Unuran " << unr.MethodName() << " \t=\t " << time << "\tns/call \t\tChi2 Prob = "
93  << prob << "\tKS Prob = " << ksprob << std::endl;
94  if (prob < 1E-06) {
95  std::cout << "Chi2 Test failed ! " << std::endl;
96  href->Chi2Test(h1,"UUP"); // print all chi2 test info
97  return 1;
98  }
99  return 0;
100 }
101 
102 int testGetRandom(TF2 * f, TH1 * h1, const TH2 * href = 0) {
103 
104 
105  // test first the time
106  h1->Reset();
107 
108  TStopwatch w;
109  w.Start();
110  double x[2] = {0,0};
111  for (int i = 0; i < n; ++i) {
112  f->GetRandom2(x[0],x[1]);
113  h1->Fill(x[0],x[1]);
114  }
115 
116  w.Stop();
117  double time = w.CpuTime()*1.E9/n;
118 
119 
120  if (href != 0) {
121  double prob = href->Chi2Test(h1,"UU");
122  std::cout << "Time using TF1::GetRandom() \t=\t " << time << "\tns/call \t\tChi2 Prob = "<< prob << std::endl;
123  if (prob < 1E-06) {
124  std::cout << "Chi2 Test failed ! " << std::endl;
125  href->Chi2Test(h1,"UUP"); // print all chi2 test info
126  return 2;
127  }
128  }
129  else
130  std::cout << "Time using TF1::GetRandom() \t=\t " << time << "\tns/call\n";
131  return 0;
132 }
133 
134 
136 
137  // check if using a random seed
138  if (useRandomSeed) gRandom->SetSeed(0);
139 
140  // switch off printing of info messages from chi2 test
141  gErrorIgnoreLevel = 1001;
142 
143 
144  gSystem->Load("libMathCore");
145  gSystem->Load("libUnuran");
146 
147  // simple test of unuran
148 
149 
150 
151  TH2D * h1 = new TH2D("h1","UNURAN gaussian 2D distribution",100,-10,10,100,-10,10);
152  TH2D * h2 = new TH2D("h2","TF1::GetRandom gaussian 2D distribution",100,-10,10,100,-10,10);
153 
154  TH2D * h3 = new TH2D("h3","UNURAN truncated gaussian 2D distribution",100,-1,1,100,-1,1);
155  TH2D * h4 = new TH2D("h4","TF1::GetRandom truncated gaussian 2D distribution",100,-1,1,100,-1,1);
156 
157 
158  TF2 * f = new TF2("g2d",gaus2d,-10,10,-10,10,3);
159  double par[3] = {1,1,0.5};
160  f->SetParameters(par);
161 
162  TF2 * flog = new TF2("logg2d",log_gaus2d,-10,10,-10,10,3);
163  flog->SetParameters(par);
164 
165 
166  f->SetNpx(100);
167  f->SetNpy(100);
168  std::cout << " Nimber of function points in TF1, Npx = " << f->GetNpx() << " Npy = " << f->GetNpy() << std::endl;
169 
170 
171  std::cout << "Test using an undefined domain :\n\n";
172 
173  // test first with getrandom
174  testGetRandom(f,h2);
175 
176  // create multi-dim distribution
178 
179  // use directly function interfaces
180  //ROOT::Math::Functor f2( *f, 2);
181  //TUnuranMultiContDist dist(f2);
182 
183  TUnuran unr(gRandom,2); // 2 is debug level
184 
185  int iret = 0;
186  TH2 * href = h2;
187 
188  //vnrou method (requires only pdf)
189  std::string method = "vnrou";
190  iret |= testUnuran(unr, method, dist, h1, href);
191 
192 
193  //hitro method (requires only pdf)
194  method = "hitro";
195  iret |= testUnuran(unr, method, dist, h1, href);
196 
197  //gibbs requires log of pdf and derivative
198 //#define USE_GIBBS
199 #ifdef USE_GIBBS
200  method = "gibbs";
201  // need to create a new multi-dim distribution with log of pdf
202  TUnuranMultiContDist logdist(flog,0,true);
203  iret |= testUnuran(unr, method, logdist, h1, href);
204 #endif
205 
206  // test setting the mode
207  std::cout << "\nTest setting the mode in Unuran distribution:\n\n";
208  double m[2] = {0,0};
209  dist.SetMode(m);
210 
211  method = "vnrou";
212  iret |= testUnuran(unr, method, dist, h1, href);
213 
214  method = "hitro";
215  iret |= testUnuran(unr, method, dist, h1, href);
216 
217 #ifdef USE_GIBBS
218  method = "gibbs";
219  logdist.SetMode(m);
220  iret |= testUnuran(unr, method, logdist, h1, href);
221 #endif
222 
223 
224 // std::cout << " chi2 test of histogram generated with Unuran vs histogram generated with TF1::GetRandom " << std::endl;
225 // h1->Chi2Test(h2,"UUP");
226 
227 //#ifdef LATER
228 
229  double xmin[2] = { -1, -1 };
230  double xmax[2] = { 1, 1 };
231 
232  f->SetRange(xmin[0],xmin[1],xmax[0],xmax[1]);
233  // change function domain (not yet implemented in unuran for multidim functions)
234  dist.SetDomain(xmin,xmax);
235 
236  const double *xlow = dist.GetLowerDomain();
237  const double *xup = dist.GetUpperDomain();
238  std::cout << "\nTest truncated distribution in domain [ " << xlow[0] << " : " << xup[0]
239  << " , " << xlow[1] << " : " << xup[1] << " ] :\n\n";
240 
241 
242  testGetRandom(f,h4);
243 
244  method = "vnrou";
245  iret |= testUnuran(unr, method, dist, h3, h4);
246  method = "hitro";
247  iret |= testUnuran(unr, method, dist, h3, h4);
248 #ifdef USE_GIBBS
249  logdist.SetDomain(xmin,xmax);
250  method = "gibbs";
251  iret |= testUnuran(unr, method, logdist, h3, h4);
252 #endif
253 
254 //#ifdef LATER
255  TCanvas * c1 = new TCanvas("c1_unuran2D","Multidimensional distribution",10,10,900,900);
256  c1->Divide(2,2);
257 #ifdef NO_TRUNC
258  TCanvas * c1 = new TCanvas("c1_unuran2D","Multidimensional distribution",10,10,500,500);
259  c1->Divide(1,2);
260 #endif
261 
262 
263  c1->cd(1);
264  h1->Draw("col");
265 
266 
267  c1->cd(2);
268  h2->Draw("col");
269 
270  c1->cd(3);
271  h3->Draw("col");
272  c1->cd(4);
273  h4->Draw("col");
274 //#endif
275 
276  if (iret != 0)
277  std::cerr <<"\n\nUnuRan 2D Continous Distribution Test:\t Failed !!!!!!!\n" << std::endl;
278  else
279  std::cerr << "\n\nUnuRan 2D Continous Distribution Test:\t OK\n" << std::endl;
280 
281  return iret;
282 
283 }
284 
285 #ifndef __CINT__
286 int main(int argc, char **argv)
287 {
288  int iret = 0;
289  if (argc > 1) {
290  TApplication theApp("App",&argc,argv);
291  iret = unuranMulti2D();
292  theApp.Run();
293  }
294  else
295  iret = unuranMulti2D();
296 
297  return iret;
298 }
299 #endif
Int_t GetNpy() const
Definition: TF2.h:100
double par[1]
Definition: unuranDistr.cxx:38
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3126
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:588
float xmin
Definition: THbookFile.cxx:93
virtual Int_t GetNpx() const
Definition: TF1.h:444
virtual void SetNpx(Int_t npx=100)
Set the number of points used to draw the function.
Definition: TF1.cxx:3202
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:58
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:105
return c1
Definition: legend1.C:41
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:679
const double * GetLowerDomain() const
get the distribution lower domain values.
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1825
Double_t CpuTime()
Stop the stopwatch (if it is running) and return the cputime (in seconds) passed between the start an...
Definition: TStopwatch.cxx:125
bool SampleMulti(double *x)
Sample multidimensional distributions User is responsible for having previously correctly initialized...
Definition: TUnuran.cxx:396
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6419
double log_gaus2d(double *x, double *p)
double sqrt(double)
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:77
Double_t x[n]
Definition: legend1.C:17
virtual Double_t Chi2Test(const TH1 *h2, Option_t *option="UU", Double_t *res=0) const
test for comparing weighted and unweighted histograms
Definition: TH1.cxx:1830
virtual void Run(Bool_t retrn=kFALSE)
Main application eventloop. Calls system dependent eventloop via gSystem.
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition: TRandom.cxx:568
int main(int argc, char **argv)
int testGetRandom(TF2 *f, TH1 *h1, const TH2 *href=0)
TString flog
Definition: pq2main.cxx:37
TH1F * h1
Definition: legend1.C:5
constexpr Double_t Pi()
Definition: TMath.h:40
bool useRandomSeed
Service class for 2-Dim histogram classes.
Definition: TH2.h:30
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2851
SVector< double, 2 > v
Definition: Dict.h:5
TMarker * m
Definition: textangle.C:8
int n
virtual void SetNpy(Int_t npy=100)
Set the number of points used to draw the function.
Definition: TF2.cxx:908
void SetDomain(const double *xmin, const double *xmax)
set the domain of the distribution giving an array of minimum and maximum values By default otherwise...
float xmax
Definition: THbookFile.cxx:93
TUnuranMultiContDist class describing multi dimensional continuous distributions. ...
A 2-Dim function with parameters.
Definition: TF2.h:29
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
constexpr Double_t E()
Definition: TMath.h:74
The Canvas class.
Definition: TCanvas.h:31
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition: TF2.h:150
TUnuran class.
Definition: TUnuran.h:79
double f(double x)
virtual void GetRandom2(Double_t &xrandom, Double_t &yrandom)
Return 2 random numbers following this function shape.
Definition: TF2.cxx:505
The TH1 histogram class.
Definition: TH1.h:56
THist< 2, double, THistStatContent, THistStatUncertainty > TH2D
Definition: THist.hxx:316
const std::string & MethodName() const
used Unuran method
Definition: TUnuran.h:237
const double * GetUpperDomain() const
get the distribution upper domain values.
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1135
bool Init(const std::string &distr, const std::string &method)
initialize with Unuran string interface
Definition: TUnuran.cxx:79
void SetMode(const double *x)
set the mode of the distribution (coordinates of the distribution maximum values) ...
int unuranMulti2D()
double result[121]
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
Definition: TApplication.h:39
double gaus2d(double *x, double *p)
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH2.cxx:2455
double exp(double)
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:292
int testUnuran(TUnuran &unr, const std::string &method, const TUnuranMultiContDist &dist, TH2 *h1, const TH2 *href)
double log(double)
virtual Double_t KolmogorovTest(const TH1 *h2, Option_t *option="") const
Statistical test of compatibility in shape between THIS histogram and h2, using Kolmogorov test...
Definition: TH2.cxx:1343
tomato 2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:290
Stopwatch class.
Definition: TStopwatch.h:28