2013-07-28 36 views
2

我剛開始看着Repa並希望知道如何最好地實現一個環繞式,環面風格的二維數組,通過模板操作讀/寫。我在使用ST monad和可變向量之前實現了這一點,但似乎這不被Repa支持。幾種方法似乎是可能的:用Haskell's Repa實現2D圓環陣列

  • 我可以'遍歷'數組,並做索引包裝自己在每個元素。對於簡單的模板應用無處不在包裝邏輯的成本是相當嚴重的,所以我需要避免這個

  • Data.Array.Repa.Stencil不支持的邊界條件,我需要,但看起來像數據.Array.Repa.Algorithms.Convolve。文檔暗示了一個沉重的性能損失,儘管

  • 從我所瞭解的情況來看,我可以使用切片遍歷數組的子集。因此,我可以定義一個內部(1,1) - (w-2,h-2),兩個水平和兩個垂直平板代表邊界,然後使用兩個不同的函數/模板遍歷它們,得到一個結果數組?任何示例代碼或進一步的文件?

  • 維修似乎也有'分區'的概念,它們可以用於實現邊界條件嗎?

哪一個可能是最快的?我失蹤的任何選項?

謝謝!

回答

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 |] 
+0

將convolveLinearDim2WithStaticStencil只使用dim2WrapAround在邊界,其中模板可以去出界或者在每個元素?它看起來像這樣基本上和Data.Array.Repa.Algorithms.Convolve中的ConvolveP一樣? (聰明的包裝邏輯,順便說一句,我會用兩個分支或模塊完成它,很好!) – NBFGRTW

+0

@ AN1只在邊界。不,名稱convolveDim2With * Static *模板表示它確實是靜態的,甚至比Repa 3的靜態模板卷積更快。 – leventov

+0

@ AN1我的「聰明」包裝是錯誤的......在這裏,決定的模數仍然更好。查看編輯的答案。 – leventov