【问题标题】:Haskell repa --- mapping with indicesHaskell repa --- 索引映射
【发布时间】:2011-06-05 10:50:25
【问题描述】:

想象一下,我想将一个函数映射到一个数组上,但该函数的类型不仅仅是 a -> ba -> Int -> b 即该函数也需要一个索引。我该怎么做?

【问题讨论】:

    标签: arrays haskell repa


    【解决方案1】:

    简答,使用traverse

    更长的例子:

    import qualified Data.Array.Repa as A
    import qualified Data.Vector.Unboxed as U
    
    arr1 :: A.Array A.DIM2 Double
    arr1 = A.fromVector (A.Z A.:. 2 A.:. 3) $ U.fromList [1::Double,2,3,4,5,6]
    
    arr2 :: A.Array A.DIM2 Double
    arr2 = A.traverse arr1 id (\lf i@(A.Z A.:. r A.:. c) -> 
                      (lf i) + (fromIntegral r) + (fromIntegral c))  
    

    arr1 是一个 2x3 矩阵。 traverse 是一个函数,它采用 (1) 原始数组,(2) 将源索引映射到目标索引的函数,以及 (3) 给定的函数 (i) 原始数组的查找函数和 (ii ) 一个返回新值的索引。

    所以这里arr2 通过添加特定条目的行和列索引来修改每个原始元素。

    【讨论】:

      【解决方案2】:

      好问题,Repa tutorial 中没有记录,所以我用a new section on traversals 更新了它。

      特别是,traverse 让您:

      • 改变输出数组的形状
      • 索引任何元素
      • 观察当前元素

      意味着您可以执行以下操作:

      用它们的行索引替换所有元素

      > traverse a id (\_ (Z :. i :. j :. k) -> i) 
      [0,0,0,0,0,0,0,0,0
      ,1,1,1,1,1,1,1,1,1
      ,2,2,2,2,2,2,2,2,2]
      

      将一个元素乘以它的行

      > traverse a id (\f (Z :. i :. j :. k) -> f (Z :. i :. j :. k) * i) 
      [0,0,0,0,0,0,0,0,0
      ,10,11,12,13,14,15,16,17,18
      ,38,40,42,44,46,48,50,52,54]
      

      等等。 travese非常功能强大,而且神奇地并行。

      高级:并行图像去饱和

      Example from the Repa tutorial

      【讨论】:

        【解决方案3】:

        使用 zipWith

        zipWith (\idx ele -> if even idx then div ele 2 else ele) [0..] xs
        

        【讨论】:

          猜你喜欢
          • 2016-02-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-24
          • 1970-01-01
          • 2018-08-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多