Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
TUnuran.cxx
Go to the documentation of this file.
1// @(#)root/unuran:$Id$
2// Authors: L. Moneta, J. Leydold Tue Sep 26 16:25:09 2006
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7 * *
8 * *
9 **********************************************************************/
10
11// Implementation file for class TUnuran
12
13#include "TUnuran.h"
14
15#include "TUnuranContDist.h"
17#include "TUnuranDiscrDist.h"
18#include "TUnuranEmpDist.h"
19
20#include "UnuranRng.h"
21#include "UnuranDistrAdapter.h"
22
23#include "TRandom.h"
24
25#include <cassert>
26
27#include <unuran.h>
28
29#include "TError.h"
30
31
33 fGen(nullptr),
34 fUdistr(nullptr),
35 fUrng(nullptr),
36 fRng(r)
37{
38 // constructor implementation with a ROOT random generator
39 // if no generator is given the ROOT default is used
40 if (fRng == nullptr) fRng = gRandom;
41 // set debug level at global level
42 // (should be in a static initialization function of the library ? )
43 if ( debugLevel > 1)
45 else if (debugLevel == 1)
47 else
49
50}
51
52
54{
55 // Destructor implementation
56 if (fGen != nullptr) unur_free(fGen);
57 if (fUrng != nullptr) unur_urng_free(fUrng);
58 // we can delete now the distribution object
59 if (fUdistr != nullptr) unur_distr_free(fUdistr);
60}
61
62//private (no impl.)
64{
65 // Implementation of copy constructor.
66}
67
69{
70 // Implementation of assignment operator.
71 if (this == &rhs) return *this; // time saving self-test
72 return *this;
73}
74
75bool TUnuran::Init(const std::string & dist, const std::string & method)
76{
77 // initialize with a string
78 std::string s = dist + " & " + method;
79 fGen = unur_str2gen(s.c_str() );
80 if (fGen == nullptr) {
81 Error("Init","Cannot create generator object");
82 return false;
83 }
84 if (! SetRandomGenerator() ) return false;
85
86 return true;
87}
88
89bool TUnuran::Init(const TUnuranContDist & distr, const std::string & method)
90{
91 // initialization with a distribution and and generator
92 // the distribution object is copied in and managed by this class
93 // use std::unique_ptr to manage previously existing distribution objects
94 TUnuranContDist * distNew = distr.Clone();
95 fDist.reset(distNew);
96
98 if (! SetContDistribution(*distNew) ) return false;
99 if (! SetMethodAndInit() ) return false;
100 if (! SetRandomGenerator() ) return false;
101 return true;
102}
103
104
105bool TUnuran::Init(const TUnuranMultiContDist & distr, const std::string & method)
106{
107 // initialization with a distribution and method
108 // the distribution object is copied in and managed by this class
109 // use std::unique_ptr to manage previously existing distribution objects
111 fDist.reset(distNew);
112
113 fMethod = method;
114 if (! SetMultiDistribution(*distNew) ) return false;
115 if (! SetMethodAndInit() ) return false;
116 if (! SetRandomGenerator() ) return false;
117 return true;
118}
119
120
121bool TUnuran::Init(const TUnuranDiscrDist & distr, const std::string & method ) {
122 // initialization with a distribution and and generator
123 // the distribution object is copied in and managed by this class
124 // use std::unique_ptr to manage previously existing distribution objects
125 TUnuranDiscrDist * distNew = distr.Clone();
126 fDist.reset(distNew);
127
128 fMethod = method;
129 if (! SetDiscreteDistribution(*distNew) ) return false;
130 if (! SetMethodAndInit() ) return false;
131 if (! SetRandomGenerator() ) return false;
132 return true;
133}
134
135bool TUnuran::Init(const TUnuranEmpDist & distr, const std::string & method ) {
136 // initialization with a distribution and and generator
137 // the distribution object is copied in and managed by this class
138 // use std::unique_ptr to manage previously existing distribution objects
139 TUnuranEmpDist * distNew = distr.Clone();
140 fDist.reset(distNew);
141
142 fMethod = method;
143 if (distr.IsBinned()) fMethod = "hist";
144 else if (distr.NDim() > 1) fMethod = "vempk";
145 if (! SetEmpiricalDistribution(*distNew) ) return false;
146 if (! SetMethodAndInit() ) return false;
147 if (! SetRandomGenerator() ) return false;
148 return true;
149}
150
151
153{
154 // set an external random generator
155 if (fRng == nullptr) return false;
156 if (fGen == nullptr) return false;
157
159 if (fUrng == nullptr) return false;
160 unsigned int ret = 0;
163 if (ret != 0) return false;
164
166 return true;
167}
168
170{
171 // internal method to set in unuran the function pointer for a continuous univariate distribution
172 if (fUdistr != nullptr) unur_distr_free(fUdistr);
174 if (fUdistr == nullptr) return false;
175 unsigned int ret = 0;
177 if ( ! dist.IsLogPdf() ) {
180 if (dist.HasCdf() ) ret |= unur_distr_cont_set_cdf(fUdistr, &ContDist::Cdf);
181 }
182 else {
183 // case user provides log of pdf
186 }
187
188 double xmin, xmax = 0;
189 if (dist.GetDomain(xmin,xmax) ) {
191 if (ret != 0) {
192 Error("SetContDistribution","invalid domain xmin = %g xmax = %g ",xmin,xmax);
193 return false;
194 }
195 }
196 if (dist.HasMode() ) {
197 ret = unur_distr_cont_set_mode(fUdistr, dist.Mode());
198 if (ret != 0) {
199 Error("SetContDistribution","invalid mode given, mode = %g ",dist.Mode());
200 return false;
201 }
202 }
203 if (dist.HasPdfArea() ) {
204 ret = unur_distr_cont_set_pdfarea(fUdistr, dist.PdfArea());
205 if (ret != 0) {
206 Error("SetContDistribution","invalid area given, area = %g ",dist.PdfArea());
207 return false;
208 }
209 }
210
211 return (ret ==0) ? true : false;
212}
213
214
216{
217 // internal method to set in unuran the function pointer for a multivariate distribution
218 if (fUdistr != nullptr) unur_distr_free(fUdistr);
219 fUdistr = unur_distr_cvec_new(dist.NDim() );
220 if (fUdistr == nullptr) return false;
221 unsigned int ret = 0;
223 if ( ! dist.IsLogPdf() ) {
227 }
228 else {
232 }
233
234 const double * xmin = dist.GetLowerDomain();
235 const double * xmax = dist.GetUpperDomain();
236 if ( xmin != nullptr || xmax != nullptr ) {
238 if (ret != 0) {
239 Error("SetMultiDistribution","invalid domain");
240 return false;
241 }
242#ifdef OLDVERS
243 Error("SetMultiDistribution","domain setting not available in UNURAN 0.8.1");
244#endif
245
246 }
247
248 const double * xmode = dist.GetMode();
249 if (xmode != nullptr) {
251 if (ret != 0) {
252 Error("SetMultiDistribution","invalid mode");
253 return false;
254 }
255 }
256 return (ret ==0) ? true : false;
257}
258
260
261 // internal method to set in unuran the function pointer for am empiral distribution (from histogram)
262 if (fUdistr != nullptr) unur_distr_free(fUdistr);
263 if (dist.NDim() == 1)
265 else
266 fUdistr = unur_distr_cvemp_new(dist.NDim() );
267
268 if (fUdistr == nullptr) return false;
269 unsigned int ret = 0;
270
271
272 // get info from histogram
273 if (dist.IsBinned() ) {
274 int nbins = dist.Data().size();
275 double min = dist.LowerBin();
276 double max = dist.UpperBin();
277 const double * pv = &(dist.Data().front());
278 ret |= unur_distr_cemp_set_hist(fUdistr, pv, nbins, min, max);
279#ifdef OLDVERS
280 Error("SetEmpiricalDistribution","hist method not available in UNURAN 0.8.1");
281#endif
282 }
283 else {
284 const double * pv = &dist.Data().front();
285 // n is number of points (size/ndim)
286 int n = dist.Data().size()/dist.NDim();
287 if (dist.NDim() == 1)
289 else
291 }
292 if (ret != 0) {
293 Error("SetEmpiricalDistribution","invalid distribution object");
294 return false;
295 }
296 return true;
297}
298
299
301{
302 // internal method to set in unuran the function pointer for a discrete univariate distribution
303 if (fUdistr != nullptr) unur_distr_free(fUdistr);
305 if (fUdistr == nullptr) return false;
306 unsigned int ret = 0;
307 // if a probability mesh function is provided
308 if (dist.ProbVec().empty()) {
311 if (dist.HasCdf() ) ret |= unur_distr_discr_set_cdf(fUdistr, &DiscrDist::Cdf);
312
313 }
314 else {
315 // case user provides vector of probabilities
316 ret |= unur_distr_discr_set_pv(fUdistr, &dist.ProbVec().front(), dist.ProbVec().size() );
317 }
318
319 int xmin, xmax = 0;
320 if (dist.GetDomain(xmin,xmax) ) {
322 if (ret != 0) {
323 Error("SetDiscrDistribution","invalid domain xmin = %d xmax = %d ",xmin,xmax);
324 return false;
325 }
326 }
327 if (dist.HasMode() ) {
328 ret = unur_distr_discr_set_mode(fUdistr, dist.Mode());
329 if (ret != 0) {
330 Error("SetContDistribution","invalid mode given, mode = %d ",dist.Mode());
331 return false;
332 }
333 }
334 if (dist.HasProbSum() ) {
335 ret = unur_distr_discr_set_pmfsum(fUdistr, dist.ProbSum());
336 if (ret != 0) {
337 Error("SetContDistribution","invalid sum given, mode = %g ",dist.ProbSum());
338 return false;
339 }
340 }
341
342 return (ret ==0) ? true : false;
343}
344
346
347 // internal function to set a method from a distribution and
348 // initialize unuran with the given distribution.
349 if (fUdistr == nullptr) return false;
350
351 struct unur_slist *mlist = nullptr;
352
353 UNUR_PAR * par = _unur_str2par(fUdistr, fMethod.c_str(), &mlist);
354 if (par == nullptr) {
355 Error("SetMethod","missing distribution information or syntax error");
356 if (mlist != nullptr) _unur_slist_free(mlist);
357 return false;
358 }
359
360
361 // set unuran to not use a private copy of the distribution object
363
364 // need to free fGen if already existing ?
365 if (fGen != nullptr ) unur_free(fGen);
366 fGen = unur_init(par);
368 if (fGen == nullptr) {
369 Error("SetMethod","initializing Unuran: condition for method violated");
370 return false;
371 }
372 return true;
373 }
374
375std::string TUnuran::GetInfo(bool extended)
376{
377 // get information string about Unuran generator
378 if (!fGen) return std::string();
379 return std::string(unur_gen_info(fGen, extended));
380}
381
382std::string TUnuran::GetGenId() const
383{
384 // get Unuran generator ID
385 if (!fGen) return std::string();
386 return std::string(unur_get_genid(fGen));
387}
388
390{
391 // get dimension of the UNURAN generator
392 if (!fGen) return 0;
393 return unur_get_dimension(fGen);
394}
395
397{
398 // get type of distribution
399 if (!fGen) return -1;
401}
402
404 if (!fGen) return false;
406}
408 if (!fGen) return false;
410}
412 if (!fGen) return false;
414}
416 if (!fGen) return false;
418}
419
421{
422 // sample one-dimensional distribution
423 assert(fGen != nullptr);
424 return unur_sample_discr(fGen);
425}
426
428{
429 // sample one-dimensional distribution
430 assert(fGen != nullptr);
431 return unur_sample_cont(fGen);
432}
433
435{
436 // sample multidimensional distribution
437 if (fGen == nullptr) return false;
439 return true;
440}
441
442void TUnuran::SetSeed(unsigned int seed) {
443 return fRng->SetSeed(seed);
444}
445
447{
448 if (fGen == nullptr) return false;
449 int ret = 0;
450 if ( debugLevel > 1)
452 else if (debugLevel == 1)
454 else
456
457 return (ret ==0) ? true : false;
458
459}
460
461bool TUnuran::InitPoisson(double mu, const std::string & method) {
462 // initialization for a Poisson
463 double p[1];
464 p[0] = mu;
465
467
468 fMethod = method;
469 if (fUdistr == nullptr) return false;
470 if (! SetMethodAndInit() ) return false;
471 if (! SetRandomGenerator() ) return false;
472 return true;
473}
474
475bool TUnuran::InitBinomial(unsigned int ntot, double prob, const std::string & method ) {
476 // initialization for a Binomial
477 double par[2];
478 par[0] = ntot;
479 par[1] = prob;
481
482 fMethod = method;
483 if (fUdistr == nullptr) return false;
484 if (! SetMethodAndInit() ) return false;
485 if (! SetRandomGenerator() ) return false;
486 return true;
487}
488
489
490bool TUnuran::ReInitDiscrDist(unsigned int npar, double * par) {
491 // re-initialization of UNURAN without freeing and creating a new fGen object
492 // works only for pre-defined distribution by changing their parameters
493 if (!fGen ) return false;
494 if (!fUdistr) return false;
496 int iret = unur_reinit(fGen);
497 if (iret) Warning("ReInitDiscrDist","re-init failed - a full initizialization must be performed");
498 return (!iret);
499}
500
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
float xmin
float xmax
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition TRandom.cxx:615
TUnuranContDist class describing one dimensional continuous distribution.
TUnuranDiscrDist class for one dimensional discrete distribution.
TUnuranEmpDist class for describing empirical distributions.
TUnuranMultiContDist class describing multi dimensional continuous distributions.
TUnuran class.
Definition TUnuran.h:79
std::string GetGenId() const
Return an ID string about the unuran generator method.
Definition TUnuran.cxx:382
bool IsDistCont() const
Return true for a univariate continuous distribution.
Definition TUnuran.cxx:403
bool SetMethodAndInit()
change the method and initialize Unuran with the previously given distribution
Definition TUnuran.cxx:345
int SampleDiscr()
Sample discrete distributions.
Definition TUnuran.cxx:420
std::unique_ptr< TUnuranBaseDist > fDist
Definition TUnuran.h:316
bool SetDiscreteDistribution(const TUnuranDiscrDist &dist)
Definition TUnuran.cxx:300
int GetDistType() const
Return the type of the distribution.
Definition TUnuran.cxx:396
bool InitBinomial(unsigned int ntot, double prob, const std::string &method="dstd")
Initialize method for the Binomial distribution.
Definition TUnuran.cxx:475
bool SetContDistribution(const TUnuranContDist &dist)
Definition TUnuran.cxx:169
std::string GetInfo(bool extended=false)
Return an information string about the used Unuran generator method.
Definition TUnuran.cxx:375
bool SampleMulti(double *x)
Sample multidimensional distributions.
Definition TUnuran.cxx:434
bool ReInitDiscrDist(unsigned int npar, double *params)
Reinitialize UNURAN by changing the distribution parameters but maintaining same distribution and met...
Definition TUnuran.cxx:490
TUnuran(TRandom *r=nullptr, unsigned int log=0)
Constructor with a generator instance and given level of log output.
Definition TUnuran.cxx:32
bool IsDistMultiCont() const
Return true for a multivariate continuous distribution.
Definition TUnuran.cxx:407
UNUR_DISTR * fUdistr
Definition TUnuran.h:314
bool Init(const std::string &distr, const std::string &method)
Initialize with Unuran string API interface.
Definition TUnuran.cxx:75
UNUR_GEN * fGen
Definition TUnuran.h:313
bool SetRandomGenerator()
Definition TUnuran.cxx:152
bool SetLogLevel(unsigned int iflag=1)
set log level
Definition TUnuran.cxx:446
UNUR_URNG * fUrng
Definition TUnuran.h:315
TRandom * fRng
Definition TUnuran.h:317
bool SetMultiDistribution(const TUnuranMultiContDist &dist)
Definition TUnuran.cxx:215
bool IsDistEmpirical() const
Return true for an empirical distribution.
Definition TUnuran.cxx:415
double Sample()
Sample 1D distribution.
Definition TUnuran.cxx:427
bool SetEmpiricalDistribution(const TUnuranEmpDist &dist)
Definition TUnuran.cxx:259
~TUnuran()
Destructor.
Definition TUnuran.cxx:53
bool InitPoisson(double mu, const std::string &method="dstd")
Initialize method for the Poisson distribution.
Definition TUnuran.cxx:461
std::string fMethod
Definition TUnuran.h:318
TUnuran & operator=(const TUnuran &rhs)
Assignment operator.
Definition TUnuran.cxx:68
int GetDimension() const
Return the dimension of unuran generator method.
Definition TUnuran.cxx:389
void SetSeed(unsigned int seed)
set the seed for the random number generator
Definition TUnuran.cxx:442
bool IsDistDiscrete() const
Return true for a discrete distribution.
Definition TUnuran.cxx:411
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
static double Cdf(double x, const UNUR_DISTR *dist)
evaluate the Cumulative distribution function, integral of the pdf
static double Pdf(double x, const UNUR_DISTR *dist)
evaluate the probality density function
static double Dpdf(double x, const UNUR_DISTR *dist)
evaluate the derivative of the pdf
static double Pmf(int x, const UNUR_DISTR *dist)
evaluate the probality mesh function
static double Cdf(int x, const UNUR_DISTR *dist)
evaluate the cumulative function
static double Pdf(const double *x, UNUR_DISTR *dist)
evaluate the probality density function
static int Dpdf(double *grad, const double *x, UNUR_DISTR *dist)
static double Pdpdf(const double *x, int coord, UNUR_DISTR *dist)
UnuranRng class for interface ROOT random generators to Unuran.
Definition UnuranRng.h:22