1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2024-11-10 00:45:36 +00:00

Minimizer: limits interface

This commit is contained in:
Antonin Portelli 2014-10-14 16:34:27 +01:00
parent bf3fe8bd13
commit 9e6bbd95c3
11 changed files with 207 additions and 29 deletions

View File

@ -28,6 +28,11 @@ using namespace Latan;
/******************************************************************************
* GslHybridRootFinder implementation *
******************************************************************************/
// constructor /////////////////////////////////////////////////////////////////
GslHybridRootFinder::GslHybridRootFinder(const Index dim)
: RootFinder(dim)
{}
// output //////////////////////////////////////////////////////////////////////
void GslHybridRootFinder::printState(void)
{

View File

@ -34,7 +34,7 @@ class GslHybridRootFinder: public RootFinder
{
public:
// constructor
GslHybridRootFinder(void) = default;
explicit GslHybridRootFinder(const Index dim);
// destructor
virtual ~GslHybridRootFinder(void) = default;
// solver

View File

@ -46,9 +46,11 @@ libLatAnalyze_la_SOURCES = \
MathParser.ypp \
MathLexer.lpp \
MatSample.cpp \
Minimizer.cpp \
Model.cpp \
Plot.cpp \
RandGen.cpp \
RootFinder.cpp \
Solver.cpp \
TabFunction.cpp \
XmlReader.cpp \

View File

@ -23,36 +23,133 @@
using namespace std;
using namespace Latan;
/******************************************************************************
* Minimizer implementation *
******************************************************************************/
// constructor /////////////////////////////////////////////////////////////////
Minimizer::Minimizer(Verbosity verbosity)
: verbosity_(verbosity)
{}
// access //////////////////////////////////////////////////////////////////////
Index Minimizer::getDim(void) const
Minimizer::Minimizer(const Index dim)
: Solver(dim)
, highLimit_(dim)
, lowLimit_(dim)
, hasHighLimit_(dim)
, hasLowLimit_(dim)
{
return x_.size();
highLimit_.fill(0.);
lowLimit_.fill(0.);
hasHighLimit_.fill(false);
hasLowLimit_.fill(false);
}
DVec & Minimizer::getState(void)
// limits //////////////////////////////////////////////////////////////////////
double Minimizer::getHighLimit(const Index i) const
{
return x_;
return highLimit_(i);
}
Minimizer::Verbosity Minimizer::getVerbosity(void) const
const DVec & Minimizer::getHighLimit(const PlaceHolder ph __unused) const
{
return verbosity_;
return highLimit_;
}
void Minimizer::setInit(const DVec &x0)
double Minimizer::getLowLimit(const Index i) const
{
x_ = x0;
return lowLimit_(i);
}
void Minimizer::setVerbosity(const Verbosity verbosity)
const DVec & Minimizer::getLowLimit(const PlaceHolder ph __unused) const
{
verbosity_ = verbosity;
return lowLimit_;
}
bool Minimizer::hasHighLimit(const Index i) const
{
return hasHighLimit_(i);
}
bool Minimizer::hasLowLimit(const Index i) const
{
return hasLowLimit_(i);
}
void Minimizer::setHighLimit(const Index i, const double l)
{
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid limit index");
}
else
{
highLimit_(i) = l;
useHighLimit(i);
}
}
void Minimizer::setHighLimit(const PlaceHolder ph __unused, const DVec &l)
{
if (l.size() != getDim())
{
LATAN_ERROR(Size, "invalid limit vector size");
}
else
{
highLimit_ = l;
useHighLimit(_);
}
}
void Minimizer::setLowLimit(const Index i, const double l)
{
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid limit index");
}
else
{
lowLimit_(i) = l;
useLowLimit(i);
}
}
void Minimizer::setLowLimit(const PlaceHolder ph __unused, const DVec &l)
{
if (l.size() != getDim())
{
LATAN_ERROR(Size, "invalid limit vector size");
}
else
{
lowLimit_ = l;
useLowLimit(_);
}
}
void Minimizer::useHighLimit(const Index i, const bool use)
{
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid limit index");
}
else
{
hasHighLimit_(i) = use;
}
}
void Minimizer::useHighLimit(const PlaceHolder ph __unused, const bool use)
{
hasHighLimit_.fill(use);
}
void Minimizer::useLowLimit(const Index i, const bool use)
{
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid limit index");
}
else
{
hasLowLimit_(i) = use;
}
}
void Minimizer::useLowLimit(const PlaceHolder ph __unused, const bool use)
{
hasLowLimit_.fill(use);
}

View File

