00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TUnuranDiscrDist.h"
00014
00015 #include "Math/IFunction.h"
00016 #include "TF1.h"
00017 #include "Math/WrappedTF1.h"
00018
00019
00020 #include <cassert>
00021
00022
00023 TUnuranDiscrDist::TUnuranDiscrDist (const ROOT::Math::IGenFunction & func, bool copyFunc) :
00024 fPmf(&func),
00025 fCdf(0),
00026 fXmin(1),
00027 fXmax(-1),
00028 fMode(0),
00029 fSum(0),
00030 fHasDomain(0),
00031 fHasMode(0),
00032 fHasSum(0),
00033 fOwnFunc(copyFunc)
00034 {
00035
00036 if (fOwnFunc) {
00037 fPmf = fPmf->Clone();
00038
00039 }
00040 }
00041
00042
00043 TUnuranDiscrDist::TUnuranDiscrDist (TF1 * func) :
00044 fPmf( (func) ? new ROOT::Math::WrappedTF1 ( *func) : 0 ),
00045 fCdf(0),
00046 fXmin(1),
00047 fXmax(-1),
00048 fMode(0),
00049 fSum(0),
00050 fHasDomain(0),
00051 fHasMode(0),
00052 fHasSum(0),
00053 fOwnFunc(true)
00054 {
00055
00056 }
00057
00058
00059 TUnuranDiscrDist::TUnuranDiscrDist(const TUnuranDiscrDist & rhs) :
00060 TUnuranBaseDist(),
00061 fPmf(0),
00062 fCdf(0)
00063 {
00064
00065 operator=(rhs);
00066 }
00067
00068 TUnuranDiscrDist & TUnuranDiscrDist::operator = (const TUnuranDiscrDist &rhs)
00069 {
00070
00071 if (this == &rhs) return *this;
00072 fPVec = rhs.fPVec;
00073 fPVecSum = rhs.fPVecSum;
00074 fXmin = rhs.fXmin;
00075 fXmax = rhs.fXmax;
00076 fMode = rhs.fMode;
00077 fSum = rhs.fSum;
00078 fHasDomain = rhs.fHasDomain;
00079 fHasMode = rhs.fHasMode;
00080 fHasSum = rhs.fHasSum;
00081 fOwnFunc = rhs.fOwnFunc;
00082 if (!fOwnFunc) {
00083 fPmf = rhs.fPmf;
00084 fCdf = rhs.fCdf;
00085 }
00086 else {
00087 if (fPmf) delete fPmf;
00088 if (fCdf) delete fCdf;
00089 fPmf = (rhs.fPmf) ? rhs.fPmf->Clone() : 0;
00090 fCdf = (rhs.fCdf) ? rhs.fCdf->Clone() : 0;
00091 }
00092
00093 return *this;
00094 }
00095
00096 TUnuranDiscrDist::~TUnuranDiscrDist() {
00097
00098 if (fOwnFunc) {
00099 if (fPmf) delete fPmf;
00100 if (fCdf) delete fCdf;
00101 }
00102 }
00103
00104 void TUnuranDiscrDist::SetCdf(const ROOT::Math::IGenFunction & cdf) {
00105
00106 fCdf = (fOwnFunc) ? cdf.Clone() : &cdf;
00107 }
00108
00109 void TUnuranDiscrDist::SetCdf(TF1 * cdf) {
00110
00111 if (!fOwnFunc && fPmf) {
00112
00113 fPmf = fPmf->Clone();
00114 }
00115 else
00116 if (fCdf) delete fCdf;
00117
00118 fCdf = (cdf) ? new ROOT::Math::WrappedTF1 ( *cdf) : 0;
00119 fOwnFunc = true;
00120 }
00121
00122 double TUnuranDiscrDist::Pmf ( int x) const {
00123
00124 if (!fPmf) {
00125 if (x < static_cast<int>(fPVec.size()) || x >= static_cast<int>(fPVec.size()) ) return 0;
00126 return fPVec[x];
00127 }
00128 return (*fPmf)(double(x));
00129 }
00130
00131 double TUnuranDiscrDist::Cdf ( int x) const {
00132
00133
00134 if (fHasDomain && x < fXmin) return 0;
00135
00136 if (fCdf) {
00137 return (*fCdf)(double(x));
00138 }
00139
00140
00141 int vsize = fPVecSum.size();
00142 if ( x < vsize )
00143 return fPVecSum[x];
00144
00145
00146 int x0 = ( fHasDomain) ? fXmin : 0;
00147 int i0 = vsize;
00148 int iN = x - x0 + 1;
00149 fPVecSum.resize(iN);
00150 double sum = ( i0 > 0 ) ? fPVecSum.back() : 0;
00151 for (int i = i0; i < iN; ++i) {
00152 sum += Pmf(i + x0);
00153 fPVecSum[i] = sum;
00154 }
00155
00156 return fPVecSum.back();
00157
00158 }
00159
00160
00161
00162
00163