Beispiel #1
0
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
}
Beispiel #2
0
/** Comparison of the FFTW, mpolar FFT, and inverse mpolar FFT */
static int comparison_fft(FILE *fp, int N, int T, int R)
{
  ticks t0, t1;
  fftw_plan my_fftw_plan;
  fftw_complex *f_hat,*f;
  int m,k;
  double t_fft, t_dft_mpolar;

  f_hat = (fftw_complex *)nfft_malloc(sizeof(fftw_complex)*N*N);
  f     = (fftw_complex *)nfft_malloc(sizeof(fftw_complex)*(T*R/4)*5);

  my_fftw_plan = fftw_plan_dft_2d(N,N,f_hat,f,FFTW_BACKWARD,FFTW_MEASURE);

  for(k=0; k<N*N; k++)
    f_hat[k] = (((double)rand())/RAND_MAX) + _Complex_I* (((double)rand())/RAND_MAX);

  t0 = getticks();
  for(m=0;m<65536/N;m++)
    {
      fftw_execute(my_fftw_plan);
      /* touch */
      f_hat[2]=2*f_hat[0];
    }
  t1 = getticks();
  GLOBAL_elapsed_time = nfft_elapsed_seconds(t1,t0);
  t_fft=N*GLOBAL_elapsed_time/65536;

  if(N<256)
    {
      mpolar_dft(f_hat,N,f,T,R,1);
      t_dft_mpolar=GLOBAL_elapsed_time;
    }

  for (m=3; m<=9; m+=3)
    {
      if((m==3)&&(N<256))
        fprintf(fp,"%d\t&\t&\t%1.1e&\t%1.1e&\t%d\t",N,t_fft,t_dft_mpolar,m);
      else
        if(m==3)
	  fprintf(fp,"%d\t&\t&\t%1.1e&\t       &\t%d\t",N,t_fft,m);
	else
	  fprintf(fp,"  \t&\t&\t       &\t       &\t%d\t",m);

      printf("N=%d\tt_fft=%1.1e\tt_dft_mpolar=%1.1e\tm=%d\t",N,t_fft,t_dft_mpolar,m);

      mpolar_fft(f_hat,N,f,T,R,m);
      fprintf(fp,"%1.1e&\t",GLOBAL_elapsed_time);
      printf("t_mpolar=%1.1e\t",GLOBAL_elapsed_time);
      inverse_mpolar_fft(f,T,R,f_hat,N,2*m,m);
      if(m==9)
	fprintf(fp,"%1.1e\\\\\\hline\n",GLOBAL_elapsed_time);
      else
	fprintf(fp,"%1.1e\\\\\n",GLOBAL_elapsed_time);
      printf("t_impolar=%1.1e\n",GLOBAL_elapsed_time);
    }

  fflush(fp);

  nfft_free(f);
  nfft_free(f_hat);

  return EXIT_SUCCESS;
}
Beispiel #3
0
void DrImage::Fourier(){
  int NStill = 0;//50;
  int NStep = 10;//(int)(25.*60.*.2) - NStill;
  int NChange = 60;
  int NSquare = 2;
  double Norm = 1./(double)(NWidth*NHeight);
  double InvNStep = 1./(double)NStep;
  Matematica *Mate = new Matematica();
  fftw_complex *out = (fftw_complex *)fftw_malloc(NWidth*NHeight*sizeof(fftw_complex));
  fftw_complex *in  = (fftw_complex *)fftw_malloc(NWidth*NHeight*sizeof(fftw_complex));
  fftw_plan direct = fftw_plan_dft_2d(NWidth,NHeight,
  				     in,out,FFTW_FORWARD,FFTW_PATIENT);
  fftw_plan reverse = fftw_plan_dft_2d(NWidth,NHeight,
  				     out,in,FFTW_BACKWARD,FFTW_PATIENT);
  int NhInit = NHeight;
  int NwInit = NWidth;
  double **data2 = (double **)calloc(3,sizeof(double));
  for(int l=0;l<3;l++){
    data2[l] = (double *)calloc(NHeight*NWidth,sizeof(double));
  }
  for(int l=0;l<3;l++){
    for(int h=0;h<NHeight;h++){
      for(int w=0;w<NWidth;w++){
  	data2[l][h*NWidth+w] = data[l][h*NWidth+w];
      }
    }
  }
  // for(int s=NStill+NStep;s>=NStep;s--){
  //   char cImage[160];
  //   sprintf(cImage,"Image%05u.png",s);
  //   pngwriter ImageOut(NWidth,NHeight,1.0,cImage);
  //   for(int h=0;h<NHeight;h++){
  //     for(int w=0;w<NWidth;w++){
  //   	ImageOut.plot(w,h,data[0][h*NWidth+w],data[1][h*NWidth+w],data[2][h*NWidth+w]);
  //     }
  //   }
  //   ImageOut.close();
  // }
  for(int s=NStep;s>0;s--){
    // NhInit--;
    // if(NhInit < 0) NhInit = 0;
    // NwInit--;
    // if(NwInit < 0) NwInit = 0;
    fprintf(stderr,"Elaborating %lf %%\r",s*InvNStep*100.);
    for(int l=0;l<3;l++){
      for(int h=0;h<NHeight;h++){
	for(int w=0;w<NWidth;w++){
	  in[h*NWidth+w][0] = data2[l][h*NWidth+w];
	  out[h*NWidth+w][0] = 0.;
	  out[h*NWidth+w][1] = 0.;
	}
      }
      fftw_execute(direct);
      // for(int h=NhInit;h<NHeight;h++){
      // 	for(int w=NwInit;w<NWidth;w++){
      // 	  printf("%d %d\n",h,w);
      // 	  out[h*NWidth+w][0] = 0.;
      // 	  out[h*NWidth+w][1] = 0.;
      // 	}
      // }
      fftw_execute(reverse);
      for(int h=0;h<NHeight;h++){
      	for(int w=0;w<NWidth;w++){
      	  data[l][h*NWidth+w] = in[h*NWidth+w][0]*Norm;
      	}
      }
    }
    char cImage[160];
    sprintf(cImage,"Image%05u.png",s);
    pngwriter ImageOut(NWidth,NHeight,1.0,cImage);
    for(int h=0;h<NHeight;h++){
      for(int w=0;w<NWidth;w++){
	ImageOut.plot(w,h,data[0][h*NWidth+w],data[1][h*NWidth+w],data[2][h*NWidth+w]);
      }
    }
    ImageOut.close();
    // FILE *FOut = fopen("Result1.dat","w");
    // for(int h=0;h<NHeight;h++){
    //   for(int w=0;w<NWidth;w++){
    // 	double x = w/(double)NWidth;
    // 	double y = h/(double)NHeight;
    // 	fprintf(FOut,"%lf %lf %lf\n",x,y,data[2][h*NWidth+w]);
    //   }
    // }
    // fclose(FOut);
    // FOut = fopen("Result2.dat","w");
    // for(int h=0;h<NHeight;h++){
    //   for(int w=0;w<NWidth;w++){
    // 	double x = w/(double)NWidth;
    // 	double y = h/(double)NHeight;
    // 	fprintf(FOut,"%lf %lf %lf\n",x,y,in[h*NWidth+w][0]);
    //   }
    // }
    // fclose(FOut);
  }
  fftw_destroy_plan(direct);
  fftw_destroy_plan(reverse);
  fftw_free(out);
  fftw_free(in);
  printf("\n");
}
Beispiel #4
0
Transformer::Transformer(DataLayout const& lay, unsigned int fftw_flags) :
		datalayout(lay),
		FFT_norm_factor(1.0/static_cast<double>(datalayout.sizex*datalayout.sizey)),
		FFTx_norm_factor(1.0/static_cast<double>(datalayout.sizex)),
		FFTy_norm_factor(1.0/static_cast<double>(datalayout.sizey)),
		DSCT_norm_factor(1.0/static_cast<double>(4*datalayout.sizex*datalayout.sizey)),
		DSCTx_norm_factor(1.0/static_cast<double>(2*datalayout.sizex)),
		DSCTy_norm_factor(1.0/static_cast<double>(2*datalayout.sizey)) {
	const int sx = static_cast<int>(datalayout.sizex);
	const int sy = static_cast<int>(datalayout.sizey);
	const double multiplier_x = M_PI/datalayout.lenx;
	const double multiplier_y = M_PI/datalayout.leny;
	// Compute frequency values
	d_fft_kx = new double[datalayout.sizex];
	d_fft_ky = new double[datalayout.sizey];
	d_dsct_kx = new double[datalayout.sizex];
	d_dsct_ky = new double[datalayout.sizey];
	for (int x=0; x < sx; x++) {
		d_fft_kx[x] = static_cast<double>((x < sx/2)? x : x-sx)*2*multiplier_x;
		d_dsct_kx[x] = static_cast<double>(x+1)*multiplier_x;
	}
	for (int y=0; y < sy; y++) {
		d_fft_ky[y] = static_cast<double>((y < sy/2)? y : y-sy)*2*multiplier_y;
		d_dsct_ky[y] = static_cast<double>(y+1)*multiplier_y;
	}
	// Initialize FFTW plans
	plans = new fftw_plan[num_transform_types];
	// Allocate a temporary data array. This is needed for computing the optimal plans.
	fftw_complex* const fftw_data = reinterpret_cast<fftw_complex*>(fftw_malloc(sx*sy*sizeof(comp)));
	double* const real_data = reinterpret_cast<double*>(fftw_data);
	// plans for plain FFT
	plans[FFT] = fftw_plan_dft_2d(sy, sx, fftw_data, fftw_data, FFTW_FORWARD, fftw_flags);
	plans[iFFT] = fftw_plan_dft_2d(sy, sx, fftw_data, fftw_data, FFTW_BACKWARD, fftw_flags);
	plans[FFTx] = fftw_plan_many_dft(1, &sx, sy, fftw_data, NULL, 1, sx, fftw_data, NULL, 1, sx,
			FFTW_FORWARD, fftw_flags);
	plans[iFFTx] = fftw_plan_many_dft(1, &sx, sy, fftw_data, NULL, 1, sx, fftw_data, NULL, 1, sx,
			FFTW_BACKWARD, fftw_flags);
	plans[FFTy] = fftw_plan_many_dft(1, &sy, sx, fftw_data, NULL, sx, 1, fftw_data, NULL, sx, 1,
			FFTW_FORWARD, fftw_flags);
	plans[iFFTy] = fftw_plan_many_dft(1, &sy, sx, fftw_data, NULL, sx, 1, fftw_data, NULL, sx, 1,
			FFTW_BACKWARD, fftw_flags);
	// For the sine and cosine transforms separately for the real and imaginary
	// part we need to fiddle with the guru interface of FFTW. Some new
	// variables are needed for describing the complex loops involved.
	// Do not try to understand this code without first understanding what fftw_plan_guru does,
	// please refer to the FFTW documentation for that.
	const fftw_r2r_kind DST_kind[] = {FFTW_RODFT10, FFTW_RODFT10};
	const fftw_r2r_kind IDST_kind[] = {FFTW_RODFT01, FFTW_RODFT01};
	const fftw_r2r_kind DCT_kind[] = {FFTW_REDFT10, FFTW_REDFT10};
	const fftw_r2r_kind IDCT_kind[] = {FFTW_REDFT01, FFTW_REDFT01};
	const int n[] = {sy, sx};
	fftw_iodim dimsx[1], dimsy[1], loopsx[2], loopsy[2];
	// x-transform loop setup
	dimsx[0].n = sx;
	dimsx[0].is = 2;
	dimsx[0].os = 2;
	loopsx[0].n = sy;
	loopsx[0].is = 2*sx;
	loopsx[0].os = 2*sx;
	loopsx[1].n = 2;
	loopsx[1].is = 1;
	loopsx[1].os = 1;
	// y-transform loop setup
	dimsy[0].n = sy;
	dimsy[0].is = 2*sx;
	dimsy[0].os = 2*sx;
	loopsy[0].n = sx;
	loopsy[0].is = 2;
	loopsy[0].os = 2;
	loopsy[1].n = 2;
	loopsy[1].is = 1;
	loopsy[1].os = 1;
	// DST plans
	plans[DST] = fftw_plan_many_r2r(2, n, 2, real_data, NULL, 2, 1, real_data, NULL, 2, 1, DST_kind, fftw_flags);
	plans[iDST] = fftw_plan_many_r2r(2, n, 2, real_data, NULL, 2, 1, real_data, NULL, 2, 1, IDST_kind, fftw_flags);
	plans[DSTx] = fftw_plan_guru_r2r(1, dimsx, 2, loopsx, real_data, real_data, DST_kind, fftw_flags);
	plans[iDSTx] = fftw_plan_guru_r2r(1, dimsx, 2, loopsx, real_data, real_data, IDST_kind, fftw_flags);
	plans[DSTy] = fftw_plan_guru_r2r(1, dimsy, 2, loopsy, real_data, real_data, DST_kind, fftw_flags);
	plans[iDSTy] = fftw_plan_guru_r2r(1, dimsy, 2, loopsy, real_data, real_data, IDST_kind, fftw_flags);
	// DCT plans
	plans[DCT] = fftw_plan_many_r2r(2, n, 2, real_data, NULL, 2, 1, real_data, NULL, 2, 1, DCT_kind, fftw_flags);
	plans[iDCT] = fftw_plan_many_r2r(2, n, 2, real_data, NULL, 2, 1, real_data, NULL, 2, 1, IDCT_kind, fftw_flags);
	plans[DCTx] = fftw_plan_guru_r2r(1, dimsx, 2, loopsx, real_data, real_data, DCT_kind, fftw_flags);
	plans[iDCTx] = fftw_plan_guru_r2r(1, dimsx, 2, loopsx, real_data, real_data, IDCT_kind, fftw_flags);
	plans[DCTy] = fftw_plan_guru_r2r(1, dimsy, 2, loopsy, real_data, real_data, DCT_kind, fftw_flags);
	plans[iDCTy] = fftw_plan_guru_r2r(1, dimsy, 2, loopsy, real_data, real_data, IDCT_kind, fftw_flags);
	// free temporary data array
	fftw_free(fftw_data);
}
Beispiel #5
0
mynamespace::rft2d::rft2d(int const N1_, int const N2_, double L1, double L2, double Var_Phi, double lx)
: 	N1(N1_), N2(N2_), Nmax(10000)
{
	if (N1%2 !=0 || N2%2 != 0)
	{
		std::cout << "division must be even number." << std::endl;
		return;
	}
	else {half_N1 = N1/2; half_N2 = N2/2;}
	double dV = L1*L2/N1/N2;
	double sigma2_p_D = sqrt(Var_Phi*M_PI*2.0*lx*lx/L1/L2);	
	double N_half_ilength2_p = -M_PI*M_PI*2.0*lx*lx;
	double sqrt2 = sqrt(2.0);
	double iDelta2 = 1.0;;
	//-----------Gaussian-table--------------------------
	std::cout << "Set up gaussian random table, size = " << Nmax << std::endl;
	std::normal_distribution<double> norm(0.0, std::sqrt(iDelta2));
	gaussian_list = new double [Nmax];
	for(int i=0;i<Nmax;i++)
	{
		gaussian_list[i] = norm(generator);
	}
	//---------------Grid-setup--------------------------------
	std::cout << "One time grids (index, argument) set up" << std::endl;
	double p1, p2, arg;
	exp_arg_clip = new bool * [half_N2+1];
	exp_tab1 = new double * [half_N2+1];
	exp_tab2 = new double * [half_N2+1];
	index_tab = new int * [half_N2+1];
	c_index_tab = new int * [half_N2+1];
	N2_low = half_N2+2; N2_high = 0; N1_low = N1+1; N1_high = 0;
	for (k2 = 0; k2 <= half_N2; k2++)
	{
		exp_arg_clip[k2] = new bool [N1];
		exp_tab1[k2] = new double [N1];
		exp_tab2[k2] = new double [N1];
		index_tab[k2] = new int [N1];
		c_index_tab[k2] = new int [N1];
		p2 = (k2 - half_N2)/L2;
		for (k1 = 0; k1 < N1; k1++)
		{
			p1 = (k1 - half_N1)/L1;
			arg = (p1*p1+p2*p2)*N_half_ilength2_p*0.5;
			exp_arg_clip[k2][k1] = true;//(arg >= -8.0);
			if (exp_arg_clip[k2][k1])
			{
				if (k2 < N2_low) N2_low = k2;
				if (k2 > N2_high) N2_high = k2;
				if (k1 < N1_low) N1_low = k1;
				if (k1 > N1_high) N1_high = k1;
			}
			exp_tab1[k2][k1] =  sigma2_p_D*std::exp(arg);
			exp_tab2[k2][k1] =  exp_tab1[k2][k1]/sqrt2;
			index_tab[k2][k1] = k1*N1+k2;
			c_index_tab[k2][k1] = ((N1-k1)%N1)*N1 + ((N2-k2)%N2);
		}
	}
	std::cout << "cut grid: [" << N2_low << ", " << N2_high << "] x [" << N1_low << ", " << N1_high << "]" << std::endl;
	//----------------FFTW-------------------------------------
	A = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N1*N2);
	B = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N1*N2);
	std::cout << "creating FFT plan" << std::endl;
	plan = fftw_plan_dft_2d(N1, N2, A, B, FFTW_BACKWARD, FFTW_MEASURE);
	std::cout << "FFT plan finished" << std::endl;
	for (k2 = 0; k2 < N2; k2++)
	{		
		for (k1 = 0; k1 < N1; k1++)
		{
			A[k1*N1+k2][0] = 0.0;
			A[k1*N1+k2][1] = 0.0;
		}
	}
	//---------------HDF5------------------------------
}
bool c_FourierTransfrom::fftw_complex_3d(const Mat_<Vec3d> &_input,
                                         Mat_<Vec6d> &_output)
{
    size_t height = _input.rows;
    size_t width = _input.cols;
    size_t n_channels = _input.channels();
    size_t n_pixels = height * width;
    size_t n_data = n_pixels * n_channels;

    fftw_complex *in, *out;
    fftw_plan p;

    in = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * n_data);
    out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * n_data);

