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,11 +72,34 @@ RooArgSet getParameters(RooAbsReal const &funct)
54
72
RooMinimizerFcn::RooMinimizerFcn (RooAbsReal *funct, RooMinimizer *context)
55
73
: RooAbsMinimizerFcn(getParameters(*funct), context), _funct(funct)
56
74
{
75
+ RooFit::VariableGroups groups;
76
+ funct->fillVariableGroups (groups);
77
+
78
+ RooArgList const ¶meters = *GetFloatParamList ();
79
+
80
+ std::size_t nParams = parameters.size ();
81
+
82
+ _secondDerivMask.resize (nParams * nParams);
83
+ for (std::size_t i = 0 ; i < nParams; ++i) {
84
+ _secondDerivMask[nParams * i + i] = 1 ;
85
+ for (std::size_t j = 0 ; j < i; ++j) {
86
+ // std::cout << parameters[i].GetName() << " " << parameters[j].GetName() << std::endl;
87
+ auto const &gr1 = groups.groups .at (parameters[i].namePtr ());
88
+ auto const &gr2 = groups.groups .at (parameters[j].namePtr ());
89
+ _secondDerivMask[nParams * i + j] = intersect (gr1.begin (), gr1.end (), gr2.begin (), gr2.end ());
90
+ _secondDerivMask[nParams * j + i] = _secondDerivMask[nParams * i + j];
91
+ }
92
+ }
93
+
57
94
if (context->_cfg .useGradient && funct->hasGradient ()) {
58
- _multiGenFcn = std::make_unique<ROOT::Math::GradFunctor>(this , &RooMinimizerFcn::operator (),
95
+ auto functor = std::make_unique<ROOT::Math::GradFunctor>(this , &RooMinimizerFcn::operator (),
59
96
&RooMinimizerFcn::evaluateGradient, getNDim ());
97
+ functor->SetVanishingSecondDerivativeFunc ([this ](int i, int j) { return this ->vanishingSecondDerivative (i, j); });
98
+ _multiGenFcn = std::move (functor);
60
99
} else {
61
- _multiGenFcn = std::make_unique<ROOT::Math::Functor>(std::cref (*this ), getNDim ());
100
+ auto functor = std::make_unique<ROOT::Math::Functor>(std::cref (*this ), getNDim ());
101
+ functor->SetVanishingSecondDerivativeFunc ([this ](int i, int j) { return this ->vanishingSecondDerivative (i, j); });
102
+ _multiGenFcn = std::move (functor);
62
103
}
63
104
}
64
105
@@ -132,3 +173,8 @@ void RooMinimizerFcn::setOffsetting(bool flag)
132
173
{
133
174
_funct->enableOffsetting (flag);
134
175
}
176
+
177
+ bool RooMinimizerFcn::vanishingSecondDerivative (int i, int j) const
178
+ {
179
+ return _secondDerivMask[_nDim * i + j] == 0 ;
180
+ }
0 commit comments