int main(int argc, char **argv)
{
int N = (argc >= 2) ? atoi(argv[1]) : 64;     // size of image
int n1 = (argc >= 3) ? atoi(argv[2]) : 1000;  // times to try


// input is NxN real numbers
int M = N*(N/2+1);  // output is this many complex numbers
double *in1 = (double *)fftw_malloc(sizeof(double) * N*N);
double *in2 = (double *)fftw_malloc(sizeof(double) * N*N);
double *out = (double *)fftw_malloc(sizeof(double) * N*N);
CD *out1 = (CD*) fftw_malloc(sizeof(CD) * M);
CD *out2 = (CD*) fftw_malloc(sizeof(CD) * M);

// make up some data
for(int i=0; i<N*N; i++) {
    in1[i] = rand()/1000000000.0;
    in2[(i+2*N+3)%(N*N)] = in1[i];    // offsets should be 3 and 2 pixels
    //in2[i] = in1[i];
    }

fftw_plan p1, p2, p3;
p1 = fftw_plan_dft_r2c_2d( N, N, in1, (double (*)[2])out1, FFTW_ESTIMATE );
p2 = fftw_plan_dft_r2c_2d( N, N, in2, (double (*)[2])out2, FFTW_ESTIMATE );
p3 = fftw_plan_dft_c2r_2d( N, N, (double (*)[2])out1, out, FFTW_ESTIMATE );

double big;
int bigj;
printf("Starting %d passes\n", n1);
for(int i=0; i<n1; i++) {
    fftw_execute(p1); /* repeat as needed */
    fftw_execute(p2);
    for(int j=0; j<M; j++)
	out1[j] = out1[j]*conj(out2[j]);
    fftw_execute(p3);
    big=-1.0E30;
    bigj = -1;
    for(int j=0; j<N*N; j++) {
	if( out[j] > big ) {
	   big = out[j];
           bigj = j;
           }
        }
    }
int x = bigj/N;
int y = bigj - N*x;
if (x > N/2) x -= N;
if (y > N/2) y -= N;
printf("x,y %d %d\n", x, y);
fftw_destroy_plan(p1);
fftw_destroy_plan(p2);
fftw_destroy_plan(p3);
return 0;
}
Exemple #2
0
// Fourier transform from (complex) k to x:
xTable*
kTable::Transform() const {
  // We'll need a new k array because FFTW kills the k array in this
  // operation.  Also, to put x=0 in center of array, we need to flop
  // every other sign of k array, and need to scale.

  DComplex* t_array = 
    (DComplex*) fftw_malloc(sizeof(DComplex)*N*(N/2+1));
  double fac = scaleby * dk * dk / (4*PI*PI);
  long int ind=0;
  for (int i=0; i<N; i++)
    for (int j=0; j<=N/2; j++) {
      if ( (i+j)%2==0) t_array[ind]=fac * array[ind];
      else t_array[ind] = -fac* array[ind];
      ind++;
    }

  xTable *xt = new xTable( N, 2*PI/(N*dk) );

  fftw_plan plan = 
    fftw_plan_dft_c2r_2d(N, N,
			 reinterpret_cast<fftw_complex*> (t_array), xt->array,
			 FFTW_ESTIMATE);
  if (plan==NULL) throw FFTInvalid();

  // Run the transform:
  fftw_execute(plan);
  fftw_destroy_plan(plan);
  fftw_free(t_array);
  return xt;
}
void FFTConvolver::ConvolveSameSize(double* image, const double* kernel, size_t imgWidth, size_t imgHeight)
{
	const size_t imgSize = imgWidth * imgHeight;
	const size_t complexSize = (imgWidth/2+1) * imgHeight;
	double* tempData = reinterpret_cast<double*>(fftw_malloc(imgSize * sizeof(double)));
	fftw_complex* fftImageData = reinterpret_cast<fftw_complex*>(fftw_malloc(complexSize * sizeof(fftw_complex)));
	fftw_complex* fftKernelData = reinterpret_cast<fftw_complex*>(fftw_malloc(complexSize * sizeof(fftw_complex)));
	
	boost::mutex::scoped_lock lock(_mutex);
	fftw_plan inToFPlan = fftw_plan_dft_r2c_2d(imgHeight, imgWidth, tempData, fftImageData, FFTW_ESTIMATE);
	fftw_plan fToOutPlan = fftw_plan_dft_c2r_2d(imgHeight, imgWidth, fftImageData, tempData, FFTW_ESTIMATE);
	lock.unlock();
	
	memcpy(tempData, image, imgSize * sizeof(double));
	fftw_execute_dft_r2c(inToFPlan, tempData, fftImageData);
	
	memcpy(tempData, kernel, imgSize * sizeof(double));
	fftw_execute_dft_r2c(inToFPlan, tempData, fftKernelData);
	
	double fact = 1.0/imgSize;
	for(size_t i=0; i!=complexSize; ++i)
		reinterpret_cast<std::complex<double>*>(fftImageData)[i] *= fact * reinterpret_cast<std::complex<double>*>(fftKernelData)[i];
		
	fftw_execute_dft_c2r(fToOutPlan, reinterpret_cast<fftw_complex*>(fftImageData), tempData);
	memcpy(image, tempData, imgSize * sizeof(double));
		
	fftw_free(fftImageData);
	fftw_free(fftKernelData);
	fftw_free(tempData);
	
	lock.lock();
	fftw_destroy_plan(inToFPlan);
	fftw_destroy_plan(fToOutPlan);
	lock.unlock();
}
EXPORT void rgrid2d_fftw_alloc(rgrid2d *grid) {

  long s;
  double *plan_temp;

  s = 2 * grid->nx * (grid->ny/2 + 1);
  if(s > temp_len) {
    if(temp) free(temp);
    if(!(temp = fftw_malloc(sizeof(double) * s))) {
      fprintf(stderr, "libgrid: Out of memory in rgrid3d_fft().\n");
      return;
    }
    temp_len = s;
    temp2 = (double complex *) temp;
  }
  if(!(plan_temp = fftw_malloc(sizeof(double) * s))) {
    fprintf(stderr, "libgrid: Out of memory in rgrid2d_fft().\n");
    return;
  }

  memcpy(plan_temp, grid->value, sizeof(double) * s);
 
  fftw_plan_with_nthreads(grid_threads());

  grid->plan = 
    fftw_plan_dft_r2c_2d(grid->nx, grid->ny, grid->value, temp2, GRID_FFTW_PLAN | FFTW_DESTROY_INPUT);

  grid->iplan = 
    fftw_plan_dft_c2r_2d(grid->nx, grid->ny, grid->cint->value, temp, GRID_FFTW_PLAN | FFTW_DESTROY_INPUT);

  memcpy(grid->value, plan_temp, sizeof(double) * s);

  fftw_free(plan_temp);
}
void DeconvolutionTool::initFFT(const QImage *inputImage) {
    removeFFTObjects();
    QTime time;
    time.start();
    QString progressText = "Loading image";
    setProgressInterval(1,100, progressText);

    // Read image size
    width = inputImage->width();
    height = inputImage->height();

    // Init FFTW structures with given size
    inputImageMatrix = (double*) fftw_malloc(sizeof(double) * width * height);
    outputImageMatrix = (double*) fftw_malloc(sizeof(double) * width * height);
    kernelMatrix = (double*) fftw_malloc(sizeof(double) * width * height);
    // kernelTempMatrix = (double*)fftw_malloc(sizeof(double)*width*height);
    laplacianMatrix = (double*) fftw_malloc(sizeof(double) * width * height);
    outLaplacianMatrix = (double*) fftw_malloc(sizeof(double) * width * height);

    inputImageFFT = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (width/2+1) * height);
    outputImageFFT = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (width/2+1) * height);
    kernelFFT = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (width/2+1) * height);
    kernelTempFFT = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (width/2+1) * height);
    laplacianMatrixFFT = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (width/2+1) * height);
    setProgressSubValue(10);

    // Init FFTW plan to optimize speed - init once and use many times
    // Column-major Format used. When creating the plan, simply pass
    // the dimensions of the array to the planner in reverse order (width, height..) -> (height, width...)
    realForwardPlan = fftw_plan_dft_r2c_2d(height, width, inputImageMatrix, inputImageFFT, FFTW_MEASURE);
    setProgressSubValue(30);
    realForwardKernelPlan = fftw_plan_dft_r2c_2d(height, width, kernelMatrix, kernelFFT, FFTW_MEASURE);
    setProgressSubValue(50);
    realBackwardPlan = fftw_plan_dft_c2r_2d(height, width, inputImageFFT, outputImageMatrix, FFTW_MEASURE);
    setProgressSubValue(70);
    QApplication::processEvents();
    forwardLaplacianPlan = fftw_plan_dft_r2c_2d(height, width, laplacianMatrix, laplacianMatrixFFT, FFTW_MEASURE);
    setProgressSubValue(90);
    backwardLaplacianPlan = fftw_plan_dft_c2r_2d(height, width, laplacianMatrixFFT, outLaplacianMatrix, FFTW_MEASURE);
    setProgressSubValue(100);

    qDebug("initFFT: %d ms", time.elapsed());
}
void // x [m x n/2+1] -> r [m x n]
mad_cmat_irfft (const cnum_t x[], num_t r[], ssz_t m, ssz_t n)
{
  CHKXR;
  ssz_t nn = m*(n/2+1);
  mad_alloc_tmp(cnum_t, cx, nn);
  mad_cvec_copy(x, cx, nn);
  fftw_plan p = fftw_plan_dft_c2r_2d(m, n, cx, r, FFTW_ESTIMATE);
  fftw_execute(p);
  fftw_destroy_plan(p);
  mad_free_tmp(cx);
  mad_vec_muln(r, 1.0/(m*n), r, m*n);
}
void gravity_fft_init(void) {

	// dimension definition
	grid_NX_COMPLEX	= root_nx;		
	grid_NY_COMPLEX	= (root_ny / 2 + 1);
	grid_NCOMPLEX	= grid_NX_COMPLEX * grid_NY_COMPLEX;
	dx		= boxsize_x / root_nx;		
	dy		= boxsize_y / root_ny;	
	
	// Array allocation
	kx  = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX);
	ky  = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX);
	if (integrator == SEI){
		kxt = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX);
		w1d = (double *) fftw_malloc( sizeof(double) * root_ny * 2 );
	}else{
		kxt = kx; 	// No time dependent wave vectors.
	}
	k   = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX);
	density = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX * 2);
	density_r = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX * 2);
	fx  = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX * 2);
	fy  = (double *) fftw_malloc( sizeof(double) * grid_NCOMPLEX * 2);
	
	// Init wavevectors
	
	for(int i = 0; i < grid_NX_COMPLEX; i++) {
		for(int j =0; j < grid_NY_COMPLEX; j++) {
			int IDX2D = i * grid_NY_COMPLEX + j;
			kx[IDX2D] = (2.0 * M_PI) / boxsize_x * (
					fmod( (double) (i + (grid_NX_COMPLEX/2.0 )), (double) grid_NX_COMPLEX)
					 - (double) grid_NX_COMPLEX / 2.0 );
			ky[IDX2D] = (2.0 * M_PI) / boxsize_y * ((double) j);
			if (integrator != SEI){
				k[IDX2D]  = pow( kx[IDX2D]*kx[IDX2D] + ky[IDX2D] * ky[IDX2D], 0.5);
			
				// we will use 1/k, that prevents singularity 
				// (the k=0 is set to zero by renormalization...)
				if ( k[IDX2D] == 0.0 ) k[IDX2D] = 1.0; 
			}
		}
	}
	
	// Init ffts (use in place fourier transform for efficient memory usage)
	r2cfft = fftw_plan_dft_r2c_2d( root_nx, root_ny, density, (fftw_complex*)density, FFTW_MEASURE);
	c2rfft = fftw_plan_dft_c2r_2d( root_nx, root_ny, (fftw_complex*)density, density, FFTW_MEASURE);
	if (integrator == SEI){
		for1dfft = fftw_plan_dft_1d(root_ny, (fftw_complex*)w1d, (fftw_complex*)w1d, FFTW_FORWARD, FFTW_MEASURE);
		bac1dfft = fftw_plan_dft_1d(root_ny, (fftw_complex*)w1d, (fftw_complex*)w1d, FFTW_BACKWARD, FFTW_MEASURE);
	}
}
//--------------------------------------------------------------------
void fftw_c2r_2d(fftw_complex *in_fft, REAL *in_real, int nx, int ny) {

	int i,j;
	int index;

	REAL *in_real_tmp = (REAL *)malloc(nx*ny*sizeof(REAL));
	fftw_plan plbd;
	plbd = fftw_plan_dft_c2r_2d(nx, ny, in_fft, in_real_tmp, FFTW_ESTIMATE);
	fftw_execute(plbd);

	for(i=0;i<nx;i++) for(j=0;j<ny;j++) {
		index = i*ny+j;
		in_real[index] = in_real_tmp[index];
	}

	fftw_destroy_plan(plbd);
	free(in_real_tmp);
}
Exemple #9
0
    // Have FFTW develop "wisdom" on doing this kind of transform
    void KTable::fftwMeasure() const 
    {
        // Copy data into new array to avoid NaN's, etc., but not bothering
        // with scaling, etc.
        FFTW_Array<std::complex<double> > t_array = _array;

        XTable xt( _N, 2*M_PI/(_N*_dk) );

        // Note: The fftw_execute function is the only thread-safe FFTW routine.
        // So if we decide to go with some kind of multi-threading (rather than multi-process
        // parallelism) all of the plan creation and destruction calls in this file 
        // will need to be placed in critical blocks or the equivalent (mutex locks, etc.).
        fftw_plan plan = fftw_plan_dft_c2r_2d(
            _N, _N, t_array.get_fftw(), xt._array.get_fftw(), FFTW_MEASURE);
#ifdef FFT_DEBUG
        if (plan==NULL) throw FFTInvalid();
#endif
        fftw_destroy_plan(plan);
    }
