예제 #1
0
int
gmx_fft_init_2d(gmx_fft_t *        pfft,
                int                nx, 
                int                ny,
                enum gmx_fft_flag  flags) 
{
    int i,j;
    gmx_fft_t             fft;
    int                    fftw_flags;

    
    /* FFTW2 is slow to measure, so we do not use it */
    /* If you change this, add an #ifndef for GMX_DISABLE_FFTW_MEASURE around it! */
    fftw_flags = FFTW_ESTIMATE;    

    if(pfft==NULL)
    {
        gmx_fatal(FARGS,"Invalid opaque FFT datatype pointer.");
        return EINVAL;
    }
    *pfft = NULL;

    if( (fft = (gmx_fft_t)malloc(sizeof(struct gmx_fft))) == NULL)
    {
        return ENOMEM;
    }    
 
    fft->single[0][0] = NULL;
    fft->single[0][1] = NULL;
    fft->single[1][0] = NULL;
    fft->single[1][1] = NULL;
        
    fft->multi[0][0] = fftw2d_create_plan(nx,ny,FFTW_BACKWARD,FFTW_OUT_OF_PLACE|fftw_flags);
    fft->multi[0][1] = fftw2d_create_plan(nx,ny,FFTW_FORWARD,FFTW_OUT_OF_PLACE|fftw_flags);
    fft->multi[1][0] = fftw2d_create_plan(nx,ny,FFTW_BACKWARD,FFTW_IN_PLACE|fftw_flags);
    fft->multi[1][1] = fftw2d_create_plan(nx,ny,FFTW_FORWARD,FFTW_IN_PLACE|fftw_flags);
    
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            if(fft->multi[i][j] == NULL)
            {
                gmx_fatal(FARGS,"Error initializing FFTW2 plan.");
                gmx_fft_destroy(fft);
                return -1;
            }        
        }
    }

    /* No workspace needed for complex-to-complex FFTs */
    fft->work = NULL;
    
    fft->ndim = 2;
    fft->nx   = nx;
    fft->ny   = ny;

    *pfft = fft;
    return 0;
}
예제 #2
0
//-----------------------------------------------------------------------
int fdct_wrapping_wavelet(CpxOffMat& Xhgh, vector<CpxNumMat>& csc)
{
  int N1 = Xhgh.m();  int N2 = Xhgh.n();
  int F1 = -Xhgh.s();  int F2 = -Xhgh.t();
  CpxNumMat T(N1, N2);
  fdct_wrapping_ifftshift(Xhgh, T);
    fftwnd_plan p ;
#pragma omp critical
  {
    p = fftw2d_create_plan(N2, N1, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
  }
  fftwnd_one(p, (fftw_complex*)T.data(), NULL);
  #pragma omp critical
  {
  fftwnd_destroy_plan(p);
  }
  double sqrtprod = sqrt(double(N1*N2));
  for(int j=0; j<N2; j++)
	 for(int i=0; i<N1; i++)
		T(i,j) /= sqrtprod;
  
  csc[0] = T;  //csc[0].resize(N1, N2);  //fdct_wrapping_fftshift(T, csc[0]);
  
  return 0;
}
예제 #3
0
void F77_FUNC_(fftw2d_f77_create_plan,FFTW2D_F77_CREATE_PLAN)
(fftwnd_plan *p, int *nx, int *ny, int *idir, int *flags)
{
     fftw_direction dir = *idir < 0 ? FFTW_FORWARD : FFTW_BACKWARD;

     *p = fftw2d_create_plan(*ny,*nx,dir,*flags);
}
예제 #4
0
int F77_FUNC_ (create_plan_2d, CREATE_PLAN_2D)
   (fftwnd_plan *p, int *n, int *m, int *idir)
{
   fftw_direction dir = ( (*idir < 0) ? FFTW_FORWARD : FFTW_BACKWARD );
   *p = fftw2d_create_plan(*m, *n, dir, FFTW_ESTIMATE | FFTW_IN_PLACE);
   if( *p == NULL ) fprintf(stderr," *** CREATE_PLAN_2D: warning empty plan ***\n");
/*   printf(" pointer size = %d, value = %d\n", sizeof ( *p ), *p ); */
   return 0;
}
예제 #5
0
void CMainFrame::Fft_back(Complex *array) {
	int m_iDem = m_iDem_ampl;
	fftw_complex *in = new fftw_complex[m_iDem * m_iDem];
	size_t dxdy = m_iDem * m_iDem;
	
	for(size_t i = 0; i < dxdy; i++) {
		in[i].re = array[i].re;
		in[i].im = array[i].im;
	}

	fftwnd_plan p = fftw2d_create_plan(m_iDem, m_iDem, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
	fftwnd_one(p, in, NULL);
	fftwnd_destroy_plan(p);
	
	for(size_t i = 0; i < dxdy; i++) {
		array[i].re = (float) in[i].re;
		array[i].im = (float) in[i].im;
	}
	delete[] in;
}
//---------------------
int fdct_wrapping_invwavelet(vector<CpxNumMat>& csc, CpxOffMat& Xhgh)
{
  assert(csc.size()==1);
  CpxNumMat& C = csc[0];
  int N1 = C.m();  int N2 = C.n();
  
  CpxNumMat T(C);  //CpxNumMat T(N1, N2);  fdct_wrapping_ifftshift(N1, N2, F1, F2, C, T);
  
  fftwnd_plan p = fftw2d_create_plan(N2, N1, FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
  fftwnd_one(p, (fftw_complex*)T.data(), NULL);
  fftwnd_destroy_plan(p);
  double sqrtprod = sqrt(double(N1*N2));
  for(int j=0; j<N2; j++)
	 for(int i=0; i<N1; i++)
		T(i,j) /= sqrtprod;
  
  Xhgh.resize(N1, N2);
  fdct_wrapping_fftshift(T, Xhgh);
  return 0;
}
예제 #7
0
파일: im_fft.cpp 프로젝트: Vulcanior/IUP
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;
  }
}
예제 #8
0
/* Call fftw for a 1 band complex image.
 */
static int 
cfwfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	fftwnd_plan plan;
	double *buf, *q, *p;
	int x, y;

	IMAGE *cmplx = im_open_local( dummy, "fwfft1:1", "t" );

	/* Make dp complex image.
	 */
	if( !cmplx || im_pincheck( in ) || im_outcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_fwfft", _( "one band uncoded only" ) );
                return( -1 );
	}
	if( im_clip2dcm( in, cmplx ) )
                return( -1 );

	/* Make the plan for the transform.
	 */
	if( !(plan = fftw2d_create_plan( in->Ysize, in->Xsize,
		FFTW_FORWARD, 
		FFTW_MEASURE | FFTW_USE_WISDOM | FFTW_IN_PLACE )) ) {
                im_error( "im_fwfft", _( "unable to create transform plan" ) );
		return( -1 );
	}

	fftwnd_one( plan, (fftw_complex *) cmplx->data, NULL );

	fftwnd_destroy_plan( plan );

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->Bbits = IM_BBITS_DPCOMPLEX;
	out->BandFmt = IM_BANDFMT_DPCOMPLEX;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (double *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Copy to out, normalise.
	 */
	for( p = (double *) cmplx->data, y = 0; y < out->Ysize; y++ ) {
		int size = out->Xsize * out->Ysize;

		q = buf;

		for( x = 0; x < out->Xsize; x++ ) {
			q[0] = p[0] / size;
			q[1] = p[1] / size;
			p += 2;
			q += 2;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
예제 #9
0
파일: fftw_test.c 프로젝트: Pinkii-/PCA
void testnd_in_place(int rank, int *n, fftw_direction dir,
		     fftwnd_plan validated_plan,
		     int alternate_api, int specific, int force_buffered)
{
     int istride;
     int N, dim, i;
     fftw_complex *in1, *in2, *out2;
     fftwnd_plan p;
     int flags = measure_flag | wisdom_flag | FFTW_IN_PLACE;

     if (coinflip())
	  flags |= FFTW_THREADSAFE;

     if (force_buffered)
	  flags |= FFTWND_FORCE_BUFFERED;

     N = 1;
     for (dim = 0; dim < rank; ++dim)
	  N *= n[dim];

     in1 = (fftw_complex *) fftw_malloc(N * MAX_STRIDE * sizeof(fftw_complex));
     in2 = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));
     out2 = (fftw_complex *) fftw_malloc(N * sizeof(fftw_complex));

     if (!specific) {
	  if (alternate_api && (rank == 2 || rank == 3)) {
	       if (rank == 2)
		    p = fftw2d_create_plan(n[0], n[1], dir, flags);
	       else
		    p = fftw3d_create_plan(n[0], n[1], n[2], dir, flags);
	  } else		/* standard api */
	       p = fftwnd_create_plan(rank, n, dir, flags);
     } else {			/* specific plan creation */
	  if (alternate_api && (rank == 2 || rank == 3)) {
	       if (rank == 2)
		    p = fftw2d_create_plan_specific(n[0], n[1], dir, flags,
						    in1, 1,
					       (fftw_complex *) NULL, 1);
	       else
		    p = fftw3d_create_plan_specific(n[0], n[1], n[2], dir, flags,
						    in1, 1,
					       (fftw_complex *) NULL, 1);
	  } else		/* standard api */
	       p = fftwnd_create_plan_specific(rank, n, dir, flags,
					       in1, 1,
					       (fftw_complex *) NULL, 1);

     }

     for (istride = 1; istride <= MAX_STRIDE; ++istride) {
	  /* 
	   * generate random inputs */
	  for (i = 0; i < N; ++i) {
	       int j;
	       c_re(in2[i]) = DRAND();
	       c_im(in2[i]) = DRAND();
	       for (j = 0; j < istride; ++j) {
		    c_re(in1[i * istride + j]) = c_re(in2[i]);
		    c_im(in1[i * istride + j]) = c_im(in2[i]);
	       }
	  }

	  if (istride != 1 || istride != 1 || coinflip())
	       fftwnd(p, istride, in1, istride, 1, (fftw_complex *) NULL, 1, 1);
	  else
	       fftwnd_one(p, in1, NULL);

	  fftwnd(validated_plan, 1, in2, 1, 1, out2, 1, 1);

	  for (i = 0; i < istride; ++i)
	       CHECK(compute_error_complex(in1 + i, istride, out2, 1, N) < TOLERANCE,
		     "testnd_in_place: wrong answer");
     }

     fftwnd_destroy_plan(p);

     fftw_free(out2);
     fftw_free(in2);
     fftw_free(in1);
}
예제 #10
0
//-------------------------------------------------------------------
int fdct_wrapping(int N1, int N2, int nbscales, int nbangles_coarse, int allcurvelets, CpxNumMat& x, vector< vector<CpxNumMat> >& c)
{
  //---------------------------------------------
  assert(N1==x.m() && N2==x.n());
  
  int F1 = N1/2;  int F2 = N2/2;
  // ifft original data
  CpxNumMat T(x);
  fftwnd_plan p = fftw2d_create_plan(N2, N1, FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
  fftwnd_one(p, (fftw_complex*)T.data(), NULL);
  fftwnd_destroy_plan(p);
  double sqrtprod = sqrt(double(N1*N2));
  for(int j=0; j<N2; j++)	 for(int i=0; i<N1; i++)		T(i,j) /= sqrtprod;
  CpxOffMat O(N1, N2);
  fdct_wrapping_fftshift(T, O);
  
  //-----------------------------------------------------------------------------
  vector<CpxOffMat> Xhghs;
  Xhghs.resize(nbscales);
  CpxOffMat X;
  //unfold or not
  if(allcurvelets==1) {
	 //--------------------------
	 double XL1 = 4.0*N1/3.0;  double XL2 = 4.0*N2/3.0; //range
	 int XS1, XS2;  int XF1, XF2;  double XR1, XR2;  fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
	 IntOffVec t1(XS1);
	 for(int i=-XF1; i<-XF1+XS1; i++)		if(     i<-N1/2) t1(i) = i+int(N1);		else if(i>(N1-1)/2) t1(i) = i-int(N1);		else t1(i) = i;
	 IntOffVec t2(XS2);
	 for(int i=-XF2; i<-XF2+XS2; i++)		if(     i<-N2/2) t2(i) = i+int(N2);		else if(i>(N2-1)/2) t2(i) = i-int(N2);		else t2(i) = i;
	 X.resize(XS1, XS2);
	 for(int j=-XF2; j<-XF2+XS2; j++)
		for(int i=-XF1; i<-XF1+XS1; i++)
		  X(i,j) = O(t1(i), t2(j));
	 DblOffMat lowpass(XS1,XS2);
	 fdct_wrapping_lowpasscompute(XL1, XL2, lowpass); //compute the low pass filter
	 for(int j=-XF2; j<-XF2+XS2; j++)
		for(int i=-XF1; i<-XF1+XS1; i++)
		  X(i,j) *= lowpass(i,j);
  } else {
	 //--------------------------
	 X = O;
  }
  //separate
  double XL1 = 4.0*N1/3.0;  double XL2 = 4.0*N2/3.0; //range
  for(int sc=nbscales-1; sc>0; sc--) {
	 double XL1n = XL1/2;	 double XL2n = XL2/2;
	 int XS1n, XS2n;  int XF1n, XF2n;  double XR1n, XR2n;
	 fdct_wrapping_rangecompute(XL1n, XL2n, XS1n, XS2n, XF1n, XF2n, XR1n, XR2n);
	 //computer filter
	 DblOffMat lowpass(XS1n, XS2n);
	 fdct_wrapping_lowpasscompute(XL1n, XL2n, lowpass);
	 DblOffMat hghpass(XS1n, XS2n);
	 for(int j=-XF2n; j<-XF2n+XS2n; j++)
		for(int i=-XF1n; i<-XF1n+XS1n; i++)
		  hghpass(i,j) = sqrt(1-lowpass(i,j)*lowpass(i,j));
	 //separate
	 CpxOffMat Xhgh(X);
	 for(int j=-XF2n; j<-XF2n+XS2n; j++)
		for(int i=-XF1n; i<-XF1n+XS1n; i++)
		  Xhgh(i,j) *= hghpass(i,j);
	 CpxOffMat Xlow(XS1n, XS2n);
	 for(int j=-XF2n; j<-XF2n+XS2n; j++)
		for(int i=-XF1n; i<-XF1n+XS1n; i++)
		  Xlow(i,j) = X(i,j) * lowpass(i,j);
	 //store and prepare for next level
	 Xhghs[sc] = Xhgh;
	 X = Xlow;
	 XL1 = XL1/2;	 XL2 = XL2/2;
  }
  Xhghs[0] = X;
  
  //-----------------------------------------------------------------------------
  vector<int> nbangles(nbscales);
  if(allcurvelets==1) {
	 //nbangles
	 nbangles[0] = 1;
	 for(int sc=1; sc<nbscales; sc++)		nbangles[sc] = nbangles_coarse * pow2( int(ceil(double(sc-1)/2)) );
	 //c
	 c.resize(nbscales);
	 for(int sc=0; sc<nbscales; sc++)		c[sc].resize( nbangles[sc] );
	 
	 double XL1 = 4.0*N1/3.0;  double XL2 = 4.0*N2/3.0; //range
	 for(int sc=nbscales-1; sc>0; sc--) {
		fdct_wrapping_sepangle(XL1, XL2, nbangles[sc], Xhghs[sc], c[sc]);
		XL1 /= 2;		XL2 /= 2;
	 }
	 fdct_wrapping_wavelet(Xhghs[0], c[0]);
  } else {
	 //nbangles
	 nbangles[0] = 1;
	 for(int sc=1; sc<nbscales-1; sc++)		nbangles[sc] = nbangles_coarse * pow2( int(ceil(double(sc-1)/2)) );
	 nbangles[nbscales-1] = 1;
	 //c
	 c.resize(nbscales);
	 for(int sc=0; sc<nbscales; sc++)		c[sc].resize( nbangles[sc] );
	 
	 fdct_wrapping_wavelet(Xhghs[nbscales-1], c[nbscales-1]);
	 double XL1 = 2.0*N1/3.0;  double XL2 = 2.0*N2/3.0; //range
	 for(int sc=nbscales-2; sc>0; sc--) {
		fdct_wrapping_sepangle(XL1, XL2, nbangles[sc], Xhghs[sc], c[sc]);
		XL1 /= 2;		XL2 /= 2;
	 }
	 fdct_wrapping_wavelet(Xhghs[0], c[0]);
  }
  
  return 0;
}
예제 #11
0
//-----------------------------------------------------------------------
int fdct_wrapping_sepangle(double XL1, double XL2, int nbangle, CpxOffMat& Xhgh, vector<CpxNumMat>& csc)
{
  //WEDGE ORDERING: from -45 degree, counter-clockwise
  typedef pair<int,int> intpair;
  map<intpair, fftwnd_plan> planmap;
  
  int nbquadrants = 4;
  int nd = nbangle / 4;
  int wcnt = 0;
  
  //backup
  CpxOffMat Xhghb(Xhgh);
  double XL1b = XL1;  double XL2b = XL2;
  
  int qvec[] = {2,1,0,3};
  for(int qi=0; qi<nbquadrants; qi++) {
	 int q = qvec[qi];
	 //ROTATE data to its right position
	 fdct_wrapping_rotate_forward(q, XL1b, XL2b, XL1, XL2);	 XL1 = abs(XL1);	 XL2 = abs(XL2);
	 fdct_wrapping_rotate_forward(q, Xhghb, Xhgh);
	 //figure out XS, XF, XR
	 double XW1 = XL1/nd;	 double XW2 = XL2/nd;
	 int XS1, XS2;  int XF1, XF2;  double XR1, XR2;  fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
	 for(int w=nd-1; w>=0; w--) {
		double xs = XR1/4 - (XW1/2)/4;
		double xe = XR1;
		double ys = -XR2 + (w-0.5)*XW2;
		double ye = -XR2 + (w+1.5)*XW2; //x range
		int xn = int(ceil(xe-xs));			 int yn = int(ceil(ye-ys));
		//MAKE THEM ODD
		if(xn%2==0) xn++;		if(yn%2==0) yn++;
		int xf = int(ceil(xs));			 //int yf = int(ceil(ys));
		//theta
		double thts, thtm, thte; //y direction
		if(w==0) {
		  thts = atan2(-1.0, 1.0-1.0/nd);
		  thtm = atan2(-1.0+1.0/nd, 1.0);
		  thte = atan2(-1.0+3.0/nd, 1.0);
		} else if(w==nd-1) {
		  thts = atan2(-1.0+(2.0*w-1.0)/nd, 1.0);
		  thtm = atan2(-1.0+(2.0*w+1.0)/nd, 1.0);
		  thte = atan2(1.0, 1.0-1.0/nd);
		} else {
		  thts = atan2(-1.0+(2.0*w-1.0)/nd, 1.0);
		  thtm = atan2(-1.0+(2.0*w+1.0)/nd, 1.0);
		  thte = atan2(-1.0+(2.0*w+3.0)/nd, 1.0);
		}
		//wrapping
		int xh = xn/2;		int yh = yn/2; //half length
		double R21 = XR2/XR1; //ratio
		CpxOffMat wpdata(xn,yn);
		for(int xcur=xf; xcur<xe; xcur++) { //for each layer
		  int yfm = (int)ceil( max(-XR2, R21*xcur*tan(thts)) );
		  int yto = (int)floor( min(XR2, R21*xcur*tan(thte)) );
		  for(int ycur=yfm; ycur<=yto; ycur++) {
			 int tmpx = xcur%xn;				  if(tmpx<-xh) tmpx+=xn;				  if(tmpx>=-xh+xn) tmpx-=xn;
			 int tmpy = ycur%yn;				  if(tmpy<-yh) tmpy+=yn;				  if(tmpy>=-yh+yn) tmpy-=yn;
			 wpdata(tmpx,tmpy) = Xhgh(xcur,ycur);
			 //partition of unity
			 double thtcur = atan2(ycur/XR2, xcur/XR1);
			 double wtht;
			 if(thtcur<thtm) {
				double l,r; fdct_wrapping_window((thtcur-thts)/(thtm-thts), l, r);
				wtht = l;
			 } else {
				double l,r; fdct_wrapping_window((thtcur-thtm)/(thte-thtm), l, r);
				wtht = r;
			 }
			 double pou = wtht;
			 wpdata(tmpx,tmpy) *= pou;
		  }
		}
		//IFFT
		{
		  //rotate backward
		  CpxOffMat rpdata;
		  fdct_wrapping_rotate_backward(q, wpdata, rpdata);
		  //ifftshift
		  int xn = rpdata.m();		int yn = rpdata.n(); //reset xn, yn
		  CpxNumMat tpdata(xn,yn);
		  fdct_wrapping_ifftshift(rpdata, tpdata);
		  //ifft
		  fftwnd_plan p = NULL;
		  map<intpair,fftwnd_plan>::iterator mit=planmap.find( intpair(xn,yn) );
		  if(mit!=planmap.end()) {
			 p = (*mit).second;
		  } else {
			 p = fftw2d_create_plan(yn, xn, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
			 planmap[ intpair(xn, yn) ] = p;
		  }
		  fftwnd_one(p, (fftw_complex*)tpdata.data(), NULL);
		  double sqrtprod = sqrt(double(xn*yn));
		  for(int j=0; j<yn; j++)		  for(int i=0; i<xn; i++)			 tpdata(i,j) /= sqrtprod;
		  //store
		  csc[wcnt] = tpdata;
		}
		
		//fdct_wrapping_fftshift(xn,yn,xh,yh,tpdata,wpdata);
		//ROTATION
		//fdct_wrapping_rotate_backward(q, wpdata, csc[wcnt]);
		
		wcnt++;
	 } //end of w loop
  } //end of q loop
  //PUT THE RIGHT DATA BACK
  Xhgh = Xhghb;
  XL1 = XL1b;  XL2 = XL2b;
  
  for(map<intpair, fftwnd_plan>::iterator mit=planmap.begin(); mit!=planmap.end(); mit++) {
	 fftwnd_plan p = (*mit).second;
	 fftwnd_destroy_plan(p);
  }
  return 0;
}
예제 #12
0
static void  TRAN_FFT_Electrode_Grid(MPI_Comm comm1, int isign)
     /* #define grid_e_ref(i,j,k) ( (i)*Ngrid2*(l3[1]-l3[0]+1)+ (j)*(l3[1]-l3[0]+1) + (k)-l3[0] ) 
      *#define fft2d_ref(i,j)  ( (i)*Ngrid2+(j) ) 
      */
{

  int side;
  int i,j,k;
  int l1[2];

#ifdef fftw2
  fftwnd_plan p;
#else
  fftw_plan p;
#endif
  fftw_complex *in,*out;

  double factor;
  int myid;

  MPI_Comm_rank(comm1,&myid);

  if (print_stdout){
    printf("TRAN_FFT_Electrode_Grid in\n");
  }

  /* allocation 
   *   ElectrodedVHart_Grid_c is a global variable 
   *  do not free these 
   */
  l1[0]= 0;
  l1[1]= TRAN_grid_bound[0];
  ElectrodedVHart_Grid_c[0]=(dcomplex*)malloc(sizeof(dcomplex)*Ngrid3*Ngrid2*(l1[1]-l1[0]+1) );
  /* ElectrodedVHart_Grid_c = Vh_electrode(kx,ky, z=[0:TRAN_grid_bound[0]]), TRAN_grid_bound: integer */

  l1[0]= TRAN_grid_bound[1];
  l1[1]= Ngrid1-1;
  ElectrodedVHart_Grid_c[1]=(dcomplex*)malloc(sizeof(dcomplex)*Ngrid3*Ngrid2*(l1[1]-l1[0]+1) ); 
  /* ElectrodedVHart_Grid_c = Vh_electrode(kx,ky, z=[TRAN_grid_bound[1]:Ngrid3-1]), TRAN_grid_bound: integer */


  /* allocation for fft ,
   *  free these at last 
   */

#ifdef fftw2
  in  = (fftw_complex*)malloc(sizeof(fftw_complex)*Ngrid3*Ngrid2);
  out = (fftw_complex*)malloc(sizeof(fftw_complex)*Ngrid3*Ngrid2);
#else
  in  = fftw_malloc(sizeof(fftw_complex)*Ngrid3*Ngrid2); 
  out = fftw_malloc(sizeof(fftw_complex)*Ngrid3*Ngrid2); 
#endif
 

#ifdef fftw2
  p=fftw2d_create_plan(Ngrid2,Ngrid3,isign,FFTW_ESTIMATE);
#else
  p=fftw_plan_dft_2d(Ngrid2,Ngrid3,in,out,isign,FFTW_ESTIMATE);
#endif


  /* left side */

  side=0;
  l1[0]= 0;
  l1[1]= TRAN_grid_bound[0];
  factor = 1.0/( (double)(Ngrid2*Ngrid3) ) ;

#define grid_e_ref(i,j,k) ( ( (i)-l1[0])*Ngrid2*Ngrid3+(j)*Ngrid3+(k) )
#define fft2d_ref(j,k)  ( (j)*Ngrid3+ (k) )

  for (i=l1[0];i<=l1[1];i++) {
    for (j=0;j<Ngrid2;j++){
      for (k=0;k<Ngrid3;k++) {

#ifdef fftw2
	c_re(in[fft2d_ref(j,k)]) = ElectrodedVHart_Grid[side][grid_e_ref(i,j,k)]; 
	c_im(in[fft2d_ref(j,k)]) = 0.0;
#else
	in[fft2d_ref(j,k)][0]= ElectrodedVHart_Grid[side][grid_e_ref(i,j,k)]; 
	in[fft2d_ref(j,k)][1]= 0.0;
#endif

      }
    }

#ifdef fftw2
    fftwnd_one(p, in, out);
#else
    fftw_execute(p);
#endif

    for (j=0;j<Ngrid2;j++) {
      for (k=0;k<Ngrid3;k++) {

#ifdef fftw2
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].r = c_re(out[fft2d_ref(j,k)])*factor;
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].i = c_im(out[fft2d_ref(j,k)])*factor;
#else
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].r = out[fft2d_ref(j,k)][0]*factor;
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].i = out[fft2d_ref(j,k)][1]*factor;
#endif

      }
    }
  } /* k */

#ifdef DEBUG
  /*debug*/
  { char name[100];int i; double R[4]; for(i=1;i<=3;i++) R[i]=0.0; 
  sprintf(name,"ElectrodedVHart_Grid_c_lr.%d",myid);
  TRAN_Print_Grid_c(name,"ElectrodedVHart_Grid_c_li",
		    Grid_Origin, gtv, l1[1]-l1[0]+1,Ngrid2, 0, Ngrid3-1, R, ElectrodedVHart_Grid_c[side]);
  }
#endif


  /* right side */

  side=1;
  l1[0]= TRAN_grid_bound[1];
  l1[1]= Ngrid1-1;
  factor = 1.0/( (double) Ngrid2*Ngrid3 );

  for (i=l1[0];i<=l1[1];i++) {
    for (j=0;j<Ngrid2;j++) {
      for (k=0;k<Ngrid3;k++) {

#ifdef fftw2
	c_re(in[fft2d_ref(j,k)]) = ElectrodedVHart_Grid[side][grid_e_ref(i,j,k)];
        c_im(in[fft2d_ref(j,k)]) = 0.0;
#else
	in[fft2d_ref(j,k)][0]= ElectrodedVHart_Grid[side][grid_e_ref(i,j,k)];
        in[fft2d_ref(j,k)][1]= 0.0;
#endif

      }
    }

#ifdef fftw2
    fftwnd_one(p, in, out);
#else
    fftw_execute(p);
#endif

    for (j=0;j<Ngrid2;j++) {
      for (k=0;k<Ngrid3;k++) {

#ifdef fftw2
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].r = c_re(out[fft2d_ref(j,k)])*factor;
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].i = c_im(out[fft2d_ref(j,k)])*factor;
#else
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].r = out[fft2d_ref(j,k)][0]*factor;
        ElectrodedVHart_Grid_c[side][grid_e_ref(i,j,k)].i = out[fft2d_ref(j,k)][1]*factor;
#endif

      }
    }
  } /* k */

