// Same deal: reverse axis order if we have separable interpolant in X domain void SBInterpolatedImage::fillXGrid(XTable& xt) const { #ifdef DANIELS_TRACING cout << "SBInterpolatedImage::fillXGrid called" << endl; #endif if ( dynamic_cast<const InterpolantXY*> (xInterp)) { int N = xt.getN(); double dx = xt.getDx(); for (int ix = -N/2; ix < N/2; ix++) { for (int iy = -N/2; iy < N/2; iy++) { Position<double> x(ix*dx,iy*dx); xt.xSet(ix,iy,xValue(x)); } } } else { // Otherwise just use the normal routine to fill the grid: SBProfile::fillXGrid(xt); } }
// 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; }