示例#1
0
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);
    }
}
示例#2
0
文件: fft.cpp 项目: kd0kfo/libdnstd
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;
}
示例#3
0
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;
}
示例#4
0
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() */
示例#5
0
// 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);
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
      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;
      }
示例#9
0
/*
	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;
}
示例#11
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 );

}
示例#12
0
/*------------------------------------------------------------------
- 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;
}
示例#13
0
文件: fastsum.c 项目: poulson/nfft
/** 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));
  }
}
示例#14
0
/*******************************************************
 *
 * 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
}