-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]

あなたが言ったように、これら2つのモジュールをリンクすることに固有のもう1つの問題は、2つのモジュールのマトリックスに異なるタイプを使用していることです。マトリックスを逆にする最初のものは、それをリストのリストとして扱います。2 つの行列を乗算する 2 つ目は、配列を使用します。2 つを組み合わせるには、表現間で変換できる必要があります。基本的に、次の 2 つの操作が必要です。

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 に答える