理系学生日記

おまえはいつまで学生気分なのか

問題2-37 (2.2.3 Sequences as Conventional Interfaces)

schemeで行列計算する!!わくわくしてきた!!
まずデータをどう表現するかが問題なんですけど、そこはSICPですから、ちゃんと教えてくれてます。偉い!
  \left(\begin{array}{cccc}1&2&3&4\\\4&5&6&6\\6&7&8&9 \end{array}\right) はこう書くよ。

(list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9)

したら、ベクトル同士の内積はこう書ける。

(define (dot-product v w)
  (accumulate + 0 (map * v w)))

シンプルでとてもきれいです。


行列とベクトルのかけ算はこんな感じ。

(define (matrix-*-vector m v)
  (map (lambda (vector elem)
	 (accumulate + 0 (map (lambda (x) (* elem x)) vector)))
       m
       v))

ヨッシャー計算してみる!
  \left(\begin{array}{cccc}1&2&3&4\\\4&5&6&6\\6&7&8&9 \end{array}\right)\left(\begin{array}{c}1\\1\\1\\1 \end{array}\right)=\left(\begin{array}{1} 10\\21\\30 \end{array}\right) をやります!

gosh> (define m (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9)))
m
gosh> (matrix-*-vector m (list 1 1 1 1))
(10 21 30)

できた!


次、転置行列する。

(define (transpose mat)
  (accumulate-n cons () mat))

\left(\begin{array}{cccc}1&2&3&4\\\4&5&6&6\\6&7&8&9 \end{array}\right)^T=\left(\begin{array}{ccc}1&4&6\\2&5&7\\3&6&8\\4&6&9\end{array}\right)をやります!

これはスゲー

gosh> (transpose m)
((1 4 6) (2 5 7) (3 6 8) (4 6 9))

最後は行列同士のかけ算だ!

(define (matrix-*-matrix m n)
  (let ((cols (transpose n)))
    (map (lambda (v) (matrix-*-vector m v)) cols)))

\left(\begin{array}{cccc}1&2&3&4\\\4&5&6&6\\6&7&8&9 \end{array}\right)\left(\begin{array}{cc}1&2\\1&2\\1&2\\1&2\end{array}\right)=\left(\begin{array}{cc}10&20\\21&42\\30&60\end{array}\right)

gosh> (matrix-*-matrix m
		 (list (list 1 2) 
		       (list 1 2)
		       (list 1 2) 
		       (list 1 2)))
((10 21 30) (20 42 60))

ん、これ違わね?転置されてしまってね?