Example #1
0
    // Transform to a single k point:
    std::complex<double> XTable::kval(double kx, double ky) const 
    {
        check_array();
        // Don't evaluate if k not in fundamental period 
        kx*=_dx; ky*=_dx;
#ifdef FFT_DEBUG
        if (std::abs(kx) > M_PI || std::abs(ky) > M_PI) 
            throw FFTOutofRange("XTable::kval() args out of range");
#endif
        std::complex<double> I(0.,1.);
        std::complex<double> dxphase=std::exp(-I*kx);
        std::complex<double> dyphase=std::exp(-I*ky);
        std::complex<double> phase(1.,0.);
        std::complex<double> z;
        std::complex<double> sum=0.;

        const double* zptr=_array.get();
        std::complex<double> yphase=std::exp(I*(ky*_N/2));
        for (int iy=0; iy< _N; iy++) {
            phase = yphase;
            phase *= std::exp(I*(kx*_N/2));
            for (int ix=0; ix< _N ; ix++) {
                sum += phase* (*(zptr++));
                phase *= dxphase;
            }
            yphase *= dyphase;
        }
        sum *= _dx*_dx;
        return sum;
    }
Example #2
0
// Transform to a single k point:
DComplex
xTable::kval(double kx, double ky) const {
  // check this:  don't evaluate if x not in fundamental period:
  kx*=dx; ky*=dx;
  if (kx > 2*PI || ky > 2*PI) throw FFTOutofRange();
  DComplex I(0.,1.);
  DComplex dxphase=exp(-I*kx);
  DComplex dyphase=exp(-I*ky);
  DComplex phase(1.,0.);
  DComplex z;
  DComplex sum=0.;

  double *zptr=array;
  DComplex yphase=exp(I*(ky*N/2));
  for (int i=0; i< N; i++) {
    phase = yphase;
    phase *= exp(I*(kx*N/2));
    for (int j=0; j< N ; j++) {
      sum += phase* (*(zptr++));
      phase *= dxphase;
    }
    yphase *= dyphase;
  }
  sum *= dx*dx*scaleby;
  return sum;
}
Example #3
0
size_t
xTable::index(int i, int j) const {
  // origin will be in center.
  i += N/2;
  j += N/2;
  if (i<0 || i>=N || j<0 || j>=N) throw FFTOutofRange() ;
  return i*N+j;
}
Example #4
0
size_t
kTable::index(int i, int j) const {
  // adjust for xTable with origin in center.
  if (i<-N/2 || i>N/2 || j<-N/2 || j>N/2) throw FFTOutofRange() ;
  if (j<0) {
    j=-j; i=-i;	//need the conjugate in this case
  }
  if (i<0) i+=N;
  return i*(N/2+1)+j;
}
Example #5
0
    // Transform to a single x point:
    // assumes (x,y) in physical units
    double KTable::xval(double x, double y) const 
    { 
        check_array();
        x*=_dk; y*=_dk;
        // Don't evaluate if x not in fundamental period +-PI/dk:
#ifdef FFT_DEBUG
        if (std::abs(x) > M_PI || std::abs(y) > M_PI) 
            throw FFTOutofRange(" (x,y) too big in xval()");
#endif
        std::complex<double> I(0.,1.);
        std::complex<double> dxphase=std::exp(I*x);
        std::complex<double> dyphase=std::exp(I*y);
        std::complex<double> phase(1.,0.);
        std::complex<double> z;
        double sum=0.;
        // y DC terms first:
        const std::complex<double>* zptr=_array.get();
        // Do the positive y frequencies
        std::complex<double> yphase=1.;
        for (int iy=0; iy< _N/2; iy++) {
            phase = yphase;
            z= *(zptr++);
            sum += (phase*z).real(); //x DC term
            for (int ix=1; ix< _N/2 ; ix++) {
                phase *= dxphase;
                z= *(zptr++);
                sum += (phase*z).real() * 2.;
            }
            phase *= dxphase; //ix=N/2 has no mirror:
            z= *(zptr++);
            sum += (phase*z).real();
            yphase *= dyphase;
        }

        // wrap to the negative ky's
        yphase = std::exp(I*(y*(-_N/2)));
        for (int iy=-_N/2; iy< 0; iy++) {
            phase = yphase;
            z= *(zptr++);
            sum += (phase*z).real(); // x DC term
            for (int ix=1; ix< _N/2 ; ix++) {
                phase *= dxphase;
                z= *(zptr++);
                sum += (phase*z).real() * 2.;
            }
            phase *= dxphase; //ix=N/2 has no mirror:
            z= *(zptr++);
            sum += (phase*z).real();
            yphase *= dyphase;
        }

        sum *= _dk*_dk/(4.*M_PI*M_PI); //inverse xform has 2pi in it.
        return sum;
    }
