matrices 0.1.0 → 0.2.0
raw patch · 6 files changed
+127/−19 lines, 6 files
Files
- matrices.cabal +10/−2
- src/Data/Matrix/Generic/Base.hs +65/−2
- src/Data/Matrix/Generic/Mutable.hs +27/−10
- src/Data/Matrix/Generic/Types.hs +5/−5
- src/Data/Matrix/Storable.hs +10/−0
- src/Data/Matrix/Storable/Mutable.hs +10/−0
matrices.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: matrices-version: 0.1.0+version: 0.2.0 synopsis: native matrix based on vector description: This library provide the APIs for creating, indexing, modifying matrices (2d arrays). The underling data@@ -12,7 +12,7 @@ license-file: LICENSE author: Kai Zhang maintainer: kai@kzhang.org-copyright: <c> 2014 Kai Zhang+copyright: (c) 2014 Kai Zhang category: Data build-type: Simple -- extra-source-files: @@ -26,9 +26,13 @@ , Data.Matrix.Generic.Mutable , Data.Matrix.Generic.Base , Data.Matrix.Generic.Types+ , Data.Matrix.Storable+ , Data.Matrix.Storable.Mutable , Data.Matrix.Unboxed , Data.Matrix.Unboxed.Mutable + ghc-options: -Wall -fwarn-tabs -funbox-strict-fields+ -- other-modules: build-depends:@@ -38,3 +42,7 @@ hs-source-dirs: src default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/kaizhang/matrices.git
src/Data/Matrix/Generic/Base.hs view
@@ -17,19 +17,28 @@ ( rows , cols , (!)+ , unsafeIndex , matrix , flatten , fromVector , toRows+ , toColumns+ , fromRows+ , fromColumns , toList , toLists+ , fromLists , tr+ , takeRow+ , takeColumn , subMatrix , ident , diag , diagRect , fromBlocks , isSymmetric+ , force+ , Data.Matrix.Generic.Base.map ) where import Control.Arrow ((***), (&&&))@@ -51,6 +60,12 @@ idx = offset + i * tda + j {-# INLINE (!) #-} +unsafeIndex :: G.Vector v a => Matrix v a -> (Int, Int) -> a+unsafeIndex (Matrix _ _ tda offset vec) (i,j) = vec `G.unsafeIndex` idx+ where+ idx = offset + i * tda + j+{-# INLINE unsafeIndex #-}+ matrix :: G.Vector v a => Int -> [a] -> Matrix v a matrix ncol xs | n `mod` ncol /= 0 = error "incorrect length" | otherwise = fromVector nrow ncol vec@@ -84,10 +99,50 @@ f i = offset + i * tda {-# INLINE toRows #-} +toColumns :: G.Vector v a => Matrix v a -> [v a]+toColumns m = Prelude.map (`takeRow` m) [0 .. c-1]+ where c = cols m+{-# INLINE toColumns #-}++fromRows :: G.Vector v a => [v a] -> Matrix v a+fromRows xs | any (\x -> G.length x /= c) xs = error "inequal length"+ | otherwise = fromVector r c . G.concat $ xs+ where+ r = length xs+ c = G.length . head $ xs+{-# INLINE fromRows #-}++fromColumns :: G.Vector v a => [v a] -> Matrix v a+fromColumns = tr . fromRows+{-# INLINE fromColumns #-}+ toLists :: G.Vector v a => Matrix v a -> [[a]]-toLists = map G.toList . toRows+toLists = Prelude.map G.toList . toRows {-# INLINE toLists #-} +-- | doesn't check if the list of list is a valid matrix+fromLists :: G.Vector v a => [[a]] -> Matrix v a+fromLists xs = fromVector r c . G.fromList . concat $ xs+ where+ r = length xs+ c = length .head $ xs+{-# INLINE fromLists #-}++takeRow :: G.Vector v a => Int -> Matrix v a -> v a+takeRow i (Matrix _ c tda offset vec) = G.slice i' c vec+ where+ i' = offset + i * tda+{-# INLINE takeRow #-}++takeColumn :: G.Vector v a => Int -> Matrix v a -> v a+takeColumn j (Matrix r _ tda offset vec) = G.create $ GM.new r >>= go idx vec r 0+ where+ go f vec' r' !i v | i >= r' = return v+ | otherwise = do GM.unsafeWrite v i $ vec' G.! f i+ go f vec' r' (i+1) v+ idx i = offset + i * tda + j+{-# INLINE takeColumn #-}+ subMatrix :: G.Vector v a => (Int, Int) -> (Int, Int) -> Matrix v a -> Matrix v a subMatrix (ri, rj) (ci, cj) (Matrix _ n tda offset vec) = Matrix m' n' tda offset' vec@@ -150,7 +205,7 @@ 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 . map ((maximum *** sum) . unzip . map (rows &&& cols)) $ ms+ (m, n) = (sum *** maximum) . unzip . Prelude.map ((maximum *** sum) . unzip . Prelude.map (rows &&& cols)) $ ms {-# INLINE fromBlocks #-} isSymmetric :: (Eq a, G.Vector v a) => Matrix v a -> Bool@@ -160,3 +215,11 @@ f i = all g [i + 1 .. c-1] where g j = m ! (i,j) == m ! (j,i) {-# INLINE isSymmetric #-}++force :: G.Vector v a => Matrix v a -> Matrix v a+force m@(Matrix r c _ _ _) = fromVector r c . G.force . flatten $ m+{-# INLINE force #-}++map :: (G.Vector v a, G.Vector v b) => (a -> b) -> Matrix v a -> Matrix v b+map f m@(Matrix r c _ _ _) = fromVector r c $ G.map f . flatten $ m+{-# INLINE map #-}
src/Data/Matrix/Generic/Mutable.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE GADTs #-} module Data.Matrix.Generic.Mutable- ( thaw+ ( fromMVector+ , thaw , unsafeThaw , freeze , unsafeFreeze@@ -8,9 +9,11 @@ , unsafeWrite , read , unsafeRead+ , replicate+ , new ) where -import Prelude hiding (read)+import Prelude hiding (read, replicate) import Control.Monad import Data.Matrix.Generic.Types import qualified Data.Vector.Generic as G@@ -21,6 +24,10 @@ (<$>) :: Monad m => (a -> b) -> m a -> m b (<$>) = liftM +fromMVector :: GM.MVector v a => Int -> Int -> v m a -> MMatrix v m a+fromMVector r c = MMatrix r c c 0+{-# INLINE fromMVector #-}+ thaw :: PrimMonad m => Matrix v a -> m (MMatrix (G.Mutable v) (PrimState m) a) thaw (Matrix r c tda offset v) = MMatrix r c tda offset <$> G.thaw v {-# INLINE thaw #-}@@ -38,25 +45,35 @@ {-# INLINE unsafeFreeze #-} write :: (PrimMonad m, GM.MVector v a)- => MMatrix v (PrimState m) a -> Int -> Int -> a -> m ()-write (MMatrix _ _ tda offset v) i j = GM.write v idx+ => MMatrix v (PrimState m) a -> (Int, Int) -> a -> m ()+write (MMatrix _ _ tda offset v) (i,j) = GM.write v idx where idx = offset + i * tda + j {-# INLINE write #-} unsafeWrite :: (PrimMonad m, GM.MVector v a)- => MMatrix v (PrimState m) a -> Int -> Int -> a -> m ()-unsafeWrite (MMatrix _ _ tda offset v) i j = GM.unsafeWrite v idx+ => MMatrix v (PrimState m) a -> (Int, Int) -> a -> m ()+unsafeWrite (MMatrix _ _ tda offset v) (i,j) = GM.unsafeWrite v idx where idx = offset + i * tda + j {-# INLINE unsafeWrite #-} read :: (PrimMonad m, GM.MVector v a)- => MMatrix v (PrimState m) a -> Int -> Int -> m a-read (MMatrix _ _ tda offset v) i j = GM.read v idx+ => MMatrix v (PrimState m) a -> (Int, Int) -> m a+read (MMatrix _ _ tda offset v) (i,j) = GM.read v idx where idx = offset + i * tda + j {-# INLINE read #-} unsafeRead :: (PrimMonad m, GM.MVector v a)- => MMatrix v (PrimState m) a -> Int -> Int -> m a-unsafeRead (MMatrix _ _ tda offset v) i j = GM.unsafeRead v idx+ => MMatrix v (PrimState m) a -> (Int, Int) -> m a+unsafeRead (MMatrix _ _ tda offset v) (i,j) = GM.unsafeRead v idx where idx = offset + i * tda + j {-# INLINE unsafeRead #-}++replicate :: (PrimMonad m, GM.MVector v a)+ => Int -> Int -> a -> m (MMatrix v (PrimState m) a)+replicate r c x = fromMVector r c <$> GM.replicate (r*c) x+{-# INLINE replicate #-}++new :: (PrimMonad m, GM.MVector v a)+ => Int -> Int -> m (MMatrix v (PrimState m) a)+new r c = fromMVector r c <$> GM.new (r*c)+{-# INLINE new #-}
src/Data/Matrix/Generic/Types.hs view
@@ -27,11 +27,11 @@ -- | row-major matrix supporting efficient slice data Matrix v a where Matrix :: G.Vector v a- => !Int -- ^ number of rows- -> !Int -- ^ number of cols- -> !Int -- ^ physical row dimension- -> !Int -- ^ offset- -> !(v a) -- ^ flat matrix+ => !Int -- number of rows+ -> !Int -- number of cols+ -> !Int -- physical row dimension+ -> !Int -- offset+ -> !(v a) -- flat matrix -> Matrix v a -- | mutable matrix
+ src/Data/Matrix/Storable.hs view
@@ -0,0 +1,10 @@+module Data.Matrix.Storable+ ( Matrix+ , module Data.Matrix.Generic.Base+ ) where++import qualified Data.Matrix.Generic.Types as MG+import Data.Matrix.Generic.Base+import qualified Data.Vector.Storable as S++type Matrix a = MG.Matrix S.Vector a
+ src/Data/Matrix/Storable/Mutable.hs view
@@ -0,0 +1,10 @@+module Data.Matrix.Storable.Mutable+ ( MMatrix+ , module Data.Matrix.Generic.Mutable+ ) where++import qualified Data.Matrix.Generic.Types as MG+import Data.Matrix.Generic.Mutable+import qualified Data.Vector.Storable.Mutable as SM++type MMatrix a = MG.MMatrix SM.MVector a