37#include "gsl/gsl_multiroots.h"
38#include "gsl/gsl_errno.h"
120 for (
unsigned int i = 0; i <
fFunctions.size(); ++i) {
176 return gsl_multiroot_fsolver_hybrids;
178 return gsl_multiroot_fsolver_hybrid;
180 return gsl_multiroot_fsolver_dnewton;
182 return gsl_multiroot_fsolver_broyden;
184 return gsl_multiroot_fsolver_hybrids;
194 return gsl_multiroot_fdfsolver_hybridsj;
196 return gsl_multiroot_fdfsolver_hybridj;
198 return gsl_multiroot_fdfsolver_newton;
200 return gsl_multiroot_fdfsolver_gnewton;
202 return gsl_multiroot_fdfsolver_hybridsj;
208 if (
name ==
nullptr)
return std::make_pair<bool,int>(
false, -1);
209 std::string aname =
name;
210 std::transform(aname.begin(), aname.end(), aname.begin(), (
int(*)(
int)) tolower );
212 if (aname.find(
"hybridsj") != std::string::npos)
return std::make_pair(
true,
kHybridSJ);
213 if (aname.find(
"hybridj") != std::string::npos)
return std::make_pair(
true,
kHybridJ);
214 if (aname.find(
"hybrids") != std::string::npos)
return std::make_pair(
false,
kHybridS);
215 if (aname.find(
"hybrid") != std::string::npos)
return std::make_pair(
false,
kHybrid);
216 if (aname.find(
"gnewton") != std::string::npos)
return std::make_pair(
true,
kGNewton);
217 if (aname.find(
"dnewton") != std::string::npos)
return std::make_pair(
false,
kDNewton);
218 if (aname.find(
"newton") != std::string::npos)
return std::make_pair(
true,
kNewton);
219 if (aname.find(
"broyden") != std::string::npos)
return std::make_pair(
false,
kBroyden);
220 MATH_INFO_MSG(
"GSLMultiRootFinder::GetType",
"Unknow algorithm - use default one");
221 return std::make_pair(
false, -1);
232 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"Function list is empty");
251 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"Error initializing the solver");
261 std::cout <<
"GSLMultiRootFinder::Solve:" <<
Name() <<
" max iterations " << maxIter <<
" and tolerance " << absTol << std::endl;
272 std::cout <<
"GSLMultiRootFinder::Solve - iteration # " << iter <<
" status = " << status << std::endl;
276 if (status == GSL_EBADFUNC) {
277 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"The iteration encountered a singular point due to a bad function value");
281 if (status == GSL_ENOPROG) {
282 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"The iteration is not making any progress");
287 MATH_ERROR_MSG(
"GSLMultiRootFinder::Solve",
"Unknown iteration error - exit");
293 status =
fSolver->TestResidual(absTol);
297 int status2 =
fSolver->TestDelta(absTol, relTol);
299 MATH_INFO_MSG(
"GSLMultiRootFinder::Solve",
"The iteration converged");
302 while (status == GSL_CONTINUE && iter < maxIter);
303 if (status == GSL_CONTINUE) {
304 MATH_INFO_MSGVAL(
"GSLMultiRootFinder::Solve",
"exceeded max iterations, reached tolerance is not sufficient",absTol);
308 MATH_INFO_MSG(
"GSLMultiRootFinder::Solve",
"The iteration converged");
309 std::cout <<
"GSL Algorithm used is : " <<
fSolver->Name() << std::endl;
310 std::cout <<
"Number of iterations = " << iter<< std::endl;
324 double ndigits = std::log10(
double(
Dim() ) );
325 int wi =
int(ndigits)+1;
326 const double * xtmp =
fSolver->X();
327 const double * ftmp =
fSolver->FVal();
328 os <<
"Root values = ";
329 for (
unsigned int i = 0; i<
Dim(); ++i)
330 os <<
"x[" << std::setw(wi) << i <<
"] = " << std::setw(12) << xtmp[i] <<
" ";
332 os <<
"Function values = ";
333 for (
unsigned int i = 0; i<
Dim(); ++i)
334 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)
GSLMultiRootDerivSolver, internal class for implementing GSL multi-root finders using derivatives.
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
! transient Vector of the functions
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.
virtual IBaseFunctionMultiDimTempl< T > * Clone() const =0
Clone a function.
const gsl_multiroot_fsolver_type * GetGSLType(GSLMultiRootFinder::EType type)
IMultiGenFunctionTempl< double > IMultiGenFunction
double gDefaultRelTolerance
const gsl_multiroot_fdfsolver_type * GetGSLDerivType(GSLMultiRootFinder::EDerivType type)
double gDefaultAbsTolerance