void FourierTransformer::setReal(MultidimArray<std::complex<double> > &input) { bool recomputePlan=false; if (fComplex==NULL) recomputePlan=true; else if (complexDataPtr!=MULTIDIM_ARRAY(input)) recomputePlan=true; else recomputePlan=!(fComplex->sameShape(input)); fFourier.resizeNoCopy(input); fComplex=&input; if (recomputePlan) { int ndim=3; if (ZSIZE(input)==1) { ndim=2; if (YSIZE(input)==1) ndim=1; } int *N = new int[ndim]; switch (ndim) { case 1: N[0]=XSIZE(input); break; case 2: N[0]=YSIZE(input); N[1]=XSIZE(input); break; case 3: N[0]=ZSIZE(input); N[1]=YSIZE(input); N[2]=XSIZE(input); break; } pthread_mutex_lock(&fftw_plan_mutex); if (fPlanForward!=NULL) fftw_destroy_plan(fPlanForward); fPlanForward=NULL; fPlanForward = fftw_plan_dft(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(*fComplex), (fftw_complex*) MULTIDIM_ARRAY(fFourier), FFTW_FORWARD, FFTW_ESTIMATE); if (fPlanBackward!=NULL) fftw_destroy_plan(fPlanBackward); fPlanBackward=NULL; fPlanBackward = fftw_plan_dft(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(fFourier), (fftw_complex*) MULTIDIM_ARRAY(*fComplex), FFTW_BACKWARD, FFTW_ESTIMATE); if (fPlanForward == NULL || fPlanBackward == NULL) REPORT_ERROR(ERR_PLANS_NOCREATE, "FFTW plans cannot be created"); delete [] N; complexDataPtr=MULTIDIM_ARRAY(*fComplex); pthread_mutex_unlock(&fftw_plan_mutex); } }
void math::FFT::ndim_discrete(std::complex<double> * data, int * nn, int ndim, int isign,unsigned flag) { fftw_complex *in,*out; fftw_plan p; unsigned long size = 1; for(int i =0;i<ndim;i++) size *= nn[i]; //assign data and allocate memory in = reinterpret_cast<fftw_complex*>(data); out = new fftw_complex[size]; //make the plan p = fftw_plan_dft(ndim,nn,in,out,isign,flag); //Run fft fftw_execute(p); //clean up fftw_destroy_plan(p); for(int i = 0;i<size;i++) data[i] = std::complex<double>(out[i][0],out[i][1]); delete [] out; }
fft_plan fft_plan_dft_2d( int n[2], std::complex<double> *in, std::complex<double> *out, int sign ) { fft_plan plan = NULL; #ifdef HAVE_LIBFFTW3 # ifdef HAVE_LIBPTHREAD pthread_mutex_lock(&mutex); # endif fftw_plan p; p = fftw_plan_dft(2, n, (fftw_complex*)in, (fftw_complex*)out, sign, FFTW_ESTIMATE); # ifdef HAVE_LIBPTHREAD pthread_mutex_unlock(&mutex); # endif if(NULL != p) { plan = (fft_plan)malloc(sizeof(tag_fft_plan)); plan->plan = p; } #else kiss_fftnd_cfg cfg; cfg = kiss_fftnd_alloc(n, 2, sign, NULL, NULL); if(NULL != cfg) { plan = (fft_plan)malloc(sizeof(tag_fft_plan)); plan->cfg = cfg; plan->in = in; plan->out = out; } #endif return plan; }
PetscErrorCode MatApply_USFFT_Private(Mat A, fftw_plan *plan, int direction, Vec x,Vec y) { #if 0 PetscErrorCode ierr; PetscScalar *r_array, *y_array; Mat_USFFT* = (Mat_USFFT*)(A->data); #endif PetscFunctionBegin; #if 0 /* resample x to usfft->resample */ ierr = MatResample_USFFT_Private(A, x);CHKERRQ(ierr); /* NB: for now we use outdim for both x and y; this will change once a full USFFT is implemented */ ierr = VecGetArray(usfft->resample,&r_array);CHKERRQ(ierr); ierr = VecGetArray(y,&y_array);CHKERRQ(ierr); if (!*plan) { /* create a plan then execute it*/ if (usfft->dof == 1) { #if defined(PETSC_DEBUG_USFFT) ierr = PetscPrintf(PetscObjectComm((PetscObject)A), "direction = %d, usfft->ndim = %d\n", direction, usfft->ndim);CHKERRQ(ierr); for (int ii = 0; ii < usfft->ndim; ++ii) { ierr = PetscPrintf(PetscObjectComm((PetscObject)A), "usfft->outdim[%d] = %d\n", ii, usfft->outdim[ii]);CHKERRQ(ierr); } #endif switch (usfft->dim) { case 1: *plan = fftw_plan_dft_1d(usfft->outdim[0],(fftw_complex*)x_array,(fftw_complex*)y_array,direction,usfft->p_flag); break; case 2: *plan = fftw_plan_dft_2d(usfft->outdim[0],usfft->outdim[1],(fftw_complex*)x_array,(fftw_complex*)y_array,direction,usfft->p_flag); break; case 3: *plan = fftw_plan_dft_3d(usfft->outdim[0],usfft->outdim[1],usfft->outdim[2],(fftw_complex*)x_array,(fftw_complex*)y_array,direction,usfft->p_flag); break; default: *plan = fftw_plan_dft(usfft->ndim,usfft->outdim,(fftw_complex*)x_array,(fftw_complex*)y_array,direction,usfft->p_flag); break; } fftw_execute(*plan); } /* if (dof == 1) */ else { /* if (dof > 1) */ *plan = fftw_plan_many_dft(/*rank*/usfft->ndim, /*n*/usfft->outdim, /*howmany*/usfft->dof, (fftw_complex*)x_array, /*nembed*/usfft->outdim, /*stride*/usfft->dof, /*dist*/1, (fftw_complex*)y_array, /*nembed*/usfft->outdim, /*stride*/usfft->dof, /*dist*/1, /*sign*/direction, /*flags*/usfft->p_flag); fftw_execute(*plan); } /* if (dof > 1) */ } /* if (!*plan) */ else { /* if (*plan) */ /* use existing plan */ fftw_execute_dft(*plan,(fftw_complex*)x_array,(fftw_complex*)y_array); } ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr); ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr); #endif PetscFunctionReturn(0); } /* MatApply_USFFT_Private() */
// multi-d fftw void ft_fftw_d(size_t rank, const int* N, const cmpvec& little_x, cmpvec& big_X) { size_t final_size = 1; for (size_t ii = 0; ii < rank; ++ii) final_size *= N[ii]; big_X.resize(final_size); // http://www.fftw.org/fftw3_doc/Complex-Multi_002dDimensional-DFTs.html cmpvec nclx(little_x); fftw_complex *in = reinterpret_cast<fftw_complex*>(&nclx[0]); fftw_complex *out = reinterpret_cast<fftw_complex*>(&big_X[0]); fftw_plan plan = fftw_plan_dft(rank, N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); fftw_execute(plan); fftw_destroy_plan(plan); }
int dspau_spectrum(double* in, double* out, int dims, int *sizes, int conversion) { int i = 0, d; int len = sizes[0]; int ret = 0; fftw_complex *fft_in, *fft_out; fftw_plan p; for(d = 1; d < dims; d++) { len *= sizes[d]; } fft_in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * len); fft_out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * len); for(i = 0; i < len; i++) { fft_in[i][0] = in[i]; fft_in[i][1] = in[i]; } p = fftw_plan_dft(dims, sizes, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE); fftw_execute(p); switch (conversion) { case magnitude: complex2mag(fft_out, out, len); break; case magnitude_dbv: complex2magdbv(fft_out, out, len); break; case magnitude_rooted: complex2magsqrt(fft_out, out, len); break; case magnitude_squared: complex2magpow(fft_out, out, len); break; case phase_degrees: complex2phideg(fft_out, out, len); break; case phase_radians: complex2phirad(fft_out, out, len); break; default: ret = -1; break; } fftw_destroy_plan(p); fftw_free(fft_in); fftw_free(fft_out); return ret; }
dspau_t* dspau_fft_dft(dspau_stream_p stream, int sign, int conversion) { dspau_t* out = (dspau_t*)calloc(sizeof(dspau_t), stream->len); int* sizes = (int*)calloc(sizeof(int), stream->dims); memcpy(sizes, stream->sizes, stream->dims * sizeof(int)); fftw_plan p; fftw_complex *fft_in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * stream->len); fftw_complex *fft_out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * stream->len); for(int i = 0; i < stream->len; i++) { fft_in[i][0] = stream->in[i]; fft_in[i][1] = 0; } dspau_buffer_reverse(sizes, int, stream->dims); p = fftw_plan_dft(stream->dims, sizes, fft_in, fft_out, sign, FFTW_ESTIMATE); fftw_execute(p); switch (conversion) { case magnitude: complex2mag(fft_out, out, stream->len); break; case magnitude_dbv: complex2magdbv(fft_out, out, stream->len); break; case magnitude_root: complex2magsqrt(fft_out, out, stream->len); break; case magnitude_square: complex2magpow(fft_out, out, stream->len); break; case phase_degrees: complex2phideg(fft_out, out, stream->len); break; case phase_radians: complex2phirad(fft_out, out, stream->len); break; default: break; } fftw_destroy_plan(p); fftw_free(fft_in); fftw_free(fft_out); dspau_t *ret = dspau_fft_shift(out, stream->dims, stream->sizes); free(out); return ret; }
static PlanType create(const std::array<std::size_t,NDims>& _shape, ComplexType* _in, ComplexType* _out, fftw_direction _dir = fftw_direction::forward, unsigned plan_flags = FFTW_MEASURE){ std::array<int,NDims> converted; for(int i = 0;i < NDims;++i) converted[i] = _shape[i]; PlanType value = fftw_plan_dft(NDims, converted.data(), _in, _out, static_cast<int>(_dir), plan_flags ); return value; }
/* Function: fft_image_transform Apply a FFT image transformation (auxiliar function) Parameters: image - Complex matrix (image data) width - Width of the matrix height - Height of the matrix depth - Depth of the matrix direction - Forward or inverse? Returns: Image transformation */ void fft_image_transform(Rcomplex *image, int *width, int *height, int *depth, int direction){ int plane_size = *width * *height * *depth, rank = (*depth == 1) ? 2 : 3; int i = 0, j = 0, d = 0; int *n = calloc(3, sizeof(int)); fftw_complex *in, *out; fftw_plan p; in = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * plane_size); out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * plane_size); for (d = 0; d < *depth; d++){ for (j = 0; j < *height; j++){ for (i = 0; i < *width; i++){ int row_major_pos = d + *depth * (j + *height * i), im_pos = IMGPOS(i, j, d, *width, *height); in[row_major_pos][0] = image[im_pos].r; in[row_major_pos][1] = image[im_pos].i; } } } n[0] = *width; n[1] = *height; n[2] = *depth; p = fftw_plan_dft(rank, n, in, out, direction, FFTW_ESTIMATE); fftw_execute(p); for (d = 0; d < *depth; d++){ for (j = 0; j < *height; j++){ for (i = 0; i < *width; i++){ int row_major_pos = d + *depth * (j + *height * i), im_pos = IMGPOS(i, j, d, *width, *height); image[im_pos].r = out[row_major_pos][0]; image[im_pos].i = out[row_major_pos][1]; } } } free(n); fftw_destroy_plan(p); fftw_free(in); fftw_free(out); }
int main() { config_struct conf = load_config_from("./../../configurations.cfg"); filenames_struct filenames = generate_filenames(&conf); clock_t _c_a_c_f_f_ = start("Creating a c2c FFTW plan... "); size_t tot_num_of_grids = pow(conf.params.numOfAxisGrids, 3); fftw_complex *delta_complex; allocate((void **)&delta_complex, tot_num_of_grids, sizeof(fftw_complex)); fftw_complex *delta_fourier; allocate((void **)&delta_fourier, tot_num_of_grids, sizeof(fftw_complex)); int rank[3] = { conf.params.numOfAxisGrids, conf.params.numOfAxisGrids, conf.params.numOfAxisGrids }; fftw_plan p; p = fftw_plan_dft(3, rank, delta_complex, delta_fourier, FFTW_FORWARD, FFTW_MEASURE); done(_c_a_c_f_f_); clock_t _l_d_c_ = start("Loading density contrast... "); char *input_path = concat(2, "./../../2_griding/output/", filenames.densityContrast); double *delta_real; allocate((void **)&delta_real, tot_num_of_grids, sizeof(double)); load_density_contrast_grid(input_path, delta_real, &conf); convert_real_delta_to_complex(delta_real, delta_complex, &conf); reordering_fourier_input(delta_complex, &conf); done(_l_d_c_); clock_t _f_t_ = start("Fourier transform... "); fftw_execute(p); fftw_destroy_plan(p); done(_f_t_); clock_t _s_d_ = start("Saving data... "); char *output_path = concat(2, "./../output/", filenames.fourierTransformed); FILE * out_file; open_file(&out_file, output_path, "wb"); write_to(out_file, (void *)delta_fourier, tot_num_of_grids, sizeof(fftw_complex)); done(_s_d_); free(delta_real); fftw_free(delta_fourier); fftw_free(delta_complex); free(input_path); free(output_path); return 0; }
/* double precision */ int tcdTransformD( tcdTRANSFORM tType, /* i: which transform to compute */ double *params, /* i: transform parameters(direction)*/ tcdDComplex *data, /* i/o: data to transform- in place */ long nAxes, /* i: number of axes */ long *lAxes, /* i: length of axes */ long *dOrigin /* i: origin of axes */ ) { long nTotal, ii; int status; int *axe_len; fftw_plan plan; /* error checking */ status = tcdCheckData( data, nAxes, lAxes ); if ( status != tcdSUCCESS ) return( status ); if ( params == NULL ) return( tcdERROR_NULLPTR); /* do transforms */ switch ( tType ) { case tcdFFT: axe_len = (int*)calloc(nAxes,sizeof(int)); for (ii=0;ii<nAxes;ii++) axe_len[ii] = lAxes[nAxes-ii-1]; if (params[0] == tcdFORWARD) plan=fftw_plan_dft(nAxes, axe_len, (void *)data, (void *)data, FFTW_FORWARD, FFTW_ESTIMATE); else plan=fftw_plan_dft(nAxes, axe_len,(void *)data, (void *)data, FFTW_BACKWARD, FFTW_ESTIMATE); free(axe_len); if (plan == NULL) { return(tcdERROR); } fftw_execute( plan); /* Normalize */ if ( params[0] == (float )tcdFORWARD ) { nTotal=1; for (ii=0;ii<nAxes ; ii++) nTotal *= lAxes[ii]; for (ii=0; ii<nTotal; ii++) { data[ii].r /= nTotal ; data[ii].i /= nTotal; } } /* destroy plan */ fftw_destroy_plan(plan); break; default: return( tcdERROR_NOTIMPLEMENTED ); } return( tcdSUCCESS ); }
/*------------------------------------------------------------------ - Config file format - simplify, don't need xml, but like the structure { "scalars" : { "nq" : 3, "lrgs" : 4, "print" : true "t" : 10.0, "dt" : 0.1 }, "coefficients" : { "alpha" : [0.112, 0.234, 0.253], "beta" : [0.453, 0.533, -0.732, 0.125, -0.653, 0.752], "delta" : [1.0, 1.0, 1.0] } } ------------------------------------------------------------------*/ int main( int argc, char **argv ){ double *hz, *hhxh; /* hamiltonian components */ double *al, *be, *de; fftw_complex *psi; /* State vector */ fftw_complex factor; double T = 10.0, dt = 0.1; uint64_t i, j, k, bcount; uint64_t nQ=3, N, L=4, dim; int *fft_dims, prnt=0; uint64_t testi, testj; int dzi, dzj; //TODO: consider using smaller vars for flags and these fftw_plan plan; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Parse configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ //TODO: going to need logic to handle incomplete config files if( argc < 2 ){ fprintf( stderr, "Need a json configuration file. Terminating...\n" ); return 1; } /* Parse file and populate applicable data structures */ { JSON_Value *root_value = NULL; JSON_Object *root_object; JSON_Array *array; root_value = json_parse_file_with_comments( argv[1] ); root_object = json_value_get_object( root_value ); nQ = (uint64_t) json_object_dotget_number( root_object, "scalars.nq" ); prnt = json_object_dotget_boolean( root_object, "scalars.print" ); L = (uint64_t) json_object_dotget_number( root_object, "scalars.lrgs" ); T = json_object_dotget_number( root_object, "scalars.t" ); dt = json_object_dotget_number( root_object, "scalars.dt" ); al = (double *)malloc( nQ*sizeof(double) ); de = (double *)malloc( nQ*sizeof(double) ); be = (double *)malloc( (nQ*(nQ-1)/2)*sizeof(double) ); array = json_object_dotget_array( root_object, "coefficients.alpha" ); if( array != NULL ){ for( i = 0; i < json_array_get_count(array); i++ ){ al[i] = -json_array_get_number( array, i ); } } array = json_object_dotget_array( root_object, "coefficients.beta" ); if( array != NULL ){ for( i = 0; i < json_array_get_count(array); i++ ){ be[i] = -json_array_get_number( array, i ); } } array = json_object_dotget_array( root_object, "coefficients.delta" ); if( array != NULL ){ for( i = 0; i < json_array_get_count(array); i++ ){ de[i] = -json_array_get_number( array, i ); } } json_value_free( root_value ); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the Hamiltonian and state vector for the simulation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create state vector and initialize to 1/sqrt(2^n)*(|00...0> + ... + |11...1>) TODO: keep track of local size and local base */ dim = 1 << nQ; factor = 1.0/sqrt( dim ); fft_dims = (int *)malloc( nQ*sizeof(int) ); psi = (fftw_complex *)malloc( (dim)*sizeof(fftw_complex) ); hz = (double *)calloc( (dim),sizeof(double) ); hhxh = (double *)calloc( (dim),sizeof(double) ); for( i = 0; i < nQ; i++ ){ fft_dims[i] = 2; } plan = fftw_plan_dft( nQ, fft_dims, psi, psi, FFTW_FORWARD, FFTW_MEASURE ); /* Assemble Hamiltonian and state vector */ for( k = 0; k < dim; k++ ){ //TODO: when parallelized, k in dzi test will be ~(k + base) bcount = 0; for( i = 0; i < nQ; i++ ){ testi = 1 << (nQ - i - 1); dzi = ((k/testi) % 2 == 0) ? 1 : -1; hz[k] += al[i] * dzi; hhxh[k] += de[i] * dzi; for( j = i; j < nQ; j++ ){ testj = 1 << (nQ - j - 1); dzj = ((k/testj) % 2 == 0) ? 1 : -1; hz[k] += be[bcount] * dzi * dzj; bcount++; } } psi[k] = factor; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Run the Simulation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ fftw_complex cz, cx; double t; N = (uint64_t)(T / dt); for( i = 0; i < N; i++ ){ t = i*dt; //t0 = (i-1)*dt; //Time-dependent coefficients cz = (-dt * I)*t/(2.0*T); cx = (-dt * I)*(1 - t/T); //Evolve system expMatTimesVec( psi, hz, cz, dim ); //apply Z part fftw_execute( plan ); expMatTimesVec( psi, hhxh, cx, dim ); //apply X part fftw_execute( plan ); expMatTimesVec( psi, hz, cz, dim ); //apply Z part /* TODO: can probably get some minor speedup by incorporating this into expMatTimesVec if needed */ scaleVec( psi, 1.0/dim, dim ); } fftw_destroy_plan( plan ); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ //TODO: locally, collect all local largests on one // node, find k largest from that subset if( prnt && nQ < 6 ){ for( i = 0; i < dim; i++ ){ printf( "psi[%d] = (%f, %f)\t%f\n", i, creal( psi[i] ), cimag( psi[i] ), cabs( psi[i]*psi[i] ) ); } } else { uint64_t *largest = (uint64_t *)calloc( L, sizeof(uint64_t) ); findLargest( largest, psi, dim, L ); for( i = 0; i < L; ++i ){ printf( "psi[%d] = (%f, %f)\t%f\n", i, creal( psi[largest[L-1-i]] ), cimag( psi[largest[L-1-i]] ), cabs( psi[largest[L-1-i]]*psi[largest[L-1-i]] ) ); } free( largest ); } /* Free work space. */ fftw_free( psi ); free( fft_dims ); free( hz ); free( hhxh ); return 0; }
/** initialization of fastsum plan */ void fastsum_init_guru(fastsum_plan *ths, int d, int N_total, int M_total, kernel k, double *param, unsigned flags, int nn, int m, int p, double eps_I, double eps_B) { int t; int N[d], n[d]; int n_total; int sort_flags_trafo = 0; int sort_flags_adjoint = 0; #ifdef _OPENMP int nthreads = nfft_get_omp_num_threads(); #endif if (d > 1) { sort_flags_trafo = NFFT_SORT_NODES; #ifdef _OPENMP sort_flags_adjoint = NFFT_SORT_NODES | NFFT_OMP_BLOCKWISE_ADJOINT; #else sort_flags_adjoint = NFFT_SORT_NODES; #endif } ths->d = d; ths->N_total = N_total; ths->M_total = M_total; ths->x = (double *)nfft_malloc(d*N_total*(sizeof(double))); ths->alpha = (double _Complex *)nfft_malloc(N_total*(sizeof(double _Complex))); ths->y = (double *)nfft_malloc(d*M_total*(sizeof(double))); ths->f = (double _Complex *)nfft_malloc(M_total*(sizeof(double _Complex))); ths->k = k; ths->kernel_param = param; ths->flags = flags; ths->p = p; ths->eps_I = eps_I; /* =(double)ths->p/(double)nn; */ /** inner boundary */ ths->eps_B = eps_B; /* =1.0/16.0; */ /** outer boundary */ /** init spline for near field computation */ if (!(ths->flags & EXACT_NEARFIELD)) { if (ths->d==1) { ths->Ad = 4*(ths->p)*(ths->p); ths->Add = (double _Complex *)nfft_malloc((ths->Ad+5)*(sizeof(double _Complex))); } else { if (ths->k == one_over_x) { double delta = 1e-8; switch(p) { case 2: delta = 1e-3; break; case 3: delta = 1e-4; break; case 4: delta = 1e-5; break; case 5: delta = 1e-6; break; case 6: delta = 1e-6; break; case 7: delta = 1e-7; break; default: delta = 1e-8; } #if defined(NF_KUB) ths->Ad = max_i(10, (int) ceil(1.4/pow(delta,1.0/4.0))); ths->Add = (double _Complex *)nfft_malloc((ths->Ad+3)*(sizeof(double _Complex))); #elif defined(NF_QUADR) ths->Ad = (int) ceil(2.2/pow(delta,1.0/3.0)); ths->Add = (double _Complex *)nfft_malloc((ths->Ad+3)*(sizeof(double _Complex))); #elif defined(NF_LIN) ths->Ad = (int) ceil(1.7/pow(delta,1.0/2.0)); ths->Add = (double _Complex *)nfft_malloc((ths->Ad+3)*(sizeof(double _Complex))); #else #error define NF_LIN or NF_QUADR or NF_KUB #endif } else { ths->Ad = 2*(ths->p)*(ths->p); ths->Add = (double _Complex *)nfft_malloc((ths->Ad+3)*(sizeof(double _Complex))); } } } /** init d-dimensional NFFT plan */ ths->n = nn; for (t=0; t<d; t++) { N[t] = nn; n[t] = 2*nn; } nfft_init_guru(&(ths->mv1), d, N, N_total, n, m, sort_flags_adjoint | PRE_PHI_HUT| PRE_PSI| MALLOC_X | MALLOC_F_HAT| MALLOC_F| FFTW_INIT | FFT_OUT_OF_PLACE, FFTW_MEASURE| FFTW_DESTROY_INPUT); nfft_init_guru(&(ths->mv2), d, N, M_total, n, m, sort_flags_trafo | PRE_PHI_HUT| PRE_PSI| MALLOC_X | MALLOC_F_HAT| MALLOC_F| FFTW_INIT | FFT_OUT_OF_PLACE, FFTW_MEASURE| FFTW_DESTROY_INPUT); /** init d-dimensional FFTW plan */ n_total = 1; for (t=0; t<d; t++) n_total *= nn; ths->b = (fftw_complex *)nfft_malloc(n_total*sizeof(fftw_complex)); #ifdef _OPENMP #pragma omp critical (nfft_omp_critical_fftw_plan) { fftw_plan_with_nthreads(nthreads); #endif ths->fft_plan = fftw_plan_dft(d,N,ths->b,ths->b,FFTW_FORWARD,FFTW_ESTIMATE); #ifdef _OPENMP } #endif if (ths->flags & NEARFIELD_BOXES) { ths->box_count_per_dim = floor((0.5 - ths->eps_B) / ths->eps_I) + 1; ths->box_count = 1; for (t=0; t<ths->d; t++) ths->box_count *= ths->box_count_per_dim; ths->box_offset = (int *) nfft_malloc((ths->box_count+1) * sizeof(int)); ths->box_alpha = (double _Complex *)nfft_malloc(ths->N_total*(sizeof(double _Complex))); ths->box_x = (double *) nfft_malloc(ths->d * ths->N_total * sizeof(double)); } }
/******************************************************* * * globale Funktionen * *******************************************************/ fepc_real_t* fft_faltung(fepc_real_t* a, vec_p n_a, fepc_real_t* b, vec_p n_b) { #if defined(HAS_FFTW3) int size_a, size_b, size_c, dim; int k, i, wert, test; int *n; vec_p temp, n_c; fepc_real_t *c; fftw_complex *in, *out,*in_a, *out_a, *in_b, *out_b; fftw_plan p; /*Auf Testen von Konsistenz wird verzichtet, da Input bereits auf Konsistenz getestet*/ /*Faltung ueber Fouriertrafo (Theorie ist in Dokumentation zu finden)*/ dim = n_a->dim; n_c = vec_new(dim); for(k=0;k<dim;k++) { n_c->array[k] = n_a->array[k]+n_b->array[k]-1; } n = n_c->array; size_a = vec_size( n_a ); size_b = vec_size( n_b ); size_c = vec_size( n_c ); /*Initialisieren des Ergebnis Array*/ c = (fepc_real_t*) malloc(sizeof(fepc_real_t) * size_c); /*Berechnen der Fouriertrafo von in_a*/ in_a = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); out_a = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); for (k=0;k<size_c;k++) { temp = entry_one2d(k,n_c); test = 0; for(i=0;i<dim;i++) { if ((temp->array[i] <0)||(temp->array[i]>=n_a->array[i])) { test = test + 1; } } if (test == 0) { wert = entry_d2one(temp,n_a); in_a[k][0] = a[wert]; in_a[k][1] = 0; } else { in_a[k][0] = 0; in_a[k][1] = 0; } vec_del(temp); } p = fftw_plan_dft(dim,n,in_a,out_a,FFTW_FORWARD,FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); /*Berechnen der Fouriertrafo von in_b*/ in_b = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); out_b = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); for (k=0;k<size_c;k++) { temp = entry_one2d(k,n_c); test = 0; for(i=0;i<dim;i++) { if ((temp->array[i] <0)||(temp->array[i]>=n_b->array[i])) { test = test + 1; } } if (test == 0) { wert = entry_d2one(temp,n_b); in_b[k][0] = b[wert]; in_b[k][1] = 0; } else { in_b[k][0] = 0; in_b[k][1] = 0; } vec_del(temp); } p = fftw_plan_dft(dim,n,in_b,out_b,FFTW_FORWARD,FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size_c); for (k=0;k<size_c;k++) { in[k][0] = out_a[k][0]*out_b[k][0] - out_a[k][1]*out_b[k][1]; in[k][1] = out_a[k][1]*out_b[k][0] + out_a[k][0]*out_b[k][1]; } /*Berechnung der Inversen Fouriertrafo von in*/ p = fftw_plan_dft(dim,n,in,out,FFTW_BACKWARD,FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); for (k=0;k<size_c;k++) { c[k] = (fepc_real_t) out[k][0]/size_c; } vec_del(n_c); fftw_free(in); fftw_free(in_a); fftw_free(in_b); fftw_free(out); fftw_free(out_a); fftw_free(out_b); return c; #else printf( "\n (fft_faltung) FEHLER : keine FFT Bibliothek verfuegbar\n" ); exit( 1 ); #endif }