Jpp 19.3.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JFIT::JGandalf< JModel_t > Class Template Reference

Fit method based on the Levenberg-Marquardt method. More...

#include <JGandalf.hh>

Inheritance diagram for JFIT::JGandalf< JModel_t >:
JEEP::JMessage< T > JROOT::JRootfit_t< JFs_t > JROOT::JRootfit< JFs_t >

Classes

struct  result_type
 Data structure for return value of fit function. More...
 

Public Types

typedef JFIT_LOCAL::JTypedef_t< JModel_t >::parameter_type parameter_type
 Data type of fit parameter.
 

Public Member Functions

 JGandalf ()
 Default constructor.
 
template<class JFunction_t , class T , class ... Args>
result_type operator() (const JFunction_t &fit, T __begin, T __end, Args ...args)
 Multi-dimensional fit of multiple data sets.
 

Public Attributes

std::vector< parameter_typeparameters
 fit parameters
 
int numberOfIterations
 number of iterations
 
double lambda
 control parameter
 
JModel_t value
 value
 
JModel_t error
 error
 
JMATH::JMatrixNS V
 Hesse matrix.
 

Static Public Attributes

static int MAXIMUM_ITERATIONS = 1000
 maximal number of iterations
 
static double EPSILON = 1.0e-3
 maximal distance to minimum
 
static bool EPSILON_ABSOLUTE = false
 set epsilon to absolute difference instead of relative
 
static double LAMBDA_MIN = 0.01
 minimal value control parameter
 
static double LAMBDA_MAX = 100.0
 maximal value control parameter
 
static double LAMBDA_UP = 10.0
 multiplication factor control parameter
 
static double LAMBDA_DOWN = 10.0
 multiplication factor control parameter
 
static double PIVOT = std::numeric_limits<double>::epsilon()
 minimal value diagonal element of Hesse matrix
 
static int debug = 0
 debug level (default is off).
 

Private Member Functions

void reset ()
 Reset current parameters.
 
template<class JFunction_t , class T , class ... Args>
void update (const JFunction_t &fit, T __begin, T __end, Args ...args)
 Recursive method to update current parameters.
 
template<class JFunction_t >
void update (const JFunction_t &fit)
 Termination method to update current parameters.
 

Static Private Member Functions

static double get (const JModel_t &model, double JModel_t::*parameter)
 Read/write access to parameter value by data member.
 
static double & get (JModel_t &model, double JModel_t::*parameter)
 Read/write access to parameter value by data member.
 
static double get (const JModel_t &model, const size_t index)
 Read/write access to parameter value by index.
 
static double & get (JModel_t &model, const size_t index)
 Read/write access to parameter value by index.
 
static double get (const JModel_t &model, const int index)
 Read/write access to parameter value by index.
 
static double & get (JModel_t &model, const int index)
 Read/write access to parameter value by index.
 

Private Attributes

std::vector< double > h
 
JMATH::JVectorND x
 
struct { 
 
   result_type   result 
 
current 
 
struct { 
 
   JModel_t   value 
 
