-2

怎么了?此代码应该通过查找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

通过乘以ab的逆来进行矩阵除法。

4

1 回答 1

2

这里似乎有几个问题。首先,lin的定义mmult似乎不完整。您开始一个列表并开始一对,但永远不要关闭它们。也许你的意思是:

l = [((i, j), sum [x ! (i, k) * y ! (k, j) | k <- kr]) | i <- ir, j <- jr]

正如您所说,链接这两个模块所固有的另一个问题是您在两个模块中使用不同类型的矩阵。第一个,您反转矩阵,将其视为列表列表。第二个,将两个矩阵相乘,使用数组。要将两者结合起来,您需要能够在表示之间进行转换。本质上,您需要两个操作:

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

你完成了!

于 2012-06-19T20:17:50.267 回答