00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef TBCI_MY_NR_H
00015 #define TBCI_MY_NR_H
00016
00017 #include "vector.h"
00018 #include "matrix.h"
00019 #include "constants.h"
00020 #include "solver/gauss_jordan.h"
00021
00022 #ifdef HAVE_SIGNALS
00023 # include <signal.h>
00024 #endif
00025
00026
00027
00028
00029
00030
00031
00032
00033 NAMESPACE_TBCI
00034
00035 #ifdef PRAGMA_I
00036 # pragma interface
00037 #endif
00038
00039 INST (template <typename T> class dummy friend void do_nothing(T);)
00040 template <typename T>
00041 inline void do_nothing(T dummy) {}
00042
00043
00044 #define DELTA(i,j) ((i==j)?1:0)
00045
00046
00047
00048
00049
00050
00051
00052
00053 #if defined(SIGHANDLE) && defined(HAVE_SIGNALS)
00054 volatile int sigint = 0;
00055
00056 void breakhandler (int signum)
00057 {
00058 STD__ cerr << "\n SIGINT !\n";
00059 sigint++;
00060 if (sigint > 2)
00061 {
00062 STD__ cerr << "\n ... aborted due to too many ignored SIGINTs !\n";
00063 exit (1);
00064 }
00065 else signal (signum, breakhandler);
00066 }
00067 #endif
00068
00069 #define DELTAX 1e-30
00070
00071 INST(template <typename T> class Vector friend int basis_trafo (long int, long int, Vector<T>&);)
00072 template <typename T>
00073 int basis_trafo (long int value, long int basis, Vector<T>& index)
00074
00075
00076 {
00077 int n=index.size();
00078 int i=0;
00079
00080 index=(T)0;
00081 if (value==0) return 1;
00082 if (n<(int)ceil(MATH__ sqrt(2*log((double)value)/log((double)basis))) || basis<=1) return 0;
00083 while( value>0 )
00084 {
00085 index(i)=value%basis;
00086 value/=basis;
00087 i++;
00088 }
00089 return 1;
00090 }
00091
00092
00093 #define CON2 2.0
00094 #define CON SQRT2
00095 #define BIG 1.0e30
00096 #define NTAB 10
00097 #define SAFE 2.0
00098
00099 INST(template <typename T> class Vector friend T partial_del (T (*func)(const Vector<T>&, const Vector<T>&), const Vector<T>&, const Vector<T>&, int, T, T&);)
00100 template <typename T>
00101 T partial_del (T (*func)(const Vector<T>&, const Vector<T>&),
00102 const Vector<T>& x, const Vector<T>& p,
00103 int mu, T h, T& err)
00104
00105
00106 {
00107
00108 T errt ALIGN(MIN_ALIGN), fac, hh, ans(0);
00109 int xlen = x.size();
00110 Matrix<T> a(NTAB,NTAB);
00111 Vector<T> buf_plus(xlen);
00112 Vector<T> buf_minus(xlen);
00113 #ifdef FOURTHORDER
00114 Vector<T> buf_plus2(xlen);
00115 Vector<T> buf_minus2(xlen);
00116 #endif
00117
00118 if (mu >= xlen)
00119 STD__ cerr << "\n error: partial_del: derivate variable index out of range \n";
00120 hh = h ;
00121 buf_plus = x; buf_minus = x; buf_plus(mu) += hh; buf_minus(mu) -= hh;
00122 #ifdef FOURTHORDER
00123 buf_plus2 = x; buf_minus2 = x; buf_plus2(mu) += hh*2; buf_minus2 -= hh*2;
00124 a(0,0) = (-(*func)(buf_plus2, p) + 8.0*(*func)(buf_plus, p)
00125 - 8.0*(*func)(buf_minus, p) + (*func)(buf_minus2, p)) / (hh*12.0);
00126 #else
00127 a(0,0) = ((*func)(buf_plus, p) - (*func)(buf_minus, p)) / (2.0*hh);
00128 #endif
00129 err = BIG;
00130 for (int i = 1; i < NTAB; i++)
00131 {
00132 hh /= CON;
00133 buf_plus = x; buf_minus = x; buf_plus(mu) += hh; buf_minus(mu) -= hh;
00134 #ifdef FOURTHORDER
00135 buf_plus2 = x; buf_minus2 = x; buf_plus2(mu) += hh*2; buf_minus2 -= hh*2;
00136 a(0,i) = (-(*func)(buf_plus2, p) + 8.0*(*func)(buf_plus, p)
00137 - 8.0*(*func)(buf_minus, p) + (*func)(buf_minus2, p)) / (hh*12.0);
00138 #else
00139 a(0,i) = ((*func)(buf_plus, p) - (*func)(buf_minus, p)) / (2.0*hh);
00140 #endif
00141 fac = CON2;
00142 for (register int j = 1; j <= i; j++)
00143 {
00144 a(j,i) = (a(j-1,i)*fac - a(j-1,i-1))/(fac-1.0);
00145 fac *= CON2;
00146 errt = MAX (MATH__ fabs(a(j,i)-a(j-1,i)), MATH__ fabs(a(j,i)-a(j-1,i-1)));
00147 if (errt <= err) {
00148 err = errt;
00149 ans = a(j,i);
00150 }
00151 }
00152 if (MATH__ fabs (a(i,i)-a(i-1,i-1)) >= MATH__ fabs (SAFE*err)) break;
00153 }
00154 return ans;
00155 }
00156
00157 INST(template <typename T> class Vector friend T chisq (Vector<T>&, Vector<T>&, Vector<T>&);)
00158 template <typename T>
00159 T chisq (Vector<T>& data, Vector<T>& func, Vector<T>& sig)
00160
00161
00162 {
00163 T chi ALIGN(MIN_ALIGN) = 0;
00164 int len=data.size();
00165
00166 for(register int i=0;i<len;i++) chi+=sqr((data(i)-func(i))/sig(i));
00167 return(chi);
00168 }
00169
00170 INST(template <typename T> class Vector friend T chisquare (T (*func)(const Vector<T>&, const Vector<T>&), Vector<T>&, Vector<T>&, Vector<T>&, Vector<T>&);)
00171 template <typename T>
00172 T chisquare (T (*func)(const Vector<T>&, const Vector<T>&),
00173 Vector<T>& param, Vector<T>& x,
00174 Vector<T>& y, Vector<T>& sigma)
00175
00176
00177 {
00178 Vector<T> arg(1);
00179
00180 T chi ALIGN(MIN_ALIGN) = 0, wfvaldiff;
00181 int anzpkt = x.size();
00182
00183 for (register int i = 0; i < anzpkt; i++)
00184 {
00185 arg(0) = x(i);
00186 wfvaldiff = (y(i) - (*func)(param, arg)) / sigma(i);
00187 chi += sqr (wfvaldiff);
00188 }
00189 return chi;
00190 }
00191
00192 #if 0
00193
00194
00195 template <typename T>
00196 class minimum
00197 {
00198 public:
00199 Vector<T> koord;
00200 T value ALIGN(MIN_ALIGN);
00201 T getval () { return value; }
00202 minimum () { value = 1e38; }
00203 };
00204
00205 INST(template <typename T> class Vector friend TVector<T> grid_mins(T (*func)(const Vector<T>&, const Vector<T>&), Vector<T>&, Vector<T>&, Vector<T>&, Vector<T>&, Vector<T>&, int, char, int, nsList<minimum<T>,T>& );)
00206 template <typename T>
00207 TVector<T> grid_mins(T (*func)(const Vector<T>&, const Vector<T>&),
00208 Vector<T>& x, Vector<T>& y,
00209 Vector<T>& sigma, Vector<T>& pmin, Vector<T>& pmax,
00210 int res, char v, int anzmin,
00211 nsList<minimum<T>,T>& minima)
00212
00213
00214 {
00215 int anzpar = pmin.size();
00216 minimum<T>* min;
00217 minimum<T> min2; min2.koord.resize (anzpar);
00218 Vector<T> actpar(anzpar);
00219 TVector<T> absmin(anzpar);
00220
00221 Vector<T> factor(anzpar);
00222 Vector<T> plim(anzpar);
00223 long int len = (long int) MATH__ pow ((double)res, anzpar);
00224 bool overflow; int k;
00225
00226 actpar = pmin;
00227 T actval ALIGN(MIN_ALIGN) = chisquare (func, actpar, x, y, sigma);
00228 min = minima.setlast();
00229 STD__ cerr << "Parameter space discretisation in process ...\n";
00230
00231 for (register int j = 0; j < anzpar; j++)
00232 {
00233 factor(j) = (pmax(j) - pmin(j)) / (res - 1);
00234 plim(j) = pmax(j) + 0.5 * factor(j);
00235 }
00236
00237 for (long int i = 0; i < len; i++)
00238 {
00239 actval = chisquare (func, actpar, x, y, sigma);
00240 if (actval < min->value)
00241 {
00242 if (v=='y' || v=='Y')
00243 STD__ cerr << "Found new min " << actval << " at " << actpar << '\n';
00244 #ifdef USEQSORT
00245 min->koord = actpar;
00246 min->value = actval;
00247 if (anzmin > 1) minima.qsort ();
00248 min = minima.setlast ();
00249 #else
00250 min2.koord = actpar; min2.value = actval;
00251 min = minima.sortin_r ( min2 );
00252 #endif
00253 }
00254 if (!(i % 1000)) STD__ cerr << i << '\r';
00255
00256 overflow = true; k = 0;
00257 while (overflow && (k < anzpar))
00258 {
00259 actpar(k) += factor(k);
00260 if (actpar(k) > plim(k)) actpar(k) = pmin(k);
00261 else overflow = false;
00262 k++;
00263 }
00264 #ifdef SIGHANDLE
00265 if (sigint) { sigint--; return 0; }
00266 #endif
00267 }
00268
00269 STD__ cerr << "\n ... done.\n\n";
00270 absmin = minima.getfirst()->koord;
00271 return absmin;
00272 }
00273 #endif
00274
00275 INST(template <typename T> class Vector friend TVector<T> grid_min(T (*func)(const Vector<T>&, const Vector<T>&), Vector<T>&, Vector<T>&, Vector<T>&, Vector<T>&, Vector<T>&, Vector<T>&, long int, int, char);)
00276 template <typename T>
00277 TVector<T> grid_min(T (*func)(const Vector<T>&, const Vector<T>&),
00278 Vector<T>& x, Vector<T>& y,
00279 Vector<T>& sig, Vector<T>& pmin,
00280 Vector<T>& pmax, Vector<T>& lambda,
00281 long int res, int max_it, char v)
00282
00283 {
00284
00285 int plen=pmin.size();
00286 int xlen=x.size();
00287 long int len=0;
00288 Vector<T> p(pmin);
00289 TVector<T> min_pos(pmin);
00290 Vector<T> factor(plen);
00291 Vector<T> arg(1);
00292 Vector<T> fval(x.size());
00293 Vector<T> index(plen);
00294 Vector<T> b(plen,0);
00295 Vector<T> a(plen,0);
00296 T min ALIGN(MIN_ALIGN) = 0, chi=0, err=0.0, fac=1e-8;
00297
00298 len=(long int) pow((double)res, plen);
00299 for (int s=0; s<xlen; s++) { arg(0)=x(s); fval(s)=(*func)(p, arg); }
00300 min=chisq(y, fval, sig);
00301 STD__ cerr << "\n parameter space discretisation in progress ... \n ";
00302 for (register int j = 0; j < plen; j++)
00303 factor(j) = (pmax(j) - pmin(j)) / ((T)res - (T)1);
00304 for (long int i=0;i<len;i++)
00305 {
00306
00307 if ( !basis_trafo(i, res, index) )
00308 STD__ cerr << "\n error: basis trafo failed\n";
00309 for (register int j=0;j<plen;j++)
00310 p(j) = factor(j) * index(j) + pmin(j);
00311
00312 for (int l=0;l<max_it;l++)
00313 {
00314
00315 err=0.0;
00316 for (int k=0;k<plen;k++)
00317 {
00318 for (int j=0;j<xlen;j++)
00319 {
00320 arg(0)=x(j);
00321 b(k)+=(y(j)-(*func)(p, arg))/(sig(j)*sig(j))*
00322 partial_del(func, p, arg, k, x(j)*fac, err);
00323 }
00324 }
00325
00326 err = 0.0;
00327 for (int t=0; t<plen; t++)
00328 {
00329 for (register int u=0; u<xlen; u++)
00330 {
00331 arg(0) = x(u);
00332 a(t) += sqr(partial_del(func, p, arg, t, x(u)*fac, err))/
00333 (sig(u)*sig(u));
00334 }
00335 }
00336 for (int q=0; q<plen; q++)
00337 p(q) += b(q)*lambda(q)/(a(q)+DELTAX);
00338 }
00339
00340 for (int q=0; q<xlen; q++) { arg(0)=x(q); fval(q)=(*func)(p, arg); }
00341
00342 chi=chisq(y, fval, sig);
00343 if ( chi<min ) { min=chi; min_pos=p; }
00344 if ( i%1000==0 ) STD__ cerr << i << "\r";
00345 #ifdef SIGHANDLE
00346 if (sigint) { sigint--; return 0; }
00347 #endif
00348 }
00349 STD__ cerr << " \n done! \n\n\n";
00350 return min_pos;
00351 }
00352
00353 INST(template <typename T> class Vector friend T lev_mar(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);)
00354 template <typename T>
00355 T lev_mar(Vector<T>& x, Vector<T>& y, Vector<T>& sig, Vector<T>& param,
00356 Vector<T>& plow, Vector<T>& phigh,
00357 T (*func)(const Vector<T>&, const Vector<T>&),
00358 Vector<T> lambda, Vector<T>& lscale,
00359 T tol, int iter, char ver)
00360
00361
00362
00363
00364
00365 {
00366 T chi ALIGN(MIN_ALIGN), chi_new, chi_min, chi_dif, err=0.0, fac=1.0e-8;
00367 int len=x.size();
00368 int plen=param.size();
00369 Vector<T> param2(plen);
00370 Vector<T> param_best(plen);
00371 Vector<T> fval(len);
00372 Vector<T> arg(1);
00373
00374
00375 chi=chisquare(func,param,x,y,sig);
00376 STD__ cerr << " \n chi-squared with start parameters is: " << chi;
00377 chi_min=chi;
00378
00379 Matrix<T> a(plen,plen);
00380 Matrix<T> b(plen,1);
00381 STD__ cerr << "\n initializing matrices and starting loop... \n";
00382 int j=0;
00383 param_best=param;
00384 do
00385 {
00386
00387 for (int k=0;k<plen;k++)
00388 for (int l=0;l<plen;l++)
00389 {
00390 for (int i=0;i<len;i++)
00391 {
00392 arg(0)=x(i);
00393 a(k,l)+=partial_del(func, param, (Vector<T>&)arg, k, x(i)*fac, err)*
00394 partial_del(func, param, (Vector<T>&)arg, l, x(i)*fac, err) /(sig(i)*sig(i));
00395 }
00396 a(k,l)*=((T)1+lambda(k)*(T)DELTA(k,l));
00397 }
00398
00399 for (int q=0; q<plen; q++)
00400 {
00401 for (int i=0;i<len;i++)
00402 {
00403 arg(0)=x(i);
00404 b(q,0)+=(y(i)-(*func)(param, (Vector<T>&)arg))/(sig(i)*sig(i))*
00405 partial_del(func, param, (Vector<T>&)arg, q, x(i)*fac, err);
00406 }
00407 }
00408
00409 char exceed = gaussj (a, b);
00410
00411 for (register int t=0; t<plen; t++) param2(t)=param(t)+b(t,0);
00412
00413 exceed = 0;
00414 for (register int i=0; i<plen; i++)
00415 {
00416 if ((param2(i) > phigh(i)) && (phigh(i)!=plow(i)) ) exceed = 1;
00417 if ((param2(i) < plow(i)) && (phigh(i)!=plow(i)) ) exceed = 1;
00418 }
00419
00420 chi_new = chisquare(func, param2, x, y, sig);
00421 chi_dif = MATH__ fabs (chi_new - chi);
00422 if ((chi_new >= chi) || (exceed == 1)) lambda *= lscale(0);
00423
00424 else {
00425
00426 lambda*=(T)1/lscale(1);
00427 param=param2;
00428
00429 if (chi_new<chi_min) {
00430 chi_min=chi_new;
00431 param_best=param;
00432 }
00433 }
00434 chi=chi_new;
00435 if (ver=='y' || ver=='Y')
00436 STD__ cerr << "\n iteration " << j << " " << param <<
00437 " " << param2 << " " << chi_new;
00438 #ifdef SIGHANDLE
00439 if (sigint) { sigint--; param = param_best; return 1e38; }
00440 #endif
00441 j++;
00442 if (j%10 == 0) STD__ cerr << ".";
00443
00444 } while( (chi_dif >= tol) && (j < iter) );
00445 param=param_best;
00446 STD__ cerr << "\n loop finished after " << j << " iterations with last delta chi: "
00447 << chi_dif << "\n and chi-squared: " << chi_new << "\n";
00448 return (chi_new);
00449 }
00450
00451 INST(template <typename T> class Matrix friend void hpsort (Matrix<T>&, int);)
00452 template <typename T>
00453 void hpsort (Matrix<T>& x, int pos)
00454
00455
00456
00457
00458 {
00459 unsigned long i, ir, j, l, n;
00460 Vector<T> rra(x.columns());
00461
00462 n=x.rows();
00463 if ( n<2 ) return;
00464 l=(n >> 1)+1;
00465 ir=n;
00466 for (;;)
00467 {
00468 if ( l>1 ) {
00469 rra=x(--l-1);
00470 }
00471 else {
00472 rra=x(ir-1);
00473 x(ir-1)=x(0);
00474 if (--ir==1) {
00475 x(0)=rra;
00476 break;
00477 }
00478 }
00479 i=l;
00480 j=l+l;
00481 while ( j<=ir ) {
00482 if ( j<ir && x(j-1,pos) < x(j,pos) ) j++;
00483 if ( rra(pos)<x(j-1,pos) ) {
00484 x(i-1)=x(j-1);
00485 i=j;
00486 j <<= 1;
00487 }
00488 else j=ir+1;
00489 }
00490 x(i-1)=rra;
00491 }
00492 }
00493
00494 NAMESPACE_END
00495
00496 #endif
00497