Linear Algebra (2)

掃き出し法で逆行列を求める、の項。行列の基本変形という言葉が出てきます。wikipedia 見てみたら行に関する基本変形を使えばなんとかなりそげ。

  • ある行を 0 でない定数倍する
  • 二つの行を入れ替える
  • ある行に、他のある行の定数倍を加える

上記三つでなんとかなりそうですが、それ以前に単位行列を吐き出す手続きの定義が必要な気がしてます。

単位行列

以下な試験をひり出した。

(test-section "getI")
(test* "(getI 2)"
       '((1 0) (0 1))
       (getI 2))

(test* "(getI 3)"
       '((1 0 0) (0 1 0) (0 0 1))
       (getI 3))

(test* "(getI 4)"
       '((1 0 0 0) (0 1 0 0) (0 0 1 0) (0 0 0 1))
       (getI 4))

(test* "(getI 5)"
       '((1 0 0 0 0)
	 (0 1 0 0 0)
	 (0 0 1 0 0)
	 (0 0 0 1 0)
	 (0 0 0 0 1))
       (getI 5))

こんなのでいいのかなぁ。とりあえず以下をナニ。

(define (getI n)
  (define (mklist pos)
    (let f ((n 0) (rslt '()))
      (if (>= n pos)
	  rslt
	  (f (+ n 1) (append (list (if (= pos n) 1 0)) rslt)))))
  (define (getI-inner rslt pos)
    (if (= 0 pos)
	rslt
	(getI-inner (append rslt (list (mklist pos))) (- pos 1))))
  (getI-inner '() n))

試験結果が以下。

test (getI 2): expects ((1 0) (0 1)) => got ((0 0) (0))
test (getI 3): expects ((1 0 0) (0 1 0) (0 0 1)) => got ((0 0 0) (0 0) (0))
test (getI 4): expects ((1 0 0 0) (0 1 0 0) (0 0 1 0) (0 0 0 1)) => got ((0 0 0 0) (0 0 0) (0 0) (0))
test (getI 5): expects ((1 0 0 0 0) (0 1 0 0 0) (0 0 1 0 0) (0 0 0 1 0) (0 0 0 0 1)) => got ((0 0 0 0 0) (0 0 0 0) (0 0 0) (0 0) (0))

あら? なんかカン違いしてますな。色々弄くりマワして以下になりました。

(define (getI n)
  (define (mklist pos)
    (let f ((num 0) (rslt '()))
      (if (>= num n)
	  rslt
	  (f (+ num 1) (append (list (if (= pos num) 1 0)) rslt)))))
  (define (getI-inner rslt pos)
    (if (= 0 pos)
	rslt
	(getI-inner (append rslt (list (mklist (- pos 1)))) (- pos 1))))
  (getI-inner '() n))

試験にパスしてはいますが微妙。どんなボケをカマしたのかはコード見て判断して下さひ。それは良いのですがもう少しなんとかならんかな。

もう少し頑張ってみる

なんか手続き定義が直感的でない。てか長い。てか適当に直して動いてるだけ。
そゆ意味ではまさに enum -> filter -> accumulate なナニっぽい。本当?
# と言いつつ次の日になったので解決したらエントリ入れます