module Data.YAP.Matrix (Matrix(..), apply) where
import Data.List (transpose)
import Prelude.YAP
import Data.YAP.Algebra
import Data.YAP.Vector
newtype Matrix a = Matrix [[a]]
deriving (Eq, Show)
instance Functor Matrix where
fmap f (Matrix as) = Matrix (fmap (fmap f) as)
instance (AbelianGroup a) => AbelianGroup (Matrix a) where
zero = Matrix (repeat (repeat zero))
Matrix as + Matrix bs = Matrix (zipWith (zipWith (+)) as bs)
Matrix as Matrix bs = Matrix (zipWith (zipWith ()) as bs)
negate (Matrix as) = Matrix (map (map negate) as)
instance Ring a => Ring (Matrix a) where
Matrix as * Matrix bs =
Matrix [[sum' $ zipWith (*) a b | b <- transpose bs] | a <- as]
fromInteger x = diagonal (fromInteger x)
diagonal :: (AbelianGroup a) => a -> Matrix a
diagonal x = Matrix (iterate (zero:) (x : repeat zero))
apply :: (Ring a) => Matrix a -> Vector a -> Vector a
apply (Matrix as) (Vector b) = Vector [sum' (zipWith (*) a b) | a <- as]
sum' :: (AbelianGroup a) => [a] -> a
sum' = foldr (+) zero