Matrix.hs (1360B)
1 module Common.Matrix (Matrix, nrows, ncols, generate, fromList, (!?), row, count) where 2 3 import Common.Util (consensus) 4 import Data.Vector (Vector) 5 import Data.Vector qualified as V 6 7 data Matrix a = Matrix Int Int (Vector a) deriving (Eq, Show) 8 9 instance Functor Matrix where 10 fmap f (Matrix nr nc vs) = Matrix nr nc (f <$> vs) 11 12 nrows :: Matrix a -> Int 13 nrows (Matrix nr _ _) = nr 14 15 ncols :: Matrix a -> Int 16 ncols (Matrix _ nc _) = nc 17 18 valuesRowMajor :: Matrix a -> Vector a 19 valuesRowMajor (Matrix _ _ vs) = vs 20 21 generate :: Int -> Int -> ((Int, Int) -> a) -> Matrix a 22 generate nr nc f = Matrix nr nc (V.generate (nr * nc) (f . (`divMod` nc))) 23 24 fromList :: [[a]] -> Maybe (Matrix a) 25 fromList [] = Just $ Matrix 0 0 V.empty 26 fromList l = do 27 let nr = length l 28 nc <- consensus (length <$> l) 29 let vs = V.concat (V.fromList <$> l) 30 Just $ Matrix nr nc vs 31 32 (!?) :: Matrix a -> (Int, Int) -> Maybe a 33 Matrix nr nc vs !? (i, j) = 34 if 0 <= i && i < nr && 0 <= j && j < nc 35 then Just $ vs V.! (i * nc + j) 36 else Nothing 37 38 row :: Int -> Matrix a -> Maybe (Vector a) 39 row i (Matrix nr nc vs) = 40 if 0 <= i && i < nr 41 then Just (V.slice (i * nc) nc vs) 42 else Nothing 43 44 -- TODO (requires copy) 45 -- col :: Int -> Matrix a -> Maybe (Vector a) 46 47 count :: (a -> Bool) -> Matrix a -> Int 48 count p = V.length . V.filter p . valuesRowMajor