TBCI Numerical high perf. C++ Library  2.8.0
LM_fit.h
Go to the documentation of this file.
1 
4 /***************************************************************************
5  LM_fit.h - Levenbaerg-Marquardt non-linear data fit
6  -------------------
7  begin : Wed Dec 15 1999
8  copyright : (C) 1999 by AMB
9  email : bilgic@hft.e-technik.uni-dortmund.de
10  ***************************************************************************/
11 
12 /***************************************************************************
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  ***************************************************************************/
20 
21 
22 #ifndef TBCI_LM_FIT_H
23 #define TBCI_LM_FIT_H
24 
25 #include "tbci/basics.h"
26 #include "tbci/vector.h"
27 #include "tbci/matrix.h"
28 #include "tbci/constants.h"
29 #include "tbci/solver/gauss_jordan.h"
30 //#include "list.h"
31 
32 #ifdef HAVE_SIGNALS
33 # include <signal.h>
34 #endif
35 /*
36 #include <cstdlib>
37 #include <cmath>
38 #include <iostream>
39 #include <iomanip>
40 */
41 
42 
44 
45 #ifdef PRAGMA_I
46 # pragma interface "LM_fit.h"
47 #endif
48 
49 #define DELTAX 1e-30
50 
52 
53 #define DELTA(i,j) ((i==j)?1:0)
54 
55 /*
56 inline int delta (int i, int j)
57 {
58  return ((i==j) ? 1 : 0);
59 }
60  */
61 
62 INST(template <typename T> class Vector friend \
63  int Basis_Trafo (long int, long int, Vector<T>&);)
64 
65 template <typename T>
66 int Basis_Trafo (long int value, long int basis, Vector<T>& index)
67 /* transforms the integer 'value' into the basis 'basis';
68  index contain the resulting digits with lowest significant first */
69 {
70  int n = index.size();
71  int i = 0;
72 
73  index = (T)0;
74  if (value == 0) return 1; //special zero treatment
75  if (n < (int)CSTD__ ceil (MATH__ sqrt(2*MATH__ log((double)value) / MATH__ log((double)basis))) || basis <= 1) return 0;
76  while (value > 0)
77  {
78  index(i) = value%basis;
79  value /= basis;
80  i++;
81  }
82  return 1;
83 }
84 
85 
86 #define CON2 2.0
87 #define CON SQRT2
88 #define BIG 1.0e30
89 #define NTAB 10
90 #define SAFE 2.0
91 
92 INST(template <typename T> class Vector friend \
93  T Partial_Del (T (*func)(const Vector<T>&, const Vector<T>&), \
94  const Vector<T>&, const Vector<T>&, \
95  int, T, T&);)
96 template <typename T>
97 T Partial_Del (T (*func)(const Vector<T>&, const Vector<T>&),
98  const Vector<T>& x, const Vector<T>& p,
99  int mu, T h, T& err)
100  // calculate partial derivative of func with respect to mu
101  // Acc. to Num. recipes, ch. 5.7
102 {
103  //static T maxarg1 ALIGN(MIN_ALIGN), maxarg2 ALIGN(MIN_ALIGN);
104  T errt ALIGN(MIN_ALIGN), fac, hh, ans = (T)0;
105  int xlen = x.size();
106  Matrix<T> a(NTAB,NTAB);
107  Vector<T> buf_plus(xlen);
108  Vector<T> buf_minus(xlen);
109 #ifdef FOURTHORDER
110  Vector<T> buf_plus2(xlen);
111  Vector<T> buf_minus2(xlen);
112 #endif
113  if (mu >= xlen)
114  STD__ cerr << "\n error: partial_del: derivate variable index out of range \n";
115  hh = h ;
116  buf_plus = x; buf_minus = x; buf_plus(mu) += hh; buf_minus(mu) -= hh;
117 #ifdef FOURTHORDER
118  buf_plus2 = x; buf_minus2 = x; buf_plus2(mu) += hh*2; buf_minus2 -= hh*2;
119  a(0,0) = (-(*func)(buf_plus2, p) + 8.0*(*func)(buf_plus, p)
120  - 8.0*(*func)(buf_minus, p) + (*func)(buf_minus2, p)) / (hh*12.0);
121 #else
122  a(0,0) = ((*func)(buf_plus, p) - (*func)(buf_minus, p)) / (2.0*hh);
123 #endif
124  err = BIG;
125  for (int i = 1; i < NTAB; i++) {
126  hh /= CON;
127  buf_plus = x; buf_minus = x; buf_plus(mu) += hh; buf_minus(mu) -= hh;
128 #ifdef FOURTHORDER
129  buf_plus2 = x; buf_minus2 = x; buf_plus2(mu) += hh*2; buf_minus2 -= hh*2;
130  a(0,i) = (-(*func)(buf_plus2, p) + 8.0*(*func)(buf_plus, p)
131  - 8.0*(*func)(buf_minus, p) + (*func)(buf_minus2, p)) / (hh*12.0);
132 #else
133  a(0,i) = ((*func)(buf_plus, p) - (*func)(buf_minus, p)) / (2.0*hh);
134 #endif
135  fac = CON2;
136  for (REGISTER int j = 1; j <= i; j++) {
137  a(j,i) = (a(j-1,i)*fac - a(j-1,i-1))/(fac-1.0);
138  fac *= CON2;
139  errt = MAX (MATH__ fabs(a(j,i)-a(j-1,i)), MATH__ fabs(a(j,i)-a(j-1,i-1)));
140  if (errt <= err) {
141  err = errt;
142  ans = a(j,i);
143  }
144  }
145  if (MATH__ fabs (a(i,i)-a(i-1,i-1)) >= MATH__ fabs (SAFE*err)) break;
146  }
147  return ans;
148 }
149 
150 
151 INST(template <typename T> class Vector friend \
153 
154 template <typename T>
156  // calculates the chi-squared sum
157 
158 {
159  T chi ALIGN(MIN_ALIGN) = 0;
160  int len=data.size();
161 
162  for(REGISTER int i=0;i<len;i++) chi+=sqr((data(i)-func(i))/sig(i));
163  return(chi);
164 }
165 
166 
167 INST(template <typename T> class Vector friend \
168  T Chisquare_2D (T (*func)(const Vector<T>&, const Vector<T>&), \
170 
171 template <typename T>
172 T Chisquare_2D (T (*func)(const Vector<T>&, const Vector<T>&),
176 {
177  Vector<T> arg(2);
178 
180  int anzpkt = x.size();
181 
182  for (REGISTER int i = 0; i < anzpkt; i++) {
183  arg(0) = x(i); arg(1) = y(i);
184  wfvaldiff = (z(i) - (*func)(param, arg)) / sigma(i);
185  chi += sqr (wfvaldiff);
186  }
187  return chi;
188 }
189 
190 
191 INST(template <typename T> class Vector friend \
192  TVector<T> Grid_Min_2D(T (*func)(const Vector<T>&, const Vector<T>&), \
194  Vector<T>&, Vector<T>&, \
195  Vector<T>&, Vector<T>&, \
196  long int, int, char);)
197 
198 template <typename T>
199 TVector<T> Grid_Min_2D(T (*func)(const Vector<T>&, const Vector<T>&),
200  Vector<T>& x, Vector<T>& y, Vector<T>& z,
201  Vector<T>& sig, Vector<T>& pmin,
203  long int res, int max_it, char v)
205 {
206 
207  int plen=pmin.size();
208  int xlen=x.size();
209  long int len=0;
210  Vector<T> p(pmin);
211  TVector<T> min_pos(pmin);
212  Vector<T> factor(plen);
213  Vector<T> arg(2);
214  Vector<T> fval(x.size());
215  Vector<T> index(plen);
216  Vector<T> b(0, plen);
217  Vector<T> a(0, plen);
218  T min ALIGN(MIN_ALIGN) = 0, chi=0 /*, err=0.0, fac=1e-8*/;
219 
220  len = (long int) MATH__ pow ((double)res, plen);
221  for (int k=0;k<xlen;k++) { arg(0)=x(k); arg(1)=y(k); fval(k)=(*func)(p, arg); }
222  min=Chisq(z, fval, sig);
223  STD__ cout << "\n parameter space discretisation with " << len << " points in progress ... \n ";
224  for (REGISTER int j = 0; j < plen; j++)
225  factor(j) = (pmax(j) - pmin(j)) / ((T)res - (T)1);
226  for (long int i=0; i<len; i++) {
227  // linearize recursive for structure by basis trafo
228  if ( !Basis_Trafo(i, res, index) )
229  STD__ cerr << "\n error: basis trafo failed\n";
230  for (REGISTER int j=0; j<plen; j++)
231  p(j) = factor(j) * index(j) + pmin(j); //p-space discr.
232 #if 0
233  //do max_it steepest gradient steps
234  for (int l=0; l<max_it; l++) {
235  // setup Vector
236  err=0.0;
237  for (int k=0; k<plen; k++) {
238  for (int j=0; j<xlen; j++) {
239  arg(0)=x(j); arg(1)=y(j);
240  b(k)+=(z(j)-(*func)(p, arg))/(sig(j)*sig(j))*
241  Partial_Del(func, p, arg, k, p(k)*fac, err);
242  }
243  }
244  // setup diagonal Matrix for steepest gradient const
245  err=0.0;
246  for (int k=0; k<plen; k++) {
247  for (REGISTER int j=0; j<xlen; j++) {
248  arg(0)=x(j); arg(1)=y(j);
249  a(k)+=sqr(Partial_Del(func, p, arg, k, p(k)*fac, err))/
250  (sig(j)*sig(j));
251  }
252  }
253  for (int k=0; k<plen; k++)
254  p(k)+=b(k)*lambda(k)/(a(k)+DELTAX);
255  }
256 #endif
257  // calc func values with new parameter
258  for (int l=0; l<xlen; l++) { arg(0)=x(l); arg(1)=y(l); fval(l)=(*func)(p, arg); }
259  // calc chi2 sqared
260  chi=Chisq(z, fval, sig);
261  if ( chi<min ) { min=chi; min_pos=p; } //choose new min
262  if ( i%1000==0 ) STD__ cerr << i << "\t\t\t\r";
263 #ifdef SIGHANDLE
264  if (sigint) { sigint--; return 0; }
265 #endif
266  }
267  STD__ cout << " \n done! \n\n" << STD__ endl;
268  return min_pos;
269 }
270 
271 
272 INST(template <typename T> class Vector friend \
274  Vector<T>&, Vector<T>&,T (*func)(const Vector<T>&, const Vector<T>&), \
275  Vector<T>, Vector<T>&, T, int, char);)
276 
277 template <typename T>
279  Vector<T>& plow, Vector<T>& phigh,
280  T (*func)(const Vector<T>&, const Vector<T>&),
281  Vector<T> lambda, Vector<T>& lscale,
282  T tol, int iter, char ver)
287 {
288  T chi ALIGN(MIN_ALIGN), chi_new, chi_min, chi_dif, err=0.0, fac=1.0e-8;
289  int len = x.size();
290  int plen = param.size();
291  Vector<T> param2(plen); // Vector<T> for new parameter set
292  Vector<T> param_best(plen); // Vector<T> for best parameter set
293  Vector<T> fval(len); // Vector for fit-func values
294  Vector<T> arg(2); // Vector for arguments of fit-func (2dim)
295 
296  // comp chi-squared
297  chi = Chisquare_2D<T> (func, param, x, y, z, sig);
298  STD__ cout << " \n chi-squared with start parameters is: " << chi;
299  chi_min = chi;
300  // ini matrices
301  Matrix<T> a(0.0, plen,plen);
302  Matrix<T> b(0.0, plen,1);
303  STD__ cout << "\n initializing matrices and starting loop... \n";
304  int j=0; // iteration counter
305  param_best=param;
306  do {
307  int k;
308  // setup Matrix
309  for (k=0; k<plen; k++)
310  for (int l=0; l<plen; l++) {
311  for (int i=0; i<len; i++) {
312  arg(0) = x(i); arg(1)=y(i);
313  a(k,l) += Partial_Del(func, param, arg, k, param(k)*fac, err)*
314  Partial_Del(func, param, arg, l, param(l)*fac, err) /(sig(i)*sig(i));
315  }
316  //STD__ cerr << "\nDEBUG matrix:\n " << a << STD__ flush;
317  //STD__ cerr << "\nDEBUG param:\n " << param << STD__ flush;
318  //STD__ cerr << "\nDEBUG arg:\n " << arg << STD__ flush;
319  //STD__ cerr << "\nDEBUG delk:\n " << Partial_Del(func, param, arg, k, param(k)*fac, err) << STD__ flush;
320  //STD__ cerr << "\nDEBUG dell:\n " << Partial_Del(func, param, arg, l, param(l)*fac, err) << STD__ flush;
321  a(k,l) *= ((T)1+lambda(k)*(T)DELTA(k,l));
322  }
323  // setup Vector<T>
324  for (k=0;k<plen;k++) {
325  for (int i=0;i<len;i++) {
326  arg(0)=x(i); arg(1)=y(i);
327  b(k,0) += (z(i)-(*func)(param, arg))/(sig(i)*sig(i))*
328  Partial_Del(func, param, arg, k, param(k)*fac, err);
329  }
330  }
331  // solve equ a.x=b
332  char exceed = gaussj (a, b);
333  // calc new parameter
334  for (REGISTER int i=0;i<plen;i++) param2(i)=param(i)+b(i,0);
335  // check parameter range
336  exceed = 0;
337  for (REGISTER int f=0; f<plen; f++) {
338  if ((param2(f) > phigh(f)) && (phigh(f)!=plow(f)) ) exceed = 1;
339  if ((param2(f) < plow(f)) && (phigh(f)!=plow(f)) ) exceed = 1;
340  }
341  // calc chi2 sqared
342  chi_new = Chisquare_2D <T> (func, param2, x, y, z, sig);
343  chi_dif = MATH__ fabs (chi_new - chi);
344  if ((chi_new >= chi) || (exceed == 1)) lambda *= lscale(0);
345  //increase lambda cause downhill is exhausted or limits are exceeded
346  else {
347  // decrease lambda and update trial solution
348  lambda*=(T)1/lscale(1);
349  param=param2;
350  // update best est. param if new min is reached
351  if (chi_new<chi_min) {
352  chi_min=chi_new;
353  param_best=param;
354  }
355  }
356  chi=chi_new; // update chi
357  if (ver=='y' || ver=='Y')
358  STD__ cerr << "\n iteration " << j << " " << param <<
359  " " << param2 << " " << chi_new;
360 #ifdef SIGHANDLE
361  if (sigint) { sigint--; param = param_best; return 1e38; }
362 #endif
363  j++;
364  if (j%10 == 0) STD__ cerr << ".";
365  // end loop if tolerance is reached or number of iterations exceeded
366  } while( (chi_dif >= tol) && (j < iter) );
367  param = param_best; // return best parameter set found
368  STD__ cout << "\n loop finished after " << j << " iterations with last delta chi: "
369  << chi_dif << "\n and chi-squared: " << chi_new << STD__ endl;
370  return (chi_new);
371 }
372 
373 
375 
376 #endif /* TBCI_LM_FIT_H */
377 
const Vector< T > const Vector< T > const Vector< T > int mu
Definition: LM_fit.h:97
const Vector< T > const Vector< T > & x
Definition: LM_fit.h:97
Vector< T > factor(plen)
#define MIN_ALIGN
Definition: basics.h:421
#define ALIGN(x)
Definition: basics.h:444
tm fac
Definition: f_matrix.h:1052
const Vector< T > const Vector< T > const Vector< T > & p
Definition: LM_fit.h:97
const Vector< T > const Vector< T > const Vector< T > int T h
Definition: LM_fit.h:97
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > & sigma
&lt; calculates function values of func at position x with params param and return chisq with given y va...
Definition: LM_fit.h:176
long int basis
Definition: LM_fit.h:66
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > & pmin
Definition: LM_fit.h:199
TBCI__ cplx< T > log(const TBCI__ cplx< T > &z)
Definition: cplx.h:771
#define REGISTER
Definition: basics.h:108
double fabs(const int a)
Definition: basics.h:1215
int xlen
Definition: LM_fit.h:105
#define NAMESPACE_TBCI
Definition: basics.h:317
#define CON2
Definition: LM_fit.h:86
#define DELTAX
Definition: LM_fit.h:49
NAMESPACE_TBCI char gaussj(Matrix< T > &a, Matrix< T > &b)
Definition: gauss_jordan.h:46
#define CON
Definition: LM_fit.h:87
int anzpkt
Definition: LM_fit.h:180
return chi
Definition: LM_fit.h:187
#define NTAB
Definition: LM_fit.h:89
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > & z
Definition: LM_fit.h:172
T arg(const TBCI__ cplx< T > &c)
Definition: cplx.h:690
#define DELTA(i, j)
the kronecker delta
Definition: LM_fit.h:53
double sqrt(const int a)
Definition: basics.h:1216
#define CSTD__
Definition: basics.h:340
cplx< T > sqr(const cplx< T > &c)
Definition: cplx.h:449
STD__ cout<< "\n parameter space discretisation with "<< len<< " points in progress ... \n ";factor(j)=(pmax(j)-pmin(j))/((T) res-(T) 1);for(long int i=0;i< len;i++){STD__ cerr<< "\n error: basis trafo failed\n";p(j)=factor(j)*index(j)+pmin(j);for(int l=0;l< xlen;l++){arg(0)=x(l);arg(1)=y(l);fval(l)=(*func)(p, arg);}chi=Chisq(z, fval, sig);if(chi< min){min=chi;min_pos=p;}if(i%1000==0) STD__ cerr<< i<< "\t\t\t\r";}STD__ cout<< " \n done! \n\n"<< STD__ endl;return min_pos;}INST(template< typename T > class Vector friend T LM_fit_2D(Vector< T > &, Vector< T > &, Vector< T > &, Vector< T > &, Vector< T > &, Vector< T > &, Vector< T > &, T(*func)(const Vector< T > &, const Vector< T > &), Vector< T >, Vector< T > &, T, int, char);) template< typename T > T LM_fit_2D(Vector< T > &x, Vector< T > &y, Vector< T > &z, Vector< T > &sig, Vector< T > &param, Vector< T > &plow, Vector< T > &phigh, T(*func)(const Vector< T > &, const Vector< T > &), Vector< T > lambda, Vector< T > &lscale, T tol, int iter, char ver)
Definition: LM_fit.h:278
long int Vector< T > & index
Definition: LM_fit.h:69
STD__ cerr<< "\n error: partial_del: derivate variable index out of range \n";hh=h;buf_plus=x;buf_minus=x;buf_plus(mu)+=hh;buf_minus(mu)-=hh;a(0, 0)=((*func)(buf_plus, p)-(*func)(buf_minus, p))/(2.0 *hh);err=1.0e30;for(int i=1;i< 10;i++){hh/=SQRT2;buf_plus=x;buf_minus=x;buf_plus(mu)+=hh;buf_minus(mu)-=hh;a(0, i)=((*func)(buf_plus, p)-(*func)(buf_minus, p))/(2.0 *hh);fac=2.0;for(REGISTER int j=1;j<=i;j++){a(j, i)=(a(j-1, i)*fac-a(j-1, i-1))/(fac-1.0);fac *=2.0;errt=MAX(MATH__ fabs(a(j, i)-a(j-1, i)), MATH__ fabs(a(j, i)-a(j-1, i-1)));if(errt<=err){err=errt;ans=a(j, i);}}if(MATH__ fabs(a(i, i)-a(i-1, i-1)) >=MATH__ fabs(2.0 *err)) break;}return ans;}INST(template< typename T > class Vector friend T Chisq(Vector< T > &, Vector< T > &, Vector< T > &);) template< typename T > T Chisq(Vector< T > &data, Vector< T > &func, Vector< T > &sig)
Definition: LM_fit.h:155
F_TMatrix< T > b
Definition: f_matrix.h:736
#define SAFE
Definition: LM_fit.h:90
#define BIG
Definition: LM_fit.h:88
Vector< T > fval(x.size())
const Vector< T > Vector< T > & param
Definition: LM_fit.h:172
TVector< T > min_pos(pmin)
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > & sig
Definition: LM_fit.h:199
unsigned long size() const
Definition: vector.h:104
Vector< T > buf_minus(xlen)
Vector< T > buf_plus(xlen)
Definition: bvector.h:49
const Vector< T > const Vector< T > const Vector< T > int T T & err
Definition: LM_fit.h:102
#define INST(x)
Definition: basics.h:238
int i
Definition: LM_fit.h:71
T chi wfvaldiff
Definition: LM_fit.h:179
#define STD__
Definition: basics.h:338
Temporary Base Class Idiom: Class TVector is used for temporary variables.
Definition: bvector.h:52
long int len
Definition: LM_fit.h:209
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > & lambda
Definition: LM_fit.h:199
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > & pmax
Definition: LM_fit.h:199
#define MAX(a, b)
Definition: basics.h:656
#define NAMESPACE_END
Definition: basics.h:323
Definition: bvector.h:54
const Vector< T > Vector< T > Vector< T > Vector< T > & y
Definition: LM_fit.h:172
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > long int res
Definition: LM_fit.h:199
#define T
Definition: bdmatlib.cc:20
const unsigned TMatrix< T > const Matrix< T > * a
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > long int int char v
&lt; find minimun of func on grid with resolution res
Definition: LM_fit.h:205
const Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > Vector< T > long int int max_it
Definition: LM_fit.h:199
#define min(a, b)
Definition: f2c.h:180
TBCI__ cplx< T > pow(const TBCI__ cplx< T > &z, const double n)
Definition: cplx.h:761
#define MATH__
Definition: basics.h:339