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