-- Glasgow Haskell 0.403 : BLAS ( Basic Linear Algebra System )
-- **********************************************************************
-- * *
-- * FILE NAME : matrix.hs DATE : 5-3-1991 *
-- * *
-- * CONTENTS : Matrix datatype and operations implemented by using *
-- * vector datatype(grounded as Haskell Array type). *
-- * Matrices are index from 1, ie the row numbers are from *
-- * 1 to nr and column numbers are from 1 to nc. Where nr *
-- * and nc are the number of rows and columns respectively. *
-- **********************************************************************
module Matrix(Mat, makemat, boundmat, matsub, incrmat, updmat,
mmatvec, mmatmat, row, col, intchrow, intchcol, interchmat,
displaymat) where
import Ix
import Basics
import Vector
data Mat a = MAT (Int,Int) (Vec a)
makemat :: (Int, Int) -> ( (Int,Int) -> a) -> Mat a
boundmat :: Mat a -> (Int,Int)
incrmat :: (Num a) => Mat a -> [((Int,Int),a)] -> Mat a
updmat :: Mat a -> [((Int,Int),a)] -> Mat a
matsub :: Mat a -> (Int,Int) -> a
mmatvec :: (Num a) => Mat a -> Vec a -> Vec a
mmatmat :: (Num a) => Mat a -> Mat a -> Mat a
row :: Mat a -> Int -> Vec a
col :: Mat a -> Int -> Vec a
intchrow :: Int -> Int -> Mat a -> Mat a
intchcol :: Int -> Int -> Mat a -> Mat a
interchmat :: (Int,Int) -> (Int,Int) -> Mat a -> Mat a
displaymat :: (Show a) => Mat a -> [Char]
makemat (nr,nc) g =
MAT (nr,nc)
(makevec (nr*nc)
(\i -> (map g (range ((1,1),(nr,nc)) )) !! (i-1) )
)
boundmat (MAT (nr,nc) elements) = (nr,nc)
updmat m s =
MAT (nr,nc) new_elements
where
MAT (nr,nc) elements = m
new_elements = updvec elements new_s
new_s = map (\( ((i,j),x) ) -> ( ((i-1)*nc+j,x) ) ) s
incrmat m s =
MAT (nr,nc) new_elements
where
MAT (nr,nc) elements = m
new_elements = incrvec elements new_s
new_s = map (\( ((i,j),x) ) -> ( ((i-1)*nc+j,x) ) ) s
matsub m (i,j) =
vecsub elements ((i-1)*nc+j)
where
MAT (nr,nc) elements = m
mmatvec m v =
makevec nr ( \ i -> sum [ (matsub m (i,j)) * (vecsub v j)
| j <- [1..nc] ] )
where
(nr,nc) = boundmat m
mmatmat m1 m2 =
if (t1 == t2) then
makemat (l,n)
( \ (i,j) -> sum [ (matsub m1 (i,k)) *
(matsub m2 (k,j)) | k <-[1..t1] ] )
else error "Dimension error"
where
(l,t1) = boundmat m1
(t2,n) = boundmat m2
row m i =
makevec n ( \ j -> matsub m (i,j) )
where
(_,n) = boundmat m
col m j =
makevec n ( \ i -> matsub m (i,j) )
where
(n,_) = boundmat m
intchrow i j m =
makemat (boundmat m)
(\ (r,c) -> if (r==i) then matsub m (j,c)
else if (r==j) then matsub m (i,c)
else matsub m (r,c) )
intchcol i j m =
makemat (boundmat m)
(\ (r,c) -> if (c==i) then matsub m (r,j)
else if (c==j) then matsub m (r,i)
else matsub m (r,c) )
interchmat (i1,j1) (i2,j2) m =
makemat (boundmat m)
(\ (i,j) -> if (i,j)==(i1,j1) then matsub m (i2,j2)
else if (i,j)==(i2,j2) then matsub m (i1,j1)
else matsub m (i,j) )
displaymat m =
"<\n" ++
concat [displayvec (row m i) | i<-[1..nr] ] ++
">\n"
where
(nr,_) = boundmat m
|