#if 0
    p = fftw_plan_dft_3d(n_channels, width, height, in, out, FFTW_FORWARD,
                         FFTW_ESTIMATE);
#else
#if 1
    p = fftw_plan_dft_2d(n_channels, width * height, in, out, FFTW_FORWARD,
                         FFTW_ESTIMATE);
#else
    p = fftw_plan_dft_1d(n_channels * width * height, in, out, FFTW_FORWARD,
                         FFTW_ESTIMATE);
#endif
#endif

    /*!< prepare the data */
    for (size_t i_row = 0; i_row < height; ++i_row)
    {
        const Vec3d *p = _input.ptr<Vec3d>(i_row);
        for (size_t i_col = 0; i_col < width; ++i_col)
        {
            size_t index = i_row * width + i_col;
            for (size_t k = 0; k < n_channels; ++k)
            {
                in[n_pixels * k + index][0] = p[i_col][k];
            }
#if 0
            in[index][0] = p[i_col][2];
            in[n_pixels + index][0] = p[i_col][1];
            in[n_pixels * 2 + index][0] = p[i_col][0];
#endif
        }
    }
    for (size_t i = 0; i < n_data; ++i)
    {
        in[i][1] = 0;
    }

    fftw_execute(p);

    /*!< write back data */
    _output = Mat_<Vec6d>::zeros(_input.size());
    for (size_t i_row = 0; i_row < height; ++i_row)
    {
        Vec6d *p = _output.ptr<Vec6d>(i_row);
        for (size_t i_col = 0; i_col < width; ++i_col)
        {
            size_t index = i_row * width + i_col;
            for (size_t k = 0; k < n_channels; ++k)
            {
                p[i_col][k] = out[n_pixels * k + index][0];
                p[i_col][k + n_channels] = out[n_pixels * k + index][1];
            }
#if 0
            p[i_col][4] = out[index][0];
            p[i_col][5] = out[index][1];
            p[i_col][2] = out[n_pixels + index][0];
            p[i_col][3] = out[n_pixels + index][1];
            p[i_col][0] = out[n_pixels * 2 + index][0];
            p[i_col][1] = out[n_pixels * 2 + index][1];
#endif
        }
    }

    fftw_destroy_plan(p);
    fftw_free(in);
    fftw_free(out);

    return true;
}
Beispiel #7
0
void perform_dft(T *out_ptr, const T *mydata, int total_samples, int width, int height, std::string feature){

    fftw_complex *data_in;
    mycomplex *cI = new mycomplex[width*height]();

    ///initialize arrays for fftw operations
    data_in = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * width* height);

    ///Store data in the real component of the data_in array.
    for(int r = 0; r < height; r++){
        for(int c = 0; c < width; c++){
                data_in[r*width+c][0] = mydata[r*width+c];
            data_in[r*width+c][1] = 0.0;
        }
    }

    fftw_complex    *data_out;
    fftw_plan       plan_f;

    data_out = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );

    plan_f = fftw_plan_dft_2d(width, height, data_in, data_out,  FFTW_FORWARD,  FFTW_ESTIMATE);

    fftw_execute( plan_f);

    double maxMagnitude =-1e5;
    double maxPower = -1e5;

    int tempr = 0, tempc = 0;
    for(int r = 0; r < height; r++){
        for(int c = 0; c < width; c++){
            /// normalize values

            double realI = data_out[r*width + c][0];
            double imagI = data_out[r*width + c][1];
            double powerI = ((realI * realI) + (imagI * imagI)) / double(total_samples);
            double magI = sqrt(powerI);

            ///Get the maximum value of the magnitude
            if(maxMagnitude < magI)
                maxMagnitude = magI;
            if(maxPower < powerI){
                tempr = r;
                tempc = c;
                maxPower = powerI;
            }

            std::complex<double> ci(realI, imagI);
            double phaseI = arg(ci) + M_PI;
            mycomplex z;
            z.r = realI;
            z.i = imagI;
            z.mag = magI;/// double(total_samples);
            z.phase = phaseI;
            z.power =powerI;
            cI[r*width+c] = z;
        }
    }

    //std::cout << maxPower << " " << tempc << " " << tempr <<  std::endl;
    double constantMagFactor = 1.0 / log10(1.0 + fabs(maxMagnitude));
    double constantPowerLogScaling = 1.0 / log10(1.0 + fabs(maxPower));

    double constantPowerScaling = 1.0 / fabs(maxPower);


    for(int r = 0; r < height; r++){
        for(int c = 0; c < width; c++){

            double magnitude = cI[r*width + c].mag;
            magnitude =  (magnitude < 1e-4) ? 0.0 : magnitude;
            magnitude = (constantMagFactor * log10(1.0 + magnitude));

            double power = cI[r*width + c].power;
            double powerLogScaling = constantPowerLogScaling * power;
            double powerScaling = constantPowerScaling * power; //Simple range mapping to (0,1)

            double phase = cI[r*width+c].phase;


            if(feature == "magnitude" || feature == "mag")
                out_ptr[r*width+c] = magnitude;
            else if(feature == "power-logscaled")
                out_ptr[r*width+c] = powerLogScaling;
            else if(feature == "power-scaled")
                out_ptr[r*width+c] = powerScaling;
            else if(feature == "power")
                out_ptr[r*width+c] = power;
            else if(feature == "phase")
                out_ptr[r*width+c] = phase / double(2 * M_PI);
            else if(feature == "magphase")
                out_ptr[r*width+c] = magnitude + phase;
            else{
                std::cerr << "Please specify the feature (magnitude or power) of the Fourier spectrum !!!" << std::endl;
                exit(-2);
            }
        }
    }

    swapQuadrants(out_ptr, width, height);

    fftw_destroy_plan( plan_f);
    fftw_free( data_out);
    fftw_free(data_in);
    delete [] cI;
}
Beispiel #8
0
int main( int argc, char** argv )
{
    CvSize imgSize;                 
    imgSize.width = 320; 
    imgSize.height = 240; 
	
	int key= -1; 
	
	// set up opencv capture objects

    CvCapture* capture= cvCaptureFromCAM(0); 
	cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);
	cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 240);
	
    CvCapture* capture2= cvCaptureFromCAM(1); 
	cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_WIDTH, 320);
	cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_HEIGHT, 240);

    CvCapture* capture3= cvCaptureFromCAM(2); 
	cvSetCaptureProperty(capture3, CV_CAP_PROP_FRAME_WIDTH, 320);
	cvSetCaptureProperty(capture3, CV_CAP_PROP_FRAME_HEIGHT, 240);

    
	// allocate image storage (other createimage specifiers: IPL_DEPTH_32F, IPL_DEPTH_8U)
	
    IplImage* colourImage  = cvCloneImage(cvQueryFrame(capture)); 
    IplImage* greyImage    = cvCreateImage(cvGetSize(colourImage), IPL_DEPTH_8U, 1); 
    IplImage* hannImage    = cvCloneImage(greyImage); 
	IplImage *poc= cvCreateImage( cvSize( greyImage->width, kFFTStoreSize ), IPL_DEPTH_64F, 1 );
	IplImage *pocdisp= cvCreateImage( cvSize( greyImage->width, kFFTStoreSize ), IPL_DEPTH_8U, 1 );
	
	// set up opencv windows
	
    cvNamedWindow("hannImage", 1);
    cvNamedWindow("greyImage", 1); 
    cvNamedWindow("greyImage2", 1); 
    cvNamedWindow("greyImage3", 1); 
    cvNamedWindow("poc", 1);
	cvMoveWindow("greyImage", 40, 0);
	cvMoveWindow("hannImage", 40, 270);
	cvMoveWindow("poc", 365, 0);
	cvMoveWindow("greyImage2", 40, 540);
	cvMoveWindow("greyImage3", 365, 540);
	
	// set up storage for fftw
	
	fftw_complex *fftwSingleRow = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * kFFTWidth * 1 );
	fftw_complex *fftwSingleRow2 = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * kFFTWidth * 1 );
	fftw_complex *fftwStore = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * kFFTWidth * kFFTStoreSize );
		
	// loop
	
    while(key != 'q') 
	{ 

		//		double t = (double)cvGetTickCount();
		//		printf( "%g ms: start.\n", (cvGetTickCount() - t)/((double)cvGetTickFrequency()*1000.));

		// capture a frame, convert to greyscale, and show it
		
		cvCopyImage(cvQueryFrame(capture), colourImage);  // cvCopy because both are allocated already!
		cvCvtColor(colourImage,greyImage,CV_BGR2GRAY); 
		cvShowImage("greyImage",greyImage); 

        cvCopyImage(cvQueryFrame(capture2), colourImage);  // cvCopy because both are allocated already!
		cvCvtColor(colourImage,greyImage,CV_BGR2GRAY); 
		cvShowImage("greyImage2",greyImage); 

        cvCopyImage(cvQueryFrame(capture3), colourImage);  // cvCopy because both are allocated already!
		cvCvtColor(colourImage,greyImage,CV_BGR2GRAY); 
		cvShowImage("greyImage3",greyImage);

        
        key = cvWaitKey(3);

		// project and calculate hann window
		
		int i, j, k;
		uchar 	*inData= ( uchar* ) greyImage->imageData;
		uchar 	*hannImageData= ( uchar* ) hannImage->imageData;
		unsigned long acc;
		
		for( j = 0 ; j < greyImage->width ; j++) {
			
			// sum input column
			
			acc= 0;
			for( i = 0; i < greyImage->height ; i++ ) {
				acc+= inData[i * greyImage->widthStep + j];
			}
			
			// hann window and output
			
			for( i = 0; i < 240 ; i++ ) {
				double hannMultiplier = 0.5 * (1 - cos(2*3.14159*j/(greyImage->width-1)));  // hann window coefficient
				hannImageData[i * hannImage->widthStep + j]=  hannMultiplier * (acc/greyImage->height);
			}
			
		}

		cvShowImage("hannImage",hannImage); 

		// set up forward FFT into store plan
		
		fftw_plan fft_plan = fftw_plan_dft_2d( 1 , kFFTWidth, fftwSingleRow, &(fftwStore[kFFTWidth * pocline]), FFTW_FORWARD,  FFTW_ESTIMATE );
				
		// load data for fftw
		
		for( int j = 0 ; j < kFFTWidth ; j++) {
			fftwSingleRow[j][0] = ( double )hannImageData[j];
			fftwSingleRow[j][1] = 0.0;
		}
		
		// run and release plan
		
		fftw_execute( fft_plan );
		fftw_destroy_plan( fft_plan );

		// compare pocline against ALL OTHER IN STORE

		for( int j = 0 ; j < kFFTStoreSize ; j++) {
			
			fftw_complex *img1= &(fftwStore[kFFTWidth * pocline]);
			fftw_complex *img2= &(fftwStore[kFFTWidth * j]);
			
			// obtain the cross power spectrum
			for( int i = 0; i < kFFTWidth ; i++ ) {
				
				// complex multiply complex img2 by complex conjugate of complex img1
				
				fftwSingleRow[i][0] = ( img2[i][0] * img1[i][0] ) - ( img2[i][1] * ( -img1[i][1] ) );
				fftwSingleRow[i][1] = ( img2[i][0] * ( -img1[i][1] ) ) + ( img2[i][1] * img1[i][0] );
				
				// set tmp to (real) absolute value of complex number res[i]
				
				double tmp = sqrt( pow( fftwSingleRow[i][0], 2.0 ) + pow( fftwSingleRow[i][1], 2.0 ) );
				
				// complex divide res[i] by (real) absolute value of res[i]
				// (this is the normalization step)
				
				if(tmp == 0) {
					fftwSingleRow[i][0]= 0;
					fftwSingleRow[i][1]= 0;
				}
				else {
					fftwSingleRow[i][0] /= tmp;
					fftwSingleRow[i][1] /= tmp;
				}
			}
				
			// run inverse
			
			fft_plan = fftw_plan_dft_2d( 1 , kFFTWidth, fftwSingleRow, fftwSingleRow2, FFTW_BACKWARD,  FFTW_ESTIMATE );
			fftw_execute(fft_plan);
			fftw_destroy_plan( fft_plan );

			// normalize and copy to result image

			double 	*poc_data = ( double* )poc->imageData;
			
			for( int k = 0 ; k < kFFTWidth ; k++ ) {
				poc_data[k+(j*kFFTWidth)] = (fftwSingleRow2[k][0] / ( double )kFFTWidth);
			}
				
			
		}
		
		
		

		// inc pocline
		
		pocline++;
		if(pocline == kFFTStoreSize-1)
			pocline= 0;
		
		
		// display??
		

//		for(int i = 0 ; i < kFFTWidth ; i++ ) {
//			poc_data[i+(pocline*kFFTWidth)] = (fftwStore[(kFFTWidth * pocline)+i])[1];
//		}
		
		// find the maximum value and its location
		CvPoint minloc, maxloc;
		double  minval, maxval;
		cvMinMaxLoc( poc, &minval, &maxval, &minloc, &maxloc, 0 );
		
		// print it
//		printf( "Maxval at (%d, %d) = %2.4f\n", maxloc.x, maxloc.y, maxval );
		
//        cvConvertScale(dft_re,dft_orig,255,0); //255.0*(max-min),0);

        
        
		cvCvtScale(poc, pocdisp, (1.0/(maxval/2))*255, 0);
		
		cvShowImage("poc",pocdisp);
		
		
		// set up fftw plans
//		fftw_plan fft_plan = fftw_plan_dft_2d( 1 , kFFTWidth, img2, img2, FFTW_FORWARD,  FFTW_ESTIMATE );
//		fftw_plan ifft_plan = fftw_plan_dft_2d( 1 , kFFTWidth, res,  res,  FFTW_BACKWARD, FFTW_ESTIMATE );
		
		
		
		// TODO FROM HERE
		
		/*
		
		if(key == 'r') {
			cvReleaseImage(&ref);
			ref= cvCloneImage(testOutImage);
			cvShowImage("ref",ref); 
		}
		
		
		
		{  // try phase correlating full img
			
			tpl= cvCloneImage(testOutImage);
			//				ref= cvCloneImage(testOutImage);
//				cvShowImage("tpl",tpl); 
//				cvShowImage("ref",ref); 
			
			
			if(ref == 0)
				continue;
			
			if( ( tpl->width != ref->width ) || ( tpl->height != ref->height ) ) {
				fprintf( stderr, "Both images must have equal width and height!\n" );
				continue
				;
			}
			
			// get phase correlation of input images
			
			phase_correlation( ref, tpl, poc );
			
			// find the maximum value and its location
			CvPoint minloc, maxloc;
			double  minval, maxval;
			cvMinMaxLoc( poc, &minval, &maxval, &minloc, &maxloc, 0 );
			
			// print it
			printf( "Maxval at (%d, %d) = %2.4f\n", maxloc.x, maxloc.y, maxval );
			
			cvCvtScale(poc, pocdisp, 1.0/(maxval/2), 0);
			
			cvShowImage("poc",pocdisp);
			
			cvReleaseImage(&tpl);
		
			
		}*/

//			cvReleaseImage(&ref);
//			ref= cvCloneImage(testOutImage);

//			printf( "%g ms: done.\n", (cvGetTickCount() - t)/((double)cvGetTickFrequency()*1000.));
			

	} 
	
	
	cvReleaseImage(&poc);

	
	return 0;
}
bool tpImageFilter::ApplyFastFilterTemplate(const T& I, TRes& O, const tpFilter& F)
{
	int L = I.getWidth();
	int width = L;
	int M = I.getHeight();
	int height = M;
	const double factor = 1.0/sqrt((double)height*width);
	O.resize(height, width);

	std::cout << "[INFO] Create complex caches numbers : " << L << "x" << M << std::endl;
	fftw_complex* in = (fftw_complex*)fftw_malloc(sizeof (fftw_complex)*M*L);
	fftw_complex* out = (fftw_complex*)fftw_malloc(sizeof (fftw_complex)*M*L);
	fftw_complex* kernel = (fftw_complex*)fftw_malloc(sizeof (fftw_complex)*M*L);
	fftw_plan p;
	fftw_plan p_inv;

	int w2 = (int)floor(F.getWidth() / 2.0);
	int h2 = (int)floor(F.getHeight() / 2.0);
	int centerX = (int)ceil(M / 2.0);
	int centerY = (int)ceil(L / 2.0);
	std::cout << "[INFO] Filtering size : " << F.getHeight() << "x" << F.getWidth() << std::endl;
	std::cout << "[INFO] half Filtering size : " << h2 << "x" << w2 << std::endl;
	//  Fill fftw_complex for kernel
	for(int x = 0; x < M; x++)
		for(int y = 0; y < L; y++)
		{
			if(((centerX - h2) < x) & ((centerX + h2) >= x) & ((centerY - w2) < y) & ((centerY + w2) >= y))
			{
				int vX = x - (centerX - h2);
				int vY = y - (centerY - w2);
				in[x*L+y][0] = F[vX][vY];
				in[x*L+y][1] = F[vX][vY];
			}
			else
			{
				in[x*L+y][0] = 0;
				in[x*L+y][1] = 0;
			}
		}
	// Create the plan (need by fftw)
	p = fftw_plan_dft_2d(M, L, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
	// Apply the transform (kernel)
	fftw_execute(p);
	for(int i = 0; i < M; i++)
		for(int j = 0; j < L; j++)
		{
			kernel[i*L+j][0] = out[i*L+j][0];
			kernel[i*L+j][1] = out[i*L+j][1];
		}
	// Apply transform (image)
	for(int i = 0; i < M; i++)
		for(int j = 0; j < L; j++)
		{
			in[i*L+j][0] = I[i][j];
			in[i*L+j][1] = 0;
		}
	fftw_execute(p);
	// Apply filter
	for(int i = 0; i < M; i++)
		for(int j = 0; j < L; j++)
		{
			out[i*L+j][0] = out[i*L+j][0]*kernel[i*L+j][0];
			out[i*L+j][1] = out[i*L+j][1]*kernel[i*L+j][1];
		}

	// Reverse the transform ...
	p_inv = fftw_plan_dft_2d(M, L, out, in, FFTW_BACKWARD, FFTW_ESTIMATE);
	fftw_execute(p_inv);
	// Copy result
	for(int i = 0; i < centerX; i++)
		for(int j = 0; j < centerY; j++)
		{
			O[i][j] = in[(i+centerX)*width + j+centerY][0]*factor*factor;
			O[i][j+centerY] = in[(i+centerX)*width + j][0]*factor*factor;
			O[i+centerX][j+centerY] = in[(i)*width + j][0]*factor*factor;
			O[i+centerX][j] = in[(i)*width + j + centerY][0]*factor*factor;
		}
	// Free memory
	fftw_destroy_plan(p);
	fftw_destroy_plan(p_inv);
	fftw_free(in);
	fftw_free(out);
	fftw_free(kernel);
	return true;
}
Beispiel #10
0
/**
 * \brief Creates and initializes the working data for the plan
 * \param [in] plan Holds the data and memory for the plan.
 * \return int Error flag value
 * \sa parseFFT2Plan
 * \sa makeFFT2Plan
 * \sa execFFT2Plan
 * \sa perfFFT2Plan
 * \sa killFFT2Plan
 */
int initFFT2Plan(void *plan){
    int i,k;
    size_t M;
    int ret = make_error(ALLOC,generic_err);
    Plan *p;
    FFTdata *d = NULL;
    p = (Plan *)plan;

    #ifdef HAVE_PAPI
    int temp_event, j;
    int PAPI_Events [NUM_PAPI_EVENTS] = PAPI_COUNTERS;
    char *PAPI_units [NUM_PAPI_EVENTS] = PAPI_UNITS;
    #endif //HAVE_PAPI

    if(p){
        d = (FFTdata *)p->vptr;
        p->exec_count = 0;
        if(DO_PERF){
            perftimer_init(&p->timers, NUM_TIMERS);

            #ifdef HAVE_PAPI
            /* Initialize plan's PAPI data */
            p->PAPI_EventSet = PAPI_NULL;
            p->PAPI_Num_Events = 0;

            TEST_PAPI(PAPI_create_eventset(&p->PAPI_EventSet), PAPI_OK, MyRank, 9999, PRINT_SOME);

            //Add the desired events to the Event Set; ensure the dsired counters
            //  are on the system then add, ignore otherwise
            for(j = 0; j < TOTAL_PAPI_EVENTS && j < NUM_PAPI_EVENTS; j++){
                temp_event = PAPI_Events[j];
                if(PAPI_query_event(temp_event) == PAPI_OK){
                    p->PAPI_Num_Events++;
                    TEST_PAPI(PAPI_add_event(p->PAPI_EventSet, temp_event), PAPI_OK, MyRank, 9999, PRINT_SOME);
                }
            }

            PAPIRes_init(p->PAPI_Results, p->PAPI_Times);
            PAPI_set_units(p->name, PAPI_units, NUM_PAPI_EVENTS);

            TEST_PAPI(PAPI_start(p->PAPI_EventSet), PAPI_OK, MyRank, 9999, PRINT_SOME);
            #endif //HAVE_PAPI
        }         //DO_PERF
    }
    if(d){
        M = d->M;

        pthread_rwlock_wrlock(&FFTW_Lock);
        d->in_original = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * M * M);
        assert(d->in_original);
        d->out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * M * M);
        assert(d->out);
        d->mid = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * M * M);
        assert(d->mid);
        if(d->in_original && d->out && d->mid){
            ret = make_error(0,specific_err);                                                   // Error in getting the plan set
        }
        d->forward = fftw_plan_dft_2d(M,M,d->in_original,d->mid,FFTW_FORWARD, FFTW_ESTIMATE);
        d->backward = fftw_plan_dft_2d(M,M,d->mid,d->out,FFTW_BACKWARD, FFTW_ESTIMATE);
        pthread_rwlock_unlock(&FFTW_Lock);
        if(d->forward && d->backward){
            ret = ERR_CLEAN;
        }

        srand(0);
        for(i = 0; i < M; i++){
            for(k = 0; k < M; k++){
                d->in_original[i * M + k][0] = rand();
                d->in_original[i * M + k][1] = rand();
            }
        }
    }
    return ret;
} /* initFFT2Plan */
Beispiel #11
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");
  }
}
Beispiel #12
0
bool FFT::convolve(float* source, float* kernel, int xSource, int ySource, int xKernel, int yKernel)
{
  int x, y, index;
  
  // get normalization params
  float maxCurrent = 0.0f;
  for (x = 0; x < xSource * ySource; x++)
    maxCurrent = (maxCurrent < source[x]) ? source[x] : maxCurrent;
  float maxKernel = 0.0f;
  for (x = 0; x < xKernel * yKernel; x++)
    maxKernel = (maxKernel < kernel[x]) ? kernel[x] : maxKernel;
  float maxProduct = maxCurrent * maxKernel;
 
  // retrieve dimensions
  int xHalf = xKernel / 2;
  int yHalf = yKernel / 2;
  int xResPadded = xSource + xKernel;
  int yResPadded = ySource + yKernel;

  if (xResPadded != yResPadded)
    (xResPadded > yResPadded) ? yResPadded = xResPadded : xResPadded = yResPadded;

  // create padded field
  fftw_complex* padded = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * xResPadded * yResPadded);
  if (!padded)
  {
    cout << " IMAGE: Not enough memory! Try a smaller final image size." << endl;
    return false;
  }
 
  // init padded field
  for (index = 0; index < xResPadded * yResPadded; index++)
    padded[index][0] = padded[index][1] = 0.0f;
  index = 0;
  for (y = 0; y < ySource; y++)
    for (x = 0; x < xSource; x++, index++)
    {
      int paddedIndex = (x + xKernel / 2) + (y + yKernel / 2) * xResPadded;
      padded[paddedIndex][0] = source[index];
    }

  // create padded filter
  fftw_complex* filter = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * xResPadded * yResPadded);
  if (!filter)
  {
    cout << " FILTER: Not enough memory! Try a smaller final image size." << endl;
    return false;
  }

  // init padded filter
  for (index = 0; index < xResPadded * yResPadded; index++)
    filter[index][0] = filter[index][1] = 0.0f;
  
  // quadrant IV
  for (y = 0; y < (yHalf + 1); y++)
    for (x = 0; x < (xHalf + 1); x++)
    {
      int filterIndex = x + xHalf + y * xKernel;
      int fieldIndex = x + (y + yResPadded - (yHalf + 1)) * xResPadded;
      filter[fieldIndex][0] = kernel[filterIndex];
    }

  // quadrant I
  for (y = 0; y < yHalf; y++)
    for (x = 0; x < (xHalf + 1); x++)
    {
      int filterIndex = (x + xHalf) + (y + yHalf + 1) * xKernel;
      int fieldIndex = x + y * xResPadded;
      filter[fieldIndex][0] = filter[fieldIndex][1] = kernel[filterIndex];
    }
  
  // quadrant III
  for (y = 0; y < (yHalf + 1); y++)
    for (x = 0; x < xHalf; x++)
    {
      int filterIndex = x + y * xKernel;
      int fieldIndex = (x + xResPadded - xHalf) + (y + yResPadded - (yHalf + 1)) * xResPadded;
      filter[fieldIndex][0] = filter[fieldIndex][1] = kernel[filterIndex];
    }

  // quadrant II
  for (y = 0; y < yHalf; y++)
    for (x = 0; x < xHalf; x++)
    {
      int filterIndex = x + (y + yHalf + 1) * xKernel;
      int fieldIndex = (x + xResPadded - xHalf) + y * xResPadded;
      filter[fieldIndex][0] = filter[fieldIndex][1] = kernel[filterIndex];
    }
  
  // perform forward FFT on field
  fftw_complex* paddedTransformed = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * xResPadded * yResPadded);
  if (!paddedTransformed)
  {
    cout << " T-IMAGE: Not enough memory! Try a smaller final image size." << endl;
    return false;
  }
  fftw_plan forwardField = fftw_plan_dft_2d(xResPadded, yResPadded, padded, paddedTransformed, FFTW_FORWARD, FFTW_ESTIMATE);  
  fftw_execute(forwardField);

  // perform forward FFT on filter
  fftw_complex* filterTransformed = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * xResPadded * yResPadded);
  if (!filterTransformed)
  {
    cout << " T-FILTER: Not enough memory! Try a smaller final image size." << endl;
    return false;
  }
  fftw_plan forwardFilter = fftw_plan_dft_2d(xResPadded, yResPadded, filter, filterTransformed, FFTW_FORWARD, FFTW_ESTIMATE);  
  fftw_execute(forwardFilter);

  // apply frequency space filter
  for (index = 0; index < xResPadded * yResPadded; index++)
  {
    float newReal = paddedTransformed[index][0] * filterTransformed[index][0] - 
                    paddedTransformed[index][1] * filterTransformed[index][1];
    float newIm   = paddedTransformed[index][0] * filterTransformed[index][1] + 
                    paddedTransformed[index][1] * filterTransformed[index][0];
    paddedTransformed[index][0] = newReal;
    paddedTransformed[index][1] = newIm;
  }
   
  // transform back
  fftw_plan backwardField = fftw_plan_dft_2d(xResPadded, yResPadded, paddedTransformed, padded, FFTW_BACKWARD, FFTW_ESTIMATE);  
  fftw_execute(backwardField);
  
  // copy back into padded
  index = 0;
  for (y = 0; y < ySource; y++)
    for (x = 0; x < xSource; x++, index++)
    {
      int paddedIndex = (x + xKernel / 2) + (y + yKernel / 2) * xResPadded;
      source[index] = padded[paddedIndex][0];
    }

  // clean up
  fftw_free(padded);
  fftw_free(paddedTransformed);
  fftw_free(filter);
  fftw_free(filterTransformed);

  // if normalization is exceeded, renormalize
  float newMax = 0.0f;
  for (x = 0; x < xSource * ySource; x++)
    newMax = (newMax < source[x]) ? source[x] : newMax;
  if (newMax > maxProduct)
  {
    float scale = maxProduct / newMax;
    for (x = 0; x < xSource * ySource; x++)
      source[x] *= scale;
  }

  return true;
}
Beispiel #13
0
int main(int argc, char *argv[]) {

  

  int i, j, Nx, Ny, Nr, Nb;
  int seedn=54;
  double sigma;
  double a;
  double mse;
  double snr;
  double snr_out;
  double gamma=0.001;
  double aux1, aux2, aux3, aux4;
  complex double alpha;
  

  purify_image img, img_copy;
  purify_visibility_filetype filetype_vis;
  purify_image_filetype filetype_img;
  complex double *xinc;
  complex double *y0;
  complex double *y;
  complex double *noise;
  double *xout;
  double *w;
  double *error;
  complex double *xoutc;
  double *wdx;
  double *wdy;
  double *dummyr;
  complex double *dummyc;

  
  //parameters for the continuos Fourier Transform
  double *deconv;
  purify_sparsemat_row gmat;
  purify_visibility vis_test;
  purify_measurement_cparam param_m1;
  purify_measurement_cparam param_m2;
  complex double *fft_temp1;
  complex double *fft_temp2;
  void *datafwd[5];
  void *dataadj[5];
  fftw_plan planfwd;
  fftw_plan planadj;

  //Structures for sparsity operator
  sopt_wavelet_type *dict_types;
  sopt_wavelet_type *dict_types1;
  sopt_wavelet_type *dict_types2;
  sopt_sara_param param1;
  sopt_sara_param param2;
  sopt_sara_param param3;
  void *datas[1];
  void *datas1[1];
  void *datas2[1];

  //Structures for the opmization problems
  sopt_l1_sdmmparam param4;
  sopt_l1_rwparam param5;
  sopt_prox_tvparam param6;
  sopt_tv_sdmmparam param7;
  sopt_tv_rwparam param8;

  clock_t start, stop;
  double t = 0.0;
  double start1, stop1;
  int dimy, dimx;
  
  //Image dimension of the zero padded image
  //Dimensions should be power of 2
  dimx = 256;
  dimy = 256;

  //Define parameters
  filetype_vis = PURIFY_VISIBILITY_FILETYPE_PROFILE_VIS;
  filetype_img = PURIFY_IMAGE_FILETYPE_FITS;

  //Read coverage
  purify_visibility_readfile(&vis_test,
             "./data/images/Coverages/cont_sim4.vis",
             filetype_vis); 
  printf("Number of visibilities: %i \n\n", vis_test.nmeas);  

   

  // Input image.
  img.fov_x = 1.0 / 180.0 * PURIFY_PI;
  img.fov_y = 1.0 / 180.0 * PURIFY_PI;
  img.nx = 4;
  img.ny = 4;

  //Read input image
  purify_image_readfile(&img, "data/images/Einstein.fits", 1);
  printf("Image dimension: %i, %i \n\n", img.nx, img.ny); 
//  purify_image_writefile(&img, "data/test/Einstein_double.fits", filetype_img);

  param_m1.nmeas = vis_test.nmeas;
  param_m1.ny1 = dimy;
  param_m1.nx1 = dimx;
  param_m1.ofy = 2;
  param_m1.ofx = 2;
  param_m1.ky = 2;
  param_m1.kx = 2;

  param_m2.nmeas = vis_test.nmeas;
  param_m2.ny1 = dimy;
  param_m2.nx1 = dimx;
  param_m2.ofy = 2;
  param_m2.ofx = 2;
  param_m2.ky = 2;
  param_m2.kx = 2;

  Nb = 9;
  Nx=param_m2.ny1*param_m2.nx1;
  Nr=Nb*Nx;
  Ny=param_m2.nmeas;

  //Memory allocation for the different variables
  deconv = (double*)malloc((Nx) * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(deconv);
  xinc = (complex double*)malloc((Nx) * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(xinc);
  xout = (double*)malloc((Nx) * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(xout);
  y = (complex double*)malloc((vis_test.nmeas) * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(y);
  y0 = (complex double*)malloc((vis_test.nmeas) * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(y0);
  noise = (complex double*)malloc((vis_test.nmeas) * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(noise);
  w = (double*)malloc((Nr) * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(w);
  error = (double*)malloc((Nx) * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(error);
  xoutc = (complex double*)malloc((Nx) * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(xoutc);

  wdx = (double*)malloc((Nx) * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(wdx);
  wdy = (double*)malloc((Nx) * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(wdy);

  dummyr = malloc(Nr * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(dummyr);
  dummyc = malloc(Nr * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(dummyc);

  for (i=0; i < Nx; i++){
    xinc[i] = 0.0 + 0.0*I;
  }

  for (i=0; i < img.nx; i++){
    for (j=0; j < img.ny; j++){
      xinc[i+j*param_m1.nx1] = img.pix[i+j*img.nx] + 0.0*I;
    }
  }
  
  //Initialize griding matrix
  assert((start = clock())!=-1);
  purify_measurement_init_cft(&gmat, deconv, vis_test.u, vis_test.v, &param_m1);
  stop = clock();
  t = (double) (stop-start)/CLOCKS_PER_SEC;
  printf("Time initalization: %f \n\n", t);

  for(i = 0; i < img.nx * img.ny; ++i){
    deconv[i] = 1.0;
  }
  
  //Memory allocation for the fft
  i = Nx*param_m1.ofy*param_m1.ofx;
  fft_temp1 = (complex double*)malloc((i) * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(fft_temp1);
  fft_temp2 = (complex double*)malloc((i) * sizeof(complex double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(fft_temp2);

  //FFT plan  
  planfwd = fftw_plan_dft_2d(param_m1.nx1*param_m1.ofx, param_m1.ny1*param_m1.ofy, 
              fft_temp1, fft_temp1, 
              FFTW_FORWARD, FFTW_MEASURE);

  planadj = fftw_plan_dft_2d(param_m1.nx1*param_m1.ofx, param_m1.ny1*param_m1.ofy, 
              fft_temp2, fft_temp2, 
              FFTW_BACKWARD, FFTW_MEASURE);


  datafwd[0] = (void*)&param_m1;
  datafwd[1] = (void*)deconv;
  datafwd[2] = (void*)&gmat;
  datafwd[3] = (void*)&planfwd;
  datafwd[4] = (void*)fft_temp1;

  dataadj[0] = (void*)&param_m2;
  dataadj[1] = (void*)deconv;
  dataadj[2] = (void*)&gmat;
  dataadj[3] = (void*)&planadj;
  dataadj[4] = (void*)fft_temp2;


  printf("FFT plan done \n\n");
  
  
  assert((start = clock())!=-1);
  purify_measurement_cftfwd((void*)y0, (void*)xinc, datafwd);
  stop = clock();
  t = (double) (stop-start)/CLOCKS_PER_SEC;
  printf("Time forward operator: %f \n\n", t);

  
  //Noise realization
  //Input snr
  snr = 30.0;
  a = cblas_dznrm2(Ny, (void*)y0, 1);
  sigma = a*pow(10.0,-(snr/20.0))/sqrt(Ny);

  FILE *fout = fopen("ein.uv", "w");
    
  for (i=0; i < Ny; i++) {
//      noise[i] = (sopt_ran_gasdev2(seedn) + sopt_ran_gasdev2(seedn)*I)*(sigma/sqrt(2));
      noise[i] = 0;
      y[i] = y0[i] + noise[i];

    fprintf(fout, "%14.5e%14.5e%14.5e%14.5e%14.5e%14.5e\n", 
            vis_test.u[i], vis_test.v[i], vis_test.w[i],
            creal(y[i]), cimag(y[i]), 1.0);
  }

  fclose(fout);

  //Rescaling the measurements

  aux4 = (double)Ny/(double)Nx;

  for (i=0; i < Ny; i++) {
    y[i] = y[i]/sqrt(aux4);
  }

  for (i=0; i < Nx; i++) {
    deconv[i] = deconv[i]/sqrt(aux4);
  }
  
  
  // Output image.
  img_copy.fov_x = 1.0 / 180.0 * PURIFY_PI;
  img_copy.fov_y = 1.0 / 180.0 * PURIFY_PI;
  img_copy.nx = param_m1.nx1;
  img_copy.ny = param_m1.ny1;

  for (i=0; i < Nx; i++){
    xoutc[i] = 0.0 + 0.0*I;
  }
  
  //Dirty image
  purify_measurement_cftadj((void*)xoutc, (void*)y, dataadj);

  for (i=0; i < Nx; i++) {
    xout[i] = creal(xoutc[i]);
  }

  aux1 = purify_utils_maxarray(xout, Nx);

  

   img_copy.pix = (double*)malloc((Nx) * sizeof(double));
  PURIFY_ERROR_MEM_ALLOC_CHECK(img_copy.pix);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "eindirty.fits", filetype_img);
  
  return 0;
  
  //SARA structure initialization

    param1.ndict = Nb;
    param1.real = 0;

    dict_types = malloc(param1.ndict * sizeof(sopt_wavelet_type));
    PURIFY_ERROR_MEM_ALLOC_CHECK(dict_types);


    dict_types[0] = SOPT_WAVELET_DB1;
    dict_types[1] = SOPT_WAVELET_DB2;
    dict_types[2] = SOPT_WAVELET_DB3;
    dict_types[3] = SOPT_WAVELET_DB4;
    dict_types[4] = SOPT_WAVELET_DB5;
    dict_types[5] = SOPT_WAVELET_DB6;
    dict_types[6] = SOPT_WAVELET_DB7;
    dict_types[7] = SOPT_WAVELET_DB8;
    dict_types[8] = SOPT_WAVELET_Dirac;
    

    sopt_sara_initop(&param1, param_m1.ny1, param_m1.nx1, 4, dict_types);

    datas[0] = (void*)&param1;

    //Db8 structure initialization

    param2.ndict = 1;
    param2.real = 0;

    dict_types1 = malloc(param2.ndict * sizeof(sopt_wavelet_type));
    PURIFY_ERROR_MEM_ALLOC_CHECK(dict_types1);

    dict_types1[0] = SOPT_WAVELET_DB8;
    
    sopt_sara_initop(&param2, param_m1.ny1, param_m1.nx1, 4, dict_types1);

  datas1[0] = (void*)&param2;

  //Dirac structure initialization

    param3.ndict = 1;
    param3.real = 0;

    dict_types2 = malloc(param3.ndict * sizeof(sopt_wavelet_type));
    PURIFY_ERROR_MEM_ALLOC_CHECK(dict_types2);

    dict_types2[0] = SOPT_WAVELET_Dirac;
    
    sopt_sara_initop(&param3, param_m1.ny1, param_m1.nx1, 4, dict_types2);

  datas2[0] = (void*)&param3;

  //Scaling constants in the diferent representation domains

  sopt_sara_analysisop((void*)dummyc, (void*)xoutc, datas);

  for (i=0; i < Nr; i++) {
    dummyr[i] = creal(dummyc[i]);
  }

  aux2 = purify_utils_maxarray(dummyr, Nr);

  sopt_sara_analysisop((void*)dummyc, (void*)xoutc, datas1);

  for (i=0; i < Nr; i++) {
    dummyr[i] = creal(dummyc[i]);
  }

  aux3 = purify_utils_maxarray(dummyr, Nx);

  


  // Output image.
  img_copy.fov_x = 1.0 / 180.0 * PURIFY_PI;
  img_copy.fov_y = 1.0 / 180.0 * PURIFY_PI;
  img_copy.nx = param_m1.nx1;
  img_copy.ny = param_m1.ny1;



  //Initial solution and weights
  for (i=0; i < Nx; i++) {
      xoutc[i] = 0.0 + 0.0*I;
      wdx[i] = 1.0;
      wdy[i] = 1.0;
  }
  for (i=0; i < Nr; i++){
    w[i] = 1.0;
  }
  //Copy true image in xout
  for (i=0; i < Nx; i++) {
    xout[i] = creal(xinc[i]);
  }



  printf("**********************\n");
  printf("BPSA reconstruction\n");
  printf("**********************\n");

  
    
  //Structure for the L1 solver      
  param4.verbose = 2;
  param4.max_iter = 300;
  param4.gamma = gamma*aux2;
  param4.rel_obj = 0.001;
  param4.epsilon = sqrt(Ny + 2*sqrt(Ny))*sigma/sqrt(aux4);
  param4.epsilon_tol = 0.01;
  param4.real_data = 0;
  param4.cg_max_iter = 100;
  param4.cg_tol = 0.000001;

  
  //Initial solution
  for (i=0; i < Nx; i++) {
      xoutc[i] = 0.0 + 0.0*I;
  }
 
  #ifdef _OPENMP 
    start1 = omp_get_wtime();
  #else
    assert((start = clock())!=-1);
  #endif
  sopt_l1_sdmm((void*)xoutc, Nx,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   &sopt_sara_synthesisop,
                   datas,
                   &sopt_sara_analysisop,
                   datas,
                   Nr,
                   (void*)y, Ny, w, param4);

  #ifdef _OPENMP 
    stop1 = omp_get_wtime();
    t = stop1 - start1;
  #else
    stop = clock();
    t = (double) (stop-start)/CLOCKS_PER_SEC;
  #endif

  printf("Time BPSA: %f \n\n", t); 

  
    //SNR
    for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);


    
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "./data/test/einbpsa.fits", filetype_img);

  //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einbpsares.fits", filetype_img);
  
  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/einbpsaerror.fits", filetype_img);
  


  printf("**********************\n");
  printf("SARA reconstruction\n");
  printf("**********************\n");

  

  //Structure for the RWL1 solver    
  param5.verbose = 2;
  param5.max_iter = 5;
  param5.rel_var = 0.001;
  param5.sigma = sigma*sqrt((double)Ny/(double)Nr);
  param5.init_sol = 1;

  
  #ifdef _OPENMP 
    start1 = omp_get_wtime();
  #else
    assert((start = clock())!=-1);
  #endif
  sopt_l1_rwsdmm((void*)xoutc, Nx,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   &sopt_sara_synthesisop,
                   datas,
                   &sopt_sara_analysisop,
                   datas,
                   Nr,
                   (void*)y, Ny, param4, param5);

  #ifdef _OPENMP 
    stop1 = omp_get_wtime();
    t = stop1 - start1;
  #else
    stop = clock();
    t = (double) (stop-start)/CLOCKS_PER_SEC;
  #endif

  printf("Time SARA: %f \n\n", t); 

  
    //SNR
    for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einsara.fits", filetype_img);

  

   //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einsarares.fits", filetype_img);

  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/einsaraerror.fits", filetype_img);

  
    printf("**********************\n");
    printf("TV reconstruction\n");
    printf("**********************\n");

    
    //Structure for the TV prox
    param6.verbose = 1;
    param6.max_iter = 50;
    param6.rel_obj = 0.0001;

    
    //Structure for the TV solver    
    param7.verbose = 2;
    param7.max_iter = 300;
    param7.gamma = gamma*aux1;
    param7.rel_obj = 0.001;
    param7.epsilon = sqrt(Ny + 2*sqrt(Ny))*sigma/sqrt(aux4);
    param7.epsilon_tol = 0.01;
    param7.real_data = 0;
    param7.cg_max_iter = 100;
    param7.cg_tol = 0.000001;
    param7.paramtv = param6;

    //Initial solution and weights
    for (i=0; i < Nx; i++) {
        xoutc[i] = 0.0 + 0.0*I;
        wdx[i] = 1.0;
        wdy[i] = 1.0;
    }

    
    assert((start = clock())!=-1);
    sopt_tv_sdmm((void*)xoutc, dimx, dimy,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   (void*)y, Ny, wdx, wdy, param7);
    stop = clock();
    t = (double) (stop-start)/CLOCKS_PER_SEC;
    
    printf("Time TV: %f \n\n", t); 

    
   //SNR
    for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/eintv.fits", filetype_img);

   //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/eintvres.fits", filetype_img);

  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/eintverror.fits", filetype_img);

  printf("**********************\n");
  printf("RWTV reconstruction\n");
  printf("**********************\n");

  

  //Structure for the RWTV solver    
  param8.verbose = 2;
  param8.max_iter = 5;
  param8.rel_var = 0.001;
  param8.sigma = sigma*sqrt(Ny/(2*Nx));
  param8.init_sol = 1;

  
  assert((start = clock())!=-1);
    sopt_tv_rwsdmm((void*)xoutc, dimx, dimy,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   (void*)y, Ny, param7, param8);
    stop = clock();
    t = (double) (stop-start)/CLOCKS_PER_SEC;

  printf("Time RWTV: %f \n\n", t); 

  

    //SNR
    for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwtv.fits", filetype_img);

   //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwtvres.fits", filetype_img);

  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwtverror.fits", filetype_img);

  printf("**********************\n");
  printf("Db8 reconstruction\n");
  printf("**********************\n");

  //Initial solution
  for (i=0; i < Nx; i++) {
        xoutc[i] = 0.0 + 0.0*I;
  }
  
  param4.gamma = gamma*aux3;

  assert((start = clock())!=-1);
   sopt_l1_sdmm((void*)xoutc, Nx,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   &sopt_sara_synthesisop,
                   datas1,
                   &sopt_sara_analysisop,
                   datas1,
                   Nx,
                   (void*)y, Ny, w, param4);

  stop = clock();
  t = (double) (stop-start)/CLOCKS_PER_SEC;

  printf("Time BPDb8: %f \n\n", t); 

  //SNR
  for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/eindb8.fits", filetype_img);

   //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/eindb8res.fits", filetype_img);

  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/eindb8error.fits", filetype_img);

  printf("**********************\n");
  printf("RWBPDb8 reconstruction\n");
  printf("**********************\n");

  

  //Structure for the RWL1 solver    
  param5.verbose = 2;
  param5.max_iter = 5;
  param5.rel_var = 0.001;
  param5.sigma = sigma*sqrt((double)Ny/(double)Nx);
  param5.init_sol = 1;

  
  assert((start = clock())!=-1);
  sopt_l1_rwsdmm((void*)xoutc, Nx,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   &sopt_sara_synthesisop,
                   datas1,
                   &sopt_sara_analysisop,
                   datas1,
                   Nx,
                   (void*)y, Ny, param4, param5);

  stop = clock();
  t = (double) (stop-start)/CLOCKS_PER_SEC;

  printf("Time RWBPDb8: %f \n\n", t); 

  

    //SNR
    for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwdb8.fits", filetype_img);

   //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwdb8res.fits", filetype_img);

  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwdb8error.fits", filetype_img);



  printf("**********************\n");
  printf("BP reconstruction\n");
  printf("**********************\n");

  param4.gamma = gamma*aux1;

  //Initial solution
  for (i=0; i < Nx; i++) {
      xoutc[i] = 0.0 + 0.0*I;
  }

  assert((start = clock())!=-1);
  sopt_l1_sdmm((void*)xoutc, Nx,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   &sopt_sara_synthesisop,
                   datas2,
                   &sopt_sara_analysisop,
                   datas2,
                   Nx,
                   (void*)y, Ny, w, param4); 

  stop = clock();
  t = (double) (stop-start)/CLOCKS_PER_SEC;

  printf("Time BP: %f \n\n", t); 

  //SNR
  for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einbp.fits", filetype_img);

   //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einbpres.fits", filetype_img);

  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/einbperror.fits", filetype_img);

  printf("**********************\n");
  printf("RWBP reconstruction\n");
  printf("**********************\n");

  

  //Structure for the RWL1 solver    
  param5.verbose = 2;
  param5.max_iter = 5;
  param5.rel_var = 0.001;
  param5.sigma = sigma*sqrt((double)Ny/(double)Nx);
  param5.init_sol = 1;

  
  assert((start = clock())!=-1);
  sopt_l1_rwsdmm((void*)xoutc, Nx,
                   &purify_measurement_cftfwd,
                   datafwd,
                   &purify_measurement_cftadj,
                   dataadj,
                   &sopt_sara_synthesisop,
                   datas2,
                   &sopt_sara_analysisop,
                   datas2,
                   Nx,
                   (void*)y, Ny, param4, param5);

  stop = clock();
  t = (double) (stop-start)/CLOCKS_PER_SEC;

  printf("Time RWBP: %f \n\n", t); 

  

    //SNR
    for (i=0; i < Nx; i++) {
        error[i] = creal(xoutc[i])-xout[i];
    }
    mse = cblas_dnrm2(Nx, error, 1);
    a = cblas_dnrm2(Nx, xout, 1);
    snr_out = 20.0*log10(a/mse);
    printf("SNR: %f dB\n\n", snr_out);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xoutc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwbp.fits", filetype_img);

   //Residual image

  purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd);
  alpha = -1.0 +0.0*I;
  cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1);
  purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj);

  for (i=0; i < Nx; i++){
    img_copy.pix[i] = creal(xinc[i]);
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwbpres.fits", filetype_img);

  //Error image
  for (i=0; i < Nx; i++){
    img_copy.pix[i] = error[i];
  }
  
  purify_image_writefile(&img_copy, "data/test/einrwbperror.fits", filetype_img);


  
  
  //Free all memory
  purify_image_free(&img);
  purify_image_free(&img_copy);
  free(deconv);
  purify_visibility_free(&vis_test);
  free(y);
  free(xinc);
  free(xout);
  free(w);
  free(noise);
  free(y0);
  free(error);
  free(xoutc);
  free(wdx);
  free(wdy);

  sopt_sara_free(&param1);
  sopt_sara_free(&param2);
  sopt_sara_free(&param3);
  free(dict_types);
  free(dict_types1);
  free(dict_types2);

  free(fft_temp1);
  free(fft_temp2);
  fftw_destroy_plan(planfwd);
  fftw_destroy_plan(planadj);
  purify_sparsemat_freer(&gmat);

  free(dummyr);
  free(dummyc);


  return 0;

}
Beispiel #14
0
void CBlasMath::generatePlans()
{
    unsigned int plannerMode = FFTW_EXHAUSTIVE;
    int minN = 2;
    int maxN = 1024;

    if(qApp) // test we have are in a gui env
    {
        QProgressDialog progress("CBlas Math Plugin is tuning fftw ...", "Abort", minN, maxN);
        progress.setMinimumDuration(0);
        progress.setWindowModality(Qt::WindowModal);
        progress.show();

        for(int n = minN; n <= maxN; n++)
        {
            progress.setValue(n);
            progress.setLabelText("Tuning fftw for matrix size " + QString::number(n) + " ...");
            fftw_complex *in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n * n);
            fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n * n);

            qApp->processEvents();
            fftw_plan pf = fftw_plan_dft_2d(n, n, in, out, FFTW_FORWARD, plannerMode);
            if (progress.wasCanceled())
                         break;

            qApp->processEvents();
            fftw_plan pb = fftw_plan_dft_2d(n, n, in, out, FFTW_BACKWARD, plannerMode);
            if (progress.wasCanceled())
                         break;

            fftw_destroy_plan(pf);
            fftw_destroy_plan(pb);
            fftw_free(in);
            fftw_free(out);
        }
    }
    else
    {
//        std::cout << "CBlas Math Plugin is tuning fftw ... (press ENTER to cancel)"  << std::endl;
//        for(int n = minN; n <= maxN; n++)
//        {
//            std::cout << '\xd' << "Tuning fftw for matrix size " << n;
//            //std::cout << std::endl << "Tuning fftw for matrix size" << n;
//            fftw_complex *in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n * n);
//            fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n * n);

//            if(cinThread.isFinished())
//                break;
//            fftw_plan pf = fftw_plan_dft_2d(n, n, in, out, FFTW_FORWARD, plannerMode);

//            if(cinThread.isFinished())
//                break;
//            fftw_plan pb = fftw_plan_dft_2d(n, n, in, out, FFTW_BACKWARD, plannerMode);

//            fftw_destroy_plan(pf);
//            fftw_destroy_plan(pb);
//            fftw_free(in);
//            fftw_free(out);
//        }
//        std::cout << std::endl << "Done!" << std::endl;
    }
}
Beispiel #15
0
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);
}
Beispiel #16
0
void sepdiv3dD(double *rk, float *x, int *ijkx, int *ijky, int *ijkz, int nx,int ny,int nz,int m,int n, int iflag)
/*< sepdiv3d: separating wave-modes based on divergence >*/
{
       int i, im, jm, ikx, iky, ikz, nxz;

	   nxz=nx*nz;
#ifdef SF_HAS_FFTW  // using FFTW in Madagascar
 
       sf_complex *xin, *xout;

       fftwf_plan xp;
       fftwf_plan xpi;

       xin=sf_complexalloc(m);
       xout=sf_complexalloc(n);

       xp=fftwf_plan_dft_3d(ny,nx,nz, (fftwf_complex *) xin, (fftwf_complex *) xout,
			    FFTW_FORWARD,FFTW_ESTIMATE);

       xpi=fftwf_plan_dft_3d(ny,nx,nz,(fftwf_complex *) xin, (fftwf_complex *) xout,
			    FFTW_BACKWARD,FFTW_ESTIMATE);

       /* FFT: from (y,x,z) to (ky, 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);
           
       /* IFFT from (ky, kx, kz) to (y, x, z) domain*/
       // Note: Spectrum of the operator is differently orderred as the spectrum after FFT
	   i=0;
       for(iky=0;iky<ny;iky++)
       {
          int iyxnz=ijky[iky]*nxz;
          for(ikx=0;ikx<nx;ikx++)
          {
             int ixnz=iyxnz+ijkx[ikx]*nz;
             for(ikz=0;ikz<nz;ikz++)
             {
                xin[i]=(float)rk[ixnz+ijkz[ikz]]*xout[i];          
                i++;
             }
		  }
	   }
       // (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
       //sf_warning("============= using user installed FFTW ====");

       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);

       /* 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);

       /* Note: Spectrum of the operator is differently orderred as the spectrum after FFT */ 
       /* IFFT from (ky, kx, kz) to (y, x, z) domain*/
	   i=0;
       for(iky=0;iky<ny;iky++)
       {
          int iyxnz=ijky[iky]*nxz;
          for(ikx=0;ikx<nx;ikx++)
          {
              int ixnz=iyxnz+ijkx[ikx]*nz;
              for(ikz=0;ikz<nz;ikz++)
              {
                xin[i]=(float)rk[ixnz+ijkz[ikz]]*xout[i];          
                i++;
              }
		  }
	   }
       /* (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
}
Beispiel #17
0
float *bs_ave(float *images, float *win, slaveinfo l, long *index,
	      long bs_cnt, float *bsc, float *wc, float *amp, int maxk,
	      int *shifts)
{
    long i, j, k, m;		// loop & helper variables
    long i1, i2, i3;		// index variables
    double t1, t2, t3, t4;	// temporary real variables
    float ct1[2], ct2[2];	// temporary complex variables
    long nx, ny, nxh, nyh;	// half of subfield size
    long nfr, N, cnt;		// # of pixels in one image, loop variable
    double s = 0;		// mean intensity in image
    long u1, u2, v1, v2;	// bispectrum vectors
    fftw_complex *im1;		// temporary matrices
    fftw_complex *im2;
    float *bsr, *bsi;		// used for calculation of SNR
    float *origin;		// phase values around origin (needed for init)

    fftw_plan fftimage;		// plan for fourier transform

    nfr = l.nrofframes;
    nx = l.sfsizex;
    ny = l.sfsizey;
    nxh = nx / 2;
    nyh = ny / 2;
    N = nx * ny;       // subfield size in pixels

    origin = (float *) calloc(2 * maxk, sizeof(float));

    im1 = fftw_malloc(N * sizeof(fftw_complex));
    im2 = fftw_malloc(N * sizeof(fftw_complex));

    // setting up resultant matrices
    bsr = (float *) calloc(bs_cnt, sizeof(float));
    bsi = (float *) calloc(bs_cnt, sizeof(float));

    fftimage = fftw_plan_dft_2d(nx, ny, im1, im2, -1, FFTW_ESTIMATE);

	for (k = 0; k < nfr; k++) {
		// set a helper index
		m = k * N;
		// Calculate the mean of the image
		stats(&images[m], N, 0, &s, NULL);
		// store the windowed image in image1
		for (j = 0; j < ny; j++) {
			for (i = 0; i < nx; i++) {
				idx(i, j, nx, i1);
				im1[i1][0] = (double) ((images[i1 + m] - s) * win[i1] + s);  // problem here, with image
				im1[i1][1] = 0.0;

			}
		}
		// a) do FFT(imagei,-1)
		//    write the result into im2 (see fftw_plan fftimage)
		// b) shift the image, so low frequencies are in the origin
		//    write the results back into im1, scaled with
		//    1/(nx*ny) (not done by FFTW but by IDL does, thanks
		//    Alexandra Tritschler for the hint!)
		fftw_execute(fftimage);
		for (j = 0; j < ny; j++) {		// iterates through subfield pixels
			for (i = 0; i < nx; i++) {
				idx(i, j, nx, i1);		// jump to pixel position
				shift_idx(i, j, nxh, nyh, nx, ny, i2);
				im1[i1][0] = im2[i2][0] / N;		// complex part
				im1[i1][1] = im2[i2][1] / N;		// imaginary part
				amp[i1] +=
					(float) (sqrt
						 (im1[i1][0] * im1[i1][0] +			// why are these so large??
						  im1[i1][1] * im1[i1][1]) / nfr);
			}
		}
		// phase around origin
		for (cnt = 0; cnt < maxk; cnt++) {
			idx(nxh + shifts[2 * cnt], nyh + shifts[2 * cnt + 1], nx, i1);
			origin[2 * cnt] += im1[i1][0];
			origin[2 * cnt + 1] += im1[i1][1];
		}
		// calculate the mean raw bispectrum fast in non redundant matrix
		for (cnt = 0; cnt < bs_cnt; cnt++) {
			// get vectors
			u1 = index[0 + cnt * 4];
			u2 = index[1 + cnt * 4];
			v1 = index[2 + cnt * 4];
			v2 = index[3 + cnt * 4];
			// get matrix indices of vectors
			idx(nxh - u1, nyh + u2, nx, i1);
			idx(nxh - v1, nyh + v2, nx, i2);
			idx(nxh - u1 - v1, nyh + u2 + v2, nx, i3);
			// calculate bispectrum i(u)*i(v)*conj(i(u+v))
			//   (a+ib)(c+id)=((ac-bd)+i(bc+ad))
			ct1[0] = im1[i1][0] * im1[i2][0] - im1[i1][1] * im1[i2][1];
			ct1[1] = im1[i1][1] * im1[i2][0] + im1[i1][0] * im1[i2][1];
			//   (a+ib)(c-id)=((ac+bd)+i(bc-ad))
			ct2[0] = ct1[0] * im1[i3][0] + ct1[1] * im1[i3][1];
			ct2[1] = ct1[1] * im1[i3][0] - ct1[0] * im1[i3][1];
			// assign values
			bsc[2 * cnt] += ct2[0];
			//      bsc[2*cnt] += ct2[0]   // noise terms attached
			//         - ((im1[i1][0]*im1[i1][0] + im1[i1][1]*im1[i1][1])
			//           +(im1[i2][0]*im1[i2][0] + im1[i2][1]*im1[i2][1])
			//           +(im1[i3][0]*im1[i3][0] + im1[i3][1]*im1[i3][1]));
			bsc[2 * cnt + 1] += ct2[1];
			bsr[cnt] += bsc[2 * cnt] * bsc[2 * cnt];
			bsi[cnt] += bsc[2 * cnt + 1] * bsc[2 * cnt + 1];
		}
	}

    // phase around origin is averaged and normalized
    for (cnt = 0; cnt < maxk; cnt++) {
		t1 = cmod(&origin[2 * cnt]);
		origin[2 * cnt] /= t1;
		origin[2 * cnt + 1] /= t1;
    }

    // create bispectrum SNR (weights) and mean in non-redundant matrices
	for (cnt = 0; cnt < bs_cnt; cnt++) {
		// calculate SNR
		// sum of 2 normally - distributed random variables (real & imaginary part)
		t1 = bsc[2 * cnt] / nfr;
		t1 *= t1;		// (squared) mean real part
		t2 = bsc[2 * cnt + 1] / nfr;
		t2 *= t2;		// (squared) mean imaginary part
		t3 = fabs(bsr[cnt] - nfr * t1) / (nfr - 1);	// variance of real part
		t4 = fabs(bsi[cnt] - nfr * t2) / (nfr - 1);	// variance of imaginary part
		wc[cnt] = (float) sqrt(t1 + t2) * sqrt(nfr) / sqrt(t3 + t4);	// => SNR of MEAN absolute

			// make mean and normalize the phases if nonzero
		if ((bsc[2 * cnt] != 0.0) || (bsc[2 * cnt + 1] != 0.0)) {
			t1 = cmod(&bsc[2 * cnt]);
			bsc[2 * cnt] /= t1;
			bsc[2 * cnt + 1] /= t1;
		}
    }

    fftw_free(im1);
    fftw_free(im2);
    free(bsr);
    free(bsi);

    fftw_cleanup();

    return (origin);
}
void test03 ( void )

/******************************************************************************/
/*
  Purpose:

    TEST03: apply FFT to complex 2D data.

  Discussion:

    In this example, we generate NX=8 by NY=10 random complex values 
    stored as an NX by NY array of type FFTW_COMPLEX named "IN".

    We have FFTW3 compute the Fourier transform of this data named "OUT".

    We have FFTW3 compute the inverse Fourier transform of "OUT" to get
    "IN2", which should be the original input data, scaled by NX * NY.

    For a 2D complex NX by NY array used by FFTW, we need to access elements
    as follows:

      a[i*ny+j][0] is the real      part of A(I,J).
      a[i*ny+j][1] is the imaginary part of A(I,J)..

  Modified:

    05 November 2007

  Author:

    John Burkardt
*/
{
  int i;
  fftw_complex *in;
  fftw_complex *in2;
  int j;
  int nx = 8;
  int ny = 10;
  fftw_complex *out;
  fftw_plan plan_backward;
  fftw_plan plan_forward;
  unsigned int seed = 123456789;

  printf ( "\n" );
  printf ( "TEST03\n" );
  printf ( "  Demonstrate FFTW3 on a %d by %d array of complex data.\n",
    nx, ny );
  printf ( "\n" );
  printf ( "  Transform data to FFT coefficients.\n" );
  printf ( "  Backtransform FFT coefficients to recover data.\n" );
  printf ( "  Compare recovered data to original data.\n" );
/*
  Create the input array.
*/
  in = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );

  srand ( seed );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      in[i*ny+j][0] = frand ( );
      in[i*ny+j][1] = frand ( );
    }
  }

  printf ( "\n" );
  printf ( "  Input Data:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f  %12f\n", i, j, in[i*ny+j][0], in[i*ny+j][1] );
    }
  }
/*
  Create the output array.
*/
  out = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );

  plan_forward = fftw_plan_dft_2d ( nx, ny, in, out, FFTW_FORWARD, 
    FFTW_ESTIMATE );

  fftw_execute ( plan_forward );

  printf ( "\n" );
  printf ( "  Output FFT Coefficients:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f  %12f\n", i, j, out[i*ny+j][0], out[i*ny+j][1] );
    }
  }
