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?
答案 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惯例,因此在这方面,床和早餐库是相当正常的。
至于例外......听起来像个臭虫?