There seem to be a couple problems here. First of all, the definition of l
in mmult
seems to be incomplete. You start a list and start a pair, but never close them. Perhaps you meant:
l = [((i, j), sum [x ! (i, k) * y ! (k, j) | k <- kr]) | i <- ir, j <- jr]
The other problem that is inherent in, as you put it, linking those two modules, is that you are using different types for matricies in the two modules. The first one, where you invert a matrix, treats it as a list of lists. The second one, which multiplies two matricies, uses arrays. To combine the two, you need to be able to convert between the representations. Essentially, you need two operations:
fromListMatrix :: [[Rational]] -> Array (Int, Int) Rational
toListMatrix :: Array (Int, Int) Rational -> [[Rational]]
Once you have these, you can implement matrix division pretty easily.
divideMatrix :: Array (Int, Int) Rational -> Array (Int, Int) Rational -> Array (Int, Int) Rational
divideMatrix a b = mmult a (fromListMatrix (invert (toListMatrix b)))
On the implementation front, let's start with toListMatrix
, as it is easier.
toListMatrix mat =
Now, we're going to need the bounds of the array, so
toListMatrix mat = let ((x0, x1), (x0', x1')) = bounds mat in
We will construct it row by row:
toListMatrix mat = let ((x0, x1), (x0', x1')) = bounds mat in
[row | rowNum <- range (x1, x1')]
Each row is simply the elements of the matrix with a fixed row number:
toListMatrix mat = let ((x0, x1), (x0', x1')) = bounds mat in
[[mat ! (pos, rowNum) | pos <- range (x0, x0')] | rowNum <- range (x1, x1')]
Moving on to fromlistMatrix
:
fromListMatrix mat =
We want to associate each element with a position, and then feed the result to array
, so:
fromListMatrix mat = array ((1, 1), (length (head mat), length mat)) indexedElems where
indexedElems =
First we need to get the row numbers in place, so:
fromListMatrix mat = array (length (head mat), length mat) indexedElems where
indexedElems = someFunction (zip [1..] mat)
Then we put in the position numbers:
fromListMatrix mat = array (length (head mat), length mat) indexedElems where
indexedElems = someFunction (map addPositions (zip [1..] mat))
addPositions (rowNum, elems) = zip [(pos, rowNum) | pos <- [1..]] elems
Now we have a list of rows of the indexed elements. We need to concatenate this into a single list:
fromListMatrix mat = array (length (head mat), length mat) indexedElems where
indexedElems = concat (map addPositions (zip [1..] mat))
addPositions (rowNum, elems) = zip [(pos, rowNum) | pos <- [1..]] elems
Finally, we clean up the code by changing map addPositions (zip [1..] mat)
into a simpler form with zipWith
:
fromListMatrix mat = array (length (head mat), length mat) indexedElems where
indexedElems = concat (zipWith addPositions [1..] mat)
addPositions rowNum elems = zip [(pos, rowNum) | pos <- [1..]] elems
You're done!