13 #ifndef ROOT_Fit_Fitter 
   14 #define ROOT_Fit_Fitter 
   40       template<
class FunctionType> 
class BasicFitMethodFunction;
 
   43       typedef BasicFitMethodFunction<ROOT::Math::IMultiGenFunction>  FitMethodFunction;
 
   44       typedef BasicFitMethodFunction<ROOT::Math::IMultiGradFunction> FitMethodGradFunction;
 
   81    typedef ROOT::Math::IParamMultiFunction                 IModelFunction;
 
   83    using IModelFunctionTempl =                             ROOT::Math::IParamMultiFunctionTempl<T>;
 
   85    typedef ROOT::Math::IParametricFunctionMultiDimTempl<ROOT::Double_v>  IModelFunction_v;
 
   86    typedef ROOT::Math::IParamMultiGradFunctionTempl<ROOT::Double_v> IGradModelFunction_v;
 
   88    typedef ROOT::Math::IParamMultiFunction                 IModelFunction_v;
 
   89    typedef ROOT::Math::IParamMultiGradFunction IGradModelFunction_v;
 
   91    typedef ROOT::Math::IParamMultiGradFunction             IGradModelFunction;
 
   92    typedef ROOT::Math::IParamFunction                      IModel1DFunction;
 
   93    typedef ROOT::Math::IParamGradFunction                  IGradModel1DFunction;
 
   95    typedef ROOT::Math::IMultiGenFunction BaseFunc;
 
   96    typedef ROOT::Math::IMultiGradFunction BaseGradFunc;
 
  107    Fitter (
const std::shared_ptr<FitResult> & result);
 
  120    Fitter(
const Fitter &);
 
  125    Fitter & operator = (
const Fitter & rhs);
 
  137    template <
class Data, 
class Function,
 
  138              class cond = 
