NMFit Namespace Reference


Functions

void Fit (bool mwt, const std::vector< double > x, const std::vector< double > y, const std::vector< double > sig, double &a, double &b, double &siga, double &sigb, double &chi2, double &q)
double gammq (double a, double x)
void gser (double &gamser, double a, double x, double &gln)
void gcf (double &gammcf, double a, double x, double &gln)
double gammln (double xx)
double FitPol (int pow, int n, const double *x, const double *y, const double *w, double *par, double *pErr)
 Fits points to a polynomial of a given degree, returns chi squared, and if desired, errors on parameters.


Function Documentation

void NMFit::Fit ( bool  mwt,
const std::vector< double >  x,
const std::vector< double >  y,
const std::vector< double >  sig,
double &  a,
double &  b,
double &  siga,
double &  sigb,
double &  chi2,
double &  q 
)

Definition at line 23 of file NMFit.cxx.

References gammq().

Referenced by bestChi2(), ComputeADCOffset(), main(), and RosieFCN().

00028                                  {
00029 
00030   double wt,t,sxoss,sx=0.0,sy=0.0,st2=0.0,ss,sigdat;
00031 
00032   if (x.empty()) return;
00033 
00034   std::cout << "I am inside NMFit::Fit()" << std::endl;
00035 
00036   b=0.0;
00037   if (mwt) {
00038     ss=0.0;
00039     for (unsigned int i=0; i<x.size(); i++) {
00040       std::cout << "With weights: x=" << x[i] << " z=" << y[i]
00041         << " sig=" << sig[i] << std::endl;
00042       wt=1.0/(sig[i]*sig[i]);
00043       ss = ss + wt;
00044       sx = sx + x[i]*wt;
00045       sy = sy + (y[i]+4000.0)*wt;
00046     }
00047   }
00048   else {
00049     for (unsigned int i=0; i<x.size(); i++) {
00050       std::cout << "W/out weights: x=" << x[i] << " z=" << y[i]
00051         << " sig=" << sig[i] << std::endl;
00052       sx = sx + x[i];
00053       sy = sy + (y[i]+4000.0);
00054     }
00055     ss=(double)x.size();
00056   }
00057   sxoss=sx/ss;
00058 
00059   std::cout << "ss/sx/sy/sxoss=" 
00060         << ss << "/" << sx  << "/" << sy  << "/" << sxoss << std::endl;
00061 
00062   if (mwt) {
00063     for (unsigned int i=0; i<x.size(); i++) {
00064       t = (x[i]-sxoss)/sig[i];
00065       st2 = st2 + t*t;
00066       b = b + t*y[i]/sig[i];
00067     }
00068   }
00069   else {
00070     for (unsigned int i=0; i<x.size(); i++) {
00071       t = x[i] - sxoss;
00072       st2 = st2 + t*t;
00073       b = b + t*y[i];
00074     }
00075   }
00076 
00077   b = b/st2;
00078   a = (sy-sx*b)/ss;
00079   siga = sqrt((1.0+sx*sx/(ss*st2))/ss);
00080   sigb = sqrt(1.0/st2);
00081   chi2 = 0.0;
00082   if (!mwt) {
00083     for (unsigned int i=0; i<x.size(); i++)
00084       chi2 = chi2 + ((y[i]-a-b*x[i])*(y[i]-a-b*x[i]));
00085     q = 1.0;
00086     sigdat = sqrt((chi2)/(x.size()-2));
00087     siga = siga*sigdat;
00088     sigb = sigb*sigdat;
00089 
00090     // tmp output
00091     std::cout << "Finished NMFit (no weights): slope/intercept=" 
00092           << a << "/" << b 
00093           << "\n                   with errors= "
00094           << siga << "/" << sigb 
00095           << "\n                   with chi^2/q= "
00096           << chi2 << "/" << q
00097           << std::endl;
00098   }
00099   else {
00100     for (unsigned int i=0; i<x.size(); i++)
00101       chi2 = chi2 + ((y[i]-a-b*x[i])/sig[i])*((y[i]-a-b*x[i])/sig[i]);
00102     q=gammq(0.5*(x.size()-2),0.5*chi2);
00103 
00104     // tmp output
00105     std::cout << "Finished NMFit (w/weights): slope/intercept=" 
00106           << a << "/" << b 
00107           << "\n                   with errors= "
00108           << siga << "/" << sigb 
00109           << "\n                   with chi^2/q= "
00110           << chi2 << "/" << q
00111           << std::endl;
00112   }
00113 }

