1#ifndef __JFIT__JGANDALF__
2#define __JFIT__JGANDALF__
11#include "Jeep/JMessage.hh"
12#include "JMath/JVectorND.hh"
13#include "JMath/JMatrixNS.hh"
14#include "JMath/JZero.hh"
15#include "JLang/JManip.hh"
16#include "JLang/JException.hh"
18#include "Jeep/JMessage.hh"
25namespace JPP {
using namespace JFIT; }
30 using JLANG::JException;
32 namespace JFIT_LOCAL {
36 template<
class U>
static auto parameter_type(U*) ->
decltype(std::declval<typename U::parameter_type>());
40 static const bool has_parameter_type = !std::is_same<std::false_type, decltype(parameter_type<T> (0))>::value;
43 template<class T, bool has_parameter_type = JTypedef<T>::has_parameter_type>
56 template<
class JModel_t>
57 inline void model(JModel_t& value)
84 template<
class JModel_t>
86 public JMessage< JGandalf<JModel_t> >
119 const JModel_t&
model) :
130 operator double()
const
160 template<
class JFunction_t,
class T,
class ...Args>
176 previous.result.chi2 = numeric_limits<double>::max();
178 current.result.chi2 = numeric_limits<double>::max();
180 current.result.gradient = zero;
193 update(fit, __begin, __end, args...);
195 DEBUG(
"lambda: " << FIXED(12,5) <<
lambda << endl);
196 DEBUG(
"chi2: " << FIXED(12,5) <<
current.result.chi2 << endl);
212 update(fit, __begin, __end, args...);
217 catch (
const exception&
error) {}
219 for (
size_t i = 0; i != N; ++i) {
248 update(fit, __begin, __end, args...);
251 DEBUG(
"Hesse matrix:" << endl <<
V << endl);
255 for (
size_t i = 0; i != N; ++i) {
261 h[i] = 1.0 / sqrt(
V(i,i));
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);
273 for (
size_t i = 0; i != N; ++i) {
279 for (
size_t col = 0; col != N; ++col) {
286 catch (
const exception&
error) {
288 ERROR(
"JGandalf: " <<
error.what() << endl <<
V << endl);
295 for (
size_t row = 0; row != N; ++row) {
297 DEBUG(
"u[" << noshowpos << setw(3) << row <<
"] = " << showpos << FIXED(15,5) <<
get(
value,
parameters[row]));
315 update(fit, __begin, __end, args...);
320 catch (
const exception&
error) {}
322 for (
size_t i = 0; i != N; ++i) {
355 current.result.gradient = zero;
369 template<
class JFunction_t,
class T,
class ...Args>
370 inline void update(
const JFunction_t& fit, T __begin, T __end, Args ...args)
372 for (T i = __begin; i != __end; ++i) {
379 for (
size_t row = 0; row !=
parameters.size(); ++row) {
380 for (
size_t col = row; col !=
parameters.size(); ++col) {
395 template<
class JFunction_t>
396 inline void update(
const JFunction_t& fit)
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);
413 static inline double get(
const JModel_t&
model,
double JModel_t::*parameter)
415 return model.*parameter;
426 static inline double&
get(JModel_t&
model,
double JModel_t::*parameter)
428 return model.*parameter;
439 static inline double get(
const JModel_t&
model,
const size_t index)
452 static inline double&
get(JModel_t&
model,
const size_t index)
465 static inline double get(
const JModel_t&
model,
const int index)
478 static inline double&
get(JModel_t&
model,
const int index)
483 std::vector<double>
h;
500 template<
class JModel_t>
501 int JGandalf<JModel_t>::MAXIMUM_ITERATIONS = 1000;
507 template<
class JModel_t>
508 double JGandalf<JModel_t>::EPSILON = 1.0e-3;
513 template<
class JModel_t>
514 bool JGandalf<JModel_t>::EPSILON_ABSOLUTE =
false;
519 template<
class JModel_t>
520 double JGandalf<JModel_t>::LAMBDA_MIN = 0.01;
526 template<
class JModel_t>
527 double JGandalf<JModel_t>::LAMBDA_MAX = 100.0;
533 template<
class JModel_t>
534 double JGandalf<JModel_t>::LAMBDA_UP = 10.0;
540 template<
class JModel_t>
541 double JGandalf<JModel_t>::LAMBDA_DOWN = 10.0;
547 template<
class JModel_t>
548 double JGandalf<JModel_t>::PIVOT = std::numeric_limits<double>::epsilon();
static auto parameter_type(...) -> std::false_type
static auto parameter_type(U *) -> decltype(std::declval< typename U::parameter_type >())
static const bool has_parameter_type
Fit method based on the Levenberg-Marquardt method.
struct JFIT::JGandalf::@3 current
void update(const JFunction_t &fit)
Termination method to update current parameters.
double lambda
control parameter
static double LAMBDA_MIN
minimal value control parameter
static double & get(JModel_t &model, const int index)
Read/write access to parameter value by index.
struct JFIT::JGandalf::@4 previous
void reset()
Reset current parameters.
static double LAMBDA_DOWN
multiplication factor control parameter
std::vector< parameter_type > parameters
fit parameters
static double get(const JModel_t &model, const size_t index)
Read/write access to parameter value by index.
static double LAMBDA_UP
multiplication factor control parameter
int numberOfIterations
number of iterations
static bool EPSILON_ABSOLUTE
set epsilon to absolute difference instead of relative
static double get(const JModel_t &model, double JModel_t::*parameter)
Read/write access to parameter value by data member.
static int MAXIMUM_ITERATIONS
maximal number of iterations
static double PIVOT
minimal value diagonal element of Hesse matrix
result_type operator()(const JFunction_t &fit, T __begin, T __end, Args ...args)
Multi-dimensional fit of multiple data sets.
void update(const JFunction_t &fit, T __begin, T __end, Args ...args)
Recursive method to update current parameters.
JGandalf()
Default constructor.
static double EPSILON
maximal distance to minimum
static double & get(JModel_t &model, double JModel_t::*parameter)
Read/write access to parameter value by data member.
JFIT_LOCAL::JTypedef_t< JModel_t >::parameter_type parameter_type
Data type of fit parameter.
JMATH::JMatrixNS V
Hesse matrix.
static double LAMBDA_MAX
maximal value control parameter
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 size_t index)
Read/write access to parameter value by index.
Auxiliary classes and methods for linear and iterative data regression.
void model(JModel_t &value)
Auxiliary function to constrain model during fit.
double T::* parameter_type
T::parameter_type parameter_type
Data structure for return value of fit function.
result_type()
Default constructor.
result_type(const double chi2, const JModel_t &model)
Constructor.
JModel_t gradient
partial derivatives of chi2