Example #6
0
// Transform to a single x point:
double
kTable::xval(double x, double y) const {
  // ??? check this:  don't evaluate if x not in fundamental period:
  x*=dk; y*=dk;
  if (x > 2*PI || y > 2*PI) throw FFTOutofRange();
  DComplex I(0.,1.);
  DComplex dxphase=exp(I*x);
  DComplex dyphase=exp(I*y);
  DComplex phase(1.,0.);
  DComplex z;
  double sum=0.;
  // y DC terms first:
  DComplex *zptr=array;
  // Do the positive y frequencies
  DComplex yphase=1.;
  for (int i=0; i< N/2; i++) {
    phase = yphase;
    z= *(zptr++);
    sum += (phase*z).real();	//x DC term
    for (int j=1; j< N/2 ; j++) {
      phase *= dxphase;
      z= *(zptr++);
      sum += (phase*z).real() * 2.;
    }
    phase *= dxphase;		//j=N/2 has no mirror:
    z= *(zptr++);
    sum += (phase*z).real();
    yphase *= dyphase;
  }

  // wrap to the negative ky's
  yphase = exp(I*(y*(-N/2)));
  for (int i=-N/2; i< 0; i++) {
    phase = yphase;
    z= *(zptr++);
    sum += (phase*z).real() * 2.;
    for (int j=1; j< N/2 ; j++) {
      phase *= dxphase;
      z= *(zptr++);
      sum += (phase*z).real() * 2.;
    }
    phase *= dxphase;		//j=N/2 has no mirror:
    z= *(zptr++);
    sum += (phase*z).real();
    yphase *= dyphase;
  }

  sum *= dk*dk*scaleby/(4.*PI*PI);	//inverse xform has 2pi in it.
  return sum;
}
Example #7
0
    // Translate the PSF to be for source at (x0,y0);
    void KTable::translate(double x0, double y0) 
    {
        clearCache(); // invalidate any stored interpolations
        check_array();
        // convert to phases:
        x0*=_dk; y0*=_dk;
        // too big will just be wrapping around:
#ifdef FFT_DEBUG
        if (x0 > M_PI || y0 > M_PI) throw FFTOutofRange("(x0,y0) too big in translate()");
#endif
        std::complex<double> I(0.,1.);
        std::complex<double> dxphase=std::exp(std::complex<double>(0.,-x0));
        std::complex<double> dyphase=std::exp(std::complex<double>(0.,-y0));
        std::complex<double> phase(1.,0.);

        std::complex<double> yphase=1.;
        std::complex<double> z;

        std::complex<double>* zptr=_array.get();

        for (int iy=0; iy< _N/2; iy++) {
            phase = yphase;
            for (int ix=0; ix<= _N/2 ; ix++) {
                z = *zptr;
                *zptr = phase * z;
                phase *= dxphase;
                zptr++;
            }
            yphase *= dyphase;
        }

        // wrap to the negative ky's
        yphase = std::exp(I*((_N/2)*y0));
        for (int iy=-_N/2; iy< 0; iy++) {
            phase = yphase;
            for (int ix=0; ix<= _N/2 ; ix++) {
                z = *zptr;
                *zptr = phase* z;
                phase *= dxphase;
                zptr++;
            }
            yphase *= dyphase;
        }
    }
Example #8
0
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;
}