Haskell的床和早餐矩阵乘法是错误的?

时间:2015-11-25 21:21:23

标签: haskell matrix linear

Haskell的床和早餐库是https://wiki.haskell.org/Applications_and_libraries/Mathematics中线性代数部分的第一个库。 所以,我正在努力:

let a = Matrix.fromList [[1,2,3], [4,5,6], [7,8,9]]
let b = Matrix.fromList [[1], [2], [3]]
a * b
*** Exception: Matrix.times: `numRows a' and `numCols b' don't match.

笏?如果我将[m x n]矩阵乘以[n x p]矩阵,我应该得到[m x p]矩阵,而不是这个愚蠢的例外。好吧,也许图书馆作者不知道哪里留下,哪里是正确的。

b * a
 *** Exception: Ix{Int}.index: Index (2) out of range ((1,1))

Waaaaat?

2 个答案:

答案 0 :(得分:3)

我敢打赌你正在使用新的GHC;因此,cabal选择了一种古老版的住宿加早餐。在我的机器上,它选择了版本0.1.2(即使最新版本是0.4.3);此版本似乎有incorrect dimensions check in its multiplication function

a `times` b
    | numRows a /= numCols b = error "Matrix.times: `numRows a' and `numCols b' don't match."
    | otherwise = fromList [ [ row i a `dotProd` col j b
                             | j <- [1..numCols b] ]
                           | i <- [1..numRows a] ]

该检查应为numCols a /= numRows b。检查在库的更高版本中得到修复;但是这些版本也(正确地)指定排除新GHC的base上限。

因此,我怀疑您要么必须更新库以使用新的GHC,修补旧版本的库,要么使用更积极维护的库。我过去对hmatrix感到满意,但请注意矩阵乘法拼写为(<>),而不是(*)

答案 1 :(得分:1)

我查看了Numeric.Matrix documentation

  

最里面的列表代表行。该函数将创建一个m-n矩阵,其中m是行数,它是行列表的最小长度,n是列数,即外部列表的长度。

这很难解析,但这意味着[[1], [2], [3]]是1x3矩阵,不是 3x1矩阵。这匹配了列数是外部列表长度的断言 - 这当然意味着每个内部列表本身就是一列。

使用短语“row-major order”会让事情变得更清晰。作为参考,Fortran是行主要的,C是列主要的。大多数线性代数包似乎遵循Fortran惯例,因此在这方面,床和早餐库是相当正常的。

至于例外......听起来像个臭虫?