   result_type   result 
 
previous 
 

Detailed Description

template<class JModel_t>
class JFIT::JGandalf< JModel_t >

Fit method based on the Levenberg-Marquardt method.

The template argument refers to the model that should be fitted to the data.
This data structure should have arithmetic capabilities.

The data member JGandalf::value corresponds to the start c.q. final value of the model of the fit procedure and JGandalf::error to the uncertainties.
The co-variance matrix is stored in data member JGandalf::V.
The data member JGandalf::parameters constitutes a list of those parameters of the model that should actually be fitted.
For this, the model should contain the type definition for parameter_type.
Normally, this type definition corresponds to a pointer to a data member of the model.
If not defined, the parameters are assumed to be data members of type double.
Alternatively, the type definition can be size_t or int.
In that case, the model should provide for the element access operator[].
The first template parameter in the function operator should provide for an implementation of the actual fit function.
This function should return the data type JGandalf::result_type.
This data structure comprises the values of the chi2 and the gradient for a given data point.
The function operator returns the minimal chi2 and summed gradient of all data points.

Definition at line 85 of file JGandalf.hh.

Member Typedef Documentation

◆ parameter_type

template<class JModel_t >
JFIT_LOCAL::JTypedef_t<JModel_t>::parameter_type JFIT::JGandalf< JModel_t >::parameter_type

Data type of fit parameter.

Definition at line 96 of file JGandalf.hh.

Constructor & Destructor Documentation

◆ JGandalf()

template<class JModel_t >
JFIT::JGandalf< JModel_t >::JGandalf ( )
inline

Default constructor.

Definition at line 144 of file JGandalf.hh.

145 {}

Member Function Documentation

◆ operator()()

template<class JModel_t >
template<class JFunction_t , class T , class ... Args>
result_type JFIT::JGandalf< JModel_t >::operator() ( const JFunction_t & fit,
T __begin,
T __end,
Args ... args )
inline

Multi-dimensional fit of multiple data sets.

The fit function should return the chi2 as well as the partial derivatives for the current value of the model and a given data point.

Parameters
fitfit function
__beginbegin of data
__endend of data
argsoptional data
Returns
chi2 and gradient

Definition at line 161 of file JGandalf.hh.

162 {
163 using namespace std;
164 using namespace JPP;
165
166 // note that all model values should be assigned to the start value of the model before use
167 // because the actual list of model parameters can vary from fit to fit
168 // (e.g. if model consists of a container).
169
170 const size_t N = parameters.size();
171
172 V.resize(N);
173 h.resize(N);
174 x.resize(N);
175
176 previous.result.chi2 = numeric_limits<double>::max();
177
178 current.result.chi2 = numeric_limits<double>::max();
179 current.result.gradient = value;
180 current.result.gradient = zero;
181
182 error = value;
183 error = zero;
184
186
188
189 DEBUG("step: " << numberOfIterations << endl);
190
191 reset();
192
193 update(fit, __begin, __end, args...);
194
195 DEBUG("lambda: " << FIXED(12,5) << lambda << endl);
196 DEBUG("chi2: " << FIXED(12,5) << current.result.chi2 << endl);
197
198 if (current.result.chi2 < previous.result.chi2) {
199
200 if (numberOfIterations != 0) {
201
202 const double tolerance = EPSILON * (EPSILON_ABSOLUTE ? 1.0 : fabs(previous.result.chi2));
203
204 if (fabs(previous.result.chi2 - current.result.chi2) <= tolerance) {
205
206 // normal end
207
208 const result_type result = current.result;
209
210 reset();
211
212 update(fit, __begin, __end, args...);
213
214 try {
215 V.invert();
216 }
217 catch (const exception& error) {}
218
219 for (size_t i = 0; i != N; ++i) {
220 get(error, parameters[i]) = sqrt(V(i,i));
221 }
222
223 return result;
224 }
225
226 if (lambda > LAMBDA_MIN) {
228 }
229 }
230
231 // store current values
232
233 previous.value = value;
234 previous.result = current.result;
235
236 } else {
237
238 value = previous.value; // restore value
239
240 lambda *= LAMBDA_UP;
241
242 if (lambda > LAMBDA_MAX) {
243 break;
244 }
245
246 reset();
247
248 update(fit, __begin, __end, args...);
249 }
250
251 DEBUG("Hesse matrix:" << endl << V << endl);
252
253 // force definite positiveness
254
255 for (size_t i = 0; i != N; ++i) {
256
257 if (V(i,i) < PIVOT) {
258 V(i,i) = PIVOT;
259 }
260
261 h[i] = 1.0 / sqrt(V(i,i));
262 }
263
264 // normalisation
265
266 for (size_t row = 0; row != N; ++row) {
267 for (size_t col = 0; col != row; ++col) {
268 V(row,col) *= h[row] * h[col];
269 V(col,row) = V(row,col);
270 }
271 }
272
273 for (size_t i = 0; i != N; ++i) {
274 V(i,i) = 1.0 + lambda;
275 }
276
277 // solve A x = b
278
279 for (size_t col = 0; col != N; ++col) {
280 x[col] = h[col] * get(current.result.gradient, parameters[col]);
281 }
282
283 try {
284 V.solve(x);
285 }
286 catch (const exception& error) {
287
288 ERROR("JGandalf: " << error.what() << endl << V << endl);
289
290 break;
291 }
292
293 // update value
294
295 for (size_t row = 0; row != N; ++row) {
296
297 DEBUG("u[" << noshowpos << setw(3) << row << "] = " << showpos << FIXED(15,5) << get(value, parameters[row]));
298
299 get(value, parameters[row]) -= h[row] * x[row];
300
301 DEBUG(" -> " << FIXED(15,5) << get(value, parameters[row]) << noshowpos << endl);
302 }
303
304 model(value);
305 }
306
307 // abnormal end
308
309 const result_type result = previous.result;
310
311 value = previous.value; // restore value
312
313 reset();
314
315 update(fit, __begin, __end, args...);
316
317 try {
318 V.invert();
319 }
320 catch (const exception& error) {}
321
322 for (size_t i = 0; i != N; ++i) {
323 get(error, parameters[i]) = sqrt(V(i,i));
324 }
325
326 return result;
327 }
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define ERROR(A)
Definition JMessage.hh:66
double lambda
control parameter
Definition JGandalf.hh:341
static double LAMBDA_MIN
minimal value control parameter
Definition JGandalf.hh:333
JMATH::JVectorND x
Definition JGandalf.hh:484
struct JFIT::JGandalf::@12 current
void reset()
Reset current parameters.
Definition JGandalf.hh:350
static double LAMBDA_DOWN
multiplication factor control parameter
Definition JGandalf.hh:336
std::vector< parameter_type > parameters
fit parameters
Definition JGandalf.hh:339
static double LAMBDA_UP
multiplication factor control parameter
Definition JGandalf.hh:335
int numberOfIterations
number of iterations
Definition JGandalf.hh:340
static bool EPSILON_ABSOLUTE
set epsilon to absolute difference instead of relative
Definition JGandalf.hh:332
std::vector< double > h
Definition JGandalf.hh:483
static double get(const JModel_t &model, double JModel_t::*parameter)
Read/write access to parameter value by data member.
Definition JGandalf.hh:413
static int MAXIMUM_ITERATIONS
maximal number of iterations
Definition JGandalf.hh:330
static double PIVOT
minimal value diagonal element of Hesse matrix
Definition JGandalf.hh:337
void update(const JFunction_t &fit, T __begin, T __end, Args ...args)
Recursive method to update current parameters.
Definition JGandalf.hh:370
result_type result
Definition JGandalf.hh:487
static double EPSILON
maximal distance to minimum
Definition JGandalf.hh:331
JModel_t value
value
Definition JGandalf.hh:342
JMATH::JMatrixNS V
Hesse matrix.
Definition JGandalf.hh:344
static double LAMBDA_MAX
maximal value control parameter
Definition JGandalf.hh:334
JModel_t error
error
Definition JGandalf.hh:343
struct JFIT::JGandalf::@13 previous
void model(JModel_t &value)
Auxiliary function to constrain model during fit.
Definition JGandalf.hh:57
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
void resize(const size_t size)
Resize matrix.
Definition JMatrixND.hh:446
void solve(JVectorND_t &u)
Get solution of equation A x = b.
Definition JMatrixNS.hh:308
void invert()
Invert matrix according LDU decomposition.
Definition JMatrixNS.hh:75

◆ reset()

template<class JModel_t >
void JFIT::JGandalf< JModel_t >::reset ( )
inlineprivate

Reset current parameters.

Definition at line 350 of file JGandalf.hh.

351 {
352 using namespace JPP;
353
354 current.result.chi2 = 0.0;
355 current.result.gradient = zero;
356
357 V.reset();
358 }
JMatrixND & reset()
Set matrix to the null matrix.
Definition JMatrixND.hh:459

◆ update() [1/2]

template<class JModel_t >
template<class JFunction_t , class T , class ... Args>
void JFIT::JGandalf< JModel_t >::update ( const JFunction_t & fit,
T __begin,
T __end,
Args ... args )
inlineprivate

Recursive method to update current parameters.

Parameters
fitfit function
__beginbegin of data
__endend of data
argsoptional data

Definition at line 370 of file JGandalf.hh.

371 {
372 for (T i = __begin; i != __end; ++i) {
373
374 const result_type& result = fit(value, *i);
375
376 current.result.chi2 += result.chi2;
377 current.result.gradient += result.gradient;
378
379 for (size_t row = 0; row != parameters.size(); ++row) {
380 for (size_t col = row; col != parameters.size(); ++col) {
381 V(row,col) += get(result.gradient, parameters[row]) * get(result.gradient, parameters[col]);
382 }
383 }
384 }
385
386 update(fit, args...);
387 }
JModel_t gradient
partial derivatives of chi2
Definition JGandalf.hh:137

◆ update() [2/2]

template<class JModel_t >
template<class JFunction_t >
void JFIT::JGandalf< JModel_t >::update ( const JFunction_t & fit)
inlineprivate

Termination method to update current parameters.

Parameters
fitfit function

Definition at line 396 of file JGandalf.hh.

397 {
398 for (size_t row = 0; row != parameters.size(); ++row) {
399 for (size_t col = 0; col != row; ++col) {
400 V(row,col) = V(col,row);
401 }
402 }
403 }

◆ get() [1/6]

template<class JModel_t >
static double JFIT::JGandalf< JModel_t >::get ( const JModel_t & model,
double JModel_t::* parameter )
inlinestaticprivate

Read/write access to parameter value by data member.

Parameters
modelmodel
parameterparameter
Returns
value

Definition at line 413 of file JGandalf.hh.

414 {
415 return model.*parameter;
416 }

◆ get() [2/6]

template<class JModel_t >
static double & JFIT::JGandalf< JModel_t >::get ( JModel_t & model,
double JModel_t::* parameter )
inlinestaticprivate

Read/write access to parameter value by data member.

Parameters
modelmodel
parameterparameter
Returns
value

Definition at line 426 of file JGandalf.hh.

427 {
428 return model.*parameter;
429 }

◆ get() [3/6]

template<class JModel_t >
static double JFIT::JGandalf< JModel_t >::get ( const JModel_t & model,
const size_t index )
inlinestaticprivate

Read/write access to parameter value by index.

Parameters
modelmodel
indexindex
Returns
value

Definition at line 439 of file JGandalf.hh.

440 {
441 return model[index];
442 }

◆ get() [4/6]

template<class JModel_t >
static double & JFIT::JGandalf< JModel_t >::get ( JModel_t & model,
const size_t index )
inlinestaticprivate

Read/write access to parameter value by index.

Parameters
modelmodel
indexindex
Returns
value

Definition at line 452 of file JGandalf.hh.

453 {
454 return model[index];
455 }

◆ get() [5/6]

template<class JModel_t >
static double JFIT::JGandalf< JModel_t >::get ( const JModel_t & model,
const int index )
inlinestaticprivate

Read/write access to parameter value by index.

Parameters
modelmodel
indexindex
Returns
value

Definition at line 465 of file JGandalf.hh.

466 {
467 return model[index];
468 }

◆ get() [6/6]

template<class JModel_t >
static double & JFIT::JGandalf< JModel_t >::get ( JModel_t & model,
const int index )
inlinestaticprivate

Read/write access to parameter value by index.

Parameters
modelmodel
indexindex
Returns
value

Definition at line 478 of file JGandalf.hh.

479 {
480 return model[index];
481 }

Member Data Documentation

◆ MAXIMUM_ITERATIONS

template<class JModel_t >
int JFIT::JGandalf< JModel_t >::MAXIMUM_ITERATIONS = 1000
static

maximal number of iterations

maximal number of iterations.

Definition at line 330 of file JGandalf.hh.

◆ EPSILON

template<class JModel_t >
double JFIT::JGandalf< JModel_t >::EPSILON = 1.0e-3
static

maximal distance to minimum

maximal distance to minimum.

Definition at line 331 of file JGandalf.hh.

◆ EPSILON_ABSOLUTE

template<class JModel_t >
bool JFIT::JGandalf< JModel_t >::EPSILON_ABSOLUTE = false
static

set epsilon to absolute difference instead of relative

set epsilon to absolute difference instead of relative.

Definition at line 332 of file JGandalf.hh.

◆ LAMBDA_MIN

template<class JModel_t >
double JFIT::JGandalf< JModel_t >::LAMBDA_MIN = 0.01
static

minimal value control parameter

Definition at line 333 of file JGandalf.hh.

◆ LAMBDA_MAX

template<class JModel_t >
double JFIT::JGandalf< JModel_t >::LAMBDA_MAX = 100.0
static

maximal value control parameter

Definition at line 334 of file JGandalf.hh.

◆ LAMBDA_UP

template<class JModel_t >
double JFIT::JGandalf< JModel_t >::LAMBDA_UP = 10.0
static

multiplication factor control parameter

Definition at line 335 of file JGandalf.hh.

◆ LAMBDA_DOWN

template<class JModel_t >
double JFIT::JGandalf< JModel_t >::LAMBDA_DOWN = 10.0
static

multiplication factor control parameter

Definition at line 336 of file JGandalf.hh.

◆ PIVOT

template<class JModel_t >
double JFIT::JGandalf< JModel_t >::PIVOT = std::numeric_limits<double>::epsilon()
static

minimal value diagonal element of Hesse matrix

minimal value diagonal element of matrix

Definition at line 337 of file JGandalf.hh.

◆ parameters

template<class JModel_t >
std::vector<parameter_type> JFIT::JGandalf< JModel_t >::parameters

fit parameters

Definition at line 339 of file JGandalf.hh.

◆ numberOfIterations

template<class JModel_t >
int JFIT::JGandalf< JModel_t >::numberOfIterations

number of iterations

Definition at line 340 of file JGandalf.hh.

◆ lambda

template<class JModel_t >
double JFIT::JGandalf< JModel_t >::lambda

control parameter

Definition at line 341 of file JGandalf.hh.

◆ value

template<class JModel_t >
JModel_t JFIT::JGandalf< JModel_t >::value

value

Definition at line 342 of file JGandalf.hh.

◆ error

template<class JModel_t >
JModel_t JFIT::JGandalf< JModel_t >::error

error

Definition at line 343 of file JGandalf.hh.

◆ V

template<class JModel_t >
JMATH::JMatrixNS JFIT::JGandalf< JModel_t >::V

Hesse matrix.

Definition at line 344 of file JGandalf.hh.

◆ h

template<class JModel_t >
std::vector<double> JFIT::JGandalf< JModel_t >::h
private

Definition at line 483 of file JGandalf.hh.

◆ x

template<class JModel_t >
JMATH::JVectorND JFIT::JGandalf< JModel_t >::x
private

Definition at line 484 of file JGandalf.hh.

◆ result

template<class JModel_t >
result_type JFIT::JGandalf< JModel_t >::result

Definition at line 487 of file JGandalf.hh.

◆ [struct]

struct { ... } JFIT::JGandalf< JModel_t >::current

◆ [struct]

struct { ... } JFIT::JGandalf< JModel_t >::previous

◆ debug

template<class T >
int JEEP::JMessage< T >::debug = 0
staticinherited

debug level (default is off).

Definition at line 45 of file JMessage.hh.


The documentation for this class was generated from the following file: