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