示例#1
0
tom::fftw::Plan<T>::Plan(tom::Volume<std::complex<T> > &vsrc, tom::Volume<T> &vdst, unsigned flags) {

    const int type = this->is_valid_dft_c2r(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_c2r");
    }

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


	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_c2r(rank, iodim, howmany_rank, howmany_dims, (fftwf_complex *)&vsrc.get(), (float  *)&vdst.get(), flags)), ::plan_destroyer<T>());
	} else {
		p = boost::shared_ptr<void>(static_cast<void *>(fftw_plan_guru_dft_c2r (rank, iodim, howmany_rank, howmany_dims, (fftw_complex  *)&vsrc.get(), (double *)&vdst.get(), flags)), ::plan_destroyer<T>());
	}
	if (!p.get()) {
		throw std::runtime_error("tom::fftw::Plan() - could not create fftw plan dft_c2r");
	}

	auto_vol_fourier.reset(new tom::Volume<std::complex<T> >(vsrc, NULL, vsrc.getSizeX(), vsrc.getSizeY(), vsrc.getSizeZ(), vsrc.getStrideX(), vsrc.getStrideY(), vsrc.getStrideZ()));
	auto_vol_real   .reset(new tom::Volume<T               >(vdst, NULL, vdst.getSizeX(), vdst.getSizeY(), vdst.getSizeZ(), vdst.getStrideX(), vdst.getStrideY(), vdst.getStrideZ()));

    this->plan.swap(p);
    this->type = tom::fftw::Plan<T>::FFTW_DFT_C2R;
    this->p_freq0 = auto_vol_fourier.release();
    this->p_time0 = auto_vol_real   .release();
	this->p_freq1 = NULL;
    this->p_time1 = NULL;
}
示例#2
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);
}