ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
unuranDemo.C
Go to the documentation of this file.
1 // Example macro to show unuran capabilities
2 // The results are compared with what is obtained using TRandom or TF1::GetRandom
3 // The macro is divided in 3 parts:
4 // - testStringAPI : show how to use string API of UNURAN to generate Gaussian random numbers
5 // - testDistr1D : show how to pass a 1D distribution object to UNURAN to generate numbers
6 // according to the given distribution object
7 // - testDistrMultiDIm : show how to pass a multidimensional distribution object to UNURAN
8 //
9 //
10 // To execute the macro type in:
11 //
12 // root[0]: gSystem->Load("libMathCore");
13 // root[0]: gSystem->Load("libUnuran");
14 // root[0]: .x unuranDemo.C+
15 //
16 //Author: Lorenzo Moneta
17 
18 
19 #include "TStopwatch.h"
20 
21 #include "TUnuran.h"
22 #include "TUnuranContDist.h"
23 #include "TUnuranMultiContDist.h"
24 #include "TUnuranDiscrDist.h"
25 #include "TUnuranEmpDist.h"
26 
27 #include "TH1.h"
28 #include "TH3.h"
29 #include "TF3.h"
30 #include "TMath.h"
31 
32 #include "TRandom2.h"
33 #include "TSystem.h"
34 #include "TStyle.h"
35 
36 #include "TApplication.h"
37 #include "TCanvas.h"
38 
39 #ifndef __CINT__ // need to exclude to avoid CINT re-defining them
40 #include "Math/ProbFunc.h"
41 #include "Math/DistFunc.h"
42 #endif
43 
44 #include <iostream>
45 #include <cassert>
46 
47 using std::cout;
48 using std::endl;
49 
50 // number of distribution generated points
51 #define NGEN 1000000
52 
53 int izone = 0;
54 TCanvas * c1 = 0;
55 
56 // test using UNURAN string interface
57 void testStringAPI() {
58 
59  TH1D * h1 = new TH1D("h1G","gaussian distribution from Unuran",100,-10,10);
60  TH1D * h2 = new TH1D("h2G","gaussian distribution from TRandom",100,-10,10);
61 
62  cout << "\nTest using UNURAN string API \n\n";
63 
64 
65  TUnuran unr;
66  if (! unr.Init( "normal()", "method=arou") ) {
67  cout << "Error initializing unuran" << endl;
68  return;
69  }
70 
71  int n = NGEN;
72  TStopwatch w;
73  w.Start();
74 
75  for (int i = 0; i < n; ++i) {
76  double x = unr.Sample();
77  h1->Fill( x );
78  }
79 
80  w.Stop();
81  cout << "Time using Unuran method " << unr.MethodName() << "\t=\t " << w.CpuTime() << endl;
82 
83 
84  // use TRandom::Gaus
85  w.Start();
86  for (int i = 0; i < n; ++i) {
87  double x = gRandom->Gaus(0,1);
88  h2->Fill( x );
89  }
90 
91  w.Stop();
92  cout << "Time using TRandom::Gaus \t=\t " << w.CpuTime() << endl;
93 
94  assert(c1 != 0);
95  c1->cd(++izone);
96  h1->Draw();
97  c1->cd(++izone);
98  h2->Draw();
99 
100 }
101 
102 
103 
104 double distr(double *x, double *p) {
105  return ROOT::Math::breitwigner_pdf(x[0],p[0],p[1]);
106 }
107 
108 double cdf(double *x, double *p) {
109  return ROOT::Math::breitwigner_cdf(x[0],p[0],p[1]);
110 }
111 
112 // test of unuran passing as input a distribution object( a BreitWigner) distribution
113 void testDistr1D() {
114 
115  cout << "\nTest 1D Continous distributions\n\n";
116 
117  TH1D * h1 = new TH1D("h1BW","Breit-Wigner distribution from Unuran",100,-10,10);
118  TH1D * h2 = new TH1D("h2BW","Breit-Wigner distribution from GetRandom",100,-10,10);
119 
120 
121 
122  TF1 * f = new TF1("distrFunc",distr,-10,10,2);
123  double par[2] = {1,0}; // values are gamma and mean
124  f->SetParameters(par);
125 
126  TF1 * fc = new TF1("cdfFunc",cdf,-10,10,2);
127  fc->SetParameters(par);
128 
129  // create Unuran 1D distribution object
131  // to use a different random number engine do:
132  TRandom2 * random = new TRandom2();
133  int logLevel = 2;
134  TUnuran unr(random,logLevel);
135 
136  // select unuran method for generating the random numbers
137  std::string method = "tdr";
138  //std::string method = "method=auto";
139  // "method=hinv"
140  // set the cdf for some methods like hinv that requires it
141  // dist.SetCdf(fc);
142 
143  //cout << "unuran method is " << method << endl;
144 
145  if (!unr.Init(dist,method) ) {
146  cout << "Error initializing unuran" << endl;
147  return;
148  }
149 
150 
151 
152  TStopwatch w;
153  w.Start();
154 
155  int n = NGEN;
156  for (int i = 0; i < n; ++i) {
157  double x = unr.Sample();
158  h1->Fill( x );
159  }
160 
161  w.Stop();
162  cout << "Time using Unuran method " << unr.MethodName() << "\t=\t " << w.CpuTime() << endl;
163 
164  w.Start();
165  for (int i = 0; i < n; ++i) {
166  double x = f->GetRandom();
167  h2->Fill( x );
168  }
169 
170  w.Stop();
171  cout << "Time using TF1::GetRandom() \t=\t " << w.CpuTime() << endl;
172 
173  c1->cd(++izone);
174  h1->Draw();
175 
176  c1->cd(++izone);
177  h2->Draw();
178 
179  std::cout << " chi2 test of UNURAN vs GetRandom generated histograms: " << std::endl;
180  h1->Chi2Test(h2,"UUP");
181 
182 }
183 
184 // 3D gaussian distribution
185 double gaus3d(double *x, double *p) {
186 
187  double sigma_x = p[0];
188  double sigma_y = p[1];
189  double sigma_z = p[2];
190  double rho = p[2];
191  double u = x[0] / sigma_x ;
192  double v = x[1] / sigma_y ;
193  double w = x[2] / sigma_z ;
194  double c = 1 - rho*rho ;
195  double result = (1 / (2 * TMath::Pi() * sigma_x * sigma_y * sigma_z * sqrt(c)))
196  * exp (-(u * u - 2 * rho * u * v + v * v + w*w) / (2 * c));
197  return result;
198 }
199 
200 // test of unuran passing as input a mluti-dimension distribution object
202 
203  cout << "\nTest Multidimensional distributions\n\n";
204 
205  TH3D * h1 = new TH3D("h13D","gaussian 3D distribution from Unuran",50,-10,10,50,-10,10,50,-10,10);
206  TH3D * h2 = new TH3D("h23D","gaussian 3D distribution from GetRandom",50,-10,10,50,-10,10,50,-10,10);
207 
208 
209 
210  TF3 * f = new TF3("g3d",gaus3d,-10,10,-10,10,-10,10,3);
211  double par[3] = {2,2,0.5};
212  f->SetParameters(par);
213 
214 
215 
217  TUnuran unr(gRandom);
218  //std::string method = "method=vnrou";
219 
220  //std::string method = "method=hitro;use_boundingrectangle=false ";
221  std::string method = "hitro";
222  if ( ! unr.Init(dist,method) ) {
223  cout << "Error initializing unuran" << endl;
224  return;
225  }
226 
227  TStopwatch w;
228  w.Start();
229 
230  double x[3];
231  for (int i = 0; i < NGEN; ++i) {
232  unr.SampleMulti(x);
233  h1->Fill(x[0],x[1],x[2]);
234  }
235 
236  w.Stop();
237  cout << "Time using Unuran method " << unr.MethodName() << "\t=\t\t " << w.CpuTime() << endl;
238 
239  assert(c1 != 0);
240  c1->cd(++izone);
241  h1->Draw();
242 
243 
244  // need to set a reasanable number of points in TF1 to get accettable quality from GetRandom to
245  int np = 200;
246  f->SetNpx(np);
247  f->SetNpy(np);
248  f->SetNpz(np);
249 
250  w.Start();
251  for (int i = 0; i < NGEN; ++i) {
252  f->GetRandom3(x[0],x[1],x[2]);
253  h2->Fill(x[0],x[1],x[2]);
254  }
255 
256  w.Stop();
257  cout << "Time using TF1::GetRandom \t\t=\t " << w.CpuTime() << endl;
258 
259 
260  c1->cd(++izone);
261  h2->Draw();
262 
263  std::cout << " chi2 test of UNURAN vs GetRandom generated histograms: " << std::endl;
264  h1->Chi2Test(h2,"UUP");
265 
266 }
267 //_____________________________________________
268 //
269 // example of discrete distributions
270 
271 double poisson(double * x, double * p) {
272  return ROOT::Math::poisson_pdf(int(x[0]),p[0]);
273 }
274 
276 
277  cout << "\nTest Discrete distributions\n\n";
278 
279  TH1D * h1 = new TH1D("h1PS","Unuran Poisson prob",20,0,20);
280  TH1D * h2 = new TH1D("h2PS","Poisson dist from TRandom",20,0,20);
281 
282  double mu = 5;
283 
284  TF1 * f = new TF1("fps",poisson,1,0,1);
285  f->SetParameter(0,mu);
286 
288  TUnuran unr;
289 
290  // dari method (needs also the mode and pmf sum)
291  dist2.SetMode(int(mu) );
292  dist2.SetProbSum(1.0);
293  bool ret = unr.Init(dist2,"dari");
294  if (!ret) return;
295 
296  TStopwatch w;
297  w.Start();
298 
299  int n = NGEN;
300  for (int i = 0; i < n; ++i) {
301  int k = unr.SampleDiscr();
302  h1->Fill( double(k) );
303  }
304 
305  w.Stop();
306  cout << "Time using Unuran method " << unr.MethodName() << "\t=\t\t " << w.CpuTime() << endl;
307 
308  w.Start();
309  for (int i = 0; i < n; ++i) {
310  h2->Fill( gRandom->Poisson(mu) );
311  }
312  cout << "Time using TRandom::Poisson " << "\t=\t\t " << w.CpuTime() << endl;
313 
314  c1->cd(++izone);
315  h1->SetMarkerStyle(20);
316  h1->Draw("E");
317  h2->Draw("same");
318 
319  std::cout << " chi2 test of UNURAN vs TRandom generated histograms: " << std::endl;
320  h1->Chi2Test(h2,"UUP");
321 
322 }
323 
324 //_____________________________________________
325 //
326 // example of empirical distributions
327 
328 void testEmpDistr() {
329 
330 
331  cout << "\nTest Empirical distributions using smoothing\n\n";
332 
333  // start with a set of data
334  // for example 1000 two-gaussian data
335  const int Ndata = 1000;
336  double x[Ndata];
337  for (int i = 0; i < Ndata; ++i) {
338  if (i < 0.5*Ndata )
339  x[i] = gRandom->Gaus(-1.,1.);
340  else
341  x[i] = gRandom->Gaus(1.,3.);
342  }
343 
344  TH1D * h0 = new TH1D("h0Ref","Starting data",100,-10,10);
345  TH1D * h1 = new TH1D("h1Unr","Unuran unbin Generated data",100,-10,10);
346  TH1D * h1b = new TH1D("h1bUnr","Unuran bin Generated data",100,-10,10);
347  TH1D * h2 = new TH1D("h2GR","Data from TH1::GetRandom",100,-10,10);
348 
349  h0->FillN(Ndata,x,0,1); // fill histogram with starting data
350 
351  TUnuran unr;
352  TUnuranEmpDist dist(x,x+Ndata,1);
353 
354 
355  TStopwatch w;
356  int n = NGEN;
357 
358  w.Start();
359  if (!unr.Init(dist)) return;
360  for (int i = 0; i < n; ++i) {
361  h1->Fill( unr.Sample() );
362  }
363 
364  w.Stop();
365  cout << "Time using Unuran unbin " << unr.MethodName() << "\t=\t\t " << w.CpuTime() << endl;
366 
367  TUnuranEmpDist binDist(h0);
368 
369  w.Start();
370  if (!unr.Init(binDist)) return;
371  for (int i = 0; i < n; ++i) {
372  h1b->Fill( unr.Sample() );
373  }
374  w.Stop();
375  cout << "Time using Unuran bin " << unr.MethodName() << "\t=\t\t " << w.CpuTime() << endl;
376 
377  w.Start();
378  for (int i = 0; i < n; ++i) {
379  h2->Fill( h0->GetRandom() );
380  }
381  cout << "Time using TH1::GetRandom " << "\t=\t\t " << w.CpuTime() << endl;
382 
383  c1->cd(++izone);
384 
385  h2->Draw();
386  h1->SetLineColor(kRed);
387  h1->Draw("same");
388  h1b->SetLineColor(kBlue);
389  h1b->Draw("same");
390 
391 
392 }
393 
394 
395 
396 void unuranDemo() {
397 
398  //gRandom->SetSeed(0);
399 
400  // load libraries
401  gSystem->Load("libMathCore");
402  gSystem->Load("libUnuran");
403 
404  // create canvas
405 
406  c1 = new TCanvas("c1_unuranMulti","Multidimensional distribution",10,10,1000,1000);
407  c1->Divide(2,4);
408  gStyle->SetOptFit();
409 
410  testStringAPI();
411  c1->Update();
412  testDistr1D();
413  c1->Update();
415  c1->Update();
416  testDiscDistr();
417  c1->Update();
418  testEmpDistr();
419  c1->Update();
420 
421 
422 }
double par[1]
Definition: unuranDistr.cxx:38
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3159
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual void SetParameters(const Double_t *params)
Definition: TF1.h:432
virtual Double_t GetRandom()
Return a random number following this function shape.
Definition: TF1.cxx:1762
void SetProbSum(double sum)
set the value of the sum of the probabilities in the given domain
virtual void SetNpx(Int_t npx=100)
Set the number of points used to draw the function.
Definition: TF1.cxx:3116
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:56
tuple random
Definition: hsimple.py:62
double Sample()
Sample 1D distribution User is responsible for having previously correctly initialized with TUnuran::...
Definition: TUnuran.cxx:389
return c
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
Definition: TRandom.cxx:235
Definition: Rtypes.h:61
virtual Double_t Chi2Test(const TH1 *h2, Option_t *option="UU", Double_t *res=0) const
chi^{2} test for comparing weighted and unweighted histograms
Definition: TH1.cxx:1850
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:29
#define assert(cond)
Definition: unittest.h:542
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:659
void SetMode(int mode)
set the mode of the distribution (location of maximum probability)
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1766
Double_t CpuTime()
Stop the stopwatch (if it is running) and return the cputime (in seconds) passed between the start an...
Definition: TStopwatch.cxx:123
int SampleDiscr()
Sample discrete distributions User is responsible for having previously correctly initialized with TU...
Definition: TUnuran.cxx:382
bool SampleMulti(double *x)
Sample multidimensional distributions User is responsible for having previously correctly initialized...
Definition: TUnuran.cxx:396
double gaus3d(double *x, double *p)
Definition: unuranDemo.C:185
TFile * f
double distr(double *x, double *p)
Definition: unuranDemo.C:104
double sqrt(double)
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:839
virtual Double_t GetRandom() const
return a random number distributed according the histogram bin contents.
Definition: TH1.cxx:4583
void Stop()
Stop the stopwatch.
Definition: TStopwatch.cxx:75
Double_t x[n]
Definition: legend1.C:17
int izone
Definition: unuranDemo.C:53
tuple np
Definition: multifit.py:30
TUnuranDiscrDist class for one dimensional discrete distribution.
TH2D * h2
Definition: fit2dHist.C:45
double breitwigner_pdf(double x, double gamma, double x0=0)
Probability density function of Breit-Wigner distribution, which is similar, just a different definit...
TH1F * h1
Definition: legend1.C:5
TUnuranEmpDist class for describing empiral distributions.
double breitwigner_cdf(double x, double gamma, double x0=0)
Cumulative distribution function (lower tail) of the Breit_Wigner distribution and it is similar (jus...
void testEmpDistr()
Definition: unuranDemo.C:328
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2878
3-D histogram with a double per channel (see TH1 documentation)}
Definition: TH3.h:309
SVector< double, 2 > v
Definition: Dict.h:5
A 3-Dim function with parameters.
Definition: TF3.h:30
double poisson(double *x, double *p)
Definition: unuranDemo.C:271
void testDistr1D()
Definition: unuranDemo.C:113
void SetOptFit(Int_t fit=1)
The type of information about fit parameters printed in the histogram statistics box can be selected ...
Definition: TStyle.cxx:1204
virtual void SetNpy(Int_t npy=100)
Set the number of points used to draw the function.
Definition: TF2.cxx:907
virtual void GetRandom3(Double_t &xrandom, Double_t &yrandom, Double_t &zrandom)
Return 3 random numbers following this function shape.
Definition: TF3.cxx:322
tuple w
Definition: qtexample.py:51
const std::string & MethodName() const
used Unuran method
Definition: TUnuran.h:239
virtual void SetMarkerStyle(Style_t mstyle=1)
Definition: TAttMarker.h:53
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH3.cxx:275
TUnuranMultiContDist class describing multi dimensional continuous distributions. ...
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:613
#define NGEN
Definition: unuranDemo.C:51
Double_t Pi()
Definition: TMath.h:44
The Canvas class.
Definition: TCanvas.h:48
TUnuran class.
Definition: TUnuran.h:81
double poisson_pdf(unsigned int n, double mu)
Probability density function of the Poisson distribution.
TUnuranContDist class describing one dimensional continuous distribution.
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:1073
double cdf(double *x, double *p)
Definition: unuranDemo.C:108
virtual void FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride=1)
Fill this histogram with an array x and weights w.
Definition: TH1.cxx:3265
bool Init(const std::string &distr, const std::string &method)
initialize with Unuran string interface
Definition: TUnuran.cxx:79
1-Dim function class
Definition: TF1.h:149
void testDistrMultiDim()
Definition: unuranDemo.C:201
double result[121]
Definition: Rtypes.h:61
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:424
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:362
virtual void Update()
Update canvas pad buffers.
Definition: TCanvas.cxx:2179
void testDiscDistr()
Definition: unuranDemo.C:275
double exp(double)
const Int_t n
Definition: legend1.C:16
void unuranDemo()
Definition: unuranDemo.C:396
void testStringAPI()
Definition: unuranDemo.C:57
virtual void SetNpz(Int_t npz=30)
Set the number of points used to draw the function.
Definition: TF3.cxx:664
Stopwatch class.
Definition: TStopwatch.h:30