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