void init_fft(void) { int i,j; int n[] = {Ny}; int howmany = Nx; int idist=NC, odist=NR; int istride=1, ostride=1; int *inembed=NULL, *onembed=NULL; Nmax = floor(2./3*NC); wc1 = (double complex *)malloc(sizeof(double complex)*Nx*NC); wr1 = (double *)wc1; wc2 = (double complex *)malloc(sizeof(double complex)*Nx*NC); wr2 = (double *)wc2; wc3 = (double complex *)malloc(sizeof(double complex)*Nx*NC); wr3 = (double *)wc3; mask = (double *)malloc(sizeof(double)*Nx*NC); for(i=0;i<Nx;i++) { for(j=0;j<NC;j++) { if (j < Nmax) mask[CINDX] = 1; else mask[CINDX] = 0; } } // // c2r1=fftw_plan_many_dft_c2r(1,&Nx,Ny,wc1,&Nx,1,NC,wr1,&Nx,1,NR,FFTW_ESTIMATE); // if (c2r1 == NULL) printf("Problem with c2r1\n"); // // r2c1=fftw_plan_many_dft_r2c(1,&Nx,Ny,wr1,&Nx,1,NR,wc1,&Nx,1,NC,FFTW_ESTIMATE); // if (r2c1 == NULL) printf("Problem with r2c1\n"); // // // c2r2=fftw_plan_many_dft_c2r(1,&Nx,Ny,wc2,&Nx,1,NC,wr2,&Nx,1,NR,FFTW_ESTIMATE); // if (c2r2 == NULL) printf("Problem with c2r2\n"); // // r2c2=fftw_plan_many_dft_r2c(1,&Nx,Ny,wr2,&Nx,1,NR,wc2,&Nx,1,NC,FFTW_ESTIMATE); // if (r2c2 == NULL) printf("Problem with r2c2\n"); // // // c2r3=fftw_plan_many_dft_c2r(1,&Nx,Ny,wc3,&Nx,1,NC,wr3,&Nx,1,NR,FFTW_ESTIMATE); // if (c2r3 == NULL) printf("Problem with c2r3\n"); // // r2c3=fftw_plan_many_dft_r2c(1,&Nx,Ny,wr3,&Nx,1,NR,wc3,&Nx,1,NC,FFTW_ESTIMATE); // if (r2c3 == NULL) printf("Problem with r2c3\n"); // c2r2=fftw_plan_many_dft_c2r(1,n,howmany,wc2, inembed, istride, idist, wr2, onembed, ostride, odist,FFTW_ESTIMATE); r2c2=fftw_plan_many_dft_r2c(1,n,howmany,wr2, onembed, ostride, odist, wc2, inembed, istride, idist,FFTW_ESTIMATE); c2r1=fftw_plan_many_dft_c2r(1,n,howmany,wc1, inembed, istride, idist, wr1, onembed, ostride, odist,FFTW_ESTIMATE); r2c1=fftw_plan_many_dft_r2c(1,n,howmany,wr1, onembed, ostride, odist, wc1, inembed, istride, idist,FFTW_ESTIMATE); c2r3=fftw_plan_many_dft_c2r(1,n,howmany,wc3, inembed, istride, idist, wr3, onembed, ostride, odist,FFTW_ESTIMATE); r2c3=fftw_plan_many_dft_r2c(1,n,howmany,wr3, onembed, ostride, odist, wc3, inembed, istride, idist,FFTW_ESTIMATE); return; }
void init_output_vtk() { double complex *w2d; const int n_size1D[1] = {NY}; #ifdef WITH_SHEAR w2d = (double complex *) fftw_malloc( sizeof(double complex) * (NY/2+1) * NZ ); if (w2d == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for w2d allocation"); // FFT plans (we use dummy arrays since we use the "guru" interface of fft3 in the code) // The in place/ out of place will be set automatically at this stage // The Following Fourier transforms takes an array of size ( NX+1, NY+1, NZ+1) but consider only the "included" array // of size ( NX+1, NY, NZ+1) and transforms it in y, in an array of size (NX+1, NY/2+1, NZ+1). The j=NY plane is therefore // not modified by these calls #ifdef _OPENMP fftw_plan_with_nthreads( 1 ); #endif #ifdef WITH_2D fft_1d_forward = fftw_plan_many_dft_r2c(1, n_size1D, 1, wr1, NULL, 1, 1, w2d, NULL, 1, 1, FFT_PLANNING || FFTW_UNALIGNED); #else fft_1d_forward = fftw_plan_many_dft_r2c(1, n_size1D, NZ, wr1, NULL, NZ+2, 1, w2d, NULL, NZ, 1, FFT_PLANNING || FFTW_UNALIGNED); #endif if (fft_1d_forward == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW 1D forward plan creation failed"); #ifdef WITH_2D fft_1d_backward = fftw_plan_many_dft_c2r(1, n_size1D, 1, w2d, NULL, 1, 1, wr1, NULL, 1, 1, FFT_PLANNING || FFTW_UNALIGNED); #else fft_1d_backward = fftw_plan_many_dft_c2r(1, n_size1D, NZ, w2d, NULL, NZ, 1, wr1, NULL, NZ+2, 1, FFT_PLANNING || FFTW_UNALIGNED); #endif if (fft_1d_backward == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW 1D backward plan creation failed"); fftw_free(w2d); #endif }
void FFT::backward(VolumeList &volumes) { if (volumes.size() > 0 && volumes[0].domain != Domain::Time) { fftw_plan plan; try { plan = backward_plans.at(volumes.data); } catch (...) { int rank = 3; int n[] = { static_cast<int>(volumes[0].width), static_cast<int>(volumes[0].height), static_cast<int>(volumes[0].depth) }; int howmany = volumes.size(); int idist = volumes.volume_size_complex; int odist = volumes.volume_size_real; int istride = 1, ostride = 1; int *inembed = 0, *onembed = 0; plan = fftw_plan_many_dft_c2r(rank, n, howmany, reinterpret_cast<fftw_complex *>(volumes.data), inembed, istride, idist, volumes.data, onembed, ostride, odist, FFTW_ESTIMATE); backward_plans[volumes.data] = plan; } fftw_execute(plan); for (size_t i = 0; i < volumes.size(); ++i) { volumes[i] *= 1.0 / volumes[i].size; volumes[i].domain = Domain::Time; } } }
void kemo_fftw_plan_many_dft_c2r(fftw_plan *plan, int rank, int *n_size, int howmany, fftw_complex *cplx_in, const int *inembed, int istride, int idist, double *dble_out, int *onembed, int ostride, int odist, unsigned *flags){ *plan = fftw_plan_many_dft_c2r(rank, n_size, howmany, cplx_in, inembed, istride, idist, dble_out, onembed, ostride, odist, *flags); return; }
void CCorrelationFilters::ifft_data(struct CDataStruct *img) { // Need to make this work with fftw threads, there seem to be some compiling and linking errors. int num_dim = img->size_data.size(); int rank = num_dim; int *n = new int(num_dim); int *m = new int(num_dim); for (int i=0; i<num_dim; i++) { n[i] = img->size_data(i); m[i] = img->size_data_freq(i); } fftw_plan plan; fftw_complex *in; double *out; int howmany = img->num_data*img->num_channels; in = reinterpret_cast<fftw_complex *>(img->data_freq); int istride = 1; int ostride = 1; int odist = img->size_data_freq.prod(); int idist = (img->size_data_freq.prod()/img->size_data_freq(num_dim-1))*(img->size_data_freq(num_dim-1)/2+1); out = new double[odist*img->num_channels*img->num_data]; plan = fftw_plan_many_dft_c2r(rank, m, howmany, in, NULL, istride, idist, out, NULL, ostride, odist, FFTW_ESTIMATE); fftw_execute(plan); img->data = out; double scale_factor = sqrt(odist); for (int i=0; i<odist*img->num_channels*img->num_data; i++) { img->data[i] = img->data[i]/scale_factor; } for (int i=0; i<img->num_data; i++) { img->ptr_data.push_back((img->data+i*odist*img->num_channels)); } fftw_destroy_plan(plan); delete[] n; delete[] m; }
int ambit_dft_r2c_inplace(struct ambit_dense_array *a, int sign) { int err = 0; fftw_plan plan = NULL; if (!ambit_dense_array_fftw_r2c_embedded(a)) { fprintf(stderr, "%s: Invalid array or inappropriate embedding.\n", __func__); err = -1; goto cleanup; } switch (sign) { case FFTW_FORWARD: plan = fftw_plan_many_dft_r2c(a->rank, (const int *)a->dim, 1, a->data, (const int *)a->dimembed, 1, 0, (C *)a->data, (const int *)a->dimembed, 1, 0, FFTW_ESTIMATE); break; case FFTW_BACKWARD: plan = fftw_plan_many_dft_c2r(a->rank, (const int *)a->dim, 1, (C *)a->data, (const int *)a->dimembed, 1, 0, a->data, (const int *)a->dimembed, 1, 0, FFTW_ESTIMATE); break; default: fprintf(stderr, "%s: Sign must be FFTW_FORWARD or FFTW_BACKWARD.\n", __func__); err = -1; goto cleanup; } if (!plan) { fprintf(stderr, "%s: DFT planning failed.\n", __func__); err = -1; goto cleanup; } fftw_execute(plan); cleanup: fftw_destroy_plan(plan); return err; }
double *ifftr(double *Y, const double *X, const unsigned long nvar, const unsigned long nobs) { const unsigned long nvarout = (nvar>>1)+1; // Since FFT of real data are symmetric, we only store nvar/2+1 fftw_complex elements as output (symmetric part is not duplicated) const int n = nvar; unsigned long i,nelem; // Create the FFTW plan fftw_plan plan = fftw_plan_many_dft_c2r(1, // [int rank] Rank 1 DFT &n, // [const int *n] Number of variables within input array nobs, // [int howmany] Number of observations (number of DFT to perform) (fftw_complex *) X, // [fftw_complex *in] Input array is X (it is cast to non-const but will not be modified since FFTW_DESTROY_INPUT is not set) NULL, // [const int *inembed] Distance between each rank in input array (Not used since rank=1) 1, // [int istride] Distance between successive variables in input array (in unit of fftw_complex) nvarout, // [int idist] Distance between 2 observations in input array (in unit of fftw_complex) Y, // [double *out] Output array is Y NULL, // [const int *onembed] Distance between each rank in output array (Not used since rank=1) 1, // [int ostride] Distance between successive variables in output array (in unit of double) n, // [int odist] Distance between 2 observations in output array (in unit of double) FFTW_ESTIMATE // [unsigned flags] Quickly choose a plan without performing full benchmarks (maybe sub-optimal but take less time) ); // If plan building fails, quit if(!plan) return NULL; // Execute FFTW plan fftw_execute(plan); // Normalize result by nvar (FFTW compute unormalized transform) nelem = nvar * nobs; for(i = 0; i < nelem; i++) Y[i] /= nvar; // Destroy FFTW plan fftw_destroy_plan(plan); return Y; }
void caffe_cpu_ifft<double>(const int howmany, const int n, const complex<double>* x, double* y){ /* FFTW plan handle */ fftw_plan hplan = 0; const fftw_complex *in = reinterpret_cast<const fftw_complex *>(x); double *out = y; int Ni[] = {n/2+1}; int No[] = {n}; hplan = fftw_plan_many_dft_c2r(1, No, howmany, const_cast<fftw_complex *>(in), Ni, 1, n/2+1, out, No, 1, n, FFTW_ESTIMATE); if (0 == hplan) goto failed; fftw_execute(hplan); fftw_destroy_plan(hplan); failed: return; }
void init_gfft() { // This will init the plans needed by gfft // Transform of NY/NPROC arrays of (logical) size [NX, NZ] // The physical size is [NX, NZ+2] // We use in-place transforms int i; double complex *wi1, *whi1; double *wir1, *whir1; const int n_size2D[2] = {NX, NZ}; const int n_size1D[1] = {NY_COMPLEX}; wi1 = (double complex *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX); if (wi1 == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for wi1 allocation"); whi1 = (double complex *) fftw_malloc( sizeof(double complex) * NX*(NY/2+1)); if (whi1 == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for wi1 allocation"); wir1 = (double *) wi1; whir1= (double *) whi1; for(i = 0 ; i < NTOTAL_COMPLEX; i++) { wi1[i]=1.0; } #ifdef _OPENMP fftw_plan_with_nthreads( nthreads ); #endif r2c_2d = fftw_plan_many_dft_r2c(2, n_size2D, NY / NPROC, wir1, NULL, 1, (NZ+2)*NX, wi1, NULL, 1, (NZ+2)*NX/2, FFT_PLANNING); if (r2c_2d == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW R2C_2D plan creation failed"); c2r_2d = fftw_plan_many_dft_c2r(2, n_size2D, NY / NPROC, wi1, NULL, 1, (NZ+2)*NX/2, wir1, NULL, 1, (NZ+2)*NX , FFT_PLANNING); if (c2r_2d == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW C2R_2D plan creation failed"); r2cfft_2Dslice = fftw_plan_dft_r2c_2d(NX,NY,wrh3,wh3,FFT_PLANNING); //,whir1,whi1 if (r2cfft_2Dslice == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW r2c slice plan creation failed"); // 1D transforms: This are actually c2c transforms, but are used for global 3D transforms. // We will transform forward and backward an array of logical size [NX/NPROC, NY, (NZ+2)/2] along the 2nd dimension // We will do NZ_COMPLEX transforms along Y. Will need a loop on NX/NPROC // We use &w1[NZ_COMPLEX] so that alignement check is done properly (see SIMD in fftw Documentation) #ifdef _OPENMP fftw_plan_with_nthreads( 1 ); #endif r2c_1d = fftw_plan_many_dft(1, n_size1D, NZ_COMPLEX, &wi1[NZ_COMPLEX], NULL, NZ_COMPLEX, 1, &wi1[NZ_COMPLEX], NULL, NZ_COMPLEX, 1, FFTW_FORWARD, FFT_PLANNING); if (r2c_1d == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW R2C_1D plan creation failed"); c2r_1d = fftw_plan_many_dft(1, n_size1D, NZ_COMPLEX, &wi1[NZ_COMPLEX], NULL, NZ_COMPLEX, 1, &wi1[NZ_COMPLEX], NULL, NZ_COMPLEX, 1, FFTW_BACKWARD, FFT_PLANNING); if (c2r_1d == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW C2R_1D plan creation failed"); // init transpose routines init_transpose(); // Let's see which method is faster (with our without threads) fftw_free(wi1); fftw_free(whi1); fft_timer=0.0; return; }