#ifndef ROOT_Fit_Chi2FCN
#define ROOT_Fit_Chi2FCN
#ifndef ROOT_Math_FitMethodFunction
#include "Math/FitMethodFunction.h"
#endif
#ifndef ROOT_Math_IParamFunction
#include "Math/IParamFunction.h"
#endif
#ifndef ROOT_Fit_BinData
#include "Fit/BinData.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>
struct ModelFunctionTrait {
typedef ::ROOT::Math::IParamMultiFunction ModelFunc;
};
template<>
struct ModelFunctionTrait<ROOT::Math::IMultiGradFunction> {
typedef ::ROOT::Math::IParamMultiGradFunction ModelFunc;
};
template<class FunType>
class Chi2FCN : public ::ROOT::Math::BasicFitMethodFunction<FunType> {
public:
typedef ::ROOT::Math::BasicFitMethodFunction<FunType> BaseObjFunction;
typedef typename BaseObjFunction::BaseFunction BaseFunction;
typedef typename ModelFunctionTrait<FunType>::ModelFunc IModelFunction;
typedef typename BaseObjFunction::Type_t Type_t;
Chi2FCN (const BinData & data, const IModelFunction & func) :
BaseObjFunction(func.NPar(), data.Size() ),
fData(data),
fFunc(func),
fNEffPoints(0),
fGrad ( std::vector<double> ( func.NPar() ) )
{ }
virtual ~Chi2FCN () {}
#ifdef LATER
private:
Chi2FCN(const Chi2FCN &);
Chi2FCN & operator = (const Chi2FCN & rhs);
#endif
public:
virtual BaseFunction * Clone() const {
Chi2FCN * fcn = new Chi2FCN(fData,fFunc);
return fcn;
}
using BaseObjFunction::operator();
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::EvaluateChi2Residual(fFunc, fData, x, i, g);
}
virtual void Gradient(const double *x, double *g) const {
FitUtil::EvaluateChi2Gradient(fFunc, fData, x, g, fNEffPoints);
}
virtual typename BaseObjFunction::Type_t Type() const { return BaseObjFunction::kLeastSquare; }
virtual const BinData & Data() const { return fData; }
virtual const IModelFunction & ModelFunction() const { return fFunc; }
protected:
virtual void SetNFitPoints(unsigned int n) const { fNEffPoints = n; }
private:
virtual double DoEval (const double * x) const {
this->UpdateNCalls();
#ifdef ROOT_FIT_PARALLEL
return FitUtilParallel::EvaluateChi2(fFunc, fData, x, fNEffPoints);
#else
if (!fData.HaveCoordErrors() )
return FitUtil::EvaluateChi2(fFunc, fData, x, fNEffPoints);
else
return FitUtil::EvaluateChi2Effective(fFunc, fData, x, fNEffPoints);
#endif
}
virtual double DoDerivative(const double * x, unsigned int icoord ) const {
Gradient(x, &fGrad[0]);
return fGrad[icoord];
}
const BinData & fData;
const IModelFunction & fFunc;
mutable unsigned int fNEffPoints;
mutable std::vector<double> fGrad;
};
typedef Chi2FCN<ROOT::Math::IMultiGenFunction> Chi2Function;
typedef Chi2FCN<ROOT::Math::IMultiGradFunction> Chi2GradFunction;
}
}
#endif /* ROOT_Fit_Chi2FCN */