22#include "gsl/gsl_errno.h"
39template <
class FMFunc>
53 double DataElement(
const double *
x,
unsigned i,
double *
g =
nullptr,
double * =
nullptr,
bool =
false)
const override
58 return fFunc.DataElement(xExt, i);
60 double val =
fFunc.DataElement(xExt, i, &
fGrad[0]);
77 typename FMFunc::Type_t
Type()
const override {
return fFunc.Type(); }
112 throw std::runtime_error(
"FitTransformFunction::DoDerivative");
152 unsigned int NDim()
const override {
return fChi2->NDim(); }
170 throw std::runtime_error(
"LSRESidualFunc::DoDerivative");
180 std::string tName(
name);
183 if (tName ==
"lms_old")
185 if (tName ==
"lm_old")
187 if (tName ==
"trust")
189 if (tName ==
"trust_lm")
191 if (tName ==
"trust_lmaccel")
193 if (tName ==
"trust_dogleg")
195 if (tName ==
"trust_ddogleg")
197 if (tName ==
"trust_subspace2D" || tName ==
"trust_2D")
208 const gsl_multifit_fdfsolver_type *gsl_old_type =
nullptr;
210 gsl_old_type = gsl_multifit_fdfsolver_lmsder;
212 gsl_old_type = gsl_multifit_fdfsolver_lmder;
240 fOptions.SetMinimizerAlgorithm(
"trust_lm");
242 fOptions.ExtraOptions()->SetValue(
"scale",
"marquardt");
269 MATH_ERROR_MSG(
"GSLNLSMinimizer::Minimize",
"Function has not been set");
276 if (fitFunc ==
nullptr && fitGradFunc ==
nullptr) {
278 std::cout <<
"GSLNLSMinimizer: Invalid function set - only FitMethodFunction types are supported" << std::endl;
285 std::cout <<
"GLSNLSMinimizer::Minimize - Using old GSLMultiFit with method " <<
fOptions.MinimizerAlgorithm()
299 std::cout <<
"GLSNLSMinimizer::Minimize - Using new GSLMultiFit with trs method " <<
fOptions.MinimizerAlgorithm()
310template <
class Func,
class FitterType>
314 unsigned int size = fitFunc.NPoints();
317 std::vector<LSResidualFunc<Func>> residualFuncs;
318 residualFuncs.reserve(
size);
323 unsigned int npar =
NPar();
324 unsigned int ndim =
NDim();
325 if (npar == 0 || npar < ndim) {
326 MATH_ERROR_MSGVAL(
"GSLNLSMinimizer::Minimize",
"Wrong number of parameters", npar);
331 std::vector<double> startValues;
334 std::unique_ptr<MultiNumGradFunction> gradFunction;
335 std::unique_ptr<MinimTransformFunction> trFuncRaw;
337 gradFunction = std::make_unique<MultiNumGradFunction>(fitFunc);
344 std::unique_ptr<FitTransformFunction<Func>> trFunc;
347 trFunc = std::make_unique<FitTransformFunction<Func>>(fitFunc, std::move(trFuncRaw));
348 assert(npar == trFunc->NTot());
349 for (
unsigned int ires = 0; ires <
size; ++ires) {
353 for (
unsigned int ires = 0; ires <
size; ++ires) {
359 std::cout <<
"Minimize using GSLNLSMinimizer " << std::endl;
361 int iret = fitter->Set(residualFuncs, &startValues.front());
364 MATH_ERROR_MSGVAL(
"GSLNLSMinimizer::Minimize",
"Error setting the residual functions ", iret);
369 bool minFound =
false;
370 unsigned int iter = 0;
375 std::cout <<
"GSLNLSMinimizer: " <<
fGSLMultiFit->Name() <<
" - start iterating......... " << std::endl;
379 status = fitter->Iterate();
381 if (debugLevel >= 1) {
382 std::cout <<
"----------> Iteration " << iter <<
" / " <<
MaxIterations() <<
" status "
383 << gsl_strerror(status) << std::endl;
384 const double *
x = fitter->X();
386 x = trFunc->Transformation(
x);
387 int pr = std::cout.precision(18);
388 std::cout <<
" FVAL = " << (fitFunc)(
x) << std::endl;
389 std::cout.precision(pr);
390 std::cout <<
" X Values : ";
391 for (
unsigned int i = 0; i <
NDim(); ++i)
393 std::cout << std::endl;
406 int status2 = fitter->TestGradient(
Tolerance());
409 fEdm = fitter->Edm();
417 if (debugLevel >= 1) {
418 std::cout <<
" after Gradient and Delta tests: " << gsl_strerror(status);
420 std::cout <<
", edm is: " <<
fEdm;
421 std::cout << std::endl;
429 fEdm = fitter->Edm();
443 const double *
x = fitter->X();
449 x = trFunc->Transformation(
x);
458 const double *cov = fitter->CovarMatrix();
464 trFunc->MatrixTransformation(
x, fitter->CovarMatrix(),
fCovMatrix.data());
469 for (
unsigned int i = 0; i < ndim; ++i)
475 if (debugLevel >= 1) {
476 std::cout <<
"GSLNLSMinimizer: Minimum Found" << std::endl;
477 int pr = std::cout.precision(18);
478 std::cout <<
"FVAL = " <<
MinValue() << std::endl;
479 std::cout <<
"Edm = " <<
fEdm << std::endl;
480 std::cout.precision(pr);
481 std::cout <<
"NIterations = " << iter << std::endl;
482 std::cout <<
"NFuncCalls = " << fitFunc.NCalls() << std::endl;
483 for (
unsigned int i = 0; i <
NDim(); ++i)
484 std::cout << std::setw(12) <<
VariableName(i) <<
" = " << std::setw(12) <<
X()[i] <<
" +/- "
485 << std::setw(12) <<
fErrors[i] << std::endl;
490 if (debugLevel >= 0) {
491 std::cout <<
"GSLNLSMinimizer: Minimization did not converge: " << std::endl;
492 if (status == GSL_ENOPROG)
493 std::cout <<
"\t iteration is not making progress towards solution" << std::endl;
495 std::cout <<
"\t failed with status " << status << std::endl;
497 if (debugLevel >= 1) {
498 std::cout <<
"FVAL = " <<
MinValue() << std::endl;
499 std::cout <<
"Edm = " << fitter->Edm() << std::endl;
500 std::cout <<
"Niterations = " << iter << std::endl;
516 unsigned int ndim =
NDim();
519 if (i > ndim || j > ndim)
#define MATH_ERROR_MSGVAL(loc, txt, x)
#define MATH_ERROR_MSG(loc, str)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
virtual unsigned int NPar() const
total number of parameter defined
unsigned int NDim() const override
number of dimensions
void SetMinValue(double val)
void SetFinalValues(const double *x, const MinimTransformFunction *func=nullptr)
double MinValue() const override
return minimum function value
MinimTransformFunction * CreateTransformation(std::vector< double > &startValues, const ROOT::Math::IMultiGradFunction *func=nullptr)
void SetFunction(const ROOT::Math::IMultiGenFunction &func) override
set the function to minimize
const ROOT::Math::IMultiGenFunction * ObjFunction() const
return pointer to used objective function
const double * X() const override
return pointer to X values at the minimum
std::string VariableName(unsigned int ivar) const override
get name of variables (override if minimizer support storing of variable names)
GSLMultiFit2, internal class for implementing GSL non linear least square GSL fitting New class imple...
GSLMultiFit, internal class for implementing GSL non linear least square GSL fitting.
double CovMatrix(unsigned int, unsigned int) const override
return covariance matrices elements if the variable is fixed the matrix is zero The ordering of the v...
int CovMatrixStatus() const override
return covariance matrix status
void SetFunction(const ROOT::Math::IMultiGenFunction &func) override
set the function to minimize
std::vector< double > fErrors
std::vector< double > fCovMatrix
~GSLNLSMinimizer() override
Destructor (no operations).
GSLNLSMinimizer(int type)
Constructor from a type.
bool DoMinimize(const Func &f, FitterType *fitter)
Internal method to perform minimization template on the type of method function.
bool Minimize() override
method to perform the minimization
const double * MinGradient() const override
return pointer to gradient values at the minimum
ROOT::Math::GSLMultiFit * fGSLMultiFit
ROOT::Math::GSLMultiFit2 * fGSLMultiFit2
virtual bool HasGradient() const
LSResidualFunc class description.
double DoEval(const double *x) const override
Implementation of the evaluation function. Must be implemented by derived classes.
LSResidualFunc< Func > & operator=(const LSResidualFunc< Func > &rhs)
void FdF(const double *x, double &f, double *g) const override
Optimized method to evaluate at the same time the function value and derivative at a point x.
LSResidualFunc(const LSResidualFunc< Func > &rhs)
void Gradient(const double *x, double *g) const override
Evaluate all the vector of function derivatives (gradient) at a point x.
double DoDerivative(const double *, unsigned int) const override
Function to evaluate the derivative with respect each coordinate. To be implemented by the derived cl...
LSResidualFunc(const Func &func, unsigned int i)
IMultiGenFunction * Clone() const override
Clone a function.
unsigned int NDim() const override
Retrieve the dimension of the function.
static int DefaultPrintLevel()
static double DefaultTolerance()
static int DefaultMaxIterations()
double Tolerance() const
Absolute tolerance.
void SetMaxIterations(unsigned int maxiter)
Set maximum iterations (one iteration can have many function calls).
int fStatus
status of minimizer
unsigned int MaxIterations() const
Max iterations.
void SetPrintLevel(int level)
Set print level.
MinimizerOptions fOptions
minimizer options
int PrintLevel() const
Set print level.
IGradientFunctionMultiDim IMultiGradFunction
IMultiGenFunctionTempl< double > IMultiGenFunction
BasicFitMethodFunction< ROOT::Math::IMultiGenFunction > FitMethodFunction
int GetTypeFromName(const char *name)
BasicFitMethodFunction< ROOT::Math::IMultiGradFunction > FitMethodGradFunction