38 RooPoisson::RooPoisson(
const char *name,
const char *title,
42 RooAbsPdf(name,title),
44 mean(
"mean",
"mean",this,_mean),
45 _noRounding(noRounding),
46 _protectNegative(false)
53 RooPoisson::RooPoisson(
const RooPoisson& other,
const char* name) :
54 RooAbsPdf(other,name),
56 mean(
"mean",this,other.mean),
57 _noRounding(other._noRounding),
58 _protectNegative(other._protectNegative)
65 Double_t RooPoisson::evaluate()
const
67 Double_t k = _noRounding ? x : floor(x);
68 if(_protectNegative && mean<0)
70 return TMath::Poisson(k,mean) ;
77 template<
class Tx,
class TMean>
78 void compute(
const size_t n,
double* __restrict output, Tx x, TMean mean,
79 const bool protectNegative,
const bool noRounding) {
81 for (
size_t i = 0; i < n; ++i) {
82 const double x_i = noRounding ? x[i] : floor(x[i]);
86 output[i] = TMath::LnGamma(x_i + 1.);
90 for (
size_t i = 0; i < n; ++i) {
91 const double x_i = noRounding ? x[i] : floor(x[i]);
92 const double logMean = _rf_fast_log(mean[i]);
93 const double logPoisson = x_i * logMean - mean[i] - output[i];
94 output[i] = _rf_fast_exp(logPoisson);
100 output[i] = 1./_rf_fast_exp(mean[i]);
102 if (protectNegative && mean[i] < 0.)
112 RooSpan<double> RooPoisson::evaluateBatch(std::size_t begin, std::size_t batchSize)
const {
113 using namespace BatchHelpers;
114 auto xData = x.getValBatch(begin, batchSize);
115 auto meanData = mean.getValBatch(begin, batchSize);
116 const bool batchX = !xData.empty();
117 const bool batchMean = !meanData.empty();
119 if (!batchX && !batchMean) {
122 batchSize = findSize({ xData, meanData });
123 auto output = _batchData.makeWritableBatchUnInit(begin, batchSize);
125 if (batchX && !batchMean ) {
126 compute(batchSize, output.data(), xData, BracketAdapter<double>(mean), _protectNegative, _noRounding);
128 else if (!batchX && batchMean ) {
129 compute(batchSize, output.data(), BracketAdapter<double>(x), meanData, _protectNegative, _noRounding);
131 else if (batchX && batchMean ) {
132 compute(batchSize, output.data(), xData, meanData, _protectNegative, _noRounding);
140 Int_t RooPoisson::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* )
const
142 if (matchArgs(allVars,analVars,x))
return 1 ;
143 if (matchArgs(allVars, analVars, mean))
return 2;
149 Double_t RooPoisson::analyticalIntegral(Int_t code,
const char* rangeName)
const
151 R__ASSERT(code == 1 || code == 2) ;
153 if(_protectNegative && mean<0)
159 const double xmin = std::max(0., x.min(rangeName));
160 const double xmax = x.max(rangeName);
162 if (xmax < 0. || xmax < xmin) {
165 if (!x.hasMax() || RooNumber::isInfinite(xmax)) {
171 const unsigned int ixmin = xmin;
172 const unsigned int ixmax = std::min(xmax + 1.,
173 (
double)std::numeric_limits<unsigned int>::max());
177 return ROOT::Math::poisson_cdf(ixmax - 1, mean);
182 return ROOT::Math::poisson_cdf(ixmax - 1, mean) - ROOT::Math::poisson_cdf(ixmin - 1, mean);
186 return ROOT::Math::poisson_cdf_c(ixmin - 1, mean) - ROOT::Math::poisson_cdf_c(ixmax - 1, mean);
191 }
else if(code == 2) {
194 Double_t mean_min = mean.min(rangeName);
195 Double_t mean_max = mean.max(rangeName);
198 if(_noRounding) ix = x + 1;
199 else ix = Int_t(TMath::Floor(x)) + 1.0;
201 return ROOT::Math::gamma_cdf(mean_max, ix, 1.0) - ROOT::Math::gamma_cdf(mean_min, ix, 1.0);
211 Int_t RooPoisson::getGenerator(
const RooArgSet& directVars, RooArgSet &generateVars, Bool_t )
const
213 if (matchArgs(directVars,generateVars,x))
return 1 ;
220 void RooPoisson::generateEvent(Int_t code)
225 xgen = RooRandom::randomGenerator()->Poisson(mean);
226 if (xgen<=x.max() && xgen>=x.min()) {