typename std::enable_if<!(std::is_same<Function, ROOT::Fit::ExecutionPolicy>::value ||
 
  139                                                     std::is_same<Function, int>::value),
 
  141    bool Fit(
const Data &data, 
const Function &func,
 
  142             const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial)
 
  145       return Fit(data, executionPolicy);
 
  151    bool Fit(
const BinData & data, 
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial) {
 
  153       return DoLeastSquareFit(executionPolicy);
 
  155    bool Fit(
const std::shared_ptr<BinData> & data, 
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial) {
 
  157       return DoLeastSquareFit(executionPolicy);
 
  163    bool LeastSquareFit(
const BinData & data) {
 
  170    bool Fit(
const UnBinData & data, 
bool extended = 
false, 
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial) {
 
  172       return DoUnbinnedLikelihoodFit(extended, executionPolicy);
 
  178    bool LikelihoodFit(
const BinData &data, 
bool extended = 
true,
 
  179                       const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial) {
 
  181       return DoBinnedLikelihoodFit(extended, executionPolicy);
 
  184    bool LikelihoodFit(
const std::shared_ptr<BinData> &data, 
bool extended = 
true,
 
  185                       const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial) {
 
  187       return DoBinnedLikelihoodFit(extended, executionPolicy);
 
  192    bool LikelihoodFit(
const UnBinData & data, 
bool extended = 
false, 
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial) {
 
  194       return DoUnbinnedLikelihoodFit(extended, executionPolicy);
 
  196    bool LikelihoodFit(
const std::shared_ptr<UnBinData> & data, 
bool extended = 
false, 
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial) {
 
  198       return DoUnbinnedLikelihoodFit(extended, executionPolicy);
 
  206    template < 
class Data , 
class Function>
 
  207    bool LikelihoodFit( 
const Data & data, 
const Function & func, 
bool extended) {
 
  209       return LikelihoodFit(data, extended);
 
  215    bool LinearFit(
const BinData & data) {
 
  217       return DoLinearFit();
 
  219    bool LinearFit(
const std::shared_ptr<BinData> & data) {
 
  221       return DoLinearFit();
 
  231    template <
class Function>
 
  232    bool FitFCN(
unsigned int npar, Function  & fcn, 
const double * params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  240    template <
class Function>
 
  241    bool SetFCN(
unsigned int npar, Function  & fcn, 
const double * params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  255    bool FitFCN(
const ROOT::Math::IMultiGenFunction &fcn, 
const double *params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  261    bool FitFCN(
const ROOT::Math::FitMethodFunction & fcn, 
const double * params = 0);
 
  268    bool SetFCN(
const ROOT::Math::IMultiGenFunction &fcn, 
const double *params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  277    bool SetFCN(
const ROOT::Math::IMultiGenFunction &fcn, 
const IModelFunction & func, 
const double *params = 0,
 
  278                unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  284    bool SetFCN(
const ROOT::Math::FitMethodFunction & fcn, 
const double * params = 0);
 
  292    bool FitFCN(
const ROOT::Math::IMultiGradFunction &fcn, 
const double *params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  298    bool FitFCN(
const ROOT::Math::FitMethodGradFunction & fcn, 
const double * params = 0);
 
  305    bool SetFCN(
const ROOT::Math::IMultiGradFunction &fcn, 
const double *params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  314    bool SetFCN(
const ROOT::Math::IMultiGradFunction &fcn, 
const IModelFunction &func, 
const double *params = 0,
 
  315                unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  321    bool SetFCN(
const ROOT::Math::FitMethodGradFunction & fcn, 
const double * params = 0);
 
  329    typedef  void (* MinuitFCN_t )(
int &npar, 
double *gin, 
double &f, 
double *u, 
int flag);
 
  330    bool FitFCN( MinuitFCN_t fcn, 
int npar = 0, 
const double * params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  337    bool SetFCN( MinuitFCN_t fcn, 
int npar = 0, 
const double * params = 0, 
unsigned int dataSize = 0, 
bool chi2fit = 
false);
 
  354    void  SetFunction(
const IModelFunction & func, 
bool useGradient = 
false);
 
  359 #ifdef R__HAS_VECCORE 
  360    template <class NotCompileIfScalarBackend = std::enable_if<!(std::is_same<double, ROOT::Double_v>::value)>>
 
  361    void SetFunction(
const IModelFunction_v &func, 
bool useGradient = 
false);
 
  363    template <class NotCompileIfScalarBackend = std::enable_if<!(std::is_same<double, ROOT::Double_v>::value)>>
 
  364    void SetFunction(
const IGradModelFunction_v &func, 
bool useGradient = 
true);
 
  369    void  SetFunction(
const IModel1DFunction & func, 
bool useGradient = 
false);
 
  374    void  SetFunction(
const IGradModelFunction & func, 
bool useGradient = 
true);
 
  378    void  SetFunction(
const IGradModel1DFunction & func, 
bool useGradient = 
true);
 
  384    const FitResult & Result()
 const {
 
  385       assert( fResult.get() );
 
  397    bool CalculateHessErrors();
 
  407    bool CalculateMinosErrors();
 
  412    const FitConfig & Config()
 const { 
return fConfig; }
 
  417    FitConfig & Config() { 
return fConfig; }
 
  423    bool IsBinFit()
 const { 
return fBinFit; }
 
  434    ROOT::Math::Minimizer * GetMinimizer()
 const { 
return fMinimizer.get(); }
 
  445    ROOT::Math::IMultiGenFunction * GetFCN()
 const { 
return fObjFunction.get(); }
 
  456    bool ApplyWeightCorrection(
const ROOT::Math::IMultiGenFunction & loglw2, 
bool minimizeW2L=
false);
 
  463    bool DoLeastSquareFit(
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial);
 
  465    bool DoBinnedLikelihoodFit(
bool extended = 
true, 
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial);
 
  467    bool DoUnbinnedLikelihoodFit( 
bool extended = 
false, 
const ROOT::Fit::ExecutionPolicy &executionPolicy = ROOT::Fit::ExecutionPolicy::kSerial);
 
  472    bool DoInitMinimizer();
 
  474    bool DoMinimization(
const BaseFunc & f, 
const ROOT::Math::IMultiGenFunction * chifunc = 0);
 
  476    bool DoMinimization(
const ROOT::Math::IMultiGenFunction * chifunc = 0);
 
  478    void DoUpdateFitConfig();
 
  480    bool DoUpdateMinimizerOptions(
bool canDifferentMinim = 
true);
 
  482    int GetNCallsFromFCN();
 
  485    void SetData(
const FitData & data) {
 
  486       fData = std::shared_ptr<FitData>(
const_cast<FitData*
>(&data),DummyDeleter<FitData>());
 
  490    void SetFunctionAndData(
const IModelFunctionTempl<T> & func, 
const FitData & data) {
 
  492       fFunc = std::shared_ptr<IModelFunctionTempl<T>>(
const_cast<IModelFunctionTempl<T>*
>(&func),DummyDeleter<IModelFunctionTempl<T>>());
 
  496    template <
class Data>
 
  497    void SetData(
const std::shared_ptr<Data> & data) {
 
  498       fData = std::static_pointer_cast<Data>(data);
 
  508    template <
class ObjFuncType>
 
  509    bool GetDataFromFCN();
 
  526    std::shared_ptr<IModelFunction_v> fFunc_v;  
 
  528    std::shared_ptr<IModelFunction> fFunc;  
 
  530    std::shared_ptr<ROOT::Fit::FitResult>  fResult;  
 
  532    std::shared_ptr<ROOT::Math::Minimizer>  fMinimizer;  
 
  534    std::shared_ptr<ROOT::Fit::FitData>  fData;  
 
  536    std::shared_ptr<ROOT::Math::IMultiGenFunction>  fObjFunction;  
 
  543 template <
class ObjFuncType>
 
  544 bool Fitter::GetDataFromFCN()  {
 
  545    ObjFuncType * objfunc = 
dynamic_cast<ObjFuncType*
>(fObjFunction.get() );
 
  547       fFunc = objfunc->ModelFunctionPtr();
 
  548       fData = objfunc->DataPtr();
 
  556 #ifdef R__HAS_VECCORE 
  557 template <
class NotCompileIfScalarBackend>
 
  558 void Fitter::SetFunction(
const IModelFunction_v &func, 
bool useGradient)
 
  560    fUseGradient = useGradient;
 
  562       const IGradModelFunction_v *gradFunc = 
dynamic_cast<const IGradModelFunction_v *
>(&func);
 
  564          SetFunction(*gradFunc, 
true);
 
  567          MATH_WARN_MSG(
"Fitter::SetFunction",
 
  568                        "Requested function does not provide gradient - use it as non-gradient function ");
 
  574    fUseGradient = 
false;
 
  575    fFunc_v = std::shared_ptr<IModelFunction_v>(
dynamic_cast<IModelFunction_v *
>(func.Clone()));
 
  579    fConfig.CreateParamsSettings(*fFunc_v);
 
  583 template <
class NotCompileIfScalarBackend>
 
  584 void Fitter::SetFunction(
const IGradModelFunction_v &func, 
bool useGradient)
 
  586    fUseGradient = useGradient;
 
  589    fFunc_v = std::shared_ptr<IModelFunction_v>(
dynamic_cast<IGradModelFunction_v *
>(func.Clone()));
 
  593    fConfig.CreateParamsSettings(*fFunc_v);
 
  609 template<
class Function>
 
  610 bool ROOT::Fit::Fitter::FitFCN(
unsigned int npar, Function & f, 
const double * par, 
unsigned int datasize,
bool chi2fit) {
 
  611    ROOT::Math::WrappedMultiFunction<Function &> wf(f,npar);
 
  612    return FitFCN(wf,par,datasize,chi2fit);
 
  614 template<
class Function>
 
  615 bool ROOT::Fit::Fitter::SetFCN(
unsigned int npar, Function & f, 
const double * par, 
unsigned int datasize,
bool chi2fit) {
 
  616    ROOT::Math::WrappedMultiFunction<Function &> wf(f,npar);
 
  617    return SetFCN(wf,par,datasize,chi2fit);
 
  623 #endif  // endif __CINT__