Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

fermiqcd_ffts.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 inline long i2pow(long n) {
00014   return 0x0001 << n;
00015 };
00016 
00017 // one dimensional fourier transform
00018 // here n is not the size of f but size of f is i2pow(n)
00019 
00020 void dft(mdp_complex *fft_f, mdp_complex *f, long n, double sign, 
00021          long offset=0, long coeff=1) {
00022   int i,j;
00023   mdp_complex phase=exp(2.0*Pi*I*sign/n);
00024   for(i=0; i<n; i++) {
00025     fft_f[offset+coeff*i]=0;
00026     for(j=0; j<n; j++)
00027       fft_f[offset+coeff*i]+=f[offset+coeff*j]*pow(phase,i*j);
00028     fft_f[offset+coeff*i]/=sqrt(n);
00029   }
00030 }
00031 
00032 /* NOT NOT UNCOMMENT THIS, WORK IN PROGRESS!!!
00033 void fft(mdp_complex *fft_f, mdp_complex *f, long n, double sign, 
00034          long offset=0, long coeff=1) {
00035   long a,b,h,pow2b, N=i2pow(n);
00036   mdp_complex alpha, omega, F[N];
00037   if(sign!=0) for(h=0; h<N; h++) {
00038     alpha=2.0*sign*Pi*I/N*h;
00039     for(a=0; a<N; a++) F[a]=f[offset+coeff*a];
00040     for(b=n-1; b>=0; b--) {
00041       pow2b=i2pow(b);
00042       omega=exp(alpha*pow2b);
00043       for(a=0; a<pow2b; a++) 
00044         F[a]+=omega*F[a+pow2b];
00045     };
00046     fft_f[offset+coeff*h]=F[0]/sqrt(N);
00047   } else {
00048     for(a=0; a<N; a++)
00049       fft_f[offset+coeff*a]=f[offset+coeff*a];
00050   }    
00051 }
00052 
00053 */
00054 
00055 void fermi_field_fft(int t, 
00056                      fermi_field& psi_out, 
00057                      fermi_field& psi_in, 
00058                      int sign) {
00059 
00060   if(psi_in.lattice().ndim!=4) error("fft3D requires TxXxXxX");
00061 
00062   int i,x1,x2,x3,spin,color;
00063   int size=psi_in.lattice().size(1);
00064   if(psi_in.lattice().size(2)>size) size=psi_in.lattice().size(2);
00065   if(psi_in.lattice().size(3)>size) size=psi_in.lattice().size(3);
00066 
00067   mdp_complex *v=new mdp_complex[size];
00068   mdp_complex *u=new mdp_complex[size];
00069 
00070   mdp_site x(psi_in.lattice());
00071 
00072   psi_out=psi_in;
00073 
00074   for(spin=0; spin<psi_out.nspin; spin++)
00075     for(color=0; color<psi_out.nc; color++) {
00076       for(x2=0; x2<psi_out.lattice().size(2); x2++)
00077         for(x3=0; x3<psi_out.lattice().size(3); x3++) {
00078           for(i=0; i<psi_out.lattice().size(1); i++) {
00079             x.set(t,i,x2,x3);
00080             v[i]=psi_out(x,spin,color);
00081           }
00082           dft(u,v,psi_out.lattice().size(1),sign);
00083           for(i=0; i<psi_out.lattice().size(1); i++) {
00084             x.set(t,i,x2,x3);
00085             psi_out(x,spin,color)=u[i];
00086           }
00087         }
00088       for(x1=0; x1<psi_out.lattice().size(1); x1++)
00089         for(x3=0; x3<psi_out.lattice().size(3); x3++) {
00090           for(i=0; i<psi_out.lattice().size(2); i++) {
00091             x.set(t,x1,i,x3);
00092             v[i]=psi_out(x,spin,color);
00093           }
00094           dft(u,v,psi_out.lattice().size(2),sign);
00095           for(i=0; i<psi_out.lattice().size(2); i++) {
00096             x.set(t,x1,i,x3);
00097             psi_out(x,spin,color)=u[i];
00098           }
00099         }
00100 
00101       for(x1=0; x1<psi_out.lattice().size(1); x1++)
00102         for(x2=0; x2<psi_out.lattice().size(2); x2++) {
00103           for(i=0; i<psi_out.lattice().size(3); i++) {
00104             x.set(t,x1,x2,i);
00105             v[i]=psi_out(x,spin,color);
00106           }
00107           dft(u,v,psi_out.lattice().size(3),sign);
00108           for(i=0; i<psi_out.lattice().size(3); i++) {
00109             x.set(t,x1,x2,i);
00110             psi_out(x,spin,color)=u[i];
00111           }
00112         }
00113     }
00114   delete[] u;
00115   delete[] v;
00116 }
00117 
00118 /* Uncomment this as an example
00119 
00120 int test1() {
00121   long i,j,n=16;
00122 
00123   double tmp=0;
00124 
00125   mdp_complex in[n], out[n], chk[n];
00126   for(i=0; i<n; i++)
00127     in[i]=exp(I*2.0*sin(i));
00128   
00129   dft(out,in,n,+1);
00130 
00131   dft(chk,out,n,-1);
00132   
00133   for(i=0; i<n; i++) {
00134     if(tmp+=abs(chk[i]-in[i])>0.00001)
00135       printf("(%f, %f) (%f, %f) (%f, %f)\n", 
00136              real(in[i]), imag(in[i]),
00137              real(chk[i]), imag(chk[i]),
00138              real(out[i]), imag(out[i]));
00139   };
00140   printf("%f\n", tmp/n);
00141   return 0;
00142 };
00143 
00144 
00145 int test2() {
00146 
00147   int box[]={1,20,20,20};
00148   mdp_lattice lattice(4,box);
00149   fermi_field psi(lattice,3);
00150   fermi_field phi(lattice,3);
00151   fermi_field chi(lattice,3);
00152 
00153   set_random(psi);
00154   mdp_site x(lattice);
00155 
00156   int t;
00157 
00158   for(t=0; t<box[0]; t++) {
00159     if(on_which_process(lattice,t)==ME) {
00160       fermi_field_fft(t,phi,psi,1);
00161       fermi_field_fft(t,chi,phi,-1);
00162     }
00163   }
00164 
00165   check_differences(psi,chi);
00166 
00167 }
00168 
00169 
00170 int main(int argc, char** argv) {
00171   mdp.open_wormholes(argc,argv);
00172   test1();
00173   test2();
00174   mdp.close_wormholes();
00175 }
00176 
00177 */

Generated on Sun Feb 27 15:12:18 2005 by  doxygen 1.4.1