哈斯克尔的矩阵部门 [英] Matrix division in Haskell

查看:102
本文介绍了哈斯克尔的矩阵部门的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么不对?此代码应该通过查找 a b inverse来进行矩阵分解。

 导入列表
导入比率

inverse :: [[Rational]] - > [[Rational]]
inverse mat = sweep([],zipWith(++)mat单元)其中
unit = map(take(length mat))$ iterate(0 :)(1: (xs,yss)= sweep(xss'++ [ws],filter(any(/ = 0))[0,0 ..])
sweep(xss,[])= xss
sweep yss')其中
Just(x:xs)= find((/ = 0)。 map(map f)[xss,yss]
f(y:ys)= zipWith(\ de - > 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'=错误范围不匹配
| (x0,x1'))=边界x
((y0, y1',y0',y1'))=边界y
ir =范围(x0,x0')
jr =范围(y1,y1')
kr =范围(x1, x1')
l = [((i,j),sum [x!(i,k)* y!(k,j)| k < - kr

通过乘以 a b 'inverse。

解决方案

这里似乎有一些问题,首先,定义 l in mmult 似乎是不完整的,你开始一个列表并开始一个列表,但是从不关闭它们。

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ )| k <-kr])| i <-ir,j <-jr]

正如你所说的,链接这两个模块的另一个问题是,你正在使用不同类型的matri cies在两个模块中,第一个是反转矩阵的地方,将它当作列表的列表。第二个乘以两个矩阵,使用数组。要组合这两者,您需要能够在表示之间进行转换。实质上,您需要两个操作:

  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 ab = mmult a(fromListMatrix(invert(toListMatrix b)))

在实现方面,让我们从到ListMatrix 开始,因为它更容易。

  toListMatrix mat = 

现在,我们将需要数组,所以

  toListMatrix mat = let((x0,x1),(x0',x1'))=边界垫in 

我们将逐行构建它:

  toListMatrix mat = let((x0,x1),(x0',x1'))=边界在
中[ rowNum < - range(x1,x1')]

每行只是矩阵的元素使用固定的行号:

  toListMatrix mat = let((x0,x1),(x0',x1'))=在
[[垫! (pos,rowNum)| pos < - range(x0,x0')] | rowNum < - range(x1,x1')]

转到 fromlistMatrix

  fromListMatrix mat = 

我们希望将每个元素与一个位置相关联,然后将结果提供给 array ,所以: indexedElems =

首先,我们需要获取行数,所以:

  fromListMatrix mat = array(length(head mat),length mat)indexedElems其中
indexedElems = someFunction(zip [1 ..] mat)

然后我们输入仓位数字:

  fromListMatrix mat = array(length(head mat),length mat)indexedElems其中
indexedElems = someFunction(map addPositions(zip [1 ..] mat))
addPositions(rowNum,elems)= zip [(pos,rowNum)| pos< - [1 ..]] elems

现在我们有一个索引行的列表元素。我们需要将它连接成一个列表:

pre $ 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其中
indexedElems = concat(zipWith addPositions [1 ..] mat)
addPositions rowNum elems = zip [(pos,rowNum)| pos< - [1 ..]] elems

完成!


What is wrong? This code is supposed to do matrix division by finding a times b inverse. I try to understand what its errors are but I fail to see how to link it.

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

How can I link it with

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

to do matrix division by multiplying a and b's inverse.

解决方案

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!

这篇关于哈斯克尔的矩阵部门的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