|
17 | 17 | #include "RooAbsPdf.h"
|
18 | 18 | #include "RooNaNPacker.h"
|
19 | 19 |
|
| 20 | +#include <Minuit2/Minuit2Minimizer.h> |
| 21 | +#include <Minuit2/FCNAdapter.h> |
| 22 | + |
20 | 23 | #include <iomanip> // std::setprecision
|
21 | 24 |
|
22 | 25 | namespace RooFit {
|
23 | 26 | namespace TestStatistics {
|
24 | 27 |
|
25 |
| -namespace { |
26 |
| - |
27 |
| -class MinuitGradFunctor : public ROOT::Math::IMultiGradFunction { |
28 |
| - |
29 |
| -public: |
30 |
| - MinuitGradFunctor(MinuitFcnGrad const &fcn) : _fcn{fcn} {} |
31 |
| - |
32 |
| - ROOT::Math::IMultiGradFunction *Clone() const override { return new MinuitGradFunctor(_fcn); } |
33 |
| - |
34 |
| - unsigned int NDim() const override { return _fcn.getNDim(); } |
35 |
| - |
36 |
| - void Gradient(const double *x, double *grad) const override { return _fcn.Gradient(x, grad); } |
37 |
| - |
38 |
| -private: |
39 |
| - double DoEval(const double *x) const override { return _fcn(x); } |
40 |
| - |
41 |
| - double DoDerivative(double const * /*x*/, unsigned int /*icoord*/) const override |
42 |
| - { |
43 |
| - throw std::runtime_error("MinuitGradFunctor::DoDerivative is not implemented, please use Gradient instead."); |
44 |
| - } |
45 |
| - |
46 |
| - MinuitFcnGrad const &_fcn; |
47 |
| -}; |
48 |
| - |
49 |
| -} // namespace |
50 |
| - |
51 | 28 | /** \class MinuitFcnGrad
|
52 | 29 | *
|
53 | 30 | * \brief Minuit-RooMinimizer interface which synchronizes parameter data and coordinates evaluation of likelihood
|
@@ -75,10 +52,7 @@ class MinuitGradFunctor : public ROOT::Math::IMultiGradFunction {
|
75 | 52 | MinuitFcnGrad::MinuitFcnGrad(const std::shared_ptr<RooFit::TestStatistics::RooAbsL> &absL, RooMinimizer *context,
|
76 | 53 | std::vector<ROOT::Fit::ParameterSettings> ¶meters, LikelihoodMode likelihoodMode,
|
77 | 54 | LikelihoodGradientMode likelihoodGradientMode)
|
78 |
| - : RooAbsMinimizerFcn(*absL->getParameters(), context), |
79 |
| - _minuitInternalX(getNDim(), 0), |
80 |
| - _minuitExternalX(getNDim(), 0), |
81 |
| - _multiGenFcn{std::make_unique<MinuitGradFunctor>(*this)} |
| 55 | + : RooAbsMinimizerFcn(*absL->getParameters(), context), _minuitInternalX(getNDim(), 0), _minuitExternalX(getNDim(), 0) |
82 | 56 | {
|
83 | 57 | synchronizeParameterSettings(parameters, true);
|
84 | 58 |
|
@@ -266,5 +240,22 @@ bool MinuitFcnGrad::Synchronize(std::vector<ROOT::Fit::ParameterSettings> ¶m
|
266 | 240 | return returnee;
|
267 | 241 | }
|
268 | 242 |
|
| 243 | +void MinuitFcnGrad::initMinimizer(ROOT::Math::Minimizer &minim) |
| 244 | +{ |
| 245 | + auto &rooFcn = *this; |
| 246 | + auto adapter = std::make_unique<ROOT::Minuit2::FCNAdapter>( |
| 247 | + [&rooFcn](double const *params) { return rooFcn(params); }, minim.ErrorDef()); |
| 248 | + adapter->SetGradientFunction( |
| 249 | + [&rooFcn](double const *params, double *grad) { return rooFcn.Gradient(params, grad); }); |
| 250 | + adapter->SetGradWithPrevResultFunction([&rooFcn](const double *params, double *grad, double *previous_grad, |
| 251 | + double *previous_g2, double *previous_gstep) { |
| 252 | + rooFcn.GradientWithPrevResult(params, grad, previous_grad, previous_g2, previous_gstep); |
| 253 | + }); |
| 254 | + adapter->SetReturnsInMinuit2ParameterSpace(rooFcn.returnsInMinuit2ParameterSpace()); |
| 255 | + |
| 256 | + auto &minuit = dynamic_cast<ROOT::Minuit2::Minuit2Minimizer &>(minim); |
| 257 | + minuit.SetFCN(getNDim(), std::move(adapter)); |
| 258 | +} |
| 259 | + |
269 | 260 | } // namespace TestStatistics
|
270 | 261 | } // namespace RooFit
|
0 commit comments