Exemple #10
0
void init_gfft() {
	double complex *wi1;
	double *wir1;
	
	DEBUG_START_FUNC;
	
	wi1 = (double complex *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (wi1 == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for wi1 allocation");
	
	wir1 = (double *) wi1;
	
#ifdef _OPENMP
	fftw_plan_with_nthreads( nthreads );
#endif
	
#ifdef WITH_2D
	r2cfft = fftw_plan_dft_r2c_2d( NX, NY, wr1, w1,  FFT_PLANNING);
	if (r2cfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW R2C plan creation failed");

	c2rfft = fftw_plan_dft_c2r_2d( NX, NY, w1,  wr1, FFT_PLANNING);
	if (c2rfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW C2R plan creation failed");
#else
	r2cfft = fftw_plan_dft_r2c_3d( NX, NY, NZ, wr1, w1,  FFT_PLANNING);
	if (r2cfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW R2C plan creation failed");

	c2rfft = fftw_plan_dft_c2r_3d( NX, NY, NZ, w1,  wr1, FFT_PLANNING);
	if (c2rfft == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW C2R plan creation failed");
	
	r2cfft_2Dslice = fftw_plan_dft_r2c_2d(NX,NY,wrh3,wh3,FFT_PLANNING);
	if (r2cfft_2Dslice == NULL) ERROR_HANDLER( ERROR_CRITICAL, "FFTW r2c slice plan creation failed");

#endif

	
	fftw_free(wi1);
	
	fft_timer=0.0;
	
	DEBUG_END_FUNC;
	
	return;
}
Exemple #11
0
    // Fourier transform from (complex) k to x:
    // This version takes XTable reference as argument 
    void KTable::transform(XTable& xt) const 
    {
        check_array();

        // check proper dimensions for xt
        assert(_N==xt.getN());

        // We'll need a new k array because FFTW kills the k array in this
        // operation.  Also, to put x=0 in center of array, we need to flop
        // every other sign of k array, and need to scale.
        dbg<<"Before make t_array"<<std::endl;
        FFTW_Array<std::complex<double> > t_array(_N);
        dbg<<"After make t_array"<<std::endl;
        double fac = _dk * _dk / (4*M_PI*M_PI);
        long int ind=0;
        dbg<<"t_array.size = "<<t_array.size()<<std::endl;
        for (int iy=0; iy<_N; iy++) {
            dbg<<"ind = "<<ind<<std::endl;
            for (int ix=0; ix<=_N/2; ix++) {
                if ( (ix+iy)%2==0) t_array[ind]=fac * _array[ind];
                else t_array[ind] = -fac* _array[ind];
                ind++;
            }
        }
        dbg<<"After fill t_array"<<std::endl;

        fftw_plan plan = fftw_plan_dft_c2r_2d(
            _N, _N, t_array.get_fftw(), xt._array.get_fftw(), FFTW_ESTIMATE);
        dbg<<"After make plan"<<std::endl;
#ifdef FFT_DEBUG
        if (plan==NULL) throw FFTInvalid();
#endif

        // Run the transform:
        fftw_execute(plan);
        dbg<<"After exec plan"<<std::endl;
        fftw_destroy_plan(plan);
        dbg<<"After destroy plan"<<std::endl;

        xt._dx = 2*M_PI/(_N*_dk);
        dbg<<"Done transform"<<std::endl;
    }
Exemple #12
0
// Have FFTW develop "wisdom" on doing this kind of transform
void 
kTable::fftwMeasure() const {
  DComplex* t_array = 
    (DComplex*) fftw_malloc(sizeof(DComplex)*N*(N/2+1));
  // Copy data into new array to avoid NaN's, etc., but not bothering
  // with scaling, etc.
  for (int i=0; i<N*(N/2+1); i++)
    t_array[i] = array[i];

  xTable *xt = new xTable( N, 2*PI/(N*dk) );

  fftw_plan plan = 
    fftw_plan_dft_c2r_2d(N, N,
			 reinterpret_cast<fftw_complex*> (t_array), xt->array,
			 FFTW_MEASURE);
  if (plan==NULL) throw FFTInvalid();
  delete xt;
  fftw_free(t_array);
  fftw_destroy_plan(plan);
}
Exemple #13
0
static void initialize_circulant(hbhankel_matrix *h,
                                 const double *F,
                                 R_len_t Nx, R_len_t Ny,
                                 R_len_t Lx, R_len_t Ly) {
  R_len_t Kx = Nx - Lx + 1, Ky = Ny - Ly + 1, i, j;
  fftw_complex *ocirc;
  fftw_plan p1, p2;
  double *circ;

  /* Allocate needed memory */
  circ = (double*) fftw_malloc(Nx * Ny * sizeof(double));
  ocirc = (fftw_complex*) fftw_malloc(Ny * (Nx/2 + 1) * sizeof(fftw_complex));

  /* Estimate the best plans for given input length, note, that input data is
     stored in column-major mode, that's why we're passing dimensions in
     *reverse* order */
  p1 = fftw_plan_dft_r2c_2d(Ny, Nx, circ, ocirc, FFTW_ESTIMATE);
  p2 = fftw_plan_dft_c2r_2d(Ny, Nx, ocirc, circ, FFTW_ESTIMATE);

  /* Fill input buffer */
  /* TF <- cbind(F[,Ky:Ny],F[,1:(Ky-1)]);
     TF <- rbind(TF[Kx:Nx,],TF[1:(Kx-1),]); */
  for (j = 0; j < Ny; ++j)
    for (i = 0; i < Nx; ++i)
      /* This is pretty ad-hoc solution and needs to be fixed in the future */
      circ[i + Nx*j] = F[(i + Kx - 1) % Nx + Nx*((j + Ky - 1) % Ny)];

  /* Run the plan on input data */
  fftw_execute(p1);

  /* Cleanup and return */
  fftw_free(circ);

  h->circ_freq = ocirc;
  h->r2c_plan = p1;
  h->c2r_plan = p2;
  h->window.x = Lx; h->window.y = Ly;
  h->length.x = Nx; h->length.y = Ny;
}
// Inverse FFT of 2D data (complex to real).
//
// Creates output data in row-major order. That is,
// ordered like a C-array: out[Nslow][Nfast].
//
void IFT_2D(
	vector<double>			&out,
	const vector<CD>		&in,
	int						Nfast,
	int						Nslow )
{
	int	N = Nslow * Nfast;

	out.resize( N );

	pthread_mutex_lock( &mutex_fft );

	fftw_plan	p;

	p = fftw_plan_dft_c2r_2d( Nslow, Nfast, (double (*)[2])&in[0],
			&out[0], FFTW_ESTIMATE );

	fftw_execute( p );
	fftw_destroy_plan( p );

	pthread_mutex_unlock( &mutex_fft );
}
Exemple #15
0
int init_global_bufs (plugin_context* ctx, int width, int height, double sgm, int ns)
{
    artistic_proc_context* c;
    int nx = width;
    int ny = height;
    fft_plans_t* f;
    fftw_complex* in;

    if (nx <= 0 || ny <= 0) {
        return -1;
    }

    if (NULL == (f = malloc (sizeof(fft_plans_t)))) {
      return -1;
    }
    if (NULL == (in = fftw_malloc (sizeof(fftw_complex)*ny*(nx/2+1)))) {
      return -1;
    }
    f->forward  = fftw_plan_dft_r2c_2d (ny, nx, (double*)in, in, FFTW_ESTIMATE);
    f->backward = fftw_plan_dft_c2r_2d (ny, nx, in, (double*)in, FFTW_ESTIMATE);
    fftw_free (in);

    if (NULL == (c = malloc (sizeof(artistic_proc_context)))) {
        return -1;
    }

    if (NULL == (c->b = calloc (ctx->num_threads, sizeof(artistic_buf_t*)))) {
        return -1;
    }

    c->width = width;
    c->height = height;
    c->sgm = sgm;
    c->ns = ns;
    c->p = f;
    ctx->data = c;

    return 0;
}
/**
 * \brief Compute the inverse transform
 *
 * Note that in order to get inverse, we also have to divide by the volume
 * of the domain, which explains why we do all this only for float valued
 * pixels.
 */
ImagePtr	FourierImage::inverse() const {
	Image<double>	*image = new Image<double>(_orig);
	int	n0 = _orig.height();
	int	n1 = _orig.width();
	debug(LOG_DEBUG, DEBUG_LOG, 0, "inverse transform, (%d,%d)", n0, n1);
	// compute the fourier transform
	fftw_plan	p = fftw_plan_dft_c2r_2d(n0, n1, (fftw_complex *)pixels,
				image->pixels, FFTW_ESTIMATE);
	fftw_execute(p);
	fftw_destroy_plan(p);
	fftw_cleanup();
	debug(LOG_DEBUG, DEBUG_LOG, 0, "inverse fourier transform complete");

	// normalize to the dimensions of the domain
	double	value = 1. / (n0 * n1);
	int	w = _orig.width();
	int	h = _orig.height();
	for (int x = 0; x < w; x++) {
		for (int y = 0; y < h; y++) {
			image->pixel(x, y) = image->pixel(x, y) * value;
		}
	}
	return ImagePtr(image);
}
Exemple #17
0
/*!
 *  dpixInverseDFT()
 *
 *      Input:  dft
 *              w, h (image size)
 *      Return: dpix (unnormalized), or null on error
 */
DPIX *
dpixInverseDFT(fftw_complex *dft,
			   l_int32       w,
			   l_int32       h)
{
	DPIX         *dpix;
	fftw_plan    plan;
	
	PROCNAME("dpixInverseDFT");
	
    if (!dft)
        return (DPIX *)ERROR_PTR("dft not defined", procName, NULL);
	if ((dpix = dpixCreate(w, h)) == NULL)
        return (DPIX *)ERROR_PTR("dpix not made", procName, NULL);
	
	/* Compute the inverse DFT, storing the results into DPix */
	plan = fftw_plan_dft_c2r_2d(h, w, dft, (double *) dpixGetData(dpix), FFTW_ESTIMATE);
	fftw_execute(plan);
	fftw_destroy_plan(plan);
	
	dpixNormalize(dpix, dpix);
	
	return dpix;
}
Exemple #18
0
// same function, takes xTable reference as agrument 
void
kTable::Transform(xTable& xt) const {

  // ??? check proper dimensions for xt ?
  Assert(N==xt.getN());

  // We'll need a new k array because FFTW kills the k array in this
  // operation.  Also, to put x=0 in center of array, we need to flop
  // every other sign of k array, and need to scale.

  DComplex* t_array = 
    (DComplex*) fftw_malloc(sizeof(DComplex)*N*(N/2+1));
  double fac = scaleby * dk * dk / (4*PI*PI);
  long int ind=0;
  for (int i=0; i<N; i++)
    for (int j=0; j<=N/2; j++) {
      if ( (i+j)%2==0) t_array[ind]=fac * array[ind];
      else t_array[ind] = -fac* array[ind];
      ind++;
    }

  fftw_plan plan = 
    fftw_plan_dft_c2r_2d(N, N,
			 reinterpret_cast<fftw_complex*> (t_array), xt.array,
			 FFTW_ESTIMATE);
  if (plan==NULL) throw FFTInvalid();

  // Run the transform:
  fftw_execute(plan);
  fftw_destroy_plan(plan);
  fftw_free(t_array);

  xt.dx = 2*PI/(N*dk);
  xt.scaleby = 1.;
  xt.valid = true;
}
Exemple #19
0
int main()
{
  // apply FFT to real 2D data.

  double *in;
  double *apex;
  int W = 640;
  int H = 480;
  int half_H = (H / 2) + 1;
  int x;
  int y;
  fftw_complex *out;
  fftw_complex *apex_f;
  fftw_plan plan_backward;
  fftw_plan plan_apex;
  fftw_plan plan_forward;
  unsigned int seed = 123456789;
  srand(seed);

  in = (double *) malloc_check(sizeof(double) * W * H);
  for(x = 0; x < W; x++)
  {
    for(y = 0; y < H; y++)
    {
#if 1
      in[x*H+y] =  ( double ) rand ( ) / ( RAND_MAX );
#else
      in[x*H+y] =  0;
#endif
    }
  }
  in[(H/2) + (W/2)*H] = 1;
  in[(H/2)+3 + (W/2 + 3)*H] = 1;
  in[10 + (20)*H] = 1;
  in[H-3 + (W-3)*H] = 1;

  y = W * H;
  for (x = 0; x < y; x++) {
    in[x] *= PALETTE_LEN -10;
  }


  apex = (double*)malloc_check(sizeof(double) * W * H);
  double apex_sum = 0;
  for(x = 0; x < W; x++)
  {
    for(y = 0; y < H; y++)
    {
      double dist = 0;
      int xx = x;
      int yy = y;
      if (xx >= W/2)
        xx = W - x;
      if (yy >= H/2)
        yy = H - y;
      dist = sqrt(xx*xx + yy*yy);
      double v = 8.01 - dist;
      if (v < 0)
        v = 0;
#if 0
      if (x == 2 && y == 1)
        v = 302.1;
#endif

#if 0
      if (x == W / 2 && y == H / 2)
        v = 850;
#endif

#if 0
      if (x < W/2 || y > H / 2)
        v = -v * 1.85;
#endif
#if 0
      if (x == W/3-1 && y == H/3-1)
        v = 200;
      if (x == W/3 && y == H/3)
        v = -200;
#endif
      apex_sum += v;
      apex[x*H+y] = v;
    }
  }

  double burn = 1.005;
  double apex_mul = (burn / (W*H)) / apex_sum;
  printf("%f %f\n", apex_sum, apex_mul);

  y = W * H;
  for (x = 0; x < y; x++) {
    apex[x] *= apex_mul;
  }

  apex_f = fftw_malloc(sizeof(fftw_complex) * W * half_H);
  plan_apex = fftw_plan_dft_r2c_2d(W, H, apex, apex_f, FFTW_ESTIMATE);
  fftw_execute(plan_apex);


  out = fftw_malloc(sizeof(fftw_complex) * W * half_H);
  plan_forward = fftw_plan_dft_r2c_2d(W, H, in, out, FFTW_ESTIMATE);
  plan_backward = fftw_plan_dft_c2r_2d(W, H, out, in, FFTW_ESTIMATE);

  int winW = W;
  int winH = H;

  SDL_Window *window;
  window = SDL_CreateWindow("fftw3_test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                            winW, winH, 0);

  if (!window) {
    fprintf(stderr, "Unable to set %dx%d video: %s\n", winW, winH, SDL_GetError());
    exit(1);
  }

  SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
  if (!renderer) {
    fprintf(stderr, "Unable to set %dx%d video: %s\n", winW, winH, SDL_GetError());
    exit(1);
  }

  SDL_ShowCursor(SDL_DISABLE);
  SDL_PixelFormat *pixelformat = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888);
  SDL_Texture *texture = SDL_CreateTexture(renderer, pixelformat->format,
                                           SDL_TEXTUREACCESS_STREAMING, winW, winH);
  if (!texture) {
    fprintf(stderr, "Cannot create texture\n");
    exit(1);
  }

#if 0
#define n_palette_points 2
  palette_point_t palette_points[n_palette_points] = {
    { 0., 0, 0, 0 },
    { 1., 1, 1, 1 },
  };
#else
#define n_palette_points 11
  palette_point_t palette_points[n_palette_points] = {
    { 0./6, 1, 1, 1 },
    { 0.5/6, 1, .9, 0 },
    { 1./6, 1, .1, 1 },
    { 1.5/6, 0, 0, 1 },
    { 3./6, .5, 0, .7 },
    { 3.5/6, 0, 1, .7 },
    { 4.5/6, .2, .8, .2 },
    { 4.8/6, 0, 0, 1 },
    { 5.25/6, .8, .8, 0 },
    { 5.55/6, .8, .2, 0.4 },
    { 5.85/6, .0,.60,.50 },
  };
#endif

  palette_t palette;
  make_palette(&palette, PALETTE_LEN,
               palette_points, n_palette_points,
               pixelformat);

  bool running = true;
  int frame_period = 50;
  int last_ticks = SDL_GetTicks() - frame_period;

  Uint32 *winbuf = (Uint32*)malloc_check(winW * winH * sizeof(Uint32));

  while (running)
  {
    bool do_render = false;

    int elapsed = SDL_GetTicks() - last_ticks;
    if (elapsed > frame_period) {
      last_ticks += frame_period * (elapsed / frame_period);
      do_render = true;
    }

    if (do_render) {
      render(winbuf, winW, winH, &palette, in, W, H);
      SDL_UpdateTexture(texture, NULL, winbuf, winW * sizeof(Uint32));
      SDL_RenderClear(renderer);
      SDL_RenderCopy(renderer, texture, NULL, NULL);
      SDL_RenderPresent(renderer);

      fftw_execute(plan_forward);

#if 1
      for (x = 0; x < W; x++) {
        for (y = 0; y < half_H; y++) {
          double *o = out[x*half_H + y];
          double *af = apex_f[x*half_H + y];
          double a, b, c, d;
          a = o[0]; b = o[1];
          c = af[0]; d = af[1];
#if 1
          o[0] = (a*c - b*d);
          o[1] = (b*c + a*d);
#else
          double l = sqrt(c*c + d*d);
          o[0] *= l;
          o[1] *= l;
#endif
        }
      }
#endif

      fftw_execute(plan_backward);
    }
    else
      SDL_Delay(5);

    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
      switch (event.type)
      {
        case SDL_KEYDOWN:
          // If escape is pressed, return (and thus, quit)

          switch(event.key.keysym.sym) {
            case SDLK_ESCAPE:
              running = false;
              break;

            default:
              break;
          }
          break;

        case SDL_QUIT:
          running = false;
          break;
      }
    }

  }
  SDL_Quit();

  fftw_destroy_plan(plan_apex);
  fftw_destroy_plan(plan_forward);
  fftw_destroy_plan(plan_backward);

  free(in);
  free(apex);
  fftw_free(out);
  fftw_free(apex_f);

  return 0;
}
Exemple #20
0
PetscInt main(PetscInt argc,char **args)
{
  typedef enum {RANDOM, CONSTANT, TANH, NUM_FUNCS} FuncType;
  const char    *funcNames[NUM_FUNCS] = {"random", "constant", "tanh"};
  PetscMPIInt    size;
  PetscInt       n = 10,N,Ny,ndim=4,dim[4],DIM,i;
  Vec            x,y,z;
  PetscScalar    s;
  PetscRandom    rdm;
  PetscReal      enorm;
  PetscInt       func=RANDOM;
  FuncType       function = RANDOM;
  PetscBool      view = PETSC_FALSE;
  PetscErrorCode ierr;
  PetscScalar    *x_array,*y_array,*z_array;
  fftw_plan      fplan,bplan;
  const ptrdiff_t N0 = 20, N1 = 20;

  ptrdiff_t alloc_local, local_n0, local_0_start;
  ierr = PetscInitialize(&argc,&args,(char *)0,help);CHKERRQ(ierr);
#if defined(PETSC_USE_COMPLEX)
  SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This example requires real numbers");
#endif
  ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr);
  alloc_local=fftw_mpi_local_size_2d(N0, N1, PETSC_COMM_WORLD,
                                              &local_n0, &local_0_start);

  if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This is a uniprocessor example only!");
  ierr = PetscOptionsBegin(PETSC_COMM_WORLD, PETSC_NULL, "FFTW Options", "ex142");CHKERRQ(ierr);
    ierr = PetscOptionsEList("-function", "Function type", "ex142", funcNames, NUM_FUNCS, funcNames[function], &func, PETSC_NULL);CHKERRQ(ierr);
    ierr = PetscOptionsBool("-vec_view draw", "View the functions", "ex112", view, &view, PETSC_NULL);CHKERRQ(ierr);
    function = (FuncType) func;
  ierr = PetscOptionsEnd();CHKERRQ(ierr);

  for (DIM = 0; DIM < ndim; DIM++){
    dim[DIM]  = n; /* size of real space vector in DIM-dimension */
  }
  ierr = PetscRandomCreate(PETSC_COMM_SELF, &rdm);CHKERRQ(ierr);
  ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr);

  for (DIM = 1; DIM < 5; DIM++){
    /* create vectors of length N=dim[0]*dim[1]* ...*dim[DIM-1] */
    /*----------------------------------------------------------*/
    N = Ny = 1;
    for (i = 0; i < DIM-1; i++) {
      N *= dim[i];
    }
    Ny = N; Ny *= 2*(dim[DIM-1]/2 + 1); /* add padding elements to output vector y */
    N *= dim[DIM-1];


    ierr = PetscPrintf(PETSC_COMM_SELF, "\n %d-D: FFTW on vector of size %d \n",DIM,N);CHKERRQ(ierr);
    ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x);CHKERRQ(ierr);
    ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr);

    ierr = VecCreateSeq(PETSC_COMM_SELF,Ny,&y);CHKERRQ(ierr);
    ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr);

    ierr = VecDuplicate(x,&z);CHKERRQ(ierr);
    ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr);


    /* Set fftw plan                    */
    /*----------------------------------*/
    ierr = VecGetArray(x,&x_array);CHKERRQ(ierr);
    ierr = VecGetArray(y,&y_array);CHKERRQ(ierr);
    ierr = VecGetArray(z,&z_array);CHKERRQ(ierr);

    unsigned int flags = FFTW_ESTIMATE; //or FFTW_MEASURE
    /* The data in the in/out arrays is overwritten during FFTW_MEASURE planning, so such planning
     should be done before the input is initialized by the user. */
    printf("DIM: %d, N %d, Ny %d\n",DIM,N,Ny);

    switch (DIM){
    case 1:
      fplan = fftw_plan_dft_r2c_1d(dim[0], (double *)x_array, (fftw_complex*)y_array, flags);
      bplan = fftw_plan_dft_c2r_1d(dim[0], (fftw_complex*)y_array, (double *)z_array, flags);
      break;
    case 2:
      fplan = fftw_plan_dft_r2c_2d(dim[0],dim[1],(double *)x_array, (fftw_complex*)y_array,flags);
      bplan = fftw_plan_dft_c2r_2d(dim[0],dim[1],(fftw_complex*)y_array,(double *)z_array,flags);
      break;
    case 3:
      fplan = fftw_plan_dft_r2c_3d(dim[0],dim[1],dim[2],(double *)x_array, (fftw_complex*)y_array,flags);
      bplan = fftw_plan_dft_c2r_3d(dim[0],dim[1],dim[2],(fftw_complex*)y_array,(double *)z_array,flags);
      break;
    default:
      fplan = fftw_plan_dft_r2c(DIM,dim,(double *)x_array, (fftw_complex*)y_array,flags);
      bplan = fftw_plan_dft_c2r(DIM,dim,(fftw_complex*)y_array,(double *)z_array,flags);
      break;
    }

    ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr);
    ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
    ierr = VecRestoreArray(z,&z_array);CHKERRQ(ierr);

    /* Initialize Real space vector x:
       The data in the in/out arrays is overwritten during FFTW_MEASURE planning, so planning
       should be done before the input is initialized by the user.
    --------------------------------------------------------*/
    if (function == RANDOM) {
      ierr = VecSetRandom(x, rdm);CHKERRQ(ierr);
    } else if (function == CONSTANT) {
      ierr = VecSet(x, 1.0);CHKERRQ(ierr);
    } else if (function == TANH) {
      ierr = VecGetArray(x, &x_array);CHKERRQ(ierr);
      for (i = 0; i < N; ++i) {
        x_array[i] = tanh((i - N/2.0)*(10.0/N));
      }
      ierr = VecRestoreArray(x, &x_array);CHKERRQ(ierr);
    }
    if (view) {
      ierr = VecView(x, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
    }

    /* FFT - also test repeated transformation   */
    /*-------------------------------------------*/
    ierr = VecGetArray(x,&x_array);CHKERRQ(ierr);
    ierr = VecGetArray(y,&y_array);CHKERRQ(ierr);
    ierr = VecGetArray(z,&z_array);CHKERRQ(ierr);
    for (i=0; i<3; i++){
      /* FFTW_FORWARD */
      fftw_execute(fplan);
      //printf("\n fout:\n");
      //fftw_complex* fout = (fftw_complex*)y_array;
      //for (i=0; i<N/2+1; i++) printf("%d (%g %g)\n",i,fout[i][0],fout[i][1]);

      /* FFTW_BACKWARD: destroys its input array 'y_array' even for out-of-place transforms! */
      fftw_execute(bplan);
    }
    ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr);
    ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr);
    ierr = VecRestoreArray(z,&z_array);CHKERRQ(ierr);

    /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */
    /*------------------------------------------------------------------*/
    s = 1.0/(PetscReal)N;
    ierr = VecScale(z,s);CHKERRQ(ierr);
    if (view) {ierr = VecView(x, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);}
    if (view) {ierr = VecView(z, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);}
    ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr);
    ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr);
    if (enorm > 1.e-11){
      ierr = PetscPrintf(PETSC_COMM_SELF,"  Error norm of |x - z| %G\n",enorm);CHKERRQ(ierr);
    }

    /* free spaces */
    fftw_destroy_plan(fplan);
    fftw_destroy_plan(bplan);
    ierr = VecDestroy(&x);CHKERRQ(ierr);
    ierr = VecDestroy(&y);CHKERRQ(ierr);
    ierr = VecDestroy(&z);CHKERRQ(ierr);
  }
  ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return 0;
}
Exemple #21
0
static MagickBooleanType InverseFourierTransform(FourierInfo *fourier_info,
  fftw_complex *fourier,Image *image,ExceptionInfo *exception)
{
  CacheView
    *image_view;

  double
    *source;

  fftw_plan
    fftw_c2r_plan;

  register IndexPacket
    *indexes;

  register PixelPacket
    *q;

  register ssize_t
    i,
    x;

  ssize_t
    y;

  source=(double *) AcquireQuantumMemory((size_t) fourier_info->height,
    fourier_info->width*sizeof(*source));
  if (source == (double *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
      return(MagickFalse);
    }
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp critical (MagickCore_InverseFourierTransform)
#endif
  {
    fftw_c2r_plan=fftw_plan_dft_c2r_2d(fourier_info->width,fourier_info->height,
      fourier,source,FFTW_ESTIMATE);
    fftw_execute(fftw_c2r_plan);
    fftw_destroy_plan(fftw_c2r_plan);
  }
  i=0L;
  image_view=AcquireAuthenticCacheView(image,exception);
  for (y=0L; y < (ssize_t) fourier_info->height; y++)
  {
    if (y >= (ssize_t) image->rows)
      break;
    q=GetCacheViewAuthenticPixels(image_view,0L,y,fourier_info->width >
      image->columns ? image->columns : fourier_info->width,1UL,exception);
    if (q == (PixelPacket *) NULL)
      break;
    indexes=GetCacheViewAuthenticIndexQueue(image_view);
    for (x=0L; x < (ssize_t) fourier_info->width; x++)
    {
      if (x < (ssize_t) image->columns)
        switch (fourier_info->channel)
        {
          case RedChannel:
          default:
          {
            SetPixelRed(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case GreenChannel:
          {
            SetPixelGreen(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case BlueChannel:
          {
            SetPixelBlue(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case OpacityChannel:
          {
            SetPixelOpacity(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case IndexChannel:
          {
            SetPixelIndex(indexes+x,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
          case GrayChannels:
          {
            SetPixelGray(q,ClampToQuantum(QuantumRange*source[i]));
            break;
          }
        }
      i++;
      q++;
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      break;
  }
  image_view=DestroyCacheView(image_view);
  source=(double *) RelinquishMagickMemory(source);
  return(MagickTrue);
}
//constructor of the class
Solver_FFTW::Solver_FFTW(){
	/*===============================================*/
	Input* initInput = new Input();
	numOfXGrid = initInput->getXGridNum();
	numOfYGrid = initInput->getYGridNum();
	cout << "Input Finished" << endl;
	cout << "Grids along x axis: " << numOfXGrid << endl;
	cout << "Grids along y axis: " << numOfYGrid << endl;

	/*======================================================
	Initializing arrays in real space
	======================================================*/
	v = new double*[numOfXGrid];
	w = new double*[numOfXGrid];
	initE = 0;
	temp_Velocity = new double[numOfXGrid*numOfYGrid];
	firstD_u = new double[numOfXGrid*numOfYGrid];
	secondD_u = new double[numOfXGrid*numOfYGrid];
	for(int i = 0; i < numOfXGrid; i++){
		v[i] = new double[numOfYGrid];
		w[i] = new double[numOfYGrid];
		for(int j = 0; j < numOfYGrid; j++){
			v[i][j] = initInput->getXVelocity(i,j);
			w[i][j] = initInput->getYVelocity(i,j);
			initE += v[i][j]*v[i][j] + w[i][j]*w[i][j]; //calculating the initial energy
		}
	}

	for(int i = 0; i < numOfXGrid*numOfYGrid; i++){
		temp_Velocity[i] = 0;
		firstD_u[i] = 0;
		secondD_u[i] = 0;
	}
	
	/*=====================================================
	Initializing first order derivatives
	=====================================================*/
	v_x = new double*[numOfXGrid];
	v_y = new double*[numOfXGrid];
	w_x = new double*[numOfXGrid];
	w_y = new double*[numOfXGrid];
	for(int i = 0; i < numOfXGrid; i++){
		v_x[i] = new double[numOfYGrid];
		v_y[i] = new double[numOfYGrid];
		w_x[i] = new double[numOfYGrid];
		w_y[i] = new double[numOfYGrid];
		for(int j = 0; j < numOfYGrid; j++){
			v_x[i][j] = 0;
			v_y[i][j] = 0;
			w_x[i][j] = 0;
			w_y[i][j] = 0;
		}
	}
	
	/*=====================================================
	Initializing second order derivatives
	=====================================================*/
	v_x_x = new double*[numOfXGrid];
	v_y_y = new double*[numOfXGrid];
	w_x_x = new double*[numOfXGrid];
	w_y_y = new double*[numOfXGrid];
	for(int i = 0; i < numOfXGrid; i++){
		v_x_x[i] = new double[numOfYGrid];
		v_y_y[i] = new double[numOfYGrid];
		w_x_x[i] = new double[numOfYGrid];
		w_y_y[i] = new double[numOfYGrid];
		for(int j = 0; j < numOfYGrid; j++){
			v_x_x[i][j] = 0;
			v_y_y[i][j] = 0;
			w_x_x[i][j] = 0;
			w_y_y[i][j] = 0;
		}
	}

	/*========================================================
	Initializing the forces
	========================================================*/
	externalFx = new double*[numOfXGrid];
	externalFy = new double*[numOfXGrid];
	for(int i = 0;i < numOfXGrid; i++){
		externalFx[i] = new double[numOfYGrid];
		externalFy[i] = new double[numOfYGrid];
		for(int j = 0;j < numOfYGrid; j++){
			externalFx[i][j] = 0;
			externalFy[i][j] = 0;
		}
	}


	/*========================================================
	initializing multiple threads
	==========================================================*/
	if(fftw_init_threads()){
		fftw_plan_with_nthreads(THREADS);
		cout << "Using "<< THREADS << " threads" << endl << endl;
	}
	else {
		cout << "Using multiple threads failed" << endl;
		exit(0);
	}

	/*=====================================================
	Initializing arrays in fourier space
	=====================================================*/
	V = (fftw_complex**)fftw_malloc(sizeof(fftw_complex*)*numOfXGrid);
	W = (fftw_complex**)fftw_malloc(sizeof(fftw_complex*)*numOfXGrid);
	temp_U = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*numOfXGrid*(numOfYGrid/2+1));
	firstD_U = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*numOfXGrid*(numOfYGrid/2+1));
	secondD_U = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*numOfXGrid*(numOfYGrid/2+1));
	for(int i = 0; i < numOfXGrid; i++){
		V[i] = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*(numOfYGrid/2+1));
		W[i] = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*(numOfYGrid/2+1));
		for(int j = 0; j < numOfYGrid/2 + 1; j++){
			V[i][j][0] = 0;
			V[i][j][1] = 0;
			W[i][j][0] = 0;
			W[i][j][1] = 0;
		}
	}

	for(int i = 0; i < numOfXGrid*(numOfYGrid/2+1); i++){
		temp_U[i][0] = 0;
		temp_U[i][1] = 0;
		firstD_U[i][0] = 0;
		firstD_U[i][1] = 0;
		secondD_U[i][0] = 0;
		secondD_U[i][1] = 0;
	}

	temp = (fftw_complex**)fftw_malloc(sizeof(fftw_complex*)*numOfXGrid);
	for(int i = 0; i < numOfXGrid; i++){
		temp[i] = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*(numOfYGrid/2+1));
	}
	/**=====================================================
	Initializing Plans
	======================================================*/
	plan_r2c = fftw_plan_dft_r2c_2d(numOfXGrid,numOfYGrid,temp_Velocity,temp_U,FFTW_ESTIMATE);
	plan_c2r = fftw_plan_dft_c2r_2d(numOfXGrid,numOfYGrid,temp_U,temp_Velocity,FFTW_ESTIMATE);
	plan_firstD = fftw_plan_dft_c2r_2d(numOfXGrid,numOfYGrid,firstD_U,firstD_u,FFTW_ESTIMATE);
	plan_secondD = fftw_plan_dft_c2r_2d(numOfXGrid,numOfYGrid,secondD_U,secondD_u,FFTW_ESTIMATE);

	/*======================================================
	initializing output energy file
	======================================================*/

	stringstream fileNameOfE;
	fileNameOfE << OUTPUT_PATH << "E" << ".txt";
	energy.open(fileNameOfE.str().c_str());

	/*======================================================
	generating the readMe.txt file
	======================================================*/

	stringstream fileNameOfReadMe;
	fileNameOfReadMe << OUTPUT_PATH << "readMe.txt";
	readMe.open(fileNameOfReadMe.str().c_str());
	readMe << "Nx = " << numOfXGrid << endl;
	readMe << "Ny = " << numOfYGrid << endl;
	readMe << "dt = " << TIME_STEP << endl;
	readMe << "Initial Energy = " << initE << endl;
	readMe << "Viscosity = "<< VISCOSITY << endl;
	readMe << "Rescaled Viscosity =" << VISCOSITY/sqrt(initE*(numOfXGrid-1)*(numOfYGrid-1));
	readMe.close();


	/*======================================================
	Initializing Adams array.
	======================================================*/
	Adams_v = new double**[3];
	Adams_w = new double**[3];
	for(int i = 0;i < 3; i++){
		Adams_v[i] = new double*[numOfXGrid];
		Adams_w[i] = new double*[numOfXGrid];
		for(int j = 0; j < numOfXGrid; j++){
			Adams_v[i][j] = new double[numOfYGrid];
			Adams_w[i][j] = new double[numOfYGrid];
			for(int k = 0; k < numOfYGrid; k++){
				Adams_v[i][j][k] = 0;
				Adams_w[i][j][k] = 0;
			}
		}
	}

	/*==================================================*/
	return;
	
}
Exemple #23
0
void test04()

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

TEST04: apply FFT to real 2D data.

Discussion:

In this example, we generate NX=8 by NY=10 random real values
stored as an NX by NY array of type DOUBLE 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.

The Fourier coefficients are stored in an NX by NYH array where
NYH = (NY/2) + 1.  We only compute about half the data because
of real data implies symmetric FFT coefficients.

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

Licensing:

This code is distributed under the GNU LGPL license.

Modified:

05 November 2007

Author:

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

	printf("\n");
	printf("TEST04\n");
	printf("  Demonstrate FFTW3 on a %d by %d array of real 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, an NX by NY array of doubles.
	*/
	in = (double *)malloc(sizeof(double) * nx * ny);

	srand(seed);

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

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

	for (i = 0; i < nx; i++)
	{
		for (j = 0; j < ny; j++)
		{
			printf("  %4d  %4d  %12f\n", i, j, in[i*ny + j]);
		}
	}
	/*
	Create the output array OUT, which is of type FFTW_COMPLEX,
	and of a size NX * NYH that is roughly half the dimension of the input data
	(ignoring the fact that the input data is real, and the FFT
	coefficients are complex).
	*/
	nyh = (ny / 2) + 1;

	out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nx * nyh);

	plan_forward = fftw_plan_dft_r2c_2d(nx, ny, in, out, 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 < nyh; j++)
		{
			printf("  %4d  %4d  %12f  %12f\n",
				i, j, out[i*nyh + j][0], out[i*nyh + j][1]);
		}
	}
	/*
	Recreate the input array.
	*/
	in2 = (double *)malloc(sizeof(double) * nx * ny);

	plan_backward = fftw_plan_dft_c2r_2d(nx, ny, out, in2, 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\n",
				i, j, in2[i*ny + j] / (double)(nx * ny));
		}
	}
	/*
	Free up the allocated memory.
	*/
	fftw_destroy_plan(plan_forward);
	fftw_destroy_plan(plan_backward);

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

	return;
}
Exemple #24
0
void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
                    float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
                    short do_jacobian, int seed)
{
	int i, j, ii;

	BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);

	o->_M = M;
	o->_N = N;
	o->_V = V;
	o->_l = l;
	o->_A = A;
	o->_w = w;
	o->_damp_reflections = 1.0f - damp;
	o->_wind_alignment = alignment;
	o->_depth = depth;
	o->_Lx = Lx;
	o->_Lz = Lz;
	o->_wx = cos(w);
	o->_wz = -sin(w); /* wave direction */
	o->_L = V * V / GRAVITY;  /* largest wave for a given velocity V */
	o->time = time;

	o->_do_disp_y = do_height_field;
	o->_do_normals = do_normals;
	o->_do_chop = do_chop;
	o->_do_jacobian = do_jacobian;

	o->_k = (float *) MEM_mallocN(M * (1 + N / 2) * sizeof(float), "ocean_k");
	o->_h0 = (fftw_complex *) MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0");
	o->_h0_minus = (fftw_complex *) MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0_minus");
	o->_kx = (float *) MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
	o->_kz = (float *) MEM_mallocN(o->_N * sizeof(float), "ocean_kz");

	/* make this robust in the face of erroneous usage */
	if (o->_Lx == 0.0f)
		o->_Lx = 0.001f;

	if (o->_Lz == 0.0f)
		o->_Lz = 0.001f;

	/* the +ve components and DC */
	for (i = 0; i <= o->_M / 2; ++i)
		o->_kx[i] = 2.0f * (float)M_PI * i / o->_Lx;

	/* the -ve components */
	for (i = o->_M - 1, ii = 0; i > o->_M / 2; --i, ++ii)
		o->_kx[i] = -2.0f * (float)M_PI * ii / o->_Lx;

	/* the +ve components and DC */
	for (i = 0; i <= o->_N / 2; ++i)
		o->_kz[i] = 2.0f * (float)M_PI * i / o->_Lz;

	/* the -ve components */
	for (i = o->_N - 1, ii = 0; i > o->_N / 2; --i, ++ii)
		o->_kz[i] = -2.0f * (float)M_PI * ii / o->_Lz;

	/* pre-calculate the k matrix */
	for (i = 0; i < o->_M; ++i)
		for (j = 0; j <= o->_N / 2; ++j)
			o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);

	/*srand(seed);*/
	BLI_srand(seed);

	for (i = 0; i < o->_M; ++i) {
		for (j = 0; j < o->_N; ++j) {
			float r1 = gaussRand();
			float r2 = gaussRand();

			fftw_complex r1r2;
			init_complex(r1r2, r1, r2);
			mul_complex_f(o->_h0[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, o->_kx[i], o->_kz[j]) / 2.0f)));
			mul_complex_f(o->_h0_minus[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, -o->_kx[i], -o->_kz[j]) / 2.0f)));
		}
	}

	o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
	o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");

	if (o->_do_disp_y) {
		o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
		o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
	}

	if (o->_do_normals) {
		o->_fft_in_nx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nx");
		o->_fft_in_nz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nz");

		o->_N_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
		/* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */
		o->_N_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");

		o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE);
		o->_N_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nz, o->_N_z, FFTW_ESTIMATE);
	}

	if (o->_do_chop) {
		o->_fft_in_x = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
		o->_fft_in_z = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");

		o->_disp_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
		o->_disp_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");

		o->_disp_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_x, o->_disp_x, FFTW_ESTIMATE);
		o->_disp_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_z, o->_disp_z, FFTW_ESTIMATE);
	}
	if (o->_do_jacobian) {
		o->_fft_in_jxx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
		                                             "ocean_fft_in_jxx");
		o->_fft_in_jzz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
		                                             "ocean_fft_in_jzz");
		o->_fft_in_jxz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
		                                             "ocean_fft_in_jxz");

		o->_Jxx = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
		o->_Jzz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
		o->_Jxz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");

		o->_Jxx_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxx, o->_Jxx, FFTW_ESTIMATE);
		o->_Jzz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jzz, o->_Jzz, FFTW_ESTIMATE);
		o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
	}

	BLI_rw_mutex_unlock(&o->oceanmutex);

	set_height_normalize_factor(o);

}
/*****************
 * Version DOUBLE
 *****************/
