2012-01-12

SICP Exercise 2.75: Message-Passing make-from-mag-ang

Implement the constructor make-from-mag-ang in message-passing style. This procedure should be analogous to the make-from-real-imag procedure given above.

Here's the make-from-real-imag procedure that's "given above":
(define (make-from-real-imag x y)
  (define (dispatch op)
    (cond ((eq? op 'real-part) x)
          ((eq? op 'imag-part) y)
          ((eq? op 'magnitude)
           (sqrt (+ (square x) (square y))))
          ((eq? op 'angle) (atan y x))
          (else
           (error "Unknown op -- MAKE-FROM-REAL-IMAG" op))))
  dispatch)
Now back in section 2.4.1, where the real/imaginary and magnitude/angle representations were introduced, the authors showed how, given a complex number represented as a magnitude, r, and an angle, A, we could calculate the real, x, and imaginary, y, parts as follows:
x = r cos A
y = r sin A
Given this, the message-passing style implementation of make-from-mag-ang is straightforward. It simply returns r in response to the 'magnitude operation, A in response to the 'angle operation, and performs the respective calculations for 'real-part and 'imag-part operations:
(define (make-from-mag-ang r a)
  (define (dispatch op)
    (cond ((eq? op 'real-part) (* r (cos a)))
          ((eq? op 'imag-part) (* r (sin a)))
          ((eq? op 'magnitude) r)
          ((eq? op 'angle) a)
          (else
           (error "Unknown op -- MAKE-FROM-MAG-ANG" op))))
  dispatch)
Let's give this a spin... First, to make things easy on us we'll define π (to 15 decimal places) and a procedure to convert degrees to radians:
(define pi 3.141592653589793)
(define (degrees->radians d) (/ (* d pi) 180))
First, we can test the selectors:
> (define a (make-from-mag-ang 2 (degrees->radians 45)))
> (define b (make-from-mag-ang 3 0))
> (define c (make-from-mag-ang 2 (degrees->radians 135)))
> (magnitude a)
2
> (angle a)
0.7853981633974483
> (real-part a)
1.4142135623730951
> (imag-part a)
1.414213562373095
> (real-part b)
3.0
> (imag-part b)
0.0
> (real-part c)
-1.414213562373095
> (imag-part c)
1.4142135623730951
Then we can try a few arithmetic operations:
> (define d (add-complex a a))
> (real-part d)
2.8284271247461903
> (imag-part d)
2.82842712474619
> (define e (add-complex a b))
> (real-part e)
4.414213562373095
> (imag-part e)
1.414213562373095
> (define f (sub-complex b a))
> (real-part f)
1.5857864376269049
> (imag-part f)
-1.414213562373095
> (define g (mul-complex a b))
> (real-part g)
4.242640687119286
> (imag-part g)
4.242640687119285

No comments:

Post a Comment