diff --git a/clustering.cabal b/clustering.cabal
--- a/clustering.cabal
+++ b/clustering.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                clustering
-version:             0.2.0
+version:             0.2.1
 synopsis:            High performance clustering algorithms
 description:
   Following clutering methods are included in this library:
@@ -31,6 +31,7 @@
     AI.Clustering.KMeans
     AI.Clustering.KMeans.Internal
     AI.Clustering.KMeans.Types
+    AI.Clustering.Utils
 
 --  other-modules:       
 
diff --git a/src/AI/Clustering/KMeans/Internal.hs b/src/AI/Clustering/KMeans/Internal.hs
--- a/src/AI/Clustering/KMeans/Internal.hs
+++ b/src/AI/Clustering/KMeans/Internal.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE FlexibleContexts #-}
 --------------------------------------------------------------------------------
 -- |
 -- Module      :  AI.Clustering.KMeans.Internal
diff --git a/src/AI/Clustering/Utils.hs b/src/AI/Clustering/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/AI/Clustering/Utils.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE FlexibleContexts #-}
+module AI.Clustering.Utils
+    ( orderBy
+    ) where
+
+import Control.Monad (forM_)
+import qualified Data.Vector.Generic as G
+import qualified Data.Matrix.Generic as M
+import qualified Data.Matrix.Generic.Mutable as MM
+
+-- | rearrange the rows of a matrix
+orderBy :: (G.Vector v1 Int, M.Matrix m v2 a) => v1 Int -> m v2 a -> m v2 a
+orderBy vec mat
+    | G.length vec /= r = error "orderBy: n != r"
+    | otherwise = M.create $ do
+        mat' <- MM.new (r,c)
+        forM_ [0..r-1] $ \i -> do
+            let i' = vec G.! i
+            forM_ [0..c-1] $ \j -> MM.unsafeWrite mat' (i,j) $ mat `M.unsafeIndex` (i',j)
+        return mat'
+  where
+    (r,c) = M.dim mat
+{-# INLINE orderBy #-}
