Haskell中的稀疏数组?

时间:2009-06-04 01:09:00

标签: arrays data-structures haskell

是否有任何标准或“最常用”的方式来表示Haskell中的多维稀疏数组(不会过多牺牲性能)?

类似map< int,map< int,MyClass> >例如,在C ++中。我用Google搜索,发现只是一些旧的学术论文和其他人也要求这样做。

谢谢!

5 个答案:

答案 0 :(得分:8)

Data.Map (Int,Int) MyClass是一个很好的建议;先尝试一下。

如果遇到空间问题,请尝试IntMap (IntMap MyClass)IntMap s(在模块Data.IntMap中)为Map,其中Int为密钥;专业化,他们比通用地图更有效。它可能会也可能不会产生重大影响。

还有Scalable, adaptive persistent container types项目可能对您有用。这些容器(包括地图)使用的空间明显少于普通地图,但它们稍微复杂一些(尽管使用起来仍然相当容易)。

答案 1 :(得分:7)

Data.Map (Int,Int) MyClass怎么样?

答案 2 :(得分:5)

HsJudy,似乎很适合稀疏密钥集。

  

为Haskell提供的Judy绑定(一个实现快速稀疏动态数组的C库),它尽可能地符合现有的Haskell库接口,如Data.Map和Data.Array.MArray。 Judy库的这种绑定包括它的四种类型:从单词到位的映射(Judy1),从单词到值(JudyL),从字符串到值(JudyHS)以及从字节数组到值(JudyHS)。 / p>

但是我可能会使用Data.Map.Map (Int, Int) MyClass,直到遇到可伸缩性或可用性问题。

答案 3 :(得分:4)

答案 4 :(得分:3)

我发现this short gist显示了Haskell的压缩行存储以及相关的矩阵向量乘法:

import Data.Vector.Unboxed as U

-- | A compressed row storage (CRS) sparse matrix.
data CRS a = CRS {
      crsValues :: Vector a
    , colIndices :: Vector Int
    , rowIndices :: Vector Int
    } deriving (Show)

multiplyMV :: CRS Double -> Vector Double -> Vector Double
multiplyMV CRS{..} x = generate (U.length x) outer
  where outer i = U.sum . U.map inner $ U.enumFromN start (end-start)
          where inner j = (crsValues ! j) * (x ! (colIndices ! j))
                start   = rowIndices ! i
                end     = rowIndices ! (i+1)
                (!) a b = unsafeIndex a b