@ -35,11 +35,31 @@ class Minimizer: public Solver
{
public:
// constructor
Minimizer(void) = default;
explicit Minimizer(const Index dim);
// destructor
virtual ~Minimizer(void) = default;
// limits
virtual double getHighLimit(const Index i) const ;
virtual const DVec & getHighLimit(const PlaceHolder ph = _) const;
virtual double getLowLimit(const Index i) const;
virtual const DVec & getLowLimit(const PlaceHolder ph = _) const;
virtual bool hasHighLimit(const Index i) const;
virtual bool hasLowLimit(const Index i) const;
virtual void setHighLimit(const Index i, const double l);
virtual void setHighLimit(const PlaceHolder ph, const DVec &l);
virtual void setLowLimit(const Index i, const double l);
virtual void setLowLimit(const PlaceHolder ph, const DVec &l);
virtual void useHighLimit(const Index i, const bool use = true);
virtual void useHighLimit(const PlaceHolder ph = _,
const bool use = true);
virtual void useLowLimit(const Index i, const bool use = true);
virtual void useLowLimit(const PlaceHolder ph = _,
const bool use = true);
// minimization
virtual const DVec & operator()(const DoubleFunction &f) = 0;
private:
DVec highLimit_, lowLimit_;
Vec<bool> hasHighLimit_, hasLowLimit_;
};
END_NAMESPACE

View File

@ -35,7 +35,7 @@ using namespace ROOT;
using namespace Minuit2;
using namespace Latan;
static constexpr double initErr = 0.5;
static constexpr double initErr = 5.0;
static constexpr unsigned int maxTry = 10u;
/******************************************************************************
@ -58,6 +58,11 @@ double MinuitMinimizer::MinuitFunction::Up(void) const
return 1.;
}
// constructor /////////////////////////////////////////////////////////////////
MinuitMinimizer::MinuitMinimizer(const Index dim)
: Minimizer(dim)
{}
// access //////////////////////////////////////////////////////////////////////
double MinuitMinimizer::getPrecision(void) const
{
@ -81,7 +86,7 @@ const DVec & MinuitMinimizer::operator()(const DoubleFunction &f)
if (f.getNArg() != x.size())
{
x.conservativeResize(f.getNArg());
LATAN_ERROR(Size, "function to minimize number of arguments mismatch");
}
// set parameters
@ -91,10 +96,20 @@ const DVec & MinuitMinimizer::operator()(const DoubleFunction &f)
for (Index i = 0; i < x.size(); ++i)
{
parameters.Add("x_" + strFrom(i), x(i), initErr*fabs(x(i)));
if (hasLowLimit(i))
{
parameters.SetLowerLimit(static_cast<unsigned int>(i),
getLowLimit(i));
}
if (hasHighLimit(i))
{
parameters.SetUpperLimit(static_cast<unsigned int>(i),
getHighLimit(i));
}
}
// pre-minimization
MnSimplex preMinimizer(minuitF, parameters, 0);
MnSimplex preMinimizer(minuitF, parameters, 2);
FunctionMinimum min = preMinimizer();
if (verbosity >= Verbosity::Debug)
@ -110,6 +125,7 @@ const DVec & MinuitMinimizer::operator()(const DoubleFunction &f)
MnMigrad minimizer(minuitF, parameters, 2);
unsigned int iTry = 0;
while ((!min.IsValid())&&(iTry < maxTry))
{
min = minimizer();

View File

@ -49,7 +49,7 @@ private:
};
public:
// constructor
MinuitMinimizer(void) = default;
explicit MinuitMinimizer(const Index dim);
// destructor
virtual ~MinuitMinimizer(void) = default;
// access

29
lib/RootFinder.cpp Normal file
View File

@ -0,0 +1,29 @@
/*
* RootFinder.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/>.
*/
#include <LatAnalyze/RootFinder.hpp>
#include <LatAnalyze/includes.hpp>
using namespace std;
using namespace Latan;
// constructor /////////////////////////////////////////////////////////////////
RootFinder::RootFinder(const Index dim)
: Solver(dim)
{}

View File

@ -34,7 +34,7 @@ class RootFinder: public Solver
{
public:
// constructor
RootFinder(void) = default;
explicit RootFinder(const Index dim);
// destructor
virtual ~RootFinder(void) = default;
// solver

View File

@ -27,7 +27,9 @@ using namespace Latan;
* Solver implementation *
******************************************************************************/
// constructor /////////////////////////////////////////////////////////////////
Solver::Solver(const double precision, const unsigned int maxIteration)
Solver::Solver(const Index dim, const double precision,
const unsigned int maxIteration)
: x_(dim)
{
setMaxIteration(maxIteration);
setPrecision(precision);
@ -61,7 +63,14 @@ Solver::Verbosity Solver::getVerbosity(void) const
void Solver::setInit(const DVec &x0)
{
x_ = x0;
if (x0.size() != x_.size())
{
LATAN_ERROR(Size, "initial vector state with invalid size");
}
else
{
x_ = x0;
}
}
void Solver::setMaxIteration(const unsigned int maxIteration)

View File

@ -42,8 +42,8 @@ public:
};
public:
// constructor
Solver(const double precision = defaultPrec,
const unsigned int maxIteration = defaultMaxIteration);
explicit Solver(const Index dim, const double precision = defaultPrec,
const unsigned int maxIteration = defaultMaxIteration);
// destructor
virtual ~Solver(void) = default;
// access