(Mode Hooks, Defining Minor Modes):
[emacs.git] / lisp / calc / calc-arith.el
blobfeb3c9d25a84165c87bb7ffd56e000876880d21a
1 ;;; calc-arith.el --- arithmetic functions for Calc
3 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
4 ;; 2005 Free Software Foundation, Inc.
6 ;; Author: David Gillespie <daveg@synaptics.com>
7 ;; Maintainer: Jay Belanger <belanger@truman.edu>
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY. No author or distributor
13 ;; accepts responsibility to anyone for the consequences of using it
14 ;; or for whether it serves any particular purpose or works at all,
15 ;; unless he says so in writing. Refer to the GNU Emacs General Public
16 ;; License for full details.
18 ;; Everyone is granted permission to copy, modify and redistribute
19 ;; GNU Emacs, but only under the conditions described in the
20 ;; GNU Emacs General Public License. A copy of this license is
21 ;; supposed to have been given to you along with GNU Emacs so you
22 ;; can know your rights and responsibilities. It should be in a
23 ;; file named COPYING. Among other things, the copyright notice
24 ;; and this notice must be preserved on all copies.
26 ;;; Commentary:
28 ;;; Code:
30 ;; This file is autoloaded from calc-ext.el.
32 (require 'calc-ext)
33 (require 'calc-macs)
35 ;;; The following lists are not exhaustive.
36 (defvar math-scalar-functions '(calcFunc-det
37 calcFunc-cnorm calcFunc-rnorm
38 calcFunc-vlen calcFunc-vcount
39 calcFunc-vsum calcFunc-vprod
40 calcFunc-vmin calcFunc-vmax))
42 (defvar math-nonscalar-functions '(vec calcFunc-idn calcFunc-diag
43 calcFunc-cvec calcFunc-index
44 calcFunc-trn
45 | calcFunc-append
46 calcFunc-cons calcFunc-rcons
47 calcFunc-tail calcFunc-rhead))
49 (defvar math-scalar-if-args-functions '(+ - * / neg))
51 (defvar math-real-functions '(calcFunc-arg
52 calcFunc-re calcFunc-im
53 calcFunc-floor calcFunc-ceil
54 calcFunc-trunc calcFunc-round
55 calcFunc-rounde calcFunc-roundu
56 calcFunc-ffloor calcFunc-fceil
57 calcFunc-ftrunc calcFunc-fround
58 calcFunc-frounde calcFunc-froundu))
60 (defvar math-positive-functions '())
62 (defvar math-nonnegative-functions '(calcFunc-cnorm calcFunc-rnorm
63 calcFunc-vlen calcFunc-vcount))
65 (defvar math-real-scalar-functions '(% calcFunc-idiv calcFunc-abs
66 calcFunc-choose calcFunc-perm
67 calcFunc-eq calcFunc-neq
68 calcFunc-lt calcFunc-gt
69 calcFunc-leq calcFunc-geq
70 calcFunc-lnot
71 calcFunc-max calcFunc-min))
73 (defvar math-real-if-arg-functions '(calcFunc-sin calcFunc-cos
74 calcFunc-tan calcFunc-sec
75 calcFunc-csc calcFunc-cot
76 calcFunc-arctan
77 calcFunc-sinh calcFunc-cosh
78 calcFunc-tanh calcFunc-sech
79 calcFunc-csch calcFunc-coth
80 calcFunc-exp
81 calcFunc-gamma calcFunc-fact))
83 (defvar math-integer-functions '(calcFunc-idiv
84 calcFunc-isqrt calcFunc-ilog
85 calcFunc-vlen calcFunc-vcount))
87 (defvar math-num-integer-functions '())
89 (defvar math-rounding-functions '(calcFunc-floor
90 calcFunc-ceil
91 calcFunc-round calcFunc-trunc
92 calcFunc-rounde calcFunc-roundu))
94 (defvar math-float-rounding-functions '(calcFunc-ffloor
95 calcFunc-fceil
96 calcFunc-fround calcFunc-ftrunc
97 calcFunc-frounde calcFunc-froundu))
99 (defvar math-integer-if-args-functions '(+ - * % neg calcFunc-abs
100 calcFunc-min calcFunc-max
101 calcFunc-choose calcFunc-perm))
104 ;;; Arithmetic.
106 (defun calc-min (arg)
107 (interactive "P")
108 (calc-slow-wrapper
109 (calc-binary-op "min" 'calcFunc-min arg '(var inf var-inf))))
111 (defun calc-max (arg)
112 (interactive "P")
113 (calc-slow-wrapper
114 (calc-binary-op "max" 'calcFunc-max arg '(neg (var inf var-inf)))))
116 (defun calc-abs (arg)
117 (interactive "P")
118 (calc-slow-wrapper
119 (calc-unary-op "abs" 'calcFunc-abs arg)))
122 (defun calc-idiv (arg)
123 (interactive "P")
124 (calc-slow-wrapper
125 (calc-binary-op "\\" 'calcFunc-idiv arg 1)))
128 (defun calc-floor (arg)
129 (interactive "P")
130 (calc-slow-wrapper
131 (if (calc-is-inverse)
132 (if (calc-is-hyperbolic)
133 (calc-unary-op "ceil" 'calcFunc-fceil arg)
134 (calc-unary-op "ceil" 'calcFunc-ceil arg))
135 (if (calc-is-hyperbolic)
136 (calc-unary-op "flor" 'calcFunc-ffloor arg)
137 (calc-unary-op "flor" 'calcFunc-floor arg)))))
139 (defun calc-ceiling (arg)
140 (interactive "P")
141 (calc-invert-func)
142 (calc-floor arg))
144 (defun calc-round (arg)
145 (interactive "P")
146 (calc-slow-wrapper
147 (if (calc-is-inverse)
148 (if (calc-is-hyperbolic)
149 (calc-unary-op "trnc" 'calcFunc-ftrunc arg)
150 (calc-unary-op "trnc" 'calcFunc-trunc arg))
151 (if (calc-is-hyperbolic)
152 (calc-unary-op "rond" 'calcFunc-fround arg)
153 (calc-unary-op "rond" 'calcFunc-round arg)))))
155 (defun calc-trunc (arg)
156 (interactive "P")
157 (calc-invert-func)
158 (calc-round arg))
160 (defun calc-mant-part (arg)
161 (interactive "P")
162 (calc-slow-wrapper
163 (calc-unary-op "mant" 'calcFunc-mant arg)))
165 (defun calc-xpon-part (arg)
166 (interactive "P")
167 (calc-slow-wrapper
168 (calc-unary-op "xpon" 'calcFunc-xpon arg)))
170 (defun calc-scale-float (arg)
171 (interactive "P")
172 (calc-slow-wrapper
173 (calc-binary-op "scal" 'calcFunc-scf arg)))
175 (defun calc-abssqr (arg)
176 (interactive "P")
177 (calc-slow-wrapper
178 (calc-unary-op "absq" 'calcFunc-abssqr arg)))
180 (defun calc-sign (arg)
181 (interactive "P")
182 (calc-slow-wrapper
183 (calc-unary-op "sign" 'calcFunc-sign arg)))
185 (defun calc-increment (arg)
186 (interactive "p")
187 (calc-wrapper
188 (calc-enter-result 1 "incr" (list 'calcFunc-incr (calc-top-n 1) arg))))
190 (defun calc-decrement (arg)
191 (interactive "p")
192 (calc-wrapper
193 (calc-enter-result 1 "decr" (list 'calcFunc-decr (calc-top-n 1) arg))))
196 (defun math-abs-approx (a)
197 (cond ((Math-negp a)
198 (math-neg a))
199 ((Math-anglep a)
201 ((eq (car a) 'cplx)
202 (math-add (math-abs (nth 1 a)) (math-abs (nth 2 a))))
203 ((eq (car a) 'polar)
204 (nth 1 a))
205 ((eq (car a) 'sdev)
206 (math-abs-approx (nth 1 a)))
207 ((eq (car a) 'intv)
208 (math-max (math-abs (nth 2 a)) (math-abs (nth 3 a))))
209 ((eq (car a) 'date)
211 ((eq (car a) 'vec)
212 (math-reduce-vec 'math-add-abs-approx a))
213 ((eq (car a) 'calcFunc-abs)
214 (car a))
215 (t a)))
217 (defun math-add-abs-approx (a b)
218 (math-add (math-abs-approx a) (math-abs-approx b)))
221 ;;;; Declarations.
223 (defvar math-decls-cache-tag nil)
224 (defvar math-decls-cache nil)
225 (defvar math-decls-all nil)
227 ;;; Math-decls-cache is an a-list where each entry is a list of the form:
228 ;;; (VAR TYPES RANGE)
229 ;;; where VAR is a variable name (with var- prefix) or function name;
230 ;;; TYPES is a list of type symbols (any, int, frac, ...)
231 ;;; RANGE is a sorted vector of intervals describing the range.
233 (defvar math-super-types
234 '((int numint rat real number)
235 (numint real number)
236 (frac rat real number)
237 (rat real number)
238 (float real number)
239 (real number)
240 (number)
241 (scalar)
242 (sqmatrix matrix vector)
243 (matrix vector)
244 (vector)
245 (const)))
247 (defun math-setup-declarations ()
248 (or (eq math-decls-cache-tag (calc-var-value 'var-Decls))
249 (let ((p (calc-var-value 'var-Decls))
250 vec type range)
251 (setq math-decls-cache-tag p
252 math-decls-cache nil)
253 (and (eq (car-safe p) 'vec)
254 (while (setq p (cdr p))
255 (and (eq (car-safe (car p)) 'vec)
256 (setq vec (nth 2 (car p)))
257 (condition-case err
258 (let ((v (nth 1 (car p))))
259 (setq type nil range nil)
260 (or (eq (car-safe vec) 'vec)
261 (setq vec (list 'vec vec)))
262 (while (and (setq vec (cdr vec))
263 (not (Math-objectp (car vec))))
264 (and (eq (car-safe (car vec)) 'var)
265 (let ((st (assq (nth 1 (car vec))
266 math-super-types)))
267 (cond (st (setq type (append type st)))
268 ((eq (nth 1 (car vec)) 'pos)
269 (setq type (append type
270 '(real number))
271 range
272 '(intv 1 0 (var inf var-inf))))
273 ((eq (nth 1 (car vec)) 'nonneg)
274 (setq type (append type
275 '(real number))
276 range
277 '(intv 3 0
278 (var inf var-inf))))))))
279 (if vec
280 (setq type (append type '(real number))
281 range (math-prepare-set (cons 'vec vec))))
282 (setq type (list type range))
283 (or (eq (car-safe v) 'vec)
284 (setq v (list 'vec v)))
285 (while (setq v (cdr v))
286 (if (or (eq (car-safe (car v)) 'var)
287 (not (Math-primp (car v))))
288 (setq math-decls-cache
289 (cons (cons (if (eq (car (car v)) 'var)
290 (nth 2 (car v))
291 (car (car v)))
292 type)
293 math-decls-cache)))))
294 (error nil)))))
295 (setq math-decls-all (assq 'var-All math-decls-cache)))))
297 (defun math-known-scalarp (a &optional assume-scalar)
298 (math-setup-declarations)
299 (if (if calc-matrix-mode
300 (eq calc-matrix-mode 'scalar)
301 assume-scalar)
302 (not (math-check-known-matrixp a))
303 (math-check-known-scalarp a)))
305 (defun math-known-matrixp (a)
306 (and (not (Math-scalarp a))
307 (not (math-known-scalarp a t))))
309 (defun math-known-square-matrixp (a)
310 (and (math-known-matrixp a)
311 (math-check-known-square-matrixp a)))
313 ;;; Try to prove that A is a scalar (i.e., a non-vector).
314 (defun math-check-known-scalarp (a)
315 (cond ((Math-objectp a) t)
316 ((memq (car a) math-scalar-functions)
318 ((memq (car a) math-real-scalar-functions)
320 ((memq (car a) math-scalar-if-args-functions)
321 (while (and (setq a (cdr a))
322 (math-check-known-scalarp (car a))))
323 (null a))
324 ((eq (car a) '^)
325 (math-check-known-scalarp (nth 1 a)))
326 ((math-const-var a) t)
328 (let ((decl (if (eq (car a) 'var)
329 (or (assq (nth 2 a) math-decls-cache)
330 math-decls-all)
331 (assq (car a) math-decls-cache)))
332 val)
333 (cond
334 ((memq 'scalar (nth 1 decl))
336 ((and (eq (car a) 'var)
337 (boundp (nth 2 a))
338 (setq val (symbol-value (nth 2 a))))
339 (math-check-known-scalarp val))
341 nil))))))
343 ;;; Try to prove that A is *not* a scalar.
344 (defun math-check-known-matrixp (a)
345 (cond ((Math-objectp a) nil)
346 ((memq (car a) math-nonscalar-functions)
348 ((memq (car a) math-scalar-if-args-functions)
349 (while (and (setq a (cdr a))
350 (not (math-check-known-matrixp (car a)))))
352 ((eq (car a) '^)
353 (math-check-known-matrixp (nth 1 a)))
354 ((math-const-var a) nil)
356 (let ((decl (if (eq (car a) 'var)
357 (or (assq (nth 2 a) math-decls-cache)
358 math-decls-all)
359 (assq (car a) math-decls-cache)))
360 val)
361 (cond
362 ((memq 'matrix (nth 1 decl))
364 ((and (eq (car a) 'var)
365 (boundp (nth 2 a))
366 (setq val (symbol-value (nth 2 a))))
367 (math-check-known-matrixp val))
369 nil))))))
371 ;;; Given that A is a matrix, try to prove that it is a square matrix.
372 (defun math-check-known-square-matrixp (a)
373 (cond ((math-square-matrixp a)
375 ((eq (car-safe a) '^)
376 (math-check-known-square-matrixp (nth 1 a)))
378 (let ((decl (if (eq (car a) 'var)
379 (or (assq (nth 2 a) math-decls-cache)
380 math-decls-all)
381 (assq (car a) math-decls-cache)))
382 val)
383 (cond
384 ((memq 'sqmatrix (nth 1 decl))
386 ((and (eq (car a) 'var)
387 (boundp (nth 2 a))
388 (setq val (symbol-value (nth 2 a))))
389 (math-check-known-square-matrixp val))
390 ((and (or
391 (integerp calc-matrix-mode)
392 (eq calc-matrix-mode 'sqmatrix))
393 (eq (car-safe a) 'var))
395 ((memq 'matrix (nth 1 decl))
396 nil)
398 nil))))))
400 ;;; Try to prove that A is a real (i.e., not complex).
401 (defun math-known-realp (a)
402 (< (math-possible-signs a) 8))
404 ;;; Try to prove that A is real and positive.
405 (defun math-known-posp (a)
406 (eq (math-possible-signs a) 4))
408 ;;; Try to prove that A is real and negative.
409 (defun math-known-negp (a)
410 (eq (math-possible-signs a) 1))
412 ;;; Try to prove that A is real and nonnegative.
413 (defun math-known-nonnegp (a)
414 (memq (math-possible-signs a) '(2 4 6)))
416 ;;; Try to prove that A is real and nonpositive.
417 (defun math-known-nonposp (a)
418 (memq (math-possible-signs a) '(1 2 3)))
420 ;;; Try to prove that A is nonzero.
421 (defun math-known-nonzerop (a)
422 (memq (math-possible-signs a) '(1 4 5 8 9 12 13)))
424 ;;; Return true if A is negative, or looks negative but we don't know.
425 (defun math-guess-if-neg (a)
426 (let ((sgn (math-possible-signs a)))
427 (if (memq sgn '(1 3))
429 (if (memq sgn '(2 4 6))
431 (math-looks-negp a)))))
433 ;;; Find the possible signs of A, assuming A is a number of some kind.
434 ;;; Returns an integer with bits: 1 may be negative,
435 ;;; 2 may be zero,
436 ;;; 4 may be positive,
437 ;;; 8 may be nonreal.
439 (defun math-possible-signs (a &optional origin)
440 (cond ((Math-objectp a)
441 (if origin (setq a (math-sub a origin)))
442 (cond ((Math-posp a) 4)
443 ((Math-negp a) 1)
444 ((Math-zerop a) 2)
445 ((eq (car a) 'intv)
446 (cond
447 ((math-known-posp (nth 2 a)) 4)
448 ((math-known-negp (nth 3 a)) 1)
449 ((Math-zerop (nth 2 a)) 6)
450 ((Math-zerop (nth 3 a)) 3)
451 (t 7)))
452 ((eq (car a) 'sdev)
453 (if (math-known-realp (nth 1 a)) 7 15))
454 (t 8)))
455 ((memq (car a) '(+ -))
456 (cond ((Math-realp (nth 1 a))
457 (if (eq (car a) '-)
458 (math-neg-signs
459 (math-possible-signs (nth 2 a)
460 (if origin
461 (math-add origin (nth 1 a))
462 (nth 1 a))))
463 (math-possible-signs (nth 2 a)
464 (if origin
465 (math-sub origin (nth 1 a))
466 (math-neg (nth 1 a))))))
467 ((Math-realp (nth 2 a))
468 (let ((org (if (eq (car a) '-)
469 (nth 2 a)
470 (math-neg (nth 2 a)))))
471 (math-possible-signs (nth 1 a)
472 (if origin
473 (math-add origin org)
474 org))))
476 (let ((s1 (math-possible-signs (nth 1 a) origin))
477 (s2 (math-possible-signs (nth 2 a))))
478 (if (eq (car a) '-) (setq s2 (math-neg-signs s2)))
479 (cond ((eq s1 s2) s1)
480 ((eq s1 2) s2)
481 ((eq s2 2) s1)
482 ((>= s1 8) 15)
483 ((>= s2 8) 15)
484 ((and (eq s1 4) (eq s2 6)) 4)
485 ((and (eq s2 4) (eq s1 6)) 4)
486 ((and (eq s1 1) (eq s2 3)) 1)
487 ((and (eq s2 1) (eq s1 3)) 1)
488 (t 7))))))
489 ((eq (car a) 'neg)
490 (math-neg-signs (math-possible-signs
491 (nth 1 a)
492 (and origin (math-neg origin)))))
493 ((and origin (Math-zerop origin) (setq origin nil)
494 nil))
495 ((and (or (eq (car a) '*)
496 (and (eq (car a) '/) origin))
497 (Math-realp (nth 1 a)))
498 (let ((s (if (eq (car a) '*)
499 (if (Math-zerop (nth 1 a))
500 (math-possible-signs 0 origin)
501 (math-possible-signs (nth 2 a)
502 (math-div (or origin 0)
503 (nth 1 a))))
504 (math-neg-signs
505 (math-possible-signs (nth 2 a)
506 (math-div (nth 1 a)
507 origin))))))
508 (if (Math-negp (nth 1 a)) (math-neg-signs s) s)))
509 ((and (memq (car a) '(* /)) (Math-realp (nth 2 a)))
510 (let ((s (math-possible-signs (nth 1 a)
511 (if (eq (car a) '*)
512 (math-mul (or origin 0) (nth 2 a))
513 (math-div (or origin 0) (nth 2 a))))))
514 (if (Math-negp (nth 2 a)) (math-neg-signs s) s)))
515 ((eq (car a) 'vec)
516 (let ((signs 0))
517 (while (and (setq a (cdr a)) (< signs 15))
518 (setq signs (logior signs (math-possible-signs
519 (car a) origin))))
520 signs))
521 (t (let ((sign
522 (cond
523 ((memq (car a) '(* /))
524 (let ((s1 (math-possible-signs (nth 1 a)))
525 (s2 (math-possible-signs (nth 2 a))))
526 (cond ((>= s1 8) 15)
527 ((>= s2 8) 15)
528 ((and (eq (car a) '/) (memq s2 '(2 3 6 7))) 15)
530 (logior (if (memq s1 '(4 5 6 7)) s2 0)
531 (if (memq s1 '(2 3 6 7)) 2 0)
532 (if (memq s1 '(1 3 5 7))
533 (math-neg-signs s2) 0))))))
534 ((eq (car a) '^)
535 (let ((s1 (math-possible-signs (nth 1 a)))
536 (s2 (math-possible-signs (nth 2 a))))
537 (cond ((>= s1 8) 15)
538 ((>= s2 8) 15)
539 ((eq s1 4) 4)
540 ((eq s1 2) (if (eq s2 4) 2 15))
541 ((eq s2 2) (if (memq s1 '(1 5)) 2 15))
542 ((Math-integerp (nth 2 a))
543 (if (math-evenp (nth 2 a))
544 (if (memq s1 '(3 6 7)) 6 4)
545 s1))
546 ((eq s1 6) (if (eq s2 4) 6 15))
547 (t 7))))
548 ((eq (car a) '%)
549 (let ((s2 (math-possible-signs (nth 2 a))))
550 (cond ((>= s2 8) 7)
551 ((eq s2 2) 2)
552 ((memq s2 '(4 6)) 6)
553 ((memq s2 '(1 3)) 3)
554 (t 7))))
555 ((and (memq (car a) '(calcFunc-abs calcFunc-abssqr))
556 (= (length a) 2))
557 (let ((s1 (math-possible-signs (nth 1 a))))
558 (cond ((eq s1 2) 2)
559 ((memq s1 '(1 4 5)) 4)
560 (t 6))))
561 ((and (eq (car a) 'calcFunc-exp) (= (length a) 2))
562 (let ((s1 (math-possible-signs (nth 1 a))))
563 (if (>= s1 8)
565 (if (or (not origin) (math-negp origin))
567 (setq origin (math-sub (or origin 0) 1))
568 (if (Math-zerop origin) (setq origin nil))
569 s1))))
570 ((or (and (memq (car a) '(calcFunc-ln calcFunc-log10))
571 (= (length a) 2))
572 (and (eq (car a) 'calcFunc-log)
573 (= (length a) 3)
574 (math-known-posp (nth 2 a))))
575 (if (math-known-nonnegp (nth 1 a))
576 (math-possible-signs (nth 1 a) 1)
577 15))
578 ((and (eq (car a) 'calcFunc-sqrt) (= (length a) 2))
579 (let ((s1 (math-possible-signs (nth 1 a))))
580 (if (memq s1 '(2 4 6)) s1 15)))
581 ((memq (car a) math-nonnegative-functions) 6)
582 ((memq (car a) math-positive-functions) 4)
583 ((memq (car a) math-real-functions) 7)
584 ((memq (car a) math-real-scalar-functions) 7)
585 ((and (memq (car a) math-real-if-arg-functions)
586 (= (length a) 2))
587 (if (math-known-realp (nth 1 a)) 7 15)))))
588 (cond (sign
589 (if origin
590 (+ (logand sign 8)
591 (if (Math-posp origin)
592 (if (memq sign '(1 2 3 8 9 10 11)) 1 7)
593 (if (memq sign '(2 4 6 8 10 12 14)) 4 7)))
594 sign))
595 ((math-const-var a)
596 (cond ((eq (nth 2 a) 'var-pi)
597 (if origin
598 (math-possible-signs (math-pi) origin)
600 ((eq (nth 2 a) 'var-e)
601 (if origin
602 (math-possible-signs (math-e) origin)
604 ((eq (nth 2 a) 'var-inf) 4)
605 ((eq (nth 2 a) 'var-uinf) 13)
606 ((eq (nth 2 a) 'var-i) 8)
607 (t 15)))
609 (math-setup-declarations)
610 (let ((decl (if (eq (car a) 'var)
611 (or (assq (nth 2 a) math-decls-cache)
612 math-decls-all)
613 (assq (car a) math-decls-cache))))
614 (if (and origin
615 (memq 'int (nth 1 decl))
616 (not (Math-num-integerp origin)))
618 (if (nth 2 decl)
619 (math-possible-signs (nth 2 decl) origin)
620 (if (memq 'real (nth 1 decl))
622 15))))))))))
624 (defun math-neg-signs (s1)
625 (if (>= s1 8)
626 (+ 8 (math-neg-signs (- s1 8)))
627 (+ (if (memq s1 '(1 3 5 7)) 4 0)
628 (if (memq s1 '(2 3 6 7)) 2 0)
629 (if (memq s1 '(4 5 6 7)) 1 0))))
632 ;;; Try to prove that A is an integer.
633 (defun math-known-integerp (a)
634 (eq (math-possible-types a) 1))
636 (defun math-known-num-integerp (a)
637 (<= (math-possible-types a t) 3))
639 (defun math-known-imagp (a)
640 (= (math-possible-types a) 16))
643 ;;; Find the possible types of A.
644 ;;; Returns an integer with bits: 1 may be integer.
645 ;;; 2 may be integer-valued float.
646 ;;; 4 may be fraction.
647 ;;; 8 may be non-integer-valued float.
648 ;;; 16 may be imaginary.
649 ;;; 32 may be non-real, non-imaginary.
650 ;;; Real infinities count as integers for the purposes of this function.
651 (defun math-possible-types (a &optional num)
652 (cond ((Math-objectp a)
653 (cond ((Math-integerp a) (if num 3 1))
654 ((Math-messy-integerp a) (if num 3 2))
655 ((eq (car a) 'frac) (if num 12 4))
656 ((eq (car a) 'float) (if num 12 8))
657 ((eq (car a) 'intv)
658 (if (equal (nth 2 a) (nth 3 a))
659 (math-possible-types (nth 2 a))
660 15))
661 ((eq (car a) 'sdev)
662 (if (math-known-realp (nth 1 a)) 15 63))
663 ((eq (car a) 'cplx)
664 (if (math-zerop (nth 1 a)) 16 32))
665 ((eq (car a) 'polar)
666 (if (or (Math-equal (nth 2 a) (math-quarter-circle nil))
667 (Math-equal (nth 2 a)
668 (math-neg (math-quarter-circle nil))))
669 16 48))
670 (t 63)))
671 ((eq (car a) '/)
672 (let* ((t1 (math-possible-types (nth 1 a) num))
673 (t2 (math-possible-types (nth 2 a) num))
674 (t12 (logior t1 t2)))
675 (if (< t12 16)
676 (if (> (logand t12 10) 0)
678 (if (or (= t1 4) (= t2 4) calc-prefer-frac)
680 15))
681 (if (< t12 32)
682 (if (= t1 16)
683 (if (= t2 16) 15
684 (if (< t2 16) 16 31))
685 (if (= t2 16)
686 (if (< t1 16) 16 31)
687 31))
688 63))))
689 ((memq (car a) '(+ - * %))
690 (let* ((t1 (math-possible-types (nth 1 a) num))
691 (t2 (math-possible-types (nth 2 a) num))
692 (t12 (logior t1 t2)))
693 (if (eq (car a) '%)
694 (setq t1 (logand t1 15) t2 (logand t2 15) t12 (logand t12 15)))
695 (if (< t12 16)
696 (let ((mask (if (<= t12 3)
698 (if (and (or (and (<= t1 3) (= (logand t2 3) 0))
699 (and (<= t2 3) (= (logand t1 3) 0)))
700 (memq (car a) '(+ -)))
702 5))))
703 (if num
704 (* mask 3)
705 (logior (if (and (> (logand t1 5) 0) (> (logand t2 5) 0))
706 mask 0)
707 (if (> (logand t12 10) 0)
708 (* mask 2) 0))))
709 (if (< t12 32)
710 (if (eq (car a) '*)
711 (if (= t1 16)
712 (if (= t2 16) 15
713 (if (< t2 16) 16 31))
714 (if (= t2 16)
715 (if (< t1 16) 16 31)
716 31))
717 (if (= t12 16) 16
718 (if (or (and (= t1 16) (< t2 16))
719 (and (= t2 16) (< t1 16))) 32 63)))
720 63))))
721 ((eq (car a) 'neg)
722 (math-possible-types (nth 1 a)))
723 ((eq (car a) '^)
724 (let* ((t1 (math-possible-types (nth 1 a) num))
725 (t2 (math-possible-types (nth 2 a) num))
726 (t12 (logior t1 t2)))
727 (if (and (<= t2 3) (math-known-nonnegp (nth 2 a)) (< t1 16))
728 (let ((mask (logior (if (> (logand t1 3) 0) 1 0)
729 (logand t1 4)
730 (if (> (logand t1 12) 0) 5 0))))
731 (if num
732 (* mask 3)
733 (logior (if (and (> (logand t1 5) 0) (> (logand t2 5) 0))
734 mask 0)
735 (if (> (logand t12 10) 0)
736 (* mask 2) 0))))
737 (if (and (math-known-nonnegp (nth 1 a))
738 (math-known-posp (nth 2 a)))
740 63))))
741 ((eq (car a) 'calcFunc-sqrt)
742 (let ((t1 (math-possible-signs (nth 1 a))))
743 (logior (if (> (logand t1 2) 0) 3 0)
744 (if (> (logand t1 1) 0) 16 0)
745 (if (> (logand t1 4) 0) 15 0)
746 (if (> (logand t1 8) 0) 32 0))))
747 ((eq (car a) 'vec)
748 (let ((types 0))
749 (while (and (setq a (cdr a)) (< types 63))
750 (setq types (logior types (math-possible-types (car a) t))))
751 types))
752 ((or (memq (car a) math-integer-functions)
753 (and (memq (car a) math-rounding-functions)
754 (math-known-nonnegp (or (nth 2 a) 0))))
756 ((or (memq (car a) math-num-integer-functions)
757 (and (memq (car a) math-float-rounding-functions)
758 (math-known-nonnegp (or (nth 2 a) 0))))
760 ((eq (car a) 'calcFunc-frac)
762 ((and (eq (car a) 'calcFunc-float) (= (length a) 2))
763 (let ((t1 (math-possible-types (nth 1 a))))
764 (logior (if (> (logand t1 3) 0) 2 0)
765 (if (> (logand t1 12) 0) 8 0)
766 (logand t1 48))))
767 ((and (memq (car a) '(calcFunc-abs calcFunc-abssqr))
768 (= (length a) 2))
769 (let ((t1 (math-possible-types (nth 1 a))))
770 (if (>= t1 16)
772 t1)))
773 ((math-const-var a)
774 (cond ((memq (nth 2 a) '(var-e var-pi var-phi var-gamma)) 8)
775 ((eq (nth 2 a) 'var-inf) 1)
776 ((eq (nth 2 a) 'var-i) 16)
777 (t 63)))
779 (math-setup-declarations)
780 (let ((decl (if (eq (car a) 'var)
781 (or (assq (nth 2 a) math-decls-cache)
782 math-decls-all)
783 (assq (car a) math-decls-cache))))
784 (cond ((memq 'int (nth 1 decl))
786 ((memq 'numint (nth 1 decl))
788 ((memq 'frac (nth 1 decl))
790 ((memq 'rat (nth 1 decl))
792 ((memq 'float (nth 1 decl))
794 ((nth 2 decl)
795 (math-possible-types (nth 2 decl)))
796 ((memq 'real (nth 1 decl))
798 (t 63))))))
800 (defun math-known-evenp (a)
801 (cond ((Math-integerp a)
802 (math-evenp a))
803 ((Math-messy-integerp a)
804 (or (> (nth 2 a) 0)
805 (math-evenp (math-trunc a))))
806 ((eq (car a) '*)
807 (if (math-known-evenp (nth 1 a))
808 (math-known-num-integerp (nth 2 a))
809 (if (math-known-num-integerp (nth 1 a))
810 (math-known-evenp (nth 2 a)))))
811 ((memq (car a) '(+ -))
812 (or (and (math-known-evenp (nth 1 a))
813 (math-known-evenp (nth 2 a)))
814 (and (math-known-oddp (nth 1 a))
815 (math-known-oddp (nth 2 a)))))
816 ((eq (car a) 'neg)
817 (math-known-evenp (nth 1 a)))))
819 (defun math-known-oddp (a)
820 (cond ((Math-integerp a)
821 (math-oddp a))
822 ((Math-messy-integerp a)
823 (and (<= (nth 2 a) 0)
824 (math-oddp (math-trunc a))))
825 ((memq (car a) '(+ -))
826 (or (and (math-known-evenp (nth 1 a))
827 (math-known-oddp (nth 2 a)))
828 (and (math-known-oddp (nth 1 a))
829 (math-known-evenp (nth 2 a)))))
830 ((eq (car a) 'neg)
831 (math-known-oddp (nth 1 a)))))
834 (defun calcFunc-dreal (expr)
835 (let ((types (math-possible-types expr)))
836 (if (< types 16) 1
837 (if (= (logand types 15) 0) 0
838 (math-reject-arg expr 'realp 'quiet)))))
840 (defun calcFunc-dimag (expr)
841 (let ((types (math-possible-types expr)))
842 (if (= types 16) 1
843 (if (= (logand types 16) 0) 0
844 (math-reject-arg expr "Expected an imaginary number")))))
846 (defun calcFunc-dpos (expr)
847 (let ((signs (math-possible-signs expr)))
848 (if (eq signs 4) 1
849 (if (memq signs '(1 2 3)) 0
850 (math-reject-arg expr 'posp 'quiet)))))
852 (defun calcFunc-dneg (expr)
853 (let ((signs (math-possible-signs expr)))
854 (if (eq signs 1) 1
855 (if (memq signs '(2 4 6)) 0
856 (math-reject-arg expr 'negp 'quiet)))))
858 (defun calcFunc-dnonneg (expr)
859 (let ((signs (math-possible-signs expr)))
860 (if (memq signs '(2 4 6)) 1
861 (if (eq signs 1) 0
862 (math-reject-arg expr 'posp 'quiet)))))
864 (defun calcFunc-dnonzero (expr)
865 (let ((signs (math-possible-signs expr)))
866 (if (memq signs '(1 4 5 8 9 12 13)) 1
867 (if (eq signs 2) 0
868 (math-reject-arg expr 'nonzerop 'quiet)))))
870 (defun calcFunc-dint (expr)
871 (let ((types (math-possible-types expr)))
872 (if (= types 1) 1
873 (if (= (logand types 1) 0) 0
874 (math-reject-arg expr 'integerp 'quiet)))))
876 (defun calcFunc-dnumint (expr)
877 (let ((types (math-possible-types expr t)))
878 (if (<= types 3) 1
879 (if (= (logand types 3) 0) 0
880 (math-reject-arg expr 'integerp 'quiet)))))
882 (defun calcFunc-dnatnum (expr)
883 (let ((res (calcFunc-dint expr)))
884 (if (eq res 1)
885 (calcFunc-dnonneg expr)
886 res)))
888 (defun calcFunc-deven (expr)
889 (if (math-known-evenp expr)
891 (if (or (math-known-oddp expr)
892 (= (logand (math-possible-types expr) 3) 0))
894 (math-reject-arg expr "Can't tell if expression is odd or even"))))
896 (defun calcFunc-dodd (expr)
897 (if (math-known-oddp expr)
899 (if (or (math-known-evenp expr)
900 (= (logand (math-possible-types expr) 3) 0))
902 (math-reject-arg expr "Can't tell if expression is odd or even"))))
904 (defun calcFunc-drat (expr)
905 (let ((types (math-possible-types expr)))
906 (if (memq types '(1 4 5)) 1
907 (if (= (logand types 5) 0) 0
908 (math-reject-arg expr "Rational number expected")))))
910 (defun calcFunc-drange (expr)
911 (math-setup-declarations)
912 (let (range)
913 (if (Math-realp expr)
914 (list 'vec expr)
915 (if (eq (car-safe expr) 'intv)
916 expr
917 (if (eq (car-safe expr) 'var)
918 (setq range (nth 2 (or (assq (nth 2 expr) math-decls-cache)
919 math-decls-all)))
920 (setq range (nth 2 (assq (car-safe expr) math-decls-cache))))
921 (if range
922 (math-clean-set (copy-sequence range))
923 (setq range (math-possible-signs expr))
924 (if (< range 8)
925 (aref [(vec)
926 (intv 2 (neg (var inf var-inf)) 0)
927 (vec 0)
928 (intv 3 (neg (var inf var-inf)) 0)
929 (intv 1 0 (var inf var-inf))
930 (vec (intv 2 (neg (var inf var-inf)) 0)
931 (intv 1 0 (var inf var-inf)))
932 (intv 3 0 (var inf var-inf))
933 (intv 3 (neg (var inf var-inf)) (var inf var-inf))] range)
934 (math-reject-arg expr 'realp 'quiet)))))))
936 (defun calcFunc-dscalar (a)
937 (if (math-known-scalarp a) 1
938 (if (math-known-matrixp a) 0
939 (math-reject-arg a 'objectp 'quiet))))
942 ;;;; Arithmetic.
944 (defsubst calcFunc-neg (a)
945 (math-normalize (list 'neg a)))
947 (defun math-neg-fancy (a)
948 (cond ((eq (car a) 'polar)
949 (list 'polar
950 (nth 1 a)
951 (if (math-posp (nth 2 a))
952 (math-sub (nth 2 a) (math-half-circle nil))
953 (math-add (nth 2 a) (math-half-circle nil)))))
954 ((eq (car a) 'mod)
955 (if (math-zerop (nth 1 a))
957 (list 'mod (math-sub (nth 2 a) (nth 1 a)) (nth 2 a))))
958 ((eq (car a) 'sdev)
959 (list 'sdev (math-neg (nth 1 a)) (nth 2 a)))
960 ((eq (car a) 'intv)
961 (math-make-intv (aref [0 2 1 3] (nth 1 a))
962 (math-neg (nth 3 a))
963 (math-neg (nth 2 a))))
964 ((and math-simplify-only
965 (not (equal a math-simplify-only)))
966 (list 'neg a))
967 ((eq (car a) '+)
968 (math-sub (math-neg (nth 1 a)) (nth 2 a)))
969 ((eq (car a) '-)
970 (math-sub (nth 2 a) (nth 1 a)))
971 ((and (memq (car a) '(* /))
972 (math-okay-neg (nth 1 a)))
973 (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
974 ((and (memq (car a) '(* /))
975 (math-okay-neg (nth 2 a)))
976 (list (car a) (nth 1 a) (math-neg (nth 2 a))))
977 ((and (memq (car a) '(* /))
978 (or (math-objectp (nth 1 a))
979 (and (eq (car (nth 1 a)) '*)
980 (math-objectp (nth 1 (nth 1 a))))))
981 (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
982 ((and (eq (car a) '/)
983 (or (math-objectp (nth 2 a))
984 (and (eq (car (nth 2 a)) '*)
985 (math-objectp (nth 1 (nth 2 a))))))
986 (list (car a) (nth 1 a) (math-neg (nth 2 a))))
987 ((and (eq (car a) 'var) (memq (nth 2 a) '(var-uinf var-nan)))
989 ((eq (car a) 'neg)
990 (nth 1 a))
991 (t (list 'neg a))))
993 (defun math-okay-neg (a)
994 (or (math-looks-negp a)
995 (eq (car-safe a) '-)))
997 (defun math-neg-float (a)
998 (list 'float (Math-integer-neg (nth 1 a)) (nth 2 a)))
1001 (defun calcFunc-add (&rest rest)
1002 (if rest
1003 (let ((a (car rest)))
1004 (while (setq rest (cdr rest))
1005 (setq a (list '+ a (car rest))))
1006 (math-normalize a))
1009 (defun calcFunc-sub (&rest rest)
1010 (if rest
1011 (let ((a (car rest)))
1012 (while (setq rest (cdr rest))
1013 (setq a (list '- a (car rest))))
1014 (math-normalize a))
1017 (defun math-add-objects-fancy (a b)
1018 (cond ((and (Math-numberp a) (Math-numberp b))
1019 (let ((aa (math-complex a))
1020 (bb (math-complex b)))
1021 (math-normalize
1022 (let ((res (list 'cplx
1023 (math-add (nth 1 aa) (nth 1 bb))
1024 (math-add (nth 2 aa) (nth 2 bb)))))
1025 (if (math-want-polar a b)
1026 (math-polar res)
1027 res)))))
1028 ((or (Math-vectorp a) (Math-vectorp b))
1029 (math-map-vec-2 'math-add a b))
1030 ((eq (car-safe a) 'sdev)
1031 (if (eq (car-safe b) 'sdev)
1032 (math-make-sdev (math-add (nth 1 a) (nth 1 b))
1033 (math-hypot (nth 2 a) (nth 2 b)))
1034 (and (or (Math-scalarp b)
1035 (not (Math-objvecp b)))
1036 (math-make-sdev (math-add (nth 1 a) b) (nth 2 a)))))
1037 ((and (eq (car-safe b) 'sdev)
1038 (or (Math-scalarp a)
1039 (not (Math-objvecp a))))
1040 (math-make-sdev (math-add a (nth 1 b)) (nth 2 b)))
1041 ((eq (car-safe a) 'intv)
1042 (if (eq (car-safe b) 'intv)
1043 (math-make-intv (logior (logand (nth 1 a) (nth 1 b))
1044 (if (equal (nth 2 a)
1045 '(neg (var inf var-inf)))
1046 (logand (nth 1 a) 2) 0)
1047 (if (equal (nth 2 b)
1048 '(neg (var inf var-inf)))
1049 (logand (nth 1 b) 2) 0)
1050 (if (equal (nth 3 a) '(var inf var-inf))
1051 (logand (nth 1 a) 1) 0)
1052 (if (equal (nth 3 b) '(var inf var-inf))
1053 (logand (nth 1 b) 1) 0))
1054 (math-add (nth 2 a) (nth 2 b))
1055 (math-add (nth 3 a) (nth 3 b)))
1056 (and (or (Math-anglep b)
1057 (eq (car b) 'date)
1058 (not (Math-objvecp b)))
1059 (math-make-intv (nth 1 a)
1060 (math-add (nth 2 a) b)
1061 (math-add (nth 3 a) b)))))
1062 ((and (eq (car-safe b) 'intv)
1063 (or (Math-anglep a)
1064 (eq (car a) 'date)
1065 (not (Math-objvecp a))))
1066 (math-make-intv (nth 1 b)
1067 (math-add a (nth 2 b))
1068 (math-add a (nth 3 b))))
1069 ((eq (car-safe a) 'date)
1070 (cond ((eq (car-safe b) 'date)
1071 (math-add (nth 1 a) (nth 1 b)))
1072 ((eq (car-safe b) 'hms)
1073 (let ((parts (math-date-parts (nth 1 a))))
1074 (list 'date
1075 (math-add (car parts) ; this minimizes roundoff
1076 (math-div (math-add
1077 (math-add (nth 1 parts)
1078 (nth 2 parts))
1079 (math-add
1080 (math-mul (nth 1 b) 3600)
1081 (math-add (math-mul (nth 2 b) 60)
1082 (nth 3 b))))
1083 86400)))))
1084 ((Math-realp b)
1085 (list 'date (math-add (nth 1 a) b)))
1086 (t nil)))
1087 ((eq (car-safe b) 'date)
1088 (math-add-objects-fancy b a))
1089 ((and (eq (car-safe a) 'mod)
1090 (eq (car-safe b) 'mod)
1091 (equal (nth 2 a) (nth 2 b)))
1092 (math-make-mod (math-add (nth 1 a) (nth 1 b)) (nth 2 a)))
1093 ((and (eq (car-safe a) 'mod)
1094 (Math-anglep b))
1095 (math-make-mod (math-add (nth 1 a) b) (nth 2 a)))
1096 ((and (eq (car-safe b) 'mod)
1097 (Math-anglep a))
1098 (math-make-mod (math-add a (nth 1 b)) (nth 2 b)))
1099 ((and (or (eq (car-safe a) 'hms) (eq (car-safe b) 'hms))
1100 (and (Math-anglep a) (Math-anglep b)))
1101 (or (eq (car-safe a) 'hms) (setq a (math-to-hms a)))
1102 (or (eq (car-safe b) 'hms) (setq b (math-to-hms b)))
1103 (math-normalize
1104 (if (math-negp a)
1105 (math-neg (math-add (math-neg a) (math-neg b)))
1106 (if (math-negp b)
1107 (let* ((s (math-add (nth 3 a) (nth 3 b)))
1108 (m (math-add (nth 2 a) (nth 2 b)))
1109 (h (math-add (nth 1 a) (nth 1 b))))
1110 (if (math-negp s)
1111 (setq s (math-add s 60)
1112 m (math-add m -1)))
1113 (if (math-negp m)
1114 (setq m (math-add m 60)
1115 h (math-add h -1)))
1116 (if (math-negp h)
1117 (math-add b a)
1118 (list 'hms h m s)))
1119 (let* ((s (math-add (nth 3 a) (nth 3 b)))
1120 (m (math-add (nth 2 a) (nth 2 b)))
1121 (h (math-add (nth 1 a) (nth 1 b))))
1122 (list 'hms h m s))))))
1123 (t (calc-record-why "*Incompatible arguments for +" a b))))
1125 (defun math-add-symb-fancy (a b)
1126 (or (and math-simplify-only
1127 (not (equal a math-simplify-only))
1128 (list '+ a b))
1129 (and (eq (car-safe b) '+)
1130 (math-add (math-add a (nth 1 b))
1131 (nth 2 b)))
1132 (and (eq (car-safe b) '-)
1133 (math-sub (math-add a (nth 1 b))
1134 (nth 2 b)))
1135 (and (eq (car-safe b) 'neg)
1136 (eq (car-safe (nth 1 b)) '+)
1137 (math-sub (math-sub a (nth 1 (nth 1 b)))
1138 (nth 2 (nth 1 b))))
1139 (and (or (and (Math-vectorp a) (math-known-scalarp b))
1140 (and (Math-vectorp b) (math-known-scalarp a)))
1141 (math-map-vec-2 'math-add a b))
1142 (let ((inf (math-infinitep a)))
1143 (cond
1144 (inf
1145 (let ((inf2 (math-infinitep b)))
1146 (if inf2
1147 (if (or (memq (nth 2 inf) '(var-uinf var-nan))
1148 (memq (nth 2 inf2) '(var-uinf var-nan)))
1149 '(var nan var-nan)
1150 (let ((dir (math-infinite-dir a inf))
1151 (dir2 (math-infinite-dir b inf2)))
1152 (if (and (Math-objectp dir) (Math-objectp dir2))
1153 (if (Math-equal dir dir2)
1155 '(var nan var-nan)))))
1156 (if (and (equal a '(var inf var-inf))
1157 (eq (car-safe b) 'intv)
1158 (memq (nth 1 b) '(2 3))
1159 (equal (nth 2 b) '(neg (var inf var-inf))))
1160 (list 'intv 3 (nth 2 b) a)
1161 (if (and (equal a '(neg (var inf var-inf)))
1162 (eq (car-safe b) 'intv)
1163 (memq (nth 1 b) '(1 3))
1164 (equal (nth 3 b) '(var inf var-inf)))
1165 (list 'intv 3 a (nth 3 b))
1166 a)))))
1167 ((math-infinitep b)
1168 (if (eq (car-safe a) 'intv)
1169 (math-add b a)
1171 ((eq (car-safe a) '+)
1172 (let ((temp (math-combine-sum (nth 2 a) b nil nil t)))
1173 (and temp
1174 (math-add (nth 1 a) temp))))
1175 ((eq (car-safe a) '-)
1176 (let ((temp (math-combine-sum (nth 2 a) b t nil t)))
1177 (and temp
1178 (math-add (nth 1 a) temp))))
1179 ((and (Math-objectp a) (Math-objectp b))
1180 nil)
1182 (math-combine-sum a b nil nil nil))))
1183 (and (Math-looks-negp b)
1184 (list '- a (math-neg b)))
1185 (and (Math-looks-negp a)
1186 (list '- b (math-neg a)))
1187 (and (eq (car-safe a) 'calcFunc-idn)
1188 (= (length a) 2)
1189 (or (and (eq (car-safe b) 'calcFunc-idn)
1190 (= (length b) 2)
1191 (list 'calcFunc-idn (math-add (nth 1 a) (nth 1 b))))
1192 (and (math-square-matrixp b)
1193 (math-add (math-mimic-ident (nth 1 a) b) b))
1194 (and (math-known-scalarp b)
1195 (math-add (nth 1 a) b))))
1196 (and (eq (car-safe b) 'calcFunc-idn)
1197 (= (length a) 2)
1198 (or (and (math-square-matrixp a)
1199 (math-add a (math-mimic-ident (nth 1 b) a)))
1200 (and (math-known-scalarp a)
1201 (math-add a (nth 1 b)))))
1202 (list '+ a b)))
1205 (defun calcFunc-mul (&rest rest)
1206 (if rest
1207 (let ((a (car rest)))
1208 (while (setq rest (cdr rest))
1209 (setq a (list '* a (car rest))))
1210 (math-normalize a))
1213 (defun math-mul-objects-fancy (a b)
1214 (cond ((and (Math-numberp a) (Math-numberp b))
1215 (math-normalize
1216 (if (math-want-polar a b)
1217 (let ((a (math-polar a))
1218 (b (math-polar b)))
1219 (list 'polar
1220 (math-mul (nth 1 a) (nth 1 b))
1221 (math-fix-circular (math-add (nth 2 a) (nth 2 b)))))
1222 (setq a (math-complex a)
1223 b (math-complex b))
1224 (list 'cplx
1225 (math-sub (math-mul (nth 1 a) (nth 1 b))
1226 (math-mul (nth 2 a) (nth 2 b)))
1227 (math-add (math-mul (nth 1 a) (nth 2 b))
1228 (math-mul (nth 2 a) (nth 1 b)))))))
1229 ((Math-vectorp a)
1230 (if (Math-vectorp b)
1231 (if (math-matrixp a)
1232 (if (math-matrixp b)
1233 (if (= (length (nth 1 a)) (length b))
1234 (math-mul-mats a b)
1235 (math-dimension-error))
1236 (if (= (length (nth 1 a)) 2)
1237 (if (= (length a) (length b))
1238 (math-mul-mats a (list 'vec b))
1239 (math-dimension-error))
1240 (if (= (length (nth 1 a)) (length b))
1241 (math-mul-mat-vec a b)
1242 (math-dimension-error))))
1243 (if (math-matrixp b)
1244 (if (= (length a) (length b))
1245 (nth 1 (math-mul-mats (list 'vec a) b))
1246 (math-dimension-error))
1247 (if (= (length a) (length b))
1248 (math-dot-product a b)
1249 (math-dimension-error))))
1250 (math-map-vec-2 'math-mul a b)))
1251 ((Math-vectorp b)
1252 (math-map-vec-2 'math-mul a b))
1253 ((eq (car-safe a) 'sdev)
1254 (if (eq (car-safe b) 'sdev)
1255 (math-make-sdev (math-mul (nth 1 a) (nth 1 b))
1256 (math-hypot (math-mul (nth 2 a) (nth 1 b))
1257 (math-mul (nth 2 b) (nth 1 a))))
1258 (and (or (Math-scalarp b)
1259 (not (Math-objvecp b)))
1260 (math-make-sdev (math-mul (nth 1 a) b)
1261 (math-mul (nth 2 a) b)))))
1262 ((and (eq (car-safe b) 'sdev)
1263 (or (Math-scalarp a)
1264 (not (Math-objvecp a))))
1265 (math-make-sdev (math-mul a (nth 1 b)) (math-mul a (nth 2 b))))
1266 ((and (eq (car-safe a) 'intv) (Math-anglep b))
1267 (if (Math-negp b)
1268 (math-neg (math-mul a (math-neg b)))
1269 (math-make-intv (nth 1 a)
1270 (math-mul (nth 2 a) b)
1271 (math-mul (nth 3 a) b))))
1272 ((and (eq (car-safe b) 'intv) (Math-anglep a))
1273 (math-mul b a))
1274 ((and (eq (car-safe a) 'intv) (math-intv-constp a)
1275 (eq (car-safe b) 'intv) (math-intv-constp b))
1276 (let ((lo (math-mul a (nth 2 b)))
1277 (hi (math-mul a (nth 3 b))))
1278 (or (eq (car-safe lo) 'intv)
1279 (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0) lo lo)))
1280 (or (eq (car-safe hi) 'intv)
1281 (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0) hi hi)))
1282 (math-combine-intervals
1283 (nth 2 lo) (and (or (memq (nth 1 b) '(2 3))
1284 (math-infinitep (nth 2 lo)))
1285 (memq (nth 1 lo) '(2 3)))
1286 (nth 3 lo) (and (or (memq (nth 1 b) '(2 3))
1287 (math-infinitep (nth 3 lo)))
1288 (memq (nth 1 lo) '(1 3)))
1289 (nth 2 hi) (and (or (memq (nth 1 b) '(1 3))
1290 (math-infinitep (nth 2 hi)))
1291 (memq (nth 1 hi) '(2 3)))
1292 (nth 3 hi) (and (or (memq (nth 1 b) '(1 3))
1293 (math-infinitep (nth 3 hi)))
1294 (memq (nth 1 hi) '(1 3))))))
1295 ((and (eq (car-safe a) 'mod)
1296 (eq (car-safe b) 'mod)
1297 (equal (nth 2 a) (nth 2 b)))
1298 (math-make-mod (math-mul (nth 1 a) (nth 1 b)) (nth 2 a)))
1299 ((and (eq (car-safe a) 'mod)
1300 (Math-anglep b))
1301 (math-make-mod (math-mul (nth 1 a) b) (nth 2 a)))
1302 ((and (eq (car-safe b) 'mod)
1303 (Math-anglep a))
1304 (math-make-mod (math-mul a (nth 1 b)) (nth 2 b)))
1305 ((and (eq (car-safe a) 'hms) (Math-realp b))
1306 (math-with-extra-prec 2
1307 (math-to-hms (math-mul (math-from-hms a 'deg) b) 'deg)))
1308 ((and (eq (car-safe b) 'hms) (Math-realp a))
1309 (math-mul b a))
1310 (t (calc-record-why "*Incompatible arguments for *" a b))))
1312 ;;; Fast function to multiply floating-point numbers.
1313 (defun math-mul-float (a b) ; [F F F]
1314 (math-make-float (math-mul (nth 1 a) (nth 1 b))
1315 (+ (nth 2 a) (nth 2 b))))
1317 (defun math-sqr-float (a) ; [F F]
1318 (math-make-float (math-mul (nth 1 a) (nth 1 a))
1319 (+ (nth 2 a) (nth 2 a))))
1321 (defun math-intv-constp (a &optional finite)
1322 (and (or (Math-anglep (nth 2 a))
1323 (and (equal (nth 2 a) '(neg (var inf var-inf)))
1324 (or (not finite)
1325 (memq (nth 1 a) '(0 1)))))
1326 (or (Math-anglep (nth 3 a))
1327 (and (equal (nth 3 a) '(var inf var-inf))
1328 (or (not finite)
1329 (memq (nth 1 a) '(0 2)))))))
1331 (defun math-mul-zero (a b)
1332 (if (math-known-matrixp b)
1333 (if (math-vectorp b)
1334 (math-map-vec-2 'math-mul a b)
1335 (math-mimic-ident 0 b))
1336 (if (math-infinitep b)
1337 '(var nan var-nan)
1338 (let ((aa nil) (bb nil))
1339 (if (and (eq (car-safe b) 'intv)
1340 (progn
1341 (and (equal (nth 2 b) '(neg (var inf var-inf)))
1342 (memq (nth 1 b) '(2 3))
1343 (setq aa (nth 2 b)))
1344 (and (equal (nth 3 b) '(var inf var-inf))
1345 (memq (nth 1 b) '(1 3))
1346 (setq bb (nth 3 b)))
1347 (or aa bb)))
1348 (if (or (math-posp a)
1349 (and (math-zerop a)
1350 (or (memq calc-infinite-mode '(-1 1))
1351 (setq aa '(neg (var inf var-inf))
1352 bb '(var inf var-inf)))))
1353 (list 'intv 3 (or aa 0) (or bb 0))
1354 (if (math-negp a)
1355 (math-neg (list 'intv 3 (or aa 0) (or bb 0)))
1356 '(var nan var-nan)))
1357 (if (or (math-floatp a) (math-floatp b)) '(float 0 0) 0))))))
1360 (defun math-mul-symb-fancy (a b)
1361 (or (and math-simplify-only
1362 (not (equal a math-simplify-only))
1363 (list '* a b))
1364 (and (Math-equal-int a 1)
1366 (and (Math-equal-int a -1)
1367 (math-neg b))
1368 (and (or (and (Math-vectorp a) (math-known-scalarp b))
1369 (and (Math-vectorp b) (math-known-scalarp a)))
1370 (math-map-vec-2 'math-mul a b))
1371 (and (Math-objectp b) (not (Math-objectp a))
1372 (math-mul b a))
1373 (and (eq (car-safe a) 'neg)
1374 (math-neg (math-mul (nth 1 a) b)))
1375 (and (eq (car-safe b) 'neg)
1376 (math-neg (math-mul a (nth 1 b))))
1377 (and (eq (car-safe a) '*)
1378 (math-mul (nth 1 a)
1379 (math-mul (nth 2 a) b)))
1380 (and (eq (car-safe a) '^)
1381 (Math-looks-negp (nth 2 a))
1382 (not (and (eq (car-safe b) '^) (Math-looks-negp (nth 2 b))))
1383 (math-known-scalarp b t)
1384 (math-div b (math-normalize
1385 (list '^ (nth 1 a) (math-neg (nth 2 a))))))
1386 (and (eq (car-safe b) '^)
1387 (Math-looks-negp (nth 2 b))
1388 (not (and (eq (car-safe a) '^) (Math-looks-negp (nth 2 a))))
1389 (math-div a (math-normalize
1390 (list '^ (nth 1 b) (math-neg (nth 2 b))))))
1391 (and (eq (car-safe a) '/)
1392 (or (math-known-scalarp a t) (math-known-scalarp b t))
1393 (let ((temp (math-combine-prod (nth 2 a) b t nil t)))
1394 (if temp
1395 (math-mul (nth 1 a) temp)
1396 (math-div (math-mul (nth 1 a) b) (nth 2 a)))))
1397 (and (eq (car-safe b) '/)
1398 (math-div (math-mul a (nth 1 b)) (nth 2 b)))
1399 (and (eq (car-safe b) '+)
1400 (Math-numberp a)
1401 (or (Math-numberp (nth 1 b))
1402 (Math-numberp (nth 2 b)))
1403 (math-add (math-mul a (nth 1 b))
1404 (math-mul a (nth 2 b))))
1405 (and (eq (car-safe b) '-)
1406 (Math-numberp a)
1407 (or (Math-numberp (nth 1 b))
1408 (Math-numberp (nth 2 b)))
1409 (math-sub (math-mul a (nth 1 b))
1410 (math-mul a (nth 2 b))))
1411 (and (eq (car-safe b) '*)
1412 (Math-numberp (nth 1 b))
1413 (not (Math-numberp a))
1414 (math-mul (nth 1 b) (math-mul a (nth 2 b))))
1415 (and (eq (car-safe a) 'calcFunc-idn)
1416 (= (length a) 2)
1417 (or (and (eq (car-safe b) 'calcFunc-idn)
1418 (= (length b) 2)
1419 (list 'calcFunc-idn (math-mul (nth 1 a) (nth 1 b))))
1420 (and (math-known-scalarp b)
1421 (list 'calcFunc-idn (math-mul (nth 1 a) b)))
1422 (and (math-known-matrixp b)
1423 (math-mul (nth 1 a) b))))
1424 (and (eq (car-safe b) 'calcFunc-idn)
1425 (= (length b) 2)
1426 (or (and (math-known-scalarp a)
1427 (list 'calcFunc-idn (math-mul a (nth 1 b))))
1428 (and (math-known-matrixp a)
1429 (math-mul a (nth 1 b)))))
1430 (and (math-looks-negp b)
1431 (math-mul (math-neg a) (math-neg b)))
1432 (and (eq (car-safe b) '-)
1433 (math-looks-negp a)
1434 (math-mul (math-neg a) (math-neg b)))
1435 (cond
1436 ((eq (car-safe b) '*)
1437 (let ((temp (math-combine-prod a (nth 1 b) nil nil t)))
1438 (and temp
1439 (math-mul temp (nth 2 b)))))
1441 (math-combine-prod a b nil nil nil)))
1442 (and (equal a '(var nan var-nan))
1444 (and (equal b '(var nan var-nan))
1446 (and (equal a '(var uinf var-uinf))
1448 (and (equal b '(var uinf var-uinf))
1450 (and (equal b '(var inf var-inf))
1451 (let ((s1 (math-possible-signs a)))
1452 (cond ((eq s1 4)
1454 ((eq s1 6)
1455 '(intv 3 0 (var inf var-inf)))
1456 ((eq s1 1)
1457 (math-neg b))
1458 ((eq s1 3)
1459 '(intv 3 (neg (var inf var-inf)) 0))
1460 ((and (eq (car a) 'intv) (math-intv-constp a))
1461 '(intv 3 (neg (var inf var-inf)) (var inf var-inf)))
1462 ((and (eq (car a) 'cplx)
1463 (math-zerop (nth 1 a)))
1464 (list '* (list 'cplx 0 (calcFunc-sign (nth 2 a))) b))
1465 ((eq (car a) 'polar)
1466 (list '* (list 'polar 1 (nth 2 a)) b)))))
1467 (and (equal a '(var inf var-inf))
1468 (math-mul b a))
1469 (list '* a b)))
1472 (defun calcFunc-div (a &rest rest)
1473 (while rest
1474 (setq a (list '/ a (car rest))
1475 rest (cdr rest)))
1476 (math-normalize a))
1478 (defun math-div-objects-fancy (a b)
1479 (cond ((and (Math-numberp a) (Math-numberp b))
1480 (math-normalize
1481 (cond ((math-want-polar a b)
1482 (let ((a (math-polar a))
1483 (b (math-polar b)))
1484 (list 'polar
1485 (math-div (nth 1 a) (nth 1 b))
1486 (math-fix-circular (math-sub (nth 2 a)
1487 (nth 2 b))))))
1488 ((Math-realp b)
1489 (setq a (math-complex a))
1490 (list 'cplx (math-div (nth 1 a) b)
1491 (math-div (nth 2 a) b)))
1493 (setq a (math-complex a)
1494 b (math-complex b))
1495 (math-div
1496 (list 'cplx
1497 (math-add (math-mul (nth 1 a) (nth 1 b))
1498 (math-mul (nth 2 a) (nth 2 b)))
1499 (math-sub (math-mul (nth 2 a) (nth 1 b))
1500 (math-mul (nth 1 a) (nth 2 b))))
1501 (math-add (math-sqr (nth 1 b))
1502 (math-sqr (nth 2 b))))))))
1503 ((math-matrixp b)
1504 (if (math-square-matrixp b)
1505 (let ((n1 (length b)))
1506 (if (Math-vectorp a)
1507 (if (math-matrixp a)
1508 (if (= (length a) n1)
1509 (math-lud-solve (math-matrix-lud b) a b)
1510 (if (= (length (nth 1 a)) n1)
1511 (math-transpose
1512 (math-lud-solve (math-matrix-lud
1513 (math-transpose b))
1514 (math-transpose a) b))
1515 (math-dimension-error)))
1516 (if (= (length a) n1)
1517 (math-mat-col (math-lud-solve (math-matrix-lud b)
1518 (math-col-matrix a) b)
1520 (math-dimension-error)))
1521 (if (Math-equal-int a 1)
1522 (calcFunc-inv b)
1523 (math-mul a (calcFunc-inv b)))))
1524 (math-reject-arg b 'square-matrixp)))
1525 ((and (Math-vectorp a) (Math-objectp b))
1526 (math-map-vec-2 'math-div a b))
1527 ((eq (car-safe a) 'sdev)
1528 (if (eq (car-safe b) 'sdev)
1529 (let ((x (math-div (nth 1 a) (nth 1 b))))
1530 (math-make-sdev x
1531 (math-div (math-hypot (nth 2 a)
1532 (math-mul (nth 2 b) x))
1533 (nth 1 b))))
1534 (if (or (Math-scalarp b)
1535 (not (Math-objvecp b)))
1536 (math-make-sdev (math-div (nth 1 a) b) (math-div (nth 2 a) b))
1537 (math-reject-arg 'realp b))))
1538 ((and (eq (car-safe b) 'sdev)
1539 (or (Math-scalarp a)
1540 (not (Math-objvecp a))))
1541 (let ((x (math-div a (nth 1 b))))
1542 (math-make-sdev x
1543 (math-div (math-mul (nth 2 b) x) (nth 1 b)))))
1544 ((and (eq (car-safe a) 'intv) (Math-anglep b))
1545 (if (Math-negp b)
1546 (math-neg (math-div a (math-neg b)))
1547 (math-make-intv (nth 1 a)
1548 (math-div (nth 2 a) b)
1549 (math-div (nth 3 a) b))))
1550 ((and (eq (car-safe b) 'intv) (Math-anglep a))
1551 (if (or (Math-posp (nth 2 b))
1552 (and (Math-zerop (nth 2 b)) (or (memq (nth 1 b) '(0 1))
1553 calc-infinite-mode)))
1554 (if (Math-negp a)
1555 (math-neg (math-div (math-neg a) b))
1556 (let ((calc-infinite-mode 1))
1557 (math-make-intv (aref [0 2 1 3] (nth 1 b))
1558 (math-div a (nth 3 b))
1559 (math-div a (nth 2 b)))))
1560 (if (or (Math-negp (nth 3 b))
1561 (and (Math-zerop (nth 3 b)) (or (memq (nth 1 b) '(0 2))
1562 calc-infinite-mode)))
1563 (math-neg (math-div a (math-neg b)))
1564 (if calc-infinite-mode
1565 '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
1566 (math-reject-arg b "*Division by zero")))))
1567 ((and (eq (car-safe a) 'intv) (math-intv-constp a)
1568 (eq (car-safe b) 'intv) (math-intv-constp b))
1569 (if (or (Math-posp (nth 2 b))
1570 (and (Math-zerop (nth 2 b)) (or (memq (nth 1 b) '(0 1))
1571 calc-infinite-mode)))
1572 (let* ((calc-infinite-mode 1)
1573 (lo (math-div a (nth 2 b)))
1574 (hi (math-div a (nth 3 b))))
1575 (or (eq (car-safe lo) 'intv)
1576 (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0)
1577 lo lo)))
1578 (or (eq (car-safe hi) 'intv)
1579 (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0)
1580 hi hi)))
1581 (math-combine-intervals
1582 (nth 2 lo) (and (or (memq (nth 1 b) '(2 3))
1583 (and (math-infinitep (nth 2 lo))
1584 (not (math-zerop (nth 2 b)))))
1585 (memq (nth 1 lo) '(2 3)))
1586 (nth 3 lo) (and (or (memq (nth 1 b) '(2 3))
1587 (and (math-infinitep (nth 3 lo))
1588 (not (math-zerop (nth 2 b)))))
1589 (memq (nth 1 lo) '(1 3)))
1590 (nth 2 hi) (and (or (memq (nth 1 b) '(1 3))
1591 (and (math-infinitep (nth 2 hi))
1592 (not (math-zerop (nth 3 b)))))
1593 (memq (nth 1 hi) '(2 3)))
1594 (nth 3 hi) (and (or (memq (nth 1 b) '(1 3))
1595 (and (math-infinitep (nth 3 hi))
1596 (not (math-zerop (nth 3 b)))))
1597 (memq (nth 1 hi) '(1 3)))))
1598 (if (or (Math-negp (nth 3 b))
1599 (and (Math-zerop (nth 3 b)) (or (memq (nth 1 b) '(0 2))
1600 calc-infinite-mode)))
1601 (math-neg (math-div a (math-neg b)))
1602 (if calc-infinite-mode
1603 '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
1604 (math-reject-arg b "*Division by zero")))))
1605 ((and (eq (car-safe a) 'mod)
1606 (eq (car-safe b) 'mod)
1607 (equal (nth 2 a) (nth 2 b)))
1608 (math-make-mod (math-div-mod (nth 1 a) (nth 1 b) (nth 2 a))
1609 (nth 2 a)))
1610 ((and (eq (car-safe a) 'mod)
1611 (Math-anglep b))
1612 (math-make-mod (math-div-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
1613 ((and (eq (car-safe b) 'mod)
1614 (Math-anglep a))
1615 (math-make-mod (math-div-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
1616 ((eq (car-safe a) 'hms)
1617 (if (eq (car-safe b) 'hms)
1618 (math-with-extra-prec 1
1619 (math-div (math-from-hms a 'deg)
1620 (math-from-hms b 'deg)))
1621 (math-with-extra-prec 2
1622 (math-to-hms (math-div (math-from-hms a 'deg) b) 'deg))))
1623 (t (calc-record-why "*Incompatible arguments for /" a b))))
1625 (defun math-div-by-zero (a b)
1626 (if (math-infinitep a)
1627 (if (or (equal a '(var nan var-nan))
1628 (equal b '(var uinf var-uinf))
1629 (memq calc-infinite-mode '(-1 1)))
1631 '(var uinf var-uinf))
1632 (if calc-infinite-mode
1633 (if (math-zerop a)
1634 '(var nan var-nan)
1635 (if (eq calc-infinite-mode 1)
1636 (math-mul a '(var inf var-inf))
1637 (if (eq calc-infinite-mode -1)
1638 (math-mul a '(neg (var inf var-inf)))
1639 (if (eq (car-safe a) 'intv)
1640 '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
1641 '(var uinf var-uinf)))))
1642 (math-reject-arg a "*Division by zero"))))
1644 (defun math-div-zero (a b)
1645 (if (math-known-matrixp b)
1646 (if (math-vectorp b)
1647 (math-map-vec-2 'math-div a b)
1648 (math-mimic-ident 0 b))
1649 (if (equal b '(var nan var-nan))
1651 (if (and (eq (car-safe b) 'intv) (math-intv-constp b)
1652 (not (math-posp b)) (not (math-negp b)))
1653 (if calc-infinite-mode
1654 (list 'intv 3
1655 (if (and (math-zerop (nth 2 b))
1656 (memq calc-infinite-mode '(1 -1)))
1657 (nth 2 b) '(neg (var inf var-inf)))
1658 (if (and (math-zerop (nth 3 b))
1659 (memq calc-infinite-mode '(1 -1)))
1660 (nth 3 b) '(var inf var-inf)))
1661 (math-reject-arg b "*Division by zero"))
1662 a))))
1664 ;; For math-div-symb-fancy
1665 (defvar math-trig-inverses
1666 '((calcFunc-sin . calcFunc-csc)
1667 (calcFunc-cos . calcFunc-sec)
1668 (calcFunc-tan . calcFunc-cot)
1669 (calcFunc-sec . calcFunc-cos)
1670 (calcFunc-csc . calcFunc-sin)
1671 (calcFunc-cot . calcFunc-tan)
1672 (calcFunc-sinh . calcFunc-csch)
1673 (calcFunc-cosh . calcFunc-sech)
1674 (calcFunc-tanh . calcFunc-coth)
1675 (calcFunc-sech . calcFunc-cosh)
1676 (calcFunc-csch . calcFunc-sinh)
1677 (calcFunc-coth . calcFunc-tanh)))
1679 (defvar math-div-trig)
1680 (defvar math-div-non-trig)
1682 (defun math-div-new-trig (tr)
1683 (if math-div-trig
1684 (setq math-div-trig
1685 (list '* tr math-div-trig))
1686 (setq math-div-trig tr)))
1688 (defun math-div-new-non-trig (ntr)
1689 (if math-div-non-trig
1690 (setq math-div-non-trig
1691 (list '* ntr math-div-non-trig))
1692 (setq math-div-non-trig ntr)))
1694 (defun math-div-isolate-trig (expr)
1695 (if (eq (car-safe expr) '*)
1696 (progn
1697 (math-div-isolate-trig-term (nth 1 expr))
1698 (math-div-isolate-trig (nth 2 expr)))
1699 (math-div-isolate-trig-term expr)))
1701 (defun math-div-isolate-trig-term (term)
1702 (let ((fn (assoc (car-safe term) math-trig-inverses)))
1703 (if fn
1704 (math-div-new-trig
1705 (cons (cdr fn) (cdr term)))
1706 (math-div-new-non-trig term))))
1708 (defun math-div-symb-fancy (a b)
1709 (or (and math-simplify-only
1710 (not (equal a math-simplify-only))
1711 (list '/ a b))
1712 (and (Math-equal-int b 1) a)
1713 (and (Math-equal-int b -1) (math-neg a))
1714 (and (Math-vectorp a) (math-known-scalarp b)
1715 (math-map-vec-2 'math-div a b))
1716 (and (eq (car-safe b) '^)
1717 (or (Math-looks-negp (nth 2 b)) (Math-equal-int a 1))
1718 (math-mul a (math-normalize
1719 (list '^ (nth 1 b) (math-neg (nth 2 b))))))
1720 (and (eq (car-safe a) 'neg)
1721 (math-neg (math-div (nth 1 a) b)))
1722 (and (eq (car-safe b) 'neg)
1723 (math-neg (math-div a (nth 1 b))))
1724 (and (eq (car-safe a) '/)
1725 (math-div (nth 1 a) (math-mul (nth 2 a) b)))
1726 (and (eq (car-safe b) '/)
1727 (or (math-known-scalarp (nth 1 b) t)
1728 (math-known-scalarp (nth 2 b) t))
1729 (math-div (math-mul a (nth 2 b)) (nth 1 b)))
1730 (and (eq (car-safe b) 'frac)
1731 (math-mul (math-make-frac (nth 2 b) (nth 1 b)) a))
1732 (and (eq (car-safe a) '+)
1733 (or (Math-numberp (nth 1 a))
1734 (Math-numberp (nth 2 a)))
1735 (Math-numberp b)
1736 (math-add (math-div (nth 1 a) b)
1737 (math-div (nth 2 a) b)))
1738 (and (eq (car-safe a) '-)
1739 (or (Math-numberp (nth 1 a))
1740 (Math-numberp (nth 2 a)))
1741 (Math-numberp b)
1742 (math-sub (math-div (nth 1 a) b)
1743 (math-div (nth 2 a) b)))
1744 (and (or (eq (car-safe a) '-)
1745 (math-looks-negp a))
1746 (math-looks-negp b)
1747 (math-div (math-neg a) (math-neg b)))
1748 (and (eq (car-safe b) '-)
1749 (math-looks-negp a)
1750 (math-div (math-neg a) (math-neg b)))
1751 (and (eq (car-safe a) 'calcFunc-idn)
1752 (= (length a) 2)
1753 (or (and (eq (car-safe b) 'calcFunc-idn)
1754 (= (length b) 2)
1755 (list 'calcFunc-idn (math-div (nth 1 a) (nth 1 b))))
1756 (and (math-known-scalarp b)
1757 (list 'calcFunc-idn (math-div (nth 1 a) b)))
1758 (and (math-known-matrixp b)
1759 (math-div (nth 1 a) b))))
1760 (and (eq (car-safe b) 'calcFunc-idn)
1761 (= (length b) 2)
1762 (or (and (math-known-scalarp a)
1763 (list 'calcFunc-idn (math-div a (nth 1 b))))
1764 (and (math-known-matrixp a)
1765 (math-div a (nth 1 b)))))
1766 (and math-simplifying
1767 (let ((math-div-trig nil)
1768 (math-div-non-trig nil))
1769 (math-div-isolate-trig b)
1770 (if math-div-trig
1771 (if math-div-non-trig
1772 (math-div (math-mul a math-div-trig) math-div-non-trig)
1773 (math-mul a math-div-trig))
1774 nil)))
1775 (if (and calc-matrix-mode
1776 (or (math-known-matrixp a) (math-known-matrixp b)))
1777 (math-combine-prod a b nil t nil)
1778 (if (eq (car-safe a) '*)
1779 (if (eq (car-safe b) '*)
1780 (let ((c (math-combine-prod (nth 1 a) (nth 1 b) nil t t)))
1781 (and c
1782 (math-div (math-mul c (nth 2 a)) (nth 2 b))))
1783 (let ((c (math-combine-prod (nth 1 a) b nil t t)))
1784 (and c
1785 (math-mul c (nth 2 a)))))
1786 (if (eq (car-safe b) '*)
1787 (let ((c (math-combine-prod a (nth 1 b) nil t t)))
1788 (and c
1789 (math-div c (nth 2 b))))
1790 (math-combine-prod a b nil t nil))))
1791 (and (math-infinitep a)
1792 (if (math-infinitep b)
1793 '(var nan var-nan)
1794 (if (or (equal a '(var nan var-nan))
1795 (equal a '(var uinf var-uinf)))
1797 (if (equal a '(var inf var-inf))
1798 (if (or (math-posp b)
1799 (and (eq (car-safe b) 'intv)
1800 (math-zerop (nth 2 b))))
1801 (if (and (eq (car-safe b) 'intv)
1802 (not (math-intv-constp b t)))
1803 '(intv 3 0 (var inf var-inf))
1805 (if (or (math-negp b)
1806 (and (eq (car-safe b) 'intv)
1807 (math-zerop (nth 3 b))))
1808 (if (and (eq (car-safe b) 'intv)
1809 (not (math-intv-constp b t)))
1810 '(intv 3 (neg (var inf var-inf)) 0)
1811 (math-neg a))
1812 (if (and (eq (car-safe b) 'intv)
1813 (math-negp (nth 2 b)) (math-posp (nth 3 b)))
1814 '(intv 3 (neg (var inf var-inf))
1815 (var inf var-inf)))))))))
1816 (and (math-infinitep b)
1817 (if (equal b '(var nan var-nan))
1819 (let ((calc-infinite-mode 1))
1820 (math-mul-zero b a))))
1821 (list '/ a b)))
1824 (defun calcFunc-mod (a b)
1825 (math-normalize (list '% a b)))
1827 (defun math-mod-fancy (a b)
1828 (cond ((equal b '(var inf var-inf))
1829 (if (or (math-posp a) (math-zerop a))
1831 (if (math-negp a)
1833 (if (eq (car-safe a) 'intv)
1834 (if (math-negp (nth 2 a))
1835 '(intv 3 0 (var inf var-inf))
1837 (list '% a b)))))
1838 ((and (eq (car-safe a) 'mod) (Math-realp b) (math-posp b))
1839 (math-make-mod (nth 1 a) b))
1840 ((and (eq (car-safe a) 'intv) (math-intv-constp a t) (math-posp b))
1841 (math-mod-intv a b))
1843 (if (Math-anglep a)
1844 (calc-record-why 'anglep b)
1845 (calc-record-why 'anglep a))
1846 (list '% a b))))
1849 (defun calcFunc-pow (a b)
1850 (math-normalize (list '^ a b)))
1852 (defun math-pow-of-zero (a b)
1853 "Raise A to the power of B, where A is a form of zero."
1854 (if (math-floatp b) (setq a (math-float a)))
1855 (cond
1856 ;; 0^0 = 1
1857 ((eq b 0)
1859 ;; 0^0.0, etc., are undetermined
1860 ((Math-zerop b)
1861 (if calc-infinite-mode
1862 '(var nan var-nan)
1863 (math-reject-arg (list '^ a b) "*Indeterminate form")))
1864 ;; 0^positive = 0
1865 ((math-known-posp b)
1867 ;; 0^negative is undefined (let math-div handle it)
1868 ((math-known-negp b)
1869 (math-div 1 a))
1870 ;; 0^infinity is undefined
1871 ((math-infinitep b)
1872 '(var nan var-nan))
1873 ;; Some intervals
1874 ((and (eq (car b) 'intv)
1875 calc-infinite-mode
1876 (math-negp (nth 2 b))
1877 (math-posp (nth 3 b)))
1878 '(intv 3 (neg (var inf var-inf)) (var inf var-inf)))
1879 ;; If none of the above, leave it alone.
1881 (list '^ a b))))
1883 (defun math-pow-zero (a b)
1884 (if (eq (car-safe a) 'mod)
1885 (math-make-mod 1 (nth 2 a))
1886 (if (math-known-matrixp a)
1887 (math-mimic-ident 1 a)
1888 (if (math-infinitep a)
1889 '(var nan var-nan)
1890 (if (and (eq (car a) 'intv) (math-intv-constp a)
1891 (or (and (not (math-posp a)) (not (math-negp a)))
1892 (not (math-intv-constp a t))))
1893 '(intv 3 (neg (var inf var-inf)) (var inf var-inf))
1894 (if (or (math-floatp a) (math-floatp b))
1895 '(float 1 0) 1))))))
1897 (defun math-pow-fancy (a b)
1898 (cond ((and (Math-numberp a) (Math-numberp b))
1899 (or (if (memq (math-quarter-integer b) '(1 2 3))
1900 (let ((sqrt (math-sqrt (if (math-floatp b)
1901 (math-float a) a))))
1902 (and (Math-numberp sqrt)
1903 (math-pow sqrt (math-mul 2 b))))
1904 (and (eq (car b) 'frac)
1905 (integerp (nth 2 b))
1906 (<= (nth 2 b) 10)
1907 (let ((root (math-nth-root a (nth 2 b))))
1908 (and root (math-ipow root (nth 1 b))))))
1909 (and (or (eq a 10) (equal a '(float 1 1)))
1910 (math-num-integerp b)
1911 (calcFunc-scf '(float 1 0) b))
1912 (and calc-symbolic-mode
1913 (list '^ a b))
1914 (math-with-extra-prec 2
1915 (math-exp-raw
1916 (math-float (math-mul b (math-ln-raw (math-float a))))))))
1917 ((or (not (Math-objvecp a))
1918 (not (Math-objectp b)))
1919 (let (temp)
1920 (cond ((and math-simplify-only
1921 (not (equal a math-simplify-only)))
1922 (list '^ a b))
1923 ((and (eq (car-safe a) '*)
1924 (or
1925 (and
1926 (math-known-matrixp (nth 1 a))
1927 (math-known-matrixp (nth 2 a)))
1928 (and
1929 calc-matrix-mode
1930 (not (eq calc-matrix-mode 'scalar))
1931 (and (not (math-known-scalarp (nth 1 a)))
1932 (not (math-known-scalarp (nth 2 a)))))))
1933 (if (and (= b -1)
1934 (math-known-square-matrixp (nth 1 a))
1935 (math-known-square-matrixp (nth 2 a)))
1936 (list '* (list '^ (nth 2 a) -1) (list '^ (nth 1 a) -1))
1937 (list '^ a b)))
1938 ((and (eq (car-safe a) '*)
1939 (or (math-known-num-integerp b)
1940 (math-known-nonnegp (nth 1 a))
1941 (math-known-nonnegp (nth 2 a))))
1942 (math-mul (math-pow (nth 1 a) b)
1943 (math-pow (nth 2 a) b)))
1944 ((and (eq (car-safe a) '/)
1945 (or (math-known-num-integerp b)
1946 (math-known-nonnegp (nth 2 a))))
1947 (math-div (math-pow (nth 1 a) b)
1948 (math-pow (nth 2 a) b)))
1949 ((and (eq (car-safe a) '/)
1950 (math-known-nonnegp (nth 1 a))
1951 (not (math-equal-int (nth 1 a) 1)))
1952 (math-mul (math-pow (nth 1 a) b)
1953 (math-pow (math-div 1 (nth 2 a)) b)))
1954 ((and (eq (car-safe a) '^)
1955 (or (math-known-num-integerp b)
1956 (math-known-nonnegp (nth 1 a))))
1957 (math-pow (nth 1 a) (math-mul (nth 2 a) b)))
1958 ((and (eq (car-safe a) 'calcFunc-sqrt)
1959 (or (math-known-num-integerp b)
1960 (math-known-nonnegp (nth 1 a))))
1961 (math-pow (nth 1 a) (math-div b 2)))
1962 ((and (eq (car-safe a) '^)
1963 (math-known-evenp (nth 2 a))
1964 (memq (math-quarter-integer b) '(1 2 3))
1965 (math-known-realp (nth 1 a)))
1966 (math-abs (math-pow (nth 1 a) (math-mul (nth 2 a) b))))
1967 ((and (math-looks-negp a)
1968 (math-known-integerp b)
1969 (setq temp (or (and (math-known-evenp b)
1970 (math-pow (math-neg a) b))
1971 (and (math-known-oddp b)
1972 (math-neg (math-pow (math-neg a)
1973 b))))))
1974 temp)
1975 ((and (eq (car-safe a) 'calcFunc-abs)
1976 (math-known-realp (nth 1 a))
1977 (math-known-evenp b))
1978 (math-pow (nth 1 a) b))
1979 ((math-infinitep a)
1980 (cond ((equal a '(var nan var-nan))
1982 ((eq (car a) 'neg)
1983 (math-mul (math-pow -1 b) (math-pow (nth 1 a) b)))
1984 ((math-posp b)
1986 ((math-negp b)
1987 (if (math-floatp b) '(float 0 0) 0))
1988 ((and (eq (car-safe b) 'intv)
1989 (math-intv-constp b))
1990 '(intv 3 0 (var inf var-inf)))
1992 '(var nan var-nan))))
1993 ((math-infinitep b)
1994 (let (scale)
1995 (cond ((math-negp b)
1996 (math-pow (math-div 1 a) (math-neg b)))
1997 ((not (math-posp b))
1998 '(var nan var-nan))
1999 ((math-equal-int (setq scale (calcFunc-abssqr a)) 1)
2000 '(var nan var-nan))
2001 ((Math-lessp scale 1)
2002 (if (math-floatp a) '(float 0 0) 0))
2003 ((Math-lessp 1 a)
2005 ((Math-lessp a -1)
2006 '(var uinf var-uinf))
2007 ((and (eq (car a) 'intv)
2008 (math-intv-constp a))
2009 (if (Math-lessp -1 a)
2010 (if (math-equal-int (nth 3 a) 1)
2011 '(intv 3 0 1)
2012 '(intv 3 0 (var inf var-inf)))
2013 '(intv 3 (neg (var inf var-inf))
2014 (var inf var-inf))))
2015 (t (list '^ a b)))))
2016 ((and (eq (car-safe a) 'calcFunc-idn)
2017 (= (length a) 2)
2018 (math-known-num-integerp b))
2019 (list 'calcFunc-idn (math-pow (nth 1 a) b)))
2020 (t (if (Math-objectp a)
2021 (calc-record-why 'objectp b)
2022 (calc-record-why 'objectp a))
2023 (list '^ a b)))))
2024 ((and (eq (car-safe a) 'sdev) (eq (car-safe b) 'sdev))
2025 (if (and (math-constp a) (math-constp b))
2026 (math-with-extra-prec 2
2027 (let* ((ln (math-ln-raw (math-float (nth 1 a))))
2028 (pow (math-exp-raw
2029 (math-float (math-mul (nth 1 b) ln)))))
2030 (math-make-sdev
2032 (math-mul
2034 (math-hypot (math-mul (nth 2 a)
2035 (math-div (nth 1 b) (nth 1 a)))
2036 (math-mul (nth 2 b) ln))))))
2037 (let ((pow (math-pow (nth 1 a) (nth 1 b))))
2038 (math-make-sdev
2040 (math-mul pow
2041 (math-hypot (math-mul (nth 2 a)
2042 (math-div (nth 1 b) (nth 1 a)))
2043 (math-mul (nth 2 b) (calcFunc-ln
2044 (nth 1 a)))))))))
2045 ((and (eq (car-safe a) 'sdev) (Math-numberp b))
2046 (if (math-constp a)
2047 (math-with-extra-prec 2
2048 (let ((pow (math-pow (nth 1 a) (math-sub b 1))))
2049 (math-make-sdev (math-mul pow (nth 1 a))
2050 (math-mul pow (math-mul (nth 2 a) b)))))
2051 (math-make-sdev (math-pow (nth 1 a) b)
2052 (math-mul (math-pow (nth 1 a) (math-add b -1))
2053 (math-mul (nth 2 a) b)))))
2054 ((and (eq (car-safe b) 'sdev) (Math-numberp a))
2055 (math-with-extra-prec 2
2056 (let* ((ln (math-ln-raw (math-float a)))
2057 (pow (calcFunc-exp (math-mul (nth 1 b) ln))))
2058 (math-make-sdev pow (math-mul pow (math-mul (nth 2 b) ln))))))
2059 ((and (eq (car-safe a) 'intv) (math-intv-constp a)
2060 (Math-realp b)
2061 (or (Math-natnump b)
2062 (Math-posp (nth 2 a))
2063 (and (math-zerop (nth 2 a))
2064 (or (Math-posp b)
2065 (and (Math-integerp b) calc-infinite-mode)))
2066 (Math-negp (nth 3 a))
2067 (and (math-zerop (nth 3 a))
2068 (or (Math-posp b)
2069 (and (Math-integerp b) calc-infinite-mode)))))
2070 (if (math-evenp b)
2071 (setq a (math-abs a)))
2072 (let ((calc-infinite-mode (if (math-zerop (nth 3 a)) -1 1)))
2073 (math-sort-intv (nth 1 a)
2074 (math-pow (nth 2 a) b)
2075 (math-pow (nth 3 a) b))))
2076 ((and (eq (car-safe b) 'intv) (math-intv-constp b)
2077 (Math-realp a) (Math-posp a))
2078 (math-sort-intv (nth 1 b)
2079 (math-pow a (nth 2 b))
2080 (math-pow a (nth 3 b))))
2081 ((and (eq (car-safe a) 'intv) (math-intv-constp a)
2082 (eq (car-safe b) 'intv) (math-intv-constp b)
2083 (or (and (not (Math-negp (nth 2 a)))
2084 (not (Math-negp (nth 2 b))))
2085 (and (Math-posp (nth 2 a))
2086 (not (Math-posp (nth 3 b))))))
2087 (let ((lo (math-pow a (nth 2 b)))
2088 (hi (math-pow a (nth 3 b))))
2089 (or (eq (car-safe lo) 'intv)
2090 (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0) lo lo)))
2091 (or (eq (car-safe hi) 'intv)
2092 (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0) hi hi)))
2093 (math-combine-intervals
2094 (nth 2 lo) (and (or (memq (nth 1 b) '(2 3))
2095 (math-infinitep (nth 2 lo)))
2096 (memq (nth 1 lo) '(2 3)))
2097 (nth 3 lo) (and (or (memq (nth 1 b) '(2 3))
2098 (math-infinitep (nth 3 lo)))
2099 (memq (nth 1 lo) '(1 3)))
2100 (nth 2 hi) (and (or (memq (nth 1 b) '(1 3))
2101 (math-infinitep (nth 2 hi)))
2102 (memq (nth 1 hi) '(2 3)))
2103 (nth 3 hi) (and (or (memq (nth 1 b) '(1 3))
2104 (math-infinitep (nth 3 hi)))
2105 (memq (nth 1 hi) '(1 3))))))
2106 ((and (eq (car-safe a) 'mod) (eq (car-safe b) 'mod)
2107 (equal (nth 2 a) (nth 2 b)))
2108 (math-make-mod (math-pow-mod (nth 1 a) (nth 1 b) (nth 2 a))
2109 (nth 2 a)))
2110 ((and (eq (car-safe a) 'mod) (Math-anglep b))
2111 (math-make-mod (math-pow-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
2112 ((and (eq (car-safe b) 'mod) (Math-anglep a))
2113 (math-make-mod (math-pow-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
2114 ((not (Math-numberp a))
2115 (math-reject-arg a 'numberp))
2117 (math-reject-arg b 'numberp))))
2119 (defun math-quarter-integer (x)
2120 (if (Math-integerp x)
2122 (if (math-negp x)
2123 (progn
2124 (setq x (math-quarter-integer (math-neg x)))
2125 (and x (- 4 x)))
2126 (if (eq (car x) 'frac)
2127 (if (eq (nth 2 x) 2)
2129 (and (eq (nth 2 x) 4)
2130 (progn
2131 (setq x (nth 1 x))
2132 (% (if (consp x) (nth 1 x) x) 4))))
2133 (if (eq (car x) 'float)
2134 (if (>= (nth 2 x) 0)
2136 (if (= (nth 2 x) -1)
2137 (progn
2138 (setq x (nth 1 x))
2139 (and (= (% (if (consp x) (nth 1 x) x) 10) 5) 2))
2140 (if (= (nth 2 x) -2)
2141 (progn
2142 (setq x (nth 1 x)
2143 x (% (if (consp x) (nth 1 x) x) 100))
2144 (if (= x 25) 1
2145 (if (= x 75) 3)))))))))))
2147 ;;; This assumes A < M and M > 0.
2148 (defun math-pow-mod (a b m) ; [R R R R]
2149 (if (and (Math-integerp a) (Math-integerp b) (Math-integerp m))
2150 (if (Math-negp b)
2151 (math-div-mod 1 (math-pow-mod a (Math-integer-neg b) m) m)
2152 (if (eq m 1)
2154 (math-pow-mod-step a b m)))
2155 (math-mod (math-pow a b) m)))
2157 (defun math-pow-mod-step (a n m) ; [I I I I]
2158 (math-working "pow" a)
2159 (let ((val (cond
2160 ((eq n 0) 1)
2161 ((eq n 1) a)
2163 (let ((rest (math-pow-mod-step
2164 (math-imod (math-mul a a) m)
2165 (math-div2 n)
2166 m)))
2167 (if (math-evenp n)
2168 rest
2169 (math-mod (math-mul a rest) m)))))))
2170 (math-working "pow" val)
2171 val))
2174 ;;; Compute the minimum of two real numbers. [R R R] [Public]
2175 (defun math-min (a b)
2176 (if (and (consp a) (eq (car a) 'intv))
2177 (if (and (consp b) (eq (car b) 'intv))
2178 (let ((lo (nth 2 a))
2179 (lom (memq (nth 1 a) '(2 3)))
2180 (hi (nth 3 a))
2181 (him (memq (nth 1 a) '(1 3)))
2182 res)
2183 (if (= (setq res (math-compare (nth 2 b) lo)) -1)
2184 (setq lo (nth 2 b) lom (memq (nth 1 b) '(2 3)))
2185 (if (= res 0)
2186 (setq lom (or lom (memq (nth 1 b) '(2 3))))))
2187 (if (= (setq res (math-compare (nth 3 b) hi)) -1)
2188 (setq hi (nth 3 b) him (memq (nth 1 b) '(1 3)))
2189 (if (= res 0)
2190 (setq him (or him (memq (nth 1 b) '(1 3))))))
2191 (math-make-intv (+ (if lom 2 0) (if him 1 0)) lo hi))
2192 (math-min a (list 'intv 3 b b)))
2193 (if (and (consp b) (eq (car b) 'intv))
2194 (math-min (list 'intv 3 a a) b)
2195 (let ((res (math-compare a b)))
2196 (if (= res 1)
2198 (if (= res 2)
2199 '(var nan var-nan)
2200 a))))))
2202 (defun calcFunc-min (&optional a &rest b)
2203 (if (not a)
2204 '(var inf var-inf)
2205 (if (not (or (Math-anglep a) (eq (car a) 'date)
2206 (and (eq (car a) 'intv) (math-intv-constp a))
2207 (math-infinitep a)))
2208 (math-reject-arg a 'anglep))
2209 (math-min-list a b)))
2211 (defun math-min-list (a b)
2212 (if b
2213 (if (or (Math-anglep (car b)) (eq (car b) 'date)
2214 (and (eq (car (car b)) 'intv) (math-intv-constp (car b)))
2215 (math-infinitep (car b)))
2216 (math-min-list (math-min a (car b)) (cdr b))
2217 (math-reject-arg (car b) 'anglep))
2220 ;;; Compute the maximum of two real numbers. [R R R] [Public]
2221 (defun math-max (a b)
2222 (if (or (and (consp a) (eq (car a) 'intv))
2223 (and (consp b) (eq (car b) 'intv)))
2224 (math-neg (math-min (math-neg a) (math-neg b)))
2225 (let ((res (math-compare a b)))
2226 (if (= res -1)
2228 (if (= res 2)
2229 '(var nan var-nan)
2230 a)))))
2232 (defun calcFunc-max (&optional a &rest b)
2233 (if (not a)
2234 '(neg (var inf var-inf))
2235 (if (not (or (Math-anglep a) (eq (car a) 'date)
2236 (and (eq (car a) 'intv) (math-intv-constp a))
2237 (math-infinitep a)))
2238 (math-reject-arg a 'anglep))
2239 (math-max-list a b)))
2241 (defun math-max-list (a b)
2242 (if b
2243 (if (or (Math-anglep (car b)) (eq (car b) 'date)
2244 (and (eq (car (car b)) 'intv) (math-intv-constp (car b)))
2245 (math-infinitep (car b)))
2246 (math-max-list (math-max a (car b)) (cdr b))
2247 (math-reject-arg (car b) 'anglep))
2251 ;;; Compute the absolute value of A. [O O; r r] [Public]
2252 (defun math-abs (a)
2253 (cond ((Math-negp a)
2254 (math-neg a))
2255 ((Math-anglep a)
2257 ((eq (car a) 'cplx)
2258 (math-hypot (nth 1 a) (nth 2 a)))
2259 ((eq (car a) 'polar)
2260 (nth 1 a))
2261 ((eq (car a) 'vec)
2262 (if (cdr (cdr (cdr a)))
2263 (math-sqrt (calcFunc-abssqr a))
2264 (if (cdr (cdr a))
2265 (math-hypot (nth 1 a) (nth 2 a))
2266 (if (cdr a)
2267 (math-abs (nth 1 a))
2268 a))))
2269 ((eq (car a) 'sdev)
2270 (list 'sdev (math-abs (nth 1 a)) (nth 2 a)))
2271 ((and (eq (car a) 'intv) (math-intv-constp a))
2272 (if (Math-posp a)
2274 (let* ((nlo (math-neg (nth 2 a)))
2275 (res (math-compare nlo (nth 3 a))))
2276 (cond ((= res 1)
2277 (math-make-intv (if (memq (nth 1 a) '(0 1)) 2 3) 0 nlo))
2278 ((= res 0)
2279 (math-make-intv (if (eq (nth 1 a) 0) 2 3) 0 nlo))
2281 (math-make-intv (if (memq (nth 1 a) '(0 2)) 2 3)
2282 0 (nth 3 a)))))))
2283 ((math-looks-negp a)
2284 (list 'calcFunc-abs (math-neg a)))
2285 ((let ((signs (math-possible-signs a)))
2286 (or (and (memq signs '(2 4 6)) a)
2287 (and (memq signs '(1 3)) (math-neg a)))))
2288 ((let ((inf (math-infinitep a)))
2289 (and inf
2290 (if (equal inf '(var nan var-nan))
2292 '(var inf var-inf)))))
2293 (t (calc-record-why 'numvecp a)
2294 (list 'calcFunc-abs a))))
2296 (defalias 'calcFunc-abs 'math-abs)
2298 (defun math-float-fancy (a)
2299 (cond ((eq (car a) 'intv)
2300 (cons (car a) (cons (nth 1 a) (mapcar 'math-float (nthcdr 2 a)))))
2301 ((and (memq (car a) '(* /))
2302 (math-numberp (nth 1 a)))
2303 (list (car a) (math-float (nth 1 a))
2304 (list 'calcFunc-float (nth 2 a))))
2305 ((and (eq (car a) '/)
2306 (eq (car (nth 1 a)) '*)
2307 (math-numberp (nth 1 (nth 1 a))))
2308 (list '* (math-float (nth 1 (nth 1 a)))
2309 (list 'calcFunc-float (list '/ (nth 2 (nth 1 a)) (nth 2 a)))))
2310 ((math-infinitep a) a)
2311 ((eq (car a) 'calcFunc-float) a)
2312 ((let ((func (assq (car a) '((calcFunc-floor . calcFunc-ffloor)
2313 (calcFunc-ceil . calcFunc-fceil)
2314 (calcFunc-trunc . calcFunc-ftrunc)
2315 (calcFunc-round . calcFunc-fround)
2316 (calcFunc-rounde . calcFunc-frounde)
2317 (calcFunc-roundu . calcFunc-froundu)))))
2318 (and func (cons (cdr func) (cdr a)))))
2319 (t (math-reject-arg a 'objectp))))
2321 (defalias 'calcFunc-float 'math-float)
2323 ;; The variable math-trunc-prec is local to math-trunc in calc-misc.el,
2324 ;; but used by math-trunc-fancy which is called by math-trunc.
2325 (defvar math-trunc-prec)
2327 (defun math-trunc-fancy (a)
2328 (cond ((eq (car a) 'frac) (math-quotient (nth 1 a) (nth 2 a)))
2329 ((eq (car a) 'cplx) (math-trunc (nth 1 a)))
2330 ((eq (car a) 'polar) (math-trunc (math-complex a)))
2331 ((eq (car a) 'hms) (list 'hms (nth 1 a) 0 0))
2332 ((eq (car a) 'date) (list 'date (math-trunc (nth 1 a))))
2333 ((eq (car a) 'mod)
2334 (if (math-messy-integerp (nth 2 a))
2335 (math-trunc (math-make-mod (nth 1 a) (math-trunc (nth 2 a))))
2336 (math-make-mod (math-trunc (nth 1 a)) (nth 2 a))))
2337 ((eq (car a) 'intv)
2338 (math-make-intv (+ (if (and (equal (nth 2 a) '(neg (var inf var-inf)))
2339 (memq (nth 1 a) '(0 1)))
2340 0 2)
2341 (if (and (equal (nth 3 a) '(var inf var-inf))
2342 (memq (nth 1 a) '(0 2)))
2343 0 1))
2344 (if (and (Math-negp (nth 2 a))
2345 (Math-num-integerp (nth 2 a))
2346 (memq (nth 1 a) '(0 1)))
2347 (math-add (math-trunc (nth 2 a)) 1)
2348 (math-trunc (nth 2 a)))
2349 (if (and (Math-posp (nth 3 a))
2350 (Math-num-integerp (nth 3 a))
2351 (memq (nth 1 a) '(0 2)))
2352 (math-add (math-trunc (nth 3 a)) -1)
2353 (math-trunc (nth 3 a)))))
2354 ((math-provably-integerp a) a)
2355 ((Math-vectorp a)
2356 (math-map-vec (function (lambda (x) (math-trunc x math-trunc-prec))) a))
2357 ((math-infinitep a)
2358 (if (or (math-posp a) (math-negp a))
2360 '(var nan var-nan)))
2361 ((math-to-integer a))
2362 (t (math-reject-arg a 'numberp))))
2364 (defun math-trunc-special (a prec)
2365 (if (Math-messy-integerp prec)
2366 (setq prec (math-trunc prec)))
2367 (or (integerp prec)
2368 (math-reject-arg prec 'fixnump))
2369 (if (and (<= prec 0)
2370 (math-provably-integerp a))
2372 (calcFunc-scf (math-trunc (let ((calc-prefer-frac t))
2373 (calcFunc-scf a prec)))
2374 (- prec))))
2376 (defun math-to-integer (a)
2377 (let ((func (assq (car-safe a) '((calcFunc-ffloor . calcFunc-floor)
2378 (calcFunc-fceil . calcFunc-ceil)
2379 (calcFunc-ftrunc . calcFunc-trunc)
2380 (calcFunc-fround . calcFunc-round)
2381 (calcFunc-frounde . calcFunc-rounde)
2382 (calcFunc-froundu . calcFunc-roundu)))))
2383 (and func (= (length a) 2)
2384 (cons (cdr func) (cdr a)))))
2386 (defun calcFunc-ftrunc (a &optional prec)
2387 (if (and (Math-messy-integerp a)
2388 (or (not prec) (and (integerp prec)
2389 (<= prec 0))))
2391 (math-float (math-trunc a prec))))
2393 ;; The variable math-floor-prec is local to math-floor in calc-misc.el,
2394 ;; but used by math-floor-fancy which is called by math-floor.
2395 (defvar math-floor-prec)
2397 (defun math-floor-fancy (a)
2398 (cond ((math-provably-integerp a) a)
2399 ((eq (car a) 'hms)
2400 (if (or (math-posp a)
2401 (and (math-zerop (nth 2 a))
2402 (math-zerop (nth 3 a))))
2403 (math-trunc a)
2404 (math-add (math-trunc a) -1)))
2405 ((eq (car a) 'date) (list 'date (math-floor (nth 1 a))))
2406 ((eq (car a) 'intv)
2407 (math-make-intv (+ (if (and (equal (nth 2 a) '(neg (var inf var-inf)))
2408 (memq (nth 1 a) '(0 1)))
2409 0 2)
2410 (if (and (equal (nth 3 a) '(var inf var-inf))
2411 (memq (nth 1 a) '(0 2)))
2412 0 1))
2413 (math-floor (nth 2 a))
2414 (if (and (Math-num-integerp (nth 3 a))
2415 (memq (nth 1 a) '(0 2)))
2416 (math-add (math-floor (nth 3 a)) -1)
2417 (math-floor (nth 3 a)))))
2418 ((Math-vectorp a)
2419 (math-map-vec (function (lambda (x) (math-floor x math-floor-prec))) a))
2420 ((math-infinitep a)
2421 (if (or (math-posp a) (math-negp a))
2423 '(var nan var-nan)))
2424 ((math-to-integer a))
2425 (t (math-reject-arg a 'anglep))))
2427 (defun math-floor-special (a prec)
2428 (if (Math-messy-integerp prec)
2429 (setq prec (math-trunc prec)))
2430 (or (integerp prec)
2431 (math-reject-arg prec 'fixnump))
2432 (if (and (<= prec 0)
2433 (math-provably-integerp a))
2435 (calcFunc-scf (math-floor (let ((calc-prefer-frac t))
2436 (calcFunc-scf a prec)))
2437 (- prec))))
2439 (defun calcFunc-ffloor (a &optional prec)
2440 (if (and (Math-messy-integerp a)
2441 (or (not prec) (and (integerp prec)
2442 (<= prec 0))))
2444 (math-float (math-floor a prec))))
2446 ;;; Coerce A to be an integer (by truncation toward plus infinity). [I N]
2447 (defun math-ceiling (a &optional prec) ; [Public]
2448 (cond (prec
2449 (if (Math-messy-integerp prec)
2450 (setq prec (math-trunc prec)))
2451 (or (integerp prec)
2452 (math-reject-arg prec 'fixnump))
2453 (if (and (<= prec 0)
2454 (math-provably-integerp a))
2456 (calcFunc-scf (math-ceiling (let ((calc-prefer-frac t))
2457 (calcFunc-scf a prec)))
2458 (- prec))))
2459 ((Math-integerp a) a)
2460 ((Math-messy-integerp a) (math-trunc a))
2461 ((Math-realp a)
2462 (if (Math-posp a)
2463 (math-add (math-trunc a) 1)
2464 (math-trunc a)))
2465 ((math-provably-integerp a) a)
2466 ((eq (car a) 'hms)
2467 (if (or (math-negp a)
2468 (and (math-zerop (nth 2 a))
2469 (math-zerop (nth 3 a))))
2470 (math-trunc a)
2471 (math-add (math-trunc a) 1)))
2472 ((eq (car a) 'date) (list 'date (math-ceiling (nth 1 a))))
2473 ((eq (car a) 'intv)
2474 (math-make-intv (+ (if (and (equal (nth 2 a) '(neg (var inf var-inf)))
2475 (memq (nth 1 a) '(0 1)))
2476 0 2)
2477 (if (and (equal (nth 3 a) '(var inf var-inf))
2478 (memq (nth 1 a) '(0 2)))
2479 0 1))
2480 (if (and (Math-num-integerp (nth 2 a))
2481 (memq (nth 1 a) '(0 1)))
2482 (math-add (math-floor (nth 2 a)) 1)
2483 (math-ceiling (nth 2 a)))
2484 (math-ceiling (nth 3 a))))
2485 ((Math-vectorp a)
2486 (math-map-vec (function (lambda (x) (math-ceiling x prec))) a))
2487 ((math-infinitep a)
2488 (if (or (math-posp a) (math-negp a))
2490 '(var nan var-nan)))
2491 ((math-to-integer a))
2492 (t (math-reject-arg a 'anglep))))
2494 (defalias 'calcFunc-ceil 'math-ceiling)
2496 (defun calcFunc-fceil (a &optional prec)
2497 (if (and (Math-messy-integerp a)
2498 (or (not prec) (and (integerp prec)
2499 (<= prec 0))))
2501 (math-float (math-ceiling a prec))))
2503 (defvar math-rounding-mode nil)
2505 ;;; Coerce A to be an integer (by rounding to nearest integer). [I N] [Public]
2506 (defun math-round (a &optional prec)
2507 (cond (prec
2508 (if (Math-messy-integerp prec)
2509 (setq prec (math-trunc prec)))
2510 (or (integerp prec)
2511 (math-reject-arg prec 'fixnump))
2512 (if (and (<= prec 0)
2513 (math-provably-integerp a))
2515 (calcFunc-scf (math-round (let ((calc-prefer-frac t))
2516 (calcFunc-scf a prec)))
2517 (- prec))))
2518 ((Math-anglep a)
2519 (if (Math-num-integerp a)
2520 (math-trunc a)
2521 (if (and (Math-negp a) (not (eq math-rounding-mode 'up)))
2522 (math-neg (math-round (math-neg a)))
2523 (setq a (let ((calc-angle-mode 'deg)) ; in case of HMS forms
2524 (math-add a (if (Math-ratp a)
2525 '(frac 1 2)
2526 '(float 5 -1)))))
2527 (if (and (Math-num-integerp a) (eq math-rounding-mode 'even))
2528 (progn
2529 (setq a (math-floor a))
2530 (or (math-evenp a)
2531 (setq a (math-sub a 1)))
2533 (math-floor a)))))
2534 ((math-provably-integerp a) a)
2535 ((eq (car a) 'date) (list 'date (math-round (nth 1 a))))
2536 ((eq (car a) 'intv)
2537 (math-floor (math-add a '(frac 1 2))))
2538 ((Math-vectorp a)
2539 (math-map-vec (function (lambda (x) (math-round x prec))) a))
2540 ((math-infinitep a)
2541 (if (or (math-posp a) (math-negp a))
2543 '(var nan var-nan)))
2544 ((math-to-integer a))
2545 (t (math-reject-arg a 'anglep))))
2547 (defalias 'calcFunc-round 'math-round)
2549 (defsubst calcFunc-rounde (a &optional prec)
2550 (let ((math-rounding-mode 'even))
2551 (math-round a prec)))
2553 (defsubst calcFunc-roundu (a &optional prec)
2554 (let ((math-rounding-mode 'up))
2555 (math-round a prec)))
2557 (defun calcFunc-fround (a &optional prec)
2558 (if (and (Math-messy-integerp a)
2559 (or (not prec) (and (integerp prec)
2560 (<= prec 0))))
2562 (math-float (math-round a prec))))
2564 (defsubst calcFunc-frounde (a &optional prec)
2565 (let ((math-rounding-mode 'even))
2566 (calcFunc-fround a prec)))
2568 (defsubst calcFunc-froundu (a &optional prec)
2569 (let ((math-rounding-mode 'up))
2570 (calcFunc-fround a prec)))
2572 ;;; Pull floating-point values apart into mantissa and exponent.
2573 (defun calcFunc-mant (x)
2574 (if (Math-realp x)
2575 (if (or (Math-ratp x)
2576 (eq (nth 1 x) 0))
2578 (list 'float (nth 1 x) (- 1 (math-numdigs (nth 1 x)))))
2579 (calc-record-why 'realp x)
2580 (list 'calcFunc-mant x)))
2582 (defun calcFunc-xpon (x)
2583 (if (Math-realp x)
2584 (if (or (Math-ratp x)
2585 (eq (nth 1 x) 0))
2587 (math-normalize (+ (nth 2 x) (1- (math-numdigs (nth 1 x))))))
2588 (calc-record-why 'realp x)
2589 (list 'calcFunc-xpon x)))
2591 (defun calcFunc-scf (x n)
2592 (if (integerp n)
2593 (cond ((eq n 0)
2595 ((Math-integerp x)
2596 (if (> n 0)
2597 (math-scale-int x n)
2598 (math-div x (math-scale-int 1 (- n)))))
2599 ((eq (car x) 'frac)
2600 (if (> n 0)
2601 (math-make-frac (math-scale-int (nth 1 x) n) (nth 2 x))
2602 (math-make-frac (nth 1 x) (math-scale-int (nth 2 x) (- n)))))
2603 ((eq (car x) 'float)
2604 (math-make-float (nth 1 x) (+ (nth 2 x) n)))
2605 ((memq (car x) '(cplx sdev))
2606 (math-normalize
2607 (list (car x)
2608 (calcFunc-scf (nth 1 x) n)
2609 (calcFunc-scf (nth 2 x) n))))
2610 ((memq (car x) '(polar mod))
2611 (math-normalize
2612 (list (car x)
2613 (calcFunc-scf (nth 1 x) n)
2614 (nth 2 x))))
2615 ((eq (car x) 'intv)
2616 (math-normalize
2617 (list (car x)
2618 (nth 1 x)
2619 (calcFunc-scf (nth 2 x) n)
2620 (calcFunc-scf (nth 3 x) n))))
2621 ((eq (car x) 'vec)
2622 (math-map-vec (function (lambda (x) (calcFunc-scf x n))) x))
2623 ((math-infinitep x)
2626 (calc-record-why 'realp x)
2627 (list 'calcFunc-scf x n)))
2628 (if (math-messy-integerp n)
2629 (if (< (nth 2 n) 10)
2630 (calcFunc-scf x (math-trunc n))
2631 (math-overflow n))
2632 (if (math-integerp n)
2633 (math-overflow n)
2634 (calc-record-why 'integerp n)
2635 (list 'calcFunc-scf x n)))))
2638 (defun calcFunc-incr (x &optional step relative-to)
2639 (or step (setq step 1))
2640 (cond ((not (Math-integerp step))
2641 (math-reject-arg step 'integerp))
2642 ((Math-integerp x)
2643 (math-add x step))
2644 ((eq (car x) 'float)
2645 (if (and (math-zerop x)
2646 (eq (car-safe relative-to) 'float))
2647 (math-mul step
2648 (calcFunc-scf relative-to (- 1 calc-internal-prec)))
2649 (math-add-float x (math-make-float
2650 step
2651 (+ (nth 2 x)
2652 (- (math-numdigs (nth 1 x))
2653 calc-internal-prec))))))
2654 ((eq (car x) 'date)
2655 (if (Math-integerp (nth 1 x))
2656 (math-add x step)
2657 (math-add x (list 'hms 0 0 step))))
2659 (math-reject-arg x 'realp))))
2661 (defsubst calcFunc-decr (x &optional step relative-to)
2662 (calcFunc-incr x (math-neg (or step 1)) relative-to))
2664 (defun calcFunc-percent (x)
2665 (if (math-objectp x)
2666 (let ((calc-prefer-frac nil))
2667 (math-div x 100))
2668 (list 'calcFunc-percent x)))
2670 (defun calcFunc-relch (x y)
2671 (if (and (math-objectp x) (math-objectp y))
2672 (math-div (math-sub y x) x)
2673 (list 'calcFunc-relch x y)))
2675 ;;; Compute the absolute value squared of A. [F N] [Public]
2676 (defun calcFunc-abssqr (a)
2677 (cond ((Math-realp a)
2678 (math-mul a a))
2679 ((eq (car a) 'cplx)
2680 (math-add (math-sqr (nth 1 a))
2681 (math-sqr (nth 2 a))))
2682 ((eq (car a) 'polar)
2683 (math-sqr (nth 1 a)))
2684 ((and (memq (car a) '(sdev intv)) (math-constp a))
2685 (math-sqr (math-abs a)))
2686 ((eq (car a) 'vec)
2687 (math-reduce-vec 'math-add (math-map-vec 'calcFunc-abssqr a)))
2688 ((math-known-realp a)
2689 (math-pow a 2))
2690 ((let ((inf (math-infinitep a)))
2691 (and inf
2692 (math-mul (calcFunc-abssqr (math-infinite-dir a inf)) inf))))
2693 (t (calc-record-why 'numvecp a)
2694 (list 'calcFunc-abssqr a))))
2696 (defsubst math-sqr (a)
2697 (math-mul a a))
2699 ;;;; Number theory.
2701 (defun calcFunc-idiv (a b) ; [I I I] [Public]
2702 (cond ((and (Math-natnump a) (Math-natnump b) (not (eq b 0)))
2703 (math-quotient a b))
2704 ((Math-realp a)
2705 (if (Math-realp b)
2706 (let ((calc-prefer-frac t))
2707 (math-floor (math-div a b)))
2708 (math-reject-arg b 'realp)))
2709 ((eq (car-safe a) 'hms)
2710 (if (eq (car-safe b) 'hms)
2711 (let ((calc-prefer-frac t))
2712 (math-floor (math-div a b)))
2713 (math-reject-arg b 'hmsp)))
2714 ((and (or (eq (car-safe a) 'intv) (Math-realp a))
2715 (or (eq (car-safe b) 'intv) (Math-realp b)))
2716 (math-floor (math-div a b)))
2717 ((or (math-infinitep a)
2718 (math-infinitep b))
2719 (math-div a b))
2720 (t (math-reject-arg a 'anglep))))
2723 ;;; Combine two terms being added, if possible.
2724 (defun math-combine-sum (a b nega negb scalar-okay)
2725 (if (and scalar-okay (Math-objvecp a) (Math-objvecp b))
2726 (math-add-or-sub a b nega negb)
2727 (let ((amult 1) (bmult 1))
2728 (and (consp a)
2729 (cond ((and (eq (car a) '*)
2730 (Math-objectp (nth 1 a)))
2731 (setq amult (nth 1 a)
2732 a (nth 2 a)))
2733 ((and (eq (car a) '/)
2734 (Math-objectp (nth 2 a)))
2735 (setq amult (if (Math-integerp (nth 2 a))
2736 (list 'frac 1 (nth 2 a))
2737 (math-div 1 (nth 2 a)))
2738 a (nth 1 a)))
2739 ((eq (car a) 'neg)
2740 (setq amult -1
2741 a (nth 1 a)))))
2742 (and (consp b)
2743 (cond ((and (eq (car b) '*)
2744 (Math-objectp (nth 1 b)))
2745 (setq bmult (nth 1 b)
2746 b (nth 2 b)))
2747 ((and (eq (car b) '/)
2748 (Math-objectp (nth 2 b)))
2749 (setq bmult (if (Math-integerp (nth 2 b))
2750 (list 'frac 1 (nth 2 b))
2751 (math-div 1 (nth 2 b)))
2752 b (nth 1 b)))
2753 ((eq (car b) 'neg)
2754 (setq bmult -1
2755 b (nth 1 b)))))
2756 (and (if math-simplifying
2757 (Math-equal a b)
2758 (equal a b))
2759 (progn
2760 (if nega (setq amult (math-neg amult)))
2761 (if negb (setq bmult (math-neg bmult)))
2762 (setq amult (math-add amult bmult))
2763 (math-mul amult a))))))
2765 (defun math-add-or-sub (a b aneg bneg)
2766 (if aneg (setq a (math-neg a)))
2767 (if bneg (setq b (math-neg b)))
2768 (if (or (Math-vectorp a) (Math-vectorp b))
2769 (math-normalize (list '+ a b))
2770 (math-add a b)))
2772 (defvar math-combine-prod-e '(var e var-e))
2774 ;;; The following is expanded out four ways for speed.
2776 ;; math-unit-prefixes is defined in calc-units.el,
2777 ;; but used here.
2778 (defvar math-unit-prefixes)
2780 (defun math-combine-prod (a b inva invb scalar-okay)
2781 (cond
2782 ((or (and inva (Math-zerop a))
2783 (and invb (Math-zerop b)))
2784 nil)
2785 ((and scalar-okay (Math-objvecp a) (Math-objvecp b))
2786 (setq a (math-mul-or-div a b inva invb))
2787 (and (Math-objvecp a)
2789 ((and (eq (car-safe a) '^)
2790 inva
2791 (math-looks-negp (nth 2 a)))
2792 (math-mul (math-pow (nth 1 a) (math-neg (nth 2 a))) b))
2793 ((and (eq (car-safe b) '^)
2794 invb
2795 (math-looks-negp (nth 2 b)))
2796 (math-mul a (math-pow (nth 1 b) (math-neg (nth 2 b)))))
2797 ((and math-simplifying
2798 (math-combine-prod-trig a b)))
2799 (t (let ((apow 1) (bpow 1))
2800 (and (consp a)
2801 (cond ((and (eq (car a) '^)
2802 (or math-simplifying
2803 (Math-numberp (nth 2 a))))
2804 (setq apow (nth 2 a)
2805 a (nth 1 a)))
2806 ((eq (car a) 'calcFunc-sqrt)
2807 (setq apow '(frac 1 2)
2808 a (nth 1 a)))
2809 ((and (eq (car a) 'calcFunc-exp)
2810 (or math-simplifying
2811 (Math-numberp (nth 1 a))))
2812 (setq apow (nth 1 a)
2813 a math-combine-prod-e))))
2814 (and (consp a) (eq (car a) 'frac)
2815 (Math-lessp (nth 1 a) (nth 2 a))
2816 (setq a (math-div 1 a) apow (math-neg apow)))
2817 (and (consp b)
2818 (cond ((and (eq (car b) '^)
2819 (or math-simplifying
2820 (Math-numberp (nth 2 b))))
2821 (setq bpow (nth 2 b)
2822 b (nth 1 b)))
2823 ((eq (car b) 'calcFunc-sqrt)
2824 (setq bpow '(frac 1 2)
2825 b (nth 1 b)))
2826 ((and (eq (car b) 'calcFunc-exp)
2827 (or math-simplifying
2828 (Math-numberp (nth 1 b))))
2829 (setq bpow (nth 1 b)
2830 b math-combine-prod-e))))
2831 (and (consp b) (eq (car b) 'frac)
2832 (Math-lessp (nth 1 b) (nth 2 b))
2833 (setq b (math-div 1 b) bpow (math-neg bpow)))
2834 (if inva (setq apow (math-neg apow)))
2835 (if invb (setq bpow (math-neg bpow)))
2836 (or (and (if math-simplifying
2837 (math-commutative-equal a b)
2838 (equal a b))
2839 (let ((sumpow (math-add apow bpow)))
2840 (and (or (not (Math-integerp a))
2841 (Math-zerop sumpow)
2842 (eq (eq (car-safe apow) 'frac)
2843 (eq (car-safe bpow) 'frac)))
2844 (progn
2845 (and (math-looks-negp sumpow)
2846 (Math-ratp a) (Math-posp a)
2847 (setq a (math-div 1 a)
2848 sumpow (math-neg sumpow)))
2849 (cond ((equal sumpow '(frac 1 2))
2850 (list 'calcFunc-sqrt a))
2851 ((equal sumpow '(frac -1 2))
2852 (math-div 1 (list 'calcFunc-sqrt a)))
2853 ((and (eq a math-combine-prod-e)
2854 (eq a b))
2855 (list 'calcFunc-exp sumpow))
2857 (condition-case err
2858 (math-pow a sumpow)
2859 (inexact-result (list '^ a sumpow)))))))))
2860 (and math-simplifying-units
2861 math-combining-units
2862 (let* ((ua (math-check-unit-name a))
2864 (and ua
2865 (eq ua (setq ub (math-check-unit-name b)))
2866 (progn
2867 (setq ua (if (eq (nth 1 a) (car ua))
2869 (nth 1 (assq (aref (symbol-name (nth 1 a))
2871 math-unit-prefixes)))
2872 ub (if (eq (nth 1 b) (car ub))
2874 (nth 1 (assq (aref (symbol-name (nth 1 b))
2876 math-unit-prefixes))))
2877 (if (Math-lessp ua ub)
2878 (let (temp)
2879 (setq temp a a b b temp
2880 temp ua ua ub ub temp
2881 temp apow apow bpow bpow temp)))
2882 (math-mul (math-pow (math-div ua ub) apow)
2883 (math-pow b (math-add apow bpow)))))))
2884 (and (equal apow bpow)
2885 (Math-natnump a) (Math-natnump b)
2886 (cond ((equal apow '(frac 1 2))
2887 (list 'calcFunc-sqrt (math-mul a b)))
2888 ((equal apow '(frac -1 2))
2889 (math-div 1 (list 'calcFunc-sqrt (math-mul a b))))
2891 (setq a (math-mul a b))
2892 (condition-case err
2893 (math-pow a apow)
2894 (inexact-result (list '^ a apow)))))))))))
2896 (defun math-combine-prod-trig (a b)
2897 (cond
2898 ((and (eq (car-safe a) 'calcFunc-sin)
2899 (eq (car-safe b) 'calcFunc-csc)
2900 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2902 ((and (eq (car-safe a) 'calcFunc-sin)
2903 (eq (car-safe b) 'calcFunc-sec)
2904 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2905 (cons 'calcFunc-tan (cdr a)))
2906 ((and (eq (car-safe a) 'calcFunc-sin)
2907 (eq (car-safe b) 'calcFunc-cot)
2908 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2909 (cons 'calcFunc-cos (cdr a)))
2910 ((and (eq (car-safe a) 'calcFunc-cos)
2911 (eq (car-safe b) 'calcFunc-sec)
2912 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2914 ((and (eq (car-safe a) 'calcFunc-cos)
2915 (eq (car-safe b) 'calcFunc-csc)
2916 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2917 (cons 'calcFunc-cot (cdr a)))
2918 ((and (eq (car-safe a) 'calcFunc-cos)
2919 (eq (car-safe b) 'calcFunc-tan)
2920 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2921 (cons 'calcFunc-sin (cdr a)))
2922 ((and (eq (car-safe a) 'calcFunc-tan)
2923 (eq (car-safe b) 'calcFunc-cot)
2924 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2926 ((and (eq (car-safe a) 'calcFunc-tan)
2927 (eq (car-safe b) 'calcFunc-csc)
2928 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2929 (cons 'calcFunc-sec (cdr a)))
2930 ((and (eq (car-safe a) 'calcFunc-sec)
2931 (eq (car-safe b) 'calcFunc-cot)
2932 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2933 (cons 'calcFunc-csc (cdr a)))
2934 ((and (eq (car-safe a) 'calcFunc-sinh)
2935 (eq (car-safe b) 'calcFunc-csch)
2936 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2938 ((and (eq (car-safe a) 'calcFunc-sinh)
2939 (eq (car-safe b) 'calcFunc-sech)
2940 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2941 (cons 'calcFunc-tanh (cdr a)))
2942 ((and (eq (car-safe a) 'calcFunc-sinh)
2943 (eq (car-safe b) 'calcFunc-coth)
2944 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2945 (cons 'calcFunc-cosh (cdr a)))
2946 ((and (eq (car-safe a) 'calcFunc-cosh)
2947 (eq (car-safe b) 'calcFunc-sech)
2948 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2950 ((and (eq (car-safe a) 'calcFunc-cosh)
2951 (eq (car-safe b) 'calcFunc-csch)
2952 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2953 (cons 'calcFunc-coth (cdr a)))
2954 ((and (eq (car-safe a) 'calcFunc-cosh)
2955 (eq (car-safe b) 'calcFunc-tanh)
2956 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2957 (cons 'calcFunc-sinh (cdr a)))
2958 ((and (eq (car-safe a) 'calcFunc-tanh)
2959 (eq (car-safe b) 'calcFunc-coth)
2960 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2962 ((and (eq (car-safe a) 'calcFunc-tanh)
2963 (eq (car-safe b) 'calcFunc-csch)
2964 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2965 (cons 'calcFunc-sech (cdr a)))
2966 ((and (eq (car-safe a) 'calcFunc-sech)
2967 (eq (car-safe b) 'calcFunc-coth)
2968 (= 0 (math-simplify (math-sub (cdr a) (cdr b)))))
2969 (cons 'calcFunc-csch (cdr a)))
2971 nil)))
2973 (defun math-mul-or-div (a b ainv binv)
2974 (if (or (Math-vectorp a) (Math-vectorp b))
2975 (math-normalize
2976 (if ainv
2977 (if binv
2978 (list '/ (math-div 1 a) b)
2979 (list '/ b a))
2980 (if binv
2981 (list '/ a b)
2982 (list '* a b))))
2983 (if ainv
2984 (if binv
2985 (math-div (math-div 1 a) b)
2986 (math-div b a))
2987 (if binv
2988 (math-div a b)
2989 (math-mul a b)))))
2991 ;; The variable math-com-bterms is local to math-commutative-equal,
2992 ;; but is used by math-commutative collect, which is called by
2993 ;; math-commutative-equal.
2994 (defvar math-com-bterms)
2996 (defun math-commutative-equal (a b)
2997 (if (memq (car-safe a) '(+ -))
2998 (and (memq (car-safe b) '(+ -))
2999 (let ((math-com-bterms nil) aterms p)
3000 (math-commutative-collect b nil)
3001 (setq aterms math-com-bterms math-com-bterms nil)
3002 (math-commutative-collect a nil)
3003 (and (= (length aterms) (length math-com-bterms))
3004 (progn
3005 (while (and aterms
3006 (progn
3007 (setq p math-com-bterms)
3008 (while (and p (not (equal (car aterms)
3009 (car p))))
3010 (setq p (cdr p)))
3012 (setq math-com-bterms (delq (car p) math-com-bterms)
3013 aterms (cdr aterms)))
3014 (not aterms)))))
3015 (equal a b)))
3017 (defun math-commutative-collect (b neg)
3018 (if (eq (car-safe b) '+)
3019 (progn
3020 (math-commutative-collect (nth 1 b) neg)
3021 (math-commutative-collect (nth 2 b) neg))
3022 (if (eq (car-safe b) '-)
3023 (progn
3024 (math-commutative-collect (nth 1 b) neg)
3025 (math-commutative-collect (nth 2 b) (not neg)))
3026 (setq math-com-bterms (cons (if neg (math-neg b) b) math-com-bterms)))))
3028 (provide 'calc-arith)
3030 ;;; arch-tag: 6c396b5b-14c6-40ed-bb2a-7cc2e8111465
3031 ;;; calc-arith.el ends here