|
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