matrices 0.4.1 → 0.4.2
raw patch · 3 files changed
+308/−8 lines, 3 files
Files
- matrices.cabal +2/−2
- src/Data/Matrix/Dense/Generic.hs +296/−2
- src/Data/Matrix/Generic.hs +10/−4
matrices.cabal view
@@ -2,12 +2,12 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: matrices-version: 0.4.1+version: 0.4.2 synopsis: native matrix based on vector description: This library provide the APIs for creating, indexing, modifying matrices (2d arrays), including dense and sparse representations. The underling data- structure is vectors.+ structure is vector. license: BSD3 license-file: LICENSE author: Kai Zhang
src/Data/Matrix/Dense/Generic.hs view
@@ -60,6 +60,34 @@ , forM , forM_ + -- * Zipping+ , Data.Matrix.Dense.Generic.zipWith+ , Data.Matrix.Dense.Generic.zipWith3+ , zipWith4+ , zipWith5+ , zipWith6+ , izipWith+ , izipWith3+ , izipWith4+ , izipWith5+ , izipWith6+ , Data.Matrix.Dense.Generic.zip+ , Data.Matrix.Dense.Generic.zip3+ , zip4+ , zip5+ , zip6++ -- * Monadic Zipping+ , zipWithM+ , zipWithM_++ -- * Unzipping+ , Data.Matrix.Dense.Generic.unzip+ , Data.Matrix.Dense.Generic.unzip3+ , unzip4+ , unzip5+ , unzip6+ -- * Monadic sequencing , Data.Matrix.Dense.Generic.sequence , Data.Matrix.Dense.Generic.sequence_@@ -219,8 +247,8 @@ G.foldM'_ step (0::Int) vec return (max maxR r, cc + c) -- figure out the dimension of the new matrix- (m, n) = (sum *** maximum) . unzip . Prelude.map ((maximum *** sum) .- unzip . Prelude.map (MG.rows &&& MG.cols)) $ ms+ (m, n) = (sum *** maximum) . Prelude.unzip . Prelude.map ((maximum *** sum) .+ Prelude.unzip . Prelude.map (MG.rows &&& MG.cols)) $ ms {-# INLINE fromBlocks #-} isSymmetric :: (Eq a, G.Vector v a) => Matrix v a -> Bool@@ -264,6 +292,272 @@ forM_ :: (G.Vector v a, Monad m) => Matrix v a -> (a -> m b) -> m () forM_ = flip mapM_ {-# INLINE forM_ #-}++zipWith :: (G.Vector v a, G.Vector v b, G.Vector v c)+ => (a -> b -> c) -> Matrix v a -> Matrix v b -> Matrix v c+zipWith f m1 m2+ | MG.dim m1 /= MG.dim m2 = error "zipWith: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zipWith f (MG.flatten m1) $ MG.flatten m2+{-# INLINE zipWith #-}++zipWith3 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d)+ => (a -> b -> c -> d) -> Matrix v a -> Matrix v b -> Matrix v c+ -> Matrix v d+zipWith3 f m1 m2 m3+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 = error "zipWith3: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zipWith3 f (MG.flatten m1) (MG.flatten m2) $ MG.flatten m3+{-# INLINE zipWith3 #-}++zipWith4 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d, G.Vector v e)+ => (a -> b -> c -> d -> e) -> Matrix v a -> Matrix v b -> Matrix v c+ -> Matrix v d -> Matrix v e+zipWith4 f m1 m2 m3 m4+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 = error "zipWith4: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zipWith4 f (MG.flatten m1) (MG.flatten m2)+ (MG.flatten m3) $ MG.flatten m4+{-# INLINE zipWith4 #-}++zipWith5 :: ( G.Vector v a, G.Vector v b, G.Vector v c,G.Vector v d+ , G.Vector v e, G.Vector v f )+ => (a -> b -> c -> d -> e -> f) -> Matrix v a -> Matrix v b+ -> Matrix v c -> Matrix v d -> Matrix v e -> Matrix v f+zipWith5 f m1 m2 m3 m4 m5+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 ||+ MG.dim m4 /= MG.dim m5 = error "zipWith5: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zipWith5 f (MG.flatten m1) (MG.flatten m2)+ (MG.flatten m3) (MG.flatten m4) $ MG.flatten m5+{-# INLINE zipWith5 #-}++zipWith6 :: ( G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d+ , G.Vector v e, G.Vector v f, G.Vector v g )+ => (a -> b -> c -> d -> e -> f -> g) -> Matrix v a -> Matrix v b+ -> Matrix v c -> Matrix v d -> Matrix v e -> Matrix v f -> Matrix v g+zipWith6 f m1 m2 m3 m4 m5 m6+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 ||+ MG.dim m4 /= MG.dim m5 ||+ MG.dim m5 /= MG.dim m6 = error "zipWith6: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zipWith6 f (MG.flatten m1) (MG.flatten m2) (MG.flatten m3)+ (MG.flatten m4) (MG.flatten m5) $ MG.flatten m6+{-# INLINE zipWith6 #-}++izipWith :: (G.Vector v a, G.Vector v b, G.Vector v c)+ => ((Int, Int) -> a -> b -> c) -> Matrix v a -> Matrix v b -> Matrix v c+izipWith f m1 m2+ | MG.dim m1 /= MG.dim m2 = error "izipWith: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.izipWith f' (MG.flatten m1) $ MG.flatten m2+ where+ c = MG.cols m1+ f' i = f (i `div` c, i `mod` c)+{-# INLINE izipWith #-}++izipWith3 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d)+ => ((Int, Int) -> a -> b -> c -> d) -> Matrix v a -> Matrix v b+ -> Matrix v c -> Matrix v d+izipWith3 f m1 m2 m3+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 = error "izipWith3: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.izipWith3 f' (MG.flatten m1) (MG.flatten m2) $ MG.flatten m3+ where+ c = MG.cols m1+ f' i = f (i `div` c, i `mod` c)+{-# INLINE izipWith3 #-}++izipWith4 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d, G.Vector v e)+ => ((Int, Int) -> a -> b -> c -> d -> e) -> Matrix v a -> Matrix v b+ -> Matrix v c -> Matrix v d -> Matrix v e+izipWith4 f m1 m2 m3 m4+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 = error "izipWith4: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.izipWith4 f' (MG.flatten m1) (MG.flatten m2)+ (MG.flatten m3) $ MG.flatten m4+ where+ c = MG.cols m1+ f' i = f (i `div` c, i `mod` c)+{-# INLINE izipWith4 #-}++izipWith5 :: ( G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d+ , G.Vector v e, G.Vector v f )+ => ((Int, Int) -> a -> b -> c -> d -> e -> f) -> Matrix v a+ -> Matrix v b -> Matrix v c -> Matrix v d -> Matrix v e -> Matrix v f+izipWith5 f m1 m2 m3 m4 m5+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 ||+ MG.dim m4 /= MG.dim m5 = error "izipWith5: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.izipWith5 f' (MG.flatten m1) (MG.flatten m2)+ (MG.flatten m3) (MG.flatten m4) $ MG.flatten m5+ where+ c = MG.cols m1+ f' i = f (i `div` c, i `mod` c)+{-# INLINE izipWith5 #-}++izipWith6 :: ( G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d+ , G.Vector v e, G.Vector v f, G.Vector v g )+ => ((Int, Int) -> a -> b -> c -> d -> e -> f -> g) -> Matrix v a+ -> Matrix v b -> Matrix v c -> Matrix v d -> Matrix v e -> Matrix v f+ -> Matrix v g+izipWith6 f m1 m2 m3 m4 m5 m6+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 ||+ MG.dim m4 /= MG.dim m5 ||+ MG.dim m5 /= MG.dim m6 = error "izipWith6: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.izipWith6 f' (MG.flatten m1) (MG.flatten m2) (MG.flatten m3)+ (MG.flatten m4) (MG.flatten m5) $ MG.flatten m6+ where+ c = MG.cols m1+ f' i = f (i `div` c, i `mod` c)+{-# INLINE izipWith6 #-}+++zip :: (G.Vector v a, G.Vector v b, G.Vector v (a,b))+ => Matrix v a -> Matrix v b -> Matrix v (a,b)+zip m1 m2+ | MG.dim m1 /= MG.dim m2 = error "zip: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zip (MG.flatten m1) $ MG.flatten m2+{-# INLINE zip #-}++zip3 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v (a,b,c))+ => Matrix v a -> Matrix v b -> Matrix v c -> Matrix v (a,b,c)+zip3 m1 m2 m3+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 = error "zip3: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zip3 (MG.flatten m1) (MG.flatten m2) $ MG.flatten m3+{-# INLINE zip3 #-}++zip4 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d, G.Vector v (a,b,c,d))+ => Matrix v a -> Matrix v b -> Matrix v c -> Matrix v d -> Matrix v (a,b,c,d)+zip4 m1 m2 m3 m4+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 = error "zip4: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zip4 (MG.flatten m1) (MG.flatten m2)+ (MG.flatten m3) $ MG.flatten m4+{-# INLINE zip4 #-}++zip5 :: ( G.Vector v a, G.Vector v b, G.Vector v c+ , G.Vector v d, G.Vector v e, G.Vector v (a,b,c,d,e) )+ => Matrix v a -> Matrix v b -> Matrix v c -> Matrix v d -> Matrix v e+ -> Matrix v (a,b,c,d,e)+zip5 m1 m2 m3 m4 m5+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 ||+ MG.dim m4 /= MG.dim m5 = error "zip5: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zip5 (MG.flatten m1) (MG.flatten m2)+ (MG.flatten m3) (MG.flatten m4) $ MG.flatten m5+{-# INLINE zip5 #-}++zip6 :: ( G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d, G.Vector v e+ , G.Vector v f, G.Vector v (a,b,c,d,e,f) )+ => Matrix v a -> Matrix v b -> Matrix v c -> Matrix v d -> Matrix v e+ -> Matrix v f -> Matrix v (a,b,c,d,e,f)+zip6 m1 m2 m3 m4 m5 m6+ | MG.dim m1 /= MG.dim m2 ||+ MG.dim m2 /= MG.dim m3 ||+ MG.dim m3 /= MG.dim m4 ||+ MG.dim m4 /= MG.dim m5 ||+ MG.dim m5 /= MG.dim m6 = error "zip6: Dimensions don't match."+ | otherwise = MG.fromVector (MG.dim m1) $+ G.zip6 (MG.flatten m1) (MG.flatten m2) (MG.flatten m3)+ (MG.flatten m4) (MG.flatten m5) $ MG.flatten m6+{-# INLINE zip6 #-}++zipWithM :: (Monad m, G.Vector v a, G.Vector v b, G.Vector v c)+ => (a -> b -> m c) -> Matrix v a -> Matrix v b -> m (Matrix v c)+zipWithM f m1 m2+ | MG.dim m1 /= MG.dim m2 = error "zipWithM: Dimensions don't match."+ | otherwise = liftM (MG.fromVector $ MG.dim m1) $+ G.zipWithM f (MG.flatten m1) $ MG.flatten m2+{-# INLINE zipWithM #-}++zipWithM_ :: (Monad m, G.Vector v a, G.Vector v b)+ => (a -> b -> m c) -> Matrix v a -> Matrix v b -> m ()+zipWithM_ f m1 m2+ | MG.dim m1 /= MG.dim m2 = error "zipWithM_: Dimensions don't match."+ | otherwise = G.zipWithM_ f (MG.flatten m1) $ MG.flatten m2+{-# INLINE zipWithM_ #-}++unzip :: (G.Vector v a, G.Vector v b, G.Vector v (a,b))+ => Matrix v (a,b) -> (Matrix v a, Matrix v b )+unzip m = (MG.fromVector d v1, MG.fromVector d v2)+ where+ d = MG.dim m+ (v1, v2) = G.unzip $ MG.flatten m+{-# INLINE unzip #-}++unzip3 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v (a,b,c))+ => Matrix v (a,b, c) -> (Matrix v a, Matrix v b, Matrix v c)+unzip3 m = (MG.fromVector d v1, MG.fromVector d v2, MG.fromVector d v3)+ where+ d = MG.dim m+ (v1, v2, v3) = G.unzip3 $ MG.flatten m+{-# INLINE unzip3 #-}++unzip4 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d, G.Vector v (a,b,c,d))+ => Matrix v (a,b,c,d) -> (Matrix v a, Matrix v b, Matrix v c, Matrix v d)+unzip4 m = ( MG.fromVector d v1+ , MG.fromVector d v2+ , MG.fromVector d v3+ , MG.fromVector d v4+ )+ where+ d = MG.dim m+ (v1, v2, v3, v4) = G.unzip4 $ MG.flatten m+{-# INLINE unzip4 #-}++unzip5 :: ( G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d+ , G.Vector v e, G.Vector v (a,b,c,d,e) )+ => Matrix v (a,b,c,d,e)+ -> (Matrix v a, Matrix v b, Matrix v c, Matrix v d, Matrix v e)+unzip5 m = ( MG.fromVector d v1+ , MG.fromVector d v2+ , MG.fromVector d v3+ , MG.fromVector d v4+ , MG.fromVector d v5+ )+ where+ d = MG.dim m+ (v1, v2, v3, v4, v5) = G.unzip5 $ MG.flatten m+{-# INLINE unzip5 #-}++unzip6 :: ( G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d+ , G.Vector v e, G.Vector v f, G.Vector v (a,b,c,d,e,f) )+ => Matrix v (a,b,c,d,e,f)+ -> (Matrix v a, Matrix v b, Matrix v c, Matrix v d, Matrix v e, Matrix v f)+unzip6 m = ( MG.fromVector d v1+ , MG.fromVector d v2+ , MG.fromVector d v3+ , MG.fromVector d v4+ , MG.fromVector d v5+ , MG.fromVector d v6+ )+ where+ d = MG.dim m+ (v1, v2, v3, v4, v5, v6) = G.unzip6 $ MG.flatten m+{-# INLINE unzip6 #-} sequence :: (G.Vector v a, G.Vector v (m a), Monad m) => Matrix v (m a) -> m (Matrix v a)
src/Data/Matrix/Generic.hs view
@@ -96,7 +96,8 @@ -- | Indexing (!) :: Matrix m v a => m v a -> (Int, Int) -> a-(!) mat (i,j) | i >= r || j >= c = error "Index out of bounds"+(!) mat (i,j) | i < 0 || i >= r || j < 0 || j >= c =+ error "Index out of bounds" | otherwise = unsafeIndex mat (i,j) where (r,c) = dim mat@@ -112,8 +113,11 @@ {-# INLINE empty #-} fromVector :: Matrix m v a => (Int, Int) -> v a -> m v a-fromVector (r,c) vec | r*c /= G.length vec = error "incorrect length"+fromVector (r,c) vec | r*c /= n = error errMsg | otherwise = unsafeFromVector (r,c) vec+ where+ errMsg = printf "fromVector: incorrect length (%d * %d != %d)" r c n+ n = G.length vec {-# INLINE fromVector #-} fromList :: Matrix m v a => (Int, Int) -> [a] -> m v a@@ -154,7 +158,8 @@ -- | Extract a row. takeRow :: Matrix m v a => m v a -> Int -> v a-takeRow mat i | i >= r = error $ printf "index out of bounds: (%d,%d)" i r+takeRow mat i | i < 0 || i >= r =+ error $ printf "index out of bounds: (%d,%d)" i r | otherwise = unsafeTakeRow mat i where (r,_) = dim mat@@ -169,7 +174,8 @@ -- | Extract a row. takeColumn :: Matrix m v a => m v a -> Int -> v a-takeColumn mat j | j >= c = error $ printf "index out of bounds: (%d,%d)" j c+takeColumn mat j | j < 0 || j >= c =+ error $ printf "index out of bounds: (%d,%d)" j c | otherwise = unsafeTakeColumn mat j where (_,c) = dim mat