# Haskell's bed-and-breakfast matrix multiplication is wrong?

Haskell's bed-and-breakfast library is the first library in the Linear algebra section in https://wiki.haskell.org/Applications_and_libraries/Mathematics. So, I'm trying:

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.

Wat? If I multiply [m x n] matrix by [n x p] matrix I should get [m x p] matrix, not this silly exception. Ok, maybe library author doesn't know where is left and where is right.

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

Waaaaat?

## Answers

I would bet that you are using a newish GHC; and as a result cabal chose an oldish version of bed-and-breakfast. On my machine, it chose version 0.1.2 (even though the latest version is 0.4.3); this version appears to have an 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] ]

That check should be numCols a /= numRows b. The check is fixed in later versions of the library; but these versions also (correctly) specify upper bounds on base that exclude new GHCs.

Therefore I suspect that you will either have to update the library to work with new GHCs, patch the old version of the library, or use a more actively maintained library. I've been happy with hmatrix in the past, though note that matrix multiplication is spelled (<>), not (*).

I looked at the Numeric.Matrix documentation.

The innermost lists represent the rows. This function will create a m-n-matrix, where m is the number of rows, which is the minimum length of the row lists and n is the number of columns, i.e. the length of the outer list.

This is... difficult to parse, but it means that [[1], [2], [3]] is a 1x3 matrix, *not* a 3x1 matrix. This matches the assertion that the number of columns is the length of the outer list--which of course implies that each inner list is itself a column.

Using the phrase "row-major order" would make things clearer. For reference, Fortran is row-major, C is column-major. Most linear algebra packages seem to follow Fortran conventions, so the bed-and-breakfast library is fairly normal in that regard.

As for the exception... sounds like a bug?