有什么问题?该代码应该通过查找a
次b
逆来进行矩阵除法。我试图了解它的错误是什么,但我没有看到如何链接它。
import List
import Ratio
inverse :: [[Rational]] -> [[Rational]]
inverse mat = sweep ([], zipWith (++) mat unit) where
unit = map (take (length mat)) $ iterate (0 :) (1 : [0,0..])
sweep (xss, []) = xss
sweep (xss, yss) = sweep (xss' ++ [ws], filter (any (/= 0)) yss') where
Just (x : xs) = find ((/= 0) . head) yss
ws = map (/ x) xs
[xss', yss'] = map (map f) [xss, yss]
f (y : ys) = zipWith (\d e -> e - d * y) ws ys
如何将其与
链接import Data.Array
mmult :: (Ix i, Num a) => Array (i, i) a -> Array (i, i) a -> Array (i, i) a
mmult x y
| x1 /= y0 || x1' /= y0' = error "range mismatch"
| otherwise = array ((x0, y1), (x0', y1')) l where
((x0, x1), (x0', x1')) = bounds x
((y0, y1), (y0', y1')) = bounds y
ir = range (x0, x0')
jr = range (y1, y1')
kr = range (x1, x1')
l = [((i, j), sum [x ! (i, k) * y ! (k, j) | k <- kr
通过将a
和b
相乘来进行矩阵除法。
答案 0 :(得分:2)
这里似乎有几个问题。首先,l
中mmult
的定义似乎不完整。你开始一个列表并开始一对,但从不关闭它们。也许你的意思是:
l = [((i, j), sum [x ! (i, k) * y ! (k, j) | k <- kr]) | i <- ir, j <- jr]
正如你所说,链接这两个模块所固有的另一个问题是,你在两个模块中使用不同类型的基质。第一个,您反转矩阵,将其视为列表列表。第二个是两个matricies的乘法,它使用数组。要将两者结合起来,您需要能够在表示之间进行转换。基本上,您需要两个操作:
fromListMatrix :: [[Rational]] -> Array (Int, Int) Rational
toListMatrix :: Array (Int, Int) Rational -> [[Rational]]
一旦有了这些,就可以很容易地实现矩阵划分。
divideMatrix :: Array (Int, Int) Rational -> Array (Int, Int) Rational -> Array (Int, Int) Rational
divideMatrix a b = mmult a (fromListMatrix (invert (toListMatrix b)))
在实施方面,让我们从toListMatrix
开始,因为它更容易。
toListMatrix mat =
现在,我们需要数组的边界,所以
toListMatrix mat = let ((x0, x1), (x0', x1')) = bounds mat in
我们将逐行构建它:
toListMatrix mat = let ((x0, x1), (x0', x1')) = bounds mat in
[row | rowNum <- range (x1, x1')]
每一行都只是具有固定行号的矩阵元素:
toListMatrix mat = let ((x0, x1), (x0', x1')) = bounds mat in
[[mat ! (pos, rowNum) | pos <- range (x0, x0')] | rowNum <- range (x1, x1')]
转到fromlistMatrix
:
fromListMatrix mat =
我们希望将每个元素与一个位置相关联,然后将结果提供给array
,所以:
fromListMatrix mat = array ((1, 1), (length (head mat), length mat)) indexedElems where
indexedElems =
首先我们需要获得行号,所以:
fromListMatrix mat = array (length (head mat), length mat) indexedElems where
indexedElems = someFunction (zip [1..] mat)
然后我们输入位置编号:
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
现在我们有一个索引元素的行列表。我们需要将它连接成一个列表:
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
最后,我们通过将map addPositions (zip [1..] mat)
更改为包含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
你已经完成了!