Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-14 09:28:31

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