37#include "gsl/gsl_multiroots.h"
38#include "gsl/gsl_errno.h"
68 fIter(0), fStatus(-1), fPrintLevel(0),
77 fIter(0), fStatus(-1), fPrintLevel(0),
86 fIter(0), fStatus(-1), fPrintLevel(0),
87 fType(0), fUseDerivAlgo(false),
109 if (
this == &rhs)
return *
this;
132 for (
unsigned int i = 0; i <
fFunctions.size(); ++i) {
188 return gsl_multiroot_fsolver_hybrids;
190 return gsl_multiroot_fsolver_hybrid;
192 return gsl_multiroot_fsolver_dnewton;
194 return gsl_multiroot_fsolver_broyden;
196 return gsl_multiroot_fsolver_hybrids;
206 return gsl_multiroot_fdfsolver_hybridsj;
208 return gsl_multiroot_fdfsolver_hybridj;
210 return gsl_multiroot_fdfsolver_newton;
212 return gsl_multiroot_fdfsolver_gnewton;
214 return gsl_multiroot_fdfsolver_hybridsj;
220 if (
name == 0)
return std::make_pair<bool,int>(
false, -1);
221 std::string aname =
name;
222 std::transform(aname.begin(), aname.end(), aname.begin(), (
int(*)(
int)) tolower );
224 if (aname.find(
"hybridsj") != std::string::npos)
return std::make_pair(
true,
kHybridSJ);
225 if (aname.find(
"hybridj") != std::string::npos)
return std::make_pair(
true,
kHybridJ);
226 if (aname.find(
"hybrids") != std::string::npos)
return std::make_pair(
false,
kHybridS);
227 if (aname.find(
"hybrid") != std::string::npos)
return std::make_pair(
false,
kHybrid);
228 if (aname.find(
"gnewton") != std::string::npos)
return std::make_pair(
true,
kGNewton);
229 if (aname.find(
"dnewton") != std::string::npos)
return std::make_pair(
false,
kDNewton);
230 if (aname.find(
"newton") != std::string::npos)
return std::make_pair(
true,
kNewton);
231 if (aname.find(
"broyden") != std::string::npos)
return std::make_pair(
false,
kBroyden);
232 MATH_INFO_MSG(
"GSLMultiRootFinder::GetType",
"Unknow algorithm - use default one");
233 return std::make_pair(
false, -1);
244 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"Function list is empty");
263 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"Error initializing the solver");
273 std::cout <<
"GSLMultiRootFinder::Solve:" <<
Name() <<
" max iterations " << maxIter <<
" and tolerance " << absTol << std::endl;
284 std::cout <<
"GSLMultiRootFinder::Solve - iteration # " << iter <<
" status = " << status << std::endl;
288 if (status == GSL_EBADFUNC) {
289 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"The iteration encountered a singolar point due to a bad function value");
293 if (status == GSL_ENOPROG) {
294 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"The iteration is not making any progress");
299 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"Uknown iteration error - exit");
311 MATH_INFO_MSG(
"GSLMultiRootFinder::Solve",
"The iteration converged");
314 while (status == GSL_CONTINUE && iter < maxIter);
315 if (status == GSL_CONTINUE) {
316 MATH_INFO_MSGVAL(
"GSLMultiRootFinder::Solve",
"exceeded max iterations, reached tolerance is not sufficient",absTol);
320 MATH_INFO_MSG(
"GSLMultiRootFinder::Solve",
"The iteration converged");
321 std::cout <<
"GSL Algorithm used is : " <<
fSolver->
Name() << std::endl;
322 std::cout <<
"Number of iterations = " << iter<< std::endl;
337 int wi = int(ndigits)+1;
340 os <<
"Root values = ";
341 for (
unsigned int i = 0; i<
Dim(); ++i)
342 os <<
"x[" << std::setw(wi) << i <<
"] = " << std::setw(12) << xtmp[i] <<
" ";
344 os <<
"Function values = ";
345 for (
unsigned int i = 0; i<
Dim(); ++i)
346 os <<
"f[" << std::setw(wi) << i <<
"] = " << std::setw(12) << ftmp[i] <<
" ";
#define MATH_INFO_MSG(loc, str)
Pre-processor macro to report messages which can be configured to use ROOT error or simply an std::io...
#define MATH_INFO_MSGVAL(loc, txt, x)
#define MATH_ERROR_MSG(loc, str)
int TestResidual(double absTol) const
test using abs tolerance Sum |f|_i < absTol
const double * FVal() const
return function values
const double * X() const
solution values at the current iteration
virtual const std::string & Name() const =0
return name
const double * Dx() const
return function steps
bool InitSolver(const std::vector< ROOT::Math::IMultiGenFunction * > &funcVec, const double *x)
init the solver with function list and initial values
virtual int Iterate()=0
perform an iteration
int TestDelta(double absTol, double relTol) const
test using abs and relative tolerance |dx| < absTol + relTol*|x| for every component
GSLMultiRootDerivSolver, internal class for implementing GSL multi-root finders using derivatives.
Class for Multidimensional root finding algorithms bassed on GSL.
GSLMultiRootFinder & operator=(const GSLMultiRootFinder &)
unsigned int Dim() const
return the number of sunctions set in the class.
const double * Dx() const
return the last step size
virtual ~GSLMultiRootFinder()
destructor
const double * FVal() const
return the function values f(X) solving the system i.e.
void SetType(EType type)
set the type for an algorithm without derivatives
std::vector< ROOT::Math::IMultiGenFunction * > fFunctions
bool Solve(const double *x, int maxIter=0, double absTol=0, double relTol=0)
Find the root starting from the point X; Use the number of iteration and tolerance if given otherwise...
EType
enumeration specifying the types of GSL multi root finders which do not require the derivatives
std::pair< bool, int > GetType(const char *name)
const char * Name() const
Return the algorithm name used for solving Note the name is available only after having called solved...
void PrintState(std::ostream &os=std::cout)
print iteration state
GSLMultiRootBaseSolver * fSolver
EDerivType
enumeration specifying the types of GSL multi root finders requiring the derivatives
GSLMultiRootFinder(EType type)
create a multi-root finder based on an algorithm not requiring function derivative
void Clear()
clear list of functions
static void SetDefaultTolerance(double abstol, double reltol=0)
set tolerance (absolute and relative) relative tolerance is only use to verify the convergence do it ...
int AddFunction(const ROOT::Math::IMultiGenFunction &func)
const double * X() const
return the root X values solving the system
static void SetDefaultMaxIterations(int maxiter)
set maximum number of iterations
GSLMultiRootSolver, internal class for implementing GSL multi-root finders not using derivatives.
Documentation for the abstract class IBaseFunctionMultiDim.
virtual IBaseFunctionMultiDimTempl< T > * Clone() const =0
Clone a function.
Namespace for new Math classes and functions.
const gsl_multiroot_fsolver_type * GetGSLType(GSLMultiRootFinder::EType type)
double gDefaultRelTolerance
const gsl_multiroot_fdfsolver_type * GetGSLDerivType(GSLMultiRootFinder::EDerivType type)
double gDefaultAbsTolerance