Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-27 08:58:58

0001 // @(#)root/minuit2:$Id$
0002 // Author: L. Moneta    10/2006
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006 ROOT Foundation,  CERN/PH-SFT                   *
0007  *                                                                    *
0008  **********************************************************************/
0009 
0010 #ifndef ROOT_Minuit2_FCNGradAdapter
0011 #define ROOT_Minuit2_FCNGradAdapter
0012 
0013 #include "Minuit2/FCNBase.h"
0014 #include "Minuit2/MnPrint.h"
0015 
0016 #include <vector>
0017 #include <functional>
0018 
0019 namespace ROOT {
0020 
0021 namespace Minuit2 {
0022 
0023 /**
0024 
0025 
0026 template wrapped class for adapting to FCNBase signature a IGradFunction
0027 
0028 @author Lorenzo Moneta
0029 
0030 @ingroup Minuit
0031 
0032 */
0033 
0034 template <class Function>
0035 class FCNGradAdapter : public FCNBase {
0036 
0037 public:
0038    FCNGradAdapter(const Function &f, double up = 1.) : fFunc(f), fUp(up), fGrad(std::vector<double>(fFunc.NDim())) {}
0039 
0040    bool HasGradient() const override { return true; }
0041 
0042    double operator()(std::vector<double> const& v) const override { return fFunc.operator()(&v[0]); }
0043    double operator()(const double *v) const { return fFunc.operator()(v); }
0044 
0045    double Up() const override { return fUp; }
0046 
0047    std::vector<double> Gradient(std::vector<double> const& v) const override
0048    {
0049       fFunc.Gradient(&v[0], &fGrad[0]);
0050       return fGrad;
0051    }
0052    std::vector<double> GradientWithPrevResult(std::vector<double> const& v, double *previous_grad, double *previous_g2,
0053                                               double *previous_gstep) const override
0054    {
0055       fFunc.GradientWithPrevResult(&v[0], &fGrad[0], previous_grad, previous_g2, previous_gstep);
0056       return fGrad;
0057    }
0058 
0059    GradientParameterSpace gradParameterSpace() const override {
0060       if (fFunc.returnsInMinuit2ParameterSpace()) {
0061          return GradientParameterSpace::Internal;
0062       } else {
0063          return GradientParameterSpace::External;
0064       }
0065    }
0066 
0067    /// return second derivatives (diagonal of the Hessian matrix)
0068    std::vector<double> G2(std::vector<double> const&  x) const override {
0069       if (fG2Func)
0070          return fG2Func(x);
0071       if (fHessianFunc) {
0072          unsigned int n = fFunc.NDim();
0073          if (fG2Vec.empty() ) fG2Vec.resize(n);
0074          if (fHessian.empty() ) fHessian.resize(n*n);
0075          fHessianFunc(x,fHessian.data());
0076          if (!fHessian.empty()) {
0077             // get diagonal element of h
0078             for (unsigned int i = 0; i < n; i++)
0079                fG2Vec[i] = fHessian[i*n+i];
0080          }
0081          else fG2Vec.clear();
0082       }
0083       else
0084          if (!fG2Vec.empty()) fG2Vec.clear();
0085       return fG2Vec;
0086    }
0087 
0088    /// compute Hessian. Return Hessian as a std::vector of size(n*n)
0089    std::vector<double> Hessian(std::vector<double> const&  x ) const override {
0090       unsigned int n = fFunc.NDim();
0091       if (fHessianFunc) {
0092          if (fHessian.empty() ) fHessian.resize(n * n);
0093          bool ret = fHessianFunc(x,fHessian.data());
0094          if (!ret) {
0095             fHessian.clear();
0096             fHessianFunc = nullptr;
0097          }
0098       } else {
0099          fHessian.clear();
0100       }
0101 
0102       return fHessian;
0103    }
0104 
0105    bool HasG2() const override {
0106       return bool(fG2Func);
0107    }
0108    bool HasHessian() const override {
0109       return bool(fHessianFunc);
0110    }
0111 
0112    template<class Func>
0113    void SetG2Function(Func f) { fG2Func = f;}
0114 
0115    template<class Func>
0116    void SetHessianFunction(Func f) { fHessianFunc = f;}
0117 
0118    void SetErrorDef(double up) override { fUp = up; }
0119 
0120 private:
0121    const Function &fFunc;
0122    double fUp;
0123    mutable std::vector<double> fGrad;
0124    mutable std::vector<double> fHessian;
0125    mutable std::vector<double> fG2Vec;
0126 
0127    std::function<std::vector<double>(std::vector<double> const& )> fG2Func;
0128    mutable std::function<bool(std::vector<double> const& , double *)> fHessianFunc;
0129 };
0130 
0131 } // end namespace Minuit2
0132 
0133 } // end namespace ROOT
0134 
0135 #endif // ROOT_Minuit2_FCNGradAdapter