150 likes | 286 Views
z = (z) + i · (z) = |z| ·e. i ·arg(z). Complex Number Arithmetic Two natural representations: • rectangular: ( real,imag ) • polar: ( norm,arg ). z = (z) + i · (z) = |z| ·e. i ·arg(z). imag. z. |z|. (z). arg(z). real. (z). Abstract Types
E N D
z = (z) + i ·(z) = |z| ·e i ·arg(z) • Complex Number Arithmetic • Two natural representations: • •rectangular:(real,imag) • •polar:(norm,arg)
z = (z) + i ·(z) = |z| ·e i ·arg(z) imag z |z| (z) arg(z) real (z)
Abstract Types (define-class <complex> (<number>)) (define-class <rect> (<complex>) (real <float>) (imag <float>)) (define-class <polar> (<complex>) (norm <float>) (arg <float>)) <object> <number> <integer> <float> <rat> <complex> <rect> <polar>
(define (make-polar <function>) (method ((n <number>) (a <number>)) (make <polar> norm: (as <float> n) arg: (as <float> a)))) (define (make-rect <function>) (method ((r <number>) (i <number>)) (make <rect> real: (as <float> r) imag: (as <float> i))))
<rect> <polar> real slot convert reference imag slot convert reference norm convert slot reference arg convert slot reference
(define-generic-function real (x)) (add-method real (method ((x <rect>)) (get-slot real: x))) (define-generic-function imag (x)) (add-method imag (method ((x <rect>)) (get-slot imag: x)))
(define-generic-function real (x)) (add-method real (method ((x <rect>)) (get-slot real: x))) (define-generic-function imag (x)) (add-method imag (method ((x <rect>)) (get-slot imag: x))) Dylan does this for you!
(add-method real (method ((z <polar>)) (* (norm z) (cos (arg z))))) (add-method imag (method ((z <polar>)) (* (norm z) (sin (arg z))))) (add-method norm (method ((z <rect>)) (sqrt (+ (square (real z)) (square (imag z)))))) (add-method arg (method ((z <rect>)) (arctan (/ (imag z) (real z)))))
(define (mul-complex <function>) (method ((x <complex>) (y <complex>)) (make-polar (* (norm x) (norm y)) (+ (arg x) (arg y))))) (define (add-complex <function>) (method ((x <complex>) (y <complex>)) (make-rect (+ (real x) (real y)) (+ (imag x) (imag y)))))
(define-generic-function add (x y)) (add-method add (method ((x <number>) (y <number>)) (+ x y))) (add-method add add-rat) (add-method add add-complex) or better... (add-method binary+ add-rat) (add-method binary+ add-complex)
Coercions — the generic function as (as <float> 1) => 1.0 (as <character> 100) => d <integer> <rat> <float> <complex> (add-method as (method ((t (singleton <rat>)) (a <integer>)) (make-rat a 1))) (add-method binary+ (method ((a <integer>) (b <rat>)) (+ (as <rat> a) b))) (add-method binary+ (method ((a <rat>) (b <integer>)) (+ a (as <rat> b))))
Polynomial Arithmetic (define-class <term> (<object>) (degree <integer>) (coeff <object>)) (define (add-term <function>) (method ((t1 <term>) (t2 <term>)) (make <term> degree: (degree t1) coeff: (+ (coeff t1) (coeff t2)))))
(define <termlist> <list>) (define (first-term <function>) (method ((t <termlist>)) (head t))) (define (rest-terms <function>) (method ((t <termlist>)) (tail t))) (define empty-termlist? null?)
(define (add-terms <function>) (method ((l1 <termlist>) (l2 <termlist>)) (cond ((empty-termlist? l1) l2) ((empty-termlist? l2) l1) (else: (bind (((t1 <term>) (first-term l1)) ((t2 <term>) (first-term l2)) ((r1 <termlist>) (rest-terms l1)) ((r2 <termlist>) (rest-terms l2))) (cond ((< (degree t1) (degree t2)) (adjoin-term t1 (add-terms r1 l2))) ((< (degree t2) (degree t1)) (adjoin-term t2 (add-terms l1 r2))) (else: (adjoin-term (add-term t1 t2) (add-terms r1 r2)))))))))
(define-class <poly> (<object>) (poly-variable <symbol>) (poly-terms <termlist>)) (define (same-variable? <function>) (method ((p1 <poly>) (p2 <poly>)) (= (poly-variable p1) (poly-variable p2)))) (define (add-poly <function>) (method ((p1 <poly>) (p2 <poly>)) (if (same-variable? p1 p2) (make <poly> poly-variable: (poly-variable p1) poly-terms: (add-terms (poly-terms p1) (poly-terms p2))) (error "Polynomials not in same variable")))) (add-method binary+ add-poly)