27#ifndef ROOT_Math_GSLMultiFit2
28#define ROOT_Math_GSLMultiFit2
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"
73 fType = gsl_multifit_nlinear_trust;
74 fParams = gsl_multifit_nlinear_default_parameters();
76 fParams.trs = gsl_multifit_nlinear_trs_lm;
78 fParams.trs = gsl_multifit_nlinear_trs_lmaccel;
80 fParams.trs = gsl_multifit_nlinear_trs_dogleg;
82 fParams.trs = gsl_multifit_nlinear_trs_ddogleg;
84 fParams.trs = gsl_multifit_nlinear_trs_subspace2D;
117 fParams.scale = gsl_multifit_nlinear_scale_more;
118 else if (sval ==
"levenberg")
119 fParams.scale = gsl_multifit_nlinear_scale_levenberg;
120 else if (sval ==
"marquardt")
121 fParams.scale = gsl_multifit_nlinear_scale_marquardt;
124 std::cout <<
"GSLMultiFit2::SetParameters use default scale : "
125 <<
fParams.scale->name << std::endl;
129 fParams.solver = gsl_multifit_nlinear_solver_qr;
130 else if (sval ==
"cholesky")
131 fParams.solver = gsl_multifit_nlinear_solver_cholesky;
132#if ((GSL_MAJOR_VERSION >= 2) && (GSL_MINOR_VERSION > 5))
133 else if (sval ==
"mcholesky")
134 fParams.solver = gsl_multifit_nlinear_solver_mcholesky;
136 else if (sval ==
"svd")
137 fParams.solver = gsl_multifit_nlinear_solver_svd;
140 std::cout <<
"GSLMultiFit2::SetParameters use default solver : "
141 <<
fParams.solver->name << std::endl;
156 if (
fWs) gsl_multifit_nlinear_free(
fWs);
157 if (
fVec != 0) gsl_vector_free(
fVec);
158 if (
fCov != 0) gsl_matrix_free(
fCov);
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;
188 if (
this == &rhs)
return *
this;
198 int Set(
const std::vector<Func> & funcVec,
const double *
x) {
201 unsigned int npts = funcVec.size();
202 if (npts == 0)
return -1;
204 unsigned int npar = funcVec[0].NDim();
213 if (
fVec != 0) gsl_vector_free(
fVec);
214 fVec = gsl_vector_alloc( npar );
215 std::copy(
x,
x+npar,
fVec->data);
217 if (
fCov != 0) gsl_matrix_free(
fCov);
218 fCov = gsl_matrix_alloc( npar, npar );
223 if (
fWs ==
nullptr)
return "undefined";
224 return std::string(gsl_multifit_nlinear_name(
fWs) );
248 gsl_vector *
f = gsl_multifit_nlinear_residual(
fWs);
250 gsl_blas_ddot(
f,
f, &chisq0);
255 const double ftol = 0.0;
260 int status = gsl_multifit_nlinear_driver(
fMaxIter, xtol, gtol, ftol,
264 fJac = gsl_multifit_nlinear_jac (
fWs);
265 gsl_multifit_nlinear_covar (
fJac, 0.0,
fCov);
269 gsl_blas_ddot(
f,
f, &chisq);
275 static void Callback(
const size_t iter,
void * params ,
const gsl_multifit_nlinear_workspace *w) {
277 if (params ==
nullptr)
return;
279 gsl_vector *
f = gsl_multifit_nlinear_residual(w);
280 gsl_vector *
x = gsl_multifit_nlinear_position(w);
284 gsl_multifit_nlinear_rcond(&rcond, w);
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));
293 printf(
" step : = {");
294 for (
unsigned int i = 0; i < w->dx->size; i++)
295 printf(
" %.4f,",gsl_vector_get(w->dx, i));
297 printf(
" gradient : = {");
298 for (
unsigned int i = 0; i < w->g->size; i++)
299 printf(
" %.4f,",gsl_vector_get(w->g, i));
310 return gsl_multifit_nlinear_niter(
fWs);
314 const double *
X()
const {
315 if (!
fWs)
return nullptr;
316 gsl_vector *
x = gsl_multifit_nlinear_position(
fWs);
322 return (
fCov) ?
fCov->data :
nullptr;
349 template<
class FuncVector>
350 void SetFunction(
const FuncVector &
f,
unsigned int nres,
unsigned int npar ) {
360 fFunc.params =
const_cast<void *
>(p);
369 gsl_multifit_nlinear_workspace *
fWs;
377 const gsl_multifit_nlinear_type *
fType;
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 PrintOptions() const
void SetFunction(const FuncVector &f, unsigned int nres, unsigned int npar)
~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.
static int Df(const gsl_vector *x, void *p, gsl_matrix *h)
static int F(const gsl_vector *x, void *p, gsl_vector *f)
GSLMultiFit, internal class for implementing GSL non linear least square GSL fitting.
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.
void SetValue(const char *name, double val)
generic methods for retrieving options
bool GetValue(const char *name, T &t) const
const IOptions * ExtraOptions() const
return extra options (NULL pointer if they are not present)
double Tolerance() const
absolute tolerance
unsigned int MaxIterations() const
max iterations
int PrintLevel() const
non-static methods for retrieving options