Skip to content

Commit f001793

Browse files
committed
[Minuit2] Use smart pointers in Minuit2Minimizer
1 parent 95c8544 commit f001793

File tree

2 files changed

+44
-67
lines changed

2 files changed

+44
-67
lines changed

math/minuit2/inc/Minuit2/Minuit2Minimizer.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,13 @@ class Minuit2Minimizer : public ROOT::Math::Minimizer {
279279
/// return the minimizer state (containing values, step size , etc..)
280280
const ROOT::Minuit2::MnUserParameterState &State() { return fState; }
281281

282-
const ROOT::Minuit2::FCNBase *GetFCN() const { return fMinuitFCN; }
283-
ROOT::Minuit2::FCNBase *GetFCN() { return fMinuitFCN; }
282+
const ROOT::Minuit2::FCNBase *GetFCN() const { return fMinuitFCN.get(); }
283+
ROOT::Minuit2::FCNBase *GetFCN() { return fMinuitFCN.get(); }
284284

285285
protected:
286286
// protected function for accessing the internal Minuit2 object. Needed for derived classes
287287

288-
virtual const ROOT::Minuit2::ModularFunctionMinimizer *GetMinimizer() const { return fMinimizer; }
289-
290-
virtual void SetMinimizer(ROOT::Minuit2::ModularFunctionMinimizer *m) { fMinimizer = m; }
288+
virtual const ROOT::Minuit2::ModularFunctionMinimizer *GetMinimizer() const { return fMinimizer.get(); }
291289

292290
void SetMinimizerType(ROOT::Minuit2::EMinimizerType type);
293291

@@ -309,10 +307,9 @@ class Minuit2Minimizer : public ROOT::Math::Minimizer {
309307
int fMinosStatus = -1; // Minos status code
310308

311309
ROOT::Minuit2::MnUserParameterState fState;
312-
// std::vector<ROOT::Minuit2::MinosError> fMinosErrors;
313-
ROOT::Minuit2::ModularFunctionMinimizer *fMinimizer;
314-
ROOT::Minuit2::FCNBase *fMinuitFCN;
315-
ROOT::Minuit2::FunctionMinimum *fMinimum;
310+
std::unique_ptr<ROOT::Minuit2::ModularFunctionMinimizer> fMinimizer;
311+
std::unique_ptr<ROOT::Minuit2::FCNBase> fMinuitFCN;
312+
std::unique_ptr<ROOT::Minuit2::FunctionMinimum> fMinimum;
316313
mutable std::vector<double> fValues;
317314
mutable std::vector<double> fErrors;
318315
};

math/minuit2/src/Minuit2Minimizer.cxx

Lines changed: 38 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,13 @@ int ControlPrintLevel()
8181
void RestoreGlobalPrintLevel(int) {}
8282
#endif
8383

84-
Minuit2Minimizer::Minuit2Minimizer(ROOT::Minuit2::EMinimizerType type)
85-
: fDim(0), fMinimizer(nullptr), fMinuitFCN(nullptr), fMinimum(nullptr)
84+
Minuit2Minimizer::Minuit2Minimizer(ROOT::Minuit2::EMinimizerType type) : fDim(0)
8685
{
8786
// Default constructor implementation depending on minimizer type
8887
SetMinimizerType(type);
8988
}
9089

91-
Minuit2Minimizer::Minuit2Minimizer(const char *type) : fDim(0), fMinimizer(nullptr), fMinuitFCN(nullptr), fMinimum(nullptr)
90+
Minuit2Minimizer::Minuit2Minimizer(const char *type) : fDim(0)
9291
{
9392
// constructor from a string
9493

@@ -116,49 +115,31 @@ void Minuit2Minimizer::SetMinimizerType(ROOT::Minuit2::EMinimizerType type)
116115
// Set minimizer algorithm type
117116
fUseFumili = false;
118117
switch (type) {
119-
case ROOT::Minuit2::kMigrad:
120-
// std::cout << "Minuit2Minimizer: minimize using MIGRAD " << std::endl;
121-
SetMinimizer(new ROOT::Minuit2::VariableMetricMinimizer());
122-
return;
118+
case ROOT::Minuit2::kMigrad: fMinimizer = std::make_unique<ROOT::Minuit2::VariableMetricMinimizer>(); return;
123119
case ROOT::Minuit2::kMigradBFGS:
124-
// std::cout << "Minuit2Minimizer: minimize using MIGRAD " << std::endl;
125-
SetMinimizer(new ROOT::Minuit2::VariableMetricMinimizer(VariableMetricMinimizer::BFGSType()));
126-
return;
127-
case ROOT::Minuit2::kSimplex:
128-
// std::cout << "Minuit2Minimizer: minimize using SIMPLEX " << std::endl;
129-
SetMinimizer(new ROOT::Minuit2::SimplexMinimizer());
120+
fMinimizer = std::make_unique<ROOT::Minuit2::VariableMetricMinimizer>(VariableMetricMinimizer::BFGSType());
130121
return;
131-
case ROOT::Minuit2::kCombined: SetMinimizer(new ROOT::Minuit2::CombinedMinimizer()); return;
132-
case ROOT::Minuit2::kScan: SetMinimizer(new ROOT::Minuit2::ScanMinimizer()); return;
122+
case ROOT::Minuit2::kSimplex: fMinimizer = std::make_unique<ROOT::Minuit2::SimplexMinimizer>(); return;
123+
case ROOT::Minuit2::kCombined: fMinimizer = std::make_unique<ROOT::Minuit2::CombinedMinimizer>(); return;
124+
case ROOT::Minuit2::kScan: fMinimizer = std::make_unique<ROOT::Minuit2::ScanMinimizer>(); return;
133125
case ROOT::Minuit2::kFumili:
134-
SetMinimizer(new ROOT::Minuit2::FumiliMinimizer());
126+
fMinimizer = std::make_unique<ROOT::Minuit2::FumiliMinimizer>();
135127
fUseFumili = true;
136128
return;
137129
default:
138130
// migrad minimizer
139-
SetMinimizer(new ROOT::Minuit2::VariableMetricMinimizer());
131+
fMinimizer = std::make_unique<ROOT::Minuit2::VariableMetricMinimizer>();
140132
}
141133
}
142134

143-
Minuit2Minimizer::~Minuit2Minimizer()
144-
{
145-
// Destructor implementation.
146-
if (fMinimizer)
147-
delete fMinimizer;
148-
if (fMinuitFCN)
149-
delete fMinuitFCN;
150-
if (fMinimum)
151-
delete fMinimum;
152-
}
135+
Minuit2Minimizer::~Minuit2Minimizer() = default;
153136

154137
void Minuit2Minimizer::Clear()
155138
{
156139
// delete the state in case of consecutive minimizations
157140
fState = MnUserParameterState();
158141
// clear also the function minimum
159-
if (fMinimum)
160-
delete fMinimum;
161-
fMinimum = nullptr;
142+
fMinimum.reset();
162143
}
163144

164145
// set variables
@@ -389,47 +370,48 @@ bool Minuit2Minimizer::GetVariableSettings(unsigned int ivar, ROOT::Fit::Paramet
389370
void Minuit2Minimizer::SetFunction(const ROOT::Math::IMultiGenFunction &func)
390371
{
391372
// set function to be minimized
392-
if (fMinuitFCN)
393-
delete fMinuitFCN;
373+
fMinuitFCN.reset();
394374
fDim = func.NDim();
395375
const bool hasGrad = func.HasGradient();
396376
if (!fUseFumili) {
397377
auto lambdaFunc = [&func](double const *params) { return func(params); };
398-
auto adapter = new ROOT::Minuit2::FCNAdapter(lambdaFunc, ErrorDef());
378+
auto adapter = std::make_unique<ROOT::Minuit2::FCNAdapter>(lambdaFunc, ErrorDef());
399379
if (hasGrad) {
400380
auto const &gradFunc = dynamic_cast<ROOT::Math::IMultiGradFunction const &>(func);
401381
auto lambdaGrad = [&gradFunc](double const *params, double *grad) { return gradFunc.Gradient(params, grad); };
402382
adapter->SetGradientFunction(lambdaGrad);
403383
}
404-
fMinuitFCN = adapter;
384+
fMinuitFCN = std::move(adapter);
385+
return;
386+
}
387+
if (hasGrad) {
388+
// for Fumili the fit method function interface is required
389+
auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodGradFunction *>(&func);
390+
if (!fcnfunc) {
391+
MnPrint print("Minuit2Minimizer", PrintLevel());
392+
print.Error("Wrong Fit method function for Fumili");
393+
return;
394+
}
395+
fMinuitFCN = std::make_unique<ROOT::Minuit2::FumiliFCNAdapter<ROOT::Math::FitMethodGradFunction>>(*fcnfunc, fDim,
396+
ErrorDef());
405397
} else {
406-
if(hasGrad) {
407-
// for Fumili the fit method function interface is required
408-
auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodGradFunction *>(&func);
409-
if (!fcnfunc) {
410-
MnPrint print("Minuit2Minimizer", PrintLevel());
411-
print.Error("Wrong Fit method function for Fumili");
412-
return;
413-
}
414-
fMinuitFCN = new ROOT::Minuit2::FumiliFCNAdapter<ROOT::Math::FitMethodGradFunction>(*fcnfunc, fDim, ErrorDef());
415-
} else {
416-
// for Fumili the fit method function interface is required
417-
auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodFunction *>(&func);
418-
if (!fcnfunc) {
419-
MnPrint print("Minuit2Minimizer", PrintLevel());
420-
print.Error("Wrong Fit method function for Fumili");
421-
return;
422-
}
423-
fMinuitFCN = new ROOT::Minuit2::FumiliFCNAdapter<ROOT::Math::FitMethodFunction>(*fcnfunc, fDim, ErrorDef());
398+
// for Fumili the fit method function interface is required
399+
auto fcnfunc = dynamic_cast<const ROOT::Math::FitMethodFunction *>(&func);
400+
if (!fcnfunc) {
401+
MnPrint print("Minuit2Minimizer", PrintLevel());
402+
print.Error("Wrong Fit method function for Fumili");
403+
return;
424404
}
405+
fMinuitFCN =
406+
std::make_unique<ROOT::Minuit2::FumiliFCNAdapter<ROOT::Math::FitMethodFunction>>(*fcnfunc, fDim, ErrorDef());
425407
}
426408
}
427409

428410
void Minuit2Minimizer::SetHessianFunction(std::function<bool(std::span<const double>, double *)> hfunc)
429411
{
430412
// for Fumili not supported for the time being
431413
if (fUseFumili) return;
432-
auto fcn = static_cast<ROOT::Minuit2::FCNAdapter *>(fMinuitFCN);
414+
auto fcn = static_cast<ROOT::Minuit2::FCNAdapter *>(fMinuitFCN.get());
433415
if (!fcn) return;
434416
fcn->SetHessianFunction(hfunc);
435417
}
@@ -487,9 +469,7 @@ bool Minuit2Minimizer::Minimize()
487469
assert(GetMinimizer() != nullptr);
488470

489471
// delete result of previous minimization
490-
if (fMinimum)
491-
delete fMinimum;
492-
fMinimum = nullptr;
472+
fMinimum.reset();
493473

494474
const int maxfcn = MaxFunctionCalls();
495475
const double tol = Tolerance();
@@ -537,7 +517,7 @@ bool Minuit2Minimizer::Minimize()
537517
std::string fumiliMethod;
538518
ret = minuit2Opt->GetValue("FumiliMethod", fumiliMethod);
539519
if (ret) {
540-
auto fumiliMinimizer = dynamic_cast<ROOT::Minuit2::FumiliMinimizer*>(fMinimizer);
520+
auto fumiliMinimizer = dynamic_cast<ROOT::Minuit2::FumiliMinimizer *>(fMinimizer.get());
541521
if (fumiliMinimizer)
542522
fumiliMinimizer->SetMethod(fumiliMethod);
543523
}
@@ -584,7 +564,7 @@ bool Minuit2Minimizer::Minimize()
584564
const ROOT::Minuit2::MnStrategy strategy = customizedStrategy(strategyLevel, fOptions);
585565

586566
ROOT::Minuit2::FunctionMinimum min = GetMinimizer()->Minimize(*fMinuitFCN, fState, strategy, maxfcn, tol);
587-
fMinimum = new ROOT::Minuit2::FunctionMinimum(min);
567+
fMinimum = std::make_unique<ROOT::Minuit2::FunctionMinimum>(min);
588568

589569
// check if Hesse needs to be run. We do it when is requested (IsValidError() == true , set by SetParabError(true) in fitConfig)
590570
// (IsValidError() means the flag to get correct error from the Minimizer is set (Minimizer::SetValidError())

0 commit comments

Comments
 (0)