CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/PhysicsTools/Utilities/interface/Likelihood.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_Utilities_Likelihood_h
00002 #define PhysicsTools_Utilities_Likelihood_h
00003 #include "PhysicsTools/Utilities/interface/RootMinuitResultPrinter.h"
00004 #include "PhysicsTools/Utilities/interface/RootMinuitFuncEvaluator.h"
00005 #include <cmath>
00006 #include "TMath.h"
00007 
00008 namespace fit {
00009   template<typename PDF, typename Tuple>
00010   struct LikelihoodEvaluator {
00011     static double evaluate(const PDF & pdf, const Tuple & tuple) {
00012       return pdf(tuple);
00013     }
00014   };
00015 
00016   // to be generalized for tuples in N variables
00017   template<typename PDF>
00018   struct LikelihoodEvaluator<PDF, double> {
00019     static double evaluate(const PDF & pdf, const double val) {
00020       return pdf(val);
00021     }    
00022   };
00023 
00024   struct NoExtendedLikelihood { };
00025 
00026   template<typename Sample, typename PDF, typename Yield = NoExtendedLikelihood>
00027   class Likelihood {
00028   public:
00029     Likelihood() { }
00030     Likelihood(const Sample & sample, PDF & pdf, Yield & yield) : 
00031       pdf_(& pdf), yield_(&yield), sample_(sample) { 
00032     }
00033     double operator()() const { return log(); }
00034     double log() const {
00035       double l = - (*yield_)();
00036       for(typename Sample::const_iterator i = sample_.begin(); i != sample_.end(); ++i) {
00037         double p = Evaluator::evaluate(*pdf_, *i);
00038         l += std::log(p);
00039       }
00040       sampleSize_ = sample_.size();
00041       return l;
00042     }
00043     double logNFactorial() const {
00044       return std::log(TMath::Factorial(sampleSize_));
00045     }
00046     double absoluteLog() const {
00047       return log() - logNFactorial();
00048     }
00049     PDF & pdf() { return * pdf_; }
00050     const PDF & pdf() const { return * pdf_; }
00051     Yield & yield() { return * yield_; }
00052     const Yield & yield() const { return * yield_; }
00053     unsigned int sampleSize() const { return sampleSize_; }
00054   private:
00055     typedef LikelihoodEvaluator<PDF, typename Sample::value_type> Evaluator;
00056     PDF * pdf_;
00057     Yield * yield_;
00058     Sample sample_;
00059     mutable unsigned int sampleSize_;
00060   };
00061 
00062   template<typename Sample, typename PDF>
00063   class Likelihood<Sample, PDF, NoExtendedLikelihood> {
00064   public:
00065     Likelihood() { }
00066     Likelihood(const Sample & sample, PDF & pdf) : 
00067       pdf_(& pdf), sample_(sample) { 
00068     }
00069     double operator()() const { return log(); }
00070     double log() const {
00071       double l = 0;
00072       for(typename Sample::const_iterator i = sample_.begin(); i != sample_.end(); ++i) {
00073         l += std::log(Evaluator::evaluate(*pdf_, *i));
00074       }
00075       return l;
00076     }
00077     PDF & pdf() { return * pdf_; }
00078     const PDF & pdf() const { return * pdf_; }
00079   private:
00080     typedef LikelihoodEvaluator<PDF, typename Sample::value_type> Evaluator;
00081     PDF * pdf_;
00082     Sample sample_;
00083   };
00084 
00085   template<typename Sample, typename PDF, typename Yield>
00086   struct RootMinuitResultPrinter<Likelihood<Sample, PDF, Yield> > {
00087     static void print(double amin, unsigned int numberOfFreeParameters, const Likelihood<Sample, PDF, Yield> & f) {
00088       std::cout << "-2 log(maximum-likelihood) = " << amin << ", free parameters = " << numberOfFreeParameters
00089                 << std::endl;      
00090     }
00091   };
00092 
00093   template<typename Sample, typename PDF, typename Yield>
00094   struct RootMinuitFuncEvaluator<Likelihood<Sample, PDF, Yield> > {
00095     static double evaluate(const Likelihood<Sample, PDF, Yield> & f) {
00096       return - 2 * f();
00097     }
00098   };
00099 
00100 }
00101 
00102 #endif