#ifdef DEBUG 
  /*debug*/
  { char name[100];int i; double R[4]; for(i=1;i<=3;i++) R[i]=0.0; 
  sprintf(name,"ElectrodedVHart_Grid_c_rr.%d",myid);
  TRAN_Print_Grid_c(name,"ElectrodedVHart_Grid_c_ri",
		    Grid_Origin, gtv,l1[1]-l1[0]+1,Ngrid2, 0, Ngrid3-1, R, ElectrodedVHart_Grid_c[side]);
  }
#endif


#ifdef fftw2
  fftwnd_destroy_plan(p);
#else
  fftw_destroy_plan(p);
#endif



#ifdef fftw2
  free(out);
  free(in);
#else
  fftw_free(out);
  fftw_free(in);
#endif

  if (print_stdout){
    printf("TRAN_FFT_Electrode_Grid out\n");
  }
}
//-------------------------------------------------------------------------------
int ifdct_wrapping(int N1, int N2, int nbscales, int nbangles_coarse, int allcurvelets, vector< vector<CpxNumMat> >& c, CpxNumMat& x)
{
  assert(nbscales==c.size() && nbangles_coarse==c[1].size());
  
  //int F1 = N1/2;  int F2 = N2/2;
  //-------------------------------------------angles to Xhgh
  vector<int> nbangles(nbscales);
  vector<CpxOffMat> Xhghs;  Xhghs.resize(nbscales);
  
  if(allcurvelets==1) {
	 //----
	 nbangles[0] = 1;
	 for(int sc=1; sc<nbscales; sc++)		nbangles[sc] = nbangles_coarse * pow2( int(ceil(double(sc-1)/2)) );
	 
	 double XL1 = 4.0*N1/3.0;  double XL2 = 4.0*N2/3.0;
	 for(int sc=nbscales-1; sc>0; sc--) {
		fdct_wrapping_invsepangle(XL1, XL2, nbangles[sc], c[sc], Xhghs[sc]);
		XL1 /= 2;		XL2 /= 2;
	 }
	 fdct_wrapping_invwavelet(c[0], Xhghs[0]);
  } else {
	 //----
	 nbangles[0] = 1;
	 for(int sc=1; sc<nbscales-1; sc++)		nbangles[sc] = nbangles_coarse * pow2( int(ceil(double(sc-1)/2)) );
	 nbangles[nbscales-1] = 1;
	 
	 fdct_wrapping_invwavelet(c[nbscales-1], Xhghs[nbscales-1]);
	 double XL1 = 2.0*N1/3.0;	 double XL2 = 2.0*N2/3.0;
	 for(int sc=nbscales-2; sc>0; sc--) {
		fdct_wrapping_invsepangle(XL1, XL2, nbangles[sc], c[sc], Xhghs[sc]);
		XL1 /= 2;		XL2 /= 2;
	 }
	 fdct_wrapping_invwavelet(c[0], Xhghs[0]);
  }
  
  //-------------------------------------------xhghs to O
  //combine
  CpxOffMat X;
  if(allcurvelets==1) {
	 double XL1 = 4.0*N1/3.0;  double XL2 = 4.0*N2/3.0; //range
	 int XS1, XS2;  int XF1, XF2;  double XR1, XR2;	 fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
	 X.resize(XS1, XS2);
  } else {
	 X.resize(N1, N2);
  }
  double XL1 = 4.0*N1/3.0;  double XL2 = 4.0*N2/3.0;
  int XS1, XS2;  int XF1, XF2;  double XR1, XR2;  fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
  for(int sc=nbscales-1; sc>0; sc--) {
	 double XL1n = XL1/2;	 double XL2n = XL2/2;
	 int XS1n, XS2n;	 int XF1n, XF2n;	 double XR1n, XR2n;
	 fdct_wrapping_rangecompute(XL1n, XL2n, XS1n, XS2n, XF1n, XF2n, XR1n, XR2n);
	 
	 DblOffMat lowpass(XS1n, XS2n);
	 fdct_wrapping_lowpasscompute(XL1n, XL2n, lowpass);
	 DblOffMat hghpass(XS1n, XS2n);
	 for(int j=-XF2n; j<-XF2n+XS2n; j++)
		for(int i=-XF1n; i<-XF1n+XS1n; i++)
		hghpass(i,j) = sqrt(1-lowpass(i,j)*lowpass(i,j));
	 for(int j=-XF2n; j<-XF2n+XS2n; j++)
		for(int i=-XF1n; i<-XF1n+XS1n; i++)
		  Xhghs[sc](i,j) *= hghpass(i,j);
	 for(int j=-XF2n; j<-XF2n+XS2n; j++)
		for(int i=-XF1n; i<-XF1n+XS1n; i++)
		  Xhghs[sc-1](i,j) *= lowpass(i,j);
	 CpxOffMat& G = Xhghs[sc];
	 for(int j=G.t(); j<G.t()+G.n(); j++)
		for(int i=G.s(); i<G.s()+G.m(); i++)
		  X(i,j) += G(i,j);
	 XL1 = XL1/2;	 XL2 = XL2/2;
	 fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
  }
  for(int j=-XF2; j<-XF2+XS2; j++)
	 for(int i=-XF1; i<-XF1+XS1; i++)
		X(i,j) += Xhghs[0](i,j);
  // fold
  CpxOffMat O(N1, N2);
  if(allcurvelets==1) {
	 double XL1 = 4.0*N1/3.0;  double XL2 = 4.0*N2/3.0;
	 int XS1, XS2;  int XF1, XF2;  double XR1, XR2;  fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
	 //times pou;
	 DblOffMat lowpass(XS1,XS2);
	 fdct_wrapping_lowpasscompute(XL1, XL2, lowpass);
	 for(int j=-XF2; j<-XF2+XS2; j++)
		for(int i=-XF1; i<-XF1+XS1; i++)
		  X(i,j) *= lowpass(i,j);
	 IntOffVec t1(XS1);
	 for(int i=-XF1; i<-XF1+XS1; i++)		if(     i<-N1/2) t1(i) = i+int(N1);		else if(i>(N1-1)/2) t1(i) = i-int(N1);		else t1(i) = i;
	 IntOffVec t2(XS2);
	 for(int i=-XF2; i<-XF2+XS2; i++)		if(     i<-N2/2) t2(i) = i+int(N2);		else if(i>(N2-1)/2) t2(i) = i-int(N2);		else t2(i) = i;
	 for(int j=-XF2; j<-XF2+XS2; j++)
		for(int i=-XF1; i<-XF1+XS1; i++)
		  O(t1(i), t2(j)) += X(i,j);
  } else {
	 O = X;
  }
  //------------------------------------------------------------
  CpxNumMat T(N1,N2);
  fdct_wrapping_ifftshift(O, T);
  fftwnd_plan p = fftw2d_create_plan(N2, N1, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
  fftwnd_one(p, (fftw_complex*)T.data(), NULL);
  fftwnd_destroy_plan(p);
  double sqrtprod = sqrt(double(N1*N2)); //scale
  for(int i=0; i<N1; i++)	 for(int j=0; j<N2; j++)	 T(i,j) /= sqrtprod;

  x = T;
  //x.resize(N1, N2);
  //fdct_wrapping_fftshift(T, x);
  
  return 0; 
}