/*
  Recreate the input array.
*/
  in2 = fftw_malloc ( sizeof ( fftw_complex ) * nx * ny );

  plan_backward = fftw_plan_dft_2d ( nx, ny, out, in2, FFTW_BACKWARD, 
    FFTW_ESTIMATE );

  fftw_execute ( plan_backward );

  printf ( "\n" );
  printf ( "  Recovered input data divided by NX * NY:\n" );
  printf ( "\n" );

  for ( i = 0; i < nx; i++ )
  {
    for ( j = 0; j < ny; j++ )
    {
      printf ( "  %4d  %4d  %12f  %12f\n",  i, j,
      in2[i*ny+j][0] / ( double ) ( nx * ny ),
      in2[i*ny+j][1] / ( double ) ( nx * ny ) );
    }
  }
/*
  Free up the allocated memory.
*/
  fftw_destroy_plan ( plan_forward );
  fftw_destroy_plan ( plan_backward );

  fftw_free ( in );
  fftw_free ( in2 );
  fftw_free ( out );

  return;
}
void spinsfast_backward_transform(fftw_complex  *f, int Ntheta, int Nphi, int lmax, fftw_complex *Gmm) {
  // f is Ntheta by Nphi, access f[ itheta * Nphi + iphi ].
  // F is  version of f extended to the whole sphere
  // Works for pixelization where first ring is north pole and the last ring is the south pole
  // ie theta = itheta*pi/(Ntheta-1)
  //    phi   = iphi*pi/Nphi
  //
  // The number of theta rows in the extended version of F is 2*(Ntheta-1) 
  int itheta, iphi;
  int m,mp;
  fftw_complex *F = fftw_malloc(2*(Ntheta-1)*Nphi*sizeof(fftw_complex));
  
  int NF = 2*(Ntheta-1)*Nphi;
  for (m=0;m<NF;m++) 
    F[m] = 0;
  
  // copy Imm values into F;
  
  int Nm = 2*lmax + 1 ;  
  int limit = lmax;
  
  if ( 2*limit+1 > Nphi   ) {
    printf("backtrans Nphi warning\n");
    limit = (Nphi-1)/2;
  }
  if ( 2*limit+1 > 2*(Ntheta-1) ) {
    printf("backtrans Ntheta warning\n");
    limit = Ntheta-3;
  }  


  for (mp=0;mp<=limit;mp++) {
    for (m=0;m<=limit;m++) {
      
      // ++
      F[ mp * Nphi + m] = Gmm[ mp * Nm + m ] ;
      
      // +-
      if (m > 0)
	F[ mp * Nphi + (Nphi - m) ] =	Gmm[ mp * Nm + (Nm - m)];
      
      // -+
      if (mp > 0) 
	F[ (2*(Ntheta-1) - mp) * Nphi + m ] = Gmm[ (Nm - mp) * Nm + m];
      
      // --
      if ( (mp > 0) && (m > 0) )
	F[ (2*(Ntheta-1) - mp) * Nphi + (Nphi - m) ] = Gmm[ (Nm - mp) * Nm + (Nm - m)];

    }
  }
  
  //    printf("Ntheta Nphi = %d %d\n",Ntheta,Nphi);
  //  printf ("dumping F status = %d\n", dump_cimage(F,2*(Ntheta-1),Nphi,"!output/eff.fits"));


  fftw_plan fftplan = fftw_plan_dft_2d( 2*(Ntheta-1),Nphi, F, F, FFTW_BACKWARD, FFTW_ESTIMATE);
  fftw_execute(fftplan);
  fftw_destroy_plan(fftplan);

  
  //printf ("dumping F status = %d\n", dump_cimage(F,2*(Ntheta-1),Nphi,"!output/EFF.fits"));

  
  for (itheta = 0; itheta < Ntheta; itheta++) {
    for (iphi = 0; iphi < Nphi; iphi++) {
      
      f[ itheta * Nphi + iphi ] =  F [ itheta * Nphi + iphi ];
      
    }
  }
  
  fftw_free(F);

}
Beispiel #20
0
struct Peak Find_FFT(IplImage* src, IplImage* tpl, int hamming)
{
	int i, j, k = 0;
	double tmp; //To store the modulus temporarily

