行列の積

ベクトルや行列の計算を使ったシミュレーションの説明は比較的によく出会うので、Haskell ではどうしたら良いだろうかと考えた。ベクトルの加算や内積はリストの計算で簡単にできる。

vadd x y = zipWith (+) x y
vdot x y = sum $ zipWith (*) x y

しかし、行列の計算は二次元配列を使わずにどう計算したらよいのだろうと思案していた。たまたま、List モジュールの勉強をしていたら、行列の転置をおこなう transpose という関数があるのを知った。行列の積を計算するときに、答えの行列の要素は、被積算行列の横ベクトルと積算行列の縦ベクトルの内積であることを考えて、二次元配列を使わずにできるのではないかと思い立った。

そこで、やってみたら、できた。

mproduct x y = mktbl (length (head y)) [vdot v w| v <- x, w <- (transpose y)]
  where mktbl n xs = if xs == [] then [] else take n xs : mktbl n (drop n xs)

実行例
Main> mproduct [[1],[2]] [[3,4]]
[[3,4],[6,8]]
Main> mproduct [[1,2]] [[3], [4]]
[[11]]

実用性のほどは分からないが、インデックスや配列を使わずに行列の積が定義できたので満足だ。List モジュールの関数には transpose 以外にもお宝が潜んでいるかもしれない。楽しみだ。


今日の Haskell
Hugs> :l List
List> take 6 $ cycle [1,2,3]
[1,2,3,1,2,3]
List> take 9 $ cycle [1,2,3]
[1,2,3,1,2,3,1,2,3]

List モジュールの cycle 関数は、引数に与えたパターンを繰り返し出力し続ける。
[PR]
by tnomura9 | 2010-12-01 17:50 | Haskell | Comments(0)
<< Ruby の配列処理のメソッド... 汎用入力関数 >>