void Chi2LibFFTW::conv2d_fft(MyMatrix<double> *img, MyMatrix<double> *kernel_img, MyMatrix<double> *output){
	MyLogger::log()->debug("[Chi2LibFFTW][conv2d_fft] Generating Convolution using FFTW");
	fftw_complex	*fft_image, *fft_kernel;
	fftw_plan       plan_forward_image, plan_forward_kernel, plan_backward;
	//auxiliary structures are necessary because fftw3 optimization plan will destroy it!
	double 			*ifft_result, *data, *kernel;
	int nwidth 	=	(int)(img->sX()+kernel_img->sX()-1);
	int nheight	=	(int)(img->sY()+kernel_img->sY()-1);

	pthread_mutex_lock( &mutex1 );
	// FFTW Allocs
	size_t size = (size_t)(nwidth * nheight);
	//the new size includes zero padding space
	data 		= fftw_alloc_real(size);
	kernel 		= fftw_alloc_real(size);
	ifft_result = fftw_alloc_real(size);

	//fftw handle real fft avoiding redundancy in the complex plane, therefore the nheight/2
	size = (size_t)(nwidth*(floor(nheight/2) + 1));
	fft_image	= fftw_alloc_complex(size);
	fft_kernel	= fftw_alloc_complex(size);

	plan_forward_image	= fftw_plan_dft_r2c_2d( nwidth, nheight, data, fft_image, FFTW_ESTIMATE );
	plan_forward_kernel	= fftw_plan_dft_r2c_2d( nwidth, nheight, kernel, fft_kernel, FFTW_ESTIMATE );
	plan_backward		= fftw_plan_dft_c2r_2d( nwidth, nheight, fft_image, ifft_result, FFTW_ESTIMATE );

	pthread_mutex_unlock( &mutex1 );

	//populate kernel and shift input
	for(unsigned int x = 0 ; x < (unsigned int)nwidth ; ++x ){
		unsigned int xnw = x*nwidth;
		for(unsigned int y=0; y < (unsigned int)nheight; ++y){
			if(x < kernel_img->sX() && y < kernel_img->sY())
				kernel[xnw+ y] = kernel_img->getValue(x,y);
			else
				kernel[xnw+ y] = 0;
		}
	}

	for(unsigned int x = 0 ; x < (unsigned int)nwidth ; ++x ){
		unsigned int xnw = x*nwidth;
		for(unsigned int y=0; y < (unsigned int)nheight; ++y){
			if(x < img->sX() && y < img->sY())
				data[xnw+ y] = img->getValue(x,y);
			else
				data[xnw+ y] = 0;
		}
	}

	MyLogger::log()->debug("[Chi2LibFFTW][conv2d_fft] Starting FFTW");
	/** FFT Execute */
		//fft of image
		fftw_execute( plan_forward_image );
		//fft of kernel
		fftw_execute( plan_forward_kernel );

		//convolution in fourier domain
		double f1, f2;
		double nwnh = (double)(nwidth*nheight);
		unsigned int limit = (unsigned int)(nwidth * (floor(nheight/2) + 1));
		for(unsigned int i=0; i< limit; ++i){
			f1 = fft_image[i][0]*fft_kernel[i][0] - fft_image[i][1]*fft_kernel[i][1];
			f2 = fft_image[i][0]*fft_kernel[i][1] + fft_image[i][1]*fft_kernel[i][0];

			fft_image[i][0]=f1/nwnh;
			fft_image[i][1]=f2/nwnh;
		}

		//ifft of the product
		fftw_execute( plan_backward );
	/** FFT Execute */
	MyLogger::log()->debug("[Chi2LibFFTW][conv2d_fft] FFTW Finished");

	if(output->sX() == (unsigned int)nwidth && output->sY() == (unsigned int)nheight)
	for(unsigned int x = 0 ; x < output->sX() ; ++x ){
		unsigned int xnw = x*nwidth;
		for(unsigned int y = 0 ; y < output->sY() ; ++y ){
			output->at(x,y) = ifft_result[xnw+y];
		}
	}

    /* free memory */
    fftw_destroy_plan( plan_forward_image );
    fftw_destroy_plan( plan_forward_kernel );
    fftw_destroy_plan( plan_backward );

    fftw_free( data );
    fftw_free( kernel );
    fftw_free( ifft_result );

    fftw_free( fft_image );
    fftw_free( fft_kernel );
}
Exemple #26
0
/* =======================================================================*
    Public Functions
 * =======================================================================*/
