#ifndef ROOT_Fit_LogLikelihoodFCN
#define ROOT_Fit_LogLikelihoodFCN
#ifndef ROOT_Fit_BasicFCN
#include "Fit/BasicFCN.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
#include <memory>
namespace ROOT {
namespace Fit {
template<class FunType>
class LogLikelihoodFCN : public BasicFCN<FunType,UnBinData> {
public:
typedef BasicFCN<FunType,UnBinData> BaseFCN;
typedef ::ROOT::Math::BasicFitMethodFunction<FunType> BaseObjFunction;
typedef typename BaseObjFunction::BaseFunction BaseFunction;
typedef ::ROOT::Math::IParamMultiFunction IModelFunction;
LogLikelihoodFCN (const std::shared_ptr<UnBinData> & data, const std::shared_ptr<IModelFunction> & func, int weight = 0, bool extended = false) :
BaseFCN( data, func),
fIsExtended(extended),
fWeight(weight),
fNEffPoints(0),
fGrad ( std::vector<double> ( func->NPar() ) )
{}
LogLikelihoodFCN (const UnBinData & data, const IModelFunction & func, int weight = 0, bool extended = false) :
BaseFCN(std::shared_ptr<UnBinData>(const_cast<UnBinData*>(&data), DummyDeleter<UnBinData>()), std::shared_ptr<IModelFunction>(dynamic_cast<IModelFunction*>(func.Clone() ) ) ),
fIsExtended(extended),
fWeight(weight),
fNEffPoints(0),
fGrad ( std::vector<double> ( func.NPar() ) )
{}
virtual ~LogLikelihoodFCN () {}
LogLikelihoodFCN(const LogLikelihoodFCN & f) :
BaseFCN(f.DataPtr(), f.ModelFunctionPtr() ),
fIsExtended(f.fIsExtended ),
fWeight( f.fWeight ),
fNEffPoints( f.fNEffPoints ),
fGrad( f.fGrad)
{ }
LogLikelihoodFCN & operator = (const LogLikelihoodFCN & rhs) {
SetData(rhs.DataPtr() );
SetModelFunction(rhs.ModelFunctionPtr() );
fNEffPoints = rhs.fNEffPoints;
fGrad = rhs.fGrad;
fIsExtended = rhs.fIsExtended;
fWeight = rhs.fWeight;
}
virtual BaseFunction * Clone() const { return new LogLikelihoodFCN(*this); }
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(BaseFCN::ModelFunction(), BaseFCN::Data(), x, i, g);
}
virtual void Gradient(const double *x, double *g) const {
FitUtil::EvaluateLogLGradient(BaseFCN::ModelFunction(), BaseFCN::Data(), x, g, fNEffPoints);
}
virtual typename BaseObjFunction::Type_t Type() const { return BaseObjFunction::kLogLikelihood; }
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(BaseFCN::ModelFunction(), BaseFCN::Data(), x, fNEffPoints);
#else
return FitUtil::EvaluateLogL(BaseFCN::ModelFunction(), BaseFCN::Data(), 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;
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 */