00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TUnuranContDist.h"
00014 #include "Math/RichardsonDerivator.h"
00015 #include "Math/WrappedTF1.h"
00016
00017 #include "Math/Integrator.h"
00018
00019 #include "TF1.h"
00020 #include <cassert>
00021 #include <cmath>
00022
00023 ClassImp(TUnuranContDist)
00024
00025 TUnuranContDist::TUnuranContDist (const ROOT::Math::IGenFunction & pdf, const ROOT::Math::IGenFunction * deriv, bool isLogPdf, bool copyFunc ) :
00026 fPdf(&pdf),
00027 fDPdf(deriv),
00028 fCdf(0),
00029 fXmin(1.),
00030 fXmax(-1.),
00031 fMode(0),
00032 fArea(0),
00033 fIsLogPdf(isLogPdf),
00034 fHasDomain(0),
00035 fHasMode(0),
00036 fHasArea(0),
00037 fOwnFunc(copyFunc)
00038 {
00039
00040
00041 if (fOwnFunc) {
00042 fPdf = fPdf->Clone();
00043 if (fDPdf) fDPdf->Clone();
00044 }
00045 }
00046
00047
00048 TUnuranContDist::TUnuranContDist (TF1 * pdf, TF1 * deriv, bool isLogPdf ) :
00049 fPdf( (pdf) ? new ROOT::Math::WrappedTF1 ( *pdf) : 0 ),
00050 fDPdf( (deriv) ? new ROOT::Math::WrappedTF1 ( *deriv) : 0 ),
00051 fCdf(0),
00052 fXmin(1.),
00053 fXmax(-1.),
00054 fMode(0),
00055 fArea(0),
00056 fIsLogPdf(isLogPdf),
00057 fHasDomain(0),
00058 fHasMode(0),
00059 fHasArea(0),
00060 fOwnFunc(true)
00061 {
00062
00063
00064 }
00065
00066
00067 TUnuranContDist::TUnuranContDist(const TUnuranContDist & rhs) :
00068 TUnuranBaseDist(),
00069 fPdf(0),
00070 fDPdf(0),
00071 fCdf(0)
00072 {
00073
00074 operator=(rhs);
00075 }
00076
00077 TUnuranContDist & TUnuranContDist::operator = (const TUnuranContDist &rhs)
00078 {
00079
00080 if (this == &rhs) return *this;
00081 fXmin = rhs.fXmin;
00082 fXmax = rhs.fXmax;
00083 fMode = rhs.fMode;
00084 fArea = rhs.fArea;
00085 fIsLogPdf = rhs.fIsLogPdf;
00086 fHasDomain = rhs.fHasDomain;
00087 fHasMode = rhs.fHasMode;
00088 fHasArea = rhs.fHasArea;
00089 fOwnFunc = rhs.fOwnFunc;
00090 if (!fOwnFunc) {
00091 fPdf = rhs.fPdf;
00092 fDPdf = rhs.fDPdf;
00093 fCdf = rhs.fCdf;
00094 }
00095 else {
00096 if (fPdf) delete fPdf;
00097 if (fDPdf) delete fDPdf;
00098 if (fCdf) delete fCdf;
00099 fPdf = (rhs.fPdf) ? rhs.fPdf->Clone() : 0;
00100 fDPdf = (rhs.fDPdf) ? rhs.fDPdf->Clone() : 0;
00101 fCdf = (rhs.fCdf) ? rhs.fCdf->Clone() : 0;
00102 }
00103
00104 return *this;
00105 }
00106
00107 TUnuranContDist::~TUnuranContDist() {
00108
00109 if (fOwnFunc) {
00110 if (fPdf) delete fPdf;
00111 if (fDPdf) delete fDPdf;
00112 if (fCdf) delete fCdf;
00113 }
00114 }
00115
00116 void TUnuranContDist::SetCdf(const ROOT::Math::IGenFunction & cdf) {
00117
00118 fCdf = (fOwnFunc) ? cdf.Clone() : &cdf;
00119 }
00120
00121
00122 void TUnuranContDist::SetCdf(TF1 * cdf) {
00123
00124 if (!fOwnFunc) {
00125
00126 assert (fPdf != 0);
00127 fPdf = fPdf->Clone();
00128 if (fDPdf) fDPdf->Clone();
00129 }
00130 else
00131 if (fOwnFunc && fCdf) delete fCdf;
00132
00133 fCdf = (cdf) ? new ROOT::Math::WrappedTF1 ( *cdf) : 0;
00134 fOwnFunc = true;
00135 }
00136
00137 double TUnuranContDist::Pdf ( double x) const {
00138
00139 assert(fPdf != 0);
00140
00141 return (*fPdf)(x);
00142 }
00143
00144 double TUnuranContDist::DPdf( double x) const {
00145
00146
00147 if (fDPdf != 0) {
00148
00149 return (*fDPdf)(x);
00150 }
00151
00152 ROOT::Math::RichardsonDerivator rd;
00153 static double gEps = 0.001;
00154 double h = ( std::abs(x) > 0 ) ? gEps * std::abs(x) : gEps;
00155 assert (fPdf != 0);
00156 return rd.Derivative1( *fPdf, x, h);
00157 }
00158
00159 double TUnuranContDist::Cdf(double x) const {
00160
00161 if (fCdf != 0) {
00162
00163 return (*fCdf)(x);
00164 }
00165
00166 ROOT::Math::Integrator ig;
00167 if (fXmin > fXmax) return ig.Integral( *fPdf );
00168 else
00169 return ig.Integral( *fPdf, fXmin, fXmax );
00170
00171 }
00172