#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),
fStatus(-1)
{}
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 & ) const {
MATH_ERROR_MSG("Minimizer::GetVariableSettings","Quering an existing variable not implemented");
MATH_UNUSED(ivar);
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 fOptions.PrintLevel(); }
unsigned int MaxFunctionCalls() const { return fOptions.MaxFunctionCalls(); }
unsigned int MaxIterations() const { return fOptions.MaxIterations(); }
double Tolerance() const { return fOptions.Tolerance(); }
double Precision() const { return fOptions.Precision(); }
int Strategy() const { return fOptions.Strategy(); }
int Status() const { return fStatus; }
double ErrorDef() const { return fOptions.ErrorDef(); }
bool IsValidError() const { return fValidError; }
virtual MinimizerOptions Options() const {
return fOptions;
}
void SetPrintLevel(int level) { fOptions.SetPrintLevel(level); }
void SetMaxFunctionCalls(unsigned int maxfcn) { if (maxfcn > 0) fOptions.SetMaxFunctionCalls(maxfcn); }
void SetMaxIterations(unsigned int maxiter) { if (maxiter > 0) fOptions.SetMaxIterations(maxiter); }
void SetTolerance(double tol) { fOptions.SetTolerance(tol); }
void SetPrecision(double prec) { fOptions.SetPrecision(prec); }
void SetStrategy(int strategyLevel) { fOptions.SetStrategy(strategyLevel); }
void SetErrorDef(double up) { fOptions.SetErrorDef(up); }
void SetValidError(bool on) { fValidError = on; }
void SetOptions(const MinimizerOptions & opt) {
fOptions = opt;
}
void SetDefaultOptions() {
fOptions.ResetToDefaultOptions();
}
protected:
bool fValidError;
MinimizerOptions fOptions;
int fStatus;
};
}
}
#endif /* ROOT_Math_Minimizer */