#if !defined(PS_FFT_H)
#define PS_FFT_H

/* #include <fftw3.h> */

/** \file psFFT.h
 *  \brief Fourier Transform functions
 *  \ingroup MathGroup
 */

/** Functions **************************************************************/
/** \addtogroup MathGroup Math Utilities
 *  \{
 */


/** Specify direction of FFT, and if the result is real or not */
typedef enum {
    PS_FFT_FORWARD = 0,                 ///< psImageFFT/psVectorFFT should perform a forward FFT.
    PS_FFT_REVERSE = 1,                 ///< psImageFFT/psVectorFFT should perform a reverse FFT.
    PS_FFT_REAL_RESULT = 2		///< psImageFFT/psVectorFFT should return a real image. This is valid
					///< for only reverse FFT, i.e., the psImageFFT/psVectorFFT flag
					///< parameter should appear as PS_FFT_REVERSE+PS_FFT_REAL_RESULT.
} psFFTFlags;


/**** Vector FFT & Complex functions ****/

/** FFT a vector. in: psF32 or psC32, out: psC32 */
psVector *
psVectorFFT(psVector *out,		///< Vector for output (or NULL)
	    const psVector *vector,	///< Vector to transform
	    psFFTFlags dir)		///< FFT direction
;

/** Get the real part of a vector */
psVector *
psVectorReal(psVector *out,		///< Vector for output (or NULL)
	     const psVector *in)	///< Vector to get the real part of
;

/** Get the imaginary part of a vector */
psVector *
psVectorImaginary(psVector *out,	///< Vector for output (or NULL)
		  const psVector *in)	///< Vector to get the imaginary part of
;

/** Construct a complex vector from real & imaginary parts */
psVector *
psVectorComplex(psVector *out,		///< Vector for output (or NULL)
		const psVector *real,	///< real part of vector
		const psVector *imag)	///< imaginary part of vector
;

/** Get the complex conjugate of an vector of complex floating-point numbers */
psVector *
psVectorConjugate(psVector *out,	///< Vector for output (or NULL)
		  const psVector *in)	///< Vector to get the complex conjugate of
;

/** Calculate power spectrum of a vector of floating-point numbers */
psVector *
psVectorPowerSpectrum(psVector *out,	///< Vector for output (or NULL)
		      const psVector *vector) ///< Vector to obtain power spectrum of
;

/**** Image FFT & Complex functions ****/

/** FFT an image.  in: psF32 or psC32, out: psC32 */
psImage *
psImageFFT(psImage *out,		///< Image for output (or NULL)
	   const psImage *image,	///< image to transform (if forward, may be real)
	   psFFTFlags dir)		///< FFT direction
;

/** Get the real part of an image */
psImage *
psImageReal(psImage *out,		///< Image for output (or NULL)
	    const psImage *in)		///< Image to get the real part of
;

/** Get the imaginary part of an image */
psImage *
psImageImaginary(psImage *out,		///< Image for output (or NULL)
		 const psImage *in)	///< Image to get the imaginary part of
;

/** Construct a complex image from real & imaginary parts */
psImage *
psImageComplex(psImage *out,		///< Image for output (or NULL)
	       const psImage *real,	///< real part of image
	       const psImage *imag)	///< imaginary part of image
;

/** Get the complex conjugate of an image */
psImage *
psImageConjugate(psImage *out,		///< Image for output (or NULL)
		 const psImage *in)	///< Image to get the complex conjugate of
;


/** Calculate power spectrum of an image */
psImage *
psImagePowerSpectrum(psImage *out,	///< Image for output (or NULL)
		     const psImage *image) ///< Image to obtain power spectrum of
;

/* \} */ // End of MathGroup Functions

#endif


