/*
* MinuitMinimizer.cpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2014 Antonin Portelli
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace ROOT;
using namespace Minuit2;
using namespace Latan;
/******************************************************************************
* MinuitMinimizer implementation *
******************************************************************************/
// MinuitFunction constructor //////////////////////////////////////////////////
MinuitMinimizer::MinuitFunction::MinuitFunction(const DoubleFunction &f)
: f_(&f)
{}
// MinuitFunction minuit members ///////////////////////////////////////////////
double MinuitMinimizer::MinuitFunction::operator()
(const vector &x) const
{
return (*f_)(x);
}
double MinuitMinimizer::MinuitFunction::Up(void) const
{
return 1.;
}
// minimization ////////////////////////////////////////////////////////////////
const DVec & MinuitMinimizer::operator()(const DoubleFunction &f)
{
DVec &x = getState();
Verbosity verbosity = getVerbosity();
if (f.getNArg() != x.size())
{
x.conservativeResize(f.getNArg());
}
// set parameters
MinuitFunction minuitF(f);
MnUserParameters parameters;
for (Index i = 0; i < x.size(); ++i)
{
parameters.Add("x_" + strFrom(i), x(i), 0.1*fabs(x(i)));
}
// pre-minimization
MnMigrad migrad1(minuitF, parameters, 1);
FunctionMinimum min = migrad1();
if (verbosity >= Verbosity::Debug)
{
cout << "-- MINUIT pre-minimization -----------------------------";
cout << min;
cout << "--------------------------------------------------------";
cout << endl;
}
for (unsigned int i = 0; i < x.size(); ++i)
{
parameters.SetValue(i, min.UserParameters().Value(i));
parameters.SetError(i, min.UserParameters().Error(i));
}
// minimization and output
MnMigrad migrad2(minuitF, parameters, 2);
min = migrad2();
if (!min.IsValid())
{
LATAN_WARNING("MINUIT library reported that minimization result is not valid");
}
for (unsigned int i = 0; i < x.size(); ++i)
{
x(i) = min.UserParameters().Value(i);
}
if (verbosity >= Verbosity::Normal)
{
cout << "-- MINUIT minimization ---------------------------------";
cout << min;
cout << "--------------------------------------------------------";
cout << endl;
}
if (verbosity >= Verbosity::Debug)
{
vector> scanRes;
MnPlot plot;
MnScan scanner(minuitF, min.UserParameters(), 2);
cout << "-- MINUIT scan -----------------------------------------";
cout << endl;
for (unsigned int i = 0; i < x.size(); i++)
{
cout << "Parameter x_" << i << endl;
scanRes = scanner.Scan(i);
plot(scanRes);
}
cout << "--------------------------------------------------------";
cout << endl;
}
return x;
}