#include #include #include #include #include "include.h" /* Below are subroutines for the 3+1 case only. multi is a basis of irreducable representations of the lattice symmetries Define lists of phases used by various subroutines Here, kt = 2*K. Half integers are defined for phaselist and phaselistv when HINDEX>1. */ #if HINDEX > 1 static complex_e phaselist[2*KKMAX][HINDEX]; static element phaseangleu[HINDEX]; static complex_e phaselistv[2*NPMAX][HINDEX]; void makephaselist(element *angle,int kt){ int i,j; element theta; for(j=0; j0 /* This is the interaction for the 3+1 dimensional case. It returns values in the vector x. */ void interaction(element *x, partype *left, partype *right, int npl, int npr){ int i,l1,l2,l3,r1,r2,r3; element *row; int hl1[HINDEX],hl2[HINDEX],hl3[HINDEX],hr1[HINDEX],hr2[HINDEX],hr3[HINDEX]; partype leftleft[NPMAX*2],rightright[NPMAX*2]; int il,ir; #if !USEMEMCMP int j; #endif memcpy(leftleft,left,npl*sizeof(partype)); memcpy(leftleft+npl,left,npl*sizeof(partype)); memcpy(rightright,right,npr*sizeof(partype)); memcpy(rightright+npr,right,npr*sizeof(partype)); for(i=0; i1){ for(il=0; il>1)+r2)*two; x[1]+=row[0]; if(EQUAL(hl1,hr2)) x[4]+=row[1]; else if(MINUS(hl1,hr2)) x[3]+=row[1]; else x[6]+=row[1]; } if(EQUAL(hl1,hr1)){ row=threeelements[l1-1]+((((2*l1-r3+1)*r3)>>1)+r2)*two; x[1]+=row[0]; if(EQUAL(hl1,hr2)) x[4]+=row[1]; else if(MINUS(hl1,hr2)) x[3]+=row[1]; else x[6]+=row[1]; } if(EQUAL(hl1,hr2)&&ORTHO(hl1,hr1)){ row=threeelements[l1-1]+((((2*l1-r1+1)*r1)>>1)+r2)*two; x[2]-=row[1]; } } } } else if(npr+2==npl){ for(il=0; il>1)+l2)*two; x[1]+=row[0]; if(EQUAL(hr1,hl2)) x[4]+=row[1]; else if(MINUS(hr1,hl2)) x[3]+=row[1]; else x[6]+=row[1]; } if(EQUAL(hr1,hl1)){ row=threeelements[r1-1]+((((2*r1-l3+1)*l3)>>1)+l2)*two; x[1]+=row[0]; if(EQUAL(hr1,hl2)) x[4]+=row[1]; else if(MINUS(hr1,hl2)) x[3]+=row[1]; else x[6]+=row[1]; } if(EQUAL(hr1,hl2)&&ORTHO(hl1,hr1)){ row=threeelements[r1-1]+((((2*r1-l1+1)*l1)>>1)+l2)*two; x[2]-=row[1]; } } } } /* here we take the case that the matrix element is the mass */ else if(npl==1 && npr==1){ x[0]=1.0/((element) hitol(left[0],hl1)+0.5); } return; } /* This is the interaction for the 2+1 dimensional case, including a phase factor. makephaselist makes a list of angles beforehand. makephaselist(0,kt) should give results identical with the function interaction(...) above. The list is long enough to accomodate winding number up to NPMAX and 2*K upto KKMAX. interactionc(...) is NOT valid for nonzero winding number. */ void interactionc(complex_e *x, partype *left, partype *right, int npl, int npr){ int i,j; int l1,l2,l3,r1,r2,r3; complex_e phase,t[HINDEX]; element *row; int hl1[HINDEX],hl2[HINDEX],hl3[HINDEX],hr1[HINDEX],hr2[HINDEX],hr3[HINDEX]; partype leftleft[NPMAX*2],rightright[NPMAX*2]; int il,ir; memcpy(leftleft,left,npl*sizeof(partype)); memcpy(leftleft+npl,left,npl*sizeof(partype)); memcpy(rightright,right,npr*sizeof(partype)); memcpy(rightright+npr,right,npr*sizeof(partype)); for(i=0; i1){ for(il=0; il>1)+r2)*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hl1,hr2)) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hl1,hr2)) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hl1,hr1)){ row=threeelements[l1-1]+((((2*l1-r3+1)*r3)>>1)+r2)*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hl1,hr2)) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hl1,hr2)) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hl1,hr2)&&ORTHO(hl1,hr1)){ row=threeelements[l1-1]+((((2*l1-r1+1)*r1)>>1)+r2)*two; x[2].re-=phase.re*row[1]; x[2].im-=phase.im*row[1]; } } } } else if(npr+2==npl){ for(il=0; il>1)+l2)*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hr1,hl2)) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hr1,hl2)) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hr1,hl1)){ row=threeelements[r1-1]+((((2*r1-l3+1)*l3)>>1)+l2)*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hr1,hl2)) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hr1,hl2)) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hr1,hl2)&&ORTHO(hl1,hr1)){ row=threeelements[r1-1]+((((2*r1-l1+1)*l1)>>1)+l2)*two; {x[2].re-=phase.re*row[1]; x[2].im-=phase.im*row[1];} } } } } /* here we take the case that the matrix element is the mass */ else if(npl==1 && npr==1){ x[0].re=1.0/((element) hitol(left[0],hl1)+0.5); } return; } /* interactioncu(x,left,right,npl,npr) This is a version for testing purposes which uses a center of mass with equal weighting for all particles. It's main purpose is to Check the other code. The angle associated with the transverse momentum and is obtained from the global variable "phasangleu". This routine can be used to calculate for nonzero winding number. */ void interactioncu(complex_e *x, partype *left, partype *right, int npl, int npr){ int i,j,il,ir; int l[NPMAX+2],r[NPMAX+2],hl[NPMAX+2][HINDEX],hr[NPMAX+2][HINDEX]; complex_e phase; element tl[NPMAX][HINDEX],tr[NPMAX][HINDEX],center,*row,t; partype leftleft[NPMAX*2],rightright[NPMAX*2]; memcpy(leftleft,left,npl*sizeof(partype)); memcpy(leftleft+npl,left,npl*sizeof(partype)); memcpy(rightright,right,npr*sizeof(partype)); memcpy(rightright+npr,right,npr*sizeof(partype)); /* The following section calculates the distance of each particle from the Center of mass. */ for(i=0; i1){ for(il=0; il>1)+ r[ir+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hl[il],hr[ir+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hl[il],hr[ir+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hl[il],hr[ir])){ row=threeelements[l[il]-1]+((((2*l[il]-r[ir+2]+1)*r[ir+2])>>1)+ r[ir+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hl[il],hr[ir+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hl[il],hr[ir+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hl[il],hr[ir+1])&&ORTHO(hl[il],hr[ir])){ row=threeelements[l[il]-1]+((((2*l[il]-r[ir]+1)*r[ir])>>1)+r[ir+1])*two; {x[2].re-=phase.re*row[1]; x[2].im-=phase.im*row[1];} } } } } else if(npr+2==npl){ for(il=0; il>1)+ l[il+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hr[ir],hl[il+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hr[ir],hl[il+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hr[ir],hl[il])){ row=threeelements[r[ir]-1]+((((2*r[ir]-l[il+2]+1)*l[il+2])>>1)+ l[il+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hr[ir],hl[il+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hr[ir],hl[il+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hr[ir],hl[il+1])&&ORTHO(hl[il],hr[ir])){ row=threeelements[r[ir]-1]+((((2*r[ir]-l[il]+1)*l[il])>>1)+ l[il+1])*two; {x[2].re-=phase.re*row[1]; x[2].im-=phase.im*row[1];} } } } } /* here we take the case that the matrix element is the mass */ else if(npl==1 && npr==1){ x[0].re=1.0/((element) l[0]+0.5); } #if UDEBUG if(npr==npl+2)printf(" Result: %f + %f i\n",x[3].re,x[3].im); #endif return; } /* interactioncv(x,left,right,npl,npr) This is a version which uses a phase convention dependent on the first particle in the state and is faster than interactioncu. This routine can be used to calculate for nonzero winding number. */ void interactioncv(complex_e *x, partype *left, partype *right, int npl, int npr){ int i,j,il,ir; int l[NPMAX+2],r[NPMAX+2],hl[NPMAX+2][HINDEX],hr[NPMAX+2][HINDEX]; complex_e phase,t[HINDEX]; element *row; int tl[NPMAX][HINDEX],tr[NPMAX][HINDEX]; partype leftleft[NPMAX*2],rightright[NPMAX*2]; memcpy(leftleft,left,npl*sizeof(partype)); memcpy(leftleft+npl,left,npl*sizeof(partype)); memcpy(rightright,right,npr*sizeof(partype)); memcpy(rightright+npr,right,npr*sizeof(partype)); /* The following section calculates the distance of each particle from the left "edge". We set tl[0] and tr[0] based on the fact that we only use differences tl[i]-tr[j] to calculate phases. */ for(i=0; i1){ for(il=0; il>1)+ r[ir+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hl[il],hr[ir+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hl[il],hr[ir+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hl[il],hr[ir])){ row=threeelements[l[il]-1]+((((2*l[il]-r[ir+2]+1)*r[ir+2])>>1)+ r[ir+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hl[il],hr[ir+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hl[il],hr[ir+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hl[il],hr[ir+1])&&ORTHO(hl[il],hr[ir])){ row=threeelements[l[il]-1]+((((2*l[il]-r[ir]+1)*r[ir])>>1)+ r[ir+1])*two; {x[2].re-=phase.re*row[1]; x[2].im-=phase.im*row[1];} } } } } else if(npr+2==npl){ for(il=0; il>1)+ l[il+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hr[ir],hl[il+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hr[ir],hl[il+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hr[ir],hl[il])){ row=threeelements[r[ir]-1]+((((2*r[ir]-l[il+2]+1)*l[il+2])>>1)+ l[il+1])*two; x[1].re+=phase.re*row[0]; x[1].im+=phase.im*row[0]; if(EQUAL(hr[ir],hl[il+1])) {x[4].re+=phase.re*row[1]; x[4].im+=phase.im*row[1];} else if(MINUS(hr[ir],hl[il+1])) {x[3].re+=phase.re*row[1]; x[3].im+=phase.im*row[1];} else {x[6].re+=phase.re*row[1]; x[6].im+=phase.im*row[1];} } if(EQUAL(hr[ir],hl[il+1])&&ORTHO(hl[il],hr[ir])){ row=threeelements[r[ir]-1]+((((2*r[ir]-l[il]+1)*l[il])>>1)+ l[il+1])*two; {x[2].re-=phase.re*row[1]; x[2].im-=phase.im*row[1];} } } } } /* here we take the case that the matrix element is the mass */ else if(npl==1 && npr==1){ x[0].re=1.0/((element) l[0]+0.5); } return; } /* This currently does nothing */ #define NOP 4 /* number of states to measure particle content */ void shuffle(sectors *s, sectors *s2,element *vec, element *val,int nval){ return; } #endif