Personal tools
You are here: Home ブログ 学習経過 Haskell で逆行列を求める
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
sysfs tips 02 ohyama 2010-09-09
sysfs tips ohyama 2010-09-02
Haskell で周波数スペクトルを得る ohyama 2010-07-29
Haskell で線形識別関数の学習を行う ohyama 2010-07-19
Haskell で逆行列を求める ohyama 2010-07-16
Recent comments
Re:vim に lisp 機能をつける t.mimori 2010-12-16
Re:Haskell で周波数スペクトルを得る H.OHYAMA 2010-08-01
Re:lkml でお勉強 (その1-1) Hiroyasu OHYAMA 2009-08-21
Re:lkml でお勉強 (その1-1) kosaki 2009-08-20
Re:vim に lisp 機能をつける ohyama 2008-05-08
Categories
学習経過
GNU/Linux
 
Document Actions

Haskell で逆行列を求める

  今回は、前回までの関数を利用して逆行列を行うプログラムを作成した。

  ソースコード

  追加した関数は次の 3 つ。

inverseMatrix :: [[Int]] -> [[Ratio Int]]
inverseMatrix mx = let factors = allFactor mx
detA = determinant mx
in if detA == 0
then []
else cutArray (length mx) $ map (\x -> (1 % (fromIntegral detA)) * (x%1))
$ checkSign factors $ map determinant $ map (cofactor mx) factors
where
checkSign :: [(Int, Int)] -> [Int] -> [Int]
checkSign fs xs | null xs = []
| True = let low = fst (head fs)
col = snd (head fs)
x = head xs
in if mod (low + col) 2 > 0 then (-1*x):checkSign (tail fs) (tail xs)
else x:checkSign (tail fs) (tail xs)

-- 配列から行列への変換
cutArray :: Int -> [a] -> [[a]]
cutArray len xs | null xs = []
| True = [(take len xs)] ++ (cutArray len $ reverse $ take ((length xs) - len) $ reverse xs)

-- 余因子行列を求める
cofactor :: [[Int]] -> (Int, Int) -> [[Int]]
cofactor mx (low, col) = map (removeColumn col) $ removeColumn low mx
where
removeColumn :: Int -> [a] -> [a]
removeColumn num xs | num > length xs = xs
| True = (take (num - 1) xs) ++ (reverse $ take ((length xs) - num) $ reverse xs)

-- 行列の各要素のインデックスを求める
allFactor :: [a] -> [(Int, Int)]
allFactor mx = do x <- allFactor' 1 mx
y <- allFactor' 1 mx
[(x, y)]
where
allFactor' :: Int -> [a] -> [Int]
allFactor' cnt mx | length mx == 0 = []
| True = cnt:(allFactor' (cnt+1) (tail mx))


  allFactor が行列の各要素のインデックスを求めている。行列式の各要素の符号を求める際に利用する。
  cofactor は入力された行列から余因子行列を求める関数になる。
  そして inverseMatrix が逆行列を求める関数になる。ここでは、cofactor 関数を呼び出し、逆行列の要素の元になる余因子行列を取得し、その逆行列を求める。そして、各符号を設定し、各要素に対して元の行列の行列式の逆数を係数に設定する。
 
 これに対して、次の行列を入れてみる。

  [[1,2,1],
   [0,-2,3],
   [2,1,5]]

  結果は次のとおり。

 [[(-2)/1,0/1,(-3)/1],
[0/1,(-1)/1,(-3)/1],
[(-1)/1,(-1)/1,(-4)/1]]

 これまでに作ってきた関数はいづれも線形代数の基本的な処理であるが。情報工学の技術では多くの場面において、これらが強烈なツールとなる。
 
 え、ライブラリがあるって?
 自分で作ったツールで出した結果の方が、絶対感動するだろうし。遊びでやっているんだから、車輪の再開発も大いに結構ではないか。

 次回は、これらを使った何か面白い計算をやってみる。

Category(s)
学習経過
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/ohyama/haskell-9006884c521730926c423081308b/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.