在Haskell上编程矩阵的语言方法是什么?

时间:2015-04-22 18:15:23

标签: haskell matrix data-structures

这很简单,只要我需要在Haskell上使用矩阵,我就会挣扎。我的策略是选择一个具体的类型(REPA,Vector,List,IntMap等)并为它编程。例如,我使用REPA来解决Eu​​ler的problem 11,我经常在马拉松上使用它。不幸的是,REPA并不是一个特别友好的API - 它需要复杂的类型注释,考虑表示和跟踪它,转换它...而且,索引是相反的。所有这些意味着我花了很多时间来查看文档并尝试正确对齐类型,这对于马拉松来说是致命的。

我可以使用向量/列表,但这也很尴尬,因为每次我索引向量时我都需要使用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

或者其他任何让我把矩阵看作数学对象而不是具体实现的东西,但我找不到简单的语言方法。你会怎么做?我想知道Lens是否能以某种方式提供帮助?

1 个答案:

答案 0 :(得分:4)

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

  • 你的意思是,一般的多维数组/张量,对元素操作而不是线性代数更感兴趣,需要有状态更新吗?那么好的旧array库可能恰到好处。在过去的几年中,vectorrepa似乎有点黯然失色,但IMO,Data.Ix索引范例实际上相当不错。 repa的不太成熟但也不那么“过度设计”的版本。

  • 如果您实际上主要对线性代数感兴趣,那么您至少应该检查一些更抽象的库。我非常喜欢vector-space界面,这是非常通用和数学的,它完全避开了特定基础上的编写操作,这对于捕获“数学错误”有很大作用。

  • 当你提到lens es时,有linear - 它以不同的方式优雅而抽象。 IMO它在某种程度上(数学上)错过了线性点,但它仍然非常酷,并且肯定提供比vector-space更多的操作。

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