ROOT  6.06/09
Reference Guide
RooPoisson.cxx
Go to the documentation of this file.
1  /*****************************************************************************
2  * Project: RooFit *
3  * *
4  * Simple Poisson PDF
5  * author: Kyle Cranmer <cranmer@cern.ch>
6  * *
7  *****************************************************************************/
8 
9 //////////////////////////////////////////////////////////////////////////////
10 //
11 // BEGIN_HTML
12 // Poisson pdf
13 // END_HTML
14 //
15 
16 #include <iostream>
17 
18 #include "RooPoisson.h"
19 #include "RooAbsReal.h"
20 #include "RooAbsCategory.h"
21 
22 #include "RooRandom.h"
23 #include "RooMath.h"
24 #include "TMath.h"
25 #include "Math/ProbFuncMathCore.h"
26 
27 #include "TError.h"
28 
29 using namespace std;
30 
32 
33 
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 /// Constructor
37 
38 RooPoisson::RooPoisson(const char *name, const char *title,
39  RooAbsReal& _x,
40  RooAbsReal& _mean,
41  Bool_t noRounding) :
42  RooAbsPdf(name,title),
43  x("x","x",this,_x),
44  mean("mean","mean",this,_mean),
45  _noRounding(noRounding),
46  _protectNegative(false)
47 {
48 }
49 
50 
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Copy constructor
54 
55  RooPoisson::RooPoisson(const RooPoisson& other, const char* name) :
56  RooAbsPdf(other,name),
57  x("x",this,other.x),
58  mean("mean",this,other.mean),
59  _noRounding(other._noRounding),
60  _protectNegative(other._protectNegative)
61 {
62 }
63 
64 
65 
66 
67 ////////////////////////////////////////////////////////////////////////////////
68 /// Implementation in terms of the TMath Poisson function
69 
71 {
72  Double_t k = _noRounding ? x : floor(x);
73  if(_protectNegative && mean<0)
74  return 1e-3;
75  return TMath::Poisson(k,mean) ;
76 }
77 
78 
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// calculate and return the negative log-likelihood of the Poisson
82 
84 {
85  return RooAbsPdf::getLogVal(s) ;
86 // Double_t prob = getVal(s) ;
87 // return prob ;
88 
89  // Make inputs to naming conventions of RooAbsPdf::extendedTerm
90  Double_t expected=mean ;
91  Double_t observed=x ;
92 
93  // Explicitly handle case Nobs=Nexp=0
94  if (fabs(expected)<1e-10 && fabs(observed)<1e-10) {
95  return 0 ;
96  }
97 
98  // Explicitly handle case Nexp=0
99  if (fabs(observed)<1e-10) {
100  return -1*expected;
101  }
102 
103  // Michaels code for log(poisson) in RooAbsPdf::extendedTer with an approximated log(observed!) term
104  Double_t extra=0;
105  if(observed<1000000) {
106  extra = -observed*log(expected)+expected+TMath::LnGamma(observed+1.);
107  } else {
108  //if many observed events, use Gauss approximation
109  Double_t sigma_square=expected;
110  Double_t diff=observed-expected;
111  extra=-log(sigma_square)/2 + (diff*diff)/(2*sigma_square);
112  }
113 
114 // if (fabs(extra)>100 || log(prob)>100) {
115 // cout << "RooPoisson::getLogVal(" << GetName() << ") mu=" << expected << " x = " << x << " -log(P) = " << extra << " log(evaluate()) = " << log(prob) << endl ;
116 // }
117 
118 // if (fabs(extra+log(prob))>1) {
119 // cout << "RooPoisson::getLogVal(" << GetName() << ") WARNING mu=" << expected << " x = " << x << " -log(P) = " << extra << " log(evaluate()) = " << log(prob) << endl ;
120 // }
121 
122  //return log(prob);
123  return -extra-analyticalIntegral(1,0) ; //log(prob);
124 
125 }
126 
127 
128 ////////////////////////////////////////////////////////////////////////////////
129 
130 Int_t RooPoisson::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /*rangeName*/) const
131 {
132  if (matchArgs(allVars,analVars,x)) return 1 ;
133  if (matchArgs(allVars, analVars, mean)) return 2;
134  return 0 ;
135 }
136 
137 
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 
141 Double_t RooPoisson::analyticalIntegral(Int_t code, const char* rangeName) const
142 {
143  R__ASSERT(code == 1 || code == 2) ;
144 
145  if(_protectNegative && mean<0)
146  return exp(-2*mean); // make it fall quickly
147 
148  if (code == 1) {
149  // Implement integral over x as summation. Add special handling in case
150  // range boundaries are not on integer values of x
151  Double_t xmin = x.min(rangeName) ;
152  Double_t xmax = x.max(rangeName) ;
153 
154  // Protect against negative lower boundaries
155  if (xmin<0) xmin=0 ;
156 
157  Int_t ixmin = Int_t (xmin) ;
158  Int_t ixmax = Int_t (xmax)+1 ;
159 
160  Double_t fracLoBin = 1-(xmin-ixmin) ;
161  Double_t fracHiBin = 1-(ixmax-xmax) ;
162 
163  if (!x.hasMax()) {
164  if (xmin<1e-6) {
165  return 1 ;
166  } else {
167 
168  // Return 1 minus integral from 0 to x.min()
169 
170  if(ixmin == 0){ // first bin
171  return TMath::Poisson(0, mean)*(xmin-0);
172  }
173  Double_t sum(0) ;
174  sum += TMath::Poisson(0,mean)*fracLoBin ;
176  sum += TMath::Poisson(ixmin-1,mean)*fracHiBin ;
177  return 1-sum ;
178  }
179  }
180 
181  if(ixmin == ixmax-1){ // first bin
182  return TMath::Poisson(ixmin, mean)*(xmax-xmin);
183  }
184 
185  Double_t sum(0) ;
186  sum += TMath::Poisson(ixmin,mean)*fracLoBin ;
187  if (RooNumber::isInfinite(xmax)){
188  sum+= 1.-ROOT::Math::poisson_cdf(ixmin,mean) ;
189  } else {
190  sum+= ROOT::Math::poisson_cdf(ixmax-2, mean) - ROOT::Math::poisson_cdf(ixmin,mean) ;
191  sum += TMath::Poisson(ixmax-1,mean)*fracHiBin ;
192  }
193 
194  return sum ;
195 
196  } else if(code == 2) {
197 
198  // the integral with respect to the mean is the integral of a gamma distribution
199  Double_t mean_min = mean.min(rangeName);
200  Double_t mean_max = mean.max(rangeName);
201 
202  Double_t ix;
203  if(_noRounding) ix = x + 1;
204  else ix = Int_t(TMath::Floor(x)) + 1.0; // negative ix does not need protection (gamma returns 0.0)
205 
206  return ROOT::Math::gamma_cdf(mean_max, ix, 1.0) - ROOT::Math::gamma_cdf(mean_min, ix, 1.0);
207  }
208 
209  return 0;
210 
211 }
212 
213 
214 
215 
216 
217 
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Advertise internal generator in x
221 
222 Int_t RooPoisson::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t /*staticInitOK*/) const
223 {
224  if (matchArgs(directVars,generateVars,x)) return 1 ;
225  return 0 ;
226 }
227 
228 
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Implement internal generator using TRandom::Poisson
232 
234 {
235  R__ASSERT(code==1) ;
236  Double_t xgen ;
237  while(1) {
239  if (xgen<=x.max() && xgen>=x.min()) {
240  x = xgen ;
241  break;
242  }
243  }
244  return;
245 }
246 
247 
float xmin
Definition: THbookFile.cxx:93
Double_t Floor(Double_t x)
Definition: TMath.h:473
RooRealProxy x
Definition: RooPoisson.h:40
Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral. ...
Definition: RooPoisson.cxx:141
Bool_t _noRounding
Definition: RooPoisson.h:42
void generateEvent(Int_t code)
Implement internal generator using TRandom::Poisson.
Definition: RooPoisson.cxx:233
#define R__ASSERT(e)
Definition: TError.h:98
RooRealProxy mean
Definition: RooPoisson.h:41
double poisson_cdf(unsigned int n, double mu)
Cumulative distribution function of the Poisson distribution Lower tail of the integral of the poisso...
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
static Int_t isInfinite(Double_t x)
Return true if x is infinite by RooNumBer internal specification.
Definition: RooNumber.cxx:57
STL namespace.
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
Definition: TIterator.cxx:20
Double_t x[n]
Definition: legend1.C:17
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition: RooRandom.cxx:53
virtual Double_t getLogVal(const RooArgSet *set=0) const
Return the log of the current value with given normalization An error message is printed if the argum...
Definition: RooAbsPdf.cxx:606
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
ClassImp(RooPoisson) RooPoisson
Constructor.
Definition: RooPoisson.cxx:31
Double_t evaluate() const
Implementation in terms of the TMath Poisson function.
Definition: RooPoisson.cxx:70
double floor(double)
float xmax
Definition: THbookFile.cxx:93
Bool_t hasMax(const char *rname=0) const
Definition: RooRealProxy.h:59
Double_t Poisson(Double_t x, Double_t par)
compute the Poisson distribution function for (x,par) The Poisson PDF is implemented by means of Eule...
Definition: TMath.cxx:564
double Double_t
Definition: RtypesCore.h:55
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
#define name(a, b)
Definition: linkTestLib0.cpp:5
Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, Bool_t staticInitOK=kTRUE) const
Advertise internal generator in x.
Definition: RooPoisson.cxx:222
double gamma_cdf(double x, double alpha, double theta, double x0=0)
Cumulative distribution function of the gamma distribution (lower tail).
Bool_t _protectNegative
Definition: RooPoisson.h:43
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
Double_t min(const char *rname=0) const
Definition: RooRealProxy.h:56
Double_t LnGamma(Double_t z)
Computation of ln[gamma(z)] for all z.
Definition: TMath.cxx:490
Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=0) const
Interface function getAnalyticalIntergral advertises the analytical integrals that are supported...
Definition: RooPoisson.cxx:130
Bool_t matchArgs(const RooArgSet &allDeps, RooArgSet &numDeps, const RooArgProxy &a) const
Utility function for use in getAnalyticalIntegral().
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:362
double exp(double)
Double_t getLogVal(const RooArgSet *set=0) const
calculate and return the negative log-likelihood of the Poisson
Definition: RooPoisson.cxx:83
Double_t max(const char *rname=0) const
Definition: RooRealProxy.h:57
double log(double)