SICP 読み (49) 2.4.1 複素数の表現

問題 2.69 において adjoin-set を使っている解を見かけた。へー、と言いつつ実装を試してみたいと思ったので詳しく見ていないんですが、一体どうやるんだろうか。(そう言いつつも結局スルーしそうな気もするが
で、この節については、試験確認ベースになるか、と。どちらかというと次の節につなげるための前段階なカンジ。
で、Ben 版と Alyssa 版の ut をしてみる事に。
で、3.14 なソレを使わねば、なんで試験では (use math.const) しとけば pi というシンボルが定数として使用できるみたい。

あと、計算方法が違う、という事は微妙な誤差が出てくるので、適当な値を使って同じソースで試験できるように手抜きを。(数値演算パケジという意味ではあり得ん試験ですが)

一応、以下の試験で両方の実装は試験をパスしている模様。

#!/usr/bin/env gosh

(use math.const)
(use test.unit)
(require "2.4.1")

(define (marume x)
  (define d 0.00001)
  (define m 100000)
  (* d (round (* m x))))

(define-test-suite "alyssa"

("real-part test"
 ("real-part test"
 (let ((z (make-from-mag-ang 2 (/ pi 6))))
   (assert-equal 1.73205
		 (marume (real-part z))))
 (let ((z (make-from-real-imag (sqrt 3) 1.0)))
   (assert-equal 1.73205
		 (marume (real-part z))))
))

("imag-part test"
 ("imag-part test"
 (let ((z (make-from-mag-ang 2 (/ pi 6))))
   (assert-equal 1.0
                 (round (imag-part z))))
 (let ((z (make-from-real-imag (sqrt 3) 1.0)))
   (assert-equal 1.0
                 (round (imag-part z))))
))

("magnitude test"
 ("magnitude test"
 (let ((z (make-from-mag-ang 2.0 (/ pi 6))))
   (assert-equal 2.0
                 (magnitude z)))
 (let ((z (make-from-real-imag (sqrt 3) 1.0)))
   (assert-equal 2.0
                 (magnitude z)))
))

("angle test"
 ("angle test"
 (let ((z (make-from-mag-ang 2 (/ pi 6))))
   (assert-equal (marume (/ pi 6))
		 (marume (angle z))))
 (let ((z (make-from-real-imag (sqrt 3) 1.0)))
   (assert-equal (marume (/ pi 6))
		 (marume (angle z))))
))

("make-from-real-imag test"
 ("make-from-real-imag test"
 (let ((z (make-from-real-imag (sqrt 3) 1.0)))
   (assert-equal 2.0 (magnitude z))
   (assert-equal (marume (/ pi 6)) (marume (angle z)))
   (assert-equal 1.0 (round (imag-part z)))
   (assert-equal 1.73205
		 (marume (real-part z))))
))

("make-from-mag-ang test"
 ("make-from-mag-ang test"
 (let ((z (make-from-mag-ang 2.0 (/ pi 6))))
   (assert-equal 2.0 (magnitude z))
   (assert-equal (marume (/ pi 6)) (marume (angle z)))
   (assert-equal 1.0 (round (imag-part z)))
   (assert-equal 1.73205
		 (marume (real-part z))))
))

("add-complex test"
 ("add-complex test"
  (let ((z1 (make-from-real-imag 4.0 4.0))
	(z2 (make-from-real-imag 2.0 2.0)))
    (let ((result (add-complex z1 z2)))
      (assert-equal (marume (sqrt 72)) 
		    (marume (magnitude result)))
      (assert-equal (marume (/ pi 4))
		    (marume (angle result)))
      (assert-equal (marume 6.0) 
		    (marume (imag-part result)))
      (assert-equal (marume 6.0) 
		    (marume (real-part result)))))
))

("sub-complex test"
 ("sub-complex test"
  (let ((z1 (make-from-real-imag 4.0 4.0))
	(z2 (make-from-real-imag 2.0 2.0)))
    (let ((result (sub-complex z1 z2)))
      (assert-equal (marume (sqrt 8))
		    (marume (magnitude result)))
      (assert-equal (marume (/ pi 4))
		    (marume (angle result)))
      (assert-equal (marume 2.0)
		    (marume (imag-part result)))
      (assert-equal (marume 2.0)
		    (marume (real-part result)))))
))

("mul-complex test"
 ("mul-complex test"
  (let ((z1 (make-from-real-imag 4.0 4.0))
	(z2 (make-from-real-imag 2.0 2.0)))
    (let ((result (mul-complex z1 z2)))
      (assert-equal (marume 16)
		    (marume (magnitude result)))
      (assert-equal (marume (/ pi 2))
		    (marume (angle result)))
      (assert-equal (marume 16)
		    (marume (imag-part result)))
      (assert-equal 0.0
		    (marume (real-part result)))))
))

("div-complex test"
 ("div-complex test"
  (let ((z1 (make-from-real-imag 4.0 4.0))
	(z2 (make-from-real-imag 2.0 2.0)))
    (let ((result (div-complex z1 z2)))
      (assert-equal 2.0
		    (marume (magnitude result)))
      (assert-equal 0.0
		    (marume (angle result)))
      (assert-equal 0.0
		    (marume (imag-part result)))
      (assert-equal 2.0
		    (marume (real-part result)))))
))
)

時間がかかっている割にはイカサマ臭い。数学なソレが微妙というのが一番の敗因。