From: David R. Sky
Subject: signum not working on complex numbers in XLISP 2.1e
Date: 
Message-ID: <Pine.LNX.4.61.0512162343210.6087@viper.wapvi.bc.ca>
Hi,

I've recently started using XLISP 2.1e for DOS, and found it has
the following math function:

"(signum <expr>)                                    GET THE SIGN OF
A NUMBER      Defined in common.lsp
      <expr>    the number
      returns   zero if number is zero, one if positive, or negative
one  if                negative.  Numeric  type is  same as 
number. For  a complex                number, returns unit
magnitude but same phase as number."

it works fine for real numbers, not so for complex numbers:

error: bad argument type - #c([real] [imag])

the code in the included common.lsp file is:

(defun signum (x)
    (cond ((not (numberp x)) (error "not a number" x))
          ((zerop x) x)
       (T (/ x (abs x)))))

I wrote some extra code. (signum x) still gives me the same error
msg, but (signum-imag x) works fine on its own (pardon lack of
white space, I can't see it):

; square function required to calculate initial radius 
; for complex numbers 
(defun sqr (n) (* n n))

; signum, partially altered
(defun signum (x)
    (cond ((not (numberp x)) (error "not a number" x))
          ((zerop x) x)
       ((= (imagpart x) 0) (/ x (abs x)))
; error msg for below option:
(t (signum-imag x))))

; but it works fine on its own:
; by David R. Sky, December 16, 2005
; released under terms of the Gnu Public License
(defun signum-imag (x)
(setf radius 
(sqrt (+ (sqr (realpart x))
(sqr (imagpart x)))))
(complex (/ (realpart x) radius)
(/ (imagpart x) radius)))

Is the problem with my code or with XLISP 2.1e, and how can I fix
the problem?

Thanks

David

From: Carl Taylor
Subject: Re: signum not working on complex numbers in XLISP 2.1e
Date: 
Message-ID: <Hu2pf.166035$qk4.149715@bgtnsc05-news.ops.worldnet.att.net>
"David R. Sky" <···@viper.wapvi.bc.ca> wrote in message 
·····································@viper.wapvi.bc.ca...
> Hi,
>
> I've recently started using XLISP 2.1e for DOS, and found it has
> the following math function:
>
> "(signum <expr>)                                    GET THE SIGN OF
> A NUMBER      Defined in common.lsp
>      <expr>    the number
>      returns   zero if number is zero, one if positive, or negative
> one  if                negative.  Numeric  type is  same as number. For  a 
> complex                number, returns unit
> magnitude but same phase as number."
>
> it works fine for real numbers, not so for complex numbers:
>
> error: bad argument type - #c([real] [imag])
>
> the code in the included common.lsp file is:
>
> (defun signum (x)
>    (cond ((not (numberp x)) (error "not a number" x))
>          ((zerop x) x)
>       (T (/ x (abs x)))))
>
> I wrote some extra code. (signum x) still gives me the same error
> msg, but (signum-imag x) works fine on its own (pardon lack of
> white space, I can't see it):

Could your problem be that you've given your function a name identical to
Lisp's own name? This can cause an error break if you don't first "shadow"
the installation function.  But just giving it a new name will of course 
also
fix the problem.  If I rename your function it works fine in LispWorks.  If 
it
still fails for you then I guess  XLISP 2.1e for DOS is not your friend.

> ; square function required to calculate initial radius ; for complex 
> numbers (defun sqr (n) (* n n))
>
> ; signum, partially altered
> (defun signum (x)
>    (cond ((not (numberp x)) (error "not a number" x))
>          ((zerop x) x)
>       ((= (imagpart x) 0) (/ x (abs x)))
> ; error msg for below option:
> (t (signum-imag x))))
>
> ; but it works fine on its own:
> ; by David R. Sky, December 16, 2005
> ; released under terms of the Gnu Public License
> (defun signum-imag (x)
> (setf radius (sqrt (+ (sqr (realpart x))
> (sqr (imagpart x)))))
> (complex (/ (realpart x) radius)
> (/ (imagpart x) radius)))

As your code is written, using <setf> causes the variable "radius"
to be classified as "special".  It should be bound using <let>.

With these modifications everything works fine.

CL-USER 1 >
(defun my-signum (x)
  (cond ((not (numberp x)) (error "not a number" x))
           ((zerop x) x)
           ((= (imagpart x) 0) (/ x (abs x)))
           ; error msg for below option:
           (t (signum-imag x))))
MY-SIGNUM

CL-USER 2 >
(defun sqr (n) (* n n))
SQR

CL-USER 3 >
(defun signum-imag (x)
  (let ((radius
           (sqrt (+ (sqr (realpart x))
                       (sqr (imagpart x))))))
     (complex (/ (realpart x) radius)
                   (/ (imagpart x) radius))))
SIGNUM-IMAG

CL-USER 4 >
(my-signum 123)
1

CL-USER 5 >
(my-signum -123)
-1

CL-USER 6 >
(my-signum 0)
0

CL-USER 7 > (my-signum #c(3 -9))
#C(0.31622776601683794 -0.9486832980505138)
From: David R. Sky
Subject: Re: signum not working on complex numbers in XLISP 2.1e
Date: 
Message-ID: <Pine.LNX.4.61.0512180137560.22521@viper.wapvi.bc.ca>
Hi Carl,

Carl: Could your problem be that you've given your function a name
identical to Lisp's own name? This can cause an error break if you
don't first "shadow" the installation function. But just giving it
a new name will of course also fix the problem.

David: I don't understand what you mean, I did name my function
differently from signum, I called it signum-imag.

As I wrote it, signum-imag works whether I input a real or complex
number (it returns a complex number), as does your <let> code. But
I wanted signum-imag to be called from within the common.lsp signum
when it encountered a complex number.

With your code adjustments I still get an error message when I type
for example

(signum #c(0 1))

error: bad argument type #c(0 1)

but

(signum-imag #c(0 1))

returns the correct

#c(0 1)

Thanks

David
On Sun, 18 Dec 2005, Carl Taylor wrote:

>
> "David R. Sky" <···@viper.wapvi.bc.ca> wrote in message 
> ·····································@viper.wapvi.bc.ca...
>> Hi,
>> 
>> I've recently started using XLISP 2.1e for DOS, and found it has
>> the following math function:
>> 
>> "(signum <expr>)                                    GET THE SIGN OF
>> A NUMBER      Defined in common.lsp
>>      <expr>    the number
>>      returns   zero if number is zero, one if positive, or negative
>> one  if                negative.  Numeric  type is  same as number. For  a 
>> complex                number, returns unit
>> magnitude but same phase as number."
>> 
>> it works fine for real numbers, not so for complex numbers:
>> 
>> error: bad argument type - #c([real] [imag])
>> 
>> the code in the included common.lsp file is:
>> 
>> (defun signum (x)
>>    (cond ((not (numberp x)) (error "not a number" x))
>>          ((zerop x) x)
>>       (T (/ x (abs x)))))
>> 
>> I wrote some extra code. (signum x) still gives me the same error
>> msg, but (signum-imag x) works fine on its own (pardon lack of
>> white space, I can't see it):
>
> Could your problem be that you've given your function a name identical to
> Lisp's own name? This can cause an error break if you don't first "shadow"
> the installation function.  But just giving it a new name will of course also
> fix the problem.  If I rename your function it works fine in LispWorks.  If 
> it
> still fails for you then I guess  XLISP 2.1e for DOS is not your friend.
>
>> ; square function required to calculate initial radius ; for complex 
>> numbers (defun sqr (n) (* n n))
>> 
>> ; signum, partially altered
>> (defun signum (x)
>>    (cond ((not (numberp x)) (error "not a number" x))
>>          ((zerop x) x)
>>       ((= (imagpart x) 0) (/ x (abs x)))
>> ; error msg for below option:
>> (t (signum-imag x))))
>> 
>> ; but it works fine on its own:
>> ; by David R. Sky, December 16, 2005
>> ; released under terms of the Gnu Public License
>> (defun signum-imag (x)
>> (setf radius (sqrt (+ (sqr (realpart x))
>> (sqr (imagpart x)))))
>> (complex (/ (realpart x) radius)
>> (/ (imagpart x) radius)))
>
> As your code is written, using <setf> causes the variable "radius"
> to be classified as "special".  It should be bound using <let>.
>
> With these modifications everything works fine.
>
> CL-USER 1 >
> (defun my-signum (x)
> (cond ((not (numberp x)) (error "not a number" x))
>          ((zerop x) x)
>          ((= (imagpart x) 0) (/ x (abs x)))
>          ; error msg for below option:
>          (t (signum-imag x))))
> MY-SIGNUM
>
> CL-USER 2 >
> (defun sqr (n) (* n n))
> SQR
>
> CL-USER 3 >
> (defun signum-imag (x)
> (let ((radius
>          (sqrt (+ (sqr (realpart x))
>                      (sqr (imagpart x))))))
>    (complex (/ (realpart x) radius)
>                  (/ (imagpart x) radius))))
> SIGNUM-IMAG
>
> CL-USER 4 >
> (my-signum 123)
> 1
>
> CL-USER 5 >
> (my-signum -123)
> -1
>
> CL-USER 6 >
> (my-signum 0)
> 0
>
> CL-USER 7 > (my-signum #c(3 -9))
> #C(0.31622776601683794 -0.9486832980505138)
>
>
>