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