你如何在Repa中计算[i] = f(a [i-1])?

时间:2012-06-27 14:36:54

标签: haskell repa

是否可以在Repa中计算一个依赖于过去值(即较小索引)的数组?给出了阵列的初始部分(例如,a[0])。 (请注意,我使用类似C的表示法来表示数组的元素;请不要混淆。)

我阅读了tutorial并快速检查了hackage但我找不到执行此功能的功能。

(我想在一维数组中进行这种计算并不会导致修复,因为你无法对其进行并行化。但我认为你可以在2维或更多维的情况下并行化它。)

修改: 可能我应该更具体地说明我想要使用哪种f。由于在a[i]是标量的情况下无法并行化,让我们关注案例a[i]是一个N dim向量。我不需要a[i]更高维度(例如矩阵),因为您可以将其“展开”到矢量。因此,f是将R ^ N映射到R ^ N的函数。

大多数情况下,就像这样:

b = M a[i-1]
a[i][j] = g(b)[j]

其中b是N dim向量,M是N×N矩阵(没有稀疏性假设),g是一些非线性函数。我想为i=1,..N-1 a[0]gM计算b。我希望有一些通用的方法来(1)并行化这种类型的计算和(2)使{{1}}等中间变量的分配有效(在类C语言中,你可以只重用它,它会如果维修或类似的库可以像魔术那样做而不破坏纯度,那就太好了。

2 个答案:

答案 0 :(得分:3)

我无法看到这样做的修复方法。但是有Vector:Data.Vector.iterateN构建你想要的矢量。然后Data.Array.Repa.fromUnboxed将其从Vector转换为Repa。

iterateN :: Int -> (a -> a) -> a -> Vector aSource
  

O(n)将值函数应用n次。第零个元素是原始值。

答案 1 :(得分:1)

编辑:实际上,我认为我误解了这个问题。我会在这里留下我的答案,以防它对其他人有用......

您可以使用traverse http://hackage.haskell.org/packages/archive/repa/3.2.1.1/doc/html/Data-Array-Repa.html#v:traverse

Prelude Data.Array.Repa R> let x = fromListUnboxed (Z :. 10 :: DIM1) [1..10]
Prelude Data.Array.Repa R> R.computeUnboxedS $ R.traverse x (\ (Z :. i) -> (Z :. (i - 1))) (\f  (Z :. i) -> f (Z :. (i + 1)) - f (Z :. i))
AUnboxed (Z :. 9) (fromList [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0])

解剖:

    R.computeUnboxedS $                            -- force the vector to be "real"
    R.traverse x                                   -- traverse the vector
    (\ (Z :. i) -> (Z :. (i - 1)))                 -- function to get the shape of the result
    (\f (Z :. i) -> f (Z :. (i + 1)) - f (Z :. i)) -- actual "stencil"

将它扩展到多维数组应该是微不足道的。