diff --git a/math/minuit2/inc/Minuit2/AnalyticalGradientCalculator.h b/math/minuit2/inc/Minuit2/AnalyticalGradientCalculator.h index 2e427c7df2834..80f6ac9815bb2 100644 --- a/math/minuit2/inc/Minuit2/AnalyticalGradientCalculator.h +++ b/math/minuit2/inc/Minuit2/AnalyticalGradientCalculator.h @@ -17,14 +17,14 @@ namespace ROOT { namespace Minuit2 { -class FCNGradientBase; +class FCNBase; class MnUserTransformation; class AnalyticalGradientCalculator : public GradientCalculator { public: - AnalyticalGradientCalculator(const FCNGradientBase &fcn, const MnUserTransformation &state) + AnalyticalGradientCalculator(const FCNBase &fcn, const MnUserTransformation &state) : fGradFunc(fcn), fTransformation(state) { } @@ -46,7 +46,7 @@ class AnalyticalGradientCalculator : public GradientCalculator { virtual bool CanComputeHessian() const; protected: - const FCNGradientBase &fGradFunc; + const FCNBase &fGradFunc; const MnUserTransformation &fTransformation; }; diff --git a/math/minuit2/inc/Minuit2/ExternalInternalGradientCalculator.h b/math/minuit2/inc/Minuit2/ExternalInternalGradientCalculator.h index e5abc05e93287..168afab6ca93c 100644 --- a/math/minuit2/inc/Minuit2/ExternalInternalGradientCalculator.h +++ b/math/minuit2/inc/Minuit2/ExternalInternalGradientCalculator.h @@ -16,7 +16,7 @@ namespace ROOT { namespace Minuit2 { -class FCNGradientBase; +class FCNBase; class MnUserTransformation; /// Similar to the AnalyticalGradientCalculator, the ExternalInternalGradientCalculator @@ -30,7 +30,7 @@ class MnUserTransformation; class ExternalInternalGradientCalculator : public AnalyticalGradientCalculator { public: - ExternalInternalGradientCalculator(const FCNGradientBase &fcn, const MnUserTransformation &trafo) + ExternalInternalGradientCalculator(const FCNBase &fcn, const MnUserTransformation &trafo) : AnalyticalGradientCalculator(fcn, trafo) { } diff --git a/math/minuit2/inc/Minuit2/FCNBase.h b/math/minuit2/inc/Minuit2/FCNBase.h index e825bad79caf5..412544f4d01d9 100644 --- a/math/minuit2/inc/Minuit2/FCNBase.h +++ b/math/minuit2/inc/Minuit2/FCNBase.h @@ -32,6 +32,10 @@ namespace Minuit2 { \ingroup Math */ +enum class GradientParameterSpace { + External, Internal +}; + //______________________________________________________________________________ /** @@ -47,7 +51,6 @@ Interface (abstract class) defining the function to be minimized, which has to b class FCNBase : public GenericFunction { public: - ~FCNBase() override {} /** @@ -106,6 +109,29 @@ class FCNBase : public GenericFunction { Re-implement this function if needed. */ virtual void SetErrorDef(double){}; + + virtual bool HasGradient() const { return false; } + + virtual std::vector Gradient(std::span ) const { return {}; } + virtual std::vector GradientWithPrevResult(std::span parameters, double * /*previous_grad*/, + double * /*previous_g2*/, double * /*previous_gstep*/) const + { + return Gradient(parameters); + }; + + virtual GradientParameterSpace gradParameterSpace() const { + return GradientParameterSpace::External; + }; + + /// return second derivatives (diagonal of the Hessian matrix) + virtual std::vector G2(std::span ) const { return {};} + + /// return Hessian + virtual std::vector Hessian(std::span ) const { return {};} + + virtual bool HasHessian() const { return false; } + + virtual bool HasG2() const { return false; } }; } // namespace Minuit2 diff --git a/math/minuit2/inc/Minuit2/FCNGradAdapter.h b/math/minuit2/inc/Minuit2/FCNGradAdapter.h index dee73f89151f2..e7fedf76d46c3 100644 --- a/math/minuit2/inc/Minuit2/FCNGradAdapter.h +++ b/math/minuit2/inc/Minuit2/FCNGradAdapter.h @@ -10,7 +10,7 @@ #ifndef ROOT_Minuit2_FCNGradAdapter #define ROOT_Minuit2_FCNGradAdapter -#include "Minuit2/FCNGradientBase.h" +#include "Minuit2/FCNBase.h" #include "Minuit2/MnPrint.h" #include @@ -32,13 +32,15 @@ template wrapped class for adapting to FCNBase signature a IGradFunction */ template -class FCNGradAdapter : public FCNGradientBase { +class FCNGradAdapter : public FCNBase { public: FCNGradAdapter(const Function &f, double up = 1.) : fFunc(f), fUp(up), fGrad(std::vector(fFunc.NDim())) {} ~FCNGradAdapter() override {} + bool HasGradient() const override { return true; } + double operator()(std::span v) const override { return fFunc.operator()(&v[0]); } double operator()(const double *v) const { return fFunc.operator()(v); } diff --git a/math/minuit2/inc/Minuit2/FCNGradientBase.h b/math/minuit2/inc/Minuit2/FCNGradientBase.h index a6a14b1873176..2ad4fda3526c2 100644 --- a/math/minuit2/inc/Minuit2/FCNGradientBase.h +++ b/math/minuit2/inc/Minuit2/FCNGradientBase.h @@ -12,8 +12,6 @@ #include "Minuit2/FCNBase.h" -#include - namespace ROOT { namespace Minuit2 { @@ -25,37 +23,9 @@ namespace Minuit2 { input Parameter vector. */ -enum class GradientParameterSpace { - External, Internal -}; - class FCNGradientBase : public FCNBase { - public: - ~FCNGradientBase() override {} - - virtual std::vector Gradient(std::span ) const = 0; - virtual std::vector GradientWithPrevResult(std::span parameters, double * /*previous_grad*/, - double * /*previous_g2*/, double * /*previous_gstep*/) const - { - return Gradient(parameters); - }; - - virtual GradientParameterSpace gradParameterSpace() const { - return GradientParameterSpace::External; - }; - - /// return second derivatives (diagonal of the Hessian matrix) - virtual std::vector G2(std::span ) const { return std::vector();} - - /// return Hessian - virtual std::vector Hessian(std::span ) const { return std::vector();} - - virtual bool HasHessian() const { return false; } - - virtual bool HasG2() const { return false; } - - + bool HasGradient() const final { return true; } }; } // namespace Minuit2 diff --git a/math/minuit2/inc/Minuit2/FumiliFCNBase.h b/math/minuit2/inc/Minuit2/FumiliFCNBase.h index 7a1c7cd8e47cf..2f15251c6f883 100644 --- a/math/minuit2/inc/Minuit2/FumiliFCNBase.h +++ b/math/minuit2/inc/Minuit2/FumiliFCNBase.h @@ -10,7 +10,7 @@ #ifndef ROOT_Minuit2_FumiliFCNBase #define ROOT_Minuit2_FumiliFCNBase -#include "Minuit2/FCNGradientBase.h" +#include "Minuit2/FCNBase.h" #include #include @@ -43,7 +43,7 @@ section 5 */ -class FumiliFCNBase : public FCNGradientBase { +class FumiliFCNBase : public FCNBase { public: /** @@ -53,6 +53,8 @@ class FumiliFCNBase : public FCNGradientBase { FumiliFCNBase() : fNumberOfParameters(0), fValue(0) {} + bool HasGradient() const override { return true; } + /** Constructor which initializes the class with the function provided by the diff --git a/math/minuit2/inc/Minuit2/FumiliMinimizer.h b/math/minuit2/inc/Minuit2/FumiliMinimizer.h index a5cd5c962f470..3c3b72c74e096 100644 --- a/math/minuit2/inc/Minuit2/FumiliMinimizer.h +++ b/math/minuit2/inc/Minuit2/FumiliMinimizer.h @@ -88,9 +88,6 @@ class FumiliMinimizer : public ModularFunctionMinimizer { FunctionMinimum Minimize(const FCNBase &, const MnUserParameterState &, const MnStrategy &, unsigned int maxfcn = 0, double toler = 0.1) const override; - FunctionMinimum Minimize(const FCNGradientBase &, const MnUserParameterState &, const MnStrategy &, - unsigned int maxfcn = 0, double toler = 0.1) const override; - using ModularFunctionMinimizer::Minimize; private: diff --git a/math/minuit2/inc/Minuit2/FunctionMinimizer.h b/math/minuit2/inc/Minuit2/FunctionMinimizer.h index 61a47c1f6d201..6c0c5d2dc881f 100644 --- a/math/minuit2/inc/Minuit2/FunctionMinimizer.h +++ b/math/minuit2/inc/Minuit2/FunctionMinimizer.h @@ -21,7 +21,6 @@ namespace ROOT { namespace Minuit2 { class FCNBase; -class FCNGradientBase; class FunctionMinimum; //_____________________________________________________________________________________ @@ -43,20 +42,10 @@ class FunctionMinimizer { virtual FunctionMinimum Minimize(const FCNBase &, std::span par, std::span err, unsigned int strategy, unsigned int maxfcn, double toler) const = 0; - // starting values for parameters and errors and FCN with Gradient - virtual FunctionMinimum Minimize(const FCNGradientBase &, std::span par, - std::span err, unsigned int strategy, unsigned int maxfcn, - double toler) const = 0; - // starting values for parameters and covariance matrix virtual FunctionMinimum Minimize(const FCNBase &, std::span par, unsigned int nrow, std::span cov, unsigned int strategy, unsigned int maxfcn, double toler) const = 0; - - // starting values for parameters and covariance matrix and FCN with Gradient - virtual FunctionMinimum Minimize(const FCNGradientBase &, std::span par, unsigned int nrow, - std::span cov, unsigned int strategy, unsigned int maxfcn, - double toler) const = 0; }; } // namespace Minuit2 diff --git a/math/minuit2/inc/Minuit2/MnApplication.h b/math/minuit2/inc/Minuit2/MnApplication.h index 89e011ff69e5b..bb224ce38ae62 100644 --- a/math/minuit2/inc/Minuit2/MnApplication.h +++ b/math/minuit2/inc/Minuit2/MnApplication.h @@ -24,7 +24,6 @@ class MinuitParameter; class MnMachinePrecision; class ModularFunctionMinimizer; class FCNBase; -class FCNGradientBase; //___________________________________________________________________________ /** @@ -40,10 +39,6 @@ class MnApplication { /// constructor from non-gradient functions MnApplication(const FCNBase &fcn, const MnUserParameterState &state, const MnStrategy &stra, unsigned int nfcn = 0); - /// constructor from gradient function - MnApplication(const FCNGradientBase &fcn, const MnUserParameterState &state, const MnStrategy &stra, - unsigned int nfcn = 0); - virtual ~MnApplication() {} /** @@ -73,7 +68,6 @@ class MnApplication { MnUserParameterState fState; MnStrategy fStrategy; unsigned int fNumCall; - bool fUseGrad; public: // facade: forward interface of MnUserParameters and MnUserTransformation diff --git a/math/minuit2/inc/Minuit2/MnHesse.h b/math/minuit2/inc/Minuit2/MnHesse.h index e633aafa6d16a..66a90efb2ec8c 100644 --- a/math/minuit2/inc/Minuit2/MnHesse.h +++ b/math/minuit2/inc/Minuit2/MnHesse.h @@ -30,7 +30,6 @@ class MinimumState; class MnMachinePrecision; class MnFcn; class FunctionMinimum; -class FCNGradientBase; //_______________________________________________________________________ /** @@ -97,8 +96,8 @@ class MnHesse { /// internal function to compute the Hessian using numerical derivative computation MinimumState ComputeNumerical(const MnFcn &, const MinimumState &, const MnUserTransformation &, unsigned int maxcalls) const; - /// internal function to compute the Hessian using an analytical computation or externally provided in the FCNGradientBase class - MinimumState ComputeAnalytical(const FCNGradientBase &, const MinimumState &, const MnUserTransformation &) const; + /// internal function to compute the Hessian using an analytical computation or externally provided in the FCNBase class + MinimumState ComputeAnalytical(const FCNBase &, const MinimumState &, const MnUserTransformation &) const; MnStrategy fStrategy; }; diff --git a/math/minuit2/inc/Minuit2/MnMigrad.h b/math/minuit2/inc/Minuit2/MnMigrad.h index e1db22a90b405..4f891f72ced1b 100644 --- a/math/minuit2/inc/Minuit2/MnMigrad.h +++ b/math/minuit2/inc/Minuit2/MnMigrad.h @@ -70,48 +70,6 @@ class MnMigrad : public MnApplication { { } - // constructs from gradient FCN - - /// construct from FCNGradientBase + std::vector for parameters and errors - MnMigrad(const FCNGradientBase &fcn, std::span par, std::span err, - unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, err), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer()) - { - } - - /// construct from FCNGradientBase + std::vector for parameters and covariance - MnMigrad(const FCNGradientBase &fcn, std::span par, unsigned int nrow, - std::span cov, unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, cov, nrow), MnStrategy(stra)), - fMinimizer(VariableMetricMinimizer()) - { - } - - /// construct from FCNGradientBase + std::vector for parameters and MnUserCovariance - MnMigrad(const FCNGradientBase &fcn, std::span par, const MnUserCovariance &cov, - unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer()) - { - } - - /// construct from FCNGradientBase + MnUserParameters - MnMigrad(const FCNGradientBase &fcn, const MnUserParameters &par, unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer()) - { - } - - /// construct from FCNGradientBase + MnUserParameters + MnUserCovariance - MnMigrad(const FCNGradientBase &fcn, const MnUserParameters &par, const MnUserCovariance &cov, unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer()) - { - } - - /// construct from FCNGradientBase + MnUserParameterState + MnStrategy - MnMigrad(const FCNGradientBase &fcn, const MnUserParameterState &par, const MnStrategy &str) - : MnApplication(fcn, MnUserParameterState(par), str), fMinimizer(VariableMetricMinimizer()) - { - } - ~MnMigrad() override {} /// Copy constructor, copy shares the reference to the same FCNBase in MnApplication diff --git a/math/minuit2/inc/Minuit2/MnMinimize.h b/math/minuit2/inc/Minuit2/MnMinimize.h index ab8f73537190c..905e158bfb1d1 100644 --- a/math/minuit2/inc/Minuit2/MnMinimize.h +++ b/math/minuit2/inc/Minuit2/MnMinimize.h @@ -67,48 +67,6 @@ class MnMinimize : public MnApplication { { } - // interfaces using FCNGradientBase - - /// construct from FCNGradientBase + std::vector for parameters and errors - MnMinimize(const FCNGradientBase &fcn, std::span par, std::span err, - unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, err), MnStrategy(stra)), fMinimizer(CombinedMinimizer()) - { - } - - /// construct from FCNGradientBase + std::vector for parameters and covariance - MnMinimize(const FCNGradientBase &fcn, std::span par, unsigned int nrow, - std::span cov, unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, cov, nrow), MnStrategy(stra)), fMinimizer(CombinedMinimizer()) - { - } - - /// construct from FCNGradientBase + std::vector for parameters and MnUserCovariance - MnMinimize(const FCNGradientBase &fcn, std::span par, const MnUserCovariance &cov, - unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(CombinedMinimizer()) - { - } - - /// construct from FCNGradientBase + MnUserParameters - MnMinimize(const FCNGradientBase &fcn, const MnUserParameters &par, unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par), MnStrategy(stra)), fMinimizer(CombinedMinimizer()) - { - } - - /// construct from FCNGradientBase + MnUserParameters + MnUserCovariance - MnMinimize(const FCNGradientBase &fcn, const MnUserParameters &par, const MnUserCovariance &cov, - unsigned int stra = 1) - : MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(CombinedMinimizer()) - { - } - - /// construct from FCNGradientBase + MnUserParameterState + MnStrategy - MnMinimize(const FCNGradientBase &fcn, const MnUserParameterState &par, const MnStrategy &str) - : MnApplication(fcn, MnUserParameterState(par), str), fMinimizer(CombinedMinimizer()) - { - } - MnMinimize(const MnMinimize &migr) : MnApplication(migr.Fcnbase(), migr.State(), migr.Strategy(), migr.NumOfCalls()), fMinimizer(migr.fMinimizer) { diff --git a/math/minuit2/inc/Minuit2/ModularFunctionMinimizer.h b/math/minuit2/inc/Minuit2/ModularFunctionMinimizer.h index 423b7f469fe61..950a728d0c890 100644 --- a/math/minuit2/inc/Minuit2/ModularFunctionMinimizer.h +++ b/math/minuit2/inc/Minuit2/ModularFunctionMinimizer.h @@ -46,36 +46,20 @@ class ModularFunctionMinimizer : public FunctionMinimizer { FunctionMinimum Minimize(const FCNBase &, std::span, std::span, unsigned int stra = 1, unsigned int maxfcn = 0, double toler = 0.1) const override; - FunctionMinimum Minimize(const FCNGradientBase &, std::span, std::span, - unsigned int stra = 1, unsigned int maxfcn = 0, double toler = 0.1) const override; - FunctionMinimum Minimize(const FCNBase &, std::span, unsigned int, std::span, unsigned int stra = 1, unsigned int maxfcn = 0, double toler = 0.1) const override; - FunctionMinimum Minimize(const FCNGradientBase &, std::span, unsigned int, - std::span, unsigned int stra = 1, unsigned int maxfcn = 0, - double toler = 0.1) const override; - // extension virtual FunctionMinimum Minimize(const FCNBase &, const MnUserParameters &, const MnStrategy &, unsigned int maxfcn = 0, double toler = 0.1) const; - virtual FunctionMinimum Minimize(const FCNGradientBase &, const MnUserParameters &, const MnStrategy &, - unsigned int maxfcn = 0, double toler = 0.1) const; - virtual FunctionMinimum Minimize(const FCNBase &, const MnUserParameters &, const MnUserCovariance &, const MnStrategy &, unsigned int maxfcn = 0, double toler = 0.1) const; - virtual FunctionMinimum Minimize(const FCNGradientBase &, const MnUserParameters &, const MnUserCovariance &, - const MnStrategy &, unsigned int maxfcn = 0, double toler = 0.1) const; - virtual FunctionMinimum Minimize(const FCNBase &, const MnUserParameterState &, const MnStrategy &, unsigned int maxfcn = 0, double toler = 0.1) const; - virtual FunctionMinimum Minimize(const FCNGradientBase &, const MnUserParameterState &, const MnStrategy &, - unsigned int maxfcn = 0, double toler = 0.1) const; - // for Fumili // virtual FunctionMinimum Minimize(const FumiliFCNBase&, const std::vector&, const std::vector&, diff --git a/math/minuit2/src/AnalyticalGradientCalculator.cxx b/math/minuit2/src/AnalyticalGradientCalculator.cxx index a63e00a644e7f..dbecc3aeba818 100644 --- a/math/minuit2/src/AnalyticalGradientCalculator.cxx +++ b/math/minuit2/src/AnalyticalGradientCalculator.cxx @@ -8,7 +8,7 @@ **********************************************************************/ #include "Minuit2/AnalyticalGradientCalculator.h" -#include "Minuit2/FCNGradientBase.h" +#include "Minuit2/FCNBase.h" #include "Minuit2/MnUserTransformation.h" #include "Minuit2/FunctionGradient.h" #include "Minuit2/MinimumParameters.h" diff --git a/math/minuit2/src/ExternalInternalGradientCalculator.cxx b/math/minuit2/src/ExternalInternalGradientCalculator.cxx index 3dd4b60d084ca..c5de47eab1bff 100644 --- a/math/minuit2/src/ExternalInternalGradientCalculator.cxx +++ b/math/minuit2/src/ExternalInternalGradientCalculator.cxx @@ -9,7 +9,7 @@ #include #include "Minuit2/ExternalInternalGradientCalculator.h" -#include "Minuit2/FCNGradientBase.h" +#include "Minuit2/FCNBase.h" #include "Minuit2/MnUserTransformation.h" #include "Minuit2/FunctionGradient.h" #include "Minuit2/MinimumParameters.h" diff --git a/math/minuit2/src/FumiliMinimizer.cxx b/math/minuit2/src/FumiliMinimizer.cxx index 3a4e358ced20e..df845fa576932 100644 --- a/math/minuit2/src/FumiliMinimizer.cxx +++ b/math/minuit2/src/FumiliMinimizer.cxx @@ -21,7 +21,7 @@ #include "Minuit2/MnUserTransformation.h" #include "Minuit2/MnUserFcn.h" #include "Minuit2/FumiliFCNBase.h" -#include "Minuit2/FCNGradientBase.h" +#include "Minuit2/FCNBase.h" #include "Minuit2/MnStrategy.h" #include "Minuit2/MnPrint.h" @@ -34,45 +34,40 @@ namespace Minuit2 { FunctionMinimum FumiliMinimizer::Minimize(const FCNBase &fcn, const MnUserParameterState &st, const MnStrategy &strategy, unsigned int maxfcn, double toler) const { + MnPrint print("FumiliMinimizer::Minimize"); + // Minimize using Fumili. Create seed and Fumili gradient calculator. // The FCNBase passed must be a FumiliFCNBase type otherwise method will fail ! - MnPrint print("FumiliMinimizer"); + if (fcn.HasGradient()) { + MnUserFcn mfcn(fcn, st.Trafo()); + Numerical2PGradientCalculator gc(mfcn, st.Trafo(), strategy); - MnUserFcn mfcn(fcn, st.Trafo()); - Numerical2PGradientCalculator gc(mfcn, st.Trafo(), strategy); + unsigned int npar = st.VariableParameters(); + if (maxfcn == 0) + maxfcn = 200 + 100 * npar + 5 * npar * npar; + // FUMILI needs much less function calls + maxfcn = int(0.1 * maxfcn); - unsigned int npar = st.VariableParameters(); - if (maxfcn == 0) - maxfcn = 200 + 100 * npar + 5 * npar * npar; - // FUMILI needs much less function calls - maxfcn = int(0.1 * maxfcn); + MinimumSeed mnseeds = SeedGenerator()(mfcn, gc, st, strategy); - MinimumSeed mnseeds = SeedGenerator()(mfcn, gc, st, strategy); + // downcast fcn - // downcast fcn + // std::cout << "FCN type " << typeid(&fcn).Name() << std::endl; - // std::cout << "FCN type " << typeid(&fcn).Name() << std::endl; + FumiliFCNBase *fumiliFcn = dynamic_cast(const_cast(&fcn)); + if (!fumiliFcn) { + print.Error("Wrong FCN type; try to use default minimizer"); + return FunctionMinimum(mnseeds, fcn.Up()); + } - FumiliFCNBase *fumiliFcn = dynamic_cast(const_cast(&fcn)); - if (!fumiliFcn) { - print.Error("Wrong FCN type; try to use default minimizer"); - return FunctionMinimum(mnseeds, fcn.Up()); - } + FumiliGradientCalculator fgc(*fumiliFcn, st.Trafo(), npar); + print.Debug("Using FumiliMinimizer"); - FumiliGradientCalculator fgc(*fumiliFcn, st.Trafo(), npar); - print.Debug("Using FumiliMinimizer"); - - return ModularFunctionMinimizer::Minimize(mfcn, fgc, mnseeds, strategy, maxfcn, toler); -} - -FunctionMinimum FumiliMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameterState &st, - const MnStrategy &strategy, unsigned int maxfcn, double toler) const -{ - - MnPrint print("FumiliMinimizer::Minimize"); + return ModularFunctionMinimizer::Minimize(mfcn, fgc, mnseeds, strategy, maxfcn, toler); + } - // Minimize using Fumili. Case of interface is a FCNGradientBase. + // Minimize using Fumili. Case of interface is a function with gradient. // Normally other method is used - probably this could be removed (t.b.i.) // need MnUserFcn @@ -87,7 +82,7 @@ FunctionMinimum FumiliMinimizer::Minimize(const FCNGradientBase &fcn, const MnUs // downcast fcn - FumiliFCNBase *fumiliFcn = dynamic_cast(const_cast(&fcn)); + FumiliFCNBase *fumiliFcn = dynamic_cast(const_cast(&fcn)); if (!fumiliFcn) { print.Error("Wrong FCN type; try to use default minimizer"); return FunctionMinimum(mnseeds, fcn.Up()); diff --git a/math/minuit2/src/Minuit2Minimizer.cxx b/math/minuit2/src/Minuit2Minimizer.cxx index ef69ab2dd09df..098dddd126560 100644 --- a/math/minuit2/src/Minuit2Minimizer.cxx +++ b/math/minuit2/src/Minuit2Minimizer.cxx @@ -549,16 +549,8 @@ bool Minuit2Minimizer::Minimize() const ROOT::Minuit2::MnStrategy strategy = customizedStrategy(strategyLevel, fOptions); - const ROOT::Minuit2::FCNGradientBase *gradFCN = dynamic_cast(fMinuitFCN); - if (gradFCN != nullptr) { - // use gradient - // SetPrintLevel(3); - ROOT::Minuit2::FunctionMinimum min = GetMinimizer()->Minimize(*gradFCN, fState, strategy, maxfcn, tol); - fMinimum = new ROOT::Minuit2::FunctionMinimum(min); - } else { - ROOT::Minuit2::FunctionMinimum min = GetMinimizer()->Minimize(*GetFCN(), fState, strategy, maxfcn, tol); - fMinimum = new ROOT::Minuit2::FunctionMinimum(min); - } + ROOT::Minuit2::FunctionMinimum min = GetMinimizer()->Minimize(*fMinuitFCN, fState, strategy, maxfcn, tol); + fMinimum = new ROOT::Minuit2::FunctionMinimum(min); // check if Hesse needs to be run. We do it when is requested (IsValidError() == true , set by SetParabError(true) in fitConfig) // (IsValidError() means the flag to get correct error from the Minimizer is set (Minimizer::SetValidError()) diff --git a/math/minuit2/src/MnApplication.cxx b/math/minuit2/src/MnApplication.cxx index 249ab54532054..8e379dbf21095 100644 --- a/math/minuit2/src/MnApplication.cxx +++ b/math/minuit2/src/MnApplication.cxx @@ -10,7 +10,7 @@ #include "Minuit2/MnApplication.h" #include "Minuit2/FunctionMinimum.h" #include "Minuit2/ModularFunctionMinimizer.h" -#include "Minuit2/FCNGradientBase.h" +#include "Minuit2/FCNBase.h" #include "Minuit2/MnPrint.h" namespace ROOT { @@ -20,14 +20,7 @@ namespace Minuit2 { // constructor from non-gradient functions MnApplication::MnApplication(const FCNBase &fcn, const MnUserParameterState &state, const MnStrategy &stra, unsigned int nfcn) - : fFCN(fcn), fState(state), fStrategy(stra), fNumCall(nfcn), fUseGrad(false) -{ -} - -// constructor from functions -MnApplication::MnApplication(const FCNGradientBase &fcn, const MnUserParameterState &state, const MnStrategy &stra, - unsigned int nfcn) - : fFCN(fcn), fState(state), fStrategy(stra), fNumCall(nfcn), fUseGrad(true) + : fFCN(fcn), fState(state), fStrategy(stra), fNumCall(nfcn) { } @@ -43,11 +36,8 @@ FunctionMinimum MnApplication::operator()(unsigned int maxfcn, double toler) maxfcn = 200 + 100 * npar + 5 * npar * npar; const FCNBase &fcn = Fcnbase(); - assert(!fUseGrad || dynamic_cast(&fcn) != nullptr); - FunctionMinimum min = - fUseGrad ? Minimizer().Minimize(static_cast(fcn), fState, fStrategy, maxfcn, toler) - : Minimizer().Minimize(fcn, fState, fStrategy, maxfcn, toler); + FunctionMinimum min = Minimizer().Minimize(fcn, fState, fStrategy, maxfcn, toler); fNumCall += min.NFcn(); fState = min.UserState(); diff --git a/math/minuit2/src/MnHesse.cxx b/math/minuit2/src/MnHesse.cxx index 74ed629ec9ee8..f1054a7fb1cfc 100644 --- a/math/minuit2/src/MnHesse.cxx +++ b/math/minuit2/src/MnHesse.cxx @@ -11,7 +11,6 @@ #include "Minuit2/MnUserParameterState.h" #include "Minuit2/MnUserFcn.h" #include "Minuit2/FCNBase.h" -#include "Minuit2/FCNGradientBase.h" #include "Minuit2/MnPosDef.h" #include "Minuit2/HessianGradientCalculator.h" #include "Minuit2/Numerical2PGradientCalculator.h" @@ -75,10 +74,9 @@ MnHesse::operator()(const FCNBase &fcn, const MnUserParameterState &state, unsig double amin = mfcn(x); MinimumParameters par(x, amin); // check if we can use analytical gradient - auto * gradFCN = dynamic_cast(&(fcn)); - if (gradFCN) { + if (fcn.HasGradient()) { // no need to compute gradient here - MinimumState tmp = ComputeAnalytical(*gradFCN, MinimumState(par, MinimumError(MnAlgebraicSymMatrix(n), 1.), FunctionGradient(n), + MinimumState tmp = ComputeAnalytical(fcn, MinimumState(par, MinimumError(MnAlgebraicSymMatrix(n), 1.), FunctionGradient(n), state.Edm(), state.NFcn()), state.Trafo()); return MnUserParameterState(tmp, fcn.Up(), state.Trafo()); } @@ -106,15 +104,14 @@ MinimumState MnHesse::operator()(const MnFcn &mfcn, const MinimumState &st, cons // check first if we have an analytical gradient if (st.Gradient().IsAnalytical()) { // check if we can compute analytical Hessian - auto * gradFCN = dynamic_cast(&(mfcn.Fcn())); - if (gradFCN && gradFCN->HasHessian()) { - return ComputeAnalytical(*gradFCN, st, trafo); + if (mfcn.Fcn().HasGradient() && mfcn.Fcn().HasHessian()) { + return ComputeAnalytical(mfcn.Fcn(), st, trafo); } } // case of numerical computation or only analytical first derivatives return ComputeNumerical(mfcn, st, trafo, maxcalls); } -MinimumState MnHesse::ComputeAnalytical(const FCNGradientBase & fcn, const MinimumState &st, const MnUserTransformation &trafo) const +MinimumState MnHesse::ComputeAnalytical(const FCNBase & fcn, const MinimumState &st, const MnUserTransformation &trafo) const { unsigned int n = st.Parameters().Vec().size(); MnAlgebraicSymMatrix vhmat(n); diff --git a/math/minuit2/src/ModularFunctionMinimizer.cxx b/math/minuit2/src/ModularFunctionMinimizer.cxx index 76da34f924533..41c4c8c13a9bd 100644 --- a/math/minuit2/src/ModularFunctionMinimizer.cxx +++ b/math/minuit2/src/ModularFunctionMinimizer.cxx @@ -21,7 +21,6 @@ #include "Minuit2/MnUserTransformation.h" #include "Minuit2/MnUserFcn.h" #include "Minuit2/FCNBase.h" -#include "Minuit2/FCNGradientBase.h" #include "Minuit2/MnStrategy.h" #include "Minuit2/MnHesse.h" #include "Minuit2/MnLineSearch.h" @@ -44,17 +43,6 @@ FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, std::span return Minimize(fcn, st, strategy, maxfcn, toler); } -FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, std::span par, - std::span err, unsigned int stra, - unsigned int maxfcn, double toler) const -{ - // minimize from FCNGradientBase (use analytical gradient provided in FCN) - // and std::vector of double's for parameter values and errors (step sizes) - MnUserParameterState st(par, err); - MnStrategy strategy(stra); - return Minimize(fcn, st, strategy, maxfcn, toler); -} - // move nrow before cov to avoid ambiguities when using default parameters FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, std::span par, unsigned int nrow, std::span cov, unsigned int stra, @@ -68,19 +56,6 @@ FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, std::span return Minimize(fcn, st, strategy, maxfcn, toler); } -FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, std::span par, - unsigned int nrow, std::span cov, unsigned int stra, - unsigned int maxfcn, double toler) const -{ - // minimize from FCNGradientBase (use analytical gradient provided in FCN) - // using std::vector for parameter error and - // an std::vector of size n*(n+1)/2 for the covariance matrix and n (rank of cov matrix) - - MnUserParameterState st(par, cov, nrow); - MnStrategy strategy(stra); - return Minimize(fcn, st, strategy, maxfcn, toler); -} - FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameters &upar, const MnStrategy &strategy, unsigned int maxfcn, double toler) const { @@ -90,15 +65,6 @@ FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnU return Minimize(fcn, st, strategy, maxfcn, toler); } -FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameters &upar, - const MnStrategy &strategy, unsigned int maxfcn, double toler) const -{ - // minimize from FCNGradientBase (use analytical gradient provided in FCN) and MnUserParameters object - - MnUserParameterState st(upar); - return Minimize(fcn, st, strategy, maxfcn, toler); -} - FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameters &upar, const MnUserCovariance &cov, const MnStrategy &strategy, unsigned int maxfcn, double toler) const @@ -109,42 +75,27 @@ FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnU return Minimize(fcn, st, strategy, maxfcn, toler); } -FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameters &upar, - const MnUserCovariance &cov, const MnStrategy &strategy, - unsigned int maxfcn, double toler) const -{ - // minimize from FCNGradientBase (use analytical gradient provided in FCN) and - // MnUserParameters MnUserCovariance objects - - MnUserParameterState st(upar, cov); - return Minimize(fcn, st, strategy, maxfcn, toler); -} - FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNBase &fcn, const MnUserParameterState &st, const MnStrategy &strategy, unsigned int maxfcn, double toler) const { - // minimize from a FCNBase and a MnUserparameterState - interface used by all the previous ones - // based on FCNBase. Create in this case a NumericalGradient calculator - // Create the minuit FCN wrapper (MnUserFcn) containing the transformation (int<->ext) + if (!fcn.HasGradient()) { + // minimize from a FCNBase and a MnUserparameterState - interface used by all the previous ones + // based on FCNBase. Create in this case a NumericalGradient calculator + // Create the minuit FCN wrapper (MnUserFcn) containing the transformation (int<->ext) - // need MnUserFcn for difference int-ext parameters - MnUserFcn mfcn(fcn, st.Trafo()); - Numerical2PGradientCalculator gc(mfcn, st.Trafo(), strategy); + // need MnUserFcn for difference int-ext parameters + MnUserFcn mfcn(fcn, st.Trafo()); + Numerical2PGradientCalculator gc(mfcn, st.Trafo(), strategy); - unsigned int npar = st.VariableParameters(); - if (maxfcn == 0) - maxfcn = 200 + 100 * npar + 5 * npar * npar; - MinimumSeed mnseeds = SeedGenerator()(mfcn, gc, st, strategy); + unsigned int npar = st.VariableParameters(); + if (maxfcn == 0) + maxfcn = 200 + 100 * npar + 5 * npar * npar; + MinimumSeed mnseeds = SeedGenerator()(mfcn, gc, st, strategy); - return Minimize(mfcn, gc, mnseeds, strategy, maxfcn, toler); -} - -// use Gradient here -FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, const MnUserParameterState &st, - const MnStrategy &strategy, unsigned int maxfcn, double toler) const -{ - // minimize from a FCNGradientBase and a MnUserParameterState - - // interface based on FCNGradientBase (external/analytical gradients) + return Minimize(mfcn, gc, mnseeds, strategy, maxfcn, toler); + } + // minimize from a function with gradient and a MnUserParameterState - + // interface based on function with gradient (external/analytical gradients) // Create in this case an AnalyticalGradient calculator // Create the minuit FCN wrapper (MnUserFcn) containing the transformation (int<->ext) @@ -164,9 +115,7 @@ FunctionMinimum ModularFunctionMinimizer::Minimize(const FCNGradientBase &fcn, c // compute seed (will use internally numerical gradient in case calculator does not implement g2 computations) MinimumSeed mnseeds = SeedGenerator()(mfcn, *gc, st, strategy); - auto minimum = Minimize(mfcn, *gc, mnseeds, strategy, maxfcn, toler); - - return minimum; + return Minimize(mfcn, *gc, mnseeds, strategy, maxfcn, toler); } FunctionMinimum ModularFunctionMinimizer::Minimize(const MnFcn &mfcn, const GradientCalculator &gc,