From 25b67e68b349c3b36ccea6f71abd9be9ccf21959 Mon Sep 17 00:00:00 2001 From: "Thomas M. Hermann" Date: Thu, 30 Apr 2009 14:24:49 -0500 Subject: [PATCH] Updated routines to handle complex numbers with integer components. - Updated COMPLEX-EQUAL to compare integer components as well as floating point. - Updated COMPLEX-RANDOM to properly handle integer components. In particular, ensure that the integer limit for the imaginary component is greater than 1. This is critical because if the components are rational and the imaginary part is zero, the complex number is converted to a rational. [CLHS 12.1.5.3] --- floating-point.lisp | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/floating-point.lisp b/floating-point.lisp index e505796..6dc8860 100644 --- a/floating-point.lisp +++ b/floating-point.lisp @@ -87,9 +87,12 @@ than some epsilon." "Return true if the relative error between Re(complex1), Re(complex2) and between Im(complex1), Im(complex2) are each less than epsilon." - (when (and (typep complex1 '(complex float)) - (typep complex2 '(complex float))) - (%complex-equal complex1 complex2 epsilon))) + (cond + ((and (typep complex1 '(complex float)) + (typep complex2 '(complex float))) + (%complex-equal complex1 complex2 epsilon)) + ((and (complexp complex1) (complexp complex2)) + (= complex1 complex2)))) (defmacro assert-complex-equal (expected form &rest extras) (expand-assert :equal form form expected extras :test #'complex-equal)) @@ -356,13 +359,31 @@ are not equal." (mapcar (lambda (x) (make-list columns :initial-element x)) (make-list rows :initial-element initial-element))) -(defun complex-random (limit &optional (state *random-state*)) - "Return a random complex number." - (check-type limit complex) +(defun %complex-float-random (limit &optional (state *random-state*)) + "Return a random complex float number." (complex (random (realpart limit) state) (random (imagpart limit) state))) +(defun %complex-rational-random (limit &optional (state *random-state*)) + "Return a random complex rational number." + (let ((imaglimit (imagpart limit))) + (if (< 1 imaglimit) + (complex + (random (realpart limit) state) + ;; Ensure that the imaginary part is not zero. + (do ((im (random imaglimit state) + (random imaglimit state))) + ((< 0 im) im))) + (error "Imaginary part must be greater than 1.")))) + +(defun complex-random (limit &optional (state *random-state*)) + "Return a random complex number. " + (check-type limit complex) + (if (typep limit '(complex rational)) + (%complex-rational-random limit state) + (%complex-float-random limit state))) + (defun make-random-list (size &optional (limit 1.0)) "Return a list of random numbers." (mapcar (if (complexp limit) #'complex-random #'random) -- 2.11.4.GIT