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
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