Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mdp_fitting_functions.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00015 void linear_fit(float *x, Measure *y, long i0, long in, Measure *a) {
00016   long i;
00017   double S=0,Sx=0,Sy=0,Sxx=0,Sxy=0,det;
00018   double dy2;
00019   for(i=i0; i<in; i++) {
00020     dy2=pow(y[i].error,2.0);
00021     if(dy2<=0) dy2=pow(y[i].mean*1e-5,2.0);
00022     S=S+1.0/dy2;
00023     Sx=Sx+1.0/dy2*x[i];
00024     Sy=Sy+y[i].mean/dy2;
00025     Sxx=Sxx+x[i]*x[i]/dy2;
00026     Sxy=Sxy+y[i].mean/dy2*x[i];
00027   }
00028   det=(S*Sxx-Sx*Sx);
00029   // this is m
00030   a[0].mean=(S*Sxy-Sx*Sy)/det;
00031   a[0].error=sqrt(S/det);
00032   // this is q
00033   a[1].mean=(Sxx*Sy-Sx*Sxy)/det;
00034   a[1].error=sqrt(Sxx/det);
00035 }
00036 
00037 
00042 float golden_rule(float (*fp)(float*, long, void*), float &xmin, 
00043                   float ax, float bx, float cx,
00044                   float tol=0.001, long niter=100, void *dummy=0) {
00045   static const float CGOLD=0.3819660;
00046   long iter;
00047   float a,b,d=0,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
00048   float e=0.0;
00049   a=(ax<cx ? ax:cx);  
00050   b=(ax>cx ? ax:cx);
00051   x=w=v=bx;
00052   fw=fv=fx=(*fp)(&x,1,dummy);
00053   for(iter=0; iter<niter; iter++) {
00054     xm=0.5*(a+b);
00055     tol2=2.0*(tol1=tol*fabs(x)+PRECISION);
00056     if(fabs(x-xm)<=(tol2-0.5*(b-a))) {
00057       xmin=x;
00058       return fx;
00059     }
00060     if(fabs(e)>tol1) {
00061       r=(x-w)*(fx-fv);
00062       q=(x-v)*(fx-fw);
00063       p=(x-v)*q-(x-w)*r;
00064       q=2.0*(q-r);
00065       if(q>0.0) p=-p;
00066       q=fabs(q);
00067       etemp=e;
00068       e=d;
00069       if(fabs(p)>=fabs(0.5*q*etemp) || p<=q*(a-x) || p>=q*(b-x))
00070         d=CGOLD*(e=((x>=xm) ? (a-x) : (b-x)));
00071       else {
00072         d=p/q;
00073         u=x+d;
00074         if(u-a < tol2 || (b-u) < tol2) {
00075           d=fabs(tol1);
00076           if(xm - x < 0.0) d=-d;
00077         }
00078       }
00079     } else {
00080       d=CGOLD*(e=(x>=xm ? (a-x) : (b-x)));
00081     }
00082     if(fabs(d)>=tol1) u=x+d; else u=x+(d>0 ? fabs(tol1): -fabs(tol1));
00083     fu=(*fp)(&u,1,dummy);
00084     if(fu <= fx) {
00085       if(u>x) a=x; else b=x;
00086       v=w; w=x; x=u;
00087       fv=fw; fw=fx; fx=fu;
00088     } else {
00089       if(u<x) a=u; else b=u;
00090       if(fu<fw || w==x) {
00091         v=w; w=u;
00092         fv=fw; fw=fu;
00093       } else if(fu <= fv || v==x || v==w) {
00094         v=u;
00095         fv=fu;
00096       }
00097     }
00098   }
00099   printf("Too many iterations in golden_rune\n");
00100   xmin=x;
00101   return fx;
00102 }
00103 
00104 typedef float (*BLM_function)(float, float*, long, void*);
00105 
00121 
00122 float BLMaux(float *x, Measure *y, 
00123 long i_min, long i_max, 
00124 float *a, float *a0, mdp_matrix &sigma, int ma,
00125              mdp_matrix &alpha,
00126              mdp_matrix &beta,
00127              BLM_function func,
00128              float h,
00129              void *junk) {
00130   long i,j,k;
00131   double sig2i, chi_square, dy, ymod, wt;
00132   double *dyda=new double[ma];
00133 
00134   for(i=0; i<ma; i++) {
00135     for(j=0; j<ma; j++) 
00136       alpha(i,j)=0.0;
00137     beta(i,0)=0.0;
00138   }
00139   chi_square=0.0;
00140   for(i=i_min; i<i_max; i++) {
00141     ymod=(*func)(x[i],a,ma,junk);
00142     for(j=0; j<ma; j++) { 
00143       a[j]+=h;
00144       dyda[j]=(*func)(x[i],a,ma,junk);
00145       a[j]-=2*h;
00146       dyda[j]-=(*func)(x[i],a,ma,junk);
00147       a[j]+=h;
00148       dyda[j]/=(2.0*h);
00149     }
00150     sig2i=1.0/pow(y[i].error,2.0);
00151     dy=y[i].mean-ymod;
00152     for(j=0; j<ma; j++) {
00153       wt=dyda[j]*sig2i;
00154       for(k=0; k<ma; k++)
00155         alpha(j,k)+=dyda[k]*wt*y[i].num;
00156       beta(j,0)+=dy*wt*y[i].num;
00157     }
00158     chi_square+=dy*dy*sig2i;
00159   }
00160   
00161   for(i=0; i<ma; i++) 
00162     for(j=0; j<ma; j++)
00163       chi_square+=(a0[i]-a[i])*sigma(i,j).re*(a0[j]-a[j]);
00164   
00165   delete[] dyda;
00166   return chi_square;
00167 }
00168 
00191 
00192 float BaesyanLevenbergMarquardt(float *x, Measure *y, 
00193                                 long i_min, long i_max, 
00194                                 float *a, int ma,
00195                                 mdp_matrix &covar, 
00196                                 BLM_function func,
00197                                 float h=0.001, 
00198                                 long nmax=1000,
00199                                 void *junk=0) {
00200   
00201   double lambda=0.1;
00202   double scale=2;
00203   double chi_square=0;
00204   double old_chi_square=0;
00205   mdp_matrix alpha(ma,ma);
00206   float *atry=new float[ma];
00207   float *a0=new float[ma];
00208   mdp_matrix sigma(ma,ma);
00209   mdp_matrix beta(ma,1);
00210   mdp_matrix oneda(ma,1);
00211   long i,j,k,n;
00212 
00213   if(max(covar)<=1e-6) 
00214     for(i=0; i<ma; i++)
00215       sigma(i,i)=0;
00216   else 
00217     sigma=inv(covar);
00218 
00219   for(i=0; i<ma; i++) {
00220     atry[i]=a[i];
00221     a0[i]=a[i];
00222   }
00223   chi_square=BLMaux(x,y,i_min,i_max,a,a0,sigma,
00224                     ma,alpha,beta,func,h,junk);
00225   old_chi_square=chi_square;
00226   
00227   for(n=0; n<nmax; n++) {
00228     for(i=0; i<ma; i++) {
00229       for(j=0; j<ma; j++) covar(i,j)=alpha(i,j);
00230       covar(i,i)*=(1.0+lambda);
00231       oneda(i,0)=beta(i,0);
00232     }
00233     
00234     // this is gaussj 
00235     covar=inv(covar);
00236     oneda=covar*oneda;
00237 
00238     for(i=0; i<ma; i++) atry[i]=a[i]+real(oneda(i,0));
00239     chi_square=BLMaux(x,y,i_min,i_max,atry,a0,sigma,
00240                       ma,covar,oneda,func,h,junk);
00241 
00242 
00243     if(fabs(chi_square - old_chi_square)<1e-4 || lambda==0) {
00244       covar=inv(covar);
00245       
00246       delete[] atry;
00247       delete[] a0;
00248       return chi_square;
00249     } else if(chi_square <= old_chi_square) {
00250       lambda/=scale;
00251       old_chi_square=chi_square;
00252       for(i=0; i<ma; i++) {
00253         for(j=0; j<ma; j++)
00254           alpha(i,j)=covar(i,j);
00255         beta(i,0)=oneda(i,0);
00256       }
00257       for(j=0; j<ma; j++) a[j]=atry[j];
00258     } else {
00259       lambda*=scale;
00260       chi_square=old_chi_square;
00261     } 
00262     //    printf("%f %f %f\n", a[0], a[1], lambda);
00263   }
00264 }
00265 

Generated on Sun Feb 27 15:12:20 2005 by  doxygen 1.4.1