	//src and tpl must be the same size
	assert(src->width == tpl->width);
	assert(src->height == tpl->height);

	// Get image properties
	int width    = src->width;
	int height   = src->height;
	int step     = src->widthStep;
	int fft_size = width * height;
	
	fftw_init_threads(); //Initialize FFTW for multithreading with a max number of 2 threads (more is not efficient)
	fftw_plan_with_nthreads(2);
	
	//Allocate arrays for FFT of src and tpl
	fftw_complex *src_spatial = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );
	fftw_complex *src_freq = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );
	
	fftw_complex *tpl_spatial = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );
	fftw_complex *tpl_freq = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );

	fftw_complex *res_spatial = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height ); //Result = Cross correlation
	fftw_complex *res_freq = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * width * height );

	// Setup pointers to images
	uchar *src_data = (uchar*) src->imageData;
	uchar *tpl_data = (uchar*) tpl->imageData;

	// Fill the structure that will be used by fftw
	for(i = 0; i < height; i++)
	{
		for(j = 0 ; j < width ; j++, k++)
		{
			src_spatial[k][0] = (double) src_data[i * step + j];
			src_spatial[k][1] =  0.0;

			tpl_spatial[k][0] = (double) tpl_data[i * step + j];
			tpl_spatial[k][1] =  0.0;
		}
	}
	
	// Hamming window to improve FFT (but slightly slower to compute)
	if(hamming == 1)
	{
		double omega = 2.0*M_PI/(fft_size-1);
		double A= 0.54;
		double B= 0.46;
		for(i=0,k=0;i<height;i++)
		{
			for(j=0;j<width;j++,k++)
			{
			    src_spatial[k][0]= (src_spatial[k][0])*(A-B*cos(omega*k));
			    tpl_spatial[k][0]= (tpl_spatial[k][0])*(A-B*cos(omega*k));
			}
		}
	}

	// Setup FFTW plans
	fftw_plan plan_src = fftw_plan_dft_2d(height, width, src_spatial, src_freq, FFTW_FORWARD, FFTW_ESTIMATE);
	fftw_plan plan_tpl = fftw_plan_dft_2d(height, width, tpl_spatial, tpl_freq, FFTW_FORWARD, FFTW_ESTIMATE);
	fftw_plan plan_res = fftw_plan_dft_2d(height, width, res_freq,  res_spatial,  FFTW_BACKWARD, FFTW_ESTIMATE);

	// Execute the FFT of the images
	fftw_execute(plan_src);
	fftw_execute(plan_tpl);

	// Compute the cross-correlation
	for(i = 0; i < fft_size ; i++ )
	{
		res_freq[i][0] = tpl_freq[i][0] * src_freq[i][0] + tpl_freq[i][1] * src_freq[i][1];
		res_freq[i][1] = tpl_freq[i][0] * src_freq[i][1] - tpl_freq[i][1] * src_freq[i][0];
		
		tmp = sqrt(pow(res_freq[i][0], 2.0) + pow(res_freq[i][1], 2.0));

		res_freq[i][0] /= tmp;
		res_freq[i][1] /= tmp;
	}

	// Get the phase correlation array = compute inverse fft
	fftw_execute(plan_res);

	// Find the peak
	struct Peak pk;	
	IplImage* peak_find = cvCreateImage(cvSize(tpl->width,tpl->height ), IPL_DEPTH_64F, 1);
	double  *peak_find_data = (double*) peak_find->imageData;
	
	for( i = 0 ; i < fft_size ; i++ )
	{
        peak_find_data[i] = res_spatial[i][0] / (double) fft_size;
    }
    
    CvPoint minloc, maxloc;
    double  minval, maxval;
    
    cvMinMaxLoc(peak_find, &minval, &maxval, &minloc, &maxloc, 0);
    
	pk.pt = maxloc;
	pk.maxval = maxval;

	// Clear memory
	fftw_destroy_plan(plan_src);
	fftw_destroy_plan(plan_tpl);
	fftw_destroy_plan(plan_res);
	fftw_free(src_spatial);
	fftw_free(tpl_spatial);
	fftw_free(src_freq);
	fftw_free(tpl_freq);
	fftw_free(res_spatial);
	fftw_free(res_freq);
	cvReleaseImage(&peak_find);
	
	fftw_cleanup_threads(); //Cleanup everything else related to FFTW
	
	return pk;
}
Beispiel #21
0
int main(int argc, char * argv[])
{
  // main function to set up the components.  All of this work would be done in Python apart from
  // the GenerateModel function

  // Check we have enough cline-args
  if(argc!=8)
  {
	  printf("This program must be run with file command-line arguments:");
	  printf("eg. ./Inclined_Exponential_Profile <n> <i> <R> <h> <t> <p> <output_name>");
      fflush(stdout);
	  return 1;
  }

  double sersic_n = strtod(argv[1], NULL);
  double inc_angle = strtod(argv[2], NULL);
  double scale_radius = strtod(argv[3], NULL);
  double scale_height = strtod(argv[4], NULL);
  double trunc_factor = strtod(argv[5], NULL);
  double pos_angle = strtod(argv[6], NULL);
  char * output_name = argv[7];

  printf("Sersic Index: %1.1f\n",sersic_n);
  printf("Inclination angle: %1.4f\n",inc_angle);
  printf("Scale radius: %3.2f\n",scale_radius);
  printf("Scale height: %3.2f\n",scale_height);
  printf("Truncation factor: %3.2f\n",trunc_factor);
  printf("Position angle: %1.4f\n",pos_angle);
  fflush(stdout);

  fftw_complex *pixelaverageft, *convmodelft, *PSFft, *dsmodelft, *dsmodel, *xshiftft, *yshiftft;
  double *pixelaverage, *image;
  double rfiducial, sum;
  float **rmodelft, *resampledmodelft, *thickdiskft;
  time_t t1, t2;
  int i, num, x, y, ip;
  int p;
  int hos;
  fftw_plan pixavplan, invplan;

  /* ******************************* */
  // step one:
  // make a circular galaxy surface brighness distribution and r2c FT it
  // this step is done once only at the start of the code, for each Sersic index
  // that we wish to simulate
  int mdim, hmdim, nsersic;
  double *model;
  fftw_complex *modelft;
  fftw_plan bigmodel;
  // set the dimension of the large input circular galaxy.  Note that this must be a large
  // value e.g. 16384 in order to avoid aliasing
  mdim = 16384;
  hmdim = 1 + mdim/2;
  model = (double*)calloc(mdim*mdim, sizeof(double));
  modelft = (fftw_complex*)fftw_malloc( mdim*hmdim*sizeof(fftw_complex) );
  bigmodel = fftw_plan_dft_r2c_2d(mdim, mdim, model, modelft, FFTW_ESTIMATE);
  // make a model with a nominal (fiducial) scalelength
  rfiducial = 30.;
  // make a set of models with different Sersic index values
  nsersic = 1;
  // store the real part of their fourier transform
  rmodelft = (float**)calloc(nsersic, sizeof(float*));
  for (i=0; i<nsersic; i++)
    {
      // allocate memory for this model FT
      rmodelft[i] = (float*)calloc(hmdim, sizeof(float));
      // make a large circular galaxy profile
      makecirculargalaxy(sersic_n, rfiducial, trunc_factor, mdim, model);
      // FFT
      fftw_execute(bigmodel);
      // convert FT complex to float Hankel and store with separate index for each model component
      makehankel(modelft, hmdim, rmodelft[i]);
    }
  // free memory not needed
  free(model);
  free(modelft);
  /* *********************** */

  // set the galaxy parameters - these would be set by the MCMC routine
  double overgalsize = scale_radius*oversampling; // major axis scalelength in pixels in oversampled arrays
  if (overgalsize >= rfiducial/sqrt(2.))
    {
      fflush(stdout);
      fprintf(stderr," error in specifying galaxy size, must be smaller than fiducial size/sqrt(2)\n");
      exit(0);
    }
  double overscaleheight = scale_height*oversampling;
  double xpos = 0.*oversampling;   // x position offset in oversampled pixels
  double ypos = 0.*oversampling;  // y position offset in oversampled pixels

  // allocate oversampled arrays
  // in future, make a selection of sizes to be chosen appropriately
  // to optimise the speed for small galaxy model generation

  int idim, odim, hdim;
  odim = 2*(int)(32.*scale_radius/2.0*pow(sersic_n,2)) ;
  idim = odim*oversampling;  // size of oversampled galaxy image
  hdim = 1 + idim/2;  // x-axis dimension of FFTW hermitian array

  // odim = idim;

  // allocate memory
  // pixel average function and its FT
  pixelaverage = (double*)calloc( idim*idim,sizeof(double) );
  pixelaverageft = (fftw_complex*)fftw_malloc( idim*hdim*sizeof(fftw_complex) );
  // x,y shift FTs
  yshiftft = (fftw_complex*)fftw_malloc( idim*sizeof(fftw_complex) );
  xshiftft = (fftw_complex*)fftw_malloc( hdim*sizeof(fftw_complex) );
  // r2c FFT of convolved model, stored as float
  resampledmodelft = (float*)calloc( idim*hdim,sizeof(float) );
  // r2c FFT of PSF, stored as complex
  PSFft = (fftw_complex*)calloc( idim*hdim,sizeof(fftw_complex) );
  // r2c FFT of thick disk convolving function, stored as complex
  thickdiskft = (float*)calloc( idim*hdim,sizeof(float) );
  // r2c FFT of oversampled, convolved model, stored as complex
  convmodelft = (fftw_complex*)fftw_malloc( idim*hdim*sizeof(fftw_complex) );
  // full FFT of downsampled model
  dsmodelft = (fftw_complex*)fftw_malloc( odim*odim*sizeof(fftw_complex) );
  // complex downsampled image domain model
  dsmodel = (fftw_complex*)calloc( odim*odim,sizeof(fftw_complex) );
  //dsmodel = (double*)calloc( odim*odim,sizeof(double) );
  // real part of downsampeld image domain model
  image = (double*)calloc( odim*odim,sizeof(double) );

  // complex downsampled image domain model
  //fftw_complex* rsmodel = (fftw_complex*)calloc( idim*idim,sizeof(fftw_complex) );
  //double* rsimage = (double*)calloc( idim*idim,sizeof(double) );

  // calculate fftw plans
  // pixelaverage plan
  pixavplan = fftw_plan_dft_r2c_2d(idim, idim, pixelaverage, pixelaverageft, FFTW_ESTIMATE);
  // inverse downsampled image plan
  invplan = fftw_plan_dft_2d(odim, odim, dsmodelft, dsmodel, FFTW_BACKWARD, FFTW_MEASURE);
  //invplan = fftw_plan_dft_c2r_2d(odim, odim, convmodelft, dsmodel, FFTW_ESTIMATE);

  //fftw_plan invplan2 = fftw_plan_dft_2d(odim, odim, convmodelft, rsmodel, FFTW_BACKWARD, FFTW_ESTIMATE);

  // fill up pixelaverage function
  // this function would also only be calculated once at the start of the galaxy measurement
  // set all values to zero
  for (ip=0; ip<idim*idim; ip++)
    {
      pixelaverage[ip]=0.;
    }
  // set a central box to a tophat function which sums to unity
  // set it to be centred in the array so we don't need to swap quadrants at the end
  hos = oversampling/2;
  int cen = idim/2;
  for (y=cen-hos; y<=cen+hos; y++)
    {
      for (x=cen-hos; x<=cen+hos; x++)
        {
          ip = y*idim + x;
          pixelaverage[ip] = 1./(double)(oversampling*oversampling);
        }
    }
  // create FT of pixelaverage
  fftw_execute(pixavplan);


  // create the FT of the PSF.  For now, just set the PSF to be a delta function in image domain
  // i.e. a uniform function in the Fourier domain
  // this function would be filled once for each galaxy component
  for (i=0; i<idim*hdim; i++) PSFft[i] = pixelaverageft[i];

  // choose which sersic index to make
  int sersicindex = 0; // this will make value of sersic index = 1

  double sini = sin(inc_angle);
  double sini_squared = sini*sini;

  double emod;

  if(sini_squared==0)
  {
	  emod = 0.;
  }
  else
  {
	  emod = (2. - sini_squared + 2*sqrt(1-sini_squared))/sini_squared;
  }

  double e1 = emod * cos(2*pos_angle);
  double e2 = emod * sin(2*pos_angle);

  // optional: run a timing test using a loop by setting a high value for num
  num = 1;
  t1 = time(NULL);
  int odimsq = odim*odim;
  for (i=0; i<num; i++)
    {

      /* ********************************************** */
      // this is the call to the C function that
      // generates a downsampled FT of galaxy model
      GenerateModel(e1, e2, overgalsize, overscaleheight, xpos, ypos, rfiducial, odim,
                    idim, mdim, rmodelft[sersicindex], resampledmodelft,
                    PSFft, thickdiskft, xshiftft, yshiftft, convmodelft, dsmodelft);
      /* ********************************************** */

      /* the following sections are all back in the Python function.
         in principle we could do the iFFT step inside the C function but this probably
         does not improve the speed and would mean also passing an fftw_plan into the C function */

      // make downsampled image inverse FFT
      fftw_execute(invplan);

      // take the real part (discard the imaginary part) and scale
      for (p=0; p<odimsq; p++)
        {
          image[p] = creal(dsmodel[p])/(odim*odim);
        }

      // end of timing loop
    }
  t2 = time(NULL);
  if (num>1)
    {
      printf(" time %g \n",difftime(t2,t1)/num);
    }


  sum = 0.;
  // take the real part (discard the imaginary part) and test the normalisation
  for (p=0; p<odimsq; p++)
    {
      sum += image[p];
    }
  printf(" sum %g \n",sum);

  // write out final output image to fits file
  remove(output_name);
  write2Dfits(output_name,image,odim,odim);

  exit(0);
}
Beispiel #22
0
void FFT(Matrix < Complex > &min, Matrix < Complex > &mout, int direction, int dccenter)
{
    assert(min.GetCols() == min.GetRows());     // square matrix
    assert(mout.GetCols() == mout.GetRows());
    assert(mout.GetCols() == min.GetRows());
    int nfft = min.GetCols();

    fftw_complex *in =
        (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nfft * nfft);
    fftw_complex *out =
        (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nfft * nfft);

    for (int iy = 0; iy < nfft; iy++)
    {
        for (int ix = 0; ix < nfft; ix++)
        {
            in[ix + nfft * iy][0] = min[ix][iy].real();
            in[ix + nfft * iy][1] = min[ix][iy].imag();
        }
    }

    fftw_plan p;

    if (direction >= 0)
        p = fftw_plan_dft_2d(nfft, nfft, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
    else
        p = fftw_plan_dft_2d(nfft, nfft, in, out, FFTW_BACKWARD,
                             FFTW_ESTIMATE);
    fftw_execute(p);
    fftw_destroy_plan(p);
    fftw_free(in);

    if (dccenter == 0)
    {
        for (int iy = 0; iy < nfft; iy++)
            for (int ix = 0; ix < nfft; ix++)
                mout[ix][iy]
                    = Complex(out[ix + nfft * iy][0], out[ix + nfft * iy][1])
                    / double (nfft);
    }
    else
    {
        for (int iy = 0; iy < nfft / 2; iy++)
        {
            for (int ix = 0; ix < nfft / 2; ix++)
            {
                mout[ix][iy] =
                    Complex(out[nfft / 2 + ix + nfft * (iy + nfft / 2)][0],
                            out[nfft / 2 + ix +
                                nfft * (iy + nfft / 2)][1]) / double (nfft);
            }

            for (int ix = nfft / 2; ix < nfft; ix++)
            {
                mout[ix][iy] =
                    Complex(out[ix - nfft / 2 + nfft * (iy + nfft / 2)][0],
                            out[ix - nfft / 2 +
                                nfft * (iy + nfft / 2)][1]) / double (nfft);
            }
        }

        for (int iy = nfft / 2; iy < nfft; iy++)
        {
            for (int ix = 0; ix < nfft / 2; ix++)
            {
                mout[ix][iy] =
                    Complex(out[ix + nfft / 2 + nfft * (iy - nfft / 2)][0],
                            out[ix + nfft / 2 +
                                nfft * (iy - nfft / 2)][1]) / double (nfft);
            }

            for (int ix = nfft / 2; ix < nfft; ix++)
            {
                mout[ix][iy] =
                    Complex(out[ix - nfft / 2 + nfft * (iy - nfft / 2)][0],
                            out[ix - nfft / 2 +
                                nfft * (iy - nfft / 2)][1]) / double (nfft);
            }
        }
    }
    fftw_free(out);

}