Skip to content

Commit 71806b3

Browse files
committed
[Minuit2] Add virtual FCNBase::HasGradient() method
By introducing a virtual `FCNBase::HasGradient()` method and moving the former `FCNGradientBase` interface to the base class, we don't need to repeat lots of code just for dealing with both the `FCNBase` and `FCNGradientBase` types. This is a completely backwards compatible change that makes the Minuit 2 code more maintainable.
1 parent 94549da commit 71806b3

20 files changed

+96
-294
lines changed

math/minuit2/inc/Minuit2/AnalyticalGradientCalculator.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ namespace ROOT {
1717

1818
namespace Minuit2 {
1919

20-
class FCNGradientBase;
20+
class FCNBase;
2121
class MnUserTransformation;
2222

2323

2424
class AnalyticalGradientCalculator : public GradientCalculator {
2525

2626
public:
27-
AnalyticalGradientCalculator(const FCNGradientBase &fcn, const MnUserTransformation &state)
27+
AnalyticalGradientCalculator(const FCNBase &fcn, const MnUserTransformation &state)
2828
: fGradFunc(fcn), fTransformation(state)
2929
{
3030
}
@@ -46,7 +46,7 @@ class AnalyticalGradientCalculator : public GradientCalculator {
4646
virtual bool CanComputeHessian() const;
4747

4848
protected:
49-
const FCNGradientBase &fGradFunc;
49+
const FCNBase &fGradFunc;
5050
const MnUserTransformation &fTransformation;
5151
};
5252

math/minuit2/inc/Minuit2/ExternalInternalGradientCalculator.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace ROOT {
1616

1717
namespace Minuit2 {
1818

19-
class FCNGradientBase;
19+
class FCNBase;
2020
class MnUserTransformation;
2121

2222
/// Similar to the AnalyticalGradientCalculator, the ExternalInternalGradientCalculator
@@ -30,7 +30,7 @@ class MnUserTransformation;
3030
class ExternalInternalGradientCalculator : public AnalyticalGradientCalculator {
3131

3232
public:
33-
ExternalInternalGradientCalculator(const FCNGradientBase &fcn, const MnUserTransformation &trafo)
33+
ExternalInternalGradientCalculator(const FCNBase &fcn, const MnUserTransformation &trafo)
3434
: AnalyticalGradientCalculator(fcn, trafo)
3535
{
3636
}

math/minuit2/inc/Minuit2/FCNBase.h

+27-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ namespace Minuit2 {
3232
\ingroup Math
3333
*/
3434

35+
enum class GradientParameterSpace {
36+
External, Internal
37+
};
38+
3539
//______________________________________________________________________________
3640
/**
3741
@@ -47,7 +51,6 @@ Interface (abstract class) defining the function to be minimized, which has to b
4751
class FCNBase : public GenericFunction {
4852

4953
public:
50-
~FCNBase() override {}
5154

5255
/**
5356
@@ -106,6 +109,29 @@ class FCNBase : public GenericFunction {
106109
Re-implement this function if needed.
107110
*/
108111
virtual void SetErrorDef(double){};
112+
113+
virtual bool HasGradient() const { return false; }
114+
115+
virtual std::vector<double> Gradient(std::span<const double> ) const { return {}; }
116+
virtual std::vector<double> GradientWithPrevResult(std::span<const double> parameters, double * /*previous_grad*/,
117+
double * /*previous_g2*/, double * /*previous_gstep*/) const
118+
{
119+
return Gradient(parameters);
120+
};
121+
122+
virtual GradientParameterSpace gradParameterSpace() const {
123+
return GradientParameterSpace::External;
124+
};
125+
126+
/// return second derivatives (diagonal of the Hessian matrix)
127+
virtual std::vector<double> G2(std::span<const double> ) const { return {};}
128+
129+
/// return Hessian
130+
virtual std::vector<double> Hessian(std::span<const double> ) const { return {};}
131+
132+
virtual bool HasHessian() const { return false; }
133+
134+
virtual bool HasG2() const { return false; }
109135
};
110136

111137
} // namespace Minuit2

math/minuit2/inc/Minuit2/FCNGradAdapter.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#ifndef ROOT_Minuit2_FCNGradAdapter
1111
#define ROOT_Minuit2_FCNGradAdapter
1212

13-
#include "Minuit2/FCNGradientBase.h"
13+
#include "Minuit2/FCNBase.h"
1414
#include "Minuit2/MnPrint.h"
1515

1616
#include <vector>
@@ -32,13 +32,15 @@ template wrapped class for adapting to FCNBase signature a IGradFunction
3232
*/
3333

3434
template <class Function>
35-
class FCNGradAdapter : public FCNGradientBase {
35+
class FCNGradAdapter : public FCNBase {
3636

3737
public:
3838
FCNGradAdapter(const Function &f, double up = 1.) : fFunc(f), fUp(up), fGrad(std::vector<double>(fFunc.NDim())) {}
3939

4040
~FCNGradAdapter() override {}
4141

42+
bool HasGradient() const override { return true; }
43+
4244
double operator()(std::span<const double> v) const override { return fFunc.operator()(&v[0]); }
4345
double operator()(const double *v) const { return fFunc.operator()(v); }
4446

math/minuit2/inc/Minuit2/FCNGradientBase.h

+1-31
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
#include "Minuit2/FCNBase.h"
1414

15-
#include <vector>
16-
1715
namespace ROOT {
1816

1917
namespace Minuit2 {
@@ -25,37 +23,9 @@ namespace Minuit2 {
2523
input Parameter vector.
2624
*/
2725

28-
enum class GradientParameterSpace {
29-
External, Internal
30-
};
31-
3226
class FCNGradientBase : public FCNBase {
33-
3427
public:
35-
~FCNGradientBase() override {}
36-
37-
virtual std::vector<double> Gradient(std::span<const double> ) const = 0;
38-
virtual std::vector<double> GradientWithPrevResult(std::span<const double> parameters, double * /*previous_grad*/,
39-
double * /*previous_g2*/, double * /*previous_gstep*/) const
40-
{
41-
return Gradient(parameters);
42-
};
43-
44-
virtual GradientParameterSpace gradParameterSpace() const {
45-
return GradientParameterSpace::External;
46-
};
47-
48-
/// return second derivatives (diagonal of the Hessian matrix)
49-
virtual std::vector<double> G2(std::span<const double> ) const { return std::vector<double>();}
50-
51-
/// return Hessian
52-
virtual std::vector<double> Hessian(std::span<const double> ) const { return std::vector<double>();}
53-
54-
virtual bool HasHessian() const { return false; }
55-
56-
virtual bool HasG2() const { return false; }
57-
58-
28+
bool HasGradient() const final { return true; }
5929
};
6030

6131
} // namespace Minuit2

math/minuit2/inc/Minuit2/FumiliFCNBase.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#ifndef ROOT_Minuit2_FumiliFCNBase
1111
#define ROOT_Minuit2_FumiliFCNBase
1212

13-
#include "Minuit2/FCNGradientBase.h"
13+
#include "Minuit2/FCNBase.h"
1414
#include <cassert>
1515
#include <vector>
1616

@@ -43,7 +43,7 @@ section 5
4343
4444
*/
4545

46-
class FumiliFCNBase : public FCNGradientBase {
46+
class FumiliFCNBase : public FCNBase {
4747

4848
public:
4949
/**
@@ -53,6 +53,8 @@ class FumiliFCNBase : public FCNGradientBase {
5353

5454
FumiliFCNBase() : fNumberOfParameters(0), fValue(0) {}
5555

56+
bool HasGradient() const override { return true; }
57+
5658
/**
5759
5860
Constructor which initializes the class with the function provided by the

math/minuit2/inc/Minuit2/FumiliMinimizer.h

-3
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ class FumiliMinimizer : public ModularFunctionMinimizer {
8888
FunctionMinimum Minimize(const FCNBase &, const MnUserParameterState &, const MnStrategy &, unsigned int maxfcn = 0,
8989
double toler = 0.1) const override;
9090

91-
FunctionMinimum Minimize(const FCNGradientBase &, const MnUserParameterState &, const MnStrategy &,
92-
unsigned int maxfcn = 0, double toler = 0.1) const override;
93-
9491
using ModularFunctionMinimizer::Minimize;
9592

9693
private:

math/minuit2/inc/Minuit2/FunctionMinimizer.h

-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ namespace ROOT {
2121
namespace Minuit2 {
2222

2323
class FCNBase;
24-
class FCNGradientBase;
2524
class FunctionMinimum;
2625

2726
//_____________________________________________________________________________________
@@ -43,20 +42,10 @@ class FunctionMinimizer {
4342
virtual FunctionMinimum Minimize(const FCNBase &, std::span<const double> par, std::span<const double> err,
4443
unsigned int strategy, unsigned int maxfcn, double toler) const = 0;
4544

46-
// starting values for parameters and errors and FCN with Gradient
47-
virtual FunctionMinimum Minimize(const FCNGradientBase &, std::span<const double> par,
48-
std::span<const double> err, unsigned int strategy, unsigned int maxfcn,
49-
double toler) const = 0;
50-
5145
// starting values for parameters and covariance matrix
5246
virtual FunctionMinimum Minimize(const FCNBase &, std::span<const double> par, unsigned int nrow,
5347
std::span<const double> cov, unsigned int strategy, unsigned int maxfcn,
5448
double toler) const = 0;
55-
56-
// starting values for parameters and covariance matrix and FCN with Gradient
57-
virtual FunctionMinimum Minimize(const FCNGradientBase &, std::span<const double> par, unsigned int nrow,
58-
std::span<const double> cov, unsigned int strategy, unsigned int maxfcn,
59-
double toler) const = 0;
6049
};
6150

6251
} // namespace Minuit2

math/minuit2/inc/Minuit2/MnApplication.h

-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class MinuitParameter;
2424
class MnMachinePrecision;
2525
class ModularFunctionMinimizer;
2626
class FCNBase;
27-
class FCNGradientBase;
2827

2928
//___________________________________________________________________________
3029
/**
@@ -40,10 +39,6 @@ class MnApplication {
4039
/// constructor from non-gradient functions
4140
MnApplication(const FCNBase &fcn, const MnUserParameterState &state, const MnStrategy &stra, unsigned int nfcn = 0);
4241

43-
/// constructor from gradient function
44-
MnApplication(const FCNGradientBase &fcn, const MnUserParameterState &state, const MnStrategy &stra,
45-
unsigned int nfcn = 0);
46-
4742
virtual ~MnApplication() {}
4843

4944
/**
@@ -73,7 +68,6 @@ class MnApplication {
7368
MnUserParameterState fState;
7469
MnStrategy fStrategy;
7570
unsigned int fNumCall;
76-
bool fUseGrad;
7771

7872
public:
7973
// facade: forward interface of MnUserParameters and MnUserTransformation

math/minuit2/inc/Minuit2/MnHesse.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class MinimumState;
3030
class MnMachinePrecision;
3131
class MnFcn;
3232
class FunctionMinimum;
33-
class FCNGradientBase;
3433

3534
//_______________________________________________________________________
3635
/**
@@ -97,8 +96,8 @@ class MnHesse {
9796
/// internal function to compute the Hessian using numerical derivative computation
9897
MinimumState ComputeNumerical(const MnFcn &, const MinimumState &, const MnUserTransformation &, unsigned int maxcalls) const;
9998

100-
/// internal function to compute the Hessian using an analytical computation or externally provided in the FCNGradientBase class
101-
MinimumState ComputeAnalytical(const FCNGradientBase &, const MinimumState &, const MnUserTransformation &) const;
99+
/// internal function to compute the Hessian using an analytical computation or externally provided in the FCNBase class
100+
MinimumState ComputeAnalytical(const FCNBase &, const MinimumState &, const MnUserTransformation &) const;
102101

103102
MnStrategy fStrategy;
104103
};

math/minuit2/inc/Minuit2/MnMigrad.h

-42
Original file line numberDiff line numberDiff line change
@@ -70,48 +70,6 @@ class MnMigrad : public MnApplication {
7070
{
7171
}
7272

73-
// constructs from gradient FCN
74-
75-
/// construct from FCNGradientBase + std::vector for parameters and errors
76-
MnMigrad(const FCNGradientBase &fcn, std::span<const double> par, std::span<const double> err,
77-
unsigned int stra = 1)
78-
: MnApplication(fcn, MnUserParameterState(par, err), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer())
79-
{
80-
}
81-
82-
/// construct from FCNGradientBase + std::vector for parameters and covariance
83-
MnMigrad(const FCNGradientBase &fcn, std::span<const double> par, unsigned int nrow,
84-
std::span<const double> cov, unsigned int stra = 1)
85-
: MnApplication(fcn, MnUserParameterState(par, cov, nrow), MnStrategy(stra)),
86-
fMinimizer(VariableMetricMinimizer())
87-
{
88-
}
89-
90-
/// construct from FCNGradientBase + std::vector for parameters and MnUserCovariance
91-
MnMigrad(const FCNGradientBase &fcn, std::span<const double> par, const MnUserCovariance &cov,
92-
unsigned int stra = 1)
93-
: MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer())
94-
{
95-
}
96-
97-
/// construct from FCNGradientBase + MnUserParameters
98-
MnMigrad(const FCNGradientBase &fcn, const MnUserParameters &par, unsigned int stra = 1)
99-
: MnApplication(fcn, MnUserParameterState(par), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer())
100-
{
101-
}
102-
103-
/// construct from FCNGradientBase + MnUserParameters + MnUserCovariance
104-
MnMigrad(const FCNGradientBase &fcn, const MnUserParameters &par, const MnUserCovariance &cov, unsigned int stra = 1)
105-
: MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(VariableMetricMinimizer())
106-
{
107-
}
108-
109-
/// construct from FCNGradientBase + MnUserParameterState + MnStrategy
110-
MnMigrad(const FCNGradientBase &fcn, const MnUserParameterState &par, const MnStrategy &str)
111-
: MnApplication(fcn, MnUserParameterState(par), str), fMinimizer(VariableMetricMinimizer())
112-
{
113-
}
114-
11573
~MnMigrad() override {}
11674

11775
/// Copy constructor, copy shares the reference to the same FCNBase in MnApplication

math/minuit2/inc/Minuit2/MnMinimize.h

-42
Original file line numberDiff line numberDiff line change
@@ -67,48 +67,6 @@ class MnMinimize : public MnApplication {
6767
{
6868
}
6969

70-
// interfaces using FCNGradientBase
71-
72-
/// construct from FCNGradientBase + std::vector for parameters and errors
73-
MnMinimize(const FCNGradientBase &fcn, std::span<const double> par, std::span<const double> err,
74-
unsigned int stra = 1)
75-
: MnApplication(fcn, MnUserParameterState(par, err), MnStrategy(stra)), fMinimizer(CombinedMinimizer())
76-
{
77-
}
78-
79-
/// construct from FCNGradientBase + std::vector for parameters and covariance
80-
MnMinimize(const FCNGradientBase &fcn, std::span<const double> par, unsigned int nrow,
81-
std::span<const double> cov, unsigned int stra = 1)
82-
: MnApplication(fcn, MnUserParameterState(par, cov, nrow), MnStrategy(stra)), fMinimizer(CombinedMinimizer())
83-
{
84-
}
85-
86-
/// construct from FCNGradientBase + std::vector for parameters and MnUserCovariance
87-
MnMinimize(const FCNGradientBase &fcn, std::span<const double> par, const MnUserCovariance &cov,
88-
unsigned int stra = 1)
89-
: MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(CombinedMinimizer())
90-
{
91-
}
92-
93-
/// construct from FCNGradientBase + MnUserParameters
94-
MnMinimize(const FCNGradientBase &fcn, const MnUserParameters &par, unsigned int stra = 1)
95-
: MnApplication(fcn, MnUserParameterState(par), MnStrategy(stra)), fMinimizer(CombinedMinimizer())
96-
{
97-
}
98-
99-
/// construct from FCNGradientBase + MnUserParameters + MnUserCovariance
100-
MnMinimize(const FCNGradientBase &fcn, const MnUserParameters &par, const MnUserCovariance &cov,
101-
unsigned int stra = 1)
102-
: MnApplication(fcn, MnUserParameterState(par, cov), MnStrategy(stra)), fMinimizer(CombinedMinimizer())
103-
{
104-
}
105-
106-
/// construct from FCNGradientBase + MnUserParameterState + MnStrategy
107-
MnMinimize(const FCNGradientBase &fcn, const MnUserParameterState &par, const MnStrategy &str)
108-
: MnApplication(fcn, MnUserParameterState(par), str), fMinimizer(CombinedMinimizer())
109-
{
110-
}
111-
11270
MnMinimize(const MnMinimize &migr)
11371
: MnApplication(migr.Fcnbase(), migr.State(), migr.Strategy(), migr.NumOfCalls()), fMinimizer(migr.fMinimizer)
11472
{

0 commit comments

Comments
 (0)