#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 */ /* Glueballs in 3+1 dimensions 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. This version also demands degeneracy in the lowest parity doublet. It also uses the string tension to determine the lattice spacing. 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 FTEPER 0 /* Number of Teper's lattice states to fit. */ /* This can be 0 or 1 */ #define FCSQUARED NPERPVALS /* Number of c^2 values in each sector and direction to use in fit. This can be up to NPERPVALS */ #define FPARITY 3/* Number of parity doublets to fit. */ /* Suggested: 0, 2, 3, or 5. */ #define FSCALE 1 /*Whether to include consistantcy of the */ /*longitudinal potential with the overall scale. The potential itself is calculated anyway. This can be 0 or 1. */ #define FLONG MAX_LONG /* Number of longitudinal points to fit */ /* This can be 0 to MAX_LONG. */ #define FWIND 1 /* number of winding spectra to fit This can be 0 or 1. */ #define FEXTRA 0 /* Fit criteria that would not be normally used. */ /*For instance, demanding a specific value for the lattice spacing. */ #define NPERP 4 /* Number of J^{P_1 C} sectors for nonzero perp momentum this must be 4 to cover all multiplets */ #define NPERPVALS 4 /* 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*/ #define NSTILL 10 /*Number of J^{P_1 C} sectors for zero transverse momentum spectra This must be 10 to cover all multiplets. */ #define NSTILLVALS 4 /*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 NLONG 3 /*Data points used to estimate longitudinal potential */ #define NWIND 3 /* Data points used to estimate winding potential */ #define MAX_LONG 3 /* max number of criteria for roundness of long. pot.*/ #if 0 /* smaller test basis */ /* This takes about 120 seconds to calculate everything */ #define NS 4 const static int kt[NS]={10,8,10,12}, np[NS]={4,6,6,4}; #define WNS 3 static int wkt0[NWIND][WNS]={{14,14,22},{11,11,21},{12,12,22}}, wnp0[NWIND][WNS]={{6,4,4},{7,5,5},{8,6,6}}, wht0[NWIND][HINDEX]={{2,0},{3,0},{4,0}}; static int wkt[1][WNS]={{14,14,22}},wnp[1][WNS]={{6,4,4}}, wht[1][HINDEX]={{1,1}}; #define LNS 4 static int lkt0[LNS]={12,12,12,16}, lnp0[LNS]={2,4,2,2}, lkt[MAX_LONG][LNS]={{7,7,7,11},{7,7,7,11}, {8,8,10,12}}, lnp[MAX_LONG][LNS]={{3,5,3,3},{3,5,3,3},{2,4,2,2}}; doublereal lkmax[MAX_LONG][LNS]={{3.0,3.0,2.0,3.0},{3.0,3.0,2.0,3.0}, {3.0,3.0,2.0,3.0}},lkmax0[LNS]={3.0,3.0,2.0,3.0}, llong0[NLONG]={2.5,3.0,4.0},llong[MAX_LONG]={2.5,0.5,0.5}, llong0m[NLONG]={0.1,0.1,0.1},llongm[MAX_LONG]={0.1,0.1,0.1}; #define PNS 4 /* number of sectors in p extrapolation */ static int pnp1[PNS]={1,3,5,7}, pkt1[PNS]={11,11,11,11}; #elif 0 /* small basis */ /* this takes about 300 seconds to calculate everything*/ #define NS 4 const static int kt[NS]={14,12,14,16}, np[NS]={4,6,6,4}; #define WNS 3 static int wkt0[NWIND][WNS]={{12,14,16},{9,11,13},{10,12,14}}, wnp0[NWIND][WNS]={{6,4,4},{7,5,5},{8,6,6}}, wht0[NWIND][HINDEX]={{2,0},{3,0},{4,0}}; static int wkt[1][WNS]={{12,14,16}},wnp[1][WNS]={{6,4,4}}, wht[1][HINDEX]={{2,2}}; #define LNS 4 static int lkt0[LNS]={12,12,12,16}, lnp0[LNS]={2,4,2,2}, lkt[MAX_LONG][LNS]={{7,7,7,11},{7,7,7,11}, {8,8,10,12}}, lnp[MAX_LONG][LNS]={{3,5,3,3},{3,5,3,3},{2,4,2,2}}; doublereal lkmax0[LNS]={3.0,3.0,2.0,3.0}, lkmax[MAX_LONG][LNS]={{3.0,3.0,2.0,3.0}, {3.0,3.0,2.0,3.0},{3.0,3.0,2.0,3.0}}, llong0[NLONG]={3.0,4.0,5.0},llong[MAX_LONG]={3.0,1.0,1.0}, llong0m[NLONG]={0.1,0.1,0.1},llongm[MAX_LONG]={0.1,0.1,0.1}; #define PNS 6 /* number of sectors in p extrapolation */ static int pnp1[PNS]={3,3,5,5,7,7},pkt1[PNS]={7,9,7,9,7,9}; #elif 1 /* larger basis */ /* this takes about 25 minutes to calculate everything*/ #define NS 4 const static int kt[NS]={12,12,14,18}, np[NS]={8,6,6,6}; #define WNS 3 #if GLUE_PERIODIC static int wkt0[NWIND][WNS]={{16,16,26},{18,18,26},{16,16,26}}; #else static int wkt0[NWIND][WNS]={{16,16,26},{17,17,25},{16,16,26}}; #endif static int wnp0[NWIND][WNS]={{6,4,4},{7,5,5},{8,6,6}}, wht0[NWIND][HINDEX]={{2,0},{3,0},{4,0}}; static int wkt[1][WNS]={{14,14,22}},wnp[1][WNS]={{8,6,6}}, wht[1][HINDEX]={{2,2}}; #define LNS 7 static int lkt0[LNS]={26,26,26,42,42,70,70}, lnp0[LNS]={2,4,2,2,2,2,2}; #if GLUE_PERIODIC static int lkt[MAX_LONG][LNS]={{14,14,14,24,24,36,36}, {14,14,14,24,24,36,36}, {22,22,22,44,44,70,70}}; #else static int lkt[MAX_LONG][LNS]={{13,13,13,23,23,35,35}, {13,13,13,23,23,35,35}, {22,22,22,44,44,70,70}}; #endif static int lnp[MAX_LONG][LNS]={{3,5,3,3,3,3,3},{3,5,3,3,3,3,3}, {2,4,2,2,2,2,2}}; doublereal lkmax0[LNS]={3.5,3.5,3.0,3.5,4.25,4.0,4.5}, lkmax[MAX_LONG][LNS]={{3.5,3.5,3.0,4.0,4.5,5.0,6.0}, {3.5,3.5,3.0,4.0,4.5,5.0,6.0},{5.0,5.0,4.5,5.0,6.0,6.0,7.0}}, llong0[NLONG]={3.577,5.058,7.154},llong0m[NLONG]={-2.726,-3.856,-5.452}, llong[MAX_LONG]={1.265,5.058,0.0},llongm[MAX_LONG]={-0.964,-3.856,0.0}; #define PNS 7 /* number of sectors in p extrapolation */ static int pnp1[PNS]={3,3,3,5,5,7,7}; #if GLUE_PERIODIC static int pkt1[PNS]={14,22,46,14,28,14,16}; #else static int pkt1[PNS]={13,21,45,13,27,13,15}; #endif #elif 1 /* BIG basis */ /* this takes about 6.654 hours to calculate everything on PC's, 4.14 CPU-hours on the CRAY T3E. max_els=3101540, max_base=2255950 (but this could grow...) */ #define NS 4 const static int kt[NS]={16,16,20,26}, np[NS]={8,6,6,6}; #define NWIND 3 #define WNS 4 #if GLUE_PERIODIC static int wkt0[NWIND][WNS]={{20,20,24,32},{20,20,26,34},{18,18,24,32}}; #else static int wkt0[NWIND][WNS]={{20,20,24,32},{19,19,25,33},{18,18,24,32}}; #endif static int wnp0[NWIND][WNS]={{4,6,4,4},{5,7,5,5},{6,8,6,6}}, wht0[NWIND][HINDEX]={{2,0},{3,0},{4,0}},wkt[1][WNS]={{16,16,24,28}}, wnp[1][WNS]={{6,8,6,6}},wht[1][HINDEX]={{2,2}}; #define LNS 7 static int lkt0[LNS]={40,40,40,50,50,70,70}, lnp0[LNS]={2,4,2,2,2,2,2}; #if GLUE_PERIODIC static int lkt[MAX_LONG][LNS]={{20,20,20,34,34,70,70}, {20,20,20,34,34,70,70}, {34,34,34,48,48,70,70}}; #else static int lkt[MAX_LONG][LNS]={{19,19,19,33,33,69,69}, {19,19,19,33,33,69,69}, {34,34,34,48,48,70,70}}; #endif int lnp[MAX_LONG][LNS]={{3,5,3,3,3,3,3},{3,5,3,3,3,3,3},{2,4,2,2,2,2,2}}; doublereal lkmax0[LNS]={4.0,4.0,3.5,3.75,4.25,4.0,4.5}, lkmax[MAX_LONG][LNS]={{4.0,4.0,3.5,4.0,5.0,5.0,6.0}, {4.0,4.0,3.5,4.0,5.0,5.0,6.0},{5.5,5.5,5.0,5.5,6.5,6.0,7.0}}, llong0[NLONG]={3.577,5.058,7.154},llong0m[NLONG]={-2.726,-3.856,-5.452}, llong[MAX_LONG]={1.265,5.058,0.0},llongm[MAX_LONG]={-0.964,-3.856,0.0}; #define PNS 7 /* number of sectors in p extrapolation */ static int pnp1[PNS]={3,3,3,5,5,7,7}; #if GLUE_PERIODIC static int pkt1[PNS]={14,36,46,14,30,14,18}; #else static int pkt1[PNS]={13,35,45,13,29,13,17}; #endif #endif /** Choose different possible bases **/ /* Total number of different bases */ #define N_ALL_BASES ((NSTILL+(NP1+NP2)*NPERP)*NS+(NWIND+FWIND)*WNS+\ (FLONG+NLONG)*LNS+PNS) static specify_calculation all_bases[N_ALL_BASES]; static specify_calculation *s[NP1][NPERP],*t[NP2][NPERP],*ws0[NWIND],*ws[FWIND], *ls[FLONG],*ls0[NLONG],*ps1,*stillbases[NSTILL]; element par[NPARAMS]; /* This is the lattice value for the 0^++ in units of the string tension extrapolated to large N. I assume that the large N extrapolation is the same as for the 2+1 glueball. The following is the mass formula: 1648./440(1-1/4.11* 2.379/3^2) The problem here is that the errors are too large to really constrain the value for anything other than the lowest state. */ #if FTEPER<2 doublereal teper[1]={12.67},tepererr[1]={1.28}; #endif 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 #if 1 && MAX_LONG==3 /*Normal values for longitudinal and winding errors */ /* these errors match what was found in 2+1 .. */ lerr0=0.1, lerr[MAX_LONG]={0.1,0.1,0.2}, werr[1]={1.0}; #elif 0 && MAX_LONG==3/*Normal values for longitudinal and winding errors */ lerr0=0.2, lerr[MAX_LONG]={0.1,0.1,0.2}, werr[1]={1.0}; #elif 0 && MAX_LONG==3 /*larger errors for longitudnal and winding criteria. */ lerr0=1.0, lerr[MAX_LONG]={1.0,1.0,1.0}, werr[1]={1.0}; #endif /* These are the parity doublets that are to be compared. parityerror is the fractional error assumed for each doublet. each element of whichparity contains {charge,multiplet,which state} for each parity doublet member. */ #if FPARITY<=5 /* This is just the size of the arrays. */ 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,5,0},{1,6,0}},{{-1,5,0},{-1,6,0}}, {{-1,7,0},{-1,4,0}}, {{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 /* Winding numbers for longitudinal string tension. lht0 must be zero since the lattice spacing is unknown. Also the winding numbers and lattice symmetry multiplet for determining roundness of the heavy sourc potential. */ #if MAX_LONG==3 static int lht[MAX_LONG][HINDEX]={{1,0},{1,0},{1,1}}, lmulti[MAX_LONG]={15,15,17},wmulti[1]={17}; #endif static integer wth,lth; /* These are all the quantities returned by fcn */ static struct {doublereal pextrap; element lvalue[FLONG]; element wvalue[FWIND]; element calclvalue[FLONG]; element calcwvalue[FWIND]; 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+FLONG+FWIND+FPARITY+FTEPER+FSCALE+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 ht_zero[HINDEX]={0,0}; /* zero winding for ordinary states */ 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 longitudinal string tension\n" " 1 fit lowest state in spectrum to lattice value\n" " 2 demand minimum chi^2 for c^2 measurements\n" " 3 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,FWIND,FLONG); 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; iNLONG element weights[NWIND*3]; #else element weights[NLONG*3]; #endif int job; element *all_vals[N_ALL_BASES]; #if defined(USE_MPI) && ONE_PROCESSOR_SPECTRUM #else full_basis basis={0}; eigensystem eigen=INITIAL_EIGENSYSTEM; #endif tif=clock(); /* bestpar is used later to see if unfitted variables have changed*/ for(i=0; i<*npar; i++)bestpar[wpar[i]]=par[wpar[i]]=xp[i]; #if PRINTIT printf(" Parameters: "); 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 NPERPVALS=%i\n", k,l,NPERPVALS); *iflag=-12; return SUBRETURN; } } #if 1 /*debugging print of the entire spectrum */ for(k=0; k0.0) rescale=sqrt(rescale); else { rescale=0.0; *iflag = -1; } break; case 3: /* Find scale by minimizing overall chi^2 */ /* This does not include the consistancy of the L nonzero, n=1 datum because it is too complicated */ /* initial guess is from Teper's lowest state */ for(rescale=teper[0]/stillvals[0][0], j=0; ; j++){ sum=0.0; zz=0.0; for(j=0; j0.0){ calclvalue[i]=sqrt(calclvalue[i]); lweights(weights,<h,1,&calclvalue[i]); calclvalue[i]=fdot(weights,lfitting,lth); fvecc[fitc++]=(lvalue[i]-calclvalue[i])/lerr[i]; } else { fprintf(stderr,__FILE__": value for calclvalue[%i]=%g bad, mlong=%g wfitting[0]=%g\n" " dot=%g rescale=%g\n",i,calclvalue[i],mlong[i], wfitting[0],(element) dot(lht[i],lht[i],HINDEX),rescale); fvecc[fitc++]=100.0*fabs(calclvalue[i])+10.0; } #if 1==0 /* debugging print */ printf("fitc=%i fvecc=%f calclvalue[%i]=%f lerr=%f lvalue=%f\n", fitc,fvecc[fitc],calclvalue[i],lerr[i],lvalue[i]); #endif } /* Consistancy of longitudinal string tension with rescale */ #if FSCALE fvecc[fitc++]=(rescale*lfitting[0]-1.0)/lerr0; #endif /* Add parity doublets to fitting criterion using fractional difference. */ for(k=0; kmulti==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(i=0 && (i