{-# LANGUAGE PackageImports, FlexibleContexts #-} -- | Read and write matrices as ASCII text files. -- -- The file format is like: -- -- @ -- MATRIX -- header -- 100 100 -- width and height -- 1.23 1.56 1.23 ... -- data, separated by whitespace -- .... -- @ module Data.Array.Repa.IO.Matrix ( readMatrixFromTextFile , writeMatrixToTextFile) where import Data.Array.Repa.IO.Internals.Text import Control.Monad import System.IO import Data.List as L import Data.Array.Repa as A import Data.Array.Repa.Repr.Unboxed as A import Prelude as P -- | Read a matrix from a text file. -- -- * WARNING: This is implemented fairly naively, just using `Strings` -- under the covers. It will be slow for large data files. -- -- * It also doesn't do graceful error handling. -- If the file has the wrong format you'll get a confusing `error`. -- readMatrixFromTextFile :: (Num e, Read e, Unbox e) => FilePath -> IO (Array U DIM2 e) readMatrixFromTextFile fileName = do handle <- openFile fileName ReadMode "MATRIX" <- hGetLine handle [width, height] <- liftM (P.map read . words) $ hGetLine handle str <- hGetContents handle let vals = readValues str let dims = Z :. width :. height return $ fromListUnboxed dims vals -- | Write a matrix as a text file. writeMatrixToTextFile :: (Show e, Source r e) => FilePath -> Array r DIM2 e -> IO () writeMatrixToTextFile fileName arr = do file <- openFile fileName WriteMode hPutStrLn file "MATRIX" let Z :. width :. height = extent arr hPutStrLn file $ show width P.++ " " P.++ show height hWriteValues file $ toList arr hClose file