proposal for object-oriented dispatch on sign
- Subject: proposal for object-oriented dispatch on sign
- From: Barton Willis
- Date: Mon, 20 Jun 2011 13:01:44 -0500
Proposal: Modify sign (not $sign) to use object-oriented dispatch.
The function associated with %asin extends the current sign function, I think:
(%i1) assume(-1 < x, x < 0);
(%o1) [x > - 1, x < 0]
(%i2) sign(asin(x));
(%o2) neg
The code (the frob macro is based on similar code in trigi): Comments?
(defvar *sign-function* (make-hash-table :size 32)
"Hash table mapping a maxima function identifier to a CL function that determines the
sign of an expression.")
(macrolet ((frob (fun sign-fun) `(setf (gethash ',fun *sign-function*) ,sign-fun)))
(frob mtimes 'sign-mtimes)
(frob mplus 'sign-mplus)
(frob mexpt 'sign-mexpt)
(frob %log 'sign-log)
(frob mabs 'sign-mabs)
(frob $min #'(lambda (x) (sign-minmax (caar x) (cdr x))))
(frob $max #'(lambda (x) (sign-minmax (caar x) (cdr x))))
(frob %csc #'(lambda (x) (sign (inv* (cons (ncons (zl-get (caar x) 'recip)) (cdr x))))))
(frob %csch #'(lambda (x) (sign (inv* (cons (ncons (zl-get (caar x) 'recip)) (cdr x))))))
(frob %asin #'(lambda (x) (if (and (eq t (mgrp (cadr x) -1)) (eq t (mgrp 1 (cadr x)))) (sign (cadr x)) (sign-any x))))
(frob %signum #'(lambda (x) (sign (cadr x))))
(frob %erf #'(lambda (x) (sign (cadr x)))))
(defmfun sign (x)
(cond ((mnump x) (setq sign (rgrp x 0) minus nil odds nil evens nil))
((and *complexsign* (atom x) (eq x '$%i))
;; In Complex Mode the sign of %i is $imaginary.
(setq sign '$imaginary))
((atom x) (if (eq x '$%i) (imag-err x)) (sign-any x))
((gethash (mop x) *sign-function*) (funcall (gethash (mop x) *sign-function*) x))
((specrepp x) (sign (specdisrep x)))
((kindp (caar x) '$posfun) (sign-posfun x))
((and (kindp (caar x) '$oddfun) (kindp (caar x) '$increasing)) (sign-oddinc x))
(t (sign-any x))))
--Barton