    {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
    {-# OPTIONS_GHC -fno-warn-unused-top-binds #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Numeric.GSL.Vector
    -- Copyright   :  (c) Alberto Ruiz 2007-14
    -- License     :  GPL
    -- Maintainer  :  Alberto Ruiz
    -- Stability   :  provisional
    --
    -----------------------------------------------------------------------------

    module Numeric.GSL.Vector (
        randomVector,
        saveMatrix,
        fwriteVector, freadVector, fprintfVector, fscanfVector
    ) where

    import Numeric.LinearAlgebra.HMatrix hiding(randomVector, saveMatrix)
    import Numeric.GSL.Internal hiding (TV,TM,TCV,TCM)

    import Foreign.Marshal.Alloc(free)
    import Foreign.Ptr(Ptr)
    import Foreign.C.Types
    import Foreign.C.String(newCString)
    import System.IO.Unsafe(unsafePerformIO)

    fromei :: a -> CInt
    fromei a
    x = Int -> CInt
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a -> Int
    forall a. Enum a => a -> Int
    fromEnum a
    x) :: CInt

    -----------------------------------------------------------------------

    -- | Obtains a vector of pseudorandom elements from the the mt19937 generator in GSL, with a given seed. Use randomIO to get a random seed.
    randomVector :: Int      -- ^ seed
                 -> RandDist -- ^ distribution
                 -> Int      -- ^ vector size
                 -> Vector Double
    randomVector :: Int -> RandDist -> Int -> Vector Double
    randomVector Int
    seed RandDist
    dist Int
    n = IO (Vector Double) -> Vector Double
    forall a. IO a -> a
    unsafePerformIO (IO (Vector Double) -> Vector Double)
    -> IO (Vector Double) -> Vector Double
    forall a b. (a -> b) -> a -> b
    $ do
        r <- Int -> IO (Vector Double)
    forall a. Storable a => Int -> IO (Vector a)
    createVector Int
    n
        (r `applyRaw` id) (c_random_vector_GSL (fi seed) ((fi.fromEnum) dist)) #|"randomVectorGSL"
        return r

    foreign import ccall unsafe "random_vector_GSL" c_random_vector_GSL :: CInt -> CInt -> TV

    --------------------------------------------------------------------------------

    -- | Saves a matrix as 2D ASCII table.
    saveMatrix :: FilePath
               -> String     -- ^ format (%f, %g, %e)
               -> Matrix Double
               -> IO ()
    saveMatrix :: String -> String -> Matrix Double -> IO ()
    saveMatrix String
    filename String
    fmt Matrix Double
    m = do
        charname <- String -> IO CString
    newCString String
    filename
        charfmt <- newCString fmt
        let o = if Matrix Double -> MatrixOrder
    forall t. Matrix t -> MatrixOrder
    orderOf Matrix Double
    m MatrixOrder -> MatrixOrder -> Bool
    forall a. Eq a => a -> a -> Bool
    == MatrixOrder
    RowMajor then CInt
    1 else CInt
    0
        (m `applyRaw` id) (matrix_fprintf charname charfmt o) #|"matrix_fprintf"
        free charname
        free charfmt

    foreign import ccall unsafe "matrix_fprintf" matrix_fprintf :: Ptr CChar -> Ptr CChar -> CInt -> TM

    --------------------------------------------------------------------------------

    -- | Loads a vector from an ASCII file (the number of elements must be known in advance).
    fscanfVector :: FilePath -> Int -> IO (Vector Double)
    fscanfVector :: String -> Int -> IO (Vector Double)
    fscanfVector String
    filename Int
    n = do
        charname <- String -> IO CString
    newCString String
    filename
        res <- createVector n
        (res `applyRaw` id) (gsl_vector_fscanf charname) #|"gsl_vector_fscanf"
        free charname
        return res

    foreign import ccall unsafe "vector_fscanf" gsl_vector_fscanf:: Ptr CChar -> TV

    -- | Saves the elements of a vector, with a given format (%f, %e, %g), to an ASCII file.
    fprintfVector :: FilePath -> String -> Vector Double -> IO ()
    fprintfVector :: String -> String -> Vector Double -> IO ()
    fprintfVector String
    filename String
    fmt Vector Double
    v = do
        charname <- String -> IO CString
    newCString String
    filename
        charfmt <- newCString fmt
        (v `applyRaw` id) (gsl_vector_fprintf charname charfmt) #|"gsl_vector_fprintf"
        free charname
        free charfmt

    foreign import ccall unsafe "vector_fprintf" gsl_vector_fprintf :: Ptr CChar -> Ptr CChar -> TV

    -- | Loads a vector from a binary file (the number of elements must be known in advance).
    freadVector :: FilePath -> Int -> IO (Vector Double)
    freadVector :: String -> Int -> IO (Vector Double)
    freadVector String
    filename Int
    n = do
        charname <- String -> IO CString
    newCString String
    filename
        res <- createVector n
        (res `applyRaw` id) (gsl_vector_fread charname) #|"gsl_vector_fread"
        free charname
        return res

    foreign import ccall unsafe "vector_fread" gsl_vector_fread:: Ptr CChar -> TV

    -- | Saves the elements of a vector to a binary file.
    fwriteVector :: FilePath -> Vector Double -> IO ()
    fwriteVector :: String -> Vector Double -> IO ()
    fwriteVector String
    filename Vector Double
    v = do
        charname <- String -> IO CString
    newCString String
    filename
        (v `applyRaw` id) (gsl_vector_fwrite charname) #|"gsl_vector_fwrite"
        free charname

    foreign import ccall unsafe "vector_fwrite" gsl_vector_fwrite :: Ptr CChar -> TV

    type PD = Ptr Double                            --
    type TV = CInt -> PD -> IO CInt                 --
    type TM = CInt -> CInt -> PD -> IO CInt         --