在 GNU Octave 中,这段代码 -
[e, ix] = min(X);
将返回最小元素及其位置。您如何在 repa 中为任意二进制函数执行此操作?
这就是我想出的:
min x = z $ foldl' f (e,0,0) es
where
(e:es) = toList x
f (a,ix,r) b = let ix' = ix+1 in if a < b then (a,ix',r) else (b,ix',ix')
z (a,ix,r) = (a,r)
在上面的示例中,我们将 repa 1D 矩阵转换为列表,并使用带有两个累加器的 foldl'(来自 Data.List)——一个用于计算迭代次数(ix),另一个用于保存最小元素的位置(r)。但是使用 repa 的重点是使用数组,而不是列表!
在 repa 中,Array 类型有两个折叠(foldS 和 foldP) - 但它们只能具有类型 (a -> a -> a) 的功能 - 意思是,我不能将带有累加器的元组传递给它。还有 traverse,原则上可以将一维数组归约为标量数组:
min x = traverse x to0D min
where
to0D (Z:.i) = Z
min f (Z) = ??? -- how to get elements for comparison?
首先想到的是
[f (Z:.i) | i <- [1..n]], where n = (\(Z:.i) -> i) $ extent x
但这也会将数组转换为列表,而不是对数组进行计算。