packages feed

repa-examples-1.0.0.0: lib/Matrix.hs

-- | 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