double NMFit::gammq ( double  a,
double  x 
)

Definition at line 118 of file NMFit.cxx.

References gcf(), and gser().

Referenced by Fit().

00118                                       {
00119 
00120   double gamser,gammcf,gln;
00121 
00122   if (x < 0.0 || a <= 0.0) {
00123     std::cout << "Invalid arguments in routine GAMMQ" << std::endl;
00124   }
00125   if (x < (a+1.0)) {
00126     gser(gamser,a,x,gln);
00127     return 1.0-gamser;
00128   }
00129   else {
00130     gcf(gammcf,a,x,gln);
00131     return gammcf;
00132   }
00133 }

void NMFit::gser ( double &  gamser,
double  a,
double  x,
double &  gln 
)

Definition at line 138 of file NMFit.cxx.

References EPS, gammln(), and ITMAX.

Referenced by gammq().

00138                                                              {
00139 
00140   int n;
00141   double sum,del,ap;
00142 
00143   gln=gammln(a);
00144   if (x <= 0.0) {
00145     if (x < 0.0) std::cout << "x less than 0 in routine GSER" << std::endl;
00146     gamser=0.0;
00147     return;
00148   }
00149   else {
00150     ap=a;
00151     sum=1.0/a;
00152     del=1.0/a;
00153     for (n=1;n<=ITMAX;n++) {
00154       ap += 1.0;
00155       del *= x/ap;
00156       sum += del;
00157       if (fabs(del) < fabs(sum)*EPS) {
00158     gamser=sum*exp(-x+a*log(x)-gln);
00159     return;
00160       }
00161     }
00162     std::cout << "a too large, ITMAX too small in routine GSER" << std::endl;
00163     return;
00164   }
00165 }

void NMFit::gcf ( double &  gammcf,
double  a,
double  x,
double &  gln 
)

Definition at line 170 of file NMFit.cxx.

References EPS, gammln(), and ITMAX.

Referenced by gammq().

00170                                                             {
00171 
00172   int n;
00173   double gold=0.0,g,fac=1.0,b1=1.0;
00174   double b0=0.0,anf,ana,an,a1,a0=1.0;
00175 
00176   gln=gammln(a);
00177   a1=x;
00178   for (n=1;n<=ITMAX;n++) {
00179     an=(double) n;
00180     ana=an-a;
00181     a0=(a1+a0*ana)*fac;
00182     b0=(b1+b0*ana)*fac;
00183     anf=an*fac;
00184     a1=x*a0+anf*a1;
00185     b1=x*b0+anf*b1;
00186     if (a1) {
00187       fac=1.0/a1;
00188       g=b1*fac;
00189       if (fabs((g-gold)/g) < EPS) {
00190     gammcf=exp(-x+a*log(x)-gln)*g;
00191     return;
00192       }
00193       gold=g;
00194     }
00195   }
00196   std::cout << "a too large, ITMAX too small in routine GCF" << std::endl;
00197 }

double NMFit::gammln ( double  xx  ) 

Definition at line 202 of file NMFit.cxx.

References x.

Referenced by gcf(), and gser().

