WAVEFUNC::WAVEFUNC( WAVEFUNC& other ) { iPosX = other.iPosX; iPosY = other.iPosY; detPosX = other.detPosX; detPosY = other.detPosY; strcpy(fileStart, other.fileStart); strcpy(fileout, other.fileout); strcpy(avgName, other.avgName); nx = other.nx; ny = other.ny; diffpat = float2D(nx,ny,"diffpat"); avgArray = float2D(nx,ny,"avgArray"); #if FLOAT_PRECISION == 1 wave = complex2Df(nx, ny, "wave"); fftPlanWaveForw = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, FFTW_ESTIMATE); fftPlanWaveInv = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, FFTW_ESTIMATE); #else wave = complex2D(nx, ny, "wave"); fftPlanWaveForw = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, fftMeasureFlag); fftPlanWaveInv = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, fftMeasureFlag); #endif }
WAVEFUNC::WAVEFUNC(int x, int y) : detPosX(0), detPosY(0), iPosX(0), iPosY(0), thickness(0.0), nx(0), ny(0) { char waveFile[256]; const char *waveFileBase = "mulswav"; nx = x; ny = y; diffpat = float2D(nx,ny,"diffpat"); avgArray = float2D(nx,ny,"avgArray"); #if FLOAT_PRECISION == 1 wave = complex2Df(nx, ny, "wave"); fftPlanWaveForw = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, FFTW_ESTIMATE); fftPlanWaveInv = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, FFTW_ESTIMATE); #else wave = complex2D(nx, ny, "wave"); fftPlanWaveForw = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, fftMeasureFlag); fftPlanWaveInv = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, fftMeasureFlag); #endif sprintf(waveFile,"%s.img",waveFileBase); strcpy(fileout,waveFile); sprintf(fileStart,"mulswav.img"); }
void fourn(float data[], unsigned long nn[], int ndim, int isign) { int nx = nn[2]; int ny = nn[1]; /* NOTE: This function only works for ndim=2 */ if (ndim != 2) { printf("fourn only works with ndim=2\n"); return; } if ((nx != nx_prev) || (ny != ny_prev)) { /* Create plans */ if (nx_prev != 0) fftwf_free(in_1d); in_2d = fftwf_malloc(sizeof(fftwf_complex)*nx*ny); out_2d = in_2d; printf("fft_test2f: creating plans, nx=%d, ny=%d, nx_prev=%d, ny_prev=%d\n", nx, ny, nx_prev, ny_prev); nx_prev = nx; ny_prev = ny; forward_plan_2d = fftwf_plan_dft_2d(ny, nx, in_2d, out_2d, FFTW_FORWARD, FFTW_MEASURE); backward_plan_2d = fftwf_plan_dft_2d(ny, nx, in_2d, out_2d, FFTW_BACKWARD, FFTW_MEASURE); } /* The Numerical Recipes routines are passed a pointer to one element * before the start of the array - add one */ memcpy(in_2d, data+1, nx*ny*sizeof(fftwf_complex)); if (isign == -1) fftwf_execute(forward_plan_2d); else fftwf_execute(backward_plan_2d); memcpy(data+1, out_2d, nx*ny*sizeof(fftwf_complex)); }
epicsShareFunc void epicsShareAPI fftw_2d (float *argv1, int *argv2, int *argv3, int *argv4) { float *data = (float *)argv1; int nx = *(int *)argv2; int ny = *(int *)argv3; int isign = *(int *)argv4; static int nx_prev, ny_prev; static fftwf_complex *in, *out; static fftwf_plan forward_plan, backward_plan; if ((nx != nx_prev) || (ny != ny_prev)) { /* Create plans */ if (nx_prev != 0) fftwf_free(in); in = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*nx*ny); out = in; //printf("fft_test2f: creating plans, nx=%d, ny=%d, nx_prev=%d, ny_prev=%d\n", // nx, ny, nx_prev, ny_prev); nx_prev = nx; ny_prev = ny; forward_plan = fftwf_plan_dft_2d(ny, nx, in, out, FFTW_FORWARD, FFTW_MEASURE); backward_plan = fftwf_plan_dft_2d(ny, nx, in, out, FFTW_BACKWARD, FFTW_MEASURE); } memcpy(in, data, nx*ny*sizeof(fftwf_complex)); if (isign == -1) fftwf_execute(forward_plan); else fftwf_execute(backward_plan); memcpy(data, in, nx*ny*sizeof(fftwf_complex)); }
// Wrapper around FFTW3 that computes the real-valued inverse Fourier transform // of a complex-valued frequantial image. // The input data must be hermitic. static void ifft_2dfloat(float *ifx, fftwf_complex *fx, int w, int h) { fftwf_complex *a = fftwf_xmalloc(w*h*sizeof*a); fftwf_complex *b = fftwf_xmalloc(w*h*sizeof*b); //fprintf(stderr, "planning...\n"); evoke_wisdom(); fftwf_plan p = fftwf_plan_dft_2d(h, w, a, b, FFTW_BACKWARD, FFTW_ESTIMATE); bequeath_wisdom(); //fprintf(stderr, "...planned!\n"); FORI(w*h) a[i] = fx[i]; fftwf_execute(p); float scale = 1.0/(w*h); FORI(w*h) { fftwf_complex z = b[i] * scale; ifx[i] = crealf(z); if (FIWARN() > 0) { if (cimagf(z) > 0.001) fail("z is not real {cimagf(z)=%g} (set FIWARN=0 to run anyway)", cimagf(z)); //assert(cimagf(z) < 0.001); } }
int main(int argc, char *argv[]) { assert(argc == 4 && "fft_host <M> <N> <OutputFilenamePrefix>"); char *dummy; const int M = strtol(argv[1], &dummy, 10); const int N = strtol(argv[2], &dummy, 10); fftwf_complex *in = malloc(M*N*sizeof(*in)); fftwf_complex *out = malloc(M*N*sizeof(*in)); assert(in && out && "Failed to allocate input and output arrays"); srand(time(NULL)); //Seed RNG for(int i = 0; i < (M*N); i++) { in[i][0] = (float)((float)rand()+rand()+rand()+rand()) / (float)(4.0f*RAND_MAX) * (float)RANGE; in[i][1] = (float)((float)rand()+rand()+rand()+rand()) / (float)(4.0f*RAND_MAX) * (float)RANGE; } fftwf_plan p = fftwf_plan_dft_2d(M, N, in, out, FFTW_FORWARD, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT); fftwf_execute(p); char inFilename[128], outFilename[128]; strncpy(inFilename, argv[3], 128); strncpy(outFilename, argv[3], 128); output(in, M, N, strncat(inFilename, ".t.in", 5), false); output(out, M, N, strncat(outFilename, ".t.out", 6), false); strncpy(inFilename, argv[3], 128); strncpy(outFilename, argv[3], 128); output(in, M, N, strncat(inFilename, ".b.in", 5), true); output(out, M, N, strncat(outFilename, ".b.out", 6), true); fftwf_destroy_plan(p); free(out); free(in); return 0; }
void diffractionIntensity ( float * const & rIoData, const std::pair<unsigned int,unsigned int>& rSize ) { unsigned int nElements = rSize.first * rSize.second; /* @ see http://www.fftw.org/doc/Precision.html */ auto tmp = new fftwf_complex[nElements]; for ( unsigned i = 0; i < nElements; ++i ) { tmp[i][0] = rIoData[i]; tmp[i][1] = 0; } fftwf_plan ft = fftwf_plan_dft_2d( rSize.second, rSize.first, tmp, tmp, FFTW_FORWARD, FFTW_ESTIMATE ); fftwf_execute( ft ); fftwf_destroy_plan( ft ); for ( unsigned i = 0; i < nElements; ++i ) { const float & re = tmp[i][0]; /* Re */ const float & im = tmp[i][1]; /* Im */ const float norm = sqrtf( re*re + im*im ); rIoData[ i /*fftShiftIndex(i,rSize)*/ ] = norm; } delete[] tmp; }
void compute() { const int M = 256; const int N = 256; cmatrix h_naught(M, N, true, complex(0.0f, 0.0f)); for (int row = 0; row < M; row++) { for (int col = 0; col < N; col++) { int n = col; int m = row; matrix3x1 K = Pi_2 * matrix3x1((float)n / N, 0, (float)m / M); complex h_0 = height_naught(K); h_naught.set(row, col, h_0); } } cmatrix h_tilde(M, N, true, complex(0, 0)); cmatrix c_heights(M, N, true, complex(0, 0)); fftwf_plan plan = fftwf_plan_dft_2d(M, N, (fftwf_complex *)h_tilde.getData(), (fftwf_complex *)c_heights.getData(), FFTW_BACKWARD, FFTW_ESTIMATE); matrix heights(M, N, true, 0.0f); const int Frames = 1; for (int p = 0; p < Frames; p++) { float t = (float)p / Frames; for (int row = 0; row < M; row++) { for (int col = 0; col < N; col++) { h_tilde.set(row, col, Htilde(h_naught, row, col, t)); } } // complex2complex FFT2D fftwf_execute(plan); // extract the real component for (int row = 0; row < M; row++) { for (int col = 0; col < N; col++) { heights.set(row, col, c_heights.get(row, col).r / 20.0f); } } // save the results { std::stringstream ss; ss << "ocean_" << std::setw(2) << std::setfill('0') << p << ".mat"; std::ofstream file(ss.str().c_str()); file << std::setprecision(10); math::matrix_writeAsText(file, heights); } } fftwf_destroy_plan(plan); }
void icfft2_allocate(sf_complex *inp /* [nkk*n2] */) /*< allocate inverse transform >*/ { #ifdef SF_HAS_FFTW icfg = fftwf_plan_dft_2d(n2,n1, (fftwf_complex *) inp, (fftwf_complex *) cc[0], FFTW_BACKWARD, FFTW_MEASURE); if (NULL == icfg) sf_error("FFTW failure."); #endif }
void cfft2(sf_complex *inp /* [n1*n2] */, sf_complex *out /* [nk*n2] */) /*< 2-D FFT >*/ { int i1, i2; #ifdef SF_HAS_FFTW if (NULL==cfg) { cfg = fftwf_plan_dft_2d(n2,n1, (fftwf_complex *) cc[0], (fftwf_complex *) dd[0], FFTW_FORWARD, FFTW_MEASURE); if (NULL == cfg) sf_error("FFTW failure."); } #endif /* FFT centering */ for (i2=0; i2<n2; i2++) { for (i1=0; i1<n1; i1++) { #ifdef SF_HAS_COMPLEX_H cc[i2][i1] = ((i2%2==0)==(i1%2==0))? inp[i2*n1+i1]:-inp[i2*n1+i1]; #else cc[i2][i1] = ((i2%2==0)==(i1%2==0))? inp[i2*n1+i1]:sf_cneg(inp[i2*n1+i1]); #endif /* #ifdef SF_HAS_COMPLEX_H cc[i2][i1] = ((i2%2==0)==(i1%2==0))? inp[i2*n1+i1]:(-1*inp[i2*n1+i1]); #else cc[i2][i1] = ((i2%2==0)==(i1%2==0))? inp[i2*n1+i1]:sf_cneg(inp[i2*n1+i1]); #endif */ } } #ifdef SF_HAS_FFTW fftwf_execute(cfg); for (i2=0; i2<n2; i2++) { for (i1=0; i1<nk; i1++) { out[i2*nk+i1]=dd[i2][i1]; } } #else for (i2=0; i2 < n2; i2++) { kiss_fft_stride(cfg1,(kiss_fft_cpx *) cc[i2],tmp[i2],1); } for (i1=0; i1 < nk; i1++) { kiss_fft_stride(cfg2,tmp[0]+i1,ctrace2,nk); for (i2=0; i2<n2; i2++) { out[i2*nk+i1] = trace2[i2]; } } #endif }
void ifft2(float *out /* [n1*n2] */, sf_complex *inp /* [nk*n2] */) /*< 2-D inverse FFT >*/ { int i1, i2; #ifdef SF_HAS_FFTW if (NULL==icfg) { icfg = cmplx? fftwf_plan_dft_2d(n2,n1, (fftwf_complex *) dd, (fftwf_complex *) cc[0], FFTW_BACKWARD, FFTW_MEASURE): fftwf_plan_dft_c2r_2d(n2,n1, (fftwf_complex *) dd, ff[0], FFTW_MEASURE); if (NULL == icfg) sf_error("FFTW failure."); } #endif #ifdef SF_HAS_FFTW for (i1=0; i1 < nk*n2; i1++) dd[i1] = inp[i1]; fftwf_execute(icfg); #else for (i1=0; i1 < nk; i1++) { kiss_fft_stride(icfg2,(kiss_fft_cpx *) (inp+i1),ctrace2,nk); for (i2=0; i2<n2; i2++) { tmp[i2][i1] = ctrace2[i2]; } } for (i2=0; i2 < n2; i2++) { if (cmplx) { kiss_fft_stride(icfg1,tmp[i2],(kiss_fft_cpx *) cc[i2],1); } else { kiss_fftri(icfg,tmp[i2],ff[i2]); } } #endif /* FFT centering and normalization */ for (i2=0; i2<n2; i2++) { for (i1=0; i1<n1; i1++) { if (cmplx) { out[i2*n1+i1] = (((i2%2==0)==(i1%2==0))? wt:-wt) * crealf(cc[i2][i1]); } else { out[i2*n1+i1] = (i2%2? -wt: wt)*ff[i2][i1]; } } } }
void fft2(float *inp /* [n1*n2] */, sf_complex *out /* [nk*n2] */) /*< 2-D FFT >*/ { int i1, i2; #ifdef SF_HAS_FFTW if (NULL==cfg) { cfg = cmplx? fftwf_plan_dft_2d(n2,n1, (fftwf_complex *) cc[0], (fftwf_complex *) dd, FFTW_FORWARD, FFTW_MEASURE): fftwf_plan_dft_r2c_2d(n2,n1, ff[0], (fftwf_complex *) dd, FFTW_MEASURE); if (NULL == cfg) sf_error("FFTW failure."); } #endif /* FFT centering */ for (i2=0; i2<n2; i2++) { for (i1=0; i1<n1; i1++) { if (cmplx) { cc[i2][i1] = sf_cmplx(((i2%2==0)==(i1%2==0))? inp[i2*n1+i1]:-inp[i2*n1+i1],0.); } else { ff[i2][i1] = (i2%2)? -inp[i2*n1+i1]:inp[i2*n1+i1]; } } } #ifdef SF_HAS_FFTW fftwf_execute(cfg); for (i1=0; i1 < nk*n2; i1++) out[i1] = dd[i1]; #else for (i2=0; i2 < n2; i2++) { if (cmplx) { kiss_fft_stride(cfg1,(kiss_fft_cpx *) cc[i2],tmp[i2],1); } else { kiss_fftr (cfg,ff[i2],tmp[i2]); } } for (i1=0; i1 < nk; i1++) { kiss_fft_stride(cfg2,tmp[0]+i1,ctrace2,nk); for (i2=0; i2<n2; i2++) { out[i2*nk+i1] = trace2[i2]; } } #endif }
WAVEFUNC::WAVEFUNC(int x, int y, float_tt resX, float_tt resY) : detPosX(0), detPosY(0), iPosX(0), iPosY(0), thickness(0.0), nx(x), ny(y), resolutionX(resX), resolutionY(resY) { char waveFile[256]; const char *waveFileBase = "mulswav"; #if FLOAT_PRECISION == 1 diffpat = float2D(nx,ny,"diffpat"); avgArray = float2D(nx,ny,"avgArray"); #else diffpat = double2D(nx,ny,"diffpat"); avgArray = double2D(nx,ny,"avgArray"); #endif m_imageIO=ImageIOPtr(new CImageIO(nx, ny, thickness, resolutionX, resolutionY)); #if FLOAT_PRECISION == 1 wave = complex2Df(nx, ny, "wave"); fftPlanWaveForw = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, FFTW_ESTIMATE); fftPlanWaveInv = fftwf_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, FFTW_ESTIMATE); #else wave = complex2D(nx, ny, "wave"); fftPlanWaveForw = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_FORWARD, fftMeasureFlag); fftPlanWaveInv = fftw_plan_dft_2d(nx,ny,wave[0],wave[0],FFTW_BACKWARD, fftMeasureFlag); #endif sprintf(waveFile,"%s.img",waveFileBase); strcpy(fileout,waveFile); sprintf(fileStart,"mulswav.img"); }
void fft2dCPU(T1* d_data, int nx, int ny) { cout << "Running forward xform 2d" << endl; fftwf_plan plan; plan = fftwf_plan_dft_2d(nx, ny, (fftwf_complex*) d_data, (fftwf_complex*) d_data, FFTW_FORWARD, FFTW_ESTIMATE); // Inverse transform 'gridData_d' in place. //fftwf_print_plan(plan); fftwf_execute(plan); fftwf_destroy_plan(plan); }
// wrapper around FFTW3 that computes the complex-valued Fourier transform // of a real-valued image static void fft_2dfloat(fftwf_complex *fx, float *x, int w, int h) { fftwf_complex *a = fftwf_malloc(w*h*sizeof*a); //fprintf(stderr, "planning...\n"); evoke_wisdom(); fftwf_plan p = fftwf_plan_dft_2d(h, w, a, fx, FFTW_FORWARD, FFTW_ESTIMATE); bequeath_wisdom(); //fprintf(stderr, "...planned!\n"); FORI(w*h) a[i] = x[i]; // complex assignment! fftwf_execute(p); fftwf_destroy_plan(p); fftwf_free(a); fftwf_cleanup(); }
// Wrapper around FFTW3 that computes the real-valued inverse Fourier transform // of a complex-valued frequantial image. // The input data must be hermitic. static void ifft_2dfloat(float *ifx, fftwf_complex *fx, int w, int h) { fftwf_complex *a = fftwf_malloc(w*h*sizeof*a); fftwf_complex *b = fftwf_malloc(w*h*sizeof*b); //fprintf(stderr, "planning...\n"); evoke_wisdom(); fftwf_plan p = fftwf_plan_dft_2d(h, w, a, b, FFTW_BACKWARD, FFTW_ESTIMATE); bequeath_wisdom(); //fprintf(stderr, "...planned!\n"); FORI(w*h) a[i] = fx[i]; fftwf_execute(p); float scale = 1.0/(w*h); FORI(w*h) { fftwf_complex z = b[i] * scale; ifx[i] = crealf(z); //assert(cimagf(z) < 0.001); }
static void iDoFFT(void *map, int width, int height, int inverse, int center, int normalize) { if (inverse && center) iCenterFFT((im_complex*)map, width, height, inverse); #ifdef USE_FFTW3 #if (IM_COMPLEX==IM_FLOAT) fftwf_plan plan = fftwf_plan_dft_2d(height, width, (fftwf_complex*)map, (fftwf_complex*)map, // in-place transform inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE); fftwf_execute(plan); fftwf_destroy_plan(plan); #else fftw_plan plan = fftw_plan_dft_2d(height, width, (fftw_complex*)map, (fftw_complex*)map, // in-place transform inverse ? FFTW_BACKWARD : FFTW_FORWARD, FFTW_ESTIMATE); fftw_execute(plan); fftw_destroy_plan(plan); #endif #else fftwnd_plan plan = fftw2d_create_plan(height, width, inverse?FFTW_BACKWARD:FFTW_FORWARD, FFTW_ESTIMATE|FFTW_IN_PLACE); fftwnd(plan, 1, (FFTW_COMPLEX*)map, 1, 0, 0, 0, 0); fftwnd_destroy_plan(plan); #endif if (!inverse && center) iCenterFFT((im_complex*)map, width, height, inverse); if (normalize) { im_real NM = (im_real)(width * height); int count = (int)(2*NM); if (normalize == 1) NM = (im_real)sqrt(NM); im_real *fmap = (im_real*)map; for (int i = 0; i < count; i++) *fmap++ /= NM; } }
void FFT::plan() { m_in.clear(); m_plan.clear(); std::cout << "Create CPU FFT plans for " << m_num_threads << " threads" << std::endl; // Create plans used by each threads std::lock_guard<std::mutex> lock(m_mutex); for (unsigned i = 0; i < m_num_threads; i++) { auto in = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * m_size.x * m_size.y * m_size.z); fftwf_plan plan; if (m_dim == 2) plan = fftwf_plan_dft_2d(m_size.y, m_size.x, in, in, m_sign, FFTW_ESTIMATE | FFTW_DESTROY_INPUT); else if (m_dim ==3) plan = fftwf_plan_dft_3d(m_size.z, m_size.y, m_size.x, in, in, m_sign, FFTW_ESTIMATE | FFTW_DESTROY_INPUT); m_in.push_back(in); m_plan.push_back(plan); } }
void Slice::backTransformSlice(unsigned char *RecImage, float** Img_2D_Temp, float** Img_2D, fftwf_complex* complexSlice, float* AbsoluteReconstructedImage) { fftwf_plan plan; // 2D FFT // printf("Executing 2D Inverse FFT - Begin.... \n"); plan = fftwf_plan_dft_2d(256, 256, complexSlice,complexSlice , FFTW_BACKWARD, FFTW_ESTIMATE); fftwf_execute(plan); //* printf("Executing 2D Inverse FFT - End.... \n"); // Scaling int mSliceSize = 256 * 256; int mNormalizedVal = mSliceSize * 50 * 1; for (int sliceCtr = 0; sliceCtr < mSliceSize; sliceCtr++) { AbsoluteReconstructedImage[sliceCtr] = (float) sqrt((complexSlice[sliceCtr][0] * complexSlice[sliceCtr][0]) + (complexSlice[sliceCtr][1] * complexSlice[sliceCtr][1]))/(mNormalizedVal); } int ctr = 0; for (int i = 0; i < 256; i++) for(int j = 0; j < 256; j++) { Img_2D_Temp[i][j] = AbsoluteReconstructedImage[ctr]; Img_2D[i][j] = 0; ctr++; } //* printf("Wrapping Around Resulting Image - Begin.... \n"); Img_2D = FFTShift::FFT_Shift_2D(Img_2D_Temp, Img_2D, 256); AbsoluteReconstructedImage = FFTShift::Repack_2D(Img_2D, AbsoluteReconstructedImage, 256); //* printf("Wrapping Around Resulting Image - End.... \n"); for (int i = 0; i < 256 * 256; i++) { RecImage[i] = (char)(AbsoluteReconstructedImage[i]); } }
void seplowrank2d(float *ldata,float *rdata,float *fmid, float *x, int *ijkx, int *ijkz, int nx,int nz,int m,int n,int m2,int n2, int iflag) /*< seplowrank2d: separating wave-modes based on low-rank decomposition >*/ { int i, im, im2, jn2, ikx, ikz; float sum1, sum2, *wp; wp = sf_floatalloc(m*n2); /* * Note: m=nx*nz; n=nkx*nkz; * * x[nx*nz]: 1D array for input and output 2D wavefield * ldata[m*m2]: 1D array for left matrix from low-rank decomposition * rdata[n2*n]: 1D array for right matrix from low-rank decomposition * fmid[m2*n2]: 1D array for mid matrix from low-rank decomposition */ #ifdef SF_HAS_FFTW /* using FFTW in Madagascar */ sf_complex *xx, *xin, *xout; fftwf_plan xp; fftwf_plan xpi; xin=sf_complexalloc(m); xout=sf_complexalloc(n); xx=sf_complexalloc(n); xp=fftwf_plan_dft_2d(nx,nz, (fftwf_complex *) xin, (fftwf_complex *) xout, FFTW_FORWARD,FFTW_ESTIMATE); xpi=fftwf_plan_dft_2d(nx,nz,(fftwf_complex *) xin, (fftwf_complex *) xout, FFTW_BACKWARD,FFTW_ESTIMATE); /* FFT: from (x,z) to (kx, kz) domain */ if(iflag==1) for(i=0;i<m;i++) xin[i]=sf_cmplx(x[i], 0.); else for(i=0;i<m;i++) xin[i]=sf_cmplx(0.0, x[i]); fftwf_execute(xp); for(i=0;i<n;i++) xx[i] = xout[i]; /* n2 IFFT from (kx, kz) to (x, z) domain*/ for(jn2=0;jn2<n2;jn2++) { i=0; int jn2n=jn2*n; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; int ii=jn2n+ixnz; for(ikz=0;ikz<nz;ikz++) { xin[i]=rdata[ii+ijkz[ikz]]*xx[i]; i++; } } /* (kx,kz) to (x, z) domain */ fftwf_execute(xpi); for(im=0;im<m;im++) wp[jn2*m+im] = creal(xout[im])/n; } fftwf_destroy_plan(xp); fftwf_destroy_plan(xpi); free(xx); free(xin); free(xout); /* Matrix multiplication in space-domain */ for(im=0;im<m;im++) { sum1=0.0; for(im2=0;im2<m2;im2++) { sum2=0.0; for(jn2=0;jn2<n2;jn2++) sum2 += fmid[im2*n2+jn2]*wp[jn2*m+im]; sum1 += ldata[im*m2+im2]*sum2; }/*im2 loop*/ x[im] = sum1; } #else /* using FFTW in user's own computer */ fftw_complex *xx, *xin, *xout; fftw_plan xp; fftw_plan xpi; xin=fftw_complexalloc(m); xout=fftw_complexalloc(n); xx=fftw_complexalloc(n); xp=fftw_plan_dft_2d(nx,nz, (fftw_complex *) xin, (fftw_complex *) xout, FFTW_FORWARD,FFTW_ESTIMATE); xpi=fftw_plan_dft_2d(nx,nz,(fftw_complex *) xin, (fftw_complex *) xout, FFTW_BACKWARD,FFTW_ESTIMATE); /* FFT: from (x,z) to (kx, kz) domain */ for(i=0;i<m;i++) { xin[i][0]=x[i]; xin[i][1]=0.; } fftw_execute(xp); if(iflag!=1) for(i=0;i<n;i++) xout[i] *= sf_cmplx(0.0, 1.0); for(i=0;i<n;i++) xx[i] = xout[i]; /* n2 IFFT from (kx, kz) to (x, z) domain*/ for(jn2=0;jn2<n2;jn2++) { int jn2n=jn2*n; i=0; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; int ii=jn2n+ixnz; for(ikz=0;ikz<nz;ikz++) { xin[i]=rdata[ii+ijkz[ikz]]*xx[i]; i++; } } /* (kx,kz) to (x, z) domain */ fftw_execute(xpi); for(im=0;im<m;im++) wp[jn2*m+im] = xout[im][0]/n; } fftw_destroy_plan(xp); fftw_destroy_plan(xpi); free(xx); free(xin); free(xout); /* Matrix multiplication in space-domain */ for(im=0;im<m;im++) { sum1=0.0; for(im2=0;im2<m2;im2++) { sum2=0.0; for(jn2=0;jn2<n2;jn2++) sum2 += fmid[im2*n2+jn2]*wp[jn2*m+im]; sum1 += ldata[im*m2+im2]*sum2; }/*im2 loop*/ x[im] = sum1; } #endif free(wp); }
static void color_prefilt(color_image_t *src, int fc) { fftw_lock(); int i, j; /* Log */ for(j = 0; j < src->height; j++) { for(i = 0; i < src->width; i++) { src->c1[j*src->width+i] = log(src->c1[j*src->width+i]+1.0f); src->c2[j*src->width+i] = log(src->c2[j*src->width+i]+1.0f); src->c3[j*src->width+i] = log(src->c3[j*src->width+i]+1.0f); } } color_image_t *img_pad = color_image_add_padding(src, 5); /* Get sizes */ int width = img_pad->width; int height = img_pad->height; /* Alloc memory */ float *fx = (float *) fftwf_malloc(width*height*sizeof(float)); float *fy = (float *) fftwf_malloc(width*height*sizeof(float)); float *gfc = (float *) fftwf_malloc(width*height*sizeof(float)); fftwf_complex *ina1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *ina2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *ina3 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *inb1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *inb2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *inb3 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *out1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *out2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *out3 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); /* Build whitening filter */ float s1 = fc/sqrt(log(2)); for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { ina1[j*width + i][0] = img_pad->c1[j*width+i]; ina2[j*width + i][0] = img_pad->c2[j*width+i]; ina3[j*width + i][0] = img_pad->c3[j*width+i]; ina1[j*width + i][1] = 0.0f; ina2[j*width + i][1] = 0.0f; ina3[j*width + i][1] = 0.0f; fx[j*width + i] = (float) i - width/2.0f; fy[j*width + i] = (float) j - height/2.0f; gfc[j*width + i] = exp(-(fx[j*width + i]*fx[j*width + i] + fy[j*width + i]*fy[j*width + i]) / (s1*s1)); } } fftshift(gfc, width, height); /* FFT */ fftwf_plan fft11 = fftwf_plan_dft_2d(width, height, ina1, out1, FFTW_FORWARD, FFTW_ESTIMATE); fftwf_plan fft12 = fftwf_plan_dft_2d(width, height, ina2, out2, FFTW_FORWARD, FFTW_ESTIMATE); fftwf_plan fft13 = fftwf_plan_dft_2d(width, height, ina3, out3, FFTW_FORWARD, FFTW_ESTIMATE); fftw_unlock(); fftwf_execute(fft11); fftwf_execute(fft12); fftwf_execute(fft13); fftw_lock(); /* Apply whitening filter */ for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { out1[j*width+i][0] *= gfc[j*width + i]; out2[j*width+i][0] *= gfc[j*width + i]; out3[j*width+i][0] *= gfc[j*width + i]; out1[j*width+i][1] *= gfc[j*width + i]; out2[j*width+i][1] *= gfc[j*width + i]; out3[j*width+i][1] *= gfc[j*width + i]; } } /* IFFT */ fftwf_plan ifft11 = fftwf_plan_dft_2d(width, height, out1, inb1, FFTW_BACKWARD, FFTW_ESTIMATE); fftwf_plan ifft12 = fftwf_plan_dft_2d(width, height, out2, inb2, FFTW_BACKWARD, FFTW_ESTIMATE); fftwf_plan ifft13 = fftwf_plan_dft_2d(width, height, out3, inb3, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_unlock(); fftwf_execute(ifft11); fftwf_execute(ifft12); fftwf_execute(ifft13); fftw_lock(); /* Local contrast normalisation */ for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { img_pad->c1[j*width+i] -= inb1[j*width+i][0] / (width*height); img_pad->c2[j*width+i] -= inb2[j*width+i][0] / (width*height); img_pad->c3[j*width+i] -= inb3[j*width+i][0] / (width*height); float mean = (img_pad->c1[j*width+i] + img_pad->c2[j*width+i] + img_pad->c3[j*width+i])/3.0f; ina1[j*width+i][0] = mean*mean; ina1[j*width+i][1] = 0.0f; } } /* FFT */ fftwf_plan fft21 = fftwf_plan_dft_2d(width, height, ina1, out1, FFTW_FORWARD, FFTW_ESTIMATE); fftw_unlock(); fftwf_execute(fft21); fftw_lock(); /* Apply contrast normalisation filter */ for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { out1[j*width+i][0] *= gfc[j*width + i]; out1[j*width+i][1] *= gfc[j*width + i]; } } /* IFFT */ fftwf_plan ifft2 = fftwf_plan_dft_2d(width, height, out1, inb1, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_unlock(); fftwf_execute(ifft2); fftw_lock(); /* Get result from contrast normalisation filter */ for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { float val = sqrt(sqrt(inb1[j*width+i][0]*inb1[j*width+i][0]+inb1[j*width+i][1]*inb1[j*width+i][1]) / (width*height)); img_pad->c1[j*width+i] /= (0.2f+val); img_pad->c2[j*width+i] /= (0.2f+val); img_pad->c3[j*width+i] /= (0.2f+val); } } color_image_rem_padding(src, img_pad, 5); /* Free */ fftwf_destroy_plan(fft11); fftwf_destroy_plan(fft12); fftwf_destroy_plan(fft13); fftwf_destroy_plan(ifft11); fftwf_destroy_plan(ifft12); fftwf_destroy_plan(ifft13); fftwf_destroy_plan(fft21); fftwf_destroy_plan(ifft2); color_image_delete(img_pad); fftwf_free(ina1); fftwf_free(ina2); fftwf_free(ina3); fftwf_free(inb1); fftwf_free(inb2); fftwf_free(inb3); fftwf_free(out1); fftwf_free(out2); fftwf_free(out3); fftwf_free(fx); fftwf_free(fy); fftwf_free(gfc); fftw_unlock(); }
void decomplowrank2d(float *ldataxx,float *rdataxx,float *fmidxx, float *ldataxz,float *rdataxz,float *fmidxz, float *ldatazz,float *rdatazz,float *fmidzz, float *px, float *pz, int *ijkx, int *ijkz, int nx, int nz, int m, int n, int MM, int m2xx, int n2xx, int m2xz, int n2xz, int m2zz, int n2zz) /*< decomplowrank2d: vector decomposition based on low-rank decomposition >*/ { int i, im, im2, jn2, ikx, ikz; float sum1, sum2, *wp; #ifdef SF_HAS_FFTW /* using FFTW in Madagascar */ sf_warning("============= using SF_HAS_FFTW ===="); sf_complex *pxx, *xin, *xout; sf_complex *pzz; fftwf_plan xp; fftwf_plan xpi; xin=sf_complexalloc(m); xout=sf_complexalloc(n); pxx=sf_complexalloc(n); pzz=sf_complexalloc(n); xp=fftwf_plan_dft_2d(nx,nz, (fftwf_complex *) xin, (fftwf_complex *) xout, FFTW_FORWARD,FFTW_ESTIMATE); xpi=fftwf_plan_dft_2d(nx,nz,(fftwf_complex *) xin, (fftwf_complex *) xout, FFTW_BACKWARD,FFTW_ESTIMATE); /* FFT: from (x,z) to (kx, kz) domain */ for(i=0;i<m;i++){ xin[i]=sf_cmplx(px[i], 0.); px[i] = 0.0; } fftwf_execute(xp); for(i=0;i<n;i++) pxx[i] = xout[i]; for(i=0;i<m;i++){ xin[i]=sf_cmplx(pz[i], 0.); pz[i] = 0.0; } fftwf_execute(xp); for(i=0;i<n;i++) pzz[i] = xout[i]; /* n2 IFFT from (kx, kz) to (x, z) domain*/ wp = sf_floatalloc(m*n2xx); for(jn2=0;jn2<n2xx;jn2++) { i=0; int jn2n=jn2*n; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; int ii=jn2n+ixnz; for(ikz=0;ikz<nz;ikz++) { xin[i]=rdataxx[ii+ijkz[ikz]]*pxx[i]; i++; } } /* (kx,kz) to (x, z) domain */ fftwf_execute(xpi); for(im=0;im<m;im++) wp[jn2*m+im] = creal(xout[im])/n; } /* Matrix multiplication in space-domain */ for(im=0;im<m;im++) { sum1=0.0; for(im2=0;im2<m2xx;im2++) { sum2=0.0; for(jn2=0;jn2<n2xx;jn2++) sum2 += fmidxx[im2*n2xx+jn2]*wp[jn2*m+im]; sum1 += ldataxx[im*m2xx+im2]*sum2; }/*im2 loop */ px[im] = sum1; } free(wp); /* n2 IFFT from (kx, kz) to (x, z) domain*/ wp = sf_floatalloc(m*n2xz); for(jn2=0;jn2<n2xz;jn2++) { i=0; int jn2n=jn2*n; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; int ii=jn2n+ixnz; for(ikz=0;ikz<nz;ikz++) { xin[i]=rdataxz[ii+ijkz[ikz]]*pzz[i]; i++; } } /* (kx,kz) to (x, z) domain */ fftwf_execute(xpi); for(im=0;im<m;im++) wp[jn2*m+im] = creal(xout[im])/n; } /* Matrix multiplication in space-domain */ for(im=0;im<m;im++) { sum1=0.0; for(im2=0;im2<m2xz;im2++) { sum2=0.0; for(jn2=0;jn2<n2xz;jn2++) sum2 += fmidxz[im2*n2xz+jn2]*wp[jn2*m+im]; sum1 += ldataxz[im*m2xz+im2]*sum2; }/*im2 loop*/ px[im] += sum1; } free(wp); /* n2 IFFT from (kx, kz) to (x, z) domain*/ wp = sf_floatalloc(m*n2zz); for(jn2=0;jn2<n2zz;jn2++) { i=0; int jn2n=jn2*n; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; int ii=jn2n+ixnz; for(ikz=0;ikz<nz;ikz++) { xin[i]=rdatazz[ii+ijkz[ikz]]*pzz[i]; i++; } } /* (kx,kz) to (x, z) domain */ fftwf_execute(xpi); for(im=0;im<m;im++) wp[jn2*m+im] = creal(xout[im])/n; } /* Matrix multiplication in space-domain */ for(im=0;im<m;im++) { sum1=0.0; for(im2=0;im2<m2zz;im2++) { sum2=0.0; for(jn2=0;jn2<n2zz;jn2++) sum2 += fmidzz[im2*n2zz+jn2]*wp[jn2*m+im]; sum1 += ldatazz[im*m2zz+im2]*sum2; }/*im2 loop*/ pz[im] = sum1; } free(wp); /* n2 IFFT from (kx, kz) to (x, z) domain*/ wp = sf_floatalloc(m*n2xz); for(jn2=0;jn2<n2xz;jn2++) { i=0; int jn2n=jn2*n; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; int ii=jn2n+ixnz; for(ikz=0;ikz<nz;ikz++) { xin[i]=rdataxz[ii+ijkz[ikz]]*pxx[i]; i++; } } /* (kx,kz) to (x, z) domain */ fftwf_execute(xpi); for(im=0;im<m;im++) wp[jn2*m+im] = creal(xout[im])/n; } /* Matrix multiplication in space-domain */ for(im=0;im<m;im++) { sum1=0.0; for(im2=0;im2<m2xz;im2++) { sum2=0.0; for(jn2=0;jn2<n2xz;jn2++) sum2 += fmidxz[im2*n2xz+jn2]*wp[jn2*m+im]; sum1 += ldataxz[im*m2xz+im2]*sum2; }/*im2 loop*/ pz[im] += sum1; } free(wp); fftwf_destroy_plan(xp); fftwf_destroy_plan(xpi); free(pxx); free(pzz); free(xin); free(xout); #else /* using FFTW in user's own computer */ sf_warning("============= using user installed FFTW ===="); #endif }
void whitening(int num_images, int sx1,int sy1, int sx, int sy, float *Image1, float *Image2) { FILE *output; int *num; int ISIZE=sx, Loop; int i,j,k,m,it; int *mask; double WL,STEPR,THETATR,RAD,ANGLE,C1,C2,ANGDIF,CNTRST,DF,PHACON,ANGSPT,CCOS, AMPCON; double CS1, KV1; float *ctf,*CHI; float *amp1; float CHI_max, CHI_min; double max1,min1,max2,min2, temp,mean,dev; output=fopen("ctf.dat","w"); fftwf_complex *in, *out, *in_cp,*out_cp; fftwf_plan p1,p2; ctf=(float *)malloc(sizeof(float)*sx*sy); CHI=(float *)malloc(sizeof(float)*sx*sy); amp1=(float *)malloc(sizeof(float)*sx*sy); in_cp=(fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*sx1*sy1); out_cp=( fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*sx1*sy1); in=(fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*sx*sy); out=( fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*sx*sy); fprintf(output,"P2 %d %d \n",sx,sy); fprintf(output,"10001 \n"); /* CTF */ CS1=CS*(10000000); KV1=KV*1000; WL=12.3/sqrt(KV1+KV1*KV1/(1000000.0)); STEPR=DSTEP*(10000)/XMAG; THETATR=WL/(STEPR*ISIZE); AMPCON=0.07; PHACON=sqrt(1-AMPCON*AMPCON); for(i=0;i<sx;i++) { for(j=0;j<sy;j++) { RAD = sqrtf((i-sx/2)*(i-sx/2)*1.0+(j-sy/2)*(j-sy/2)*1.0); ANGLE=RAD*THETATR; ANGSPT=atan2(((j-sy/2)*1.0),((i-sx/2)*1.0)); C1=2*pi*ANGLE*ANGLE/(2.0*WL); C2=-C1*CS1*ANGLE*ANGLE/2.0; ANGDIF=ANGSPT-ANGAST*pi/180; CCOS=cos(2*ANGDIF); if(i==sx/2 && j==sy/2) { ctf[IDX(i,j,sx,sy)]=1.0; CHI[IDX(i,j,sx,sy)]=0; } else if(DIFMID1==0.0 || DIFMID2==0.0 ) ctf[IDX(i,j,sx,sy)]=1.0; else { DF=0.5*(DIFMID1+DIFMID2+CCOS*(DIFMID1-DIFMID2)); CHI[IDX(i,j,sx,sy)]=C1*DF+C2; ctf[IDX(i,j,sx,sy)]=-sin(CHI[IDX(i,j,sx,sy)])*PHACON-cos(CHI[IDX(i,j,sx,sy)])*AMPCON; } } } CHI_max=-1.0e20; CHI_min=-CHI_max; for(i=0;i<sx;i++) for(j=0;j<sy;j++) { if(CHI_max<CHI[IDX(i,j,sx,sy)]) CHI_max=CHI[IDX(i,j,sx,sy)]; if(CHI_min>CHI[IDX(i,j,sx,sy)]) CHI_min=CHI[IDX(i,j,sx,sy)]; } printf("CHI_min=%f CHI_max=%f \n",CHI_min, CHI_max); /* Iteratively whiten each unit cell */ for(it=0;it<num_images;it++) { /* Calculate the average spectrum */ mean=0.0; for(i=0;i<sx;i++) for(j=0;j<sy;j++) mean+=Image1[IDX(i,j,sx,sy)1+it*sx1*sy1]; mean/=(sx*sy); for(i=0;i<sx1;i++) for(j=0;j<sy1;j++) { in_cp[IDX(i,j,sx,sy)1][0]=(Image1[IDX(i,j,sx,sy)1+it*sx1*sy1]-mean)*pow(-1.0,(i+j)*1.0); in_cp[IDX(i,j,sx,sy)1][1]=0; } p1=fftwf_plan_dft_2d(sx1,sy1,in_cp,out_cp,FFTW_FORWARD,FFTW_ESTIMATE); fftwf_execute(p1); fftwf_destroy_plan(p1); /* if(it==77) { for(i=0;i<sx1;i++) { for(j=0;j<sy1;j++) fprintf(output,"%f ", sqrt(powf(out_cp[IDX(i,j,sx,sy)1][0],2.0)+powf(out_cp[IDX(i,j,sx,sy)1][1],2.0))); } fclose(output); } */ /* Downsample in Fourier space */ for(i=-sx/2;i<sx/2;i++) for(j=-sy/2;j<sy/2;j++) { out[IDX(i+sx/2,j+sy/2,sx,sy)][0]=out_cp[IDX(i+sx1/2,j+sy1/2,sx1,sy1)][0]; out[IDX(i+sx/2,j+sy/2,sx,sy)][1]=out_cp[IDX(i+sx1/2,j+sy1/2,sx1,sy1)][1]; } for(i=0;i<sx;i++) for(j=0;j<sy;j++) amp1[IDX(i,j,sx,sy)]=pow(out[IDX(i,j,sx,sy)][0],2.0)+pow(out[IDX(i,j,sx,sy)][1],2.0); /* normalize the images if applicable */ for(i=0;i<sx;i++) for(j=0;j<sy;j++) { if(do_whiten==1) { out[IDX(i,j,sx,sy)][0]=(float)(out[IDX(i,j,sx,sy)][0]/sqrtf(amp1[IDX(i,j,sx,sy)]+1.0e-30)); out[IDX(i,j,sx,sy)][1]=(float)(out[IDX(i,j,sx,sy)][1]/sqrtf(amp1[IDX(i,j,sx,sy)]+1.0e-30)); if(ctf[IDX(i,j,sx,sy)]<0) { out[IDX(i,j,sx,sy)][0]*=-1; out[IDX(i,j,sx,sy)][1]*=-1; } } } p2=fftwf_plan_dft_2d(sx,sy,out,in,FFTW_BACKWARD,FFTW_ESTIMATE); fftwf_execute(p2); fftwf_destroy_plan(p2); for(i=0;i<sx;i++) for(j=0;j<sy;j++) Image2[IDX(i,j,sx,sy)+it*sx*sy]=in[IDX(i,j,sx,sy)][0]*pow(-1,(i+j)*1.0)/(sx*sy); if(it==77) { max2=-1.0e20; min2=-max2; for(i=0;i<sx;i++) for(j=0;j<sy;j++) { amp1[IDX(i,j,sx,sy)]=in[IDX(i,j,sx,sy)][0]; // sqrt(powf(out[IDX(i,j,sx,sy)][0],2.0)+powf(out[IDX(i,j,sx,sy)][1],2.0)); if(max2<amp1[IDX(i,j,sx,sy)]) max2=amp1[IDX(i,j,sx,sy)]; if(min2>amp1[IDX(i,j,sx,sy)]) min2=amp1[IDX(i,j,sx,sy)]; } printf("amp max=%f min=%f \n",max2,min2); for(i=0;i<sx;i++) { for(j=0;j<sy;j++) fprintf(output,"%f ", (amp1[IDX(i,j,sx,sy)])); // -min2)/(max2-min2)*10001+1) ; fprintf(output,"\n"); } fclose(output); } } fftwf_free(in); fftwf_free(out); fftwf_free(in_cp); fftwf_free(out_cp); free(amp1); free(CHI); free(ctf); }
static float *color_gist_gabor(color_image_t *src, const int w, image_list_t *G) { fftw_lock(); int i, j, k; /* Get sizes */ int width = src->width; int height = src->height; float *res = (float *) malloc(3*w*w*G->size*sizeof(float)); fftwf_complex *ina1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *ina2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *ina3 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *inb1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *inb2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *inb3 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *outa1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *outa2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *outa3 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *outb1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *outb2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *outb3 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { ina1[j*width+i][0] = src->c1[j*width+i]; ina2[j*width+i][0] = src->c2[j*width+i]; ina3[j*width+i][0] = src->c3[j*width+i]; ina1[j*width+i][1] = 0.0f; ina2[j*width+i][1] = 0.0f; ina3[j*width+i][1] = 0.0f; } } /* FFT */ fftwf_plan fft1 = fftwf_plan_dft_2d(width, height, ina1, outa1, FFTW_FORWARD, FFTW_ESTIMATE); fftwf_plan fft2 = fftwf_plan_dft_2d(width, height, ina2, outa2, FFTW_FORWARD, FFTW_ESTIMATE); fftwf_plan fft3 = fftwf_plan_dft_2d(width, height, ina3, outa3, FFTW_FORWARD, FFTW_ESTIMATE); fftwf_plan ifft1 = fftwf_plan_dft_2d(width, height, outb1, inb1, FFTW_BACKWARD, FFTW_ESTIMATE); fftwf_plan ifft2 = fftwf_plan_dft_2d(width, height, outb2, inb2, FFTW_BACKWARD, FFTW_ESTIMATE); fftwf_plan ifft3 = fftwf_plan_dft_2d(width, height, outb3, inb3, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_unlock(); fftwf_execute(fft1); fftwf_execute(fft2); fftwf_execute(fft3); for(k = 0; k < G->size; k++) { for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { outb1[j*width+i][0] = outa1[j*width+i][0] * G->data[k]->data[j*G->data[k]->stride+i]; outb2[j*width+i][0] = outa2[j*width+i][0] * G->data[k]->data[j*G->data[k]->stride+i]; outb3[j*width+i][0] = outa3[j*width+i][0] * G->data[k]->data[j*G->data[k]->stride+i]; outb1[j*width+i][1] = outa1[j*width+i][1] * G->data[k]->data[j*G->data[k]->stride+i]; outb2[j*width+i][1] = outa2[j*width+i][1] * G->data[k]->data[j*G->data[k]->stride+i]; outb3[j*width+i][1] = outa3[j*width+i][1] * G->data[k]->data[j*G->data[k]->stride+i]; } } fftwf_execute(ifft1); fftwf_execute(ifft2); fftwf_execute(ifft3); for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { src->c1[j*width+i] = sqrt(inb1[j*width+i][0]*inb1[j*width+i][0]+inb1[j*width+i][1]*inb1[j*width+i][1])/(width*height); src->c2[j*width+i] = sqrt(inb2[j*width+i][0]*inb2[j*width+i][0]+inb2[j*width+i][1]*inb2[j*width+i][1])/(width*height); src->c3[j*width+i] = sqrt(inb3[j*width+i][0]*inb3[j*width+i][0]+inb3[j*width+i][1]*inb3[j*width+i][1])/(width*height); } } color_down_N(res+0*G->size*w*w+k*w*w, src, w, 0); color_down_N(res+1*G->size*w*w+k*w*w, src, w, 1); color_down_N(res+2*G->size*w*w+k*w*w, src, w, 2); } fftw_lock(); fftwf_destroy_plan(fft1); fftwf_destroy_plan(fft2); fftwf_destroy_plan(fft3); fftwf_destroy_plan(ifft1); fftwf_destroy_plan(ifft2); fftwf_destroy_plan(ifft3); fftwf_free(ina1); fftwf_free(ina2); fftwf_free(ina3); fftwf_free(inb1); fftwf_free(inb2); fftwf_free(inb3); fftwf_free(outa1); fftwf_free(outa2); fftwf_free(outa3); fftwf_free(outb1); fftwf_free(outb2); fftwf_free(outb3); fftw_unlock(); return res; }
/*static*/ float *gist_gabor(image_t *src, const int w, image_list_t *G) { fftw_lock(); int i, j, k; /* Get sizes */ int width = src->width; int height = src->height; int stride = src->stride; float *res = (float *) malloc(w*w*G->size*sizeof(float)); fftwf_complex *in1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *in2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *out1 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); fftwf_complex *out2 = (fftwf_complex *) fftwf_malloc(width*height*sizeof(fftwf_complex)); for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { in1[j*width + i][0] = src->data[j*stride+i]; in1[j*width + i][1] = 0.0f; } } /* FFT */ fftwf_plan fft = fftwf_plan_dft_2d(width, height, in1, out1, FFTW_FORWARD, FFTW_ESTIMATE); fftwf_plan ifft = fftwf_plan_dft_2d(width, height, out2, in2, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_unlock(); fftwf_execute(fft); for(k = 0; k < G->size; k++) { for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { out2[j*width+i][0] = out1[j*width+i][0] * G->data[k]->data[j*stride+i]; out2[j*width+i][1] = out1[j*width+i][1] * G->data[k]->data[j*stride+i]; } } fftwf_execute(ifft); for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { src->data[j*stride+i] = sqrt(in2[j*width+i][0]*in2[j*width+i][0]+in2[j*width+i][1]*in2[j*width+i][1])/(width*height); } } down_N(res+k*w*w, src, w); } fftw_lock(); fftwf_destroy_plan(fft); fftwf_destroy_plan(ifft); fftwf_free(in1); fftwf_free(in2); fftwf_free(out1); fftwf_free(out2); fftw_unlock(); return res; }
void gridrec( const float *data, int dy, int dt, int dx, const float *center, const float *theta, float *recon, int ngridx, int ngridy, const char *fname, const float *filter_par) { int s, p, iu, iv; float *sine, *cose, *wtbl, *work, *winv; float (* const filter)(float, float, float) = get_filter(fname); const float C = 7.0; const float nt = 20.0; const float lambda = 0.99998546; const unsigned int L = (int)(2*C/M_PI); const int ltbl = 512; int pdim; float _Complex *sino, *filphase, **H; const float coefs[11] = { 0.5767616E+02, -0.8931343E+02, 0.4167596E+02, -0.1053599E+02, 0.1662374E+01, -0.1780527E-00, 0.1372983E-01, -0.7963169E-03, 0.3593372E-04, -0.1295941E-05, 0.3817796E-07}; // Compute pdim = next power of 2 >= dx for(pdim = 16; pdim < dx; pdim *= 2); const int M02 = pdim/2-1; // Allocate storage for various arrays. sino = malloc_vector_c(pdim); filphase = malloc_vector_c(pdim/2); H = malloc_matrix_c(pdim, pdim); wtbl = malloc_vector_f(ltbl+1); winv = malloc_vector_f(pdim-1); work = malloc_vector_f(L+1); // Set up table of sines and cosines. set_trig_tables(dt, theta, &sine, &cose); // Set up PSWF lookup tables. set_pswf_tables(C, nt, lambda, coefs, ltbl, M02, wtbl, winv); // Set up fftw plans fftwf_plan reverse_1d; fftwf_plan forward_2d; reverse_1d = fftwf_plan_dft_1d(pdim, sino, sino, FFTW_BACKWARD, FFTW_MEASURE); forward_2d = fftwf_plan_dft_2d(pdim, pdim, H[0], H[0], FFTW_FORWARD, FFTW_MEASURE); // For each slice. for (s=0; s<dy; s+=2) { // Set up table of combined filter-phase factors. set_filter_tables(dt, pdim, center[s], filter, filter_par, filphase); // First clear the array H for(iu=0; iu<pdim; iu++) { for(iv=0; iv<pdim; iv++) { H[iu][iv] = 0.0; } } // Loop over the dt projection angles. For each angle, do the following: // 1. Copy the real projection data from the two slices into the // real and imaginary parts of the first dx elements of the // complex array, sino[]. Set the remaining pdim-dx elements // to zero (zero-padding). // 2. Carry out a (1D) Fourier transform on the complex data. // This results in transform data that is arranged in // "wrap-around" order, with non-negative spatial frequencies // occupying the first half, and negative frequencies the second // half, of the array, sino[]. // 3. Multiply each element of the 1-D transform by a complex, // frequency dependent factor, filphase[]. These factors were // precomputed as part of recofour1((float*)sino-1,pdim,1);n_init() and combine the // tomographic filtering with a phase factor which shifts the // origin in configuration space to the projection of the // rotation axis as defined by the parameter, "center". If a // region of interest (ROI) centered on a different origin has // been specified [(X0,Y0)!=(0,0)], multiplication by an // additional phase factor, dependent on angle as well as // frequency, is required. // 4. For each data element, find the Cartesian coordinates, // <U,V>, of the corresponding point in the 2D frequency plane, // in units of the spacing in the MxM rectangular grid placed // thereon; then calculate the upper and lower limits in each // coordinate direction of the integer coordinates for the // grid points contained in an LxL box centered on <U,V>. // Using a precomputed table of the (1-D) convolving function, // W, calculate the contribution of this data element to the // (2-D) convolvent (the 2_D convolvent is the product of // 1_D convolvents in the X and Y directions) at each of these // grid points, and update the complex 2D array H accordingly. // At the end of Phase 1, the array H[][] contains data arranged in // "natural", rather than wrap-around order -- that is, the origin in // the spatial frequency plane is situated in the middle, rather than // at the beginning, of the array, H[][]. This simplifies the code // for carrying out the convolution (step 4 above), but necessitates // an additional correction -- See Phase 3 below. float _Complex Cdata1, Cdata2; float U, V, rtmp; const float L2 = (int)(C/M_PI); const float tblspcg = 2*ltbl/L; const int pdim2 = pdim >> 1; const int M2 = pdim >> 1; int iul, iuh, ivl, ivh; int j, k; // For each projection for(p=0; p<dt; p++) { for(j=0; j<pdim; j++) { if(j < dx) { // Add data from both slices float second_sino = 0.0; const unsigned int index = j+p*dx+s*dx*dt; if ((s + 1) < dy) { second_sino = data[index + dx*dt]; } sino[j] = data[index] + I*second_sino; } else { // Zero fill the rest of the array sino[j] = 0.0; } } // Take FFT of the projection array fftwf_execute(reverse_1d); // For each FFT(projection) for(j=1; j<pdim2; j++) { Cdata1 = filphase[j] * sino[j]; Cdata2 = conjf(filphase[j]) * sino[pdim-j]; U = j * cose[p] + M2; V = j * sine[p] + M2; // Note freq space origin is at (M2,M2), but we // offset the indices U, V, etc. to range from 0 to M-1. iul = ceil(U-L2); iuh = floor(U+L2); ivl = ceil(V-L2); ivh = floor(V+L2); if(iul<1) iul = 1; if(iuh>=pdim) iuh = pdim-1; if(ivl<1) ivl = 1; if(ivh>=pdim) ivh = pdim-1; // Note aliasing value (at index=0) is forced to zero. for(iv=ivl, k=0; iv<=ivh; iv++, k++) { work[k] = wtbl[lroundf(fabs(V-iv)*tblspcg)]; } for(iu=iul; iu<=iuh; iu++) { rtmp = wtbl[lroundf(fabs(U-iu)*tblspcg)]; for(iv=ivl, k=0; iv<=ivh; iv++, k++) { const float convolv = rtmp*work[k]; H[iu][iv] += convolv*Cdata1; H[pdim-iu][pdim-iv] += convolv*Cdata2; } } } } // Carry out a 2D inverse FFT on the array H. // At the conclusion of this phase, the configuration // space data is arranged in wrap-around order with the origin // (center of reconstructed images) situated at the start of the // array. The first (resp. second) half of the array contains the lower, // Y<0 (resp, upper Y>0) part of the image, and within each row of the // array, the first (resp. second) half contains data for the right [X>0] // (resp. left [X<0]) half of the image. fftwf_execute(forward_2d); // Copy the real and imaginary parts of the complex data from H[][], // into the output buffers for the two reconstructed real images, // simultaneously carrying out a final multiplicative correction. // The correction factors are taken from the array, winv[], previously // computed in set_pswf_tables(), and consist logically of three parts, namely: // 1. A positive real factor, corresponding to the reciprocal // of the inverse Fourier transform, of the convolving // function, W, and // 2. Multiplication by the cell size, (1/D1)^2, in 2D frequency // space. This correctly normalizes the 2D inverse FFT carried // out in Phase 2. (Note that all quantities are expressed in // units in which the detector spacing is one.) // 3. A sign change for the "odd-numbered" elements (in a // checkerboard pattern) of the array. This compensates // for the fact that the 2-D Fourier transform (Phase 2) // started with a frequency array in which the zero frequency // point appears in the middle of the array instead of at // its start. // Only the elements in the square M0xM0 subarray of H[][], centered // about the origin, are utilized. The other elements are not part of the // actual region being reconstructed and are discarded. Because of the // wrap-around ordering, the subarray must actually be taken from the four // corners" of the 2D array, H[][] -- See Phase 2 description, above. // The final data corresponds physically to the linear X-ray absorption // coefficient expressed in units of the inverse detector spacing -- to // convert to inverse cm (say), one must divide the data by the detector // spacing in cm. int ustart, vstart, ufin, vfin; const int padx = (pdim-ngridx)/2; const int pady = (pdim-ngridy)/2; const int offsetx = M02+1-padx; const int offsety = M02+1-pady; const int islc1 = s*ngridx*ngridy; // index slice 1 const int islc2 = (s+1)*ngridx*ngridy; // index slice 2 ustart = pdim-offsety; ufin = pdim; j = 0; while(j<ngridy) { for(iu=ustart; iu<ufin; j++, iu++) { const float corrn_u = winv[j+pady]; vstart = pdim-offsetx; vfin = pdim; k = 0; while(k<ngridx) { for(iv=vstart; iv<vfin; k++, iv++) { const float corrn = corrn_u*winv[k+padx]; recon[islc1+ngridy*(ngridx-1-k)+j] = corrn*crealf(H[iu][iv]); if((s+1) < dy) { recon[islc2+ngridy*(ngridx-1-k)+j] = corrn*cimagf(H[iu][iv]); } } if(k<ngridx) { vstart = 0; vfin = ngridx-offsetx; } } } if(j<ngridy) { ustart = 0; ufin = ngridy-offsety; } } } free_vector_f(sine); free_vector_f(cose); free_vector_c(sino); free_vector_f(wtbl); free_vector_c(filphase); free_vector_f(winv); free_vector_f(work); free_matrix_c(H); fftwf_destroy_plan(reverse_1d); fftwf_destroy_plan(forward_2d); return; }
void sep(float *w, float *x, int *ijkx, int *ijkz, int nx,int nz,int m,int n, int iflag) /*< sep: separating wave-modes by filtering in wavenumber domain >*/ { int i, ikx, ikz, im; #ifdef SF_HAS_FFTW /* using FFTW in Madagascar */ /* int ntest=30; sf_complex *xi, *xo; xi=sf_complexalloc(ntest); xo=sf_complexalloc(ntest); fftwf_plan xf; xf=fftwf_plan_dft_1d(ntest,(fftwf_complex *) xi, (fftwf_complex *) xo, FFTW_FORWARD,FFTW_ESTIMATE); for(i=0;i<ntest;i++) xi[i] = sf_cmplx(0.0, 0.0); for(i=ntest/2-3;i<ntest/2+3;i++) xi[i] = sf_cmplx(sin(i*1.0), 0.0); fftwf_execute(xf); for(i=0;i<ntest;i++) sf_warning("xo[%d]=(%f, %f)",i,creal(xo[i]),cimag(xo[i])); free(xi); free(xo); fftwf_destroy_plan(xf); exit(0); */ sf_complex *xin, *xout; fftwf_plan xp; fftwf_plan xpi; xin=sf_complexalloc(m); xout=sf_complexalloc(n); xp=fftwf_plan_dft_2d(nx,nz, (fftwf_complex *) xin, (fftwf_complex *) xout, FFTW_FORWARD,FFTW_ESTIMATE); xpi=fftwf_plan_dft_2d(nx,nz,(fftwf_complex *) xin, (fftwf_complex *) xout, FFTW_BACKWARD,FFTW_ESTIMATE); /* (x,z) to (kx, kz) domain */ if(iflag==1) for(i=0;i<m;i++) xin[i]=sf_cmplx(x[i], 0.); else for(i=0;i<m;i++) xin[i]=sf_cmplx(0.0, x[i]); fftwf_execute(xp); /* Filtering in (kx, kz) domain */ i=0; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; for(ikz=0;ikz<nz;ikz++) { xin[i]=w[ixnz+ijkz[ikz]]*xout[i]; i++; } } /* IFFT from (kx,kz) to (x, z) domain */ fftwf_execute(xpi); for(im=0;im<m;im++) x[im] = creal(xout[im])/n; fftwf_destroy_plan(xp); fftwf_destroy_plan(xpi); free(xin); free(xout); #else /* using FFTW in user's own computer */ fftw_complex *xin, *xout; fftw_plan xp; fftw_plan xpi; xin=fftw_complexalloc(m); xout=fftw_complexalloc(n); xp=fftw_plan_dft_2d(nx,nz, (fftw_complex *) xin, (fftw_complex *) xout, FFTW_FORWARD,FFTW_ESTIMATE); xpi=fftw_plan_dft_2d(nx,nz,(fftw_complex *) xin, (fftw_complex *) xout, FFTW_BACKWARD,FFTW_ESTIMATE); /* (x,z) to (kx, kz) domain */ for(i=0;i<m;i++) { xin[i][0]=x[i]; xin[i][1]=0.; } fftw_execute(xp); /* Filtering in (kx, kz) domain */ i=0; for(ikx=0;ikx<nx;ikx++) { /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ int ixnz=ijkx[ikx]*nz; for(ikz=0;ikz<nz;ikz++) { xin[i]=w[ixnz+ijkz[ikz]]*xout[i]; i++; } } /* IFFT from (kx,kz) to (x, z) domain */ fftw_execute(xpi); for(im=0;im<m;im++) x[im] = xout[im][0]/n; fftw_destroy_plan(xp); fftw_destroy_plan(xpi); free(xin); free(xout); #endif }
void envelop(int sx,int sy, float *refer, float A, float B, float *FSC) { int i,j,k,m; float WL,STEPR,THETATR,RAD,env; int ISIZE=sx; fftwf_complex *in, *out; fftwf_plan p1,p2; in=(fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*sx*sy); out=( fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*sx*sy); CS=CS*(10000000); KV=KV*1000; WL=12.3/sqrt(KV+KV*KV/(1000000.0)); STEPR=DSTEP*(10000)/XMAG; THETATR=WL/(STEPR*ISIZE); /* FFT transform */ for(i=0;i<sx;i++) for(j=0;j<sy;j++) { in[IDX(i,j,sx,sy)][0]=refer[IDX(i,j,sx,sy)]*powf(-1,(i+j)*1.0); in[IDX(i,j,sx,sy)][1]=0.0; } p1=fftwf_plan_dft_2d(sx,sy,in,out,FFTW_FORWARD,FFTW_ESTIMATE); p2=fftwf_plan_dft_2d(sx,sy,out,in,FFTW_BACKWARD,FFTW_ESTIMATE); fftwf_execute(p1); fftwf_destroy_plan(p1); /* Apply envelope */ float rmax=sx*DSTEP*10000/(XMAG*RESMAX); float rmin=sx*DSTEP*10000/(XMAG*RESMIN); float invresol; printf("\nApplying Envelope with B-factor %f\n",B); printf("RESMAX=%f RESMIN=%f \n", RESMAX, RESMIN); printf("rmax=%f rmin=%f \n", rmax,rmin); printf("sx=%i, sy=%i\n\n",sx,sy); for(i=0;i<sx;i++) for(j=0;j<sy;j++) { RAD = sqrtf((i-sx/2)*(i-sx/2)*1.0+(j-sy/2)*(j-sy/2)*1.0)+1; m=(int)RAD; invresol = RAD*XMAG/(sx*DSTEP*10000); if(m<sx/2) // rmax && m>rmin) { if(m<rmax) env=B*invresol*invresol/4.0; else env=0.0; // if(j==sy/2) printf("m=%i, invresol=%f, env=%f\n",m,invresol,env); // RAD=RAD*THETATR; // env=B*RAD*RAD; // out[j+i*sy][0]=out[j+i*sy][0]*(A+(1-A)*sqrt(2*fabs(FSC[m])/(1+fabs(FSC[m]))))*exp(env); // out[j+i*sy][1]=out[j+i*sy][1]*(A+(1-A)*sqrt(2*fabs(FSC[m])/(1+fabs(FSC[m]))))*exp(env); out[IDX(i,j,sx,sy)][0]=out[IDX(i,j,sx,sy)][0]*(A+(1-A)*sqrt(2*fabs(FSC[m])/(1+fabs(FSC[m]))))*exp(-env); out[IDX(i,j,sx,sy)][1]=out[IDX(i,j,sx,sy)][1]*(A+(1-A)*sqrt(2*fabs(FSC[m])/(1+fabs(FSC[m]))))*exp(-env); // env=B/(4*RAD*RAD); // out[IDX(i,j,sx,sy)][0]=out[IDX(i,j,sx,sy)][0]*exp(env); // out[IDX(i,j,sx,sy)][1]=out[IDX(i,j,sx,sy)][1]*exp(env); } else { out[IDX(i,j,sx,sy)][0]=0; out[IDX(i,j,sx,sy)][1]=0; } } /* IFFT transform */ fftwf_execute(p2); fftwf_destroy_plan(p2); for(i=0;i<sx;i++) for(j=0;j<sy;j++) refer[IDX(i,j,sx,sy)]=in[IDX(i,j,sx,sy)][0]*powf(-1,(i+j)*1.0); fftwf_free(in); fftwf_free(out); }
float* CalcFFT(GDALDataset *srcDS1, GDALDataset *srcDS2, GDALDataset *dstDS) { fftwf_plan plan1, plan2, planI; fftwf_complex *img1, *img2; unsigned char *out; int band; const size_t px_count = dstDS->GetRasterXSize() * dstDS->GetRasterYSize(); const size_t buffer_len = sizeof(fftwf_complex) * px_count; img1 = (fftwf_complex*) fftwf_malloc(buffer_len); img2 = (fftwf_complex*) fftwf_malloc(buffer_len); out = (unsigned char*) fftwf_malloc(sizeof(unsigned char) * px_count); /* ^ not used in fft, but aligned is good anyway */ if(img1 == NULL || img2 == NULL || out == NULL) error("Could not allocate memory\n"); if(fftwf_init_threads()) fftwf_plan_with_nthreads(CORES); plan1 = fftwf_plan_dft_2d(dstDS->GetRasterYSize(), dstDS->GetRasterXSize(), img1, img1, FFTW_FORWARD, FFTW_ESTIMATE); plan2 = fftwf_plan_dft_2d(dstDS->GetRasterYSize(), dstDS->GetRasterXSize(), img2, img2, FFTW_FORWARD, FFTW_ESTIMATE); planI = fftwf_plan_dft_2d(dstDS->GetRasterYSize(), dstDS->GetRasterXSize(), img2, img2, FFTW_BACKWARD, FFTW_ESTIMATE); if(plan1 == NULL || plan2 == NULL || planI == NULL) error("Could not plan FFT\n"); for(band = 1; band <= dstDS->GetRasterCount(); band++) { printf("FFT 1 band %d\n", band); runFFT( plan1, srcDS1, img1, band, dstDS ); printf("FFT 2 band %d\n", band); runFFT( plan2, srcDS2, img2, band, dstDS ); printf("Complex Conj band %d\n", band); /* mult img1 and conj of img2 */ for(int px = 0; px < px_count; px++) { img2[px] = img1[px] * conj(img2[px]); } /* IFFT of result */ printf("IFFT band %d\n", band); fftwf_execute(planI); printf("normalize band %d\n", band); complex float norm = csqrt(px_count + 0I); float max = cabs(img2[0] / norm); float min = cabs(img2[0] / norm); for(int i = 0; i < px_count; i++) { img2[i] = img2[i] / norm; if(cabs(img2[i]) < min) min = cabs(img2[i]); if(cabs(img2[i]) > max) max = cabs(img2[i]); } /* img2 should now be real - normalize 0-255 and -- write output */ printf("Save band %d; min = %f max = %f\n", band, min, max); for(int i = 0; i < px_count; i++) { out[i] = floor( ((cabs(img2[i]) - min) / (max-min) ) * 255.0 ); } fft2shift(out, dstDS->GetRasterYSize(), dstDS->GetRasterXSize()); dstDS->GetRasterBand(band)->RasterIO( GF_Write, 0, 0, dstDS->GetRasterXSize(), dstDS->GetRasterYSize(), out, dstDS->GetRasterXSize(), dstDS->GetRasterYSize(), GDT_Byte, 0, 0); } fftwf_destroy_plan(plan1); fftwf_destroy_plan(plan2); fftwf_destroy_plan(planI); fftwf_free(img1); fftwf_free(img2); fftwf_free(out); }
void CLSimulator::initializeFFTW() { _distances_split = (fftwf_complex *)fftwf_malloc(_nFFT * sizeof(fftwf_complex)); _sVals_split = (fftwf_complex *)fftwf_malloc(_nFFT * sizeof(fftwf_complex)); _convolution_split = (fftwf_complex *)fftwf_malloc(_nFFT * sizeof(fftwf_complex)); _distances_f_split = (fftwf_complex *)fftwf_malloc(_nFFT * sizeof(fftwf_complex)); _sVals_f_split = (fftwf_complex *)fftwf_malloc(_nFFT * sizeof(fftwf_complex)); _convolution_f_split = (fftwf_complex *)fftwf_malloc(_nFFT * sizeof(fftwf_complex)); assert(_nX >= 1 && _nY >= 1 && _nZ >= 1); assert((_nX >= _nY) && (_nY >= _nZ)); if (_nY == 1) { _p_distances_fftw = fftwf_plan_dft_1d(_nFFT, _distances_split, _distances_f_split, FFTW_FORWARD, FFTW_ESTIMATE); _p_sVals_fftw = fftwf_plan_dft_1d(_nFFT, _sVals_split, _sVals_f_split, FFTW_FORWARD, FFTW_ESTIMATE); _p_inv_fftw = fftwf_plan_dft_1d(_nFFT, _convolution_f_split, _convolution_split, FFTW_BACKWARD, FFTW_ESTIMATE); } else if (_nZ == 1) { _p_distances_fftw = fftwf_plan_dft_2d(_nFFTx, _nFFTy, _distances_split, _distances_f_split, FFTW_FORWARD, FFTW_ESTIMATE); _p_sVals_fftw = fftwf_plan_dft_2d(_nFFTx, _nFFTy, _sVals_split, _sVals_f_split, FFTW_FORWARD, FFTW_ESTIMATE); _p_inv_fftw = fftwf_plan_dft_2d(_nFFTx, _nFFTy, _convolution_f_split, _convolution_split, FFTW_BACKWARD, FFTW_ESTIMATE); } else { _p_distances_fftw = fftwf_plan_dft_3d(_nFFTx, _nFFTy, _nFFTz, _distances_split, _distances_f_split, FFTW_FORWARD, FFTW_ESTIMATE); _p_sVals_fftw = fftwf_plan_dft_3d(_nFFTx, _nFFTy, _nFFTz, _sVals_split, _sVals_f_split, FFTW_FORWARD, FFTW_ESTIMATE); _p_inv_fftw = fftwf_plan_dft_3d(_nFFTx, _nFFTy, _nFFTz, _convolution_f_split, _convolution_split, FFTW_BACKWARD, FFTW_ESTIMATE); } for (size_t i = 0; i < _nFFT; ++i) { _sVals_split[i][0] = 0; _sVals_split[i][1] = 0; } for (size_t x_idx = 0, x_val = _nX - 1; x_idx < _nX; ++x_idx, --x_val) { for (size_t y_idx = 0, y_val = _nY - 1; y_idx < _nY; ++y_idx, --y_val) { float distance = sqrt(pow(float(x_val), 2.0f) + pow(float(y_val), 2.0f)); _distances_split[x_idx + y_idx * _nFFTx][0] = _f_w_EE((float(distance))); _distances_split[x_idx + y_idx * _nFFTx][1] = 0; } } for (size_t x_idx = 0, x_val = _nX - 1; x_idx < _nX; ++x_idx, --x_val) { for (size_t y_idx = _nY, y_val = 1; y_idx < _nFFTy - 1; ++y_idx, ++y_val) { float distance = sqrt(pow(float(x_val), 2.0f) + pow(float(y_val), 2.0f)); _distances_split[x_idx + y_idx * _nFFTx][0] = _f_w_EE((float(distance))); _distances_split[x_idx + y_idx * _nFFTx][1] = 0; } } if (_nY > 1) { for (size_t x_idx = 0; x_idx < _nFFTx; ++x_idx) { _distances_split[x_idx + (_nFFTy - 1) * _nFFTx][0] = 0; _distances_split[x_idx + (_nFFTy - 1) * _nFFTx][1] = 0; } } for (size_t x_idx = _nX, x_val = 1; x_idx < _nFFTx - 1; ++x_idx, ++x_val) { for (size_t y_idx = 0, y_val = _nY - 1; y_idx < _nY; ++y_idx, --y_val) { float distance = sqrt(pow(float(x_val), 2.0f) + pow(float(y_val), 2.0f)); _distances_split[x_idx + y_idx * _nFFTx][0] = _f_w_EE((float(distance))); _distances_split[x_idx + y_idx * _nFFTx][1] = 0; } } for (size_t y_idx = 0; y_idx < _nFFTy; ++y_idx) { _distances_split[(_nFFTx - 1) + y_idx * _nFFTx][0] = 0; _distances_split[(_nFFTx - 1) + y_idx * _nFFTx][1] = 0; } for (size_t x_idx = _nX, x_val = 1; x_idx < _nFFTx - 1; ++x_idx, ++x_val) { for (size_t y_idx = _nY, y_val = 1; y_idx < _nFFTy - 1; ++y_idx, ++y_val) { float distance = sqrt(pow(float(x_val), 2.0f) + pow(float(y_val), 2.0f)); _distances_split[x_idx + y_idx * _nFFTx][0] = _f_w_EE((float(distance))); _distances_split[x_idx + y_idx * _nFFTx][1] = 0; } } fftwf_execute(_p_distances_fftw); }