Пример #1
0
tom::fftw::Plan<T>::Plan(tom::Volume<T> &vsrc, tom::Volume<std::complex<T> > &vdst, unsigned flags){

    const int type = this->is_valid_dft_r2c(vsrc, vdst);
    if (type == TOM_FFTW_PLAN_INVALID) {
        throw std::invalid_argument("tom::fftw::Plan() - The input volumes have not the right size or alignment for dft_r2c");
    }


    int rank = (type==TOM_FFTW_PLAN_3D ? 3 : 2);
    int howmany_rank = 0;
    fftw_iodim iodim[3];
    iodim[0].n  = vsrc.getSizeX();
    iodim[0].is = vsrc.getStrideX()/sizeof(T);
    iodim[0].os = vdst.getStrideX()/sizeof(std::complex<T>);
    iodim[1].n  = vsrc.getSizeY();
    iodim[1].is = vsrc.getStrideY()/sizeof(T);
    iodim[1].os = vdst.getStrideY()/sizeof(std::complex<T>);
    iodim[2].n  = vsrc.getSizeZ();
    iodim[2].is = vsrc.getStrideZ()/sizeof(T);
    iodim[2].os = vdst.getStrideZ()/sizeof(std::complex<T>);
    fftw_iodim *howmany_dims = NULL;


	boost::shared_ptr<void> p(static_cast<void *>(0), ::plan_destroyer<T>());
	if (tom::is_float<T>()) {
		p = boost::shared_ptr<void>(static_cast<void *>(fftwf_plan_guru_dft_r2c(rank, iodim, howmany_rank, howmany_dims, (float  *)&vsrc.get(), (fftwf_complex *)&vdst.get(), flags)), ::plan_destroyer<T>());
	} else {
		p = boost::shared_ptr<void>(static_cast<void *>(fftw_plan_guru_dft_r2c (rank, iodim, howmany_rank, howmany_dims, (double *)&vsrc.get(), (fftw_complex  *)&vdst.get(), flags)), ::plan_destroyer<T>());
	}
	if (!p.get()) {
		throw std::runtime_error("tom::fftw::Plan() - could not create fftw plan dft_r2c");
	}

    std::auto_ptr<tom::Volume<std::complex<T> > > p_freq0(new tom::Volume<std::complex<T> >(vdst, NULL, vdst.getSizeX(), vdst.getSizeY(), vdst.getSizeZ(), vdst.getStrideX(), vdst.getStrideY(), vdst.getStrideZ()));
    std::auto_ptr<tom::Volume<T               > > p_time0(new tom::Volume<T               >(vsrc, NULL, vsrc.getSizeX(), vsrc.getSizeY(), vsrc.getSizeZ(), vsrc.getStrideX(), vsrc.getStrideY(), vsrc.getStrideZ()));

	this->plan.swap(p);
    this->type = tom::fftw::Plan<T>::FFTW_DFT_R2C;
    this->p_freq0 = p_freq0.release();
    this->p_time0 = p_time0.release();
    this->p_freq1 = NULL;
    this->p_time1 = NULL;
}
Пример #2
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");
    }
}
Пример #3
0
Transformer_CPU::Transformer_CPU(int dim_x, int dim_y, int dim_z, int exp_x, int exp_y, int exp_z)
	: dim_x(dim_x), dim_y(dim_y), dim_z(dim_z), exp_x(exp_x), exp_y(exp_y), exp_z(exp_z)
{
	if (os::disable_SSE_for_FFTW()) {
		fftw_strategy |= FFTW_UNALIGNED; // see os.h for explanation
	}

	Matrix tmp(Shape(2, exp_x, exp_y, exp_z));
	Matrix::rw_accessor tmp_acc(tmp);
	double *tmp_inout = tmp_acc.ptr();

	// Create fftw plans
	fftw_iodim dims, loop;

	// X-Transform: (dim_y*dim_z) x 1d-C2C-FFT (length: exp_x) in x-direction, in-place transform
	dims.n = exp_x;
	dims.is = 1;
	dims.os = 1;
	
	loop.n = dim_y*dim_z;
	loop.is = exp_x;
	loop.os = exp_x/2+1;

	plan_x_r2c = fftw_plan_guru_dft_r2c(
		1, &dims, 
		1, &loop, 
		(      double*)tmp_inout,
		(fftw_complex*)tmp_inout, 
		fftw_strategy
	);
	assert(plan_x_r2c);

	dims.n = exp_x;
	dims.is = 1;
	dims.os = 1;
	
	loop.n = dim_y*dim_z;
	loop.is = exp_x/2+1;
	loop.os = exp_x;

	plan_x_c2r = fftw_plan_guru_dft_c2r(
		1, &dims, 
		1, &loop, 
		(fftw_complex*)tmp_inout, 
		(      double*)tmp_inout,
		fftw_strategy
	);
	assert(plan_x_c2r);

	// Y-Transform: (dim_z*exp_x/2+1) x 1d-C2C-FFT (length: exp_y) in x-direction, in-place transform
	dims.n = exp_y;
	dims.is = 1;
	dims.os = 1;
	
	loop.n = dim_z*(exp_x/2+1);
	loop.is = exp_y;
	loop.os = exp_y;

	plan_y_forw = fftw_plan_guru_dft(
		1, &dims,
		1, &loop,
		(fftw_complex*)tmp_inout, // in
		(fftw_complex*)tmp_inout, // out (-> in-place transform)
		FFTW_FORWARD,
		fftw_strategy
	);
	assert(plan_y_forw);

	plan_y_inv = fftw_plan_guru_dft(
		1, &dims,
		1, &loop,
		(fftw_complex*)tmp_inout, // in
		(fftw_complex*)tmp_inout, // out (-> in-place transform)
		FFTW_BACKWARD,
		fftw_strategy
	);
	assert(plan_y_inv);

	// Z-Transform: (exp_x/2+1*exp_y) x 1d-C2C-FFT (length: exp_z) in x-direction, in-place transform
	dims.n = exp_z;
	dims.is = 1;
	dims.os = 1;
	
	loop.n = (exp_x/2+1)*exp_y;
	loop.is = exp_z;
	loop.os = exp_z;

	plan_z_forw = fftw_plan_guru_dft(
		1, &dims,
		1, &loop,
		(fftw_complex*)tmp_inout, // in
		(fftw_complex*)tmp_inout, // out (-> in-place transform)
		FFTW_FORWARD,
		fftw_strategy
	);
	assert(plan_z_forw);

	plan_z_inv = fftw_plan_guru_dft(
		1, &dims,
		1, &loop,
		(fftw_complex*)tmp_inout, // in
		(fftw_complex*)tmp_inout, // out (-> in-place transform)
		FFTW_BACKWARD,
		fftw_strategy
	);
	assert(plan_z_inv);
}