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