void testrft(FILE *fp,real ***grid,int nx,int ny,int nz,gmx_bool bFirst) { #ifdef USE_SGI_FFT #ifdef GMX_DOUBLE static double *coeff; #else static float *coeff; #endif static int la1,la2; #endif real *cptr; real *gptr,*fqqq,fg,fac; int ntot,i,j,k,m,n,ndim[4]; int npppm,job; ndim[0] = 0; ndim[1] = nx; ndim[2] = ny; ndim[3] = nz; ntot = nx*ny*nz; cptr = grid[0][0]; fqqq = &(grid[0][0][0]); #ifdef USE_SGI_FFT if (bFirst) { fprintf(fp,"Going to use SGI optimized FFT routines.\n"); #ifdef GMX_DOUBLE coeff = dfft3di(nx,ny,nz,NULL); #else coeff = sfft3di(nx,ny,nz,NULL); #endif bFirst = FALSE; } job = 1; la1 = nx+2; la2 = ny; #ifdef GMX_DOUBLE dzfft3d(job,nx,ny,nz,cptr,la1,la2,coeff); #else scfft3d(job,nx,ny,nz,cptr,la1,la2,coeff); #endif #else fourn(fqqq-1,ndim,3,1); #endif job = -1; #ifdef USE_SGI_FFT #ifdef GMX_DOUBLE zdfft3d(job,nx,ny,nz,cptr,la1,la2,coeff); #else csfft3d(job,nx,ny,nz,cptr,la1,la2,coeff); #endif #else fourn(fqqq-1,ndim,3,-1); #endif }
void testfft(FILE *fp,t_complex ***grid,int nx,int ny,int nz,gmx_bool bFirst) { #ifdef USE_SGI_FFT #ifdef GMX_DOUBLE static zomplex *coeff; #else static complex *coeff; #endif static int la1,la2; #endif t_complex *cptr; real *gptr,*fqqq,fg,fac; int ntot,i,j,k,m,n,ndim[4]; int npppm; ndim[0] = 0; ndim[1] = nx; ndim[2] = ny; ndim[3] = nz; ntot = nx*ny*nz; cptr = grid[0][0]; fqqq = &(grid[0][0][0].re); #ifdef USE_SGI_FFT if (bFirst) { fprintf(fp,"Going to use SGI optimized FFT routines.\n"); #ifdef GMX_DOUBLE coeff = zfft3di(nx,ny,nz,NULL); #else coeff = cfft3di(nx,ny,nz,NULL); #endif bFirst = FALSE; } la1 = nx; la2 = ny; #ifdef GMX_DOUBLE zfft3d(1,nx,ny,nz,(zomplex *)cptr,la1,la2,coeff); #else cfft3d(1,nx,ny,nz,(complex *)cptr,la1,la2,coeff); #endif #else fourn(fqqq-1,ndim,3,1); #endif #ifdef USE_SGI_FFT #ifdef GMX_DOUBLE zfft3d(-1,nx,ny,nz,(zomplex *)cptr,la1,la2,coeff); #else cfft3d(-1,nx,ny,nz,(complex *)cptr,la1,la2,coeff); #endif #else fourn(fqqq-1,ndim,3,-1); #endif }
int main(void) { int isign; long idum=(-23); unsigned long i,j,k,l,ndum=2,*nn; float *data1,*data2; nn=lvector(1,NDIM); data1=vector(1,NDAT2); data2=vector(1,NDAT2); for (i=1;i<=NDIM;i++) nn[i]=(ndum <<= 1); for (i=1;i<=nn[3];i++) for (j=1;j<=nn[2];j++) for (k=1;k<=nn[1];k++) { l=k+(j-1)*nn[1]+(i-1)*nn[2]*nn[1]; l=(l<<1)-1; /* real part of component */ data2[l]=data1[l]=2*ran1(&idum)-1; /* imaginary part of component */ l++; data2[l]=data1[l]=2*ran1(&idum)-1; } isign=1; fourn(data2,nn,NDIM,isign); /* here would be any processing to be done in Fourier space */ isign = -1; fourn(data2,nn,NDIM,isign); printf("Double 3-dimensional transform\n\n"); printf("%22s %24s %20s\n", "Double transf.","Original data","Ratio"); printf("%10s %13s %12s %13s %11s %13s\n\n", "real","imag.","real","imag.","real","imag."); for (i=1;i<=4;i++) { k=2*(j=2*i); l=k+(j-1)*nn[1]+(i-1)*nn[2]*nn[1]; l=(l<<1)-1; printf("%12.2f %12.2f %10.2f %12.2f %14.2f %12.2f\n", data2[l],data2[l+1],data1[l],data1[l+1], data2[l]/data1[l],data2[l+1]/data1[l+1]); } printf("\nThe product of transform lengths is: %4lu\n",nn[1]*nn[2]*nn[3]); free_vector(data2,1,NDAT2); free_vector(data1,1,NDAT2); free_lvector(nn,1,NDIM); return 0; }
static void convolveWithGaussian(double *forceMap,int S,int /*s*/) { static double *bf = NULL ; if(bf == NULL) { bf = new double[S*S*2] ; for(int i=0;i<S;++i) for(int j=0;j<S;++j) { int x = (i<S/2)?i:(S-i) ; int y = (j<S/2)?j:(S-j) ; // int l=2*(x*x+y*y); bf[2*(i+S*j)] = log(sqrtf(0.1 + x*x+y*y)); // linear -> derivative is constant bf[2*(i+S*j)+1] = 0 ; } unsigned long nn[2] = {S,S}; fourn(&bf[-1],&nn[-1],2,1) ; } unsigned long nn[2] = {S,S}; fourn(&forceMap[-1],&nn[-1],2,1) ; for(int i=0;i<S;++i) for(int j=0;j<S;++j) { float a = forceMap[2*(i+S*j)]*bf[2*(i+S*j)] - forceMap[2*(i+S*j)+1]*bf[2*(i+S*j)+1] ; float b = forceMap[2*(i+S*j)]*bf[2*(i+S*j)+1] + forceMap[2*(i+S*j)+1]*bf[2*(i+S*j)] ; forceMap[2*(i+S*j)] = a ; forceMap[2*(i+S*j)+1] = b ; } fourn(&forceMap[-1],&nn[-1],2,-1) ; for(int i=0;i<S*S*2;++i) forceMap[i] /= S*S; }
void main(){ long fftSize[NSIZES] = /* size of FFTs cols, must be powers of 2 */ {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216}; Complex *a1; long isize; long i1; long TheErr; long N; long M; long N2 = 16; /* the number of rows in the 3d fft */ long M2; long N3 = 32; /* the number of pages in the 3d fft */ long M3; float maxerrifft; float maxerrfft; unsigned long nn[3]; unsigned int randseed = 777; int rannum; #if macintosh UnsignedWide TheTime1; Microseconds(&TheTime1); randseed = TheTime1.lo; #endif printf(" %6d Byte Floats \n", sizeof(a1[0].Re)); printf(" randseed = %10u\n", randseed); for (isize = 0; isize < NSIZES; isize++){ srand(randseed); N = fftSize[isize]; M = roundtol(LOG2(N)); N = POW2(M); M2 = roundtol(LOG2(N2)); N2 = POW2(M2); M3 = roundtol(LOG2(N3)); N3 = POW2(M3); printf("ffts size = %5d X%5d X%6d, ", N3, N2, N); nn[0] = N3; nn[1] = N2; nn[2] = N; TheErr = fft3dInit(M3, M2, M); if(!TheErr){ a1 = (Complex *) malloc(N3*N2*N*sizeof(Complex) ); if (a1 == 0) TheErr = 2; } if(!TheErr){ /* set up a simple test case */ for (i1=0; i1<N3*N2*N; i1++){ rannum = rand(); a1[i1].Re = BIPRAND(rannum); rannum = rand(); a1[i1].Im = BIPRAND(rannum); } /* first use fourn from numerical recipes in C to verify ifft3d */ /* Note their inverse fft is really the conventional forward fft */ fourn((float *)a1-1, nn-1, 3, -1); ifft3d((float *)a1, M3, M2, M); maxerrifft = 0; srand(randseed); for (i1=0; i1<N3*N2*N; i1++){ rannum = rand(); maxerrifft = fmax(maxerrifft, fabs(BIPRAND(rannum)-a1[i1].Re)); a1[i1].Re = BIPRAND(rannum); rannum = rand(); maxerrifft = fmax(maxerrifft, fabs(BIPRAND(rannum)-a1[i1].Im)); a1[i1].Im = BIPRAND(rannum); } printf("errifft = %4.3e, ", maxerrifft); /* now use iffts to verify ffts */ ifft3d((float *)a1, M3, M2, M); fft3d((float *)a1, M3, M2, M); maxerrfft = 0; srand(randseed); for (i1=0; i1<N3*N2*N; i1++){ rannum = rand(); maxerrfft = fmax(maxerrfft, fabs(BIPRAND(rannum)-a1[i1].Re)); rannum = rand(); maxerrfft = fmax(maxerrfft, fabs(BIPRAND(rannum)-a1[i1].Im)); } printf("errfft = %4.3e\n", maxerrfft); free(a1); fft3dFree(); } else{ if(TheErr==2) printf(" out of memory \n"); else printf(" error \n"); fft3dFree(); } } printf(" Done. \n"); return; }
void rlft3(float ***data, float **speq, unsigned long nn1, unsigned long nn2, unsigned long nn3, int isign) { void fourn(float data[], unsigned long nn[], int ndim, int isign); void nrerror(char error_text[]); unsigned long i1,i2,i3,j1,j2,j3,nn[4],ii3; double theta,wi,wpi,wpr,wr,wtemp; float c1,c2,h1r,h1i,h2r,h2i; if (1+&data[nn1][nn2][nn3]-&data[1][1][1] != nn1*nn2*nn3) nrerror("rlft3: problem with dimensions or contiguity of data array\n"); c1=0.5; c2 = -0.5*isign; theta=isign*(6.28318530717959/nn3); wtemp=sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi=sin(theta); nn[1]=nn1; nn[2]=nn2; nn[3]=nn3 >> 1; if (isign == 1) { fourn(&data[1][1][1]-1,nn,3,isign); for (i1=1;i1<=nn1;i1++) for (i2=1,j2=0;i2<=nn2;i2++) { speq[i1][++j2]=data[i1][i2][1]; speq[i1][++j2]=data[i1][i2][2]; } } for (i1=1;i1<=nn1;i1++) { j1=(i1 != 1 ? nn1-i1+2 : 1); wr=1.0; wi=0.0; for (ii3=1,i3=1;i3<=(nn3>>2)+1;i3++,ii3+=2) { for (i2=1;i2<=nn2;i2++) { if (i3 == 1) { j2=(i2 != 1 ? ((nn2-i2)<<1)+3 : 1); h1r=c1*(data[i1][i2][1]+speq[j1][j2]); h1i=c1*(data[i1][i2][2]-speq[j1][j2+1]); h2i=c2*(data[i1][i2][1]-speq[j1][j2]); h2r= -c2*(data[i1][i2][2]+speq[j1][j2+1]); data[i1][i2][1]=h1r+h2r; data[i1][i2][2]=h1i+h2i; speq[j1][j2]=h1r-h2r; speq[j1][j2+1]=h2i-h1i; } else { j2=(i2 != 1 ? nn2-i2+2 : 1); j3=nn3+3-(i3<<1); h1r=c1*(data[i1][i2][ii3]+data[j1][j2][j3]); h1i=c1*(data[i1][i2][ii3+1]-data[j1][j2][j3+1]); h2i=c2*(data[i1][i2][ii3]-data[j1][j2][j3]); h2r= -c2*(data[i1][i2][ii3+1]+data[j1][j2][j3+1]); data[i1][i2][ii3]=h1r+wr*h2r-wi*h2i; data[i1][i2][ii3+1]=h1i+wr*h2i+wi*h2r; data[j1][j2][j3]=h1r-wr*h2r+wi*h2i; data[j1][j2][j3+1]= -h1i+wr*h2i+wi*h2r; } } wr=(wtemp=wr)*wpr-wi*wpi+wr; wi=wi*wpr+wtemp*wpi+wi; } } if (isign == -1) fourn(&data[1][1][1]-1,nn,3,isign); }
void rsk_turbdriving_field() { int dots, kx, ky, kz, i,l, kmin, kmax, bytes; int nn[4]; double rcube, rcubehalf, xk, yk, zk, Pk, abs_k; /* double Ak[2*DOTS*DOTS*DOTS+1], matrix[DOTS][DOTS][DOTS]; */ double *Ak, *matrix; if(!(Ak = malloc(bytes=sizeof(double)*(2*DOTS*DOTS*DOTS+1)))) { printf("failed to allocate memory for Ak: %d.\n",bytes); endrun(2); } if(!(matrix = malloc(sizeof(double)*DOTS*DOTS*DOTS))) { printf("failed to allocate memory for matrix.\n"); endrun(2); } dots = DOTS; rcube = 2.0; rcubehalf = rcube/2.0; kmin = All.kMin; kmax = All.kMax; All.DeltaTimeDrv = 0; /* /\* ---------------------------------------------------------------------*\/ */ ran1(&iiseed); nn[1] = dots; /* dimensions of array */ nn[2] = dots; nn[3] = dots; if(kmin < 1) kmin = 1; for (kx = 0; kx < dots; kx++) { xk = kx; if(kx > dots/2) xk = dots - xk; for (ky = 0; ky < dots; ky++) { yk = ky; if(ky > dots/2) yk = dots - yk; for (kz = 0; kz < dots/2+1; kz++) { zk = kz; abs_k = sqrt(xk*xk + yk*yk + zk*zk); if((abs_k < kmin) || (abs_k > kmax)) Pk = 0; else Pk = 1/pow(abs_k,All.DrvIndx); gen_Ak(Ak,kx,ky,kz,Pk,dots); } } } Ak[2*( 0*dots*dots + 0*dots + 0)+1] = 0; Ak[2*( 0*dots*dots + 0*dots + dots/2)+1] = 0; Ak[2*( 0*dots*dots + dots/2*dots + 0)+1] = 0; Ak[2*( 0*dots*dots + dots/2*dots + dots/2)+1] = 0; Ak[2*(dots/2*dots*dots + 0*dots + 0)+1] = 0; Ak[2*(dots/2*dots*dots + 0*dots + dots/2)+1] = 0; Ak[2*(dots/2*dots*dots + dots/2*dots + 0)+1] = 0; Ak[2*(dots/2*dots*dots + dots/2*dots + dots/2)+1] = 0; for(i=2*dots*dots*dots;i>0;i--) /* array must start with Ak[1] for fourn */ Ak[i]=Ak[i-1]; fourn(Ak,nn,3,-1); for(i=1,l=0;i<2*dots*dots*dots;i+=2,l++) Ak[l] = Ak[i]; l = 0; /* assign the real part to matrix */ for(kz = 0; kz<dots; kz++) { for(ky = 0; ky<dots; ky++) { for(kx = 0; kx<dots; kx++) { /* matrix[kx][ky][kz] = Ak[l]; */ matrix[kx*DOTS*DOTS+ky*DOTS+kz] = Ak[l]; l++; } } } for(l = 0; l<2*dots*dots*dots+1; l++) /*empty Ak*/ Ak[l] = 0; if(dots != IFIELDSIZE) { if(ThisTask==0) { printf("STOP: array sizes do nor agree\n"); printf("dots: %d\n",dots); printf("ifieldsize: %d\n",IFIELDSIZE); fflush(stdout); } exit(1); } if(icomp == 1) /* copy matrix into xmatrix */ { for(kz = 0; kz<IFIELDSIZE; kz++) { for(ky = 0; ky<IFIELDSIZE; ky++) { for(kx = 0; kx<IFIELDSIZE; kx++) { xmatrix[kx*IFIELDSIZE*IFIELDSIZE+ky*IFIELDSIZE+kz] = matrix[kx*IFIELDSIZE*IFIELDSIZE+ky*IFIELDSIZE+kz]; } } } } if(icomp == 2) /* copy matrix into ymatrix */ { for(kz = 0; kz<IFIELDSIZE; kz++) { for(ky = 0; ky<IFIELDSIZE; ky++) { for(kx = 0; kx<IFIELDSIZE; kx++) { ymatrix[kx*IFIELDSIZE*IFIELDSIZE+ky*IFIELDSIZE+kz] = matrix[kx*IFIELDSIZE*IFIELDSIZE+ky*IFIELDSIZE+kz]; } } } } if(icomp == 3) /* copy matrix into zmatrix */ { for(kz = 0; kz<IFIELDSIZE; kz++) { for(ky = 0; ky<IFIELDSIZE; ky++) { for(kx = 0; kx<IFIELDSIZE; kx++) { zmatrix[kx*IFIELDSIZE*IFIELDSIZE+ky*IFIELDSIZE+kz] = matrix[kx*IFIELDSIZE*IFIELDSIZE+ky*IFIELDSIZE+kz]; } } } } SysState.EnergyDrv = 0.0; for(i=0;i<6;i++) { SysState.EnergyDrvComp[i] = 0.0; SysState.EnergyDrv += SysState.EnergyDrvComp[i]; } /* ende */ free(Ak); free(matrix); }
void main(int nar, char* ar[]) { int i,j,k,l,m, n=0, num, nnn[4]; float*u; // ,*f; double*f; parlist par; FILE *in,*out,*col,*grs; char name[100]; char buffer[48]; float cpu[2]; clock_t t; /* set default values */ par.sigma=2; par.seed=200294; par.dim=intvector(1,3); par.dim[1]=64; par.dim[2]=32; par.dim[3]=16; empty(&par.inname); empty(&par.outname); empty(&par.colname); empty(&par.grsname); par.length=1; par.nongauss=0; par.lo=-4; par.hi=4; par.bins=100; par.med=0; par.pixel=1; par.normal=1; par.time=0; /* work through arguments */ while(++n<nar){ if(ar[n][0]=='-'&&ar[n][1]){ switch(ar[n][1]) { case'0' : par.grsname =READSTR; break; case'1' : par.colname =READSTR; break; case'L' : par.length =READINT; break; case'N' : par.normal =0; break; case'b' : par.bins =READINT; break; case'g' : par.nongauss=READINT; break; case'h' : par.hi =READFLT; break; case'i' : par.inname =READSTR; break; case'l' : par.lo =READFLT; break; case'm' : par.med =READINT; break; case'o' : par.outname =READSTR; break; case'p' : par.pixel =READINT; break; case'r' : par.seed =READINT; break; case's' : par.sigma =READFLT; break; case't' : par.time =1; break; case'x' : par.dim[1] =READINT; break; case'y' : par.dim[2] =READINT; break; case'z' : par.dim[3] =READINT; break; default : Explain(stderr,ar[0],&par); } } else { Explain(stderr,ar[0],&par); } } par.a=1./(float)par.dim[1]; /* grid constant is used everywhere */ /* allocate some memory */ n=par.dim[1]*par.dim[2]*par.dim[3]; u=vector(0,2*n); /* open input file and read data */ fileopenr(&in,par.inname); /* printf("%s"," here 1a \n"); printf("size = %d\n",sizeof(in)); */ if(in) { //f=vector(0,n); f=doublevector(0,n); fread((void*)buffer,sizeof(char),24,in); if(n!=fread((void*)f,sizeof(double),n,in)) { fprintf(stderr,"error when reading input!\n"); exit(99); } /* printf("f[0] %d\n",&f[0]); printf("f[0]wert %g\n", f[0]); printf("f[1]wert %g\n", f[1]); printf("f[1]wert %g\n", f[2]); printf("f[1]wert %g\n", f[3]); */ printf("---\n"); //for(i=0;i<n;i++) u[2*i]=f[i],u[2*i+1]=0; for(i=0;i<n;i++) u[2*i]=(float)f[i],u[2*i+1]=0; /* printf("u[0] %d\n",&u[0]); printf("u[0]wert %g\n", u[0]); printf("f[0] %d\n",&f[0]); printf("f[0]wert %g\n", f[0]); printf("u[1] %d\n",&u[1]); printf("u[1]wert %g\n", u[1]); printf("f[1] %d\n",&f[1]); printf("f[1]wert %g\n", f[1]); printf("%s"," here 1c \n"); */ //free_vector(f,0,n); free_doublevector(f,0,n); /* printf("%s"," here 1d \n"); printf("par.sigma = %g\n",par.sigma); */ if(par.sigma>0) fourn(u-1,par.dim,3,1); } /* printf("%s"," here 1e \n"); */ fileclose(in); /* printf("%s"," here 1 \n"); */ /* open output files */ fileopenw(&out,par.outname); /* printf("%s"," here 2 \n"); */ cpu[0]=cpu[1]=0; for(num=0; num<par.length; num++) { /* random field in Fourier space */ if(par.time) t=clock(); if(!in) randomfield(u,&par); if(par.time) cpu[0]+=(clock()-t)/(float)CLOCKS_PER_SEC; /* convolution and normalization */ if(par.time) t=clock(); if(par.sigma>0) convolution(u,&par); if(par.sigma>0) fourn(u-1,par.dim,3,-1); normalize(u,&par); if(par.time) cpu[0]+=(clock()-t)/(float)CLOCKS_PER_SEC; /* printf("%s"," here 2c \n");*/ /* perform statistics */ if(par.time) t=clock(); minkowski(out,u,&par); if(par.time) cpu[1]+=(clock()-t)/(float)CLOCKS_PER_SEC; } /* printf("%s"," here 3 \n"); */ if(par.time) fprintf(stderr,"CPU: %13s%13s\n" " %8.2f sec %8.2f sec\n", "fields","minkowski",cpu[0],cpu[1]); /* output xpm bitmap data */ fileopenw(&col,par.colname); if(col) picture(1,col,u,&par); fileclose(col); fileopenw(&grs,par.grsname); if(grs) picture(0,grs,u,&par); fileclose(grs); /* finish */ fileclose(out); free_vector(u,0,2*n); exit(0); }
/*============================================================================== * CALC_POTENTIAL: * * rho^ = FFT(rho) * Phi^ = G^ * rho^ ; G^ = -1/k**2 (no adjustment for finite differences) * Phi = FFT(Phi^) * * uses NR routine fourn.c for FFT's *==============================================================================*/ void fft_potential(flouble *data, long l1dim) { FILE *fpout; double Green, sf, sf2; double FFTnorm; double kx, ky, kz, ksquare, kf; double sin2sfkz, sin2sfky; long *k; long k_dim, k_nyq; long i, l, m, n; int forward=1, backward=-1; unsigned long nn[NDIM]; /* dimensions of grid */ nn[0] = l1dim; nn[1] = l1dim; nn[2] = l1dim; k_dim = l1dim; k_nyq = l1dim/2; /* this will help extracting information from data^ */ k = (long*) calloc(l1dim,sizeof(long)); for(i=0; i<l1dim; i++) { if(i <= k_nyq) k[i] = i; else k[i] = -(l1dim-i); } /* fourn normalisation factor */ FFTnorm = (double)pow3(l1dim); /* fundamental wave in box units: kf = 2*pi */ kf = TWOPI; /* adjusting the 7-point-difference Green's function */ sf = PI/(double)l1dim/kf; sf2 = pow2(sf); /* forward FFT */ fourn(data-1, nn-1, NDIM, forward); PkSpectrum.time -= time(NULL); PkSpectrum.time += time(NULL); /* calculation of gravitational potential */ for(n = 0; n < k_dim; n++) { kz = kf * k[n]; sin2sfkz = pow2(sin(sf*kz)); for(m = 0; m < k_dim; m++) { ky = kf * k[m]; sin2sfky = pow2(sin(sf*ky)); for(l = 0; l < k_dim; l++) { kx = kf * k[l]; /* get k^2 => NOT needed for 7-point difference approximation to Green = -1.0 / ksquare */ /* ksquare = kx * kx + ky * ky + kz * kz; */ /* Green's function */ if (k[l] == 0 && k[m] == 0 && k[n] == 0) { Green = 0.0; } else { /* 7-point difference approximation to Green = -1.0 / ksquare */ Green = -sf2/(pow2(sin(sf*kx))+sin2sfky+sin2sfkz); } data[Re(l,m,n,l1dim)] *= Green; data[Im(l,m,n,l1dim)] *= Green; } } } /* backward FFT */ fourn(data-1, nn-1, NDIM, backward); /* normalize FFT output */ for(i=0; i<2*l1dim*l1dim*l1dim; i++) data[i] /= FFTnorm; /* delete k-array again */ free(k); }
int main(int argc, char **argv) { fcpx *bufcz, **cmp; fcpx **sm, **seg_fft, *seg_fftb; float *dt; float phase,amplt; /* read these from oct files */ float real,imag; /* calculate these from phase,amplt */ double alpha; float t1, t2, tmp, peak; float w[NFFT], amp[NFFT][NFFT]; int width; int count; int nlines=0; int nbytes1,nbytes2; int phase_int; int step; int xw,yh; int i,j,i1,j1; int ndim; int isign; int ic, lc; int imax,jmax; /* indices of max power */ /* FILE *int_file, *sm_file;*/ FILE *pha_file, *amp_file, *sm_file, *int_file; /* intfile is temporarily created form amp_file and pha_file */ struct stat *file_stat = malloc(sizeof(struct stat)); fprintf(stdout,"*** power spectrum smoothing of interferogram ***\n"); fprintf(stdout,"*** Original by Zhong Lu ***\n"); fprintf(stdout,"*** thanking C. Werner and R. Goldstein for their advice ***\n"); fprintf(stdout,"*** circa 2000 Tim Wright ***\n"); fprintf(stdout,"*** Modified to work with 8 Bit Phase/Amplitude... ***\n"); fprintf(stdout,"*** Version 3.0 20140530 ***\n"); fprintf(stdout,"*** Kurt Feigl to record gradients ***\n"); if(argc != 6){ /* fprintf(stderr,"\nusage: %s <ifm> <sm-ifm> <width> <alpha> \n\n",argv[0]) ;*/ // fprintf(stderr,"\nusage: %s <pha.oct> <amp.oct> <smp.oct> <ncol> <alpha> \n\n",argv[0]) ; fprintf(stderr,"\nusage: %s <pha.oct> <amp.oct> <smp.oct> <ncol> <alpha> \n\n",argv[0]) ; fprintf(stderr,"input parameters: \n"); // fprintf(stderr,"pha.oct (Input) Phase (Unsigned 8Bit Integer 0 = -pi; 255 = pi)\n"); fprintf(stderr,"pha.oct (Input) Phase (Unsigned 8Bit Integer -128 = -pi; 127 = pi)\n"); // fprintf(stderr,"amp.oct (Input) Amplitude (Unsigned 8Bit Integer 0 - 255)\n"); /* fprintf(stderr,"ifm (Input)complex interferogram (4-byte for real and 4-byte for imaginary)\n");*/ fprintf(stderr,"smp.oct (Output) Smoothed Phase (Unsigned 8Bit Integer -128 = -pi; 127 = pi)\n"); fprintf(stderr,"ncols (Input) Number of columns in all 3 files (pixels per line);\n"); /* fprintf(stderr,"alpha (Input) Power factor in Goldstein & Werner technique (recommend: 0.0 < 0.7 < 1.0);\n"); */ fprintf(stderr,"alpha (Input) Alpha exponent in Goldstein & Werner technique (recommend: 0.0 < 0.7 < 1.0);\n"); exit(-1); } pha_file = fopen(argv[1],"rb"); if (pha_file == NULL){fprintf(stderr,"cannot open phase file: %s\n",argv[1]); exit(-1);} amp_file = fopen(argv[2],"rb"); if (amp_file == NULL){fprintf(stderr,"cannot open amplitude file: %s\n",argv[1]); exit(-1);} sm_file = fopen(argv[3],"w"); if (sm_file == NULL){fprintf(stderr,"cannot create smoothed interferogram file: %s\n",argv[2]); exit(-1);} int_file = fopen("temp.cr4","wb"); if (int_file == NULL){fprintf(stderr,"cannot create temp complex file: temp.cr4\n"); exit(-1);} sscanf(argv[4],"%d",&width); sscanf(argv[5],"%lf",&alpha); /* Work out number of lines in file and check that the files are the same size */ stat(argv[1],file_stat); nbytes1=(int)file_stat->st_size; fprintf (stderr, "nbytes1 = %d\n",nbytes1); stat(argv[2],file_stat); nbytes2=(int)file_stat->st_size; fprintf (stderr, "nbytes2 = %d\n",nbytes2); if (nbytes1==nbytes2) { nlines=(int)(nbytes1/width); } else { fprintf(stderr, "\t Amplitude and Phase Files are different sizes\n"); exit(-1); } /* fseek(int_file, 0L, 2); nlines=(int)ftell(int_file)/(width*2*sizeof(float)); rewind(int_file);*/ step = STEP; fprintf(stderr, "Input parameters:\n"); fprintf(stderr, "\tInput Phase: %s\n", argv[1]); fprintf(stderr, "\tInput Amplitude: %s\n", argv[2]); fprintf(stderr, "\tSmoothed phase: %s\n", argv[3]); fprintf(stderr, "\tPower spectrum alpha: %f\n", alpha); fprintf(stderr, "\tFFT window size: %d\n", NFFT); fprintf(stderr, "\tImage width: %d\n", width); fprintf(stderr, "\tImage length: %d\n", nlines); xw=width; yh=nlines; fprintf(stdout,"\tarray width, height: %5d %5d\n",xw,yh); cmp = alloc_2d_c(0, nlines-1, 0,width-1); sm = alloc_2d_c(0,nlines-1, 0,width); if (cmp == NULL || sm == NULL) {fprintf(stderr, "failure to allocate space for cmp and sm buffers\n"); exit(-1);} seg_fftb = (fcpx *)malloc(sizeof(fcpx)*NFFT*NFFT); if(seg_fftb == NULL){fprintf(stderr,"failure to allocate space for complex data\n"); exit(-1);} seg_fft = (fcpx **)malloc(sizeof(fcpx *)*NFFT); if(seg_fft == NULL){fprintf(stderr,"failure to allocate space for complex data pointers\n"); exit(-1);} bufcz = (fcpx *)malloc(sizeof(fcpx)*width); if(bufcz == NULL){fprintf(stderr,"failure to allocate space for input line buffer\n"); exit(-1);} for(i=0; i < NFFT; i++)seg_fft[i] = seg_fftb + i*NFFT; for(i=0; i < nlines; i++){ for(j=0; j < width; j++){ sm[i][j].re=0.0; sm[i][j].im=0.0; } } for(j=0; j < width; j++){bufcz[j].re=0.; bufcz[j].im=0.;} for (i=0; i <= NFFT/2-1; i++) { w[i] = 2.0*(i+1)/(float)NFFT; w[NFFT-i-1]=w[i]; } for (i=0; i < NFFT; i++) for (j=0; j < NFFT; j++)wf[i][j] = w[i]*w[j]; /* Merge amp and phase into "temp.cr4" */ count=0; while (count < nbytes1) { phase = (float)fgetc(pha_file); amplt = (float)fgetc(amp_file); // if (phase==0&&lt!=0) phase=1; // real = (amplt/255)*cos(phase*2*PI/255); // imag = (amplt/255)*sin(phase*2*PI/255); if (amplt==0) phase=0; real = (amplt/256)*cos(phase*2*PI/256); imag = (amplt/256)*sin(phase*2*PI/256); fwrite (&real, sizeof(float),1,int_file); fwrite (&imag, sizeof(float),1,int_file); count ++; } printf("\n Created temporary Complex File: temp.cr4\n"); /* Close file for writing and reopen for reading */ fclose (int_file); fclose (pha_file); fclose (amp_file); int_file = fopen("temp.cr4","r"); if (int_file == NULL){fprintf(stderr,"cannot create temp complex file: temp.cr4\n"); exit(-1);} fseek(int_file, 0, 0); for (i=0; i < yh; i ++) fread((char *)cmp[i], sizeof(fcpx), width, int_file); #if 1 fprintf(stderr, "Please wait, I am filtering the noisy ifms\n"); fprintf(stderr, "I am slow, but you will like the results\n\n"); lc=0; /* loop over patches with overlap by step */ for (i=-NFFT+step; i <= yh-step; i += step){ for (j=-NFFT+step; j < width-step; j += step){ dt=(float *)&seg_fft[0][0]; ic = 0; for (i1=0; i1 < NFFT; i1++){ for (j1=0; j1 < NFFT; j1++){ /* pad with zeros */ if ( (i+i1) < 0 || (i+i1) >= yh || (j+j1) < 0 || (j+j1) >= width ) { dt[ic++] = 0.0; dt[ic++] = 0.0; } else { /* normalize magnitude to unity */ t1 = cmp[i+i1][j+j1].re; t2 = cmp[i+i1][j+j1].im; tmp = sqrt(t1*t1 + t2*t2); if (tmp != 0.0) { dt[ic++]=t1/tmp; dt[ic++]=t2/tmp; } else { dt[ic++]=0.0; dt[ic++]=0.0; } } } } /* Fourier transform */ ndim=2, isign=1, nfft[1]=NFFT, nfft[2]=NFFT, nfft[0]=0; fourn(dt-1, nfft, ndim, isign); /* look for maximum spectral amplitude, a.k.a. power */ peak = 0.0; for (i1=0; i1 < NFFT; i1++){ for (j1=0; j1 < NFFT; j1++){ /* calculate power */ tmp = sqrt(seg_fft[i1][j1].re*seg_fft[i1][j1].re + seg_fft[i1][j1].im*seg_fft[i1][j1].im); /* if power is greater than peak, then update peak */ if (peak < tmp) { peak = tmp; printf("%3d %3d %5d %5d %12.4e %12.4e %12.4e\n",i1,j1,i,j,seg_fft[i1][j1].re,seg_fft[i1][j1].im,tmp); } /* record power */ amp[i1][j1] = tmp; } } /* replace spectral value by amplified value */ if (peak != 0.0) { for (i1=0; i1 < NFFT; i1++){ for (j1=0; j1 < NFFT; j1++){ seg_fft[i1][j1].re = (float)(seg_fft[i1][j1].re*pow((amp[i1][j1]/peak), alpha)/(float)NFFT); seg_fft[i1][j1].im = (float)(seg_fft[i1][j1].im*pow((amp[i1][j1]/peak), alpha)/(float)NFFT); } } } /* inverse Fourier transform */ isign=-1; fourn(dt-1, nfft, ndim, isign); for (i1=0; i1 < NFFT; i1++){ for (j1=0; j1 < NFFT; j1++){ tmp = sqrt(seg_fft[i1][j1].re*seg_fft[i1][j1].re + seg_fft[i1][j1].im*seg_fft[i1][j1].im); seg_fft[i1][j1].re = (float)(seg_fft[i1][j1].re*wf[i1][j1]/tmp); seg_fft[i1][j1].im = (float)(seg_fft[i1][j1].im*wf[i1][j1]/tmp); } } /* replace phase value with filtered (smoothed) value */ for (i1=0; i1 < NFFT; i1++){ for (j1=0; j1 < NFFT; j1++){ /* check that pixel is not in the padded area */ if ( (i+i1) >= 0 && (i+i1) < yh && (j+j1) >= 0 && (j+j1) < width && cmp[i1+i][j1+j].re != 0.0 && cmp[i1+i][j1+j].im != 0.0 ) { sm[i1+i][j1+j].re += seg_fft[i1][j1].re; sm[i1+i][j1+j].im += seg_fft[i1][j1].im; } } } } lc += step; fprintf(stderr, "processing line: %5d\r", i); } /* Close file for reading and reopen for writing !! There's probably a more elegant solution but this works !! */ fclose (int_file); int_file = fopen("temp.cr4","w"); if (int_file == NULL){fprintf(stderr,"cannot rewrite temp complex file: temp.cr4\n"); exit(-1);} /* Write temporary complex output file */ fprintf(stderr, "writing output image \n"); for (i=0; i < yh ; i++) fwrite((char *)sm[i], sizeof(fcpx), width, int_file); /* Once more...Close for writing and reopen for reading */ fclose (int_file); int_file = fopen("temp.cr4","rb"); if (int_file == NULL){fprintf(stderr,"cannot create temp complex file: temp.cr4\n"); exit(-1);} /* Convert complex array into octal and write Smoothed Phase File */ count = 0; while (count < nbytes1) { fread(&real, sizeof(float),1,int_file); fread(&imag, sizeof(float),1,int_file); // /* Changed to deal with diapason nulls (phase==0) properly */ // phase_int = (int)(ROUND((255*atan2(imag,real)/2/PI))); // if (atan2(imag,real)==0) phase_int=0; // else if (phase_int==0&&atan2(imag,real)>0) phase_int++; // else if (phase_int==0&&atan2(imag,real)<0) phase_int--; // while (phase_int > 255) phase_int -=255; // while (phase_int < 0) phase_int +=255; /* Changed to deal with diapason nulls (phase==0) properly */ /* 20140530 use 256 */ phase_int = (int)(ROUND((256*atan2(imag,real)/2/PI))); if (atan2(imag,real)==0) phase_int=0; else if (phase_int==0&&atan2(imag,real)>0) phase_int++; else if (phase_int==0&&atan2(imag,real)<0) phase_int--; while (phase_int > 127) phase_int -=256; while (phase_int < -128) phase_int +=256; fputc(phase_int, sm_file); count ++; } printf("\n finished***\n"); #endif system("rm temp.cr4"); fclose (int_file); fclose (sm_file); return(0); }