Haskell Repa中的基本顺序数组变换

Haskell Repa中的基本顺序数组变换,haskell,repa,Haskell,Repa,我想知道在repa中是否有(//)的类似物 无法并行化的数组转换需要它。例如,如果函数要求整个数组更改数组的单个条目,然后将其应用于新数组,依此类推(并且应按顺序运行)。(//)可以通过Data.array.Repa.from函数实现: import Data.Array.Repa (//) :: Shape sh => Array sh a -> [(sh,a)] -> Array sh a (//) arr us = fromFunction (extent arr) (

我想知道在repa中是否有(//)的类似物

无法并行化的数组转换需要它。例如,如果函数要求整个数组更改数组的单个条目,然后将其应用于新数组,依此类推(并且应按顺序运行)。

(//)
可以通过Data.array.Repa.from函数实现:

import Data.Array.Repa

(//) :: Shape sh => Array sh a -> [(sh,a)] -> Array sh a
(//) arr us = fromFunction (extent arr) (\sh -> case lookup sh us of
                                                 Just a  -> a
                                                 Nothing -> index arr sh)
fromFunction
可以传递类型为
Shape sh=>s->a
的函数,该函数本身可以使用整个数组


上述实现一次执行所有更新。

一个(//)潜在的问题是,它需要搜索列表以查找每个元素的值。如果数组或列表很大,这可能会很昂贵

另一种选择是利用数据中的便捷功能。矢量:

modify :: Vector v a => (forall s. Mutable v s a -> ST s ()) -> v a -> v a
如果安全的话,这有可能在适当的地方进行更新。大概是

import Data.Vector.Unboxed as V
import Data.Vector.Mutable.Unboxed as M
import Data.Array.Repa as R

(///) :: Shape sh => Array sh a -> [(sh,a)] -> Array sh a
(///) arr us = R.fromVector sh . modify f $ R.toVector arr
  where
  sh = extent arr
  f mv = forM_ us $ \(k,x) -> do
    M.write mv (R.toIndex sh k) x
在我的笔记本电脑上,我对一个100万元素的DIM1阵列进行了测试,更新了100个条目,得到了以下结果: (//): 3.598973 (///):2.08599999997E-3