3

問題

既に存在する可能性のある repa ライブラリ内の関数を探しています。次のような関数が必要です。

  1. 2D 配列を取ります
  2. ウィンドウ サイズを指定する 2 つの整数
  3. 2D 配列の指定されたサイズの各ウィンドウで、新しい値 (この特定のウィンドウの小さな値など) を計算します。

min3x3 ウィンドウで関数をマッピング:

| | 1 2 3 4 3
  4 5 6 7 2
  7 8 9 4 2
  5 4 8 1 6
  8 5 3 3 2 |

戻ります:

| | 1 1 2 2 2
  1 1 2 2 2
  4 4 1 1 1
  4 3 1 1 1
  4 3 1 1 1 |

のBoundClamp  コンストラクターに似たスキームを使用していることに注意してくださいData.Array.Repa.Stencil。これはステンシル畳み込みではありません。つまり、2D 配列のすべての要素にステンシルを適用しているわけではありません。代わりに、配列の各ウィンドウで関数を実行し、エッジの範囲外の要素には 2D 配列のエッジで最も近い値が割り当てられます。

可能な解決策の種類

関数は次のようになります。

mapF
  :: Source r a
  => Boundary a            -- ^ How to handle the boundary of the array.
  -> (Int,Int)             -- ^ window size in the X and Y direction.
  -> (Array r DIM2 a -> b) -- ^ function over window e.g. to return the minimum value.
  -> Array r DIM2 a        -- ^ Array to apply function to.
  -> Array r DIM2 b

これはすでに存在するものですか、それともコード化するのは簡単ですか?

4

1 に答える 1

1

私はレパで錆びていますがtraverse、配列の境界を使用して手動で検出できると信じています。次のタイプを検討してください。

traverse ::
  (Source r a, Shape sh, Shape sh') =>
  Array r sh a
  -> (sh -> sh') -> ((sh -> a) -> sh' -> b) -> Array D sh' b

この関数は、元の配列、新しい形状を生成する関数、ルックアップ関数と新しい値を生成するためのインデックスを受け取る関数を受け取り、新しい (遅延した) 配列を生成します。

簡単な解決策は、インデックスのすべての隣接をチェックし、 and を使用して境界を制御することminですmax

import qualified Data.Array.Repa as R
import           Data.Array.Repa (Z(..), traverse, fromListUnboxed, toList, (:.)(..))
import Prelude
import Data.List.Split

main = do let a = fromListUnboxed (Z :. h :. w) ( [1..6] ++ [2..7] ++ [3..8] ++ [4..9] ++ [5..10] ::  [Int])
              r = traverse a id (\f (Z :. y :. x) -> minimum [f (Z :. yi :. xi) | xi <- idx w x, yi <- idx h y])
          printArray a
          printArray r
  where
    idx b i = map (bound b) [i, i+1, i-1]
    bound b = min (b-1) . max 0
    w = 6 :: Int
    h = 5 :: Int

    printArray = putStrLn . unlines . map show . chunksOf w . toList

この解決策に異議を唱える主な理由は、パフォーマンスです (同じ数値の多くの比較、静的に排除する必要がある多くの境界チェック)。OTOH、あなたの質問は簡単な解決策を求めただけで、パフォーマンスに過度に関心があるようには見えませんでした.

Repa に組み込まれているより高速なソリューションがあるかどうかにも興味があります。

于 2014-05-12T18:32:12.543 に答える