Linear Algebra (4)

基本変形にようやく着手できる模様。以下。

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

いっちゃん簡単なのから。ちょっと微妙なのが行とか列の添字が 1 から始まる事なんですがどう誤魔化したものやら。
とりあえず試験を一つでっち上げてみる。

(test-section "Fi(lambda)"
(test* "(F-i-lambda 1 2 '((1 0) (0 1)))"
       '((2 0) (0 1))
       (F-i-lambda 1 2 '((1 0) (0 1))))

以下なソレで試験にパス。

(define (F-i-lambda row n l)
  (let f ((i 1) (l l))
    (if (null? l)
	'()
	(cons (if (= row i)
		  (scalar-*-v n (car l))
		  (car l))
	      (f (+ i 1) (cdr l))))))

もう少し試験を追加してみます。

(test* "(F-i-lambda 2 1/2 '((1 0 0) (0 1 0) (0 0 1)))"
       '((1 0 0) (0 1/2 0) (0 0 1))
       (F-i-lambda 2 1/2 '((1 0 0) (0 1 0) (0 0 1))))

次は

Fij というナニ。i 行目と j 行目の入れ替え。以下な試験を書いてみた。

(test-section "Fij")
(test* "(F-i-j 1 2 '((1 0 0) (0 1 0) (0 0 1)))"
       '((0 1 0) (1 0 0) (0 0 1))
       (F-i-j 1 2 '((1 0 0) (0 1 0) (0 0 1))))

これ、どうしたものか。指定した行を戻す手続き作っとくか。まず試験を。

(test-section "getRow")
(test* "(getRow 3 '((1 0) (0 1)))"
       #f
       (getRow 3 '((1 0) (0 1))))

(test* "(getRow 2 '((1 0) (0 1)))"
       '(0 1)
       (getRow 2 '((1 0) (0 1))))

(test* "(getRow 1 '((1 0) (0 1)))"
       '(1 0)
       (getRow 1 '((1 0) (0 1))))

手続きてきには以下なカンジで良いのかな。

(define (getRow row l)
  (let f ((i 1) (l l))
    (cond ((null? l) #f)
	  ((= i row) (car l))
	  (else
	   (f (+ i 1) (cdr l))))))

これを使って交換する行を持っときゃ良いはずなんですがどうしたものかな。

(define (F-i-j i j l)
  (let ((row-i (getRow i l))
	(row-j (getRow j l)))
    (let f ((now 1)
	    (l l))
      (if (null? l)
	  '()
	  (cons (cond ((= now i) row-j)
		      ((= now j) row-i)
		      (else (car l)))
		(f (+ now 1) (cdr l)))))))

上記で試験パス。ちなみに最初は以下になっててびっくり。

	  (cons (cond ((= now i) row-i)
		      ((= now j) row-j)
		      (else (car l)))
		(f (+ now 1) (cdr l)))))))

実は交換されてない、というオチ。

交換できるんですが、ベクタベクタを加える手続きの定義が必要。試験が以下。

(test-section "v-+-v")
(test* "(v-+-v '(1 0) '(0 1))"
       '(1 1)
       (v-+-v '(1 0) '(0 1)))

手続きの定義が以下。

(define (v-+-v v1 v2)
  (if (null? v1)
      '()
      (cons (+ (car v1) (car v2))
	    (v-+-v (cdr v1) (cdr v2)))))

試験パス。本体の試験を考えてみる。以下。

(test-section "Fij-lambda")
(test* "(F-i-j-lambda 1 2 1/2 '((1 0 0) (0 1 0) (0 0 1)))"
       '((1 1/2 0) (0 1 0) (0 0 1))
       (F-i-j-lambda 1 2 1/2 '((1 0 0) (0 1 0) (0 0 1))))

(test* "(F-i-j-lambda 2 1 1/2 '((1 0 0) (0 1 0) (0 0 1)))"
       '((1 0 0) (1/2 1 0) (0 0 1))
       (F-i-j-lambda 2 1 1/2 '((1 0 0) (0 1 0) (0 0 1))))

で、小さい方のインデクスを保存、みたいな実装書いたんですが、

  (let* ((row-index1 (if (< i j) i j))
	 (row-index2 (if (= i row-index1) j i))

よく考えたらこれでは駄目。sw にしないとナニ。てか、i と j の大小関係如何を問わず出てくる結果が同じなんだよねぇ。
# 同じコトしてるっちゃしてるんですが

ええと

F21(-3) と F12(-3) の違いな模様。酒呑んでヤッてるのでダメです。そもそもこの違いを理解できてないのが敗因。
とりあえずエントリ投入。