module: extended-library language: prefix-dylan author: Jonathan Bachrach Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND (define-class () (real-part required-init-keyword: real-part: type: ) (imag-part required-init-keyword: imag-part: type: )) (define-method contagious-class ((x ) (y )) ) (define-method contagious-class ((x ) (y )) ) (define-method contagious-class ((x ) (y )) ) (define-method contagious-class ((x ) (y )) ) (define-method contagious-class ((x ) (y )) ) (define-method contagious-class ((x ) (y )) ) (define-method contagious-class ((x ) (y )) ) (define-method make ((class (singleton )) #rest all-keys #key real (imag: imaginary) magnitude angle) (if real (if imaginary (if magnitude (error "Illegal arguments to make ~A" all-keys) (if angle (error "Illegal arguments to make ~A" all-keys) (make-rectangular real imaginary))) (if magnitude (error "Illegal arguments to make ~A" all-keys) (if angle (error "Illegal arguments to make ~A" all-keys) (make-rectangular real 0)))) (if imaginary (if magnitude (error "Illegal arguments to make ~A" all-keys) (if angle (error "Illegal arguments to make ~A" all-keys) (make-rectangular 0 imaginary))) (if magnitude (if angle (make-polar magnitude angle) (make-polar magnitude 0)) (if angle (make-polar 0 angle) (make-rectangular 0 0)))))) (define-method canonicalize ((number )) (if (= (imag-part number) 0) (shallow-copy (real-part number)) number)) (define-method as ((class (singleton )) (real )) (make-rectangular real 0)) (define-method id-hash ((object )) (values (merge-hash-ids (id-hash (real-part object)) (id-hash (imag-part object)) ordered: #T) $permanent-hash-state)) (define-method make-rectangular ((real-part ) (imag-part )) (make real-part: real-part imag-part: imag-part)) (define-method make-rectangular* ((real-part ) (imag-part )) (canonicalize (make-rectangular real-part imag-part))) (define $i (make-rectangular 0 1)) (define-method make-polar ((magnitude ) (angle )) (make real-part: (* magnitude (sin angle)) imag-part: (* magnitude (cos angle)))) (define-method angle ((complex )) (atan2 (real-part complex) (imag-part complex))) (define-method integral? ((number )) (and (integral? (real-part number)) (integral? (imag-part number)))) (define-method = ((number-1 ) (number-2 )) (and (= (real-part number-1) (real-part number-2)) (= (imag-part number-1) (imag-part number-2)))) (define-method < ((number-1 ) (number-2 )) (bind ((distance-1 (+ (* (real-part number-1) (real-part number-1)) (* (imag-part number-1) (imag-part number-1)))) (distance-2 (+ (* (real-part number-2) (real-part number-2)) (* (imag-part number-2) (imag-part number-2))))) (< distance-1 distance-2))) (define-method + ((number-1 ) (number-2 )) (make-rectangular* (+ (real-part number-1) (real-part number-2)) (+ (imag-part number-1) (imag-part number-2)))) (define-method * ((number-1 ) (number-2 )) (make-rectangular* (- (* (real-part number-1) (real-part number-2)) (* (imag-part number-1) (imag-part number-2))) (+ (* (imag-part number-1) (real-part number-2)) (* (real-part number-1) (imag-part number-2))))) (define-method - ((number-1 ) (number-2 )) (make-rectangular* (- (real-part number-1) (real-part number-2)) (- (imag-part number-1) (imag-part number-2)))) (define-method / ((x ) (y )) (bind (((rx ) (real-part x)) ((ix ) (imag-part x)) ((ry ) (real-part y)) ((iy ) (imag-part y)) ((denominator ) (+ (* ry ry) (* iy iy)))) (make-rectangular* (/ (+ (* rx ry) (* ix iy)) denominator) (/ (- (* ix ry) (* rx iy)) denominator)))) (define-method negative ((number )) (make-rectangular (- (real-part number)) (- (imag-part number)))) (define-method abs ((number )) (sqrt (+ (* (real-part number) (real-part number)) (* (imag-part number) (imag-part number))))) (define-method phase ((number )) (atan2 (imag-part number) (real-part number))) ;;; !@#$ IRRATIONALS NOT NECESSARILY WORKING ;;; !@#$ NEED TO COMPARE AGAINST A DEPENDABLE IMPLEMENTATION (define-method sin ((number )) (bind (((real ) (real-part number)) ((imag ) (imag-part number))) (make-rectangular (* (sin real) (cosh imag)) (* (cos real) (sinh imag))))) (define-method cos ((number )) (bind (((real ) (real-part number)) ((imag ) (imag-part number))) (make-rectangular (* (cos real) (cosh imag)) (- (* (sin real) (sinh imag)))))) (define-method tan ((number )) (bind (((numerator ) (sin number)) ((denominator ) (cos number))) (if (zero? denominator) (error "~S undefined tangent." number) (/ numerator denominator)))) (define-method asin ((number )) (- (* $i (log (+ (* $i number) (sqrt (- 1 (* number number)))))))) (define-method acos ((number )) (- (/ $pi 2) (asin number))) (define-method atan ((number )) (/ (- (log (+ 1 (* $i number))) (log (- 1 (* $i number)))) (* 2 $i))) (define-method sinh ((number )) (/ (- (exp number) (exp (- number))) 2)) (define-method cosh ((number )) (/ (+ (exp number) (exp (- number))) 2)) (define-method tanh ((number )) (/ (- (exp number) (exp (- number))) (+ (exp number) (exp (- number))))) (define-method asinh ((number )) (log (+ number (sqrt (+ 1 (* number number)))))) (define-method acosh ((number )) (log (+ number (* (+ number 1) (sqrt (/ (- number 1) (+ number 1))))))) (define-method atanh ((number )) (log (* (+ number 1) (sqrt (/ (- 1 (* number number))))))) (define-method log ((number )) (make-rectangular* (log (abs number)) (phase number))) (define-method exp ((power )) (* (exp (real-part power)) (cis (imag-part power)))) (define-method expt ((base ) (power )) (if (negative? base) (/ (exp (* power (log (- base))))) (exp (* power (log base))))) (define-method expt ((base ) (power )) (* (expt (abs base) power) (cis (* power (phase base))))) (define-method expt ((base ) (power )) (exp (* power (log base)))) (define-method sqrt ((number )) (exp (/ (log number) 2)))