#include #include #include #include #include #include "spectrum.h" #include "jessica.h" #include "extrapolate.h" #if defined(USE_MPI) #include "usempi.h" #endif #if HINDEX==2 #define PRINTIT 1 /* Print timing and convergence information */ /* Mesons on the transverse lattice This program searches coupling constant space for a best fit to Poincare symmetries that are broken by the transverse lattice regulator. We test for rotational invariance in the transverse plane. In practice, we will choose the x^1 direction and the x^1=x^2 directions in order to take advandage of residual reflection symmetries. We measure: multi p-truncation convergence for n=(1,0) winding mode 15 longitudinal potential for n=(0,0) and various L 3 longitudinal eigenvalue for n=(1,0) and one L 15 longitudinal eigenvalue for n=(1,1) and one L 17 winding mode potential for various n=(c,0) 15 winding mode potential for one n=(c,c) 17 spectrum for P_perp = (0,0) and (c,0) 9, 8 7, 10 spectrum for P_perp = (c,c) 11, 12 14, 13 ************************************+++++++**********************************/ #define FCSQUARED 1 /* Number of c^2 values in each sector and direction to use in fit. This can be up to NPERPVALS */ #define FPARITY 1 /* Number of parity doublets to fit. */ #define NPERP 4 /* Number of J^{P_1 C} sectors for nonzero perp momentum this must be 4 to cover all multiplets */ #define NPERPVALS 2 /* number of states calculated in each sector */ #define NP1 1 /* Number of nonzero values of P_perp in the (c,0) direction*/ #define NP2 1 /* Number of nonzero values of P_perp in the (c,c) direction*/ /* This can be 1. */ #define NSTILL 10 /*Number of sectors for zero transverse momentum spectra This must be 10 to cover all multiplets. */ #define NSTILLVALS 2 /*Number of states calculated in each sector*/ /*This must be large enough to use for nonzero momenta */ #define MAXTH 10 /* max number of terms in fit functions */ #define FIX_MASSES 2 /* number of masses to fix to experimental values */ #define FEXTRA 0 /* Fit criteria that would not be normally used. */ /*For instance, demanding a specific value for the lattice spacing. */ /* if these are zero, take values from lattice glueball results */ #define NLONG 0 /*Data points used to estimate longitudinal potential */ #define NWIND 0 /* Data points used to estimate winding potential */ #define PNS 0 /* number of sectors in p extrapolation */ #if 0 /* basis simon is using test */ /* This takes about 120 seconds to calculate everything */ #define NS 4 const static int kt[NS]={6,8,10,12}, np[NS]={4,4,4,4}; #if PNS<=4 /* check dimensions */ static int pnp1[4]={1,3,5,7}, pkt1[4]={11,11,11,11}; #endif #elif 1 /* smaller test basis */ /* This takes about 120 seconds to calculate everything */ #define NS 3 const static int kt[NS]={12,14,18}, np[NS]={4,4,4}; #if PNS static int pnp1[PNS]={1,3,5,7}, pkt1[PNS]={11,11,11,11}; #else static int *pnp1=NULL, *pkt1=NULL; #endif #endif /** Choose different possible bases **/ /* Total number of different bases */ #define N_ALL_BASES ((NSTILL+(NP1+NP2)*NPERP)*NS+PNS) static specify_calculation all_bases[N_ALL_BASES]; static specify_calculation *s[NP1][NPERP],*t[NP2][NPERP], *ps1,*stillbases[NSTILL]; element par[NPARAMS]; static int wpar[NPARAMS],scalemethod; static doublereal p1a[NP1][HINDEX]={{0.25,0.0}}, p2a[NP2][HINDEX]={{0.25,0.25}}; static int pht1[HINDEX]={1,0}; /* winding number for p-extrapolation */ /* The error for: c^2 for each state (either direction), roundness of winding mode potential (two data points), and roundness of heavy quark potential, parity doublets (fractional error). */ #if FCSQUARED <= 4 /* check that array is big enough */ static const element c2err[NPERP][4]={{0.25,2.0,2.0,2.0}, {0.25,2.0,2.0,2.0}, {0.25,2.0,2.0,2.0}, {0.25,2.0,2.0,2.0}}; #endif /* These are the parity doublets that are to be compared. */ #if FPARITY<=5 /* This is just the size of the arrays. */ /* relative error for chi^2 fit */ static element parityerr[5]={0.25,0.25,0.25,0.25,0.25}; static struct { int charge; int multi; int state;} whichparity[5][2]={ {{-1,7,0},{-1,3,0}}, /* components of rho */ {{1,5,0},{1,6,0}},{{-1,5,0},{-1,6,0}}, /* lowest J_z=2 doublets */ {{1,7,0},{1,5,0}},{{1,7,0},{1,6,0}}}; #endif /* Error for extra fit criteria. */ #if FEXTRA<2 doublereal extraerr[1]={0.1}; #endif /* experimental meson masses, here I include the lowest state in each J_z^{P_1,C} sector that is not otherwise determined by an O^3 rotational symmetry. The idea is that spin multiplets should be fixed by FPARITY above. */ #if FIX_MASSES<=7 /* This is just the size of the array. */ struct { doublereal value; /* mass^2 in units of the string tension */ doublereal error; /* mass^2 error in units of the string tension */ int charge; int multi; int state; } experiment[7]={{0.094,1.0,1,4,0}, /* pion */ {3.191,2.0,-1,3,0}, /* J_z=0 of the rho */ {4.991,0.6, 1,3,0}, /* a_0(983) */ {7.878,1.0,-1,4,0}, /* J_z=0 of the b_1(1235) */ {8.200,1.0, 1,7,0}, /* J_z=1 of the a_1(1260) */ {9.000,1.0, 1,5,0}, /* J_z=2 of the a_2(1320) */ {14.75,5.0,-1,5,0}}; /* J_z=2 of the rho_2(1690) */ #endif static integer wth,lth; /* These are all the quantities returned by fcn */ static struct {doublereal pextrap; element wfitting[MAXTH]; element lfitting[MAXTH]; element rescale; element spectrumvals1[NP1+1][NPERP][NPERPVALS]; element spectrumvals2[NP2+1][NPERP][NPERPVALS]; element stillvals[NSTILL][NSTILLVALS]; element c2[2][NPERP][NPERPVALS]; } best; #define CHI_DIM ((NP1+NP2)*NPERP*FCSQUARED+FPARITY+FIX_MASSES+FEXTRA) /*Number of dimensions of chi^2 fit*/ #define NOUT 100 /* Output file name length */ /*********************************************************************/ int MAIN(int argc, char **argv){ char out[NOUT],*pout; /* maxfev is the maximum number of iterations in minimizing chi^2. */ integer mm=CHI_DIM,npar=1,maxfev,mode=1,ifail=0,info,nfev,ipvt[NPARAMS]; /* epsfcn should be a little less than the Lanczos accuracy. (say 10 times) ftol should be a little more than epsfcn xtol is the desired precision of the coupling constants factor controls the maximum initial step size. If the starting parameters are near the minimum, this must be decreased to maybe 1. (recommended range: 0.1 to 100, default 100). */ /* epsfcn is the variable used to determine the step size for the finite difference approximation. Since the extrapolations magnify any error in the eigenvalues, this should be comfortably larger than the errors in the lanczos routine. However, it should also be smaller than xtol. */ doublereal xtol=0.01,gtol=0.0,ftol=5.0e-3,epsfcn=5.0e-5,factor=1.0; doublereal vpar[NPARAMS],fvec[CHI_DIM],diag[NPARAMS],fjac[CHI_DIM*NPARAMS]; doublereal qtf[NPARAMS],wa1[NPARAMS],wa2[NPARAMS],wa3[NPARAMS],wa4[CHI_DIM]; int count_bases=0; element angle[HINDEX+2]; element chi2; #if NSTILL==6 int multistill[NSTILL]={3, 5, 5, 6, 6, 7}, /* ostill[NSTILL]={1, 1,-1, 1,-1,-1};*/ charge_still[NSTILL]={1, 1,-1, 1,-1, 1}; #elif NSTILL==10 int multistill[NSTILL]={3, 3, 4, 4, 5, 5, 6, 6, 7, 7}, /* ostill[NSTILL]= {1,-1, 1,-1, 1,-1, 1,-1, 1,-1};*/ charge_still[NSTILL]={1,-1, 1,-1, 1,-1, 1,-1,-1, 1}; #elif NSTILL==12 int multistill[NSTILL]={3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}, /* ostill[NSTILL]={1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1};*/ charge_still[NSTILL]={1,-1, 1,-1, 1,-1, 1,-1,-1, 1,-1, 1}; #endif int i,j,k,l, multis[NPERP]={15,15,16,16}, chargest[NPERP]={1,-1,-1,1}, multit[NPERP]={17,17,18,18}; FILE *fp; #ifdef USE_MPI int myrank; #endif #ifdef BABBAGE /* Routine to initialize Fortran on Babbage */ if(hf_fint((char*)NULL)) exit(1); #endif /* initialize parallelization via MPI when applicable. in this case we use a simple master/slave setup to distribute the construction of the Hamiltonian and the diagonalization of the various bases. */ #ifdef USE_MPI MPI_Init(&argc, &argv); /* initialize MPI */ initmpisectors(); MPI_Comm_rank(MPI_COMM_WORLD,&myrank); if(myrank!=WORLD_MASTER){ slave(); MPI_Finalize(); /* cleanup MPI */ return 0; } #endif /* Choose scale method and open output file */ printf("Output file name: "); fgets(out,NOUT,stdin); if((pout=strchr(out,'\n'))!=NULL)*pout='\0'; printf("%s\n",out); if((fp = fopen(out,"w")) == NULL){ fprintf(stderr,__FILE__": Can't open file %s, exiting\n",out); goto cleanup; } printf("Input maximum number of iterations: "); scanf("%li",&maxfev); printf("Choose method for determining the overall scale:\n" " 0 use scale from glueball calculations\n" " 1 find scale by demanding overall minimum chi^2.\n"); scanf("%i",&scalemethod); /* Print out the results in the output file **/ fprintf(fp,"********* Eigenvalues for the 3+1 transverse lattice *********\n"); fprintf(fp,"Couplings:\n "); for(i=0; i0 fprintf(fp,"Includes %i nonstandard fit criteria (such as a \n" " specific lattice spacing).\n",FEXTRA); #endif #if FTEPER>0 fprintf(fp,"Includes a fit to %i eigenvalues from Teper.\n",FTEPER); #endif #if FPARITY>0 fprintf(fp,"Parity doublets (charge,multi,state) with error for difference\n" " over average.\n"); for(i=0; i0 fprintf(fp,".\nOrdinary spectra multiplets, %i states, (charge,multiplet) =", NSTILLVALS); for(i=0, k=5; i0 " Finally come the states for the ordinary spectra.\n" #endif "\n",NPARAMS); fflush(fp); /******************* make basis structures ****************************/ for(k=0; k4) fprintf(stderr,__FILE__": Error in lmdif info=%li\n",info); if(info==0)goto cleanup; /*Map best values into par[] */ for(i=0; i0){fprintf(fp,"\n");printf("\nwhile fitting");} for(i=0; icharge!=s[0][i]->charge)continue; /* assume that the two spin 1 multiplets are degenerate */ if(((stillbases[j]->multi==3 || stillbases[j]->multi==5 || stillbases[j]->multi==7) && s[0][i]->multi==15) || ((stillbases[j]->multi==4 || stillbases[j]->multi==6 || stillbases[j]->multi==7) && s[0][i]->multi==16)) addterms(spectrumvals1[0][i],&k,NPERPVALS,stillvals[j],NSTILLVALS); if(((stillbases[j]->multi==3 || stillbases[j]->multi==6 || stillbases[j]->multi==7) && t[0][i]->multi==17) || ((stillbases[j]->multi==4 || stillbases[j]->multi==5 || stillbases[j]->multi==7) && t[0][i]->multi==18)) addterms(spectrumvals2[0][i],&l,NPERPVALS,stillvals[j],NSTILLVALS); } if(k!=NPERPVALS || l!=NPERPVALS){ fprintf(stderr,__FILE__": Incorrect multiplet mapping from states " "in ordinary\n" "spectrum to those in nonzero P_perp, exiting\n"); fprintf(stderr," k=%i, l=%i and NPERPVAL=%i\n", k,l,NPERPVALS); *iflag=-12; return SUBRETURN; } } #if 1 /*debugging print of the entire spectrum */ for(k=0; kmulti==experiment[j].multi && stillbases[i]->charge==experiment[j].charge){ sum += stillvals[i][experiment[j].state]* (rescale*stillvals[i][experiment[j].state]- experiment[j].value)/pow(experiment[j].error,2); zz += pow(stillvals[i][experiment[j].state]/experiment[j].error,2); break; } #if FSCALE sum += lfitting[0]*(rescale*lfitting[0]-1.0)/pow(lerr0,2); zz += pow(lfitting[0]/lerr0,2); #endif temp=rescale; /* Here I include a damping factor which will slow convergence but hopefully stablize it. */ rescale -= 0.25*sum/zz; #if 0 /* debugging print */ if(j<100)printf("rescale: j=%i rescale=%.16g\n",j,rescale); #endif /* converge as well as we can, assuming round-off errors */ if(fabs(temp-rescale)<=(2.0+2.0*FCSQUARED)*ELEMENT_EPSILON)break; if(j==1000){ fprintf(stderr,__FILE__": Scale determination not converged, " "rescale=%g\n",rescale); *iflag=-2; break; } } break; default: fprintf(stderr,__FILE__": in fcn, scale method=%i is wrong.\n", scalemethod); *iflag=-14; rescale=0.123456789; /*Find scale by using glueball results */ } /* If rescale is negative for some reason, set it to something large and positive. */ if(rescale<0.0){ rescale=50.0; fprintf(stderr,__FILE__": rescale is negative, set recale=%f.\n", rescale); } /* Calculate the desired dispersion using the overall scale and lattice spacing from glueball calculations. Find error of speed of light squared with coupling g^2 N and "a" as determined above. One can weight the value for our value of sigma. */ fitc=0; temp=wfitting[0]*pow(rescale,2)/fdot(p1a[0],p1a[0],HINDEX); for(i=0; imulti==whichparity[k][0].multi && stillbases[i]->charge==whichparity[k][0].charge)break; for(j=0; jmulti==whichparity[k][1].multi && stillbases[j]->charge==whichparity[k][1].charge)break; if(imulti==experiment[j].multi && stillbases[i]->charge==experiment[j].charge){ fvecc[fitc++]=(rescale*stillvals[i][experiment[j].state]- experiment[j].value)/experiment[j].error; break; } /* Demand that the lattice spacing be a specific value. */ #if FEXTRA==1 fvecc[fitc++]=(1.0+2.0*sqrt(par[0]/par[1])-wfitting[0]*rescale)/ extraerr[0]; #endif /* after including all fit criteria, make sure we have actually filled the fvecc vector. */ if(fitc!=*m){ fprintf(stderr,__FILE__": Fit criteria %i wrong, should be %li\n", fitc,*m); *iflag=-75; return SUBRETURN; } /* check if this is the best chi^2 so far, if so, copy values into the structure best. bestpar makes sure that the unfitted variables are the same; that is the previous best values are from the same fit. */ sum=fdot(fvecc,fvecc,*m); for(i=0; i=0 && (i