00001 #ifndef __INCLUDE_SFIT_CC__
00002 #define __INCLUDE_SFIT_CC__
00003
00004 #include <ctime>
00005
00006 #include "sfit.h"
00007
00008
00009 #include "minimization.h"
00010
00011 int CCF2SFit::nmaxpars=10;
00012 bool CCF2SFit::MCsourceflag=0;
00013
00014 void CParInfo::Set(string nameset, double xset, double errorset, double xminset, double xmaxset){
00015 strcpy(name,nameset.c_str());
00016 currentx=xset;
00017 error=errorset;
00018 xmin=xminset;
00019 xmax=xmaxset;
00020 }
00021
00022 CParInfo::CParInfo(){
00023 name= new char [20];
00024 }
00025
00026 CParInfo::~CParInfo(){
00027 delete [] name;
00028 }
00029
00030 void CCF2SFit::SetCalcFlag( int calcflagset){
00031 calcflag=calcflagset;
00032 }
00033
00034 void CCF2SFit::SetMCSourceFlag( bool MCsourceflagset){
00035 MCsourceflag=MCsourceflagset;
00036 }
00037
00038 void CCF2SFit::SetPar(string parstring, double xset){
00039 int i;
00040 char parname[20];
00041 strcpy(parname,parstring.c_str());
00042 i=0;
00043 while (Misc::comparestrings(par[i]->name,parname)==0 && i<nmaxpars){
00044 i+=1;
00045 }
00046 if (i<nmaxpars) par[i]->currentx=xset;
00047 else printf("Can not set %s, parameter with that name does not exist\n",parname);
00048 }
00049
00050 double CCF2SFit::GetPar(string parstring){
00051 int i;
00052 double xvalue;
00053 char parname[20];
00054 strcpy(parname,parstring.c_str());
00055 i=0;
00056 while (Misc::comparestrings(par[i]->name,parname)==0 && i<nmaxpars){
00057 i+=1;
00058 }
00059 if(i<nmaxpars) xvalue=par[i]->bestx;
00060 else{
00061 printf("Can not set %s, parameter with that name does not exist\n",parname);
00062 xvalue=0.0;
00063 }
00064 return xvalue;
00065 }
00066
00067 void CCF2SFit::SetPar(string parstring, double xset, double errorset,double xminset, double xmaxset){
00068 int i;
00069 char parname[20];
00070 strcpy(parname,parstring.c_str());
00071 i=0;
00072 while (Misc::comparestrings(par[i]->name,parname)==0 && i<nmaxpars){
00073 i+=1;
00074 }
00075 if (i<nmaxpars) par[i]->Set(parstring,xset,errorset,xminset,xmaxset);
00076 else printf("Can not set %s, parameter with that name does not exist\n",
00077 parname);
00078 }
00079
00080 void CCF2SFit::AddPar(string parstring, double xset, double errorset,double xminset, double xmaxset){
00081 if (npars>nfreepars) SwitchPars(nfreepars,npars);
00082 nfreepars+=1;
00083 npars+=1;
00084 if (nfreepars<nmaxpars){
00085 par[nfreepars-1]->Set(parstring,xset,errorset,xminset,xmaxset);
00086 parameter::set(sourcecalc->spars,parstring,xset);
00087 }
00088 else{
00089 printf("Too Many Parameters! Increase static int CCF2SFit::nmaxpars\n");
00090 exit(1);
00091 }
00092 ErrorMatrix[nfreepars-1][nfreepars-1]=errorset*errorset;
00093 StepMatrix[nfreepars-1][nfreepars-1]=errorset;
00094 }
00095
00096 void CCF2SFit::UseBestPars(){
00097 int i;
00098 currentchisquared=bestchisquared;
00099 for (i=0;i<nfreepars;i++) par[i]->currentx=par[i]->bestx;
00100 }
00101
00102 void CCF2SFit::SetL( int lxset, int lyset, int lzset){
00103 lx=lxset;
00104 ly=lyset;
00105 lz=lzset;
00106 }
00107
00108 void CCF2SFit::SwitchPars( int i, int j){
00109 int k;
00110 CParInfo *partemp;
00111 partemp=par[j];
00112 par[j]=par[i];
00113 par[i]=partemp;
00114
00115 for (k=0;k<nmaxpars;k++){
00116 SwitchValues(&ErrorMatrix[i][k],&ErrorMatrix[j][k]);
00117 SwitchValues(&ErrorMatrix[k][i],&ErrorMatrix[k][j]);
00118 SwitchValues(&StepMatrix[i][k],&StepMatrix[j][k]);
00119 SwitchValues(&StepMatrix[k][i],&StepMatrix[k][j]);
00120 }
00121 }
00122
00123 void CCF2SFit::SwitchValues( double *a, double *b){
00124 double dummy;
00125 dummy=*a;
00126 *a=*b;
00127 *b=dummy;
00128 }
00129
00130 void CCF2SFit::FreePar(string parstring){
00131 int i;
00132 char parname[20];
00133 strcpy(parname,parstring.c_str());
00134 i=nfreepars;
00135 while (Misc::comparestrings(par[i]->name,parname)==0 && i<npars){
00136 i+=1;
00137 }
00138 if (i==nmaxpars) printf("Par %s already free or does not exist\n",
00139 parstring.c_str());
00140 else{
00141 if (i!=nfreepars) SwitchPars(i,nfreepars);
00142 par[nfreepars]->fixed=false;
00143 printf("Freeing par[%d], name=%s\n",nfreepars,par[nfreepars]->name);
00144 nfreepars+=1;
00145 }
00146 }
00147
00148 void CCF2SFit::FixPar(string parstring){
00149 int i;
00150 char parname[20];
00151 strcpy(parname,parstring.c_str());
00152 i=0;
00153 while (Misc::comparestrings(par[i]->name,parname)==0 && i<nfreepars){
00154 i+=1;
00155 }
00156 if (i==nfreepars) printf("Par %s already fixed or does not exist\n",
00157 parstring.c_str());
00158 else{
00159 if (i!=nfreepars-1) SwitchPars(i,nfreepars-1);
00160 nfreepars-=1;
00161 par[nfreepars]->fixed=true;
00162 printf("Fixing par[%d], name=%s\n",nfreepars,par[nfreepars]->name);
00163 }
00164
00165 }
00166
00167 void CCF2SFit::PrintPars(){
00168 int i;
00169 printf("ipar name value error min max fixed\n");
00170 for (i=0;i<npars;i++){
00171 printf("%2d : %12s %11.4e %11.4e %11.4e %11.4e %d\n",
00172 i,par[i]->name,par[i]->currentx,par[i]->error,
00173 par[i]->xmin,par[i]->xmax,int(par[i]->fixed));
00174 }
00175 }
00176
00177 void CCF2SFit::Init(){
00178 int i,j;
00179 ResetChiSquared();
00180 nfreepars=npars=0;
00181 ncalls=0;
00182 randy= new CRandom(-1234);
00183 par= new CParInfo *[nmaxpars];
00184 ErrorMatrix= new double *[nmaxpars];
00185 StepMatrix= new double *[nmaxpars];
00186 for (i=0;i<nmaxpars;i++){
00187 par[i]= new CParInfo();
00188 par[i]->bestx=0.0;
00189 par[i]->xmin=-1.0E10; par[i]->xmax=1.0E10;
00190 ErrorMatrix[i]= new double [nmaxpars];
00191 StepMatrix[i]= new double [nmaxpars];
00192 par[i]->fixed=false;
00193 for (j=0;j<nmaxpars;j++){
00194 ErrorMatrix[i][j]=0.0;
00195 StepMatrix[i][j]=0.0;
00196 }
00197 }
00198 printf("SFit Initialized\n");
00199 }
00200
00201 void CCF2SFit::ResetChiSquared(){
00202 currentchisquared=1.0E20;
00203 bestchisquared=1.0E20;
00204 }
00205
00206 void CCF2SFit::InitErrorMatrix(){
00207 int i,j;
00208 for (i=0;i<nfreepars;i++){
00209 for (j=0;j<nfreepars;j++){
00210 if (i!=j){
00211 ErrorMatrix[i][j]=StepMatrix[i][j]=0.0;
00212 }
00213 else{
00214 StepMatrix[i][j]=par[i]->error;
00215 ErrorMatrix[i][j]=par[i]->error*par[i]->error;
00216 }
00217 }
00218 }
00219 }
00220
00221 void CCF2SFit::UpdateStepMatrix(){
00222 int i,j;
00223 double *SMeigenval;
00224 CGSLMatrix_Real *matrixcalc;
00225 matrixcalc= new CGSLMatrix_Real(nfreepars);
00226 SMeigenval= new double [nfreepars];
00227 matrixcalc->EigenFind(ErrorMatrix,StepMatrix,SMeigenval);
00228 for (i=0;i<nfreepars;i++){
00229 if (SMeigenval[i]<-1.0E-10){
00230 printf("FATAL: In UpdateStepSize, negative eigenvalue, =%g\n",
00231 SMeigenval[i]);
00232 exit(1);
00233 }
00234 }
00235 for (i=0;i<nfreepars;i++){
00236 par[i]->error=0.0;
00237 for (j=0;j<nfreepars;j++){
00238 StepMatrix[i][j]=StepMatrix[i][j]
00239 *sqrt(fabs(SMeigenval[j]));
00240 par[i]->error+=StepMatrix[i][j]*StepMatrix[i][j];
00241 }
00242 par[i]->error=sqrt(par[i]->error);
00243 }
00244 delete [] SMeigenval;
00245 delete (matrixcalc);
00246 }
00247
00248 void CCF2SFit::PrintErrorMatrix(){
00249 int ia,ib;
00250 printf("________ < delX_i delX_j > ________\n");
00251 for (ia=0;ia<nfreepars;ia++){
00252 for (ib=0;ib<nfreepars;ib++) printf("%9.2e ",ErrorMatrix[ia][ib]);
00253 printf("\n");
00254 }
00255 printf("___________________________________\n");
00256 }
00257
00258 void CCF2SFit::PrintStepMatrix(){
00259 int ia,ib;
00260 printf("________ < StepMatrix_ij > ________\n");
00261 for (ia=0;ia<nfreepars;ia++){
00262 for (ib=0;ib<nfreepars;ib++) printf("%9.2e ",StepMatrix[ia][ib]);
00263 printf("\n");
00264 }
00265 printf("___________________________________\n");
00266 }
00267
00268 CCF2SFit::CCF2SFit(){
00269 sourceCH=NULL;
00270 source3D=NULL;
00271 lista=NULL;
00272 listb=NULL;
00273 kernel=NULL;
00274 kernelwf=NULL;
00275 wf=NULL;
00276 cexp3D=NULL;
00277 cerror3D=NULL;
00278 ctheory3D=NULL;
00279 cexpCH=NULL;
00280 cerrorCH=NULL;
00281 ctheoryCH=NULL;
00282 Init();
00283 }
00284
00285 CCF2SFit::CCF2SFit(CCHArray *sourceCHset,C3DArray *source3Dset,CMCList *listaset,CMCList *listbset,CKernel *kernelset,CKernelWF *kernelwfset,CWaveFunction *wfset,C3DArray *cexp3Dset,C3DArray *cerror3Dset,C3DArray *ctheory3Dset,CCHArray *cexpCHset,CCHArray *cerrorCHset,CCHArray *ctheoryCHset){
00286 sourceCH=sourceCHset;
00287 source3D=source3Dset;
00288 lista=listaset;
00289 listb=listbset;
00290 kernel=kernelset;
00291 kernelwf=kernelwfset;
00292 wf=wfset;
00293 cexp3D=cexp3Dset;
00294 cerror3D=cerror3Dset;
00295 ctheory3D=ctheory3D;
00296 cexpCH=cexpCHset;
00297 cerrorCH=cerrorCHset;
00298 ctheoryCH=ctheoryCHset;
00299 Init();
00300 }
00301
00302 CCF2SFit::~CCF2SFit(){
00303 int i;
00304 delete [] par;
00305 for (i=0;i<nmaxpars;i++){
00306 delete [] ErrorMatrix[i];
00307 delete [] StepMatrix[i];
00308 }
00309 delete [] ErrorMatrix;
00310 delete [] StepMatrix;
00311 }
00312
00313 double CCF2SFit::GetChiSquared( double *xx){
00314 double chisquared;
00315 int i;
00316 double *x;
00317 ncalls+=1;
00318 x= new double [nfreepars];
00319 for (i=0;i<nfreepars;i++) x[i]=xx[i];
00320
00321
00322
00323
00324
00325 for (i=0;i<nfreepars;i++){
00326 parameter::set(sourcecalc->spars,par[i]->name,x[i]);
00327 }
00328 if (calcflag==1){
00329 sourcecalc->CalcS(lx,ly,lz,sourceCH);
00330 S2CF::s2c(sourceCH,kernel,ctheoryCH);
00331 chisquared=CFCalc::GetChiSquared(lx,ly,lz,cexpCH,cerrorCH,ctheoryCH);
00332 }
00333 else if (calcflag==2){
00334
00335
00336
00337 sourcecalc->CalcS(sourceCH);
00338 S2CF::s2c(sourceCH,kernel,ctheoryCH);
00339 ctheoryCH->FillRemainderX();
00340 ArrayCalc::Calc3DArrayFromAExpArray(ctheoryCH,ctheory3D);
00341 chisquared=CFCalc::GetChiSquared(cexp3D,cerror3D,ctheory3D);
00342
00343
00344
00345
00346
00347 }
00348 else if (calcflag==3){
00349 sourcecalc->CalcS(lista,listb);
00350 S2CF::s2c(lista,listb,kernelwf,ctheory3D);
00351 chisquared=CFCalc::GetChiSquared(cexp3D,cerror3D,ctheory3D);
00352 }
00353 else if (calcflag==4){
00354 sourcecalc->CalcS(lista,listb);
00355 S2CF::s2c(lista,listb,wf,ctheory3D);
00356 chisquared=CFCalc::GetChiSquared(cexp3D,cerror3D,ctheory3D);
00357 }
00358
00359 else if (calcflag==5){
00360 time_t start,end;
00361 time(&start);
00362
00363 sourcecalc->CalcS(sourceCH);
00364 S2CF::s2c(sourceCH,kernel,ctheoryCH);
00365 ctheoryCH->FillRemainderX();
00366 ArrayCalc::Calc3DArrayFromAExpArray(ctheoryCH,ctheory3D);
00367 chisquared=CFCalc::GetChiSquared(cexp3D,cerror3D,ctheory3D);
00368
00369 time(&end);
00370 double dif = difftime(end, start);
00371 printf("%g seconds ",dif);
00372
00373 }
00374 else if (calcflag==6){
00375 sourcecalc->CalcS(source3D);
00376 S2CF::s2c(source3D,kernelwf,ctheory3D);
00377 chisquared=CFCalc::GetChiSquared(cexp3D,cerror3D,ctheory3D);
00378 }
00379 else if(calcflag==7){
00380 sourcecalc->CalcS(sourceCH);
00381 S2CF::s2c(sourceCH,kernel,ctheoryCH);
00382 ctheoryCH->FillRemainderX();
00383 chisquared=CFCalc::GetChiSquared(cexpCH,cerrorCH,ctheoryCH);
00384 }
00385 else if(calcflag==8){
00386 sourcecalc->GaussCFCalc(ctheory3D);
00387 chisquared=CFCalc::GetChiSquared(cexp3D,cerror3D,ctheory3D);
00388 }
00389 else if(calcflag==9){
00390 sourcecalc->randy->reset(-1234);
00391 S2CF::s2c_gauss(sourcecalc,kernelwf,ctheory3D);
00392 chisquared=CFCalc::GetChiSquared(cexp3D,cerror3D,ctheory3D);
00393 }
00394
00395 if (chisquared<bestchisquared){
00396 bestchisquared=chisquared;
00397 for (i=0;i<nfreepars;i++) par[i]->bestx=x[i];
00398 }
00399 return chisquared;
00400 delete [] x;
00401 }
00402
00403 void CCF2SFit::Newton(int maxtries){
00404 bool success,screwy;
00405 int i,j,k,itry,nrescale,nsuccess;
00406 double **curvature,*slope,**eigenvec;
00407 double *x,*xnew,*xa,*xb,*xc,*xd,*delx,*dx,*eigenval;
00408 double chi2,chi2a,chi2b,chi2c,chi2d,newchi2,scheck;
00409 CGSLMatrix_Real *matrixcalc;
00410 matrixcalc= new CGSLMatrix_Real(nfreepars);
00411 slope= new double [nfreepars];
00412 x= new double [nfreepars];
00413 xnew= new double [nfreepars];
00414 xa= new double [nfreepars];
00415 xb= new double [nfreepars];
00416 xc= new double [nfreepars];
00417 xd= new double [nfreepars];
00418 delx= new double [nfreepars];
00419 dx= new double [nfreepars];
00420 eigenval=new double[nfreepars];
00421 curvature= new double *[nfreepars];
00422 eigenvec=new double *[nfreepars];
00423 for (i=0;i<nfreepars;i++){
00424 curvature[i]= new double [nfreepars];
00425 eigenvec[i]=new double[nfreepars];
00426 }
00427
00428 for (i=0;i<nfreepars;i++){
00429 dx[i]=par[i]->error;
00430 x[i]=par[i]->currentx;
00431 }
00432
00433 nsuccess=itry=0;
00434 do{
00435 itry+=1;
00436 chi2=GetChiSquared(x);
00437 NEWSTART:
00438 for (i=1;i<nfreepars;i++){
00439 for (j=0;j<i;j++){
00440 for (k=0;k<nfreepars;k++) xa[k]=xb[k]=xc[k]=xd[k]=x[k];
00441 xa[i]+=dx[i]; xa[j]+=dx[j];
00442 xb[i]+=dx[i]; xb[j]-=dx[j];
00443 xc[i]-=dx[i]; xc[j]+=dx[j];
00444 xd[i]-=dx[i]; xd[j]-=dx[j];
00445 chi2a=GetChiSquared(xa);
00446 chi2b=GetChiSquared(xb);
00447 chi2c=GetChiSquared(xc);
00448 chi2d=GetChiSquared(xd);
00449 curvature[i][j]=(chi2a+chi2d-chi2b-chi2c)/(4.0*dx[i]*dx[j]);
00450 curvature[j][i]=curvature[i][j];
00451 printf("___ itry=%d, Curvature[%d][%d]=%g ___\n",
00452 itry,i,j,curvature[i][j]);
00453 }
00454 }
00455 for (i=0;i<nfreepars;i++){
00456 for (k=0;k<nfreepars;k++) xa[k]=xb[k]=x[k];
00457 xa[i]+=dx[i];
00458 xb[i]-=dx[i];
00459 chi2a=GetChiSquared(xa);
00460 chi2b=GetChiSquared(xb);
00461 curvature[i][i]=(chi2a-2*chi2+chi2b)/(dx[i]*dx[i]);
00462 printf("___ itry=%d, Curvature[%d][%d]=%g ___\n",itry,i,i,curvature[i][i]);
00463 slope[i]=(chi2a-chi2b)/(2.0*dx[i]);
00464 }
00465 matrixcalc->SolveLinearEqs(slope,curvature,delx);
00466 matrixcalc->EigenFind(curvature,eigenvec,eigenval);
00467 screwy=0;
00468 for(i=0;i<nfreepars;i++){
00469 if(eigenval[i]<0.0){
00470 printf("NEWTON's METHOD: screwy eigenval[i]=%g, is less than zero\n",eigenval[i]);
00471 screwy=1;
00472 }
00473 }
00474 if(screwy==1){
00475 if(fabs(chi2-bestchisquared)<1.0E-20) exit(1);
00476 for(i=0;i<nfreepars;i++) x[i]=par[i]->bestx;
00477 chi2=bestchisquared;
00478 goto NEWSTART;
00479 }
00480 nrescale=0;
00481 TRY_RESCALED:
00482 printf("delx[] = ");
00483 for (i=0;i<nfreepars;i++){
00484 printf("%g ",delx[i]);
00485 xnew[i]=x[i]-delx[i];
00486 }
00487 printf("\n");
00488
00489 for (i=0;i<nfreepars;i++){
00490 if (par[i]->fixed==false){
00491 if (xnew[i]<par[i]->xmin || xnew[i]>par[i]->xmax){
00492 for (j=0;j<nfreepars;j++) delx[j]=0.5*delx[j];
00493 printf("Stepped outside min/max, will rescale delx[]\n");
00494 if (nrescale>4) exit(1);
00495 nrescale+=1;
00496 goto TRY_RESCALED;
00497 }
00498 }
00499 }
00500
00501 newchi2=GetChiSquared(xnew);
00502 if (newchi2>chi2){
00503 for (j=0;j<nfreepars;j++){
00504 delx[j]=0.5*delx[j];
00505 }
00506 printf("new chi^2 bigger than previous, will rescale delx[]\n");
00507 goto TRY_RESCALED;
00508 }
00509
00510 success=1;
00511 scheck=0.0;
00512 for (i=0;i<nfreepars;i++){
00513 for (j=0;j<nfreepars;j++){
00514 scheck+=curvature[i][j]*delx[i]*delx[j];
00515 }
00516 }
00517 if (scheck<1.0) success=1;
00518
00519 if (success){
00520 printf("SUCCESS!!!!!!!!!!!\n");
00521 nsuccess+=1;
00522 CalcErrorMatrixFromCurvature(curvature);
00523 for (i=0;i<nfreepars;i++) dx[i]=par[i]->error;
00524 }
00525
00526 chi2=newchi2;
00527 for (i=0;i<nfreepars;i++) x[i]=xnew[i];
00528 }while (itry<maxtries && nsuccess<2);
00529
00530 currentchisquared=chi2;
00531 for (i=0;i<nfreepars;i++) par[i]->currentx=x[i];
00532
00533 delete [] dx;
00534 delete [] x;
00535 delete [] xnew;
00536 delete [] delx;
00537 delete [] xa;
00538 delete [] xb;
00539 delete [] xc;
00540 delete [] xd;
00541 delete [] slope;
00542 delete [] eigenval;
00543 for (i=0;i<nfreepars;i++){
00544 delete [] curvature[i];
00545 delete [] eigenvec[i];
00546 }
00547 delete [] curvature;
00548 delete [] eigenvec;
00549 delete (matrixcalc);
00550 }
00551
00552 void CCF2SFit::CalcErrorMatrixFromCurvature( double **C){
00553 int i,j,k;
00554 CGSLMatrix_Real *matrixcalc;
00555 double **U;
00556 double *EigenVal;
00557 matrixcalc= new CGSLMatrix_Real(nfreepars);
00558 EigenVal= new double [nfreepars];
00559 U= new double *[nfreepars];
00560 for (i=0;i<nfreepars;i++) U[i]= new double [nfreepars];
00561 matrixcalc->EigenFind(C,U,EigenVal);
00562
00563 for (i=0;i<nfreepars;i++){
00564 for (j=0;j<=i;j++){
00565 if (i<nfreepars && j<nfreepars){
00566 ErrorMatrix[i][j]=0.0;
00567 for (k=0;k<nfreepars;k++){
00568 ErrorMatrix[i][j]+=U[i][k]*U[j][k]/EigenVal[k];
00569 }
00570 }
00571 else ErrorMatrix[i][j]=0.0;
00572 if (i!=j) ErrorMatrix[j][i]=ErrorMatrix[i][j];
00573 }
00574 par[i]->error=sqrt(fabs(ErrorMatrix[i][i]));
00575 }
00576
00577 for (i=0;i<nfreepars;i++) delete [] U[i];
00578 delete [] U;
00579 delete [] EigenVal;
00580 delete (matrixcalc);
00581 }
00582
00583
00584 void CCF2SFit::ConjugateGradient( int maxcalls){
00585 int i;
00586 double * x = new double [nfreepars];
00587 for (i=0;i<nfreepars;i++)
00588 {
00589 x[i] = par[i]->currentx;
00590 }
00591 SetDimension(nfreepars);
00592 double fmin;
00593 int iter;
00594 if (conjugate_gradient(x, iter, fmin) == true )
00595 {
00596 printf("SUCCESS in Conjugate gradient method after %d iterations\n",iter);
00597 currentchisquared=fmin;
00598 for ( int i=0;i<nfreepars;i++)
00599 {
00600 par[i]->currentx = x[i];
00601 }
00602 }
00603
00604 printf("Best chi^2=%g, Best x[] = ",bestchisquared);
00605 for (i=0;i<nfreepars;i++) printf("%g ",par[i]->bestx);
00606 printf("\n");
00607
00608 delete [] x;
00609 }
00610
00611
00612 double CCF2SFit::fn( double * x){
00613 return GetChiSquared(x);
00614 }
00615
00616
00617 bool CCF2SFit::dfn( double * x){
00618 double * x_minus = new double [nfreepars];
00619 double * x_plus = new double [nfreepars];
00620 double delta_x;
00621
00622 for ( int i=0;i<nfreepars;i++)
00623 {
00624 x_minus[i] = x[i];
00625 x_plus[i] = x[i];
00626 }
00627 for ( int i=0;i<nfreepars;i++)
00628 {
00629
00630 delta_x = fabs(x[i] * 1.0e-3) > 1.0e-4 ? fabs(x[i] * 1.0e-3) : 1.0e-4;
00631 x_minus[i] = x[i] - delta_x;
00632 x_plus[i] = x[i] + delta_x;
00633 vec_dx[i] = 0.5 * (GetChiSquared(x_plus) - GetChiSquared(x_minus)) / delta_x;
00634 x_minus[i] = x[i];
00635 x_plus[i] = x[i];
00636 }
00637 for ( int i=0;i<nfreepars;i++)
00638 {
00639 printf("dx[%d] = %g, ", i, vec_dx[i]);
00640 }
00641 printf("\n");
00642 delete [] x_minus;
00643 delete [] x_plus;
00644 return true ;
00645 }
00646
00647 void CCF2SFit::Metropolis( int maxcalls){
00648 int icall,i,j,Nsuccess=0;
00649 bool success;
00650 double stepscale,step,chisquared;
00651 double *x,*xran,*xbar;
00652 x= new double [nfreepars];
00653 xran= new double [nfreepars];
00654 xbar= new double [nfreepars];
00655 for (i=0;i<nfreepars;i++){
00656 x[i]=par[i]->currentx;
00657 xbar[i]=0.0;
00658 for (j=0;j<nfreepars;j++) ErrorMatrix[i][j]=0.0;
00659 }
00660 stepscale=1.0/sqrt( double (nfreepars));
00661 for (icall=0;icall<maxcalls;icall++){
00662
00663 GETNEWXRAN:
00664 if (MCsourceflag){
00665 for (i=0;i<nfreepars;i++) x[i]=par[i]->currentx;
00666 currentchisquared=GetChiSquared(x);
00667 }
00668 for (j=0;j<nfreepars;j++)
00669 xran[j]=randy->gauss();
00670 for (i=0;i<nfreepars;i++){
00671 if (par[i]->fixed==false){
00672 x[i]=par[i]->currentx;
00673 for (j=0;j<nfreepars;j++){
00674 step=StepMatrix[i][j]*xran[j]*stepscale;
00675 x[i]+=step;
00676 }
00677 }
00678 }
00679 for (i=0;i<nfreepars;i++)
00680 if (x[i]<par[i]->xmin || x[i]>par[i]->xmax) goto GETNEWXRAN;
00681
00682 chisquared=GetChiSquared(x);
00683 success=0;
00684 if (chisquared<currentchisquared){
00685 success=1;
00686 }
00687 else if (randy->ran()<exp(-0.5*(chisquared-currentchisquared))){
00688 success=1;
00689 }
00690
00691 if (success==1){
00692 Nsuccess+=1;
00693 currentchisquared=chisquared;
00694 for (i=0;i<nfreepars;i++) par[i]->currentx=x[i];
00695 printf("SUCCESS, Nsuccess=%d\n",Nsuccess);
00696 }
00697
00698 for (i=0;i<nfreepars;i++){
00699 xbar[i]+=x[i];
00700 for (j=0;j<nfreepars;j++) ErrorMatrix[i][j]+=x[i]*x[j];
00701 }
00702 }
00703
00704 for (i=0;i<nfreepars;i++){
00705 par[i]->xbar=xbar[i]/ double (maxcalls);
00706 for (j=0;j<nfreepars;j++) ErrorMatrix[i][j]=ErrorMatrix[i][j]/ double (maxcalls);
00707 }
00708 for (i=0;i<nfreepars;i++)
00709 for (j=0;j<nfreepars;j++) ErrorMatrix[i][j]=(ErrorMatrix[i][j]-par[i]->xbar*par[j]->xbar)
00710 * double (Nsuccess)/ double (Nsuccess-1);
00711
00712 printf("Best chi^2=%g, Best x[] = ",bestchisquared);
00713 for (i=0;i<nfreepars;i++) printf("%g ",par[i]->bestx);
00714 printf("\n");
00715
00716 delete [] x;
00717 delete [] xran;
00718 delete [] xbar;
00719 }
00720
00721 void CCF2SFit::SteepestDescent( int maxtries){
00722 int i,j,itry,nfailure,nsuccess;
00723 double chisquared,newchisquared,chi2a,chi2b,qstep;
00724 double d2chi2dq2,dchi2dq,dq,qhatnorm;
00725 double *delx,*delq,*x,*xa,*xb,*qxratio,*xnew,*qhat;
00726 delx= new double [nfreepars];
00727 x= new double [nfreepars];
00728 xa= new double [nfreepars];
00729 xb= new double [nfreepars];
00730 xnew= new double [nfreepars];
00731 delq= new double [nfreepars];
00732 qxratio= new double [nfreepars];
00733 qhat=new double[nfreepars];
00734 for (i=0;i<nfreepars;i++){
00735 qxratio[i]=par[i]->error;
00736 x[i]=par[i]->currentx;
00737 }
00738 chisquared=GetChiSquared(x);
00739
00740 for(itry=0;itry<maxtries;itry++){
00741
00742 dq=0.01;
00743 qhatnorm=0.0;
00744 for (i=0;i<nfreepars;i++){
00745 delx[i]=qxratio[i]*dq;
00746 for (j=0;j<nfreepars;j++){
00747 xa[j]=x[j];
00748 xb[j]=x[j];
00749 }
00750 xb[i]=x[i]+0.5*delx[i];
00751 xa[i]=x[i]-0.5*delx[i];
00752 chi2a=GetChiSquared(xa);
00753 chi2b=GetChiSquared(xb);
00754 qhat[i]=-(chi2b-chi2a)*qxratio[i]/delx[i];
00755 qhatnorm+=qhat[i]*qhat[i];
00756 }
00757 for(i=0;i<nfreepars;i++) qhat[i]=qhat[i]/sqrt(qhatnorm);
00758
00759
00760 nsuccess=0;
00761 while(nsuccess<3){
00762 for (i=0;i<nfreepars;i++){
00763 delq[i]=qhat[i]*dq;
00764 delx[i]=delq[i]*qxratio[i];
00765 xa[i]=x[i]-0.5*delx[i];
00766 xb[i]=x[i]+0.5*delx[i];
00767 }
00768 chi2a=GetChiSquared(xa);
00769 chi2b=GetChiSquared(xb);
00770 dchi2dq=(chi2b-chi2a)/dq;
00771 d2chi2dq2=4.0*(chi2b+chi2a-2.0*chisquared)/(dq*dq);
00772 qstep=-dchi2dq/d2chi2dq2;
00773 printf("||||||||| qstep=%g, ",qstep);
00774 if(d2chi2dq2<0.0) printf("upside down curvature\n");
00775 if (fabs(qstep)>1.0) qstep=qstep/fabs(qstep);
00776 if(qstep*dchi2dq>0) qstep=-0.5*qstep/fabs(qstep);
00777 printf("-> %g |||||||||\n",qstep);
00778
00779 TRYNEWQSTEP:
00780 nfailure=0;
00781 for (i=0;i<nfreepars;i++){
00782 delq[i]=qstep*qhat[i];
00783 xnew[i]=x[i]+delq[i]*qxratio[i];
00784 }
00785 newchisquared=GetChiSquared(xnew);
00786 if(newchisquared>chisquared){
00787 qstep=0.5*qstep;
00788 nfailure+=1;
00789 if (nfailure>5){
00790 printf("STEEPEST DESCENT FAILURE\n");
00791 exit(1);
00792 }
00793 goto TRYNEWQSTEP;
00794 }
00795 printf("++++++++++++ qstep=%g ++++++++++++++\n",qstep);
00796 chisquared=newchisquared;
00797 for(i=0;i<nfreepars;i++) x[i]=xnew[i];
00798 if(fabs(qstep)<2.0*dq){
00799 dq=dq/3.0;
00800 nsuccess+=1;
00801 }
00802
00803 }
00804 printf("_______________________ finished itry=%d _______________________________\n",itry);
00805 }
00806
00807 chisquared=GetChiSquared(x);
00808 currentchisquared=chisquared;
00809 for (i=0;i<nfreepars;i++){
00810 if (par[i]->fixed==false) par[i]->currentx=x[i];
00811 }
00812
00813 delete [] xa;
00814 delete [] xb;
00815 delete [] x;
00816 delete [] xnew;
00817 delete [] delx;
00818 delete [] delq;
00819 delete [] qxratio;
00820 delete [] qhat;
00821 }
00822 #endif