[comp.sources.misc] v13i033: Emacs Calculator 1.01, part 07/19

daveg@csvax.caltech.edu (David Gillespie) (06/06/90)

Posting-number: Volume 13, Issue 33
Submitted-by: daveg@csvax.caltech.edu (David Gillespie)
Archive-name: gmcalc/part07

---- Cut Here and unpack ----
#!/bin/sh
# this is part 7 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file calc-ext.el continued
#
CurArch=7
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file calc-ext.el"
sed 's/^X//' << 'SHAR_EOF' >> calc-ext.el
X
X;;; Create a vector of consecutive integers. [Public]
X(defun math-vec-index (n)
X  (and (not (integerp n))
X       (setq n (math-check-fixnum n)))
X  (or (natnump n) (math-reject-arg n 'natnump))
X  (let ((vec nil))
X    (while (> n 0)
X      (setq vec (cons n vec)
X	    n (1- n)))
X    (cons 'vec vec))
X)
X(fset 'calcFunc-index (symbol-function 'math-vec-index))
X
X
X;;; Compute the row and column norms of a vector or matrix.  [Public]
X(defun math-rnorm (a)
X  (if (and (Math-vectorp a)
X	   (math-constp a))
X      (if (math-matrixp a)
X	  (math-reduce-vec 'math-max (math-map-vec 'math-cnorm a))
X	(math-reduce-vec 'math-max (math-map-vec 'math-abs a)))
X    (calc-record-why 'vectorp a)
X    (list 'calcFunc-rnorm a))
X)
X(fset 'calcFunc-rnorm (symbol-function 'math-rnorm))
X
X(defun math-cnorm (a)
X  (if (and (Math-vectorp a)
X	   (math-constp a))
X      (if (math-matrixp a)
X	  (math-reduce-vec 'math-max
X			   (math-reduce-cols 'math-add-abs a))
X	(math-reduce-vec 'math-add-abs a))
X    (calc-record-why 'vectorp a)
X    (list 'calcFunc-cnorm a))
X)
X(fset 'calcFunc-cnorm (symbol-function 'math-cnorm))
X
X(defun math-add-abs (a b)
X  (math-add (math-abs a) (math-abs b))
X)
X
X
X;;; Sort the elements of a vector into increasing order.
X(defun math-sort-vector (vec)   ; [Public]
X  (if (math-vectorp vec)
X      (cons 'vec (sort (copy-sequence (cdr vec)) 'math-beforep))
X    (math-reject-arg vec 'vectorp))
X)
X(fset 'calcFunc-sort (symbol-function 'math-sort-vector))
X
X(defun math-rsort-vector (vec)   ; [Public]
X  (if (math-vectorp vec)
X      (cons 'vec (nreverse (sort (copy-sequence (cdr vec)) 'math-beforep)))
X    (math-reject-arg vec 'vectorp))
X)
X(fset 'calcFunc-rsort (symbol-function 'math-rsort-vector))
X
X
X;;; Compile a histogram of data from a vector.
X(defun math-histogram (vec wts n)
X  (or (Math-vectorp vec)
X      (math-reject-arg vec 'vectorp))
X  (if (Math-vectorp wts)
X      (or (= (length vec) (length wts))
X	  (math-dimension-error)))
X  (or (natnump n)
X      (math-reject-arg n 'natnump))
X  (let ((res (make-vector n 0))
X	(vp vec)
X	(wvec (Math-vectorp wts))
X	(wp wts)
X	bin)
X    (while (setq vp (cdr vp))
X      (setq bin (car vp))
X      (or (natnump bin)
X	  (setq bin (math-floor bin)))
X      (and (natnump bin)
X	   (< bin n)
X	   (aset res bin (math-add (aref res bin)
X				   (if wvec (car (setq wp (cdr wp))) wts)))))
X    (cons 'vec (append res nil)))
X)
X(fset 'calcFunc-histogram (symbol-function 'math-histogram))
X
X
X(defun math-matrix-trace (mat)   ; [Public]
X  (if (math-square-matrixp mat)
X      (math-matrix-trace-step 2 (1- (length mat)) mat (nth 1 (nth 1 mat)))
X    (math-reject-arg mat 'square-matrixp))
X)
X(fset 'calcFunc-tr (symbol-function 'math-matrix-trace))
X
X(defun math-matrix-trace-step (n size mat sum)
X  (if (<= n size)
X      (math-matrix-trace-step (1+ n) size mat
X			      (math-add sum (nth n (nth n mat))))
X    sum)
X)
X
X
X;;; Matrix inverse and determinant.
X(defun math-matrix-inv-raw (m)
X  (let ((n (1- (length m))))
X    (if (<= n 3)
X	(let ((det (math-det-raw m)))
X	  (and (not (math-zerop det))
X	       (math-div
X		(cond ((= n 1) 1)
X		      ((= n 2)
X		       (list 'vec
X			     (list 'vec
X				   (nth 2 (nth 2 m))
X				   (math-neg (nth 2 (nth 1 m))))
X			     (list 'vec
X				   (math-neg (nth 1 (nth 2 m)))
X				   (nth 1 (nth 1 m)))))
X		      ((= n 3)
X		       (list 'vec
X			     (list 'vec
X				   (math-sub (math-mul (nth 3 (nth 3 m))
X						       (nth 2 (nth 2 m)))
X					     (math-mul (nth 3 (nth 2 m))
X						       (nth 2 (nth 3 m))))
X				   (math-sub (math-mul (nth 3 (nth 1 m))
X						       (nth 2 (nth 3 m)))
X					     (math-mul (nth 3 (nth 3 m))
X						       (nth 2 (nth 1 m))))
X				   (math-sub (math-mul (nth 3 (nth 2 m))
X						       (nth 2 (nth 1 m)))
X					     (math-mul (nth 3 (nth 1 m))
X						       (nth 2 (nth 2 m)))))
X			     (list 'vec
X				   (math-sub (math-mul (nth 3 (nth 2 m))
X						       (nth 1 (nth 3 m)))
X					     (math-mul (nth 3 (nth 3 m))
X						       (nth 1 (nth 2 m))))
X				   (math-sub (math-mul (nth 3 (nth 3 m))
X						       (nth 1 (nth 1 m)))
X					     (math-mul (nth 3 (nth 1 m))
X						       (nth 1 (nth 3 m))))
X				   (math-sub (math-mul (nth 3 (nth 1 m))
X						       (nth 1 (nth 2 m)))
X					     (math-mul (nth 3 (nth 2 m))
X						       (nth 1 (nth 1 m)))))
X			     (list 'vec
X				   (math-sub (math-mul (nth 2 (nth 3 m))
X						       (nth 1 (nth 2 m)))
X					     (math-mul (nth 2 (nth 2 m))
X						       (nth 1 (nth 3 m))))
X				   (math-sub (math-mul (nth 2 (nth 1 m))
X						       (nth 1 (nth 3 m)))
X					     (math-mul (nth 2 (nth 3 m))
X						       (nth 1 (nth 1 m))))
X				   (math-sub (math-mul (nth 2 (nth 2 m))
X						       (nth 1 (nth 1 m)))
X					     (math-mul (nth 2 (nth 1 m))
X						       (nth 1 (nth 2 m))))))))
X		det)))
X      (let ((lud (math-matrix-lud m)))
X	(and lud
X	     (math-lud-solve lud (math-diag-matrix 1 n))))))
X)
X
X(defun math-matrix-det (m)
X  (if (math-square-matrixp m)
X      (math-with-extra-prec 2 (math-det-raw m))
X    (math-reject-arg m 'square-matrixp))
X)
X(fset 'calcFunc-det (symbol-function 'math-matrix-det))
X
X(defun math-det-raw (m)
X  (let ((n (1- (length m))))
X    (cond ((= n 1)
X	   (nth 1 (nth 1 m)))
X	  ((= n 2)
X	   (math-sub (math-mul (nth 1 (nth 1 m))
X			       (nth 2 (nth 2 m)))
X		     (math-mul (nth 2 (nth 1 m))
X			       (nth 1 (nth 2 m)))))
X	  ((= n 3)
X	   (math-sub
X	    (math-sub
X	     (math-sub
X	      (math-add
X	       (math-add
X		(math-mul (nth 1 (nth 1 m))
X			  (math-mul (nth 2 (nth 2 m))
X				    (nth 3 (nth 3 m))))
X		(math-mul (nth 2 (nth 1 m))
X			  (math-mul (nth 3 (nth 2 m))
X				    (nth 1 (nth 3 m)))))
X	       (math-mul (nth 3 (nth 1 m))
X			 (math-mul (nth 1 (nth 2 m))
X				   (nth 2 (nth 3 m)))))
X	      (math-mul (nth 3 (nth 1 m))
X			(math-mul (nth 2 (nth 2 m))
X				  (nth 1 (nth 3 m)))))
X	     (math-mul (nth 1 (nth 1 m))
X		       (math-mul (nth 3 (nth 2 m))
X				 (nth 2 (nth 3 m)))))
X	    (math-mul (nth 2 (nth 1 m))
X		      (math-mul (nth 1 (nth 2 m))
X				(nth 3 (nth 3 m))))))
X	  (t (let ((lud (math-matrix-lud m)))
X	       (if lud
X		   (let ((lu (car lud)))
X		     (math-det-step n (nth 2 lud)))
X		 0)))))
X)
X
X(defun math-det-step (n prod)
X  (if (> n 0)
X      (math-det-step (1- n) (math-mul prod (nth n (nth n lu))))
X    prod)
X)
X
X;;; This returns a list (LU index d), or NIL if not possible.
X;;; Argument M must be a square matrix.
X(defun math-matrix-lud (m)
X  (let ((old (assoc m math-lud-cache))
X	(context (list calc-internal-prec calc-prefer-frac)))
X    (if (and old (equal (nth 1 old) context))
X	(cdr (cdr old))
X      (let* ((lud (catch 'singular (math-do-matrix-lud m)))
X	     (entry (cons context lud)))
X	(if old
X	    (setcdr old entry)
X	  (setq math-lud-cache (cons (cons m entry) math-lud-cache)))
X	lud)))
X)
X(defvar math-lud-cache nil)
X
X;;; Numerical Recipes section 2.3; implicit pivoting omitted.
X(defun math-do-matrix-lud (m)
X  (let* ((lu (math-copy-matrix m))
X	 (n (1- (length lu)))
X	 i (j 1) k imax sum big
X	 (d 1) (index nil))
X    (while (<= j n)
X      (setq i 1
X	    big 0
X	    imax j)
X      (while (< i j)
X	(math-working "LUD step" (format "%d/%d" j i))
X	(setq sum (nth j (nth i lu))
X	      k 1)
X	(while (< k i)
X	  (setq sum (math-sub sum (math-mul (nth k (nth i lu))
X					    (nth j (nth k lu))))
X		k (1+ k)))
X	(setcar (nthcdr j (nth i lu)) sum)
X	(setq i (1+ i)))
X      (while (<= i n)
X	(math-working "LUD step" (format "%d/%d" j i))
X	(setq sum (nth j (nth i lu))
X	      k 1)
X	(while (< k j)
X	  (setq sum (math-sub sum (math-mul (nth k (nth i lu))
X					    (nth j (nth k lu))))
X		k (1+ k)))
X	(setcar (nthcdr j (nth i lu)) sum)
X	(let ((dum (math-abs-approx sum)))
X	  (if (Math-lessp big dum)
X	      (setq big dum
X		    imax i)))
X	(setq i (1+ i)))
X      (if (> imax j)
X	  (setq lu (math-swap-rows lu j imax)
X		d (- d)))
X      (setq index (cons imax index))
X      (let ((pivot (nth j (nth j lu))))
X	(if (math-zerop pivot)
X	    (throw 'singular nil)
X	  (setq i j)
X	  (while (<= (setq i (1+ i)) n)
X	    (setcar (nthcdr j (nth i lu))
X		    (math-div (nth j (nth i lu)) pivot)))))
X      (setq j (1+ j)))
X    (list lu (nreverse index) d))
X)
X
X(defun math-swap-rows (m r1 r2)
X  (or (= r1 r2)
X      (let* ((r1prev (nthcdr (1- r1) m))
X	     (row1 (cdr r1prev))
X	     (r2prev (nthcdr (1- r2) m))
X	     (row2 (cdr r2prev))
X	     (r2next (cdr row2)))
X	(setcdr r2prev row1)
X	(setcdr r1prev row2)
X	(setcdr row2 (cdr row1))
X	(setcdr row1 r2next)))
X  m
X)
X
X(defun math-abs-approx (a)
X  (cond ((Math-negp a)
X	 (math-neg a))
X	((Math-anglep a)
X	 a)
X	((eq (car a) 'cplx)
X	 (math-add (math-abs (nth 1 a)) (math-abs (nth 2 a))))
X	((eq (car a) 'polar)
X	 (nth 1 a))
X	((eq (car a) 'sdev)
X	 (math-abs (nth 1 a)))
X	((eq (car a) 'intv)
X	 (math-max (math-abs (nth 2 a)) (math-abs (nth 3 a))))
X	((eq (car a) 'vec)
X	 (math-cnorm a))
X	((eq (car a) 'calcFunc-abs)
X	 (car a))
X	(t a))
X)
X
X(defun math-lud-solve (lud b)
X  (and lud
X	 (let* ((x (math-copy-matrix b))
X		(n (1- (length x)))
X		(m (1- (length (nth 1 x))))
X		(lu (car lud))
X		(col 1)
X		i j ip ii index sum)
X	   (while (<= col m)
X	     (math-working "LUD solver step" col)
X	     (setq i 1
X		   ii nil
X		   index (nth 1 lud))
X	     (while (<= i n)
X	       (setq ip (car index)
X		     index (cdr index)
X		     sum (nth col (nth ip x)))
X	       (setcar (nthcdr col (nth ip x)) (nth col (nth i x)))
X	       (if (null ii)
X		   (or (math-zerop sum)
X		       (setq ii i))
X		 (setq j ii)
X		 (while (< j i)
X		   (setq sum (math-sub sum (math-mul (nth j (nth i lu))
X						     (nth col (nth j x))))
X			 j (1+ j))))
X	       (setcar (nthcdr col (nth i x)) sum)
X	       (setq i (1+ i)))
X	     (while (>= (setq i (1- i)) 1)
X	       (setq sum (nth col (nth i x))
X		     j i)
X	       (while (<= (setq j (1+ j)) n)
X		 (setq sum (math-sub sum (math-mul (nth j (nth i lu))
X						   (nth col (nth j x))))))
X	       (setcar (nthcdr col (nth i x))
X		       (math-div sum (nth i (nth i lu)))))
X	     (setq col (1+ col)))
X	   x))
X)
X
X(defun calcFunc-lud (m)
X  (if (math-square-matrixp m)
X      (or (math-with-extra-prec 2
X	    (let ((lud (math-matrix-lud m)))
X	      (and lud
X		   (let* ((lmat (math-copy-matrix (car lud)))
X			  (umat (math-copy-matrix (car lud)))
X			  (n (1- (length (car lud))))
X			  (perm (math-diag-matrix 1 n))
X			  i (j 1))
X		     (while (<= j n)
X		       (setq i 1)
X		       (while (< i j)
X			 (setcar (nthcdr j (nth i lmat)) 0)
X			 (setq i (1+ i)))
X		       (setcar (nthcdr j (nth j lmat)) 1)
X		       (while (<= (setq i (1+ i)) n)
X			 (setcar (nthcdr j (nth i umat)) 0))
X		       (setq j (1+ j)))
X		     (while (>= (setq j (1- j)) 1)
X		       (let ((pos (nth (1- j) (nth 1 lud))))
X			 (or (= pos j)
X			     (setq perm (math-swap-rows perm j pos)))))
X		     (list 'vec perm lmat umat)))))
X	  (math-reject-arg m "Singular matrix"))
X    (math-reject-arg m 'square-matrixp))
X)
X
X;;; Compute a right-handed vector cross product.  [O O O] [Public]
X(defun math-cross (a b)
X  (if (and (eq (car-safe a) 'vec)
X	   (= (length a) 4))
X      (if (and (eq (car-safe b) 'vec)
X	       (= (length b) 4))
X	  (list 'vec
X		(math-sub (math-mul (nth 2 a) (nth 3 b))
X			  (math-mul (nth 3 a) (nth 2 b)))
X		(math-sub (math-mul (nth 3 a) (nth 1 b))
X			  (math-mul (nth 1 a) (nth 3 b)))
X		(math-sub (math-mul (nth 1 a) (nth 2 b))
X			  (math-mul (nth 2 a) (nth 1 b))))
X	(math-reject-arg b "Three-vector expected"))
X    (math-reject-arg a "Three-vector expected"))
X)
X(fset 'calcFunc-cross (symbol-function 'math-cross))
X
X
X
X
X;;;; Hours-minutes-seconds forms.
X
X(defun math-normalize-hms (a)
X  (let ((h (math-normalize (nth 1 a)))
X	(m (math-normalize (nth 2 a)))
X	(s (let ((calc-internal-prec (max (- calc-internal-prec 4) 3)))
X	     (math-normalize (nth 3 a)))))
X    (if (math-negp h)
X	(progn
X	  (if (math-posp s)
X	      (setq s (math-add s -60)
X		    m (math-add m 1)))
X	  (if (math-posp m)
X	      (setq m (math-add m -60)
X		    h (math-add h 1)))
X	  (if (not (math-lessp -60 s))
X	      (setq s (math-add s 60)
X		    m (math-add m -1)))
X	  (if (not (math-lessp -60 m))
X	      (setq m (math-add m 60)
X		    h (math-add h -1))))
X      (if (math-negp s)
X	  (setq s (math-add s 60)
X		m (math-add m -1)))
X      (if (math-negp m)
X	  (setq m (math-add m 60)
X		h (math-add h -1)))
X      (if (not (math-lessp s 60))
X	  (setq s (math-add s -60)
X		m (math-add m 1)))
X      (if (not (math-lessp m 60))
X	  (setq m (math-add m -60)
X		h (math-add h 1))))
X    (if (and (eq (car-safe s) 'float)
X	     (<= (+ (math-numdigs (nth 1 s)) (nth 2 s))
X		 (- 2 calc-internal-prec)))
X	(setq s 0))
X    (list 'hms h m s))
X)
X
X;;; Convert A from ANG or current angular mode to HMS format.
X(defun math-to-hms (a &optional ang)   ; [X R] [Public]
X  (cond ((eq (car-safe a) 'hms) a)
X	((eq (car-safe a) 'sdev)
X	 (math-make-sdev (math-to-hms (nth 1 a))
X			 (math-to-hms (nth 2 a))))
X	((not (Math-numberp a))
X	 (list 'calcFunc-hms a))
X	((math-negp a)
X	 (math-neg (math-to-hms (math-neg a) ang)))
X	((eq (or ang calc-angle-mode) 'rad)
X	 (math-to-hms (math-div a (math-pi-over-180)) 'deg))
X	((memq (car-safe a) '(cplx polar)) a)
X	(t
X	 ;(setq a (let ((calc-internal-prec (max (1- calc-internal-prec) 3)))
X	 ;	    (math-normalize a)))
X	 (math-normalize
X	  (let* ((b (math-mul a 3600))
X		 (hm (math-trunc (math-div b 60)))
X		 (hmd (math-idivmod hm 60)))
X	    (list 'hms
X		  (car hmd)
X		  (cdr hmd)
X		  (math-sub b (math-mul hm 60)))))))
X)
X(fset 'calcFunc-hms (symbol-function 'math-to-hms))
X
X;;; Convert A from HMS format to ANG or current angular mode.
X(defun math-from-hms (a &optional ang)   ; [R X] [Public]
X  (cond ((not (eq (car-safe a) 'hms))
X	 (if (Math-numberp a)
X	     a
X	   (if (eq (car-safe a) 'sdev)
X	     (math-make-sdev (math-from-hms (nth 1 a))
X			     (math-from-hms (nth 2 a)))
X	     (if (eq (or ang calc-angle-mode) 'rad)
X		 (list '>rad a)
X	       (list '>deg a)))))
X	((math-negp a)
X	 (math-neg (math-from-hms (math-neg a) ang)))
X	((eq (or ang calc-angle-mode) 'rad)
X	 (math-mul (math-from-hms a 'deg) (math-pi-over-180)))
X	((memq (car-safe a) '(cplx polar)) a)
X	(t
X	 (math-add (math-div (math-add (math-div (nth 3 a)
X						 '(float 6 1))
X				       (nth 2 a))
X			     60)
X		   (nth 1 a))))
X)
X
X
X
X;;;; Complex numbers.
X
X(defun math-normalize-polar (a)
X  (let ((r (math-normalize (nth 1 a)))
X	(th (math-normalize (nth 2 a))))
X    (cond ((math-zerop r)
X	   '(polar 0 0))
X	  ((or (math-zerop th))
X	   r)
X	  ((and (not (eq calc-angle-mode 'rad))
X		(or (equal th '(float 18 1))
X		    (equal th 180)))
X	   (math-neg r))
X	  ((math-negp r)
X	   (math-neg (list 'polar (math-neg r) th)))
X	  (t
X	   (list 'polar r th))))
X)
X
X
X;;; Coerce A to be complex (rectangular form).  [c N]
X(defun math-complex (a)
X  (cond ((eq (car-safe a) 'cplx) a)
X	((eq (car-safe a) 'polar)
X	 (if (math-zerop (nth 1 a))
X	     (nth 1 a)
X	   (let ((sc (math-sin-cos (nth 2 a))))
X	     (list 'cplx
X		   (math-mul (nth 1 a) (nth 1 sc))
X		   (math-mul (nth 1 a) (nth 2 sc))))))
X	(t (list 'cplx a 0)))
X)
X
X;;; Coerce A to be complex (polar form).  [c N]
X(defun math-polar (a)
X  (cond ((eq (car-safe a) 'polar) a)
X	((math-zerop a) '(polar 0 0))
X	(t
X	 (list 'polar
X	       (math-abs a)
X	       (math-cplx-arg a))))
X)
X
X;;; Multiply A by the imaginary constant i.  [N N] [Public]
X(defun math-imaginary (a)
X  (if (and (Math-objvecp a)
X	   (not calc-symbolic-mode))
X      (math-mul a
X		(if (or (eq (car-safe a) 'polar)
X			(and (not (eq (car-safe a) 'cplx))
X			     (eq calc-complex-mode 'polar)))
X		    (list 'polar 1 (math-quarter-circle nil))
X		  '(cplx 0 1)))
X    (math-mul a '(var i var-i)))
X)
X
X
X;;;; Error forms.
X
X;;; Build a standard deviation form.  [X X X]
X(defun math-make-sdev (x sigma)
X  (if (memq (car-safe x) '(cplx polar mod sdev intv vec))
X      (math-reject-arg x 'realp))
X  (if (memq (car-safe sigma) '(cplx polar mod sdev intv vec))
X      (math-reject-arg sigma 'realp))
X  (if (math-negp sigma)
X      (list 'sdev x (math-neg sigma))
X    (if (and (math-zerop sigma) (Math-scalarp x))
X	x
X      (list 'sdev x sigma)))
X)
X(defun calcFunc-sdev (x sigma)
X  (math-make-sdev x sigma)
X)
X
X
X
X;;;; Modulo forms.
X
X(defun math-normalize-mod (a)
X  (let ((n (math-normalize (nth 1 a)))
X	(m (math-normalize (nth 2 a))))
X    (if (and (math-anglep n) (math-anglep m) (math-posp m))
X	(math-make-mod n m)
X      (if (math-anglep n)
X	  (if (math-anglep m)
X	      (calc-record-why "Modulus must be positive" m)
X	    (calc-record-why "Modulus must be real" m))
X	(calc-record-why "Value must be real" n))
X      (list 'calcFunc-makemod n m)))
X)
X
X;;; Build a modulo form.  [N R R]
X(defun math-make-mod (n m)
X  (setq calc-previous-modulo m)
X  (and n
X       (if (not (and (Math-anglep n) (Math-anglep m)))
X	   (math-reject-arg n 'anglep)
X	 (if (or (Math-negp n)
X		 (not (Math-lessp n m)))
X	     (list 'mod (math-mod n m) m)
X	   (list 'mod n m))))
X)
X(defun calcFunc-makemod (n m)
X  (math-make-mod n m)
X)
X
X
X
X;;;; Interval forms.
X
X;;; Build an interval form.  [X I X X]
X(defun math-make-intv (mask lo hi)
X  (if (memq (car-safe lo) '(cplx polar mod sdev intv vec))
X      (math-reject-arg lo 'realp))
X  (if (memq (car-safe hi) '(cplx polar mod sdev intv vec))
X      (math-reject-arg hi 'realp))
X  (if (and (Math-realp lo) (Math-realp hi))
X      (let ((cmp (math-compare lo hi)))
X	(if (= cmp 0)
X	    (if (= mask 3)
X		lo
X	      (list 'intv mask lo hi))
X	  (if (> cmp 0)
X	      (if (= mask 3)
X		  (list 'intv 2 lo lo)
X		(list 'intv mask lo lo))
X	    (list 'intv mask lo hi))))
X    (list 'intv mask lo hi))
X)
X
X(defun math-sort-intv (mask lo hi)
X  (if (Math-lessp hi lo)
X      (math-make-intv (aref [0 2 1 3] mask) hi lo)
X    (math-make-intv mask lo hi))
X)
X
X
X
X;;;; Arithmetic.
X
X(defun math-neg-fancy (a)
X  (cond ((eq (car a) 'polar)
X	 (list 'polar
X	       (nth 1 a)
X	       (if (math-posp (nth 2 a))
X		   (math-sub (nth 2 a) (math-half-circle nil))
X		 (math-add (nth 2 a) (math-half-circle nil)))))
X	((eq (car a) 'mod)
X	 (if (math-zerop (nth 1 a))
X	     a
X	   (list 'mod (math-sub (nth 2 a) (nth 1 a)) (nth 2 a))))
X	((eq (car a) 'sdev)
X	 (list 'sdev (math-neg (nth 1 a)) (nth 2 a)))
X	((eq (car a) 'intv)
X	 (math-make-intv (aref [0 2 1 3] (nth 1 a))
X			 (math-neg (nth 3 a))
X			 (math-neg (nth 2 a))))
X	((eq (car a) '-)
X	 (math-sub (nth 2 a) (nth 1 a)))
X	((and (memq (car a) '(* /))
X	      (math-looks-negp (nth 1 a)))
X	 (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
X	((and (memq (car a) '(* /))
X	      (math-looks-negp (nth 2 a)))
X	 (list (car a) (nth 1 a) (math-neg (nth 2 a))))
X	((and (memq (car a) '(* /))
X	      (or (math-numberp (nth 1 a))
X		  (and (eq (car (nth 1 a)) '*)
X		       (math-numberp (nth 1 (nth 1 a))))))
X	 (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
X	((and (eq (car a) '/)
X	      (or (math-numberp (nth 2 a))
X		  (and (eq (car (nth 2 a)) '*)
X		       (math-numberp (nth 1 (nth 2 a))))))
X	 (list (car a) (nth 1 a) (math-neg (nth 2 a))))
X	((eq (car a) 'neg)
X	 (nth 1 a))
X	(t (list 'neg a)))
X)
X
X(defun math-neg-float (a)
X  (list 'float (Math-integer-neg (nth 1 a)) (nth 2 a))
X)
X
X(defun math-add-objects-fancy (a b)
X  (cond ((and (Math-numberp a) (Math-numberp b))
X	 (setq aa (math-complex a)
X	       bb (math-complex b))
X	 (math-normalize
X	  (let ((res (list 'cplx
X			   (math-add (nth 1 aa) (nth 1 bb))
X			   (math-add (nth 2 aa) (nth 2 bb)))))
X	    (if (math-want-polar a b)
X		(math-polar res)
X	      res))))
X	((or (Math-vectorp a) (Math-vectorp b))
X	 (math-map-vec-2 'math-add a b))
X	((eq (car-safe a) 'sdev)
X	 (if (eq (car-safe b) 'sdev)
X	     (math-make-sdev (math-add (nth 1 a) (nth 1 b))
X			     (math-hypot (nth 2 a) (nth 2 b)))
X	   (and (or (Math-anglep b)
X		    (not (Math-objvecp b)))
X		(math-make-sdev (math-add (nth 1 a) b)
X				(nth 2 a)))))
X	((and (eq (car-safe b) 'sdev)
X	      (or (Math-anglep a)
X		  (not (Math-objvecp a))))
X	 (math-make-sdev (math-add a (nth 1 b))
X			 (nth 2 b)))
X	((eq (car-safe a) 'intv)
X	 (if (eq (car-safe b) 'intv)
X	     (math-make-intv (logand (nth 1 a) (nth 1 b))
X			     (math-add (nth 2 a) (nth 2 b))
X			     (math-add (nth 3 a) (nth 3 b)))
X	   (and (or (Math-anglep b)
X		    (not (Math-objvecp b)))
X		(math-make-intv (nth 1 a)
X				(math-add (nth 2 a) b)
X				(math-add (nth 3 a) b)))))
X	((and (eq (car-safe b) 'intv)
X	      (or (Math-anglep a)
X		  (not (Math-objvecp a))))
X	 (math-make-intv (nth 1 b)
X			 (math-add a (nth 2 b))
X			 (math-add a (nth 3 b))))
X	((and (eq (car-safe a) 'mod)
X	      (eq (car-safe b) 'mod)
X	      (equal (nth 2 a) (nth 2 b)))
X	 (math-make-mod (math-add (nth 1 a) (nth 1 b)) (nth 2 a)))
X	((and (eq (car-safe a) 'mod)
X	      (Math-anglep b))
X	 (math-make-mod (math-add (nth 1 a) b) (nth 2 a)))
X	((and (eq (car-safe b) 'mod)
X	      (Math-anglep a))
X	 (math-make-mod (math-add a (nth 1 b)) (nth 2 b)))
X	((and (or (eq (car-safe a) 'hms) (eq (car-safe b) 'hms))
X	      (and (Math-anglep a) (Math-anglep b)))
X	 (or (eq (car-safe a) 'hms) (setq a (math-to-hms a)))
X	 (or (eq (car-safe b) 'hms) (setq b (math-to-hms b)))
X	 (math-normalize
X	  (if (math-negp a)
X	      (math-neg (math-add (math-neg a) (math-neg b)))
X	    (if (math-negp b)
X		(let* ((s (math-add (nth 3 a) (nth 3 b)))
X		       (m (math-add (nth 2 a) (nth 2 b)))
X		       (h (math-add (nth 1 a) (nth 1 b))))
X		  (if (math-negp s)
X		      (setq s (math-add s 60)
X			    m (math-add m -1)))
X		  (if (math-negp m)
X		      (setq m (math-add m 60)
X			    h (math-add h -1)))
X		  (if (math-negp h)
X		      (math-add b a)
X		    (list 'hms h m s)))
X	      (let* ((s (math-add (nth 3 a) (nth 3 b)))
X		     (m (math-add (nth 2 a) (nth 2 b)))
X		     (h (math-add (nth 1 a) (nth 1 b))))
X		(list 'hms h m s))))))
X	(t (calc-record-why "Incompatible arguments" a b)))
X)
X
X(defun math-add-symb-fancy (a b)
X  (or (and (eq (car-safe b) '+)
X	   (math-add (math-add a (nth 1 b))
X		     (nth 2 b)))
X      (and (eq (car-safe b) '-)
X	   (math-sub (math-add a (nth 1 b))
X		     (nth 2 b)))
X      (and (eq (car-safe b) 'neg)
X	   (eq (car-safe (nth 1 b)) '+)
X	   (math-sub (math-sub a (nth 1 (nth 1 b)))
X		     (nth 2 (nth 1 b))))
X      (cond
X       ((eq (car-safe a) '+)
X	(let ((temp (math-combine-sum (nth 2 a) b nil nil t)))
X	  (and temp
X	       (math-add (nth 1 a) temp))))
X       ((eq (car-safe a) '-)
X	(let ((temp (math-combine-sum (nth 2 a) b t nil t)))
X	  (and temp
X	       (math-add (nth 1 a) temp))))
X       ((and (Math-objectp a) (Math-objectp b))
X	nil)
X       (t
X	(math-combine-sum a b nil nil nil)))
X      (and (Math-looks-negp b)
X	   (list '- a (math-neg b)))
X      (and (Math-looks-negp a)
X	   (list '- b (math-neg a)))
X      (list '+ a b))
X)
X
X
X(defun math-mul-objects-fancy (a b)
X  (cond ((and (Math-numberp a) (Math-numberp b))
X	 (math-normalize
X	  (if (math-want-polar a b)
X	      (let ((a (math-polar a))
X		    (b (math-polar b)))
X		(list 'polar
X		      (math-mul (nth 1 a) (nth 1 b))
X		      (math-fix-circular (math-add (nth 2 a) (nth 2 b)))))
X	    (setq a (math-complex a)
X		  b (math-complex b))
X	    (list 'cplx
X		  (math-sub (math-mul (nth 1 a) (nth 1 b))
X			    (math-mul (nth 2 a) (nth 2 b)))
X		  (math-add (math-mul (nth 1 a) (nth 2 b))
X			    (math-mul (nth 2 a) (nth 1 b)))))))
X	((Math-vectorp a)
X	 (if (Math-vectorp b)
X	     (if (math-matrixp a)
X		 (if (math-matrixp b)
X		     (cons 'vec (math-mul-mats (cdr a)
X					       (mapcar 'cdr
X						       (cdr b))))
X		   (math-mat-col
X		    (cons 'vec
X			  (if (= (length (nth 1 a)) 2)
X			      (math-mul-mats (cdr a)
X					     (mapcar 'cdr
X						     (cdr (math-row-matrix
X							   b))))
X			    (math-mul-mats (cdr a)
X					   (mapcar 'cdr
X						   (cdr (math-col-matrix
X							 b))))))
X		    1))
X	       (if (math-matrixp b)
X		   (cons 'vec (math-mul-mat-row a (mapcar 'cdr (cdr b))))
X		 (car (math-mul-mat-row a
X					(mapcar 'cdr
X						(cdr (math-col-matrix
X						      b)))))))
X	   (math-map-vec-2 'math-mul a b)))
X	((Math-vectorp b)
X	 (math-map-vec-2 'math-mul a b))
X	((eq (car-safe a) 'sdev)
X	 (if (eq (car-safe b) 'sdev)
X	     (math-make-sdev (math-mul (nth 1 a) (nth 1 b))
X			     (math-hypot (math-mul (nth 2 a) (nth 1 b))
X					 (math-mul (nth 2 b) (nth 1 a))))
X	   (and (or (Math-anglep b)
X		    (not (Math-objvecp b)))
X		(math-make-sdev (math-mul (nth 1 a) b)
X				(math-abs (math-mul (nth 2 a) b))))))
X	((and (eq (car-safe b) 'sdev)
X	      (or (Math-anglep a)
X		  (not (Math-objvecp a))))
X	 (math-make-sdev (math-mul a (nth 1 b))
X			 (math-abs (math-mul a (nth 2 b)))))
X	((and (eq (car-safe a) 'intv) (Math-anglep b))
X	 (if (Math-negp b)
X	     (math-neg (math-mul a (math-neg b)))
X	   (math-make-intv (nth 1 a)
X			   (math-mul (nth 2 a) b)
X			   (math-mul (nth 3 a) b))))
X	((and (eq (car-safe b) 'intv) (Math-anglep a))
X	 (math-mul b a))
X	((and (eq (car-safe a) 'intv) (math-constp a)
X	      (eq (car-safe b) 'intv) (math-constp b))
X	 (let ((lo (math-mul a (nth 2 b)))
X	       (hi (math-mul a (nth 3 b))))
X	   (and (Math-anglep lo)
X		(setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0) lo lo)))
X	   (and (Math-anglep hi)
X		(setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0) hi hi)))
X	   (math-combine-intervals (nth 2 lo) (and (memq (nth 1 b) '(2 3))
X						   (memq (nth 1 lo) '(2 3)))
X				   (nth 3 lo) (and (memq (nth 1 b) '(2 3))
X						   (memq (nth 1 lo) '(1 3)))
X				   (nth 2 hi) (and (memq (nth 1 b) '(1 3))
X						   (memq (nth 1 hi) '(2 3)))
X				   (nth 3 hi) (and (memq (nth 1 b) '(1 3))
X						   (memq (nth 1 hi) '(1 3))))))
X	((and (eq (car-safe a) 'mod)
X	      (eq (car-safe b) 'mod)
X	      (equal (nth 2 a) (nth 2 b)))
X	 (math-make-mod (math-mul (nth 1 a) (nth 1 b)) (nth 2 a)))
X	((and (eq (car-safe a) 'mod)
X	      (Math-anglep b))
X	 (math-make-mod (math-mul (nth 1 a) b) (nth 2 a)))
X	((and (eq (car-safe b) 'mod)
X	      (Math-anglep a))
X	 (math-make-mod (math-mul a (nth 1 b)) (nth 2 b)))
X	((and (eq (car-safe a) 'hms) (Math-realp b))
X	 (math-with-extra-prec 2
X	   (math-to-hms (math-mul (math-from-hms a 'deg) b) 'deg)))
X	((and (eq (car-safe b) 'hms) (Math-realp a))
X	 (math-mul b a))
X	(t (calc-record-why "Incompatible arguments" a b)))
X)
X
X;;; Fast function to multiply floating-point numbers.
X(defun math-mul-float (a b)   ; [F F F]
X  (math-make-float (math-mul (nth 1 a) (nth 1 b))
X		   (+ (nth 2 a) (nth 2 b)))
X)
X
X(defun math-sqr-float (a)   ; [F F]
X  (math-make-float (math-mul (nth 1 a) (nth 1 a))
X		   (+ (nth 2 a) (nth 2 a)))
X)
X
X(defun math-combine-intervals (a am b bm c cm d dm)
X  (let (res)
X    (if (= (setq res (math-compare a c)) 1)
X	(setq a c am cm)
X      (if (= res 0)
X	  (setq am (or am cm))))
X    (if (= (setq res (math-compare b d)) -1)
X	(setq b d bm dm)
X      (if (= res 0)
X	  (setq bm (or bm dm))))
X    (math-make-intv (+ (if am 2 0) (if bm 1 0)) a b))
X)
X
X(defun math-mul-symb-fancy (a b)
X  (or (and (Math-equal-int a 1)
X	   b)
X      (and (Math-equal-int a -1)
X	   (math-neg b))
X      (and (Math-numberp b)
X	   (math-mul b a))
X      (and (eq (car-safe a) 'neg)
X	   (math-neg (math-mul (nth 1 a) b)))
X      (and (eq (car-safe b) 'neg)
X	   (math-neg (math-mul a (nth 1 b))))
X      (and (eq (car-safe a) '*)
X	   (math-mul (nth 1 a)
X		     (math-mul (nth 2 a) b)))
X      (and (eq (car-safe a) '^)
X	   (Math-looks-negp (nth 2 a))
X	   (not (and (eq (car-safe b) '^) (Math-looks-negp (nth 2 b))))
X	   (math-div b (math-normalize
X			(list '^ (nth 1 a) (math-neg (nth 2 a))))))
X      (and (eq (car-safe b) '^)
X	   (Math-looks-negp (nth 2 b))
X	   (not (and (eq (car-safe a) '^) (Math-looks-negp (nth 2 a))))
X	   (math-div a (math-normalize
X			(list '^ (nth 1 b) (math-neg (nth 2 b))))))
X      (and (eq (car-safe a) '/)
X	   (math-div (math-mul (nth 1 a) b) (nth 2 a)))
X      (and (eq (car-safe b) '/)
X	   (math-div (math-mul a (nth 1 b)) (nth 2 b)))
X      (and (eq (car-safe b) '+)
X	   (Math-numberp a)
X	   (or (Math-numberp (nth 1 b))
X	       (Math-numberp (nth 2 b)))
X	   (math-add (math-mul a (nth 1 b))
X		     (math-mul a (nth 2 b))))
X      (and (eq (car-safe b) '-)
X	   (Math-numberp a)
X	   (or (Math-numberp (nth 1 b))
X	       (Math-numberp (nth 2 b)))
X	   (math-sub (math-mul a (nth 1 b))
X		     (math-mul a (nth 2 b))))
X      (and (eq (car-safe b) '*)
X	   (Math-numberp (nth 1 b))
X	   (not (Math-numberp a))
X	   (math-mul (nth 1 b) (math-mul a (nth 2 b))))
X      (and (or t  ; this seems more reasonable...
X	       (eq (car-safe a) '-)
X	       (math-looks-negp a))
X	   (math-looks-negp b)
X	   (math-mul (math-neg a) (math-neg b)))
X      (and (eq (car-safe b) '-)
X	   (math-looks-negp a)
X	   (math-mul (math-neg a) (math-neg b)))
X      (cond
X       ((eq (car-safe b) '*)
X	(let ((temp (math-combine-prod a (nth 1 b) nil nil t)))
X	  (and temp
X	       (math-mul temp (nth 2 b)))))
X       (t
X	(math-combine-prod a b nil nil nil)))
X      (list '* a b))
X)
X
X(defun math-want-polar (a b)
X  (cond ((eq (car-safe a) 'polar)
X	 (if (eq (car-safe b) 'cplx)
X	     (eq car-complex-mode 'polar)
X	   t))
X	((eq (car-safe a) 'cplx)
X	 (if (eq (car-safe b) 'polar)
X	     (eq car-complex-mode 'polar)
X	   nil))
X	((eq (car-safe b) 'polar)
X	 t)
X	((eq (car-safe b) 'cplx)
X	 nil)
X	(t (eq (car-complex-mode 'polar))))
X)
X
X;;; Force A to be in the (-pi,pi] or (-180,180] range.
X(defun math-fix-circular (a &optional dir)   ; [R R]
X  (cond ((eq calc-angle-mode 'deg)
X	 (cond ((and (Math-lessp '(float 18 1) a) (not (eq dir 1)))
X		(math-fix-circular (math-add a '(float -36 1)) -1))
X	       ((or (Math-lessp '(float -18 1) a) (eq dir -1))
X		a)
X	       (t
X		(math-fix-circular (math-add a '(float 36 1)) 1))))
X	((eq calc-angle-mode 'hms)
X	 (cond ((and (Math-lessp 180 (nth 1 a)) (not (eq dir 1)))
X		(math-fix-circular (math-add a '(float -36 1)) -1))
X	       ((or (Math-lessp -180 (nth 1 a)) (eq dir -1))
X		a)
X	       (t
X		(math-fix-circular (math-add a '(float 36 1)) 1))))
X	(t
X	 (cond ((and (Math-lessp (math-pi) a) (not (eq dir 1)))
X		(math-fix-circular (math-sub a (math-two-pi)) -1))
X	       ((or (Math-lessp (math-neg (math-pi)) a) (eq dir -1))
X		a)
X	       (t
X		(math-fix-circular (math-add a (math-two-pi)) 1)))))
X)
X
X
X(defun math-div-objects-fancy (a b)
X  (cond ((and (Math-numberp a) (Math-numberp b))
X	 (math-normalize
X	  (cond ((math-want-polar a b)
X		 (let ((a (math-polar a))
X		       (b (math-polar b)))
X		   (list 'polar
X			 (math-div (nth 1 a) (nth 1 b))
X			 (math-fix-circular (math-sub (nth 2 a)
X						      (nth 2 b))))))
X		((Math-realp b)
X		 (setq a (math-complex a))
X		 (list 'cplx (math-div (nth 1 a) b)
X		       (math-div (nth 2 a) b)))
X		(t
X		 (setq a (math-complex a)
X		       b (math-complex b))
X		 (math-div
X		  (list 'cplx
X			(math-add (math-mul (nth 1 a) (nth 1 b))
X				  (math-mul (nth 2 a) (nth 2 b)))
X			(math-sub (math-mul (nth 2 a) (nth 1 b))
X				  (math-mul (nth 1 a) (nth 2 b))))
X		  (math-add (math-sqr (nth 1 b))
X			    (math-sqr (nth 2 b))))))))
X	((math-matrixp b)
X	 (if (math-square-matrixp b)
X	     (let ((n1 (length b)))
X	       (if (Math-vectorp a)
X		   (if (math-matrixp a)
X		       (if (= (length a) n1)
X			   (math-lud-solve (math-matrix-lud b) a)
X			 (if (= (length (nth 1 a)) n1)
X			     (math-transpose
X			      (math-lud-solve (math-matrix-lud
X					       (math-transpose b))
X					      (math-transpose a)))
X			   (math-dimension-error)))
X		     (if (= (length a) n1)
X			 (math-mat-col (math-lud-solve (math-matrix-lud b)
X						       (math-col-matrix a))
X				       1)
X		       (math-dimension-error)))
X		 (if (Math-equal-int a 1)
X		     (math-inv b)
X		   (math-mul a (math-inv b)))))
X	   (math-reject-arg b 'square-matrixp)))
X	((Math-vectorp a)
X	 (math-map-vec-2 'math-div a b))
X	((eq (car-safe a) 'sdev)
X	 (if (eq (car-safe b) 'sdev)
X	     (let ((x (math-div (nth 1 a) (nth 1 b))))
X	       (math-make-sdev
X		x
X		(math-div
X		 (math-hypot (nth 2 a) (math-mul (nth 2 b) x))
X		 (math-abs (nth 1 b)))))
X	   (and (or (Math-anglep b)
X		    (not (Math-objvecp b)))
X		(math-make-sdev (math-div (nth 1 a) b)
X				(math-abs (math-div (nth 2 a) b))))))
X	((and (eq (car-safe b) 'sdev)
X	      (or (Math-anglep a)
X		  (not (Math-objvecp a))))
X	 (let ((x (math-div a (nth 1 b))))
X	   (math-make-sdev x
X			   (math-abs (math-div (math-mul (nth 2 b) x)
X					       (nth 1 b))))))
X	((and (eq (car-safe a) 'intv) (Math-anglep b))
X	 (if (Math-negp b)
X	     (math-neg (math-div a (math-neg b)))
X	   (math-make-intv (nth 1 a)
X			   (math-div (nth 2 a) b)
X			   (math-div (nth 3 a) b))))
X	((and (eq (car-safe b) 'intv) (Math-anglep a))
X	 (if (Math-posp (nth 2 b))
X	     (if (Math-negp a)
X		 (math-neg (math-div (math-neg a) b))
X	       (math-make-intv (aref [0 2 1 3] (nth 1 b))
X			       (math-div a (nth 3 b))
X			       (math-div a (nth 2 b))))
X	   (if (Math-negp (nth 3 b))
X	       (math-neg (math-div a (math-neg b)))
X	     (calc-record-why "Division by zero" b)
X	     nil)))
X	((and (eq (car-safe a) 'intv) (math-constp a)
X	      (eq (car-safe b) 'intv) (math-constp b))
X	 (if (or (Math-posp (nth 2 b)) (Math-negp (nth 3 b)))
X	     (let ((lo (math-div a (nth 2 b)))
X		   (hi (math-div a (nth 3 b))))
X	       (and (Math-anglep lo)
X		    (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0)
X				   lo lo)))
X	       (and (Math-anglep hi)
X		    (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0)
X				   hi hi)))
X	       (math-combine-intervals
X		(nth 2 lo) (and (memq (nth 1 b) '(2 3))
X				(memq (nth 1 lo) '(2 3)))
X		(nth 3 lo) (and (memq (nth 1 b) '(2 3))
X				(memq (nth 1 lo) '(1 3)))
X		(nth 2 hi) (and (memq (nth 1 b) '(1 3))
X				(memq (nth 1 hi) '(2 3)))
X		(nth 3 hi) (and (memq (nth 1 b) '(1 3))
X				(memq (nth 1 hi) '(1 3)))))
X	   (calc-record-why "Division by zero" b)
X	   nil))
X	((and (eq (car-safe a) 'mod)
X	      (eq (car-safe b) 'mod)
X	      (equal (nth 2 a) (nth 2 b)))
X	 (math-make-mod (math-div-mod (nth 1 a) (nth 1 b) (nth 2 a))
X			(nth 2 a)))
X	((and (eq (car-safe a) 'mod)
X	      (Math-anglep b))
X	 (math-make-mod (math-div-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
X	((and (eq (car-safe b) 'mod)
X	      (Math-anglep a))
X	 (math-make-mod (math-div-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
X	((eq (car-safe a) 'hms)
X	 (if (eq (car-safe b) 'hms)
X	     (math-with-extra-prec 1
X	       (math-div (math-from-hms a 'deg)
X			 (math-from-hms b 'deg)))
X	   (math-with-extra-prec 2
X	     (math-to-hms (math-div (math-from-hms a 'deg) b) 'deg))))
X	(t (calc-record-why "Incompatible arguments" a b)))
X)
X
X(defun math-div-symb-fancy (a b)
X  (or (and (Math-equal-int b 1) a)
X      (and (Math-equal-int b -1) (math-neg a))
X      (and (eq (car-safe b) '^)
X	   (or (Math-looks-negp (nth 2 b)) (Math-equal-int a 1))
X	   (math-mul a (math-normalize
X			(list '^ (nth 1 b) (math-neg (nth 2 b))))))
X      (and (eq (car-safe a) 'neg)
X	   (math-neg (math-div (nth 1 a) b)))
X      (and (eq (car-safe b) 'neg)
X	   (math-neg (math-div a (nth 1 b))))
X      (and (eq (car-safe a) '/)
X	   (math-div (nth 1 a) (math-mul (nth 2 a) b)))
X      (and (eq (car-safe b) '/)
X	   (math-div (math-mul a (nth 2 b)) (nth 1 b)))
X      (and (eq (car-safe b) 'frac)
X	   (math-mul a (math-make-frac (nth 2 b) (nth 1 b))))
X      (and (eq (car-safe a) '+)
X	   (or (Math-numberp (nth 1 a))
X	       (Math-numberp (nth 2 a)))
X	   (Math-numberp b)
X	   (math-add (math-div (nth 1 a) b)
X		     (math-div (nth 2 a) b)))
X      (and (eq (car-safe a) '-)
X	   (or (Math-numberp (nth 1 a))
X	       (Math-numberp (nth 2 a)))
X	   (Math-numberp b)
X	   (math-sub (math-div (nth 1 a) b)
X		     (math-div (nth 2 a) b)))
X      (and (or (eq (car-safe a) '-)
X	       (math-looks-negp a))
X	   (math-looks-negp b)
X	   (math-div (math-neg a) (math-neg b)))
X      (and (eq (car-safe b) '-)
X	   (math-looks-negp a)
X	   (math-div (math-neg a) (math-neg b)))
X      (if (eq (car-safe a) '*)
X	  (if (eq (car-safe b) '*)
X	      (let ((c (math-combine-prod (nth 1 a) (nth 1 b) nil t t)))
X		(and c
X		     (math-div (math-mul c (nth 2 a)) (nth 2 b))))
X	    (let ((c (math-combine-prod (nth 1 a) b nil t t)))
X	      (and c
X		   (math-mul c (nth 2 a)))))
X	(if (eq (car-safe b) '*)
X	    (let ((c (math-combine-prod a (nth 1 b) nil t t)))
X	      (and c
X		   (math-div c (nth 2 b))))
X	  (math-combine-prod a b nil t nil)))
X      (list '/ a b))
X)
X
X(defun math-div-mod (a b m)   ; [R R R R]  (Returns nil if no solution)
X  (and (Math-integerp a) (Math-integerp b) (Math-integerp m)
X       (let ((u1 1) (u3 b) (v1 0) (v3 m))
X	 (while (not (eq v3 0))   ; See Knuth sec 4.5.2, exercise 15
X	   (let* ((q (math-idivmod u3 v3))
X		  (t1 (math-sub u1 (math-mul v1 (car q)))))
X	     (setq u1 v1  u3 v3  v1 t1  v3 (cdr q))))
X	 (let ((q (math-idivmod a u3)))
X	   (and (eq (cdr q) 0)
X		(math-mod (math-mul (car q) u1) m)))))
X)
X
X(defun math-mod-intv (a b)
X  (let* ((q1 (math-floor (math-div (nth 2 a) b)))
X	 (q2 (math-floor (math-div (nth 3 a) b)))
X	 (m1 (math-sub (nth 2 a) (math-mul q1 b)))
X	 (m2 (math-sub (nth 3 a) (math-mul q2 b))))
X    (cond ((equal q1 q2)
X	   (math-sort-intv (nth 1 a) m1 m2))
X	  ((and (math-equal-int (math-sub q2 q1) 1)
X		(math-zerop m2)
X		(memq (nth 1 a) '(0 2)))
X	   (math-make-intv (nth 1 a) m1 b))
X	  (t
X	   (math-make-intv 2 0 b))))
X)
X
X(defun math-pow-fancy (a b)
X  (cond ((and (Math-numberp a) (Math-numberp b))
X	 (cond ((and (eq (car-safe b) 'frac)
X		     (equal (nth 2 b) 2))
X		(math-ipow (math-sqrt-raw (math-float a)) (nth 1 b)))
X	       ((equal b '(float 5 -1))
X		(math-sqrt-raw (math-float a)))
X	       (t
X		(math-with-extra-prec 2
X		  (math-exp-raw
X		   (math-float (math-mul b (math-ln-raw (math-float a)))))))))
X	((or (not (Math-objvecp a))
X	     (not (Math-objectp b)))
X	 (cond ((and (eq (car-safe a) 'calcFunc-sqrt)
X		     (math-evenp b))
X		(math-pow (nth 1 a) (math-div2 b)))
X	       ((eq (car-safe a) '*)
X		(math-mul (math-pow (nth 1 a) b)
X			  (math-pow (nth 2 a) b)))
X	       ((eq (car-safe a) '/)
X		(math-div (math-pow (nth 1 a) b)
X			  (math-pow (nth 2 a) b)))
X	       ((and (eq (car-safe a) '^)
X		     (Math-integerp b))
X		(math-pow (nth 1 a) (math-mul (nth 2 a) b)))
X	       ((and (math-looks-negp a)
X		     (Math-integerp b))
X		(if (math-evenp b)
X		    (math-pow (math-neg a) b)
X		  (math-neg (math-pow (math-neg a) b))))
X	       (t (if (Math-objectp a)
X		      (calc-record-why 'objectp b)
X		    (calc-record-why 'objectp a))
X		  (list '^ a b))))
X	((and (eq (car-safe a) 'sdev) (eq (car-safe b) 'sdev))
X	 (if (and (math-constp a) (math-constp b))
X	     (math-with-extra-prec 2
X	       (let* ((ln (math-ln-raw (math-float (nth 1 a))))
X		      (pow (math-exp-raw
X			    (math-float (math-mul (nth 1 b) ln)))))
X		 (list 'sdev
X		       pow
X		       (math-mul
X			pow
X			(math-hypot (math-mul (nth 2 a)
X					      (math-div (nth 1 b)
X							(nth 1 a)))
X				    (math-mul (nth 2 b) ln))))))
X	   (let ((pow (math-pow (nth 1 a) (nth 1 b))))
X	     (list 'sdev
X		   pow
X		   (math-mul pow
X			     (math-hypot (math-mul (nth 2 a)
X						   (math-div (nth 1 b)
X							     (nth 1 a)))
X					 (math-mul (nth 2 b)
X						   (math-ln
X						    (nth 1 a)))))))))
X	((and (eq (car-safe a) 'sdev) (Math-realp b))
X	 (if (math-constp a)
X	     (math-with-extra-prec 2
X	       (let ((pow (math-pow (nth 1 a) (math-sub b 1))))
X		 (list 'sdev
X		       (math-mul pow (nth 1 a))
X		       (math-mul pow (math-mul (nth 2 a) b)))))
X	   (list 'sdev
X		 (math-mul (math-pow (nth 1 a) b))
X		 (math-mul (math-pow (nth 1 a) (math-add b -1))
X			   (math-mul (nth 2 a) b)))))
X	((and (eq (car-safe b) 'sdev) (Math-realp a))
X	 (math-with-extra-prec 2
X	   (let* ((ln (math-ln-raw (math-float a)))
X		  (pow (math-exp (math-mul (nth 1 b) ln))))
X	     (list 'sdev
X		   pow
X		   (math-mul pow (math-mul (nth 2 b) ln))))))
X	((and (eq (car-safe a) 'intv) (math-constp a)
X	      (Math-realp b)
X	      (or (Math-posp (nth 2 a))
X		  (Math-natnump b)
X		  (and (math-zerop (nth 2 a))
X		       (Math-posp b))))
X	 (if (math-evenp b)
X	     (setq a (math-abs a)))
X	 (math-sort-intv (nth 1 a)
X			 (math-pow (nth 2 a) b)
X			 (math-pow (nth 3 a) b)))
X	((and (eq (car-safe b) 'intv) (math-constp b)
X	      (Math-posp a))
X	 (math-sort-intv (nth 1 b)
X			 (math-pow a (nth 2 b))
X			 (math-pow a (nth 3 b))))
X	((and (eq (car-safe a) 'intv) (math-constp a)
X	      (eq (car-safe b) 'intv) (math-constp b)
X	      (or (and (not (Math-negp (nth 2 a)))
X		       (not (Math-negp (nth 2 b))))
X		  (and (Math-posp (nth 2 a))
X		       (not (Math-posp (nth 3 b))))))
X	 (let ((lo (math-pow a (nth 2 a)))
X	       (hi (math-pow a (nth 3 a))))
X	   (math-combine-intervals (nth 2 lo) (and (memq (nth 1 a) '(2 3))
X						   (memq (nth 1 lo) '(2 3)))
X				   (nth 3 lo) (and (memq (nth 1 a) '(2 3))
X						   (memq (nth 1 lo) '(1 3)))
X				   (nth 2 hi) (and (memq (nth 1 a) '(1 3))
X						   (memq (nth 1 hi) '(2 3)))
X				   (nth 3 hi) (and (memq (nth 1 a) '(1 3))
X						   (memq (nth 1 hi) '(1 3))))))
X	((and (eq (car-safe a) 'mod) (eq (car-safe b) 'mod)
X	      (equal (nth 2 a) (nth 2 b)))
X	 (math-make-mod (math-pow-mod (nth 1 a) (nth 1 b) (nth 2 a))
X			(nth 2 a)))
X	((and (eq (car-safe a) 'mod) (Math-anglep b))
X	 (math-make-mod (math-pow-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
X	((and (eq (car-safe b) 'mod) (Math-anglep a))
X	 (math-make-mod (math-pow-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
X	((not (Math-numberp a))
X	 (math-reject-arg a 'numberp))
X	(t
X	 (math-reject-arg b 'numberp)))
X)
X
X;;; This assumes A < M and M > 0.
X(defun math-pow-mod (a b m)   ; [R R R R]
X  (if (and (Math-integerp a) (Math-integerp b) (Math-integerp m))
X      (if (Math-negp b)
X	  (math-div-mod 1 (math-pow-mod a (Math-integer-neg b) m) m)
X	(if (eq m 1)
X	    0
X	  (math-pow-mod-step a b m)))
X    (math-mod (math-pow a b) m))
X)
X
X(defun math-pow-mod-step (a n m)   ; [I I I I]
X  (math-working "pow" a)
X  (let ((val (cond
X	      ((eq n 0) 1)
X	      ((eq n 1) a)
X	      (t
X	       (let ((rest (math-pow-mod-step
X			    (math-imod (math-mul a a) m)
X			    (math-div2 n)
X			    m)))
X		 (if (math-evenp n)
X		     rest
X		   (math-mod (math-mul a rest) m)))))))
X    (math-working "pow" val)
X    val)
X)
X
X(defvar math-power-of-2-cache (list 1 2 4 8 16 32 64 128 256 512 1024))
X(defvar math-big-power-of-2-cache nil)
X(defun math-power-of-2 (n)    ;  [I I] [Public]
X  (if (and (natnump n) (<= n 100))
X      (or (nth n math-power-of-2-cache)
X	  (let* ((i (length math-power-of-2-cache))
X		 (val (nth (1- i) math-power-of-2-cache)))
X	    (while (<= i n)
X	      (setq val (math-mul val 2)
X		    math-power-of-2-cache (nconc math-power-of-2-cache
X						 (list val))
X		    i (1+ i)))
X	    val))
X    (let ((found (assq n math-big-power-of-2-cache)))
X      (if found
X	  (cdr found)
X	(let ((po2 (math-ipow 2 n)))
X	  (setq math-big-power-of-2-cache
X		(cons (cons n po2) math-big-power-of-2-cache))
X	  po2))))
X)
X
X(defun math-integer-log2 (n)    ; [I I] [Public]
X  (let ((i 0)
X	(p math-power-of-2-cache)
X	val)
X    (while (and p (Math-natnum-lessp (setq val (car p)) n))
X      (setq p (cdr p)
X	    i (1+ i)))
X    (if p
X	(and (equal val n)
X	     i)
X      (while (Math-natnum-lessp
X	      (prog1
X		  (setq val (math-mul val 2))
X		(setq math-power-of-2-cache (nconc math-power-of-2-cache
X						   (list val))))
X	      n)
X	(setq i (1+ i)))
X      (and (equal val n)
X	   i)))
X)
X
X
X
X;;; Compute the integer square-root floor(sqrt(A)).  A > 0.  [I I] [Public]
X;;; This method takes advantage of the fact that Newton's method starting
X;;; with an overestimate always works, even using truncating integer division!
X(defun math-isqrt (a)
X  (cond ((Math-zerop a) a)
X	((Math-negp a)
X	 (math-imaginary (math-isqrt (math-neg a))))
X	((integerp a)
X	 (math-isqrt-small a))
X	((eq (car a) 'bigpos)
X	 (math-normalize (cons 'bigpos (cdr (math-isqrt-bignum (cdr a))))))
X	(t
X	 (math-floor (math-sqrt a))))
X)
X
X;;; This returns (flag . result) where the flag is T if A is a perfect square.
X(defun math-isqrt-bignum (a)   ; [P.l L]
X  (let ((len (length a)))
X    (if (= (% len 2) 0)
X	(let* ((top (nthcdr (- len 2) a)))
X	  (math-isqrt-bignum-iter
X	   a
X	   (math-scale-bignum-3
X	    (math-bignum-big
X	     (1+ (math-isqrt-small
X		  (+ (* (nth 1 top) 1000) (car top)))))
X	    (1- (/ len 2)))))
X      (let* ((top (nth (1- len) a)))
X	(math-isqrt-bignum-iter
X	 a
X	 (math-scale-bignum-3
X	  (list (1+ (math-isqrt-small top)))
X	  (/ len 2))))))
X)
X
X(defun math-isqrt-bignum-iter (a guess)   ; [l L l]
X  (math-working "isqrt" (cons 'bigpos guess))
X  (let* ((q (math-div-bignum a guess))
X	 (s (math-add-bignum (car q) guess))
X	 (g2 (math-div2-bignum s))
X	 (comp (math-compare-bignum g2 guess)))
X    (if (< comp 0)
X	(math-isqrt-bignum-iter a g2)
X      (cons (and (= comp 0)
X		 (math-zerop-bignum (cdr q))
X		 (= (% (car s) 2) 0))
X	    guess)))
X)
X
X(defun math-scale-bignum-3 (a n)   ; [L L S]
X  (while (> n 0)
X    (setq a (cons 0 a)
X	  n (1- n)))
X  a
X)
X
X(defun math-isqrt-small (a)   ; A > 0.  [S S]
X  (let ((g (cond ((>= a 10000) 1000)
X		 ((>= a 100) 100)
X		 (t 10)))
X	g2)
X    (while (< (setq g2 (/ (+ g (/ a g)) 2)) g)
X      (setq g g2))
X    g)
X)
X
X
X(defun math-inexact-result ()
X  (and calc-symbolic-mode
X       (signal 'inexact-result nil))
X)
X
X
X;;; Compute the square root of a number.
X;;; [T N] if possible, else [F N] if possible, else [C N].  [Public]
X(defun math-sqrt (a)
X  (or
X   (and (Math-zerop a) a)
X   (and (Math-negp a)
X	(math-imaginary (math-sqrt (math-neg a))))
X   (and (integerp a)
X	(let ((sqrt (math-isqrt-small a)))
X	  (if (= (* sqrt sqrt) a)
X	      sqrt
X	    (math-sqrt-float (math-float a) (math-float sqrt)))))
X   (and (eq (car-safe a) 'bigpos)
X	(let* ((res (math-isqrt-bignum (cdr a)))
X	       (sqrt (math-normalize (cons 'bigpos (cdr res)))))
X	  (if (car res)
X	      sqrt
X	    (math-sqrt-float (math-float a) (math-float sqrt)))))
X   (and (eq (car-safe a) 'frac)
X	(let* ((num-res (math-isqrt-bignum (cdr (Math-bignum-test (nth 1 a)))))
X	       (num-sqrt (math-normalize (cons 'bigpos (cdr num-res))))
X	       (den-res (math-isqrt-bignum (cdr (Math-bignum-test (nth 2 a)))))
X	       (den-sqrt (math-normalize (cons 'bigpos (cdr den-res)))))
X	  (if (and (car num-res) (car den-res))
X	      (list 'frac num-sqrt den-sqrt)
X	    (math-sqrt-float (math-float a)
X			     (math-div (math-float num-sqrt) den-sqrt)))))
X   (and (eq (car-safe a) 'float)
X	(if calc-symbolic-mode
X	    (if (= (% (nth 2 a) 2) 0)
X		(let ((res (math-isqrt-bignum
X			    (cdr (Math-bignum-test (nth 1 a))))))
X		  (if (car res)
X		      (math-make-float (math-normalize
X					(cons 'bigpos (cdr res)))
X				       (/ (nth 2 a) 2))
X		    (signal 'inexact-result nil)))
X	      (signal 'inexact-result nil))
X	  (math-sqrt-float a)))
X   (and (eq (car-safe a) 'cplx)
X	(math-with-extra-prec 2
X	  (let* ((d (math-abs a))
X		 (imag (math-sqrt (math-mul (math-sub d (nth 1 a))
X					    '(float 5 -1)))))
X	    (list 'cplx
X		  (math-sqrt (math-mul (math-add d (nth 1 a)) '(float 5 -1)))
X		  (if (math-negp (nth 2 a)) (math-neg imag) imag)))))
X   (and (eq (car-safe a) 'polar)
X	(list 'polar
X	      (math-sqrt (nth 1 a))
X	      (math-mul (nth 2 a) '(float 5 -1))))
X   (and (eq (car-safe a) 'sdev) (not (math-negp (nth 1 a)))
X	(let ((sqrt (math-sqrt (nth 1 a))))
X	  (math-make-sdev sqrt
X			  (math-div (nth 2 a) (math-mul sqrt 2)))))
X   (and (eq (car-safe a) 'intv)
X	(math-make-intv (nth 1 a) (math-sqrt (nth 2 a)) (math-sqrt (nth 3 a))))
X   (and (memq (car-safe a) '(* /))
X	(let ((s1 (math-sqrt (nth 1 a)))
X	      (s2 (math-sqrt (nth 2 a))))
X	  (and (not (and (eq (car-safe s1) 'calcFunc-sqrt)
X			 (eq (car-safe s2) 'calcFunc-sqrt)))
X	       (if (eq (car a) '*)
X		   (math-mul s1 s2)
X		 (math-div s1 s2)))))
X   (progn
X     (calc-record-why 'numberp a)
X     (list 'calcFunc-sqrt a)))
X)
X(fset 'calcFunc-sqrt (symbol-function 'math-sqrt))
X
X(defun math-sqrt-float (a &optional guess)   ; [F F F]
X  (if calc-symbolic-mode
X      (signal 'inexact-result nil)
X    (math-with-extra-prec 1 (math-sqrt-raw a guess)))
X)
X
X(defun math-sqrt-raw (a &optional guess)   ; [F F F]
X  (if (not (Math-posp a))
X      (math-sqrt a)
X    (if (null guess)
X	(let ((ldiff (- (math-numdigs (nth 1 a)) 6)))
X	  (or (= (% (+ (nth 2 a) ldiff) 2) 0) (setq ldiff (1+ ldiff)))
X	  (setq guess (math-make-float (math-isqrt-small
X					(math-scale-int (nth 1 a) (- ldiff)))
X				       (/ (+ (nth 2 a) ldiff) 2)))))
X    (math-sqrt-float-iter a guess))
X)
X
X(defun math-sqrt-float-iter (a guess)   ; [F F F]
X  (math-working "sqrt" guess)
X  (let ((g2 (math-mul-float (math-add-float guess (math-div-float a guess))
X			    '(float 5 -1))))
X     (if (math-nearly-equal-float g2 guess)
X	 g2
X       (math-sqrt-float-iter a g2)))
X)
X
X;;; True if A and B differ only in the last digit of precision.  [P F F]
X(defun math-nearly-equal-float (a b)
X  (let ((diff (nth 1 (math-sub-float a b))))
X    (or (eq diff 0)
X	(and (not (consp diff))
X	     (< diff 10)
X	     (> diff -10)
X	     (= diff (if (< (nth 2 a) (nth 2 b))
X			 (nth 2 a) (nth 2 b)))
X	     (or (= (math-numdigs (nth 1 a)) calc-internal-prec)
X		 (= (math-numdigs (nth 1 b)) calc-internal-prec)))))
X)
X
X(defun math-nearly-equal (a b)   ;  [P R R] [Public]
X  (math-nearly-equal-float (math-float a) (math-float b))
X)
X
X;;; True if A is nearly zero compared to B.  [P F F]
X(defun math-nearly-zerop-float (a b)
X  (or (eq (nth 1 a) 0)
X      (<= (+ (math-numdigs (nth 1 a)) (nth 2 a))
X	  (1+ (- (+ (math-numdigs (nth 1 b)) (nth 2 b)) calc-internal-prec))))
X)
X
X(defun math-nearly-zerop (a b)
X  (math-nearly-zerop-float (math-float a) (math-float b))
X)
X
X;;; This implementation could be improved, accuracy-wise.
X(defun math-hypot (a b)
X  (cond ((Math-zerop a) (math-abs b))
X	((Math-zerop b) (math-abs a))
X	((not (Math-scalarp a))
X	 (calc-record-why 'scalarp a)
X	 (list 'calcFunc-hypot a b))
X	((not (Math-scalarp b))
X	 (calc-record-why 'scalarp b)
X	 (list 'calcFunc-hypot a b))
X	((and (Math-realp a) (Math-realp b))
X	 (math-with-extra-prec 1
X	   (math-sqrt (math-add (math-sqr a) (math-sqr b)))))
X	((eq (car-safe a) 'hms)
X	 (if (eq (car-safe b) 'hms)   ; this helps sdev's of hms forms
X	     (math-to-hms (math-hypot (math-from-hms a 'deg)
X				      (math-from-hms b 'deg)))
X	   (math-to-hms (math-hypot (math-from-hms a 'deg) b))))
X	((eq (car-safe b) 'hms)
X	 (math-to-hms (math-hypot a (math-from-hms b 'deg))))
X	(t nil))
X)
X(fset 'calcFunc-hypot (symbol-function 'math-hypot))
X
X(defun calcFunc-sqr (x)
X  (math-pow x 2)
X)
X
X
X
X;;; Compute the minimum of two real numbers.  [R R R] [Public]
X(defun math-min (a b)
X  (if (and (consp a) (eq (car a) 'intv))
X      (if (and (consp b) (eq (car b) 'intv))
X	  (let ((lo (nth 2 a))
X		(lom (memq (nth 1 a) '(2 3)))
X		(hi (nth 3 a))
X		(him (memq (nth 1 a) '(1 3)))
X		res)
X	    (if (= (setq res (math-compare (nth 2 b) lo)) -1)
X		(setq lo (nth 2 b) lom (memq (nth 1 b) '(2 3)))
X	      (if (= res 0)
X		  (setq lom (or lom (memq (nth 1 b) '(2 3))))))
X	    (if (= (setq res (math-compare (nth 3 b) hi)) -1)
X		(setq hi (nth 3 b) him (memq (nth 1 b) '(1 3)))
X	      (if (= res 0)
X		  (setq him (or him (memq (nth 1 b) '(1 3))))))
X	    (math-make-intv (+ (if lom 2 0) (if him 1 0)) lo hi))
X	(math-min a (list 'intv 3 b b)))
X    (if (and (consp b) (eq (car b) 'intv))
X	(math-min (list 'intv 3 a a) b)
X      (if (Math-lessp a b)
X	  a
X	b)))
X)
X
X(defun calcFunc-min (a &rest b)
X  (if (not (or (Math-anglep a)
X	       (and (eq (car a) 'intv) (math-constp a))))
X      (math-reject-arg a 'anglep))
X  (math-min-list a b)
X)
X
X(defun math-min-list (a b)
X  (if b
X      (if (or (Math-anglep (car b))
X	      (and (eq (car (car b)) 'intv) (math-constp (car b))))
X	  (math-min-list (math-min a (car b)) (cdr b))
X	(math-reject-arg (car b) 'anglep))
X    a)
X)
X
X;;; Compute the maximum of two real numbers.  [R R R] [Public]
X(defun math-max (a b)
X  (if (or (and (consp a) (eq (car a) 'intv))
X	  (and (consp b) (eq (car b) 'intv)))
X      (math-neg (math-min (math-neg a) (math-neg b)))
X    (if (Math-lessp a b)
X	b
X      a))
X)
X
X(defun calcFunc-max (a &rest b)
X  (if (not (or (Math-anglep a)
X	       (and (eq (car a) 'intv) (math-constp a))))
X      (math-reject-arg a 'anglep))
X  (math-max-list a b)
X)
X
X(defun math-max-list (a b)
X  (if b
X      (if (or (Math-anglep (car b))
X	      (and (eq (car (car b)) 'intv) (math-constp (car b))))
X	  (math-max-list (math-max a (car b)) (cdr b))
X	(math-reject-arg (car b) 'anglep))
X    a)
X)
X
X
X;;; Compute the absolute value of A.  [O O; r r] [Public]
X(defun math-abs (a)
X  (cond ((Math-negp a)
X	 (math-neg a))
X	((Math-anglep a)
X	 a)
X	((eq (car a) 'cplx)
X	 (math-hypot (nth 1 a) (nth 2 a)))
X	((eq (car a) 'polar)
X	 (nth 1 a))
X	((eq (car a) 'vec)
X	 (if (cdr (cdr (cdr a)))
X	     (math-sqrt (math-abssqr a))
X	   (if (cdr (cdr a))
X	       (math-hypot (nth 1 a) (nth 2 a))
X	     (if (cdr a)
X		 (math-abs (nth 1 a))
X	       a))))
X	((eq (car a) 'sdev)
X	 (list 'sdev (math-abs (nth 1 a)) (nth 2 a)))
X	((and (eq (car a) 'intv) (math-constp a))
X	 (if (Math-posp a)
X	     a
X	   (let* ((nlo (math-neg (nth 2 a)))
X		  (res (math-compare nlo (nth 3 a))))
X	     (cond ((= res 1)
X		    (math-make-intv (if (memq (nth 1 a) '(0 1)) 2 3) 0 nlo))
X		   ((= res 0)
X		    (math-make-intv (if (eq (nth 1 a) 0) 2 3) 0 nlo))
X		   (t
X		    (math-make-intv (if (memq (nth 1 a) '(0 2)) 2 3)
X				    0 (nth 3 a)))))))
X	((eq (car a) 'calcFunc-abs)
X	 (car a))
X	((math-looks-negp a)
X	 (list 'calcFunc-abs (math-neg a)))
X	(t (calc-record-why 'numvecp a)
X	   (list 'calcFunc-abs a)))
X)
X(fset 'calcFunc-abs (symbol-function 'math-abs))
X
X
X(defun math-trunc-fancy (a)
X  (cond ((eq (car a) 'cplx) (math-trunc (nth 1 a)))
X	((eq (car a) 'polar) (math-trunc (math-complex a)))
X	((eq (car a) 'hms) (list 'hms (nth 1 a) 0 0))
X	((eq (car a) 'mod)
X	 (if (math-messy-integerp (nth 2 a))
X	     (math-trunc (math-make-mod (nth 1 a) (math-trunc (nth 2 a))))
X	   (math-make-mod (math-trunc (nth 1 a)) (nth 2 a))))
X	((eq (car a) 'intv)
X	 (math-make-intv 3
X			 (if (and (Math-negp (nth 2 a))
X				  (Math-num-integerp (nth 2 a))
X				  (memq (nth 1 a) '(0 1)))
X			     (math-add (math-trunc (nth 2 a)) 1)
X			   (math-trunc (nth 2 a)))
X			 (if (and (Math-posp (nth 3 a))
X				  (Math-num-integerp (nth 3 a))
X				  (memq (nth 1 a) '(0 2)))
X			     (math-add (math-trunc (nth 3 a)) -1)
X			   (math-trunc (nth 3 a)))))
X	((math-provably-integerp a) a)
X	(t (math-reject-arg a 'numberp)))
X)
X(defun calcFunc-ftrunc (a)
X  (math-float (math-trunc a))
X)
X
X(defun math-floor-fancy (a)
X  (cond ((math-provably-integerp a) a)
X	((eq (car a) 'hms)
X	 (if (or (math-posp a)
X		 (and (math-zerop (nth 2 a))
X		      (math-zerop (nth 3 a))))
X	     (math-trunc a)
X	   (math-add (math-trunc a) -1)))
X	((eq (car a) 'intv)
X	 (math-make-intv 3
X			 (math-floor (nth 2 a))
X			 (if (and (Math-num-integerp (nth 3 a))
X				  (memq (nth 1 a) '(0 2)))
X			     (math-add (math-floor (nth 3 a)) -1)
X			   (math-floor (nth 3 a)))))
X	(t (math-reject-arg a 'anglep)))
X)
X(defun calcFunc-ffloor (a)
X  (math-float (math-floor a))
X)
X
X;;; Coerce A to be an integer (by truncation toward plus infinity).  [I N]
X(defun math-ceiling (a)   ;  [Public]
X  (cond ((Math-integerp a) a)
X	((Math-messy-integerp a) (math-trunc a))
X	((Math-realp a)
X	 (if (Math-posp a)
X	     (math-add (math-trunc a) 1)
X	   (math-trunc a)))
X	((math-provably-integerp a) a)
X	((eq (car a) 'hms)
X	 (if (or (math-negp a)
X		 (and (math-zerop (nth 2 a))
X		      (math-zerop (nth 3 a))))
X	     (math-trunc a)
X	   (math-add (math-trunc a) 1)))
X	((eq (car a) 'intv)
X	 (math-make-intv 3
X			 (if (and (Math-num-integerp (nth 2 a))
X				  (memq (nth 1 a) '(0 1)))
X			     (math-add (math-floor (nth 2 a)) 1)
X			   (math-ceiling (nth 2 a)))
X			 (math-ceiling (nth 3 a))))
X	(t (math-reject-arg a 'anglep)))
X)
X(fset 'calcFunc-ceil (symbol-function 'math-ceiling))
X(defun calcFunc-fceil (a)
X  (math-float (math-ceiling a))
X)
X
X;;; Coerce A to be an integer (by rounding to nearest integer).  [I N] [Public]
X(defun math-round (a)
X  (cond ((Math-anglep a)
X	 (if (Math-num-integerp a)
X	     (math-trunc a)
X	   (if (Math-negp a)
X	       (math-neg (math-round (math-neg a)))
X	     (math-floor
X	      (let ((calc-angle-mode 'deg))   ; in case of HMS forms
X		(math-add a (if (Math-ratp a)
X				'(frac 1 2)
X			      '(float 5 -1))))))))
X	((math-provably-integerp a) a)
X	((eq (car a) 'intv)
X	 (math-floor (math-add a '(frac 1 2))))
X	(t (math-reject-arg a 'anglep)))
X)
X(fset 'calcFunc-round (symbol-function 'math-round))
X(defun calcFunc-fround (a)
X  (math-float (math-round a))
X)
X
X
X;;; Convert a real value to fractional form.  [T R I; T R F] [Public]
X(defun math-to-fraction (a &optional tol)
X  (or tol (setq tol 0))
X  (cond ((Math-ratp a)
X	 a)
X	((memq (car a) '(cplx polar vec hms sdev intv mod))
X	 (cons (car a) (mapcar (function
X				(lambda (x)
X				  (math-to-fraction x tol)))
X			       (cdr a))))
X	((Math-negp a)
X	 (math-neg (math-to-fraction (math-neg a) tol)))
X	((not (eq (car a) 'float))
X	 (math-reject-arg a 'numberp))
X	((integerp tol)
X	 (if (<= tol 0)
X	     (setq tol (+ tol calc-internal-prec)))
X	 (math-to-fraction a (list 'float 5
SHAR_EOF
echo "End of part 7"
echo "File calc-ext.el is continued in part 8"
echo "8" > s2_seq_.tmp
exit 0