2

我有两个 Repa 数组a1a2并且我想消除a2其中相应索引a1高于某个阈值的所有元素。例如:

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

4

2 回答 2

0

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

我希望这是足够的信息,因此您可以自己将这些部分组合在一起。如果有疑问,请查看我提到的函数的类型签名。

于 2017-04-13T00:21:27.807 回答
0

看待这个问题的一种方法是,为了创建一个 Repa Array,您需要在创建时知道 Array 的大小(extent)(例如fromFunction),但是,在过滤操作的情况下,没有办法知道在不应用阈值谓词的情况下, repa中结果数组的大小,本质上是计算结果数组的值。

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

vector包通过流融合优雅地解决了这个问题,并且repa-array,仍处于实验阶段的下一个版本的 Repa 似乎正在尝试使用类似的方法,除了扩展到更高的维度(我可能错了,避风港没有看得太仔细)。

因此,简短的回答是,没有办法使用 Repa 风格的功能融合进行过滤。任何一个:

  • 坚持selectP- 更快(可能),但内存效率较低(肯定),或
  • ifiltervector包装中捎带进行顺序过滤
于 2017-04-25T02:20:19.477 回答