代码之家  ›  专栏  ›  技术社区  ›  Koz Ross

如何沿最内层尺寸对体量阵列进行排序?

  •  1
  • Koz Ross  · 技术社区  · 7 年前

    我有一个 Array r Ix2 a (Manifest r Ix2 a, Ord a) this ,massiv根本没有实现任何排序。我必须自己动手,还是可以重新使用已经存在的东西 Vector s(例如 vector-algorithms 例如?

    1 回复  |  直到 7 年前
        1
  •  2
  •   lehins Michael Shigorin    7 年前

    当然,最好是自己进行分类,并将PR提交给 massiv 图书馆;)但有一种方法可以回过头来 vector-algorithms 包裹我很想知道我是如何高效地完成这项工作的,下面就是它,以及对每行排序的自动并行化:

    {-# LANGUAGE FlexibleContexts    #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TypeFamilies        #-}
    module Examples.SortRows where
    
    import           Data.Massiv.Array                 as A
    import           Data.Massiv.Array.Manifest.Vector as A
    import           Data.Massiv.Core.Scheduler
    import           Data.Typeable
    import           Data.Vector.Algorithms.Merge
    import           Data.Vector.Generic               as VG
    import           Data.Vector.Generic.Mutable       as VGM
    import           System.IO.Unsafe
    
    sortRows ::
         forall r e v.
         (Ord e, Typeable v, A.Mutable r Ix2 e, VG.Vector v e, ARepr v ~ r, VRepr r ~ v)
      => Array r Ix2 e
      -> Array r Ix2 e
    sortRows arr = unsafePerformIO $ do
      mv :: VG.Mutable v RealWorld e <- VG.thaw (A.toVector arr :: v e)
      let comp = getComp arr
          sz@(m :. n) = size arr
      case comp of
        Seq -> do
          loopM_ 0 (< m) (+ 1) $ \i -> sort $ VGM.slice (toLinearIndex sz (i :. 0)) n mv
        ParOn wIds ->
          withScheduler_ wIds $ \scheduler -> do
            loopM_ 0 (< m) (+ 1) $ \i ->
              scheduleWork scheduler $ sort $ VGM.slice (toLinearIndex sz (i :. 0)) n mv
      v :: v e <- VG.unsafeFreeze mv
      return $ A.fromVector comp sz v
    

    commit 以及一个简单的属性测试。