【问题标题】:How to sort a massiv array along innermost dimension?如何沿最内层对massiv数组进行排序?
【发布时间】:2018-12-03 00:29:17
【问题描述】:
我有一个Array r Ix2 a 这样(Manifest r Ix2 a, Ord a)。我想对该数组最内层的维度进行排序——也就是说,在内部对每一行进行排序,而不是跨行排序。根据this,massiv 根本没有实现任何排序。我是否必须自己推出,或者我可以重新使用 Vectors 已经存在的东西(例如 vector-algorithms)?
【问题讨论】:
标签:
arrays
sorting
haskell
multidimensional-array
massiv
【解决方案1】:
当然,最好推出自己的排序并将 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 的massiv 示例中添加了这个以及一个简单的属性测试。