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

    module Numeric.GSL.IO (
        saveMatrix,
        fwriteVector, freadVector, fprintfVector, fscanfVector,
        fileDimensions, loadMatrix, fromFile
    ) where

    import Numeric.LinearAlgebra.HMatrix hiding(saveMatrix, loadMatrix)
    import Numeric.GSL.Vector
    import System.Process(readProcess)

    {- |  obtains the number of rows and columns in an ASCII data file
          (provisionally using unix's wc).
    -}
    fileDimensions :: FilePath -> IO (Int,Int)
    fileDimensions :: FilePath -> IO (Int, Int)
    fileDimensions FilePath
    fname = do
        wcres <- FilePath -> [FilePath] -> FilePath -> IO FilePath
    readProcess FilePath
    "wc" [FilePath
    "-w",FilePath
    fname] FilePath
    ""
        contents <- readFile fname
        let tot = FilePath -> Int
    forall a. Read a => FilePath -> a
    read (FilePath -> Int) -> (FilePath -> FilePath) -> FilePath -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [FilePath] -> FilePath
    forall a. HasCallStack => [a] -> a
    head ([FilePath] -> FilePath)
    -> (FilePath -> [FilePath]) -> FilePath -> FilePath
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath]
    words (FilePath -> Int) -> FilePath -> Int
    forall a b. (a -> b) -> a -> b
    $ FilePath
    wcres
            c   = [FilePath] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ([FilePath] -> Int) -> (FilePath -> [FilePath]) -> FilePath -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[FilePath]] -> [FilePath]
    forall a. HasCallStack => [a] -> a
    head ([[FilePath]] -> [FilePath])
    -> (FilePath -> [[FilePath]]) -> FilePath -> [FilePath]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([FilePath] -> Bool) -> [[FilePath]] -> [[FilePath]]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile [FilePath] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([[FilePath]] -> [[FilePath]])
    -> (FilePath -> [[FilePath]]) -> FilePath -> [[FilePath]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
    forall a b. (a -> b) -> [a] -> [b]
    map FilePath -> [FilePath]
    words ([FilePath] -> [[FilePath]])
    -> (FilePath -> [FilePath]) -> FilePath -> [[FilePath]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> [FilePath]
    lines (FilePath -> Int) -> FilePath -> Int
    forall a b. (a -> b) -> a -> b
    $ FilePath
    contents
        if tot > 0
            then return (tot `div` c, c)
            else return (0,0)

    -- | Loads a matrix from an ASCII file formatted as a 2D table.
    loadMatrix :: FilePath -> IO (Matrix Double)
    loadMatrix :: FilePath -> IO (Matrix Double)
    loadMatrix FilePath
    file = FilePath -> (Int, Int) -> IO (Matrix Double)
    fromFile FilePath
    file ((Int, Int) -> IO (Matrix Double))
    -> IO (Int, Int) -> IO (Matrix Double)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< FilePath -> IO (Int, Int)
    fileDimensions FilePath
    file

    -- | Loads a matrix from an ASCII file (the number of rows and columns must be known in advance).
    fromFile :: FilePath -> (Int,Int) -> IO (Matrix Double)
    fromFile :: FilePath -> (Int, Int) -> IO (Matrix Double)
    fromFile FilePath
    filename (Int
    r,Int
    c) = Int -> Vector Double -> Matrix Double
    forall t. Storable t => Int -> Vector t -> Matrix t
    reshape Int
    c (Vector Double -> Matrix Double)
    -> IO (Vector Double) -> IO (Matrix Double)
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` FilePath -> Int -> IO (Vector Double)
    fscanfVector FilePath
    filename (Int
    rInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    c)