void
s_ncc_fft_compile (FATM_Options* fopt)
{
    fftw_plan pat_plan;
    double* temp;
    int i, j;
    Image_Rect* prv = &fopt->pat_rect_valid;
    fftw_iodim fftw_dims[2];
    int fft_nx = fopt->sig_rect_scan.dims[1];    /* In fftw3, nx is rows */
    int fft_ny = fopt->sig_rect_scan.dims[0];    /* In fftw3, ny is cols */

    /* Allocate memory */
    S_Ncc_Fft_Data* udp = (S_Ncc_Fft_Data*) malloc (sizeof(S_Ncc_Fft_Data));
    fopt->alg_data = (void*) udp;

    /* Alloc memory for integral images */
    s_ncc_fft_scorewin_alloc (fopt);

    /* Compute pattern statistics */
//    s_pattern_statistics (&udp->p_stats, fopt);

    /* Alloc memory for fft of pat */
    udp->pat_fft = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) * fft_nx * (fft_ny/2+1));
    memset (udp->pat_fft, 0, sizeof(fftw_complex) * fft_nx * (fft_ny/2+1));

    /* Copy pattern into fft memory.  Flip it so that convolution 
	becomes correlation */
    temp = (double*) udp->pat_fft + (fft_nx-1) * (2*(fft_ny/2+1)) + fft_ny - 1;
    for (j = 0; j < prv->dims[0]; j++) {
	for (i = 0; i < prv->dims[1]; i++) {
	    *temp-- = image_data(&fopt->pat)[image_index(prv->dims, j, i)];
	}
	temp -= (2*(fft_ny/2+1)) - prv->dims[1];
    }

    /* Peform fft */
    pat_plan = fftw_plan_dft_r2c_2d (fft_nx, fft_ny, 
	(double*) udp->pat_fft, udp->pat_fft, FFTW_ESTIMATE);
    fftw_execute (pat_plan);
    fftw_destroy_plan (pat_plan);

    /* Debugging info */
    dump_fft (udp->pat_fft, fft_nx, fft_ny, "pat_fft.txt");

    /* Alloc memory for fft of sig */
    udp->sig_fft = (fftw_complex*) fftw_malloc (sizeof(fftw_complex) 
						* fft_nx * (fft_ny/2+1));

    /* Create plan for sig -> sig_fft */
    fftw_dims[0].n = fft_nx;
    fftw_dims[0].is = fopt->sig.dims[0];
    fftw_dims[0].os = (fft_ny/2+1);
    fftw_dims[1].n = fft_ny;
    fftw_dims[1].is = 1;
    fftw_dims[1].os = 1;

    /* NOTE: Using FFTW_MEASURE overwrites input.  So I need to allocate 
	a temporary array. */
    udp->sig_fftw3_plan = fftw_plan_guru_dft_r2c (
	2, fftw_dims, 0, 0, 
	(double*) fopt->sig.data, udp->sig_fft, 
	FFTW_ESTIMATE | FFTW_UNALIGNED | FFTW_PRESERVE_INPUT);
    if (udp->sig_fftw3_plan == 0) {
	printf ("Error: couldn't make plan\n");
    }
    printf ("SRS: %d %d\n", fopt->sig_rect_scan.dims[0], fopt->sig_rect_scan.dims[1]);
    printf ("SIG: %d %d\n", fopt->sig.dims[0], fopt->sig.dims[1]);

    /* Alloc memory for temporary score */
    udp->padded_score = (double*) fftw_malloc (sizeof(double) * fft_nx * fft_ny);

    /* Create plan for pat_fft * sig_fft -> score */
    udp->sco_fftw3_plan = fftw_plan_dft_c2r_2d (fft_nx, fft_ny, 
	udp->sig_fft, udp->padded_score, FFTW_MEASURE);
    if (udp->sco_fftw3_plan == 0) {
	printf ("Error: couldn't make plan\n");
    }
}
Exemple #27
0
/* Complex to real inverse transform.
 */