00202                               {
00203 
00204   double x,tmp,ser;
00205   static double cof[6]={76.18009173,-86.50532033,24.01409822,
00206             -1.231739516,0.120858003e-2,-0.536382e-5};
00207   int j;
00208 
00209   x=xx-1.0;
00210   tmp=x+5.5;
00211   tmp -= (x+0.5)*log(tmp);
00212   ser=1.0;
00213   for (j=0;j<=5;j++) {
00214     x += 1.0;
00215     ser += cof[j]/x;
00216   }
00217   return -tmp+log(2.50662827465*ser);
00218 }

double NMFit::FitPol ( int  pow,
int  n,
const double *  x,
const double *  y,
const double *  w,
double *  par,
double *  pErr = 0 
)

Fits points to a polynomial of a given degree, returns chi squared, and if desired, errors on parameters.

If w is 0 (NULL pointer), then the errors are all set to 1

Definition at line 225 of file NMFit.cxx.

References ok, and p.

Referenced by AlignChamW0::AdjustBField(), TOFTempCorrector::FitGraph(), FitGraph(), VtxConFit::FitVertex(), main(), and RosieFCN().

00228 {
00229   pow++;
00230   memset(par, 0, pow * sizeof(double));
00231 
00232   const int kMaxDegree = 16;
00233 
00234   if (pow > kMaxDegree) {
00235     cout << "NMFit::Pol() does not support " << pow - 1
00236      << "-degree polynomial" << endl;
00237     exit(0);
00238   }
00239   if (n < pow) {
00240     cout << "NMFit::Pol() cannot do a " << pow - 1 << "-degree polynomial fit"
00241      << " with " << n << " points" << endl;
00242     return 0;
00243   }
00244 
00245   double mat[kMaxDegree * kMaxDegree];
00246   double vec[kMaxDegree];
00247 
00248   memset(mat, 0, kMaxDegree * kMaxDegree * sizeof(double));
00249   memset(vec, 0, kMaxDegree * sizeof(double));
00250 
00251   double val1; // w * x^(2j)
00252   double val2; // w * y * x^j
00253   double val3; // w * x^j * x^k
00254   double chi2 = 0; // chi^2 = sum_i(w * y^2) - p * v
00255 
00256   // Compute elements of symmetric matrix and vector
00257   // m[j][k] = sum_i (w[i] * x[i]^j * x[i]^k)
00258   // v[j] = sum_i (w[i] * y[i] * x[i]^j)
00259   //
00260   for (int i = 0; i < n; ++i) {
00261     if (w) val1 = fabs(w[i]); // Make sure that weights are definite positive
00262     else val1 = 1.0;
00263 
00264     val2 = val1 * y[i];
00265     chi2 += val2 * y[i]; 
00266 
00267     for (int j = 0; j < pow; ++j) {
00268       vec[j] += val2;
00269       val3 = val1;
00270       for (int k = j; k < pow; ++k) {
00271     mat[j * pow + k] += val3;
00272     mat[k * pow + j] = mat[j * pow + k];
00273     val3 *= x[i];
00274       }
00275 
00276       val1 *= x[i] * x[i]; // We go from element [i][i] to [i+1][i+1], or 2 powerso f x
00277       val2 *= x[i]; 
00278     }
00279 
00280   }
00281 
00282   TMatrixDSym m(pow, mat);
00283   TVectorD v(pow, vec);
00284 
00285   TDecompLU lu(m);
00286   lu.Decompose();
00287   Bool_t ok;
00288   TVectorD p = lu.Solve(v, ok);
00289 
00290   // If errors on parameters are requested, we need matrix inverse
00291   if (pErr) {
00292     TMatrixD inv(pow, pow);
00293     lu.Invert(inv);
00294     for (int i = 0; i < pow; ++i) pErr[i] = sqrt(inv[i][i]);
00295   }
00296 
00297   // Copy parameters and finish computation of chi squared
00298   for (int i = 0; i < pow; ++i) {
00299     par[i] = p[i];
00300     chi2 -= par[i] * vec[i];
00301   }
00302 
00303   return chi2;
00304 }


Generated on Mon Nov 23 08:05:25 2009 for MIPP(E907) by  doxygen 1.4.7