Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TUnuranContDist.cxx
Go to the documentation of this file.
1 // @(#)root/unuran:$Id$
2 // Authors: L. Moneta, J. Leydold Wed Feb 28 2007
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Implementation file for class TUnuranContDist
12 
13 #include "TUnuranContDist.h"
15 #include "Math/WrappedTF1.h"
16 
17 #include "Math/Integrator.h"
18 
19 #include "TF1.h"
20 #include <cassert>
21 #include <cmath>
22 
23 ClassImp(TUnuranContDist);
24 
25 TUnuranContDist::TUnuranContDist (const ROOT::Math::IGenFunction & pdf, const ROOT::Math::IGenFunction * deriv, bool isLogPdf, bool copyFunc ) :
26  fPdf(&pdf),
27  fDPdf(deriv),
28  fCdf(0),
29  fXmin(1.),
30  fXmax(-1.),
31  fMode(0),
32  fArea(0),
33  fIsLogPdf(isLogPdf),
34  fHasDomain(0),
35  fHasMode(0),
36  fHasArea(0),
37  fOwnFunc(copyFunc)
38 {
39  // Constructor from generic function interfaces
40  // manage the functions and clone them if flag copyFunc is true
41  if (fOwnFunc) {
42  fPdf = fPdf->Clone();
43  if (fDPdf) fDPdf->Clone();
44  }
45 }
46 
47 
48 TUnuranContDist::TUnuranContDist (TF1 * pdf, TF1 * deriv, bool isLogPdf ) :
49  fPdf( (pdf) ? new ROOT::Math::WrappedTF1 ( *pdf) : 0 ),
50  fDPdf( (deriv) ? new ROOT::Math::WrappedTF1 ( *deriv) : 0 ),
51  fCdf(0),
52  fXmin(1.),
53  fXmax(-1.),
54  fMode(0),
55  fArea(0),
56  fIsLogPdf(isLogPdf),
57  fHasDomain(0),
58  fHasMode(0),
59  fHasArea(0),
60  fOwnFunc(true)
61 {
62  // Constructor from a TF1 objects
63  // function pointers are managed by class
64 }
65 
66 
67 TUnuranContDist::TUnuranContDist(const TUnuranContDist & rhs) :
68  TUnuranBaseDist(),
69  fPdf(0),
70  fDPdf(0),
71  fCdf(0)
72 {
73  // Implementation of copy constructor
74  operator=(rhs);
75 }
76 
77 TUnuranContDist & TUnuranContDist::operator = (const TUnuranContDist &rhs)
78 {
79  // Implementation of assignment operator.
80  if (this == &rhs) return *this; // time saving self-test
81  fXmin = rhs.fXmin;
82  fXmax = rhs.fXmax;
83  fMode = rhs.fMode;
84  fArea = rhs.fArea;
85  fIsLogPdf = rhs.fIsLogPdf;
86  fHasDomain = rhs.fHasDomain;
87  fHasMode = rhs.fHasMode;
88  fHasArea = rhs.fHasArea;
89  fOwnFunc = rhs.fOwnFunc;
90  if (!fOwnFunc) {
91  fPdf = rhs.fPdf;
92  fDPdf = rhs.fDPdf;
93  fCdf = rhs.fCdf;
94  }
95  else {
96  if (fPdf) delete fPdf;
97  if (fDPdf) delete fDPdf;
98  if (fCdf) delete fCdf;
99  fPdf = (rhs.fPdf) ? rhs.fPdf->Clone() : 0;
100  fDPdf = (rhs.fDPdf) ? rhs.fDPdf->Clone() : 0;
101  fCdf = (rhs.fCdf) ? rhs.fCdf->Clone() : 0;
102  }
103 
104  return *this;
105 }
106 
107 TUnuranContDist::~TUnuranContDist() {
108  // destructor implementation
109  if (fOwnFunc) {
110  if (fPdf) delete fPdf;
111  if (fDPdf) delete fDPdf;
112  if (fCdf) delete fCdf;
113  }
114 }
115 
116 void TUnuranContDist::SetCdf(const ROOT::Math::IGenFunction & cdf) {
117  // set cdf distribution using a generic function interface
118  fCdf = (fOwnFunc) ? cdf.Clone() : &cdf;
119 }
120 
121 
122 void TUnuranContDist::SetCdf(TF1 * cdf) {
123  // set cumulative distribution function from a TF1
124  if (!fOwnFunc) {
125  // need to manage all functions now
126  assert (fPdf != 0);
127  fPdf = fPdf->Clone();
128  if (fDPdf) fDPdf->Clone();
129  }
130  else
131  if (fOwnFunc && fCdf) delete fCdf;
132 
133  fCdf = (cdf) ? new ROOT::Math::WrappedTF1 ( *cdf) : 0;
134  fOwnFunc = true;
135 }
136 
137 double TUnuranContDist::Pdf ( double x) const {
138  // evaluate the pdf of the distribution
139  assert(fPdf != 0);
140  //fX[0] = x;
141  return (*fPdf)(x);
142 }
143 
144 double TUnuranContDist::DPdf( double x) const {
145  // evaluate the derivative of the pdf
146  // if derivative function is not given is evaluated numerically
147  if (fDPdf != 0) {
148  //fX[0] = x;
149  return (*fDPdf)(x);
150  }
151  // do numerical derivation using numerical derivation
152  ROOT::Math::RichardsonDerivator rd;
153  static double gEps = 0.001;
154  double h = ( std::abs(x) > 0 ) ? gEps * std::abs(x) : gEps;
155  assert (fPdf != 0);
156  return rd.Derivative1( *fPdf, x, h);
157 }
158 
159 double TUnuranContDist::Cdf(double x) const {
160  // evaluate the integral (cdf) on the domain
161  if (fCdf != 0) {
162  // fX[0] = x;
163  return (*fCdf)(x);
164  }
165  // do numerical integration
166  ROOT::Math::Integrator ig;
167  if (fXmin > fXmax) return ig.Integral( *fPdf );
168  else
169  return ig.Integral( *fPdf, fXmin, fXmax );
170 
171 }
172