-- | Reading and writing matricies as ASCII files. -- We use ASCII so we can generate and check simple test data by hand, -- and we don't want to fool around with byte order issues. -- -- Matrix file format is like: -- -- MATRIX -- header -- 100 100 -- width and height -- 1.23 1.56 1.23 ... -- data, separated by whitespace -- .... -- -- TODO: Merge this with PPM.hs -- TODO: Merge this with Vector.hs. -- We should really have fns that read and write arrays of arbitrary dimension. -- module Matrix ( readMatrixFromTextFile , writeMatrixAsTextFile , genRandomMatrix) where import Data.List as L import Data.Array.Repa as A import qualified Data.Array.Parallel.Unlifted as U import Prelude as P import System.IO import Control.Monad import Data.Char import System.Random import Vector -- Reading ---------------------------------------------------------------------------------------- -- | Read a matrix from a text file. readMatrixFromTextFile :: (U.Elt a, Num a, Read a) => FilePath -- ^ File name of matrix file. -> IO (Array DIM2 a) 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 let mat = fromList dims vals return mat -- | Write a matrix as a text file. writeMatrixAsTextFile :: (U.Elt a, Show a) => Array DIM2 a -- ^ Matrix to write. -> FilePath -- ^ File name of output file. -> IO () writeMatrixAsTextFile arr fileName = do file <- openFile fileName WriteMode hPutStrLn file "MATRIX" let Z :. width :. height = extent arr hPutStrLn file $ show width ++ " " ++ show height hWriteValues file $ toList arr hClose file -- | Generate a random(ish) matrix. genRandomMatrix :: DIM2 -> IO (Array DIM2 Double) genRandomMatrix sh = do uarr <- genRandomUArray (A.size sh) return $ fromUArray sh uarr