#ifndef ROOT_Math_GSLNLSMinimizer
#define ROOT_Math_GSLNLSMinimizer
#ifndef ROOT_Math_Minimizer
#include "Math/Minimizer.h"
#endif
#ifndef ROOT_Math_IFunctionfwd
#include "Math/IFunctionfwd.h"
#endif
#ifndef ROOT_Math_IParamFunctionfwd
#include "Math/IParamFunctionfwd.h"
#endif
#ifndef ROOT_Math_FitMethodFunction
#include "Math/FitMethodFunction.h"
#endif
#ifndef ROOT_Math_MinimizerVariable
#include "Math/MinimizerVariable.h"
#endif
#include <vector>
#include <map>
#include <string>
namespace ROOT {
namespace Math {
class GSLMultiFit;
class LSResidualFunc : public IMultiGradFunction {
public:
LSResidualFunc() : fIndex(0), fChi2(0)
{}
LSResidualFunc(const ROOT::Math::FitMethodFunction & func, unsigned int i) :
fIndex(i),
fChi2(&func),
fX2(std::vector<double>(func.NDim() ) )
{}
LSResidualFunc(const LSResidualFunc & rhs) :
IMultiGenFunction(),
IMultiGradFunction()
{
operator=(rhs);
}
LSResidualFunc & operator= (const LSResidualFunc & rhs)
{
fIndex = rhs.fIndex;
fChi2 = rhs.fChi2;
fX2 = rhs.fX2;
return *this;
}
IMultiGenFunction * Clone() const {
return new LSResidualFunc(*fChi2,fIndex);
}
unsigned int NDim() const { return fChi2->NDim(); }
void Gradient( const double * x, double * g) const {
double f0 = 0;
FdF(x,f0,g);
}
void FdF (const double * x, double & f, double * g) const {
unsigned int n = NDim();
std::copy(x,x+n,fX2.begin());
const double kEps = 1.0E-4;
f = DoEval(x);
for (unsigned int i = 0; i < n; ++i) {
fX2[i] += kEps;
g[i] = ( DoEval(&fX2.front()) - f )/kEps;
fX2[i] = x[i];
}
}
private:
double DoEval (const double * x) const {
return fChi2->DataElement(x, fIndex);
}
double DoDerivative(const double * x, unsigned int icoord) const {
std::copy(x,x+NDim(),fX2.begin());
const double kEps = 1.0E-4;
fX2[icoord] += kEps;
return ( DoEval(&fX2.front()) - DoEval(x) )/kEps;
}
unsigned int fIndex;
const ROOT::Math::FitMethodFunction * fChi2;
mutable std::vector<double> fX2;
};
class GSLNLSMinimizer : public ROOT::Math::Minimizer {
public:
GSLNLSMinimizer (int type = 0);
~GSLNLSMinimizer ();
private:
GSLNLSMinimizer(const GSLNLSMinimizer &) : ROOT::Math::Minimizer() {}
GSLNLSMinimizer & operator = (const GSLNLSMinimizer & rhs) {
if (this == &rhs) return *this;
return *this;
}
public:
virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func);
virtual void SetFunction(const ROOT::Math::IMultiGradFunction & func);
virtual bool SetVariable(unsigned int ivar, const std::string & name, double val, double step);
virtual bool SetLowerLimitedVariable(unsigned int ivar , const std::string & name , double val , double step , double lower );
virtual bool SetUpperLimitedVariable(unsigned int ivar , const std::string & name , double val , double step , double upper );
virtual bool SetLimitedVariable(unsigned int ivar , const std::string & name , double val , double step , double lower , double upper );
virtual bool SetFixedVariable(unsigned int ivar , const std::string & name , double val );
virtual bool SetVariableValue(unsigned int ivar, double val );
virtual bool SetVariableValues(const double * x);
virtual bool Minimize();
virtual double MinValue() const { return fMinVal; }
virtual double Edm() const { return fEdm; }
virtual const double * X() const { return &fValues.front(); }
virtual const double * MinGradient() const;
virtual unsigned int NCalls() const { return (fObjFunc) ? fObjFunc->NCalls() : 0; }
virtual unsigned int NDim() const { return fDim; }
virtual unsigned int NFree() const { return fNFree; }
virtual bool ProvidesError() const { return true; }
virtual const double * Errors() const { return (fErrors.size() > 0) ? &fErrors.front() : 0; }
virtual double CovMatrix(unsigned int , unsigned int ) const;
virtual int CovMatrixStatus() const;
protected:
private:
unsigned int fDim;
unsigned int fNFree;
unsigned int fSize;
ROOT::Math::GSLMultiFit * fGSLMultiFit;
const ROOT::Math::FitMethodFunction * fObjFunc;
double fMinVal;
double fEdm;
double fLSTolerance;
std::vector<double> fValues;
std::vector<double> fErrors;
std::vector<double> fCovMatrix;
std::vector<double> fSteps;
std::vector<std::string> fNames;
std::vector<LSResidualFunc> fResiduals;
std::vector<ROOT::Math::EMinimVariableType> fVarTypes;
std::map< unsigned int, std::pair<double, double> > fBounds;
};
}
}
#endif /* ROOT_Math_GSLNLSMinimizer */