static int 
invfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	IMAGE *cmplx = im_open_local( dummy, "invfft1-1", "t" );
	IMAGE *real = im_open_local( out, "invfft1-2", "t" );
	const int half_width = in->Xsize / 2 + 1;

	/* Transform to halfcomplex here.
	 */
	double *half_complex = IM_ARRAY( dummy, 
		in->Ysize * half_width * 2, double );

	/* We have to have a separate real buffer for the planner to work on.
	 */
	double *planner_scratch = IM_ARRAY( dummy, 
		in->Ysize * half_width * 2, double );

	fftw_plan plan;
	int x, y;
	double *q, *p;

	if( !cmplx || !real || !half_complex || im_pincheck( in ) || 
		im_poutcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_invfft", 
			"%s", _( "one band uncoded only" ) );
                return( -1 );
	}

	/* Make dp complex image for input.
	 */
	if( im_clip2fmt( in, cmplx, IM_BANDFMT_DPCOMPLEX ) )
                return( -1 );

	/* Make mem buffer real image for output.
	 */
        if( im_cp_desc( real, in ) )
                return( -1 );
	real->BandFmt = IM_BANDFMT_DOUBLE;
        if( im_setupout( real ) )
                return( -1 );

	/* Build half-complex image.
	 */
	q = half_complex;
	for( y = 0; y < cmplx->Ysize; y++ ) {
		p = ((double *) cmplx->data) + y * in->Xsize * 2; 

		for( x = 0; x < half_width; x++ ) {
			q[0] = p[0];
			q[1] = p[1];
			p += 2;
			q += 2;
		}
	}

	/* Make the plan for the transform. Yes, they really do use nx for
	 * height and ny for width.
	 */
	if( !(plan = fftw_plan_dft_c2r_2d( in->Ysize, in->Xsize,
		(fftw_complex *) planner_scratch, (double *) real->data,
		0 )) ) {
                im_error( "im_invfft", 
			"%s", _( "unable to create transform plan" ) );
		return( -1 );
	}

	fftw_execute_dft_c2r( plan,
		(fftw_complex *) half_complex, (double *) real->data );

	fftw_destroy_plan( plan );

	/* Copy to out.
	 */
        if( im_copy( real, out ) )
                return( -1 );

	return( 0 );
}
Exemple #28
0
/* --------------------------------------------------------------------------- *
 * This overloaded function is an implementation of your tone mapping operator *
 * --------------------------------------------------------------------------- */
