diff --git a/matrices.cabal b/matrices.cabal
--- a/matrices.cabal
+++ b/matrices.cabal
@@ -2,20 +2,17 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                matrices
-version:             0.4.4
+version:             0.4.5
 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 vector.
+description:         Pure Haskell matrix library, supporting creating, indexing,
+                     and modifying dense/sparse matrices.
 license:             BSD3
 license-file:        LICENSE
 author:              Kai Zhang
 maintainer:          kai@kzhang.org
-copyright:           (c) 2015,2016 Kai Zhang
+copyright:           (c) 2015-2017 Kai Zhang
 category:            Data
 build-type:          Simple
--- extra-source-files:
 cabal-version:       >=1.10
 
 library
@@ -36,12 +33,10 @@
 
   ghc-options: -Wall -funbox-strict-fields
 
-  -- other-modules:
-
   build-depends:
       base >=4.8 && <5
     , deepseq
-    , vector >=0.9
+    , vector >=0.11
     , primitive
 
   hs-source-dirs:      src
diff --git a/src/Data/Matrix/Dense/Generic.hs b/src/Data/Matrix/Dense/Generic.hs
--- a/src/Data/Matrix/Dense/Generic.hs
+++ b/src/Data/Matrix/Dense/Generic.hs
@@ -53,11 +53,14 @@
     , Data.Matrix.Dense.Generic.foldl
 
     -- * Mapping
-    , imap
     , Data.Matrix.Dense.Generic.map
+    , imap
+
     -- * Monadic mapping
     , mapM
+    , imapM
     , mapM_
+    , imapM_
     , forM
     , forM_
 
@@ -117,7 +120,7 @@
 
 type instance MG.Mutable Matrix = MMatrix
 
--- | row-major matrix supporting efficient slice
+-- | Row-major matrix supporting efficient slice
 data Matrix v a = Matrix !Int    -- number of rows
                          !Int    -- number of cols
                          !Int    -- physical row dimension
@@ -268,29 +271,50 @@
 force m@(Matrix r c _ _ _) = MG.fromVector (r,c) . G.force . MG.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 _ _ _) = MG.fromVector (r,c) $ G.map f . MG.flatten $ m
+{-# INLINE map #-}
+
 imap :: (G.Vector v a, G.Vector v b) => ((Int, Int) -> a -> b) -> Matrix v a -> Matrix v b
 imap f m@(Matrix r c _ _ _) = MG.fromVector (r,c) $ G.imap f' . MG.flatten $ m
   where
     f' i = f (i `div` c, i `mod` c)
 {-# INLINE imap #-}
 
-map :: (G.Vector v a, G.Vector v b) => (a -> b) -> Matrix v a -> Matrix v b
-map f m@(Matrix r c _ _ _) = MG.fromVector (r,c) $ G.map f . MG.flatten $ m
-{-# INLINE map #-}
-
 foldl :: G.Vector v b => (a -> b -> a) -> a -> Matrix v b -> a
 foldl f acc m = G.foldl f acc . MG.flatten $ m
 {-# INLINE foldl #-}
 
-mapM :: (G.Vector v a, G.Vector v b, Monad m) => (a -> m b) -> Matrix v a -> m (Matrix v b)
-mapM f m@(Matrix r c _ _ _) = liftM (MG.fromVector (r,c)) . G.mapM f . MG.flatten $ m
+mapM :: (G.Vector v a, G.Vector v b, Monad m)
+     => (a -> m b) -> Matrix v a -> m (Matrix v b)
+mapM f m@(Matrix r c _ _ _) = liftM (MG.fromVector (r,c)) $ G.mapM f $ MG.flatten m
 {-# INLINE mapM #-}
 
+-- | O(m*n) Apply the monadic action to every element and its index,
+-- yielding a matrix of results.
+imapM :: (G.Vector v a, G.Vector v b, Monad m)
+      => ((Int, Int) -> a -> m b) -> Matrix v a -> m (Matrix v b)
+imapM f m@(Matrix r c _ _ _) = fmap (MG.fromVector (r,c)) $ G.imapM f' $
+    MG.flatten m
+  where
+    f' i = f (i `div` c, i `mod` c)
+{-# INLINE imapM #-}
+
 mapM_ :: (G.Vector v a, Monad m) => (a -> m b) -> Matrix v a -> m ()
 mapM_ f = G.mapM_ f . MG.flatten
 {-# INLINE mapM_ #-}
 
-forM :: (G.Vector v a, G.Vector v b, Monad m) => Matrix v a -> (a -> m b) -> m (Matrix v b)
+-- | O(m*n) Apply the monadic action to every element and its index,
+-- ignoring the results.
+imapM_ :: (G.Vector v a, Monad m)
+       => ((Int, Int) -> a -> m b) -> Matrix v a -> m ()
+imapM_ f m@(Matrix _ c _ _ _) = G.imapM_ f' $ MG.flatten m
+  where
+    f' i = f (i `div` c, i `mod` c)
+{-# INLINE imapM_ #-}
+
+forM :: (G.Vector v a, G.Vector v b, Monad m)
+     => Matrix v a -> (a -> m b) -> m (Matrix v b)
 forM = flip mapM
 {-# INLINE forM #-}
 
