Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:31:26

0001 // @(#)root/mathcore:$Id$
0002 // Author: L. Moneta Wed Aug 30 11:05:19 2006
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // Header file for class Fitter
0012 
0013 #ifndef ROOT_Fit_Fitter
0014 #define ROOT_Fit_Fitter
0015 
0016 /**
0017 @defgroup Fit Fitting and Parameter Estimation
0018 
0019 Classes used for fitting (regression analysis) and estimation of parameter values given a data sample.
0020 
0021 @ingroup MathCore
0022 
0023 @see ROOT::Math::MinimizerOptions::SetDefaultMinimizer
0024 
0025 */
0026 
0027 #include "Fit/BinData.h"
0028 #include "Fit/UnBinData.h"
0029 #include "Fit/FitConfig.h"
0030 #include "ROOT/EExecutionPolicy.hxx"
0031 #include "Fit/FitResult.h"
0032 #include "Math/IParamFunction.h"
0033 #include <memory>
0034 
0035 namespace ROOT {
0036 
0037 
0038    namespace Math {
0039       class Minimizer;
0040 
0041       // should maybe put this in a FitMethodFunctionfwd file
0042       template<class FunctionType> class BasicFitMethodFunction;
0043 
0044       // define the normal and gradient function
0045       typedef BasicFitMethodFunction<ROOT::Math::IMultiGenFunction>  FitMethodFunction;
0046       typedef BasicFitMethodFunction<ROOT::Math::IMultiGradFunction> FitMethodGradFunction;
0047 
0048    }
0049 
0050    /**
0051       Namespace for the fitting classes
0052       @ingroup Fit
0053     */
0054 
0055    namespace Fit {
0056 
0057 /**
0058    @defgroup FitMain User Fitting classes
0059 
0060    Main Classes used for fitting a given data set
0061    @ingroup Fit
0062 */
0063 
0064 
0065 //___________________________________________________________________________________
0066 /**
0067    Fitter class, entry point for performing all type of fits.
0068    Fits are performed using the generic ROOT::Fit::Fitter::Fit method.
0069    The inputs are the data points and a model function (using a ROOT::Math::IParamFunction)
0070    The result of the fit is returned and kept internally in the  ROOT::Fit::FitResult class.
0071    The configuration of the fit (parameters, options, etc...) are specified in the
0072    ROOT::Math::FitConfig class.
0073    After fitting the config of the fit will be modified to have the new values the resulting
0074    parameter of the fit with step sizes equal to the errors. FitConfig can be preserved with
0075    initial parameters by calling FitConfig.SetUpdateAfterFit(false);
0076 
0077    @ingroup FitMain
0078 */
0079 class Fitter {
0080 
0081 public:
0082 
0083    typedef ROOT::Math::IParamMultiFunction                 IModelFunction;
0084    template <class T>
0085    using IModelFunctionTempl =                             ROOT::Math::IParamMultiFunctionTempl<T>;
0086 #ifdef R__HAS_VECCORE
0087    typedef ROOT::Math::IParametricFunctionMultiDimTempl<ROOT::Double_v>  IModelFunction_v;
0088    typedef ROOT::Math::IParamMultiGradFunctionTempl<ROOT::Double_v> IGradModelFunction_v;
0089 #else
0090    typedef ROOT::Math::IParamMultiFunction                 IModelFunction_v;
0091    typedef ROOT::Math::IParamMultiGradFunction IGradModelFunction_v;
0092 #endif
0093    typedef ROOT::Math::IParamMultiGradFunction             IGradModelFunction;
0094    typedef ROOT::Math::IParamFunction                      IModel1DFunction;
0095    typedef ROOT::Math::IParamGradFunction                  IGradModel1DFunction;
0096 
0097    typedef ROOT::Math::IMultiGenFunction BaseFunc;
0098    typedef ROOT::Math::IMultiGradFunction BaseGradFunc;
0099 
0100 
0101    /**
0102       Default constructor
0103    */
0104    Fitter () {}
0105 
0106    /**
0107       Constructor from a result
0108    */
0109    Fitter (const std::shared_ptr<FitResult> & result);
0110 
0111 
0112    /**
0113       Destructor.
0114       Make it virtual in case users derive from Fitter class to extend it by adding new methods.
0115       This is needed to avoid a warning seen when doing from Python
0116       (see ROOT issue [#12391](https://github.com/root-project/root/issues/12391) ).
0117       Note that the Fitter class does not provide virtual functions to be re-implemented by derived classes.
0118    */
0119    virtual ~Fitter () {}
0120 
0121    /**
0122       Copy constructor (disabled, class is not copyable)
0123    */
0124    Fitter(const Fitter &) = delete;
0125 
0126    /**
0127       Assignment operator (disabled, class is not copyable)
0128    */
0129    Fitter & operator = (const Fitter &) = delete;
0130 
0131 
0132 public:
0133 
0134    /**
0135        fit a data set using any  generic model  function
0136        If data set is binned a least square fit is performed
0137        If data set is unbinned a maximum likelihood fit (not extended) is done
0138        Pre-requisite on the function:
0139        it must implement the 1D or multidimensional parametric function interface.
0140        Note that both the input data and the function object are copied by the Fitter.
0141    */
0142    template <class Data, class Function,
0143              class cond = typename std::enable_if<!(std::is_same<Function, ROOT::EExecutionPolicy>::value ||
0144                                                     std::is_same<Function, int>::value),
0145                                                   Function>::type>
0146    bool Fit(const Data &data, const Function &func,
0147             const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential)
0148    {
0149       SetFunction(func);
0150       return Fit(data, executionPolicy);
0151    }
0152 
0153    /**
0154       Fit a binned data set using a least square fit.
0155       Note that the provided input data are copied in the Fitter class.
0156       Use the next function (passing a `shared_ptr` to the BinData class if you want to avoid
0157       copying.
0158    */
0159    bool Fit(const BinData & data, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0160       return LeastSquareFit(data, executionPolicy);
0161    }
0162 
0163    /**
0164       Fit a binned data set using a least square fit.
0165       Pass the input data using a `shared_ptr` for NOT copying the input data.
0166    */
0167    bool Fit(const std::shared_ptr<BinData> & data, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0168       return LeastSquareFit(data, executionPolicy);
0169    }
0170 
0171    /**
0172        Fit a binned data set using a least square fit copying the input data.
0173    */
0174    bool LeastSquareFit(const BinData & data, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0175       SetData(data);
0176       return DoLeastSquareFit(executionPolicy);
0177    }
0178    /**
0179        Fit a binned data set using a least square fit NOT copying the input data.
0180    */
0181    bool LeastSquareFit(const std::shared_ptr<BinData> & data, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0182       SetData(data);
0183       return DoLeastSquareFit(executionPolicy);
0184    }
0185 
0186    /**
0187        Fit an un-binned data set using the negative log-likelihood method.
0188        This function copies the input data.
0189    */
0190    bool Fit(const UnBinData & data, bool extended = false, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0191       return LikelihoodFit(data, extended, executionPolicy);
0192    }
0193    /**
0194        Fit an un-binned data set using the negative log-likelihood method.
0195        This function uses a `shared_ptr` to avoid copying the input data.
0196    */
0197    bool Fit(const std::shared_ptr<UnBinData> & data, bool extended = false, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0198       return LikelihoodFit(data, extended, executionPolicy);
0199    }
0200 
0201    /**
0202       Binned Likelihood fit copying the input data.
0203       Default is extended.
0204     */
0205    bool LikelihoodFit(const BinData &data, bool extended = true,
0206                       const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0207       SetData(data);
0208       return DoBinnedLikelihoodFit(extended, executionPolicy);
0209    }
0210    /**
0211       Binned Likelihood fit using a `shared_ptr` for NOT copying the input data.
0212       Default is extended.
0213     */
0214    bool LikelihoodFit(const std::shared_ptr<BinData> &data, bool extended = true,
0215                       const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0216       SetData(data);
0217       return DoBinnedLikelihoodFit(extended, executionPolicy);
0218    }
0219    /**
0220       Un-binned Likelihood fit copying the input data
0221       Default is NOT extended
0222     */
0223    bool LikelihoodFit(const UnBinData & data, bool extended = false, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0224       SetData(data);
0225       return DoUnbinnedLikelihoodFit(extended, executionPolicy);
0226    }
0227    /**
0228       Un-binned Likelihood fit using a `shared_ptr` for NOT copying the input data.
0229       Default is NOT extended
0230     */
0231    bool LikelihoodFit(const std::shared_ptr<UnBinData> & data, bool extended = false, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential) {
0232       SetData(data);
0233       return DoUnbinnedLikelihoodFit(extended, executionPolicy);
0234    }
0235 
0236    /**
0237       Likelihood fit given a data set (Binned or Un-binned) using any  generic model  function.
0238       This interface copies the input data and the model function object
0239    */
0240    template < class Data , class Function>
0241    bool LikelihoodFit( const Data & data, const Function & func, bool extended) {
0242       SetFunction(func);
0243       return LikelihoodFit(data, extended);
0244    }
0245 
0246    /**
0247       Do a linear fit copying the input data
0248     */
0249    bool LinearFit(const BinData & data) {
0250       SetData(data);
0251       return DoLinearFit();
0252    }
0253    /**
0254       Do a linear fit using a `shared_ptr` for NOT copying the input data
0255     */
0256    bool LinearFit(const std::shared_ptr<BinData> & data) {
0257       SetData(data);
0258       return DoLinearFit();
0259    }
0260 
0261    /**
0262       Fit using the a generic FCN function as a C++ callable object implementing
0263       double () (const double *)
0264       Note that the function dimension (i.e. the number of parameter) is needed in this case
0265       For the options see documentation for following methods FitFCN(IMultiGenFunction & fcn,..)
0266     */
0267    template <class Function>
0268    bool FitFCN(unsigned int npar, Function  & fcn, const double * params = nullptr, unsigned int dataSize = 0, int fitType = 0);
0269 
0270    /**
0271       Set a generic FCN function as a C++ callable object implementing
0272       double () (const double *)
0273       Note that the function dimension (i.e. the number of parameter) is needed in this case
0274       For the options see documentation for following methods FitFCN(IMultiGenFunction & fcn,..)
0275     */
0276    template <class Function>
0277    bool SetFCN(unsigned int npar, Function  & fcn, const double * params = nullptr, unsigned int dataSize = 0, int fitType = 0);
0278 
0279    /**
0280       Fit using the given FCN function represented by a multi-dimensional function interface
0281       (ROOT::Math::IMultiGenFunction).
0282       Give optionally the initial parameter values, data size to have the fit Ndf correctly
0283       set in the FitResult and flag specifying the type of fit. The fitType can be:
0284       0 undefined, 1 least square fit, 2 unbinned likelihood fit, 3 binned likelihood fit
0285       Note that if the parameters values are not given (params=0) the
0286       current parameter settings are used. The parameter settings can be created before
0287       by using the FitConfig::SetParamsSetting. If they have not been created they are created
0288       automatically when the params pointer is not zero.
0289       Note that passing a params != 0 will set the parameter settings to the new value AND also the
0290       step sizes to some pre-defined value (stepsize = 0.3 * abs(parameter_value) )
0291     */
0292    bool FitFCN(const ROOT::Math::IMultiGenFunction &fcn, const double *params = nullptr, unsigned int dataSize = 0, int fitType = 0);
0293 
0294    /**
0295        Fit using a FitMethodFunction interface. Same as method above, but now extra information
0296        can be taken from the function class
0297    */
0298    bool FitFCN(const ROOT::Math::FitMethodFunction & fcn, const double *params = nullptr);
0299 
0300    /**
0301       Set the FCN function represented by a multi-dimensional function interface
0302       (ROOT::Math::IMultiGenFunction) and optionally the initial parameters
0303       See also note above for the initial parameters for FitFCN
0304     */
0305    bool SetFCN(const ROOT::Math::IMultiGenFunction &fcn, const double *params = nullptr, unsigned int dataSize = 0, int fitType = 0);
0306 
0307    /**
0308       Set the FCN function represented by a multi-dimensional function interface
0309      (ROOT::Math::IMultiGenFunction) and optionally the initial parameters
0310       See also note above for the initial parameters for FitFCN
0311       With this interface we pass in addition a ModelFunction that will be attached to the FitResult and
0312       used to compute confidence interval of the fit
0313    */
0314    bool SetFCN(const ROOT::Math::IMultiGenFunction &fcn, const IModelFunction & func, const double *params = nullptr,
0315                unsigned int dataSize = 0, int fitType = 0);
0316 
0317    /**
0318        Set the objective function (FCN)  using a FitMethodFunction interface.
0319        Same as method above, but now extra information can be taken from the function class
0320    */
0321    bool SetFCN(const ROOT::Math::FitMethodFunction & fcn, const double *params = nullptr);
0322 
0323    /**
0324        Fit using a FitMethodGradFunction interface. Same as method above, but now extra information
0325        can be taken from the function class
0326    */
0327    bool FitFCN(const ROOT::Math::FitMethodGradFunction & fcn, const double *params = nullptr);
0328 
0329    /**
0330        Set the objective function (FCN)  using a FitMethodGradFunction interface.
0331        Same as method above, but now extra information can be taken from the function class
0332    */
0333    bool SetFCN(const ROOT::Math::FitMethodGradFunction & fcn, const double *params = nullptr);
0334 
0335 
0336    /**
0337       fit using user provided FCN with Minuit-like interface
0338       If npar = 0 it is assumed that the parameters are specified in the parameter settings created before
0339       For the options same consideration as in the previous method
0340     */
0341    typedef  void (* MinuitFCN_t )(int &npar, double *gin, double &f, double *u, int flag);
0342    bool FitFCN( MinuitFCN_t fcn, int npar = 0, const double *params = nullptr, unsigned int dataSize = 0, int fitType = 0);
0343 
0344    /**
0345       set objective function using user provided FCN with Minuit-like interface
0346       If npar = 0 it is assumed that the parameters are specified in the parameter settings created before
0347       For the options same consideration as in the previous method
0348     */
0349    bool SetFCN( MinuitFCN_t fcn, int npar = 0, const double *params = nullptr, unsigned int dataSize = 0, int fitType = 0);
0350 
0351    /**
0352       Perform a fit with the previously set FCN function. Require SetFCN before
0353     */
0354    bool FitFCN();
0355 
0356    /**
0357       Perform a simple FCN evaluation. FitResult will be modified and contain  the value of the FCN
0358     */
0359    bool EvalFCN();
0360 
0361 
0362 
0363    /**
0364        Set the fitted function (model function) from a parametric function interface.
0365        @param useGradient if true, the minimizer uses the gradient information provided by the user, otherwise a numerical gradient is computed and used.
0366    */
0367    void  SetFunction(const IModelFunction & func, bool useGradient = false);
0368 
0369    /**
0370        Set the fitted function (model function) from a vectorized parametric function interface
0371    */
0372 #ifdef R__HAS_VECCORE
0373    template <class NotCompileIfScalarBackend = std::enable_if<!(std::is_same<double, ROOT::Double_v>::value)>>
0374    void SetFunction(const IModelFunction_v &func, bool useGradient = false);
0375 
0376    template <class NotCompileIfScalarBackend = std::enable_if<!(std::is_same<double, ROOT::Double_v>::value)>>
0377    void SetFunction(const IGradModelFunction_v &func, bool useGradient = true);
0378 #endif
0379    /**
0380       Set the fitted function from a parametric 1D function interface
0381     */
0382    void  SetFunction(const IModel1DFunction & func, bool useGradient = false);
0383 
0384    /**
0385        Set the fitted function (model function) from a parametric gradient function interface
0386    */
0387    void  SetFunction(const IGradModelFunction & func, bool useGradient = true);
0388    /**
0389       Set the fitted function from 1D gradient parametric function interface
0390     */
0391    void  SetFunction(const IGradModel1DFunction & func, bool useGradient = true);
0392 
0393 
0394    /**
0395       get fit result
0396    */
0397    const FitResult & Result() const {
0398       assert( fResult.get() );
0399       return *fResult;
0400    }
0401 
0402 
0403    /**
0404       perform an error analysis on the result using the Hessian
0405       Errors are obtained from the inverse of the Hessian matrix
0406       To be called only after fitting and when a minimizer supporting the Hessian calculations is used
0407       otherwise an error (false) is returned.
0408       A new  FitResult with the Hessian result will be produced
0409     */
0410    bool CalculateHessErrors();
0411 
0412    /**
0413       perform an error analysis on the result using MINOS
0414       To be called only after fitting and when a minimizer supporting MINOS is used
0415       otherwise an error (false) is returned.
0416       The result will be appended in the fit result class
0417       Optionally a vector of parameter indices can be passed for selecting
0418       the parameters to analyse using FitConfig::SetMinosErrors
0419     */
0420    bool CalculateMinosErrors();
0421 
0422    /**
0423       access to the fit configuration (const method)
0424    */
0425    const FitConfig & Config() const { return fConfig; }
0426 
0427    /**
0428       access to the configuration (non const method)
0429    */
0430    FitConfig & Config() { return fConfig; }
0431 
0432    /**
0433       query if fit is binned. In cse of false the fit can be unbinned
0434       or is not defined (like in case of fitting through a ROOT::Fit::Fitter::FitFCN)
0435     */
0436    bool IsBinFit() const { return fBinFit; }
0437 
0438    /**
0439       return pointer to last used minimizer
0440       (is NULL in case fit is not yet done)
0441       This pointer is guaranteed to be valid as far as the fitter class is valid and a new fit is not redone.
0442       To be used only after fitting.
0443       The pointer should not be stored and will be invalided after performing a new fitting.
0444       In this case a new instance of ROOT::Math::Minimizer will be re-created and can be
0445       obtained calling again GetMinimizer()
0446     */
0447    ROOT::Math::Minimizer * GetMinimizer() const { return fMinimizer.get(); }
0448 
0449    /**
0450       return pointer to last used objective function
0451       (is NULL in case fit is not yet done)
0452       This pointer will be valid as far as the fitter class
0453       has not been deleted. To be used after the fitting.
0454       The pointer should not be stored and will be invalided after performing a new fitting.
0455       In this case a new instance of the function pointer will be re-created and can be
0456       obtained calling again GetFCN()
0457     */
0458    ROOT::Math::IMultiGenFunction * GetFCN() const {
0459       return fObjFunction.get();
0460     }
0461 
0462 
0463    /**
0464       apply correction in the error matrix for the weights for likelihood fits
0465       This method can be called only after a fit. The
0466       passed function (loglw2) is a log-likelihood function implemented using the
0467       sum of weight squared
0468       When using FitConfig.SetWeightCorrection() this correction is applied
0469       automatically when doing a likelihood fit (binned or unbinned)
0470    */
0471    bool ApplyWeightCorrection(const ROOT::Math::IMultiGenFunction & loglw2, bool minimizeW2L=false);
0472 
0473    /// Set number of fit points when using an external FCN function
0474    /// This function can be called after Fit to set the correct number of Ndf in FitResult
0475    void SetNumberOfFitPoints(unsigned int npoints) {
0476       if (fExtObjFunction) fDataSize = npoints;
0477       if (!fResult->IsEmpty()) fResult->SetChi2AndNdf(-1,npoints);
0478    }
0479 
0480    /// Set the type of fit when using an external FCN
0481    /// possible types are : 1 (least-square), 2 (unbinned-likelihood), 3 (binned-likelihood)
0482    /// Note that in case of binned likelihood fit the chi2 will be computed as 2 * MinFCN()
0483    /// Note this function should be called before fitting to have effect on th FitResult
0484    void SetFitType(int type) {
0485       if (fExtObjFunction) fFitType = type;
0486    }
0487 
0488 
0489 protected:
0490 
0491 
0492    /// least square fit
0493    bool DoLeastSquareFit(const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential);
0494    /// binned likelihood fit
0495    bool DoBinnedLikelihoodFit(bool extended = true, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential);
0496    /// un-binned likelihood fit
0497    bool DoUnbinnedLikelihoodFit( bool extended = false, const ROOT::EExecutionPolicy &executionPolicy = ROOT::EExecutionPolicy::kSequential);
0498    /// linear least square fit
0499    bool DoLinearFit();
0500    /// Set Objective function
0501    bool DoSetFCN(bool useExtFCN, const ROOT::Math::IMultiGenFunction &fcn, const double *params, unsigned int dataSize,
0502                  int fitType);
0503 
0504    // initialize the minimizer
0505    bool DoInitMinimizer();
0506    /// do minimization
0507    template<class ObjFunc_t>
0508    bool DoMinimization(std::unique_ptr<ObjFunc_t> f, const ROOT::Math::IMultiGenFunction * chifunc = nullptr);
0509    // do minimization for weighted likelihood fits
0510    template<class ObjFunc_t>
0511    bool DoWeightMinimization(std::unique_ptr<ObjFunc_t> f, const ROOT::Math::IMultiGenFunction * chifunc = nullptr);
0512    // do minimization after having set the objective function
0513    bool DoMinimization(const ROOT::Math::IMultiGenFunction * chifunc = nullptr);
0514    // update config after fit
0515    void DoUpdateFitConfig();
0516    // update minimizer options for re-fitting
0517    bool DoUpdateMinimizerOptions(bool canDifferentMinim = true);
0518    // get function calls from the FCN
0519    int GetNCallsFromFCN();
0520 
0521    /// Set the input data for the fit using a shared ptr (No Copying)
0522    template <class Data>
0523    void SetData(const std::shared_ptr<Data> & data) {
0524       fData = std::static_pointer_cast<Data>(data);
0525    }
0526 
0527    /// Set the input data for the fit (Copying the given data object)
0528    template <class Data>
0529    void SetData(const Data & data) {
0530       auto dataClone = std::make_shared<Data>(data);
0531       SetData(dataClone);
0532    }
0533 
0534    /// look at the user provided FCN and get data and model function is
0535    /// they derive from ROOT::Fit FCN classes
0536    void ExamineFCN();
0537 
0538 
0539    /// internal functions to get data set and model function from FCN
0540    /// useful for fits done with customized FCN classes
0541    template <class ObjFuncType>
0542    bool GetDataFromFCN();
0543 
0544    /// Return pointer to the used objective function for fitting.
0545    /// If using an external function (e.g. given in SetFCN), return the cached pointer,
0546    /// otherwise use the one stored as shared ptr and managed by the Fitter class
0547    const ROOT::Math::IBaseFunctionMultiDimTempl<double> * ObjFunction() const {
0548       // need to specify here full return type since when using the typedef (IMultiGenFunction)
0549       // there is an error when using the class in Python (see issue #12391)
0550       return (fExtObjFunction) ? fExtObjFunction : fObjFunction.get();
0551    }
0552 
0553 private:
0554 
0555    bool fUseGradient = false;  ///< flag to indicate if using gradient or not
0556 
0557    bool fBinFit = false;    ///< flag to indicate if fit is binned
0558                             ///< in case of false the fit is unbinned or undefined)
0559                             ///< flag it is used to compute chi2 for binned likelihood fit
0560 
0561    int fFitType = 0;   ///< type of fit   (0 undefined, 1 least square, 2 likelihood, 3 binned likelihood)
0562 
0563    int fDataSize = 0;  ///< size of data sets (need for Fumili or LM fitters)
0564 
0565    FitConfig fConfig;       ///< fitter configuration (options and parameter settings)
0566 
0567    std::shared_ptr<IModelFunction_v> fFunc_v;  ///<! copy of the fitted  function containing on output the fit result
0568 
0569    std::shared_ptr<IModelFunction> fFunc;  ///<! copy of the fitted  function containing on output the fit result
0570 
0571    std::shared_ptr<ROOT::Fit::FitResult>  fResult;  ///<! pointer to the object containing the result of the fit
0572 
0573    std::shared_ptr<ROOT::Math::Minimizer>  fMinimizer;  ///<! pointer to used minimizer
0574 
0575    std::shared_ptr<ROOT::Fit::FitData>  fData;  ///<! pointer to the fit data (binned or unbinned data)
0576 
0577    std::shared_ptr<ROOT::Math::IMultiGenFunction>  fObjFunction;  ///<! pointer to used objective function
0578 
0579    const ROOT::Math::IMultiGenFunction * fExtObjFunction = nullptr;     ///<! pointer to an external FCN
0580 
0581 };
0582 
0583 
0584 // internal functions to get data set and model function from FCN
0585 // useful for fits done with customized FCN classes
0586 template <class ObjFuncType>
0587 bool Fitter::GetDataFromFCN()  {
0588    const ObjFuncType * objfunc = dynamic_cast<const ObjFuncType*>(ObjFunction());
0589    if (objfunc) {
0590       fFunc = objfunc->ModelFunctionPtr();
0591       fData = objfunc->DataPtr();
0592       return true;
0593    }
0594    else {
0595       return false;
0596    }
0597 }
0598 
0599 #ifdef R__HAS_VECCORE
0600 template <class NotCompileIfScalarBackend>
0601 void Fitter::SetFunction(const IModelFunction_v &func, bool useGradient)
0602 {
0603    fUseGradient = useGradient;
0604    if (fUseGradient) {
0605       const IGradModelFunction_v *gradFunc = dynamic_cast<const IGradModelFunction_v *>(&func);
0606       if (gradFunc) {
0607          SetFunction(*gradFunc, true);
0608          return;
0609       } else {
0610          MATH_WARN_MSG("Fitter::SetFunction",
0611                        "Requested function does not provide gradient - use it as non-gradient function ");
0612       }
0613    }
0614 
0615    //  set the fit model function (clone the given one and keep a copy )
0616    //  std::cout << "set a non-grad function" << std::endl;
0617    fUseGradient = false;
0618    fFunc_v = std::shared_ptr<IModelFunction_v>(dynamic_cast<IModelFunction_v *>(func.Clone()));
0619    assert(fFunc_v);
0620 
0621    // creates the parameter  settings
0622    fConfig.CreateParamsSettings(*fFunc_v);
0623    fFunc.reset();
0624 }
0625 
0626 template <class NotCompileIfScalarBackend>
0627 void Fitter::SetFunction(const IGradModelFunction_v &func, bool useGradient)
0628 {
0629    fUseGradient = useGradient;
0630 
0631    //  set the fit model function (clone the given one and keep a copy )
0632    fFunc_v = std::shared_ptr<IModelFunction_v>(dynamic_cast<IGradModelFunction_v *>(func.Clone()));
0633    assert(fFunc_v);
0634 
0635    // creates the parameter  settings
0636    fConfig.CreateParamsSettings(*fFunc_v);
0637    fFunc.reset();
0638 }
0639 #endif
0640 
0641    } // end namespace Fit
0642 
0643 } // end namespace ROOT
0644 
0645 // implementation of inline methods
0646 
0647 
0648 
0649 #include "Math/WrappedFunction.h"
0650 
0651 template<class Function>
0652 bool ROOT::Fit::Fitter::FitFCN(unsigned int npar, Function & f, const double * par, unsigned int datasize,int fitType) {
0653    ROOT::Math::WrappedMultiFunction<Function &> wf(f,npar);
0654    if (!DoSetFCN(false, wf, par, datasize, fitType))
0655       return false;
0656    return FitFCN();
0657 }
0658 template<class Function>
0659 bool ROOT::Fit::Fitter::SetFCN(unsigned int npar, Function & f, const double * par, unsigned int datasize,int fitType) {
0660    ROOT::Math::WrappedMultiFunction<Function &> wf(f,npar);
0661    return DoSetFCN(false, wf, par, datasize, fitType);
0662 }
0663 
0664 
0665 
0666 
0667 #endif /* ROOT_Fit_Fitter */