3

我刚开始研究 Repa,想知道如何最好地实现一个由模板操作读取/写入的环绕式、圆环式 2D 数组。我在使用 ST monad 和可变向量之前实现了这一点,但似乎 Repa 不支持这一点。一些方法似乎是可能的:

  • 我可以“遍历”数组并在每个元素处进行索引包装。对于简单的模板,在任何地方都应用包装逻辑的成本非常高,所以我需要避免这个

  • Data.Array.Repa.Stencil 不支持我需要的边界条件,但看起来像 Data.Array.Repa.Algorithms.Convolve 一样。但是,文档表明会造成严重的性能损失

  • 据我了解,我可以使用切片遍历数组的一个子集。所以,我可以定义一个内部 (1, 1) - (w-2, h-2),两个水平和两个垂直的平板代表边界,然后使用两个不同的函数/模板遍历它们,得到一个结果数组? 关于此的任何示例代码或进一步的文档?

  • Repa 似乎也有“分区”的概念,可以用来实现边界条件吗?

哪一个可能最快?我缺少任何选项吗?

谢谢!

4

1 回答 1

3

最有效的方法是使用Partitioned数组表示(您的第四个选项),但是,它不方便,因为您应该手动处理5 个区域

Yarr 中,您可以编写一个实用程序

dim2WrapAround :: USource r l Dim2 a => UArray r l Dim2 a -> Dim2 -> Dim2 -> IO a
{-# INLINE dim2WrapAround #-}
dim2WrapAround arr (sizeX, sizeY) (posX, posY) =
    index arr (wrap sizeX posX, wrap sizeY posY)
  where wrap size pos = (pos + size) `mod` size

-- I'm afraid to write the signature...
{-# INLINE convolveOnThorus #-}
convolveOnThorus = convolveLinearDim2WithStaticStencil dim2WrapAround

用法:

myConvolution :: UArray F L Dim2 Float -> UArray CV CVL Dim2 Float
myConvolution = convolveOnThorus [dim2St| some
                                           coeffs
                                               here |]
于 2013-07-28T23:07:04.353 回答