#ifndef ROOT_Fit_LogLikelihoodFCN
#define ROOT_Fit_LogLikelihoodFCN
#ifndef ROOT_Math_FitMethodFunction
#include "Math/FitMethodFunction.h"
#endif
#ifndef ROOT_Math_IParamFunction
#include "Math/IParamFunction.h"
#endif
#ifndef ROOT_Fit_UnBinData
#include "Fit/UnBinData.h"
#endif
#ifndef ROOT_Fit_FitUtil
#include "Fit/FitUtil.h"
#endif
#ifdef ROOT_FIT_PARALLEL
#ifndef ROOT_Fit_FitUtilParallel
#include "Fit/FitUtilParallel.h"
#endif
#endif
namespace ROOT {
namespace Fit {
template<class FunType>
class LogLikelihoodFCN : public ::ROOT::Math::BasicFitMethodFunction<FunType> {
public:
typedef ::ROOT::Math::BasicFitMethodFunction<FunType> BaseObjFunction;
typedef typename BaseObjFunction::BaseFunction BaseFunction;
typedef ::ROOT::Math::IParamMultiFunction IModelFunction;
LogLikelihoodFCN (const UnBinData & data, const IModelFunction & func, int weight = 0, bool extended = false) :
BaseObjFunction(func.NPar(), data.Size() ),
fIsExtended(extended),
fWeight(weight),
fData(data),
fFunc(func),
fNEffPoints(0),
fGrad ( std::vector<double> ( func.NPar() ) )
{}
virtual ~LogLikelihoodFCN () {}
private:
LogLikelihoodFCN(const LogLikelihoodFCN &);
LogLikelihoodFCN & operator = (const LogLikelihoodFCN &);
public:
virtual BaseFunction * Clone() const { return new LogLikelihoodFCN(fData,fFunc,fWeight,fIsExtended); }
virtual unsigned int NFitPoints() const { return fNEffPoints; }
virtual double DataElement(const double * x, unsigned int i, double * g) const {
if (i==0) this->UpdateNCalls();
return FitUtil::EvaluatePdf(fFunc, fData, x, i, g);
}
virtual void Gradient(const double *x, double *g) const {
FitUtil::EvaluateLogLGradient(fFunc, fData, x, g, fNEffPoints);
}
virtual typename BaseObjFunction::Type_t Type() const { return BaseObjFunction::kLogLikelihood; }
virtual const UnBinData & Data() const { return fData; }
virtual const IModelFunction & ModelFunction() const { return fFunc; }
void UseSumOfWeightSquare(bool on = true) {
if (fWeight == 0) return;
if (on) fWeight = 2;
else fWeight = 1;
}
protected:
private:
virtual double DoEval (const double * x) const {
this->UpdateNCalls();
#ifdef ROOT_FIT_PARALLEL
return FitUtilParallel::EvaluateLogL(fFunc, fData, x, fNEffPoints);
#else
return FitUtil::EvaluateLogL(fFunc, fData, x, fWeight, fIsExtended, fNEffPoints);
#endif
}
virtual double DoDerivative(const double * x, unsigned int icoord ) const {
Gradient(x, &fGrad[0]);
return fGrad[icoord];
}
bool fIsExtended;
int fWeight;
const UnBinData & fData;
const IModelFunction & fFunc;
mutable unsigned int fNEffPoints;
mutable std::vector<double> fGrad;
};
typedef LogLikelihoodFCN<ROOT::Math::IMultiGenFunction> LogLikelihoodFunction;
typedef LogLikelihoodFCN<ROOT::Math::IMultiGradFunction> LogLikelihoodGradFunction;
}
}
#endif /* ROOT_Fit_LogLikelihoodFCN */