Haskell 使用边界情况在repa数组上映射窗口函数 问题

Haskell 使用边界情况在repa数组上映射窗口函数 问题,haskell,repa,Haskell,Repa,我正在repa库中寻找一个可能已经存在的函数。我想要一个函数: 获取二维数组 指定窗口大小的两个整数 在2D阵列上给定大小的每个窗口中,计算一个新值,例如该特定窗口中的小值 例子 将min功能与3x3窗口映射到: | 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 | 这是已经存在的东西,还是编码起来很简单?我对我的repa很生疏,但我相信你可以使用遍历并手动检测数组边界。考虑类型: traverse :: (Source

我正在repa库中寻找一个可能已经存在的函数。我想要一个函数:

  • 获取二维数组
  • 指定窗口大小的两个整数
  • 在2D阵列上给定大小的每个窗口中,计算一个新值,例如该特定窗口中的小值
  • 例子 将
    min
    功能与3x3窗口映射到:

    | 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 |
    这是已经存在的东西,还是编码起来很简单?

    我对我的repa很生疏,但我相信你可以使用
    遍历
    并手动检测数组边界。考虑类型:

    traverse ::
      (Source r a, Shape sh, Shape sh') =>
      Array r sh a
      -> (sh -> sh') -> ((sh -> a) -> sh' -> b) -> Array D sh' b
    
    该函数采用原始数组、生成新形状的函数、采用查找函数和索引生成新值的函数,并生成新(延迟)数组

    一个简单的解决方案是检查索引的所有邻居,使用
    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
    
    将限定的Data.Array.Repa导入为R
    导入Data.Array.Repa(Z(..),遍历,fromlistunbox,toList,(:)(..)
    进口序曲
    导入Data.List.Split
    main=do让a=fromlistunbox(Z:.h:.w)([1..6]+[2..7]+[3..8]++[4..9]+[5..10]:[Int])
    
    r=遍历id(\f(Z:.y:.x)->最小值[f(Z:.yi:.xi)席X>代码>遍历< /代码>不允许我指定在2D数组边界上发生的事情,例如指定边界钳。也就是,<代码>遍历<代码>,意味着我必须以编程方式围绕每个元素构造一个窗口,以计算<代码> min <代码>。这个细节是用RePA中的模板功能抽象的。
    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