Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何计算Repa中的a[i]=f(a[i-1])?_Haskell_Repa - Fatal编程技术网

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

Haskell 如何计算Repa中的a[i]=f(a[i-1])?,haskell,repa,Haskell,Repa,是否可以在Repa中计算一个数组,该数组取决于过去的值(即较小的索引)?给出了数组的初始部分(例如,a[0])。(请注意,我使用类C符号表示数组的元素;请不要混淆。) 我阅读并快速检查了黑客攻击,但我找不到一个函数来完成它 (我想在一维数组中进行这种计算在Repa中没有意义,因为你不能并行化它。但我认为你可以在二维或更高维的情况下并行化它。) 编辑: 也许我应该更具体地说明我想要使用哪种f。由于在a[i]是标量的情况下无法并行化,因此让我们关注a[i]是N维向量的情况。我不需要a[I]具有更高的

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

我阅读并快速检查了黑客攻击,但我找不到一个函数来完成它

(我想在一维数组中进行这种计算在Repa中没有意义,因为你不能并行化它。但我认为你可以在二维或更高维的情况下并行化它。)

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

大多数情况下,是这样的:

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

其中,
b
是一个N维向量,
M
是一个N乘N矩阵(没有稀疏性假设),而
g
是一些非线性函数。我想为给定的
a[0]
g
M
计算它。我希望有一些通用的方法来(1)并行化这种类型的计算,(2)使中间变量的分配,如
b
高效(在类似C的语言中,您可以重用它,如果Repa或类似的库可以像魔术一样在不破坏纯度的情况下进行,那就太好了)。

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

您可以使用
遍历

剖析它:

    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"

将其扩展到多维数组应该很简单。

我看不到一种Repa方法可以做到这一点。但是对于向量,有一个方法:构建你想要的向量。然后将其从向量转换为Repa

iterateN :: Int -> (a -> a) -> a -> Vector aSource
O(n)对值应用函数n次。第零个元素是原始值


对于关联的
f
,它可以并行化,称为“扫描”。但是,我在Repa文档中找不到scan。您可以使用Repa模具进行扫描。但也请参见@Headsink扫描不需要一系列作为输入吗?对我来说,这看起来更像是扫描。哦,这不是扫描。我把这个等式误读为
a[I]=f(a[I],a[I-1])
。实际上,这更像是
拿n$iterate f z
@Heatsink是的,这正是我的意思。你认为在Repa中进行这种计算有可能吗,特别是当
f
是多维的时候?另外,我担心使用无限列表和take会产生一些开销,与类C语言相比,在计算之前可以分配内存。我希望与裸Haskell列表相比,Repa能够减少此类开销。您仅基于源数组计算结果数组。我要计算的是一个数组,它的元素取决于它前面的一步。您可能认为标题中的
i
是数组的大小。我指的是索引。使用
Data.Vector.unbox.scanl1'
Repa.tounbox
的组合怎么样?例如,
cumsum
将是:
R.fromnboxed(R.extent y)$U.scanl1'(+)$(R.toUnboxed y)
。[非常难看,可能无法扩展到更高的维度。]cumsum仍然是从源阵列到目标阵列的计算。它取决于源数组的早期部分,而不是目标。正如上面评论中提到的散热器和phg,unfold是我所需要的。我想知道如何在Repa(或Haskell中的任何其他面向数组的库)中展开。谢谢。在进行1D计算时,这应该足够了。也许我不需要关心Repa。我只想在Haskell的速度方面与(非优化的)C相媲美。这是多维的吗?(a是否可以是另一个向量?)如果可以,它是否可以并行化?这取决于你所问的多维泛化的类型。在1D的情况下,显然不可能并行化,因为函数本身具有很强的内在顺序性。你能更具体地说明你所问的多维泛化是什么样子的吗?当然。假设
a[i]
是一个向量(因此
a
是一个二维数组),我想计算
a[i]=ma[i-1]
给定一个初始值
a[0]
和一个矩阵
M
,直到
i=N-1
。使用我用于标题的符号,它的
f(x)=mx
,其中
f
现在是矢量化的。你可以想到任何类型的
f
,但基本上它只使用前面一步的值。好吧,如果你幸运的是
f
是线性的,有几个选项可以优化矩阵乘法,我会先试试。但这取决于
M
的形式。因为我不认为你的
M
是稀疏的(或者是稀疏的?),你可以寻找适合你的矩阵类型的东西。但是,一般来说,每个
a[i][j]
都可以依赖于整个
a[i-1]
,所以我想对于任意矩阵,你几乎不能并行化。你是对的,我并没有假设稀疏
M
。我应该澄清一下。我认为Repa能够并行任何类型的向量到向量计算,而不仅仅是线性计算。我错了吗?我知道不能跨步骤并行计算,但我认为可以在步骤内并行计算(例如,向量到向量计算)。
iterateN :: Int -> (a -> a) -> a -> Vector aSource