int TMOZhao10::Transform()
{
	double* data;
	int size = pSrc->GetHeight()*pSrc->GetWidth();
	int spec_size = pSrc->GetHeight()*(pSrc->GetWidth()/2+1);
	double *rgb[] = {fftw_alloc_real(size),fftw_alloc_real(size),fftw_alloc_real(size)};
	double *lab[] = {fftw_alloc_real(size),fftw_alloc_real(size),fftw_alloc_real(size)};
	fftw_complex *spec_rgb[] = {fftw_alloc_complex(spec_size),fftw_alloc_complex(spec_size),fftw_alloc_complex(spec_size)};
	fftw_complex *spec_lab[] = {fftw_alloc_complex(spec_size),fftw_alloc_complex(spec_size),fftw_alloc_complex(spec_size)};
	
	double *theta = fftw_alloc_real(spec_size);
	double *phi = fftw_alloc_real(spec_size);
	
	fftw_complex *spec_gray = fftw_alloc_complex(spec_size);
	double *gray = fftw_alloc_real(size);
	
	fftw_plan p = fftw_plan_dft_r2c_2d(pSrc->GetHeight(), pSrc->GetWidth(),rgb[0], spec_rgb[0], FFTW_ESTIMATE);
	
	//copy data channels to r,g,b arrays
	data=pSrc->GetData();
	for(int i=0;i<size;++i){
		rgb[0][i] = *data++;
		rgb[1][i] = *data++;
		rgb[2][i] = *data++;
	}
	
	//transform to Lab space
	pSrc->Convert(TMO_LAB);
	pDst->Convert(TMO_LAB);
	
	
	//copy data channels to l,a,b array
	data=pSrc->GetData();
	for(int i=0;i<size;++i){
		lab[0][i] = *data++/100;
		lab[1][i] = *data++/100;
		lab[2][i] = *data++/100;
		
		//fprintf(stderr,"%f %f %f\n",lab[0][i],lab[1][i],lab[2][i]);
	}
	
	//compute fft of all channels
	fftw_execute_dft_r2c(p,rgb[0], spec_rgb[0]);
	fftw_execute_dft_r2c(p,rgb[1], spec_rgb[1]);
	fftw_execute_dft_r2c(p,rgb[2], spec_rgb[2]);
	fftw_execute_dft_r2c(p,lab[0], spec_lab[0]);
	fftw_execute_dft_r2c(p,lab[1], spec_lab[1]);
	fftw_execute_dft_r2c(p,lab[2], spec_lab[2]);
	
	fftw_destroy_plan(p);
	p = fftw_plan_dft_c2r_2d(pSrc->GetHeight(), pSrc->GetWidth(),spec_gray, gray, FFTW_ESTIMATE);
	
	//compute phi and theta coefficient
	double thetasum=0;
	double phisum=0;
	for(int i=0;i<spec_size;++i){
		double a2 = spec_lab[1][i][0]*spec_lab[1][i][0]+spec_lab[1][i][1]*spec_lab[1][i][1];
		double b2 = spec_lab[2][i][0]*spec_lab[2][i][0]+spec_lab[2][i][1]*spec_lab[2][i][1];
		phi[i] = a2/(a2+b2);
		phisum += phi[i];
		
		double rr2 = spec_rgb[0][i][0]*spec_rgb[0][i][0]+spec_rgb[0][i][1]*spec_rgb[0][i][1];
		double gg2 = spec_rgb[1][i][0]*spec_rgb[1][i][0]+spec_rgb[1][i][1]*spec_rgb[1][i][1];
		double bb2 = spec_rgb[2][i][0]*spec_rgb[2][i][0]+spec_rgb[2][i][1]*spec_rgb[2][i][1];
		double l2 = spec_lab[0][i][0]*spec_lab[0][i][0]+spec_lab[0][i][1]*spec_lab[0][i][1];
		double rgb2 = rr2+gg2+bb2;
		theta[i] = (rgb2-l2)/rgb2;
		thetasum += theta[i];
	}
	
	thetasum=0.6*spec_size;
	phisum=0.9*spec_size;
	for(int i=0;i<spec_size;++i){
		spec_gray[i][0] = ((1-thetasum/spec_size)*spec_lab[0][i][0]+thetasum/spec_size*(phisum/spec_size*spec_lab[1][i][0]+(1-phisum/spec_size)*spec_lab[2][i][0]))/size;
		//spec_gray[i][0] = ((1-theta[i])*spec_lab[0][i][0]+theta[i]*(phi[i]*spec_lab[1][i][0]+(1-phi[i])*spec_lab[2][i][0]))/size;
		spec_gray[i][1] = ((1-thetasum/spec_size)*spec_lab[0][i][1]+thetasum/spec_size*(phisum/spec_size*spec_lab[1][i][1]+(1-phisum/spec_size)*spec_lab[2][i][1]))/size; 
		//spec_gray[i][1] = ((1-theta[i])*spec_lab[0][i][1]+theta[i]*(phi[i]*spec_lab[1][i][1]+(1-phi[i])*spec_lab[2][i][1]))/size; 
	}
	
	fftw_execute(p);
	
	double minimum = 99999999999999999;
	double maximum = -99999999999999999;
	data=pDst->GetData();
	for(int i=0;i<size;++i){
		if(gray[i]>maximum) maximum=gray[i];
		if(gray[i]<minimum) minimum=gray[i];
		*data++ = gray[i]*100;
		*data++ = 0;//gray[i];
		*data++ = 0;//gray[i];
	}
	
	fprintf(stderr,"%f %f %d %d\n",minimum,maximum,size,spec_size);
	data=pDst->GetData();
	for(int i=0;i<size;++i){
		*data = 100*(gray[i]-minimum)/(maximum-minimum);
		data += 3;
	}
	
	fftw_destroy_plan(p);
	fftw_free(gray); fftw_free(spec_gray);
	fftw_free(phi); fftw_free(theta);
	fftw_free(rgb[0]);fftw_free(rgb[1]);fftw_free(rgb[2]);
	fftw_free(lab[0]);fftw_free(lab[1]);fftw_free(lab[2]);
	fftw_free(spec_rgb[0]);fftw_free(spec_rgb[1]);fftw_free(spec_rgb[2]);
	fftw_free(spec_lab[0]);fftw_free(spec_lab[1]);fftw_free(spec_lab[2]);
	
	pDst->Convert(TMO_RGB);
	return 0;
}
Exemple #29
0
/****** fft_conv ************************************************************
PROTO	void fft_conv(double *data1, double *fdata2, int *size)
PURPOSE	Optimized 2-dimensional FFT convolution using the FFTW library.
INPUT	ptr to the first image,
	ptr to the Fourier transform of the second image,
	image size vector.
OUTPUT	-.
NOTES	For data1 and fdata2, memory must be allocated for
	size[0]* ... * 2*(size[naxis-1]/2+1) doubles (padding required).
AUTHOR	E. Bertin (IAP)
VERSION	26/03/2007
 ***/
