diff --git a/math/mathcore/inc/Fit/Chi2FCN.h b/math/mathcore/inc/Fit/Chi2FCN.h index 7e01871b1920b..defd65df68af8 100644 --- a/math/mathcore/inc/Fit/Chi2FCN.h +++ b/math/mathcore/inc/Fit/Chi2FCN.h @@ -120,7 +120,7 @@ class Chi2FCN : public BasicFCN { } // need to be virtual to be instantiated - virtual void Gradient(const double *x, double *g) const { + void Gradient(const double *x, double *g) const override { // evaluate the chi2 gradient FitUtil::Evaluate::EvalChi2Gradient(BaseFCN::ModelFunction(), BaseFCN::Data(), x, g, fNEffPoints, fExecutionPolicy); @@ -150,7 +150,7 @@ class Chi2FCN : public BasicFCN { } // for derivatives - virtual double DoDerivative(const double * x, unsigned int icoord) const { + double DoDerivative(const double * x, unsigned int icoord) const override { Gradient(x, fGrad.data()); return fGrad[icoord]; } diff --git a/math/mathcore/inc/Fit/LogLikelihoodFCN.h b/math/mathcore/inc/Fit/LogLikelihoodFCN.h index 5211ef3095126..27e1b6d7b3b6b 100644 --- a/math/mathcore/inc/Fit/LogLikelihoodFCN.h +++ b/math/mathcore/inc/Fit/LogLikelihoodFCN.h @@ -124,7 +124,7 @@ class LogLikelihoodFCN : public BasicFCN { } // need to be virtual to be instantiated - virtual void Gradient(const double *x, double *g) const { + void Gradient(const double *x, double *g) const override { // evaluate the chi2 gradient FitUtil::Evaluate::EvalLogLGradient(BaseFCN::ModelFunction(), BaseFCN::Data(), x, g, fNEffPoints, fExecutionPolicy); @@ -158,7 +158,7 @@ class LogLikelihoodFCN : public BasicFCN { } // for derivatives - virtual double DoDerivative(const double * x, unsigned int icoord) const { + double DoDerivative(const double * x, unsigned int icoord) const override { Gradient(x, &fGrad[0]); return fGrad[icoord]; } diff --git a/math/mathcore/inc/Fit/PoissonLikelihoodFCN.h b/math/mathcore/inc/Fit/PoissonLikelihoodFCN.h index 2708015c4acdb..651bbac3f7f9e 100644 --- a/math/mathcore/inc/Fit/PoissonLikelihoodFCN.h +++ b/math/mathcore/inc/Fit/PoissonLikelihoodFCN.h @@ -124,7 +124,7 @@ class PoissonLikelihoodFCN : public BasicFCN } /// evaluate gradient - virtual void Gradient(const double *x, double *g) const + void Gradient(const double *x, double *g) const override { // evaluate the Poisson gradient FitUtil::Evaluate::EvalPoissonLogLGradient(BaseFCN::ModelFunction(), BaseFCN::Data(), x, g, @@ -192,7 +192,7 @@ class PoissonLikelihoodFCN : public BasicFCN } // for derivatives - virtual double DoDerivative(const double * x, unsigned int icoord) const { + double DoDerivative(const double * x, unsigned int icoord) const override { Gradient(x, &fGrad[0]); return fGrad[icoord]; } diff --git a/math/mathcore/inc/Math/IFunction.h b/math/mathcore/inc/Math/IFunction.h index 39ac759435d0d..ad7b65c24e655 100644 --- a/math/mathcore/inc/Math/IFunction.h +++ b/math/mathcore/inc/Math/IFunction.h @@ -91,10 +91,66 @@ namespace ROOT { // if it inherits from ROOT::Math::IGradientFunctionMultiDim. virtual bool HasGradient() const { return false; } - private: + virtual bool returnsInMinuit2ParameterSpace() const { return false; } + + /// Evaluate all the vector of function derivatives (gradient) at a point x. + /// Derived classes must re-implement it if more efficient than evaluating one at a time + virtual void Gradient(const T *x, T *grad) const + { + unsigned int ndim = NDim(); + for (unsigned int icoord = 0; icoord < ndim; ++icoord) { + grad[icoord] = Derivative(x, icoord); + } + } + + /// In some cases, the gradient algorithm will use information from the previous step, these can be passed + /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size + /// so that these can be passed forward again as well at the call site, if necessary. + virtual void GradientWithPrevResult(const T *x, T *grad, T *previous_grad, T *previous_g2, T *previous_gstep) const + { + unsigned int ndim = NDim(); + for (unsigned int icoord = 0; icoord < ndim; ++icoord) { + grad[icoord] = Derivative(x, icoord, previous_grad, previous_g2, previous_gstep); + } + } + + /// Optimized method to evaluate at the same time the function value and derivative at a point x. + /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. + /// Derived class should implement this method if performances play an important role and if it is faster to + /// evaluate value and derivative at the same time + virtual void FdF(const T *x, T &f, T *df) const + { + f = operator()(x); + Gradient(x, df); + } + + /// Return the partial derivative with respect to the passed coordinate. + T Derivative(const T *x, unsigned int icoord = 0) const { return DoDerivative(x, icoord); } + + /// In some cases, the derivative algorithm will use information from the previous step, these can be passed + /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size + /// so that these can be passed forward again as well at the call site, if necessary. + T Derivative(const T *x, unsigned int icoord, T *previous_grad, T *previous_g2, + T *previous_gstep) const + { + return DoDerivativeWithPrevResult(x, icoord, previous_grad, previous_g2, previous_gstep); + } + private: /// Implementation of the evaluation function. Must be implemented by derived classes. virtual T DoEval(const T *x) const = 0; + + /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. + virtual T DoDerivative(const T * /*x*/, unsigned int /*icoord*/) const { return {}; } + + /// In some cases, the derivative algorithm will use information from the previous step, these can be passed + /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size + /// so that these can be passed forward again as well at the call site, if necessary. + virtual T DoDerivativeWithPrevResult(const T *x, unsigned int icoord, T * /*previous_grad*/, + T * /*previous_g2*/, T * /*previous_gstep*/) const + { + return DoDerivative(x, icoord); + } }; @@ -135,10 +191,36 @@ namespace ROOT { // if it inherits from ROOT::Math::IGradientFunctionOneDim. virtual bool HasGradient() const { return false; } + /// Return the derivative of the function at a point x + /// Use the private method DoDerivative + double Derivative(double x) const { return DoDerivative(x); } + + /// Compatibility method with multi-dimensional interface for partial derivative. + double Derivative(const double *x) const { return DoDerivative(*x); } + + /// Compatibility method with multi-dimensional interface for Gradient. + void Gradient(const double *x, double *g) const { g[0] = DoDerivative(*x); } + + /// Optimized method to evaluate at the same time the function value and derivative at a point x. + /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. + /// Derived class should implement this method if performances play an important role and if it is faster to + /// evaluate value and derivative at the same time. + virtual void FdF(double x, double &f, double &df) const + { + f = operator()(x); + df = Derivative(x); + } + + /// Compatibility method with multi-dimensional interface for Gradient and function evaluation. + void FdF(const double *x, double &f, double *df) const { FdF(*x, f, *df); } + private: /// implementation of the evaluation function. Must be implemented by derived classes virtual double DoEval(double x) const = 0; + + /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. + virtual double DoDerivative(double) const { return 0.; } }; @@ -170,71 +252,8 @@ namespace ROOT { class IGradientFunctionMultiDimTempl : virtual public IBaseFunctionMultiDimTempl { public: - typedef IBaseFunctionMultiDimTempl BaseFunc; - typedef IGradientFunctionMultiDimTempl BaseGrad; - - - /// Evaluate all the vector of function derivatives (gradient) at a point x. - /// Derived classes must re-implement it if more efficient than evaluating one at a time - virtual void Gradient(const T *x, T *grad) const - { - unsigned int ndim = NDim(); - for (unsigned int icoord = 0; icoord < ndim; ++icoord) { - grad[icoord] = Derivative(x, icoord); - } - } - - /// In some cases, the gradient algorithm will use information from the previous step, these can be passed - /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size - /// so that these can be passed forward again as well at the call site, if necessary. - virtual void GradientWithPrevResult(const T *x, T *grad, T *previous_grad, T *previous_g2, T *previous_gstep) const - { - unsigned int ndim = NDim(); - for (unsigned int icoord = 0; icoord < ndim; ++icoord) { - grad[icoord] = Derivative(x, icoord, previous_grad, previous_g2, previous_gstep); - } - } - - using BaseFunc::NDim; - - /// Optimized method to evaluate at the same time the function value and derivative at a point x. - /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. - /// Derived class should implement this method if performances play an important role and if it is faster to - /// evaluate value and derivative at the same time - virtual void FdF(const T *x, T &f, T *df) const - { - f = BaseFunc::operator()(x); - Gradient(x, df); - } - - /// Return the partial derivative with respect to the passed coordinate. - T Derivative(const T *x, unsigned int icoord = 0) const { return DoDerivative(x, icoord); } - - /// In some cases, the derivative algorithm will use information from the previous step, these can be passed - /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size - /// so that these can be passed forward again as well at the call site, if necessary. - T Derivative(const T *x, unsigned int icoord, T *previous_grad, T *previous_g2, - T *previous_gstep) const - { - return DoDerivativeWithPrevResult(x, icoord, previous_grad, previous_g2, previous_gstep); - } bool HasGradient() const override { return true; } - - virtual bool returnsInMinuit2ParameterSpace() const { return false; } - - private: - /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. - virtual T DoDerivative(const T *x, unsigned int icoord) const = 0; - - /// In some cases, the derivative algorithm will use information from the previous step, these can be passed - /// in with this overload. The `previous_*` arrays can also be used to return second derivative and step size - /// so that these can be passed forward again as well at the call site, if necessary. - virtual T DoDerivativeWithPrevResult(const T *x, unsigned int icoord, T * /*previous_grad*/, - T * /*previous_g2*/, T * /*previous_gstep*/) const - { - return DoDerivative(x, icoord); - } }; @@ -257,38 +276,7 @@ namespace ROOT { public: - typedef IBaseFunctionOneDim BaseFunc; - typedef IGradientFunctionOneDim BaseGrad; - - /// Return the derivative of the function at a point x - /// Use the private method DoDerivative - double Derivative(double x) const { return DoDerivative(x); } - - /// Compatibility method with multi-dimensional interface for partial derivative. - double Derivative(const double *x) const { return DoDerivative(*x); } - - /// Compatibility method with multi-dimensional interface for Gradient. - void Gradient(const double *x, double *g) const { g[0] = DoDerivative(*x); } - - /// Optimized method to evaluate at the same time the function value and derivative at a point x. - /// Often both value and derivatives are needed and it is often more efficient to compute them at the same time. - /// Derived class should implement this method if performances play an important role and if it is faster to - /// evaluate value and derivative at the same time. - virtual void FdF(double x, double &f, double &df) const - { - f = operator()(x); - df = Derivative(x); - } - - /// Compatibility method with multi-dimensional interface for Gradient and function evaluation. - void FdF(const double *x, double &f, double *df) const { FdF(*x, f, *df); } - bool HasGradient() const override { return true; } - - private: - - /// Function to evaluate the derivative with respect each coordinate. To be implemented by the derived class. - virtual double DoDerivative(double x) const = 0; }; diff --git a/math/mathmore/src/GSLNLSMinimizer.cxx b/math/mathmore/src/GSLNLSMinimizer.cxx index 3fabfca8381e9..25b42f1386809 100644 --- a/math/mathmore/src/GSLNLSMinimizer.cxx +++ b/math/mathmore/src/GSLNLSMinimizer.cxx @@ -106,7 +106,7 @@ class FitTransformFunction : public FMFunc { double DoEval(const double *x) const override { return fFunc(fTransform->Transformation(x)); } - double DoDerivative(const double * /* x */, unsigned int /*icoord*/) const + double DoDerivative(const double * /* x */, unsigned int /*icoord*/) const override { // not used throw std::runtime_error("FitTransformFunction::DoDerivative"); diff --git a/roofit/roofit/test/GaussFunction.h b/roofit/roofit/test/GaussFunction.h index e08a6485c041d..593ffabc6c4ee 100644 --- a/roofit/roofit/test/GaussFunction.h +++ b/roofit/roofit/test/GaussFunction.h @@ -60,7 +60,7 @@ class GaussFunction : public ROOT::Math::IParamMultiGradFunction { return a * std::exp(-0.5 * y * y); } - double DoDerivative(const double *x, unsigned int icoord) const + double DoDerivative(const double *x, unsigned int icoord) const override { (void)icoord; assert(icoord == 0); diff --git a/roottest/root/meta/execTypedefList.C b/roottest/root/meta/execTypedefList.C index 410586aa834c3..6224604bdfbe5 100644 --- a/roottest/root/meta/execTypedefList.C +++ b/roottest/root/meta/execTypedefList.C @@ -149,17 +149,17 @@ int execTypedefList() { // res = check_target("std::list::const_iterator","list::const_iterator"); if (res) return res; #if defined(_MSC_VER) - res = check_file("typelist_win32.v5.txt",340); if (res) return res; + res = check_file("typelist_win32.v5.txt",336); if (res) return res; #if __cplusplus > 201402L res = check_file("typelist_win32.v6.cxx17.txt",1408); if (res) return res; #else res = check_file("typelist_win32.v6.txt",1420); if (res) return res; #endif #elif defined(R__MACOSX) && __cplusplus > 201402L - res = check_file("typelist.v5.txt",340); if (res) return res; + res = check_file("typelist.v5.txt",336); if (res) return res; res = check_file("typelist.v6.cxx17.txt",1310); if (res) return res; #else - res = check_file("typelist.v5.txt",340); if (res) return res; + res = check_file("typelist.v5.txt",336); if (res) return res; res = check_file("typelist.v6.txt",1322); if (res) return res; #endif diff --git a/roottest/root/meta/typelist.v5.txt b/roottest/root/meta/typelist.v5.txt index cf7be2b2c0575..e99fabebd8ca8 100644 --- a/roottest/root/meta/typelist.v5.txt +++ b/roottest/root/meta/typelist.v5.txt @@ -134,7 +134,6 @@ basic_istream >::traits_type vector,allocator > >::size_type ROOT::Fit::DataRange::RangeSet TVirtualCollectionProxy::CreateIterators_t -ROOT::Math::IGradientFunctionMultiDim::BaseFunc timespec_t Float_t ROOT::Fit::LogLikelihoodFCN::BaseObjFunction @@ -271,7 +270,6 @@ FontH_t ROOT::Math::KDTree >::value_type char* vector >::value_type -ROOT::Math::IGradientFunctionOneDim::BaseFunc istream TTabCom::TContainer Ssiz_t @@ -299,14 +297,12 @@ basic_stringbuf,allocator >::char_type ROOT::TSchemaRule::RuleType_t vector >::value_type UShort_t -ROOT::Math::IGradientFunctionMultiDim::BaseGrad ROOT::Math::BasicFitMethodFunction::BaseFunction basic_ostream >::char_type vector >::const_reference string::const_iterator ROOT::Fit::PoissonLLFunction vector >::const_iterator -ROOT::Math::IGradientFunctionOneDim::BaseGrad TVirtualFitter::FCNFunc_t KeySym_t string::difference_type diff --git a/roottest/root/meta/typelist_win32.v5.txt b/roottest/root/meta/typelist_win32.v5.txt index c67e38332a044..2ad26df29e5d9 100644 --- a/roottest/root/meta/typelist_win32.v5.txt +++ b/roottest/root/meta/typelist_win32.v5.txt @@ -133,7 +133,6 @@ basic_istream >::traits_type vector,allocator > >::size_type ROOT::Fit::DataRange::RangeSet TVirtualCollectionProxy::CreateIterators_t -ROOT::Math::IGradientFunctionMultiDim::BaseFunc timespec_t Float_t ROOT::Fit::LogLikelihoodFCN::BaseObjFunction @@ -271,7 +270,6 @@ FontH_t ROOT::Math::KDTree >::value_type char* vector >::value_type -ROOT::Math::IGradientFunctionOneDim::BaseFunc istream TTabCom::TContainer Ssiz_t @@ -299,14 +297,12 @@ basic_stringbuf,allocator >::char_type ROOT::TSchemaRule::RuleType_t vector >::value_type UShort_t -ROOT::Math::IGradientFunctionMultiDim::BaseGrad ROOT::Math::BasicFitMethodFunction::BaseFunction basic_ostream >::char_type vector >::const_reference string::const_iterator ROOT::Fit::PoissonLLFunction vector >::const_iterator -ROOT::Math::IGradientFunctionOneDim::BaseGrad TVirtualFitter::FCNFunc_t KeySym_t string::difference_type