如何根据Repa

时间:2017-04-12 14:54:24

标签: haskell filter repa

我有两个Repa数组a1a2,我希望消除a2a1中相应索引高于某个阈值的所有元素。例如:

import qualified Data.Array.Repa as R -- for Repa
import Data.Array.Repa (Z (..), (:.)(..))


a1 = R.fromFunction (Z :. 4) $ \(Z :. x) -> [8, 15, 9, 14] ! x
a2 = R.fromFunction (Z :. 4) $ \(Z :. x) -> [0, 1, 2, 3] ! x
threshold = 10
desired = R.fromFunction (Z :. 2) $ \(Z :. x) -> [0, 2] ! x
-- 15 and 14 are above the threshold, 10

执行此操作的一种方法是使用selectP,但我想避免使用它,因为它计算数组,并且如果可能的话,我希望我的数组保持延迟形式。

另一种方法是使用repa-array,但stack solver似乎不知道如何使用解析程序nightly-2017-04-10导入此库。

2 个答案:

答案 0 :(得分:0)

您可以使用类型为zip的谓词函数构建一个包含filter,然后(Int,Int) -> Bool的对的列表,最后提取该对的第一个或第二个元素(具体取决于哪个)你想要的一个,分别使用map fstmap snd。你需要的一切都在前奏中。

我希望这是足够的信息,所以你可以自己把各个部分放在一起。如果有疑问,请查看我提到的函数的类型签名。

答案 1 :(得分:0)

查看此问题的一种方法是,为了创建Repa数组,您需要在创建时知道数组的大小(extent)(例如fromFunction),但是,在过滤操作的情况下,如果不应用阈值谓词,则无法知道repa中结果数组的大小,主要是计算结果数组的值。

另一种看待它的方法是,D elayed数组是一个从索引到值的简单函数,对于大多数操作来说都很好。但是,对于过滤,当您应用谓词时,为了在特定索引处查找值,您现在需要知道结果数组中该索引之前的所有值,导致任何位置,可能存在值,也许不

vector包使用流融合优雅地解决了这个问题,并且repa-array,仍处于试验阶段的下一版本版本似乎试图使用类似的方法,除了扩展到更高的维度(我可能错了,看起来太紧密了)。

所以,简短的回答,没有办法用Repa样式功能融合进行过滤。之一:

  • 坚持selectP - 更快(可能),但内存效率更低(肯定),或
  • ifilter包中捎带回vector以获取顺序 过滤