Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
GSLMultiFit2.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 class GSLMultiFit
26
27#ifndef ROOT_Math_GSLMultiFit2
28#define ROOT_Math_GSLMultiFit2
29
30#include "gsl/gsl_vector.h"
31#include "gsl/gsl_matrix.h"
32#include "gsl/gsl_multifit_nlinear.h"
33#include "gsl/gsl_blas.h"
34#include "gsl/gsl_version.h"
36
37#include "Math/IFunction.h"
39#include "Math/GenAlgoOptions.h"
40#include <string>
41#include <vector>
42#include <cassert>
43
44//#if GSL_MAJOR_VERSION > 1
45
46namespace ROOT {
47
48 namespace Math {
49
50
51/**
52 GSLMultiFit2, internal class for implementing GSL non linear least square GSL fitting
53 New class implementing new GSL non linear fitting methods introduced in GSL 2.2
54
55 @ingroup MultiMin
56*/
58
59
60public:
61
62 /**
63 Default constructor
64 No need to specify the type so far since only one solver exists so far
65 */
66 GSLMultiFit2 (int type = 0) :
67 //fSolver(0),
68 fVec(0),
69 //fTmp(0),
70 fCov(0)
71 //fJac(0)
72 {
73 fType = gsl_multifit_nlinear_trust; // default value (unique for the moment)
75 if (type == 1) // lm
77 else if (type == 2)
79 else if (type == 3)
81 else if (type == 4)
83 else if (type == 5)
85
86 }
87
89 {
90 // set the extra minimizer options from GSLMultiFit
92 opt.SetValue("scale", fParams.scale->name);
93 opt.SetValue("solver", fParams.solver->name);
94 opt.SetValue("fdtype", fParams.fdtype);
95 opt.SetValue("factor_up", fParams.factor_up);
96 opt.SetValue("factor_down", fParams.factor_down);
97 opt.SetValue("avmax", fParams.avmax);
98 opt.SetValue("h_df", fParams.h_df);
99 opt.SetValue("h_fvv", fParams.h_fvv);
100
101 return opt;
102 }
103
105 {
106 // set the parameters from the minimizer options
107 fPrintLevel = minimOptions.PrintLevel();
108 if (minimOptions.Tolerance() > 0) fTolerance = minimOptions.Tolerance();
109 if (minimOptions.MaxIterations() > 0) fMaxIter = minimOptions.MaxIterations();
110 // now specific options to set the specific GSL parameters
111 const ROOT::Math::IOptions * opt = minimOptions.ExtraOptions();
112 if (!opt)
113 return;
114 std::string sval;
115 opt->GetValue("scale",sval);
116 if (sval == "more")
118 else if (sval == "levenberg")
120 else if (sval == "marquardt")
122 else {
123 if (fPrintLevel > 0)
124 std::cout << "GSLMultiFit2::SetParameters use default scale : "
125 << fParams.scale->name << std::endl;
126 }
127 opt->GetValue("solver",sval);
128 if (sval == "qr")
130 else if (sval == "cholesky")
132#if ((GSL_MAJOR_VERSION >= 2) && (GSL_MINOR_VERSION > 5))
133 else if (sval == "mcholesky")
135#endif
136 else if (sval == "svd")
138 else {
139 if (fPrintLevel > 0)
140 std::cout << "GSLMultiFit2::SetParameters use default solver : "
141 << fParams.solver->name << std::endl;
142 }
143 double val;
144 opt->GetValue("factor_up",val);
145 fParams.factor_up = val;
146 opt->GetValue("factor_down",val);
147 fParams.factor_down = val;
148
149
150 }
151
152 /**
153 Destructor (no operations)
154 */
157 if (fVec != 0) gsl_vector_free(fVec);
158 if (fCov != 0) gsl_matrix_free(fCov);
159 }
160
161 void PrintOptions() const {
162 std::cout << "GSLMultiFit: Parameters used for solving the non-linear fit problem" << std::endl;
163 std::cout << "\t\t Solver for trust region : " << fParams.trs->name << std::endl;
164 std::cout << "\t\t Scaling method : " << fParams.scale->name << std::endl;
165 std::cout << "\t\t Solver method for GN step : " << fParams.solver->name << std::endl;
166 std::cout << "\t\t Finite difference type : " << fParams.fdtype << std::endl;
167 std::cout << "\t\t Factor TR up : " << fParams.factor_up << std::endl;
168 std::cout << "\t\t Factor TR down : " << fParams.factor_down << std::endl;
169 std::cout << "\t\t Max allowed |a|/|v| : " << fParams.avmax << std::endl;
170 std::cout << "\t\t Step size for deriv : " << fParams.h_df << std::endl;
171 std::cout << "\t\t Step size for fvv : " << fParams.h_fvv << std::endl;
172 std::cout << "\t\t Max number of iterations : " << fMaxIter << std::endl;
173 std::cout << "\t\t Tolerance : " << fTolerance << std::endl;
174 }
175
176private:
177 // usually copying is non trivial, so we make this unaccessible
178
179 /**
180 Copy constructor
181 */
183
184 /**
185 Assignment operator
186 */
188 if (this == &rhs) return *this; // time saving self-test
189 return *this;
190 }
191
192
193public:
194
195
196 /// set the solver parameters
197 template<class Func>
198 int Set(const std::vector<Func> & funcVec, const double * x) {
199 // create a vector of the fit contributions
200 // create function wrapper from an iterator of functions
201 unsigned int npts = funcVec.size();
202 if (npts == 0) return -1;
203
204 unsigned int npar = funcVec[0].NDim();
205
206 // Remove unused typedef to remove warning in GCC48
207 // http://gcc.gnu.org/gcc-4.8/porting_to.html
208 // typedef typename std::vector<Func> FuncVec;
209 //FuncIt funcIter = funcVec.begin();
211
212 // set initial values
213 if (fVec != 0) gsl_vector_free(fVec);
215 std::copy(x,x+npar, fVec->data);
216
217 if (fCov != 0) gsl_matrix_free(fCov);
219 return 0;
220 }
221
222 std::string Name() const {
223 if (fWs == nullptr) return "undefined";
224 return std::string(gsl_multifit_nlinear_name(fWs) );
225 }
226
227 int Iterate() {
228 return -1;
229 }
230
231
232 int Solve() {
233 int npts = fFunc.n;
234 int npar = fFunc.p;
235
236 if (fPrintLevel > 0)
237 PrintOptions();
238
239 /* allocate workspace with default parameters */
241
242 /* initialize solver with starting point and weights */
244 // in case of weights
245 //gsl_multifit_nlinear_winit (&x.vector, &wts.vector, &fdf, w);
246
247 /* compute initial cost function */
249 double chisq0;
251
252 // use slightly larger tolerance for gradient
253 const double xtol = fTolerance;
254 const double gtol = 10*fTolerance;
255 const double ftol = 0.0;
256
257 /* solve the system with a maximum of 100 iterations */
258 int info = 0;
259 void * callback_params = (fPrintLevel > 0) ? &fPrintLevel : nullptr;
262
263 /* compute covariance of best fit parameters */
266
267 /* compute final cost */
268 double chisq;
270
271 return status;
272
273 }
274
275 static void Callback(const size_t iter, void * params , const gsl_multifit_nlinear_workspace *w) {
276 // return in case of printLevel=0
277 if (params == nullptr) return;
278
281 double rcond = 0;
282
283 /* compute reciprocal condition number of J(x) */
285
286 printf("iter %2zu: x = {",iter);
287 for (unsigned int i = 0; i < x->size; i++)
288 printf(" %.4f,",gsl_vector_get(x, i));
289 printf(" } cond(J) = %8.4f, |f(x)| = %.4f\n",1.0 / rcond, gsl_blas_dnrm2(f));
290
291 // trust state is not accessible
292 //gsl_multifit_nlinear_trust_state * state = (gsl_multifit_nlinear_trust_state *) w->state;
293 printf(" step : = {");
294 for (unsigned int i = 0; i < w->dx->size; i++)
295 printf(" %.4f,",gsl_vector_get(w->dx, i));
296 printf("\n");
297 printf(" gradient : = {");
298 for (unsigned int i = 0; i < w->g->size; i++)
299 printf(" %.4f,",gsl_vector_get(w->g, i));
300 printf("\n");
301 //if (state) {
302 // printf(" diagonal : D = {");
303 // for (unsigned int i = 0; i < state->diag->size; i++)
304 // printf(" %.4f,",gsl_vector_get(state->diag, i));
305 // }
306
307 }
308
309 int NIter() const {
311 }
312
313 /// parameter values at the minimum
314 const double * X() const {
315 if (!fWs) return nullptr;
317 return x->data;
318 }
319
320 /// return covariance matrix of the parameters
321 const double * CovarMatrix() const {
322 return (fCov) ? fCov->data : nullptr;
323 }
324
325 /// gradient value at the minimum
326 const double * Gradient() const {
327 return nullptr;
328 }
329
330 // this functions are not used (kept for keeping same interface as old GSLMultiFit class )
331 /// test gradient (ask from solver gradient vector)
332 int TestGradient(double /* absTol */ ) const {
333 return -1;
334 }
335
336 /// test using abs and relative tolerance
337 /// |dx| < absTol + relTol*|x| for every component
338 int TestDelta(double /* absTol */, double /* relTol */) const {
339 return -1;
340 }
341
342 // calculate edm 1/2 * ( grad^T * Cov * grad )
343 double Edm() const {
344 return -1;
345 }
346
347protected:
348
349 template<class FuncVector>
350 void SetFunction(const FuncVector & f, unsigned int nres, unsigned int npar ) {
351 const void * p = &f;
352 assert (p != 0);
354 // set to null for internal finite diff
356 //fFunc.fdf = &GSLMultiFitFunctionAdapter<FuncVector >::FDf;
357 fFunc.fvv = NULL; /* not using geodesic acceleration */
358 fFunc.n = nres;
359 fFunc.p = npar;
360 fFunc.params = const_cast<void *>(p);
361 }
362
363private:
364
365 int fPrintLevel = 0;
366 int fMaxIter = 100;
367 double fTolerance = 1.E-6;
368 gsl_multifit_nlinear_fdf fFunc;
370 //gsl_multifit_fdfsolver * fSolver;
371 // cached vector to avoid re-allocating every time a new one
372 mutable gsl_vector * fVec;
373 //mutable gsl_vector * fTmp;
374 mutable gsl_matrix * fCov;
375 mutable gsl_matrix * fJac;
376
378 gsl_multifit_nlinear_parameters fParams;
379
380
381};
382
383 } // end namespace Math
384
385} // end namespace ROOT
386
387
388#endif /* ROOT_Math_GSLMultiFit2 */
#define f(i)
Definition RSha256.hxx:104
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
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
GSLMultiFit2, internal class for implementing GSL non linear least square GSL fitting New class imple...
int Set(const std::vector< Func > &funcVec, const double *x)
set the solver parameters
gsl_multifit_nlinear_workspace * fWs
const double * CovarMatrix() const
return covariance matrix of the parameters
const double * X() const
parameter values at the minimum
void SetParameters(const ROOT::Math::MinimizerOptions &minimOptions)
void SetFunction(const FuncVector &f, unsigned int nres, unsigned int npar)
std::string Name() const
~GSLMultiFit2()
Destructor (no operations)
GSLMultiFit2(const GSLMultiFit &)
Copy constructor.
int TestDelta(double, double) const
test using abs and relative tolerance |dx| < absTol + relTol*|x| for every component
ROOT::Math::GenAlgoOptions GetDefaultOptions() const
GSLMultiFit2(int type=0)
Default constructor No need to specify the type so far since only one solver exists so far.
static void Callback(const size_t iter, void *params, const gsl_multifit_nlinear_workspace *w)
const gsl_multifit_nlinear_type * fType
const double * Gradient() const
gradient value at the minimum
gsl_multifit_nlinear_fdf fFunc
gsl_multifit_nlinear_parameters fParams
int TestGradient(double) const
test gradient (ask from solver gradient vector)
GSLMultiFit2 & operator=(const GSLMultiFit2 &rhs)
Assignment operator.
Class for adapting a C++ functor class to C function pointers used by GSL MultiFit Algorithm The temp...
GSLMultiFit, internal class for implementing GSL non linear least square GSL fitting.
Definition GSLMultiFit.h:53
class implementing generic options for a numerical algorithm Just store the options in a map of strin...
Generic interface for defining configuration options of a numerical algorithm.
Definition IOptions.h:28
void SetValue(const char *name, double val)
generic methods for retrieving options
Definition IOptions.h:42
bool GetValue(const char *name, T &t) const
Definition IOptions.h:54
Double_t x[n]
Definition legend1.C:17
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...