我刚开始看看Repa,并想知道如何最好地实现由模板操作读/写的环绕式圆环式2D数组。我在使用ST monad和mutable向量之前实现了这个,但是看起来这不受Repa的支持。一些方法似乎是可能的:
我可以“遍历”数组并在每个元素上执行索引包装。对于简单的模板,在任何地方应用包装逻辑的成本非常严重,所以我需要避免使用这个
Data.Array.Repa.Stencil不支持我需要的边界条件,但看起来像Data.Array.Repa.Algorithms.Convolve。文档显示了严重的性能损失,但
据我所知,我可以使用切片遍历数组的子集。所以,我可以定义一个内部(1,1) - (w-2,h-2),两个表示边界的水平和两个垂直平板,然后使用两个不同的函数/模板遍历它们,从而产生一个结果数组?有关此的任何示例代码或进一步的文档吗?
Repa似乎也有'分区'的概念,它们可以用于实现边界条件吗?
哪一个可能最快?我缺少的任何选项?
谢谢!
答案 0 :(得分:2)
最有效的方法是使用Partitioned
数组表示(第4个选项),但是,这很不方便,因为您应该手动使用5 areas。
在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 |]