    {-# LANGUAGE TypeFamilies #-}

    {-# OPTIONS_GHC -fno-warn-missing-signatures #-}

    {- |
    Module      : Numeric.GSL.Fourier
    Copyright   :  (c) Alberto Ruiz 2006
    License     :  GPL
    Maintainer  :  Alberto Ruiz
    Stability   :  provisional

    Fourier Transform.

    <http://www.gnu.org/software/gsl/manual/html_node/Fast-Fourier-Transforms.html#Fast-Fourier-Transforms>

    -}

    module Numeric.GSL.Fourier (
        fft,
        ifft
    ) where

    import Numeric.LinearAlgebra.HMatrix
    import Numeric.GSL.Internal
    import Foreign.C.Types
    import System.IO.Unsafe (unsafePerformIO)

    genfft :: CInt -> c t -> Vector a
    genfft CInt
    code c t
    v = IO (Vector a) -> Vector a
    forall a. IO a -> a
    unsafePerformIO (IO (Vector a) -> Vector a) -> IO (Vector a) -> Vector a
    forall a b. (a -> b) -> a -> b
    $ do
        r <- Int -> IO (Vector a)
    forall a. Storable a => Int -> IO (Vector a)
    createVector (c t -> IndexOf c
    forall (c :: * -> *) t. Container c t => c t -> IndexOf c
    size c t
    v)
        (v `applyRaw` (r `applyRaw` id)) (c_fft code) #|"fft"
        return r

    foreign import ccall unsafe "gsl-aux.h fft" c_fft ::  CInt -> TCV (TCV Res)

    {- | Fast 1D Fourier transform of a 'Vector' @(@'Complex' 'Double'@)@ using /gsl_fft_complex_forward/. It uses the same scaling conventions as GNU Octave.

    >>> fft (fromList [1,2,3,4])
    fromList [10.0 :+ 0.0,(-2.0) :+ 2.0,(-2.0) :+ 0.0,(-2.0) :+ (-2.0)]

    -}
    fft :: Vector (Complex Double) -> Vector (Complex Double)
    fft :: Vector (Complex Double) -> Vector (Complex Double)
    fft = CInt -> Vector (Complex Double) -> Vector (Complex Double)
    forall {c :: * -> *} {t} {a}.
    (IndexOf c ~ Int,
     TransRaw (c t) (CInt -> Ptr a -> IO CInt)
     ~ TCV (CInt -> Ptr (Complex Double) -> IO CInt),
     Container c t, TransArray (c t), Storable a) =>
    CInt -> c t -> Vector a
    genfft CInt
    0

    -- | The inverse of 'fft', using /gsl_fft_complex_inverse/.
    ifft :: Vector (Complex Double) -> Vector (Complex Double)
    ifft :: Vector (Complex Double) -> Vector (Complex Double)
    ifft = CInt -> Vector (Complex Double) -> Vector (Complex Double)
    forall {c :: * -> *} {t} {a}.
    (IndexOf c ~ Int,
     TransRaw (c t) (CInt -> Ptr a -> IO CInt)
     ~ TCV (CInt -> Ptr (Complex Double) -> IO CInt),
     Container c t, TransArray (c t), Storable a) =>
    CInt -> c t -> Vector a
    genfft CInt
    1