2015-04-22 38 views
3

尽可能简单,只要我需要在Haskell上使用矩阵,我就会挣扎。我的策略是选择具体类型(REPA,Vector,List,IntMap等)并为其编程。例如,我用REPA来解决欧拉的problem 11,我经常在马拉松上使用它。不幸的是,REPA并不是一个特别友好的API--它需要复杂的类型注释,考虑表示并跟踪它,并将其转换......还有,索引被逆转。所有这些意味着我花了大量的时间只是看着文档,并尝试正确地对齐类型,这在你参加马拉松比赛时是致命的。在Haskell上编程矩阵的语言学方法是什么?

我可以使用矢量/列表,但这也是很尴尬,因为那时我需要使用toIndex :: [Int] → Int; fromIndex Int → [Int]函数,每次我索引矢量。

我也尝试创建Data.Vector的包装,如data Matrix a = Matrix { shape :: [a], buffer :: Vector a },但很快我注意到我还必须为每个单独的矢量函数创建一个包装,并且使用不同的类型来匹配可变的矢量等等,一团糟。

最后,我需要的是一个简单的方法来处理矩阵 - 类似:

matrix = Matrix.fromList [3,3] [1,2,3,4,5,6,7,8,9] 
main = do 
    matrix' <- set matrix [1,1] 0 
    print $ get matrix [1,1] 
    print $ sum matrix 

或其他任何东西,让我想想矩阵作为数学对象,而不是一个具体的实现,但我没有找到一种简单的语言学方法。你会怎么做?我不知道镜头能不能帮助吗?

+0

[linear](https://hackage.haskell.org/package/linear-1.18.0.1/docs/Linear-Matrix.html)包中有一些通用的矩阵运算,用少数的泛型类型类,但是我不能很好地解释它是如何工作的。 –

+1

如果你想要一个简单的“Haskell中的Matlab”包,请尝试[hmatrix](http://hackage.haskell.org/package/hmatrix) - 它有一个相当全面和易于理解的API。 –

回答

4
  • 你是说,真的只是矩阵(即有两个索引维的数组)?那么hmatrix可能是最适合你的。它的矩阵类型与你的Vector包装器有点不同,它的界面真的很像“纯功能性的Matlab ”(我个人无法遵守的哲学,但是很好......)无论如何,代数运算,切片等通过底层GSL例程。请注意,这个库并没有真正做有状态的东西,它保留了一个纯粹的功能接口,并依赖于内置例程的优化。

  • 你的意思是说,一般的多维数组/张量对元素操作而不是线性代数更感兴趣,并且需要有状态更新?然后好的旧array图书馆可能是正确的。在过去的几年中,似乎已经被vectorrepa黯然失色,但IMO,Data.Ix索引模式实际上相当不错。排序不太成熟,但也更少“过度工程”版本repa

  • 如果你实际上大多是感兴趣的线性代数,那么你至少应该检查一些更抽象的库。我非常喜欢vector-space界面,这是非常一般的和数学的,它完全避免了在特定基础上的书写操作,这对于捕捉“数学错误”确实有很大帮助。

  • 虽然你提到lens es,有linear –这是优雅和抽象的不同方式。国际海事组织(IMO)错过了线性化的一点(数学),但它仍然非常酷,并且绝对提供比vector-space更多的操作。

  • 哦,最后还有matrix。它与hmatrix非常相似,但在本机Haskell中实现而不是在GSL绑定中实现,这意味着它在高度优化的LA算法中并不丰富,但也不是那么重的依赖。除此之外,它似乎稍微更优雅。

+0

我真的只想要一个N维**方便的**数据结构。也就是说,我可以创建一个三维地图,复制/粘贴块,修改有界卷,压缩,映射,过滤器等。REPA非常快,但使用起来很麻烦。阵列也非常糟糕。例如,我不能使用线性矢量来索引这些数组。这太糟糕了......我不认为这些答案中有任何答案。 :( – MaiaVictor

+0

嗯,或许你不应该要求_matrices_然后......无论如何,我认为'array'对于你的应用来说是非常正确的事情,尤其是你可以使用线性''' V'类型来索引它们,因为它们有一个'Ix'实例。你在那里有什么问题? – leftaroundabout

+0

不知道如何用V创建多维数组并使用V3索引它们例如 – MaiaVictor