CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/PhysicsTools/RooStatsCms/interface/BinomialNoncentralInterval.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_RooStatsCms_BinomialNoncentralinterval_h
00002 #define PhysicsTools_RooStatsCms_BinomialNoncentralinterval_h
00003 /* \class BinomialNoncentralinterval
00004  *
00005  * \author Jordan Tucker
00006  *
00007  * integration in CMSSW: Luca Listta
00008  *
00009  */
00010 
00011 #include <algorithm>
00012 #include <cmath>
00013 #include <vector>
00014 
00015 #include "Math/PdfFuncMathCore.h"
00016 
00017 #if (defined (STANDALONE) or defined (__CINT__) )
00018 #include "BinomialInterval.h"
00019 #include "BinomialProbHelper.h"
00020 #else
00021 #include "PhysicsTools/RooStatsCms/interface/BinomialInterval.h"
00022 #include "PhysicsTools/RooStatsCms/interface/BinomialProbHelper.h"
00023 #endif
00024 
00025 // Implement noncentral binomial confidence intervals using the Neyman
00026 // construction. The Sorter class gives the ordering of points,
00027 // i.e. it must be a functor implementing a greater-than relationship
00028 // between two prob_helper instances. See feldman_cousins for an
00029 // example.
00030 template <typename Sorter>
00031 class BinomialNoncentralInterval : public BinomialInterval {
00032  public:
00033   // Given a true value of rho and ntot trials, calculate the
00034   // acceptance set [x_l, x_r] for use in a Neyman construction.
00035   bool find_rho_set(const double rho, const int ntot, int& x_l, int& x_r) const {
00036     // Get the binomial probabilities for every x = 0..n, and sort them
00037     // in decreasing order, determined by the Sorter class.
00038     std::vector<BinomialProbHelper> probs;
00039     for (int i = 0; i <= ntot; ++i)
00040       probs.push_back(BinomialProbHelper(rho, i, ntot));
00041     std::sort(probs.begin(), probs.end(), sorter_);
00042 
00043     // Add up the probabilities until the total is 1 - alpha or
00044     // bigger, adding the biggest point first, then the next biggest,
00045     // etc. "Biggest" is given by the Sorter class and is taken care
00046     // of by the sort above. JMTBAD need to find equal probs and use
00047     // the sorter to differentiate between them.
00048     const double target = 1 - alpha_;
00049     // An invalid interval.
00050     x_l = ntot;
00051     x_r = 0;
00052     double sum = 0;
00053     for (int i = 0; i <= ntot && sum < target; ++i) {
00054       sum += probs[i].prob();
00055       const int& x = probs[i].x();
00056       if (x < x_l) x_l = x;
00057       if (x > x_r) x_r = x;
00058     }
00059   
00060     return x_l <= x_r;
00061   }
00062 
00063   // Construct nrho acceptance sets in rho = [0,1] given ntot trials
00064   // and put the results in already-allocated x_l and x_r.
00065   bool neyman(const int ntot, const int nrho, double* rho, double* x_l, double* x_r) {
00066     int xL, xR;
00067     for (int i = 0; i < nrho; ++i) {
00068       rho[i] = double(i)/nrho;
00069       find_rho_set(rho[i], ntot, xL, xR);
00070       x_l[i] = xL;
00071       x_r[i] = xR;
00072     }
00073     return true;
00074   }
00075 
00076   // Given X successes and n trials, calculate the interval using the
00077   // rho acceptance sets implemented above.
00078   void calculate(const double X, const double n) {
00079     set(0, 1);
00080 
00081     const double tol = 1e-9;
00082     double rho_min, rho_max, rho;
00083     int x_l, x_r;
00084   
00085     // Binary search for the smallest rho whose acceptance set has right
00086     // endpoint X; this is the lower endpoint of the rho interval.
00087     rho_min = 0; rho_max = 1;
00088     while (std::fabs(rho_max - rho_min) > tol) {
00089       rho = (rho_min + rho_max)/2;
00090       find_rho_set(rho, int(n), x_l, x_r);
00091       if (x_r < X)
00092         rho_min = rho;
00093       else
00094         rho_max = rho;
00095     }
00096     lower_ = rho;
00097   
00098     // Binary search for the largest rho whose acceptance set has left
00099     // endpoint X; this is the upper endpoint of the rho interval.
00100     rho_min = 0; rho_max = 1;
00101     while (std::fabs(rho_max - rho_min) > tol) {
00102       rho = (rho_min + rho_max)/2;
00103       find_rho_set(rho, int(n), x_l, x_r);
00104       if (x_l > X)
00105         rho_max = rho;
00106       else
00107         rho_min = rho;
00108     }
00109     upper_ = rho;
00110   }
00111 
00112  private:
00113   Sorter sorter_;
00114 
00115 #if (defined (STANDALONE) or defined (__CINT__) )
00116 ClassDefT(BinomialNoncentralInterval,1)
00117 #endif
00118 };
00119 
00120 #endif