28 #ifndef ROOT_Math_GSLMultiRootSolver
29 #define ROOT_Math_GSLMultiRootSolver
31 #include "gsl/gsl_vector.h"
32 #include "gsl/gsl_matrix.h"
33 #include "gsl/gsl_multiroots.h"
34 #include "gsl/gsl_blas.h"
57 class GSLMultiRootBaseSolver {
64 virtual ~GSLMultiRootBaseSolver () {}
71 bool InitSolver(
const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec,
const double * x) {
74 unsigned int n = funcVec.size();
75 if (n == 0)
return false;
77 unsigned int ndim = funcVec[0]->NDim();
80 MATH_ERROR_MSGVAL(
"GSLMultiRootSolver::InitSolver",
"Wrong function dimension",ndim);
81 MATH_ERROR_MSGVAL(
"GSLMultiRootSolver::InitSolver",
"Number of functions",n);
87 int iret = SetSolver(funcVec,x);
92 virtual const std::string & Name()
const = 0;
95 virtual int Iterate() = 0;
98 const double * X()
const {
99 gsl_vector * x = GetRoot();
104 const double * FVal()
const {
105 gsl_vector * f = GetF();
110 const double * Dx()
const {
111 gsl_vector * dx = GetDx();
117 int TestDelta(
double absTol,
double relTol)
const {
118 gsl_vector * x = GetRoot();
119 gsl_vector * dx = GetDx();
120 if (x == 0 || dx == 0)
return -1;
121 return gsl_multiroot_test_delta(dx, x, absTol, relTol);
126 int TestResidual(
double absTol)
const {
127 gsl_vector * f = GetF();
128 if (f == 0)
return -1;
129 return gsl_multiroot_test_residual(f, absTol);
137 virtual int SetSolver(
const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec,
const double * x) = 0;
139 virtual gsl_vector * GetRoot()
const = 0;
141 virtual gsl_vector * GetF()
const = 0;
143 virtual gsl_vector * GetDx()
const = 0;
155 class GSLMultiRootSolver :
public GSLMultiRootBaseSolver {
162 GSLMultiRootSolver (
const gsl_multiroot_fsolver_type * type,
int n ) :
165 fName(std::string(
"undefined"))
167 CreateSolver(type, n);
173 virtual ~GSLMultiRootSolver () {
174 if (fSolver) gsl_multiroot_fsolver_free(fSolver);
175 if (fVec != 0) gsl_vector_free(fVec);
184 GSLMultiRootSolver(
const GSLMultiRootSolver &) : GSLMultiRootBaseSolver() {}
189 GSLMultiRootSolver & operator = (
const GSLMultiRootSolver & rhs) {
190 if (
this == &rhs)
return *
this;
198 void CreateSolver(
const gsl_multiroot_fsolver_type * type,
unsigned int n) {
201 if (fSolver) gsl_multiroot_fsolver_free(fSolver);
202 fSolver = gsl_multiroot_fsolver_alloc(type, n);
203 fName = std::string(gsl_multiroot_fsolver_name(fSolver) );
208 virtual int SetSolver(
const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec,
const double * x) {
212 unsigned int n = funcVec.size();
214 fFunctions.SetFunctions(funcVec, funcVec.size() );
216 if (fVec != 0) gsl_vector_free(fVec);
217 fVec = gsl_vector_alloc( n);
218 std::copy(x,x+n, fVec->data);
220 assert(fSolver != 0);
221 return gsl_multiroot_fsolver_set(fSolver, fFunctions.GetFunctions(), fVec);
224 virtual const std::string & Name()
const {
228 virtual int Iterate() {
229 if (fSolver == 0)
return -1;
230 return gsl_multiroot_fsolver_iterate(fSolver);
234 virtual gsl_vector * GetRoot()
const {
235 if (fSolver == 0)
return 0;
236 return gsl_multiroot_fsolver_root(fSolver);
240 virtual gsl_vector * GetF()
const {
241 if (fSolver == 0)
return 0;
242 return gsl_multiroot_fsolver_f(fSolver);
246 virtual gsl_vector * GetDx()
const {
247 if (fSolver == 0)
return 0;
248 return gsl_multiroot_fsolver_dx(fSolver);
254 GSLMultiRootFunctionWrapper fFunctions;
255 gsl_multiroot_fsolver * fSolver;
257 mutable gsl_vector * fVec;
268 class GSLMultiRootDerivSolver :
public GSLMultiRootBaseSolver {
275 GSLMultiRootDerivSolver (
const gsl_multiroot_fdfsolver_type * type,
int n ) :
278 fName(std::string(
"undefined"))
280 CreateSolver(type, n);
286 virtual ~GSLMultiRootDerivSolver () {
287 if (fDerivSolver) gsl_multiroot_fdfsolver_free(fDerivSolver);
288 if (fVec != 0) gsl_vector_free(fVec);
297 GSLMultiRootDerivSolver(
const GSLMultiRootDerivSolver &) : GSLMultiRootBaseSolver() {}
302 GSLMultiRootDerivSolver & operator = (
const GSLMultiRootDerivSolver & rhs) {
303 if (
this == &rhs)
return *
this;
312 void CreateSolver(
const gsl_multiroot_fdfsolver_type * type,
unsigned int n) {
315 if (fDerivSolver) gsl_multiroot_fdfsolver_free(fDerivSolver);
316 fDerivSolver = gsl_multiroot_fdfsolver_alloc(type, n);
317 fName = std::string(gsl_multiroot_fdfsolver_name(fDerivSolver) );
323 virtual int SetSolver(
const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec,
const double * x) {
327 assert(fDerivSolver !=0);
328 unsigned int n = funcVec.size();
329 fGradFuncVec.reserve( n );
330 for (
unsigned int i = 0; i < n; ++i) {
331 ROOT::Math::IMultiGradFunction * func =
dynamic_cast<ROOT::Math::IMultiGradFunction *
>(funcVec[i] );
333 MATH_ERROR_MSG(
"GSLMultiRootSolver::SetSolver",
"Function does not provide gradient interface");
336 fGradFuncVec.push_back( func);
339 fDerivFunctions.SetFunctions(fGradFuncVec, funcVec.size() );
341 if (fVec != 0) gsl_vector_free(fVec);
342 fVec = gsl_vector_alloc( n);
343 std::copy(x,x+n, fVec->data);
345 return gsl_multiroot_fdfsolver_set(fDerivSolver, fDerivFunctions.GetFunctions(), fVec);
348 virtual const std::string & Name()
const {
352 virtual int Iterate() {
353 if (fDerivSolver == 0)
return -1;
354 return gsl_multiroot_fdfsolver_iterate(fDerivSolver);
358 virtual gsl_vector * GetRoot()
const {
359 if (fDerivSolver == 0)
return 0;
360 return gsl_multiroot_fdfsolver_root(fDerivSolver);
364 virtual gsl_vector * GetF()
const {
365 if (fDerivSolver == 0)
return 0;
366 return gsl_multiroot_fdfsolver_f(fDerivSolver);
370 virtual gsl_vector * GetDx()
const {
371 if (fDerivSolver == 0)
return 0;
372 return gsl_multiroot_fdfsolver_dx(fDerivSolver);
379 GSLMultiRootDerivFunctionWrapper fDerivFunctions;
380 gsl_multiroot_fdfsolver * fDerivSolver;
382 mutable gsl_vector * fVec;
383 std::vector<ROOT::Math::IMultiGradFunction*> fGradFuncVec;