Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
GSLMultiRootSolver.h
Go to the documentation of this file.
1// @(#)root/mathmore:$Id$
2// Author: L. Moneta Wed Dec 20 17:26:06 2006
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License *
10 * as published by the Free Software Foundation; either version 2 *
11 * of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this library (see file COPYING); if not, write *
20 * to the Free Software Foundation, Inc., 59 Temple Place, Suite *
21 * 330, Boston, MA 02111-1307 USA, or contact the author. *
22 * *
23 **********************************************************************/
24
25// Header file for the class GSLMultiRootBaseSolver,
26// GSLMultiRootSolver and GSLMultiRootDerivSolver
27
28#ifndef ROOT_Math_GSLMultiRootSolver
29#define ROOT_Math_GSLMultiRootSolver
30
31#include "gsl/gsl_vector.h"
32#include "gsl/gsl_matrix.h"
33#include "gsl/gsl_multiroots.h"
34#include "gsl/gsl_blas.h"
36
37#include "Math/IFunction.h"
38#include "Math/Error.h"
39
40#include <vector>
41#include <string>
42#include <cassert>
43
44
45namespace ROOT {
46
47 namespace Math {
48
49
50/**
51 GSLMultiRootBaseSolver, internal class for implementing GSL multi-root finders
52 This is the base class for GSLMultiRootSolver (solver not using derivatives) and
53 GSLMUltiRootDerivSolver (solver using derivatives)
54
55 @ingroup MultiRoot
56*/
58
59public:
60
61 /**
62 virtual Destructor
63 */
65
66
67public:
68
69
70 /// init the solver with function list and initial values
71 bool InitSolver(const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec, const double * x) {
72 // create a vector of the fit contributions
73 // create function wrapper from an iterator of functions
74 unsigned int n = funcVec.size();
75 if (n == 0) return false;
76
77 unsigned int ndim = funcVec[0]->NDim(); // should also be = n
78
79 if (ndim != n) {
80 MATH_ERROR_MSGVAL("GSLMultiRootSolver::InitSolver","Wrong function dimension",ndim);
81 MATH_ERROR_MSGVAL("GSLMultiRootSolver::InitSolver","Number of functions",n);
82 return false;
83 }
84
85
86 // set function list and initial values in solver
87 int iret = SetSolver(funcVec,x);
88 return (iret == 0);
89 }
90
91 /// return name
92 virtual const std::string & Name() const = 0;
93
94 /// perform an iteration
95 virtual int Iterate() = 0;
96
97 /// solution values at the current iteration
98 const double * X() const {
99 gsl_vector * x = GetRoot();
100 return x->data;
101 }
102
103 /// return function values
104 const double * FVal() const {
105 gsl_vector * f = GetF();
106 return f->data;
107 }
108
109 /// return function steps
110 const double * Dx() const {
111 gsl_vector * dx = GetDx();
112 return dx->data;
113 }
114
115 /// test using abs and relative tolerance
116 /// |dx| < absTol + relTol*|x| for every component
117 int TestDelta(double absTol, double relTol) const {
118 gsl_vector * x = GetRoot();
119 gsl_vector * dx = GetDx();
120 if (x == nullptr || dx == nullptr) return -1;
121 return gsl_multiroot_test_delta(dx, x, absTol, relTol);
122 }
123
124 /// test using abs tolerance
125 /// Sum |f|_i < absTol
126 int TestResidual(double absTol) const {
127 gsl_vector * f = GetF();
128 if (f == nullptr) return -1;
129 return gsl_multiroot_test_residual(f, absTol);
130 }
131
132
133private:
134
135 // accessor to be implemented by the derived classes
136
137 virtual int SetSolver(const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec, const double * x) = 0;
138
139 virtual gsl_vector * GetRoot() const = 0;
140
141 virtual gsl_vector * GetF() const = 0;
142
143 virtual gsl_vector * GetDx() const = 0;
144
145
146};
147
148
149/**
150 GSLMultiRootSolver, internal class for implementing GSL multi-root finders
151 not using derivatives
152
153 @ingroup MultiRoot
154*/
156
157public:
158
159 /**
160 Constructor from type and simension of system (number of functions)
161 */
162 GSLMultiRootSolver (const gsl_multiroot_fsolver_type * type, int n ) :
163 fSolver(nullptr),
164 fVec(nullptr),
165 fName(std::string("undefined"))
166 {
168 }
169
170 /**
171 Destructor (no operations)
172 */
174 if (fSolver) gsl_multiroot_fsolver_free(fSolver);
175 if (fVec != nullptr) gsl_vector_free(fVec);
176 }
177
178 // usually copying is non trivial, so we delete this
183
184
185 void CreateSolver(const gsl_multiroot_fsolver_type * type, unsigned int n) {
186
187 /// create the solver from the type and size of number of fitting points and number of parameters
188 if (fSolver) gsl_multiroot_fsolver_free(fSolver);
189 fSolver = gsl_multiroot_fsolver_alloc(type, n);
190 fName = std::string(gsl_multiroot_fsolver_name(fSolver) );
191 }
192
193
194 /// set the solver parameters
195 int SetSolver(const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec, const double * x) override {
196 // create a vector of the fit contributions
197 // create function wrapper from an iterator of functions
198 assert(fSolver !=nullptr);
199 unsigned int n = funcVec.size();
200
201 fFunctions.SetFunctions(funcVec, funcVec.size() );
202 // set initial values and create cached vector
203 if (fVec != nullptr) gsl_vector_free(fVec);
204 fVec = gsl_vector_alloc( n);
205 std::copy(x,x+n, fVec->data);
206 // solver should have been already created at this point
207 assert(fSolver != nullptr);
208 return gsl_multiroot_fsolver_set(fSolver, fFunctions.GetFunctions(), fVec);
209 }
210
211 const std::string & Name() const override {
212 return fName;
213 }
214
215 int Iterate() override {
216 if (fSolver == nullptr) return -1;
217 return gsl_multiroot_fsolver_iterate(fSolver);
218 }
219
220 /// solution values at the current iteration
221 gsl_vector * GetRoot() const override {
222 if (fSolver == nullptr) return nullptr;
223 return gsl_multiroot_fsolver_root(fSolver);
224 }
225
226 /// return function values
227 gsl_vector * GetF() const override {
228 if (fSolver == nullptr) return nullptr;
229 return gsl_multiroot_fsolver_f(fSolver);
230 }
231
232 /// return function steps
233 gsl_vector * GetDx() const override {
234 if (fSolver == nullptr) return nullptr;
235 return gsl_multiroot_fsolver_dx(fSolver);
236 }
237
238
239private:
240
242 gsl_multiroot_fsolver * fSolver;
243 // cached vector to avoid re-allocating every time a new one
244 mutable gsl_vector * fVec;
245 std::string fName; // solver name
246
247};
248
249/**
250 GSLMultiRootDerivSolver, internal class for implementing GSL multi-root finders
251 using derivatives
252
253 @ingroup MultiRoot
254*/
256
257public:
258
259 /**
260 Constructor
261 */
262 GSLMultiRootDerivSolver (const gsl_multiroot_fdfsolver_type * type, int n ) :
263 fDerivSolver(nullptr),
264 fVec(nullptr),
265 fName(std::string("undefined"))
266 {
268 }
269
270 /**
271 Destructor (no operations)
272 */
274 if (fDerivSolver) gsl_multiroot_fdfsolver_free(fDerivSolver);
275 if (fVec != nullptr) gsl_vector_free(fVec);
276 }
277
278 // usually copying is non trivial, so we delete this
283
284 /// create the solver from the type and size of number of fitting points and number of parameters
285 void CreateSolver(const gsl_multiroot_fdfsolver_type * type, unsigned int n) {
286
287 /// create the solver from the type and size of number of fitting points and number of parameters
288 if (fDerivSolver) gsl_multiroot_fdfsolver_free(fDerivSolver);
289 fDerivSolver = gsl_multiroot_fdfsolver_alloc(type, n);
290 fName = std::string(gsl_multiroot_fdfsolver_name(fDerivSolver) );
291 }
292
293
294
295 /// set the solver parameters for the case of derivative
296 int SetSolver(const std::vector<ROOT::Math::IMultiGenFunction*> & funcVec, const double * x) override {
297 // create a vector of the fit contributions
298 // need to create a vecctor of gradient functions, convert and store in the class
299 // the new vector pointer
300 assert(fDerivSolver !=nullptr);
301 unsigned int n = funcVec.size();
302 fGradFuncVec.reserve( n );
303 for (unsigned int i = 0; i < n; ++i) {
304 ROOT::Math::IMultiGradFunction * func = dynamic_cast<ROOT::Math::IMultiGradFunction *>(funcVec[i] );
305 if (func == nullptr) {
306 MATH_ERROR_MSG("GSLMultiRootSolver::SetSolver","Function does not provide gradient interface");
307 return -1;
308 }
309 fGradFuncVec.push_back( func);
310 }
311
312 fDerivFunctions.SetFunctions(fGradFuncVec, funcVec.size() );
313 // set initial values
314 if (fVec != nullptr) gsl_vector_free(fVec);
315 fVec = gsl_vector_alloc( n);
316 std::copy(x,x+n, fVec->data);
317
318 return gsl_multiroot_fdfsolver_set(fDerivSolver, fDerivFunctions.GetFunctions(), fVec);
319 }
320
321 const std::string & Name() const override {
322 return fName;
323 }
324
325 int Iterate() override {
326 if (fDerivSolver == nullptr) return -1;
327 return gsl_multiroot_fdfsolver_iterate(fDerivSolver);
328 }
329
330 /// solution values at the current iteration
331 gsl_vector * GetRoot() const override {
332 if (fDerivSolver == nullptr) return nullptr;
333 return gsl_multiroot_fdfsolver_root(fDerivSolver);
334 }
335
336 /// return function values
337 gsl_vector * GetF() const override {
338 if (fDerivSolver == nullptr) return nullptr;
339 return gsl_multiroot_fdfsolver_f(fDerivSolver);
340 }
341
342 /// return function steps
343 gsl_vector * GetDx() const override {
344 if (fDerivSolver == nullptr) return nullptr;
345 return gsl_multiroot_fdfsolver_dx(fDerivSolver);
346 }
347
348
349
350private:
351
353 gsl_multiroot_fdfsolver * fDerivSolver;
354 // cached vector to avoid re-allocating every time a new one
355 mutable gsl_vector * fVec;
356 std::vector<ROOT::Math::IMultiGradFunction*> fGradFuncVec;
357 std::string fName; // solver name
358
359};
360
361 } // end namespace Math
362
363} // end namespace ROOT
364
365
366#endif /* ROOT_Math_GSLMultiRootSolver */
#define MATH_ERROR_MSGVAL(loc, txt, x)
Definition Error.h:109
#define MATH_ERROR_MSG(loc, str)
Definition Error.h:83
#define f(i)
Definition RSha256.hxx:104
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
GSLMultiRootBaseSolver, internal class for implementing GSL multi-root finders This is the base class...
int TestResidual(double absTol) const
test using abs tolerance Sum |f|_i < absTol
virtual gsl_vector * GetDx() const =0
virtual int SetSolver(const std::vector< ROOT::Math::IMultiGenFunction * > &funcVec, const double *x)=0
virtual gsl_vector * GetRoot() const =0
virtual gsl_vector * GetF() const =0
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
virtual ~GSLMultiRootBaseSolver()
virtual Destructor
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
wrapper to a multi-dim function with derivatives for multi roots algorithm
void SetFunctions(const FuncVector &f, unsigned int n)
Fill gsl function structure from a C++ function iterator and size and number of residuals.
GSLMultiRootDerivSolver, internal class for implementing GSL multi-root finders using derivatives.
gsl_multiroot_fdfsolver * fDerivSolver
GSLMultiRootDerivSolver & operator=(const GSLMultiRootDerivSolver &rhs)=delete
const std::string & Name() const override
return name
int SetSolver(const std::vector< ROOT::Math::IMultiGenFunction * > &funcVec, const double *x) override
set the solver parameters for the case of derivative
gsl_vector * GetRoot() const override
solution values at the current iteration
~GSLMultiRootDerivSolver() override
Destructor (no operations)
GSLMultiRootDerivSolver(const gsl_multiroot_fdfsolver_type *type, int n)
Constructor.
GSLMultiRootDerivSolver(GSLMultiRootDerivSolver &&)=delete
gsl_vector * GetDx() const override
return function steps
int Iterate() override
perform an iteration
std::vector< ROOT::Math::IMultiGradFunction * > fGradFuncVec
void CreateSolver(const gsl_multiroot_fdfsolver_type *type, unsigned int n)
create the solver from the type and size of number of fitting points and number of parameters
GSLMultiRootDerivFunctionWrapper fDerivFunctions
GSLMultiRootDerivSolver(const GSLMultiRootDerivSolver &)=delete
gsl_vector * GetF() const override
return function values
wrapper to a multi-dim function without derivatives for multi roots algorithm
void SetFunctions(const FuncVector &f, unsigned int n)
Fill gsl function structure from a C++ function iterator and size and number of residuals.
GSLMultiRootSolver, internal class for implementing GSL multi-root finders not using derivatives.
gsl_vector * GetDx() const override
return function steps
void CreateSolver(const gsl_multiroot_fsolver_type *type, unsigned int n)
int Iterate() override
perform an iteration
GSLMultiRootFunctionWrapper fFunctions
gsl_multiroot_fsolver * fSolver
GSLMultiRootSolver(const gsl_multiroot_fsolver_type *type, int n)
Constructor from type and simension of system (number of functions)
GSLMultiRootSolver(const GSLMultiRootSolver &)=delete
const std::string & Name() const override
return name
GSLMultiRootSolver & operator=(const GSLMultiRootSolver &rhs)=delete
GSLMultiRootSolver(GSLMultiRootSolver &&)=delete
gsl_vector * GetRoot() const override
solution values at the current iteration
int SetSolver(const std::vector< ROOT::Math::IMultiGenFunction * > &funcVec, const double *x) override
set the solver parameters
gsl_vector * GetF() const override
return function values
~GSLMultiRootSolver() override
Destructor (no operations)
Interface (abstract class) for multi-dimensional functions providing a gradient calculation.
Definition IFunction.h:168
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Namespace for new Math classes and functions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...