00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015 void linear_fit(float *x, Measure *y, mdp_int i0, mdp_int in, Measure *a) {
00016 mdp_int 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
00030 a[0].mean=(S*Sxy-Sx*Sy)/det;
00031 a[0].error=sqrt(S/det);
00032
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*, mdp_int, void*), float &xmin,
00043 float ax, float bx, float cx,
00044 float tol=0.001, mdp_int niter=100, void *dummy=0) {
00045 static const float CGOLD=0.3819660;
00046 mdp_int 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*, mdp_int, void*);
00105
00121
00122 float BLMaux(float *x, Measure *y,
00123 mdp_int i_min, mdp_int 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 mdp_int 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 mdp_int i_min, mdp_int i_max,
00194 float *a, int ma,
00195 mdp_matrix &covar,
00196 BLM_function func,
00197 float h=0.001,
00198 mdp_int 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 mdp_int 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
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
00263 }
00264 }
00265