25
25
#include " RooAbsArg.h"
26
26
#include " RooAbsPdf.h"
27
27
#include " RooArgSet.h"
28
- #include " RooRealVar.h"
29
- #include " RooMsgService.h"
28
+ #include " RooFit/VariableGroups.h"
30
29
#include " RooMinimizer.h"
30
+ #include " RooMsgService.h"
31
31
#include " RooNaNPacker.h"
32
+ #include " RooRealVar.h"
32
33
33
34
#include " Math/Functor.h"
34
35
#include " TMatrixDSym.h"
@@ -40,6 +41,23 @@ using std::setprecision;
40
41
41
42
namespace {
42
43
44
+ template <class InputIt1 , class InputIt2 >
45
+ bool intersect (InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
46
+ {
47
+ while (first1 != last1 && first2 != last2) {
48
+ if (*first1 < *first2) {
49
+ ++first1;
50
+ continue ;
51
+ }
52
+ if (*first2 < *first1) {
53
+ ++first2;
54
+ continue ;
55
+ }
56
+ return true ;
57
+ }
58
+ return false ;
59
+ }
60
+
43
61
// Helper function that wraps RooAbsArg::getParameters and directly returns the
44
62
// output RooArgSet. To be used in the initializer list of the RooMinimizerFcn
45
63
// constructor.
@@ -56,14 +74,38 @@ RooArgSet getParameters(RooAbsReal const &funct)
56
74
RooMinimizerFcn::RooMinimizerFcn (RooAbsReal *funct, RooMinimizer *context)
57
75
: RooAbsMinimizerFcn(getParameters(*funct), context), _funct(funct)
58
76
{
59
- unsigned int nDim = getNDim ();
77
+ RooFit::VariableGroups groups;
78
+ funct->fillVariableGroups (groups);
79
+
80
+ RooArgList parameters;
81
+ for (std::size_t i = 0 ; i < getNDim (); ++i) {
82
+ parameters.add (floatableParam (i));
83
+ }
84
+
85
+ std::size_t nParams = parameters.size ();
86
+
87
+ _secondDerivMask.resize (nParams * nParams);
88
+ for (std::size_t i = 0 ; i < nParams; ++i) {
89
+ _secondDerivMask[nParams * i + i] = 1 ;
90
+ for (std::size_t j = 0 ; j < i; ++j) {
91
+ // std::cout << parameters[i].GetName() << " " << parameters[j].GetName() << std::endl;
92
+ auto const &gr1 = groups.groups .at (parameters[i].namePtr ());
93
+ auto const &gr2 = groups.groups .at (parameters[j].namePtr ());
94
+ _secondDerivMask[nParams * i + j] = intersect (gr1.begin (), gr1.end (), gr2.begin (), gr2.end ());
95
+ _secondDerivMask[nParams * j + i] = _secondDerivMask[nParams * i + j];
96
+ }
97
+ }
60
98
61
99
if (context->_cfg .useGradient && funct->hasGradient ()) {
62
100
_gradientOutput.resize (_allParams.size ());
63
- _multiGenFcn = std::make_unique<ROOT::Math::GradFunctor>(this , &RooMinimizerFcn::operator (),
64
- &RooMinimizerFcn::evaluateGradient, nDim);
101
+ auto functor = std::make_unique<ROOT::Math::GradFunctor>(this , &RooMinimizerFcn::operator (),
102
+ &RooMinimizerFcn::evaluateGradient, getNDim ());
103
+ functor->SetVanishingSecondDerivativeFunc ([this ](int i, int j) { return this ->vanishingSecondDerivative (i, j); });
104
+ _multiGenFcn = std::move (functor);
65
105
} else {
66
- _multiGenFcn = std::make_unique<ROOT::Math::Functor>(std::cref (*this ), getNDim ());
106
+ auto functor = std::make_unique<ROOT::Math::Functor>(std::cref (*this ), getNDim ());
107
+ functor->SetVanishingSecondDerivativeFunc ([this ](int i, int j) { return this ->vanishingSecondDerivative (i, j); });
108
+ _multiGenFcn = std::move (functor);
67
109
}
68
110
}
69
111
@@ -148,4 +190,9 @@ void RooMinimizerFcn::setOffsetting(bool flag)
148
190
_funct->enableOffsetting (flag);
149
191
}
150
192
193
+ bool RooMinimizerFcn::vanishingSecondDerivative (int i, int j) const
194
+ {
195
+ return _secondDerivMask[getNDim () * i + j] == 0 ;
196
+ }
197
+
151
198
// / \endcond
0 commit comments