#ifndef ROOT_Math_Minimizer
#define ROOT_Math_Minimizer
#ifndef ROOT_Math_IFunction
#include "Math/IFunction.h"
#endif
#ifndef ROOT_Math_MinimizerOptions
#include "Math/MinimizerOptions.h"
#endif
#ifndef ROOT_Math_Util
#include "Math/Util.h"
#endif
#ifndef ROOT_Math_Error
#include "Math/Error.h"
#endif
#include <vector>
#include <string>
#include <limits>
#include <cmath>
namespace ROOT {
namespace Fit {
class ParameterSettings;
}
namespace Math {
class Minimizer {
public:
Minimizer () :
fValidError(false),
fDebug(MinimizerOptions::DefaultPrintLevel()),
fStrategy(MinimizerOptions::DefaultStrategy()),
fStatus(-1),
fMaxCalls(MinimizerOptions::DefaultMaxFunctionCalls()),
fMaxIter(MinimizerOptions::DefaultMaxIterations()),
fTol(MinimizerOptions::DefaultTolerance()),
fPrec(MinimizerOptions::DefaultPrecision()),
fUp(MinimizerOptions::DefaultErrorDef() )
{}
virtual ~Minimizer () {}
private:
Minimizer(const Minimizer &) {}
Minimizer & operator = (const Minimizer & rhs) {
if (this == &rhs) return *this;
return *this;
}
public:
virtual void Clear() {}
virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func) = 0;
virtual void SetFunction(const ROOT::Math::IMultiGradFunction & func)
{
SetFunction(static_cast<const ::ROOT::Math::IMultiGenFunction &> (func));
}
template<class VariableIterator>
int SetVariables(const VariableIterator & begin, const VariableIterator & end) {
unsigned int ivar = 0;
for ( VariableIterator vitr = begin; vitr != end; ++vitr) {
bool iret = false;
if (vitr->IsFixed() )
iret = SetFixedVariable(ivar, vitr->Name(), vitr->Value() );
else if (vitr->IsDoubleBound() )
iret = SetLimitedVariable(ivar, vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->LowerLimit(), vitr->UpperLimit() );
else if (vitr->HasLowerLimit() )
iret = SetLowerLimitedVariable(ivar, vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->LowerLimit() );
else if (vitr->HasUpperLimit() )
iret = SetUpperLimitedVariable(ivar, vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->UpperLimit() );
else
iret = SetVariable( ivar, vitr->Name(), vitr->Value(), vitr->StepSize() );
if (iret) ivar++;
}
return ivar;
}
virtual bool SetVariable(unsigned int ivar, const std::string & name, double val, double step) = 0;
virtual bool SetLowerLimitedVariable(unsigned int ivar , const std::string & name , double val , double step , double lower ) {
return SetLimitedVariable(ivar, name, val, step, lower, std::numeric_limits<double>::infinity() );
}
virtual bool SetUpperLimitedVariable(unsigned int ivar , const std::string & name , double val , double step , double upper ) {
return SetLimitedVariable(ivar, name, val, step, - std::numeric_limits<double>::infinity(), upper );
}
virtual bool SetLimitedVariable(unsigned int ivar , const std::string & name , double val , double step ,
double lower , double upper ) {
MATH_WARN_MSG("Minimizer::SetLimitedVariable","Setting of limited variable not implemented - set as unlimited");
MATH_UNUSED(lower); MATH_UNUSED(upper);
return SetVariable(ivar, name, val, step);
}
virtual bool SetFixedVariable(unsigned int ivar , const std::string & name , double val ) {
MATH_ERROR_MSG("Minimizer::SetFixedVariable","Setting of fixed variable not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(name); MATH_UNUSED(val);
return false;
}
virtual bool SetVariableValue(unsigned int ivar , double value) {
MATH_ERROR_MSG("Minimizer::SetVariableValue","Set of a variable value not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(value);
return false;
}
virtual bool SetVariableValues(const double * x) {
bool ret = true;
unsigned int i = 0;
while ( i <= NDim() && ret) {
ret &= SetVariableValue(i,x[i] ); i++;
}
return ret;
}
virtual bool SetVariableStepSize(unsigned int ivar, double value ) {
MATH_ERROR_MSG("Minimizer::SetVariableStepSize","Setting an existing variable step size not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(value);
return false;
}
virtual bool SetVariableLowerLimit(unsigned int ivar, double lower) {
MATH_ERROR_MSG("Minimizer::SetVariableLowerLimit","Setting an existing variable limit not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(lower);
return false;
}
virtual bool SetVariableUpperLimit(unsigned int ivar, double upper) {
MATH_ERROR_MSG("Minimizer::SetVariableUpperLimit","Setting an existing variable limit not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(upper);
return false;
}
virtual bool SetVariableLimits(unsigned int ivar, double lower, double upper) {
return SetVariableLowerLimit(ivar,lower) && SetVariableUpperLimit(ivar,upper);
}
virtual bool FixVariable(unsigned int ivar) {
MATH_ERROR_MSG("Minimizer::FixVariable","Fixing an existing variable not implemented");
MATH_UNUSED(ivar);
return false;
}
virtual bool ReleaseVariable(unsigned int ivar) {
MATH_ERROR_MSG("Minimizer::ReleaseVariable","Releasing an existing variable not implemented");
MATH_UNUSED(ivar);
return false;
}
virtual bool IsFixedVariable(unsigned int ivar) const {
MATH_ERROR_MSG("Minimizer::IsFixedVariable","Quering an existing variable not implemented");
MATH_UNUSED(ivar);
return false;
}
virtual bool GetVariableSettings(unsigned int ivar, ROOT::Fit::ParameterSettings & pars) const {
MATH_ERROR_MSG("Minimizer::GetVariableSettings","Quering an existing variable not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(pars);
return false;
}
virtual bool SetVariableInitialRange(unsigned int , double , double ) {
return false;
}
virtual bool Minimize() = 0;
virtual double MinValue() const = 0;
virtual const double * X() const = 0;
virtual double Edm() const { return -1; }
virtual const double * MinGradient() const { return NULL; }
virtual unsigned int NCalls() const { return 0; }
virtual unsigned int NIterations() const { return NCalls(); }
virtual unsigned int NDim() const = 0;
virtual unsigned int NFree() const { return NDim(); }
virtual bool ProvidesError() const { return false; }
virtual const double * Errors() const { return NULL; }
virtual double CovMatrix(unsigned int ivar , unsigned int jvar ) const {
MATH_UNUSED(ivar); MATH_UNUSED(jvar);
return 0;
}
virtual bool GetCovMatrix(double * covMat) const {
MATH_UNUSED(covMat);
return false;
}
virtual bool GetHessianMatrix(double * hMat) const {
MATH_UNUSED(hMat);
return false;
}
virtual int CovMatrixStatus() const {
return 0;
}
virtual double Correlation(unsigned int i, unsigned int j ) const {
double tmp = CovMatrix(i,i) * CovMatrix(j,j);
return ( tmp < 0) ? 0 : CovMatrix(i,j) / std::sqrt( tmp );
}
virtual double GlobalCC(unsigned int ivar) const {
MATH_UNUSED(ivar);
return -1;
}
virtual bool GetMinosError(unsigned int ivar , double & errLow, double & errUp, int option = 0) {
MATH_ERROR_MSG("Minimizer::GetMinosError","Minos Error not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(errLow); MATH_UNUSED(errUp); MATH_UNUSED(option);
return false;
}
virtual bool Hesse() {
MATH_ERROR_MSG("Minimizer::Hesse","Hesse not implemented");
return false;
}
virtual bool Scan(unsigned int ivar , unsigned int & nstep , double * x , double * y ,
double xmin = 0, double xmax = 0) {
MATH_ERROR_MSG("Minimizer::Scan","Scan not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(nstep); MATH_UNUSED(x); MATH_UNUSED(y);
MATH_UNUSED(xmin); MATH_UNUSED(xmax);
return false;
}
virtual bool Contour(unsigned int ivar , unsigned int jvar, unsigned int & npoints,
double * xi , double * xj ) {
MATH_ERROR_MSG("Minimizer::Contour","Contour not implemented");
MATH_UNUSED(ivar); MATH_UNUSED(jvar); MATH_UNUSED(npoints);
MATH_UNUSED(xi); MATH_UNUSED(xj);
return false;
}
virtual void PrintResults() {}
virtual std::string VariableName(unsigned int ivar) const {
MATH_UNUSED(ivar);
return std::string();
}
virtual int VariableIndex(const std::string & name) const {
MATH_ERROR_MSG("Minimizer::VariableIndex","Getting variable index from name not implemented");
MATH_UNUSED(name);
return -1;
}
int PrintLevel() const { return fDebug; }
unsigned int MaxFunctionCalls() const { return fMaxCalls; }
unsigned int MaxIterations() const { return fMaxIter; }
double Tolerance() const { return fTol; }
double Precision() const { return fPrec; }
int Strategy() const { return fStrategy; }
int Status() const { return fStatus; }
double ErrorDef() const { return fUp; }
bool IsValidError() const { return fValidError; }
virtual MinimizerOptions Options() const {
MinimizerOptions opt;
opt.SetPrintLevel(fDebug);
opt.SetStrategy(fStrategy);
opt.SetMaxFunctionCalls(fMaxCalls);
opt.SetMaxIterations(fMaxIter);
opt.SetTolerance(fTol);
opt.SetPrecision(fPrec);
opt.SetErrorDef(fUp);
return opt;
}
void SetPrintLevel(int level) { fDebug = level; }
void SetMaxFunctionCalls(unsigned int maxfcn) { if (maxfcn > 0) fMaxCalls = maxfcn; }
void SetMaxIterations(unsigned int maxiter) { if (maxiter > 0) fMaxIter = maxiter; }
void SetTolerance(double tol) { fTol = tol; }
void SetPrecision(double prec) { fPrec = prec; }
void SetStrategy(int strategyLevel) { fStrategy = strategyLevel; }
void SetErrorDef(double up) { fUp = up; }
void SetValidError(bool on) { fValidError = on; }
void SetOptions(const MinimizerOptions & opt) {
fDebug = opt.PrintLevel();
fStrategy = opt.Strategy();
fMaxCalls = opt.MaxFunctionCalls();
fMaxIter = opt.MaxIterations();
fTol = opt.Tolerance();
fPrec = opt.Precision();
fUp = opt.ErrorDef();
}
void SetDefaultOptions() {
fDebug = MinimizerOptions::DefaultPrintLevel();
fStrategy = MinimizerOptions::DefaultStrategy();
fMaxCalls = MinimizerOptions::DefaultMaxFunctionCalls();
fMaxIter = MinimizerOptions::DefaultMaxIterations();
fTol = MinimizerOptions::DefaultTolerance();
fPrec = MinimizerOptions::DefaultPrecision();
fUp = MinimizerOptions::DefaultErrorDef();
}
protected:
bool fValidError;
int fDebug;
int fStrategy;
int fStatus;
unsigned int fMaxCalls;
unsigned int fMaxIter;
double fTol;
double fPrec;
double fUp;
};
}
}
#endif /* ROOT_Math_Minimizer */