void    fft_conv(double *data1, double *fdata2, int *size)
  {
   fftw_plan	plan;
   double	*fdata1,*fdata1p,*fdata2p,
		real,imag, fac;
   int		i, npix,npix2;

/* Convert axis indexing to that of FFTW */
  npix = size[0]*size[1];
  npix2 = (((size[0]/2) + 1)*2) * size[1];

/* Forward FFT "in place" for data1 */
#ifdef USE_THREADS
  QPTHREAD_MUTEX_LOCK(&fftmutex);
#endif
  QFFTWMALLOC(fdata1, double, npix2);
  plan = fftw_plan_dft_r2c_2d(size[1], size[0], data1,
        (fftw_complex *)fdata1, FFTW_ESTIMATE|FFTW_DESTROY_INPUT);
#ifdef USE_THREADS
  QPTHREAD_MUTEX_UNLOCK(&fftmutex);
#endif
  fftw_execute(plan);

#ifdef USE_THREADS
  QPTHREAD_MUTEX_LOCK(&fftmutex);
#endif
  fftw_destroy_plan(plan);
#ifdef USE_THREADS
  QPTHREAD_MUTEX_UNLOCK(&fftmutex);
#endif

/* Actual convolution (Fourier product) */
  fac = 1.0/npix;  
  fdata1p = fdata1;
  fdata2p = fdata2;
  for (i=npix2/2; i--; fdata2p+=2)
    {
    real = *fdata1p **fdata2p - *(fdata1p+1)**(fdata2p+1);
    imag = *(fdata1p+1)**fdata2p + *fdata1p**(fdata2p+1);
    *(fdata1p++) = fac*real;
    *(fdata1p++) = fac*imag;
    }

/* Reverse FFT */
#ifdef USE_THREADS
  QPTHREAD_MUTEX_LOCK(&fftmutex);
#endif
  plan = fftw_plan_dft_c2r_2d(size[1], size[0], (fftw_complex *)fdata1, 
        data1, FFTW_ESTIMATE|FFTW_DESTROY_INPUT);
#ifdef USE_THREADS
  QPTHREAD_MUTEX_UNLOCK(&fftmutex);
#endif

  fftw_execute(plan);

#ifdef USE_THREADS
  QPTHREAD_MUTEX_LOCK(&fftmutex);
#endif
  fftw_destroy_plan(plan);
/* Free the fdata1 scratch array */
  QFFTWFREE(fdata1);
#ifdef USE_THREADS
  QPTHREAD_MUTEX_UNLOCK(&fftmutex);
#endif

  return;
  }
