hmatrix-csv-0.1.0.0: Data/Csv/HMatrix.hs
module Data.Csv.HMatrix
(
-- * Usage example
-- $example
-- * Information
-- $info
decodeMatrix
, decodeMatrixWith
, encodeMatrix
, encodeMatrixWith
) where
import Data.Csv
import Numeric.LinearAlgebra.HMatrix
import qualified Data.Vector as V
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Char8 as C
import Data.Char (ord)
-- $example
--
-- For decoding we have to specify, if there is a header. This can be done with the HasHeader/NoHeader type:
--
-- > >>> decodeMatrix NoHeader "1.0,2.0,3.0\r\n4.0,5.0,6.0\r\n7.0,8.0,9.0\r\n"
-- > (3><3)
-- > [ 1.0, 2.0, 3.0
-- > , 4.0, 5.0, 6.0
-- > , 7.0, 8.0, 9.0 ]
--
-- Cassava, which is used for parsing the .csv files uses overloaded string literals. If you try this in ghci, make sure to start it with the right flag:
--
-- > >>> ghci -XOverloadedStrings
--
-- Encoding a file works pretty much the same, except that we do not need to specify a header.
--
-- > >>> encodeMatrix $ matrix 3 [1,2,3,4,5,6,7,8,9]
-- > "1.0,2.0,3.0\r\n4.0,5.0,6.0\r\n7.0,8.0,9.0\r\n"
-- $info
-- I'm quite new to haskell programming. If you have any advice or want to help improve this library, feel free to file an issue or send a pull-request on github. Every feedback is appreciated.
-- As of now only matrices of type Double are supported.
-- | Decodes a matrix.
decodeMatrix :: HasHeader -> ByteString -> Matrix Double
decodeMatrix header s = decodeMatrixWith header ',' s
-- | Decodes a matrix from ByteString and additionally allow
-- to specify the delimter which was used.
decodeMatrixWith :: HasHeader -> Char -> ByteString -> Matrix Double
decodeMatrixWith header del s =
case decodeWith opt header s of
Left err -> error err
Right v -> fromLists . V.toList . V.map V.toList $ v
where opt = defaultDecodeOptions { decDelimiter = fromIntegral (ord del) }
rowToRecord :: [Double] -> Record
rowToRecord x = record $ map (C.pack . show) x
-- | Encodes a matrix with comma as delimiter.
encodeMatrix :: Matrix Double -> ByteString
encodeMatrix m = encodeMatrixWith ',' m
-- | Encodes a matrix but allows to specify a delimiter.
encodeMatrixWith :: Char -> Matrix Double -> ByteString
encodeMatrixWith del m = encodeWith opt s
where opt = defaultEncodeOptions { encDelimiter = fromIntegral (ord del) }
s = map rowToRecord $ toLists m