CMS 3D CMS Logo

BinomialNoncentralInterval.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_RooStatsCms_BinomialNoncentralinterval_h
2 #define PhysicsTools_RooStatsCms_BinomialNoncentralinterval_h
3 /* \class BinomialNoncentralinterval
4  *
5  * \author Jordan Tucker
6  *
7  * integration in CMSSW: Luca Listta
8  *
9  */
10 
11 #include <algorithm>
12 #include <cmath>
13 #include <vector>
14 
15 #include "Math/PdfFuncMathCore.h"
16 
17 #if (defined(STANDALONE) or defined(__CINT__))
18 #include "BinomialInterval.h"
19 #include "BinomialProbHelper.h"
20 #else
23 #endif
24 
25 // Implement noncentral binomial confidence intervals using the Neyman
26 // construction. The Sorter class gives the ordering of points,
27 // i.e. it must be a functor implementing a greater-than relationship
28 // between two prob_helper instances. See feldman_cousins for an
29 // example.
30 template <typename Sorter>
32 public:
33  // Given a true value of rho and ntot trials, calculate the
34  // acceptance set [x_l, x_r] for use in a Neyman construction.
35  bool find_rho_set(const double rho, const int ntot, int& x_l, int& x_r) const {
36  // Get the binomial probabilities for every x = 0..n, and sort them
37  // in decreasing order, determined by the Sorter class.
38  std::vector<BinomialProbHelper> probs;
39  for (int i = 0; i <= ntot; ++i)
40  probs.push_back(BinomialProbHelper(rho, i, ntot));
41  std::sort(probs.begin(), probs.end(), sorter_);
42 
43  // Add up the probabilities until the total is 1 - alpha or
44  // bigger, adding the biggest point first, then the next biggest,
45  // etc. "Biggest" is given by the Sorter class and is taken care
46  // of by the sort above. JMTBAD need to find equal probs and use
47  // the sorter to differentiate between them.
48  const double target = 1 - alpha_;
49  // An invalid interval.
50  x_l = ntot;
51  x_r = 0;
52  double sum = 0;
53  for (int i = 0; i <= ntot && sum < target; ++i) {
54  sum += probs[i].prob();
55  const int& x = probs[i].x();
56  if (x < x_l)
57  x_l = x;
58  if (x > x_r)
59  x_r = x;
60  }
61 
62  return x_l <= x_r;
63  }
64 
65  // Construct nrho acceptance sets in rho = [0,1] given ntot trials
66  // and put the results in already-allocated x_l and x_r.
67  bool neyman(const int ntot, const int nrho, double* rho, double* x_l, double* x_r) override {
68  int xL, xR;
69  for (int i = 0; i < nrho; ++i) {
70  rho[i] = double(i) / nrho;
71  find_rho_set(rho[i], ntot, xL, xR);
72  x_l[i] = xL;
73  x_r[i] = xR;
74  }
75  return true;
76  }
77 
78  // Given X successes and n trials, calculate the interval using the
79  // rho acceptance sets implemented above.
80  void calculate(const double X, const double n) override {
81  set(0, 1);
82 
83  const double tol = 1e-9;
84  double rho_min, rho_max, rho;
85  int x_l, x_r;
86 
87  // Binary search for the smallest rho whose acceptance set has right
88  // endpoint X; this is the lower endpoint of the rho interval.
89  rho_min = 0;
90  rho_max = 1;
91  while (std::fabs(rho_max - rho_min) > tol) {
92  rho = (rho_min + rho_max) / 2;
93  find_rho_set(rho, int(n), x_l, x_r);
94  if (x_r < X)
95  rho_min = rho;
96  else
97  rho_max = rho;
98  }
99  lower_ = rho;
100 
101  // Binary search for the largest rho whose acceptance set has left
102  // endpoint X; this is the upper endpoint of the rho interval.
103  rho_min = 0;
104  rho_max = 1;
105  while (std::fabs(rho_max - rho_min) > tol) {
106  rho = (rho_min + rho_max) / 2;
107  find_rho_set(rho, int(n), x_l, x_r);
108  if (x_l > X)
109  rho_max = rho;
110  else
111  rho_min = rho;
112  }
113  upper_ = rho;
114  }
115 
116 private:
117  Sorter sorter_;
118 
119 #if (defined(STANDALONE) or defined(__CINT__))
120  ClassDefT(BinomialNoncentralInterval, 1)
121 #endif
122 };
123 
124 #endif
bool find_rho_set(const double rho, const int ntot, int &x_l, int &x_r) const
#define X(str)
Definition: MuonsGrabber.cc:38
void calculate(const double X, const double n) override
bool neyman(const int ntot, const int nrho, double *rho, double *x_l, double *x_r) override