Exemple #30
0
// calculate a degree 3 spline of 2 dim periodic data:
// in each cell, data is approximated by degree 3 polynomial
// f(x,y) = p00*N0(x)N0(y) + p01*N0(x)N1(y) + p10*N1(x)N0(y) + ...
// where Ni(x) = binom(3,i)*x^i(1-x)^(3-i)
spline2d_t spline2d_init(double *data, int m, int n) {
  int i, j, l1, l2, idx;

  double  *d;

  double complex *kcx, *kcy, *kd, *kp;

  double complex wx[4], wy[4];

  double complex kcxx, kcyy;

  fftw_plan cxplan, cyplan, dplan, iplan;

  spline2d_t myspline;

  myspline.nx = m;
  myspline.ny = n;

  myspline.cells = calloc(m*n,sizeof(spline2d_cell_t));

  d  = calloc(m*(n/2+1)*2,sizeof(double));

  kcx = calloc(m,sizeof(double complex));
  kcy = calloc(n,sizeof(double complex));
  kd  = calloc(m*(n/2+1),sizeof(double complex));
  kp  = calloc(m*(n/2+1),sizeof(double complex));

  cxplan = fftw_plan_dft_1d(m, kcx, kcx, FFTW_BACKWARD, FFTW_MEASURE);
  cyplan = fftw_plan_dft_1d(n, kcy, kcy, FFTW_BACKWARD, FFTW_MEASURE);

  dplan = fftw_plan_dft_r2c_2d(m, n, d, kd, FFTW_MEASURE);
  iplan = fftw_plan_dft_c2r_2d(m, n, kp, d, FFTW_MEASURE);

  // initialize kcx,kcy
  kcx[0] = 1.0 + 0.0*I;
  kcx[1] = 4.0 + 0.0*I;
  kcx[2] = 1.0 + 0.0*I;
  kcy[0] = 1.0 + 0.0*I;
  kcy[1] = 4.0 + 0.0*I;
  kcy[2] = 1.0 + 0.0*I;
  fftw_execute(cxplan);
  fftw_execute(cyplan);

  // calculate kd
  for(i = 0; i < m; i++) {
    for(j = 0; j < n; j++) {
      idx = i*(n/2 + 0)*2 + j;
      d[idx] = data[i*n + j];
    }
  }
  fftw_execute(dplan); // kd now holds fft of data

  // calculate p's
  for(l1 = 0; l1 < 4; l1++) {
    for(l2 = 0; l2 < 4; l2++) {
      for(i = 0; i < m; i++) {
        for(j = 0; j < n/2 + 1; j++) {
          idx = i*(n/2 + 1) + j;

          // weights calcualted here!!
          wx[0] = 1.0;
          wx[1] = cexp(2.0*M_PI*I*i/(double)m)*4.0;
          wx[1]+= cexp(4.0*M_PI*I*i/(double)m)*2.0;
          wx[2] = cexp(2.0*M_PI*I*i/(double)m)*2.0;
          wx[2]+= cexp(4.0*M_PI*I*i/(double)m)*4.0;
          wx[3] = cexp(2.0*M_PI*I*i/(double)m);
          wy[0] = 1.0;
          wy[1] = cexp(2.0*M_PI*I*j/(double)n)*4.0;
          wy[1]+= cexp(4.0*M_PI*I*j/(double)n)*2.0;
          wy[2] = cexp(2.0*M_PI*I*j/(double)n)*2.0;
          wy[2]+= cexp(4.0*M_PI*I*j/(double)n)*4.0;
          wy[3] = cexp(2.0*M_PI*I*j/(double)n);

          if(l1 == 0 || l1 == 3) {
            kcxx = 1.0;
          }
          else {
            kcxx = kcx[i];
          }
          if(l2 == 0 || l2 == 3) {
            kcyy = 1.0;
          }
          else {
            kcyy = kcy[j];
          }

          if(cabs(kcxx*kcyy) > 0) {
            kp[idx] = kd[idx]*wx[l1]*wy[l2]/(kcxx*kcyy);
          }
        }
      }
      fftw_execute(iplan); // d holds p[i*n + j][l1*4 + l2] unnormalized
      for(i = 0; i < m; i++) {
        for(j = 0; j < n; j++) {
          myspline.cells[i*n + j].p[l1][l2]
            = d[i*(n/2+0)*2 + j]/(double)(m*n);
        }
      }
    }
  }

  fftw_destroy_plan(cxplan);
  fftw_destroy_plan(cyplan);
  fftw_destroy_plan(dplan);
  fftw_destroy_plan(iplan);

  free(kcx);
  free(kcy);
  free(kd);
  free(kp);

  return myspline;
}