//============================================================= // Fast Fourier transform of DPoly to CDPoly static CDPoly PolyFFT(const DPoly & p) { size_t n = p.Degree(); size_t nl = log2(n); size_t j, k, m, m2, s; DComplex wm, w, t, u; CDPoly a = BitRevCopy(p); m = 2; m2 = 1; for (s = 0; s < nl; ++s) { wm = exp(PI2I / double(m)); w = DComplex(1.0); for (j = 0; j <= (m2 - 1); ++j) { for (k = j; k <= n - 1; k += m) { t = w * a[k + m2]; u = a[k]; a[k] = u + t; a[k + m2] = u - t; } w *= wm; } m <<= 1; m2 <<= 1; } return a; }
void // Translate the PSF to be for source at (x0,y0); // ??need a sign flip here? kTable::Translate(double x0, double y0) { // convert to phases: x0*=dk; y0*=dk; // too big will just be wrapping around: if (x0 > PI || y0 > PI) throw FFTOutofRange(); DComplex I(0.,1.); DComplex dxphase=exp(DComplex(0.,x0)); DComplex dyphase=exp(DComplex(0.,y0)); DComplex phase(1.,0.); DComplex yphase=1.; DComplex z; DComplex *zptr=array; for (int i=0; i< N/2; i++) { phase = yphase; for (int j=0; j<= N/2 ; j++) { z = *zptr; *zptr = phase * z; phase *= dxphase; zptr++; } yphase *= dyphase; } // wrap to the negative ky's yphase = exp(I*((-N/2)*y0)); for (int i=-N/2; i< 0; i++) { phase = yphase; for (int j=0; j<= N/2 ; j++) { z = *zptr; *zptr = phase* z; phase *= dxphase; zptr++; } yphase *= dyphase; } return; }
//============================================================= // performs a reverse-bit copy of a DPoly into a new CDPoly static CDPoly BitRevCopy(const DPoly & p) { size_t n = p.Degree(); size_t b = log2(n); CDPoly a(n); for (size_t k = 0; k < n; ++k) a[FlipBits(k,b)] = DComplex(p.Get(k)); return a; }