TEfficiencyHelper.h

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: TEfficiencyHelper.h 36767 2010-11-19 10:22:55Z moneta $
00002 // Author: L. Moneta Nov 2010 
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2010  LCG ROOT Math Team, CERN/PH-SFT                *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 // helper class for binomial Neyman intervals
00011 // author Jordan Tucker
00012 //  integration in CMSSW: Luca Lista
00013 //   modified and integrated in ROOT: Lorenzo Moneta
00014 
00015 
00016 #ifndef TEFFiciencyHelper_h
00017 #define TEFFiciencyHelper_h
00018 
00019 #include <algorithm>
00020 #include <cmath>
00021 #include <vector>
00022 
00023 #include "Math/PdfFuncMathCore.h"
00024 
00025 
00026 // Helper class impelementing the
00027 // binomial probability and the likelihood ratio
00028 // used for ordering the interval in the FeldmanCousins interval class 
00029 class BinomialProbHelper {
00030 public:
00031    BinomialProbHelper(double rho, int x, int n)
00032       : fRho(rho), fX(x), fN(n),
00033         fRho_hat(double(x)/n),
00034         fProb(ROOT::Math::binomial_pdf(x, rho, n)) {
00035       // Cache the likelihood ratio L(\rho)/L(\hat{\rho}), too.
00036       if (x == 0)
00037          fLRatio = pow(1 - rho, n);
00038       else if (x == n)
00039          fLRatio = pow(rho, n);
00040       else
00041          fLRatio = pow(rho/fRho_hat, x) * pow((1 - rho)/(1 - fRho_hat), n - x);
00042    }
00043 
00044    double Rho   () const { return fRho;    };
00045    int    X     () const { return fX;      };
00046    int    N     () const { return fN;      };
00047    double Prob  () const { return fProb;   };
00048    double LRatio() const { return fLRatio; };
00049 
00050 private:
00051    double fRho;
00052    int fX;
00053    int fN;
00054    double fRho_hat;
00055    double fProb;
00056    double fLRatio;
00057 };
00058 
00059 
00060 
00061 // Implement noncentral binomial confidence intervals using the Neyman
00062 // construction. The Sorter class gives the ordering of points,
00063 // i.e. it must be a functor implementing a greater-than relationship
00064 // between two prob_helper instances. See feldman_cousins for an
00065 // example.
00066 template <typename Sorter>
00067 class BinomialNeymanInterval  {
00068 public:
00069 
00070    BinomialNeymanInterval() :
00071       fLower(0), 
00072       fUpper(1),
00073       fAlpha(0)
00074    {}
00075 
00076    void Init(double alpha) { 
00077       fAlpha = alpha;
00078    }
00079 
00080    // Given a true value of rho and ntot trials, calculate the
00081    // acceptance set [x_l, x_r] for use in a Neyman construction.
00082    bool Find_rho_set(const double rho, const int ntot, int& x_l, int& x_r) const {
00083       // Get the binomial probabilities for every x = 0..n, and sort them
00084       // in decreasing order, determined by the Sorter class.
00085       std::vector<BinomialProbHelper> probs;
00086       for (int i = 0; i <= ntot; ++i)
00087          probs.push_back(BinomialProbHelper(rho, i, ntot));
00088       std::sort(probs.begin(), probs.end(), fSorter);
00089 
00090       // Add up the probabilities until the total is 1 - alpha or
00091       // bigger, adding the biggest point first, then the next biggest,
00092       // etc. "Biggest" is given by the Sorter class and is taken care
00093       // of by the sort above. JMTBAD need to find equal probs and use
00094       // the sorter to differentiate between them.
00095       const double target = 1 - fAlpha;
00096       // An invalid interval.
00097       x_l = ntot;
00098       x_r = 0;
00099       double sum = 0;
00100       for (int i = 0; i <= ntot && sum < target; ++i) {
00101          sum += probs[i].Prob();
00102          const int& x = probs[i].X();
00103          if (x < x_l) x_l = x;
00104          if (x > x_r) x_r = x;
00105       }
00106   
00107       return x_l <= x_r;
00108    }
00109 
00110    // Construct nrho acceptance sets in rho = [0,1] given ntot trials
00111    // and put the results in already-allocated x_l and x_r.
00112    bool Neyman(const int ntot, const int nrho, double* rho, double* x_l, double* x_r) {
00113       int xL, xR;
00114       for (int i = 0; i < nrho; ++i) {
00115          rho[i] = double(i)/nrho;
00116          Find_rho_set(rho[i], ntot, xL, xR);
00117          x_l[i] = xL;
00118          x_r[i] = xR;
00119       }
00120       return true;
00121    }
00122 
00123    // Given X successes and n trials, calculate the interval using the
00124    // rho acceptance sets implemented above.
00125    void Calculate(const double X, const double n) {
00126       Set(0, 1);
00127 
00128       const double tol = 1e-9;
00129       double rho_min, rho_max, rho;
00130       int x_l, x_r;
00131   
00132       // Binary search for the smallest rho whose acceptance set has right
00133       // endpoint X; this is the lower endpoint of the rho interval.
00134       rho_min = 0; rho_max = 1;
00135       while (std::abs(rho_max - rho_min) > tol) {
00136          rho = (rho_min + rho_max)/2;
00137          Find_rho_set(rho, int(n), x_l, x_r);
00138          if (x_r < X)
00139             rho_min = rho;
00140          else
00141             rho_max = rho;
00142       }
00143       fLower = rho;
00144   
00145       // Binary search for the largest rho whose acceptance set has left
00146       // endpoint X; this is the upper endpoint of the rho interval.
00147       rho_min = 0; rho_max = 1;
00148       while (std::abs(rho_max - rho_min) > tol) {
00149          rho = (rho_min + rho_max)/2;
00150          Find_rho_set(rho, int(n), x_l, x_r);
00151          if (x_l > X)
00152             rho_max = rho;
00153          else
00154             rho_min = rho;
00155       }
00156       fUpper = rho;
00157    }
00158 
00159    double Lower() const { return fLower; }
00160    double Upper() const { return fUpper; }
00161 
00162 private:
00163    Sorter fSorter;
00164 
00165    double fLower;
00166    double fUpper;
00167 
00168    double    fAlpha;
00169 
00170    void Set(double l, double u) { fLower = l; fUpper = u; }
00171 
00172 };
00173 
00174 
00175 
00176 
00177 struct FeldmanCousinsSorter {
00178    bool operator()(const BinomialProbHelper& l, const BinomialProbHelper& r) const {
00179       return l.LRatio() > r.LRatio();
00180    }
00181 };
00182 
00183 class FeldmanCousinsBinomialInterval : public BinomialNeymanInterval<FeldmanCousinsSorter> {
00184    //const char* name() const { return "Feldman-Cousins"; }
00185 
00186 };
00187 
00188 
00189 
00190 
00191 #endif

Generated on Tue Jul 5 14:24:16 2011 for ROOT_528-00b_version by  doxygen 1.5.1