2014-02-20 20:21:45 +00:00
|
|
|
/*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2014-03-13 18:51:01 +00:00
|
|
|
#include <LatAnalyze/MinuitMinimizer.hpp>
|
|
|
|
#include <LatAnalyze/includes.hpp>
|
2014-02-20 20:21:45 +00:00
|
|
|
#include <Minuit2/FCNBase.h>
|
|
|
|
#include <Minuit2/FunctionMinimum.h>
|
|
|
|
#include <Minuit2/MnMigrad.h>
|
|
|
|
#include <Minuit2/MnPrint.h>
|
|
|
|
#include <Minuit2/MnPlot.h>
|
|
|
|
#include <Minuit2/MnScan.h>
|
|
|
|
#include <Minuit2/ScanMinimizer.h>
|
|
|
|
#include <Minuit2/SimplexMinimizer.h>
|
|
|
|
#include <Minuit2/VariableMetricMinimizer.h>
|
|
|
|
|
|
|
|
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<double> &x) const
|
|
|
|
{
|
2014-02-21 01:18:22 +00:00
|
|
|
return (*f_)(x);
|
2014-02-20 20:21:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2014-03-03 12:41:48 +00:00
|
|
|
MinuitFunction minuitF(f);
|
2014-02-20 20:21:45 +00:00
|
|
|
MnUserParameters parameters;
|
|
|
|
|
2014-02-26 18:36:29 +00:00
|
|
|
for (Index i = 0; i < x.size(); ++i)
|
2014-02-20 20:21:45 +00:00
|
|
|
{
|
|
|
|
parameters.Add("x_" + strFrom(i), x(i), 0.1*fabs(x(i)));
|
|
|
|
}
|
|
|
|
|
|
|
|
// pre-minimization
|
2014-03-03 12:41:48 +00:00
|
|
|
MnMigrad migrad1(minuitF, parameters, 1);
|
|
|
|
FunctionMinimum min = migrad1();
|
2014-02-20 20:21:45 +00:00
|
|
|
|
|
|
|
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
|
2014-03-03 12:41:48 +00:00
|
|
|
MnMigrad migrad2(minuitF, parameters, 2);
|
2014-02-20 20:21:45 +00:00
|
|
|
|
|
|
|
min = migrad2();
|
2014-04-03 09:04:59 +01:00
|
|
|
if (!min.IsValid())
|
|
|
|
{
|
|
|
|
LATAN_WARNING("MINUIT library reported that minimization result is not valid");
|
|
|
|
}
|
2014-02-20 20:21:45 +00:00
|
|
|
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<pair<double, double>> 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;
|
|
|
|
}
|