home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume24 / gnucalc / part08 < prev    next >
Encoding:
Text File  |  1991-10-29  |  55.3 KB  |  1,899 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@synaptics.com (David Gillespie)
  3. Subject:  v24i056:  gnucalc - GNU Emacs Calculator, v2.00, Part08/56
  4. Message-ID: <1991Oct29.225927.19993@sparky.imd.sterling.com>
  5. X-Md4-Signature: da4707b63937149a0325ffa6456ffa96
  6. Date: Tue, 29 Oct 1991 22:59:27 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: daveg@synaptics.com (David Gillespie)
  10. Posting-number: Volume 24, Issue 56
  11. Archive-name: gnucalc/part08
  12. Environment: Emacs
  13. Supersedes: gmcalc: Volume 13, Issue 27-45
  14.  
  15. ---- Cut Here and unpack ----
  16. #!/bin/sh
  17. # this is Part.08 (part 8 of a multipart archive)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file calc-alg.el continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 8; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping calc-alg.el'
  35. else
  36. echo 'x - continuing file calc-alg.el'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'calc-alg.el' &&
  38. X           ((eq x 1) (nth 1 expr))
  39. X           ((eq x 2) -1)
  40. X           ((eq x 3) (math-neg (nth 1 expr))))))
  41. X      (and math-integrating
  42. X       (integerp (nth 2 expr))
  43. X       (>= (nth 2 expr) 2)
  44. X       (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-cos)
  45. X            (math-mul (math-pow (nth 1 expr) (- (nth 2 expr) 2))
  46. X                  (math-sub 1
  47. X                    (math-sqr
  48. X                     (list 'calcFunc-sin
  49. X                           (nth 1 (nth 1 expr)))))))
  50. X           (and (eq (car-safe (nth 1 expr)) 'calcFunc-cosh)
  51. X            (math-mul (math-pow (nth 1 expr) (- (nth 2 expr) 2))
  52. X                  (math-add 1
  53. X                    (math-sqr
  54. X                     (list 'calcFunc-sinh
  55. X                           (nth 1 (nth 1 expr)))))))))
  56. X      (and (eq (car-safe (nth 2 expr)) 'frac)
  57. X       (Math-ratp (nth 1 expr))
  58. X       (Math-posp (nth 1 expr))
  59. X       (if (equal (nth 2 expr) '(frac 1 2))
  60. X           (list 'calcFunc-sqrt (nth 1 expr))
  61. X         (let ((flr (math-floor (nth 2 expr))))
  62. X           (and (not (Math-zerop flr))
  63. X            (list '* (list '^ (nth 1 expr) flr)
  64. X              (list '^ (nth 1 expr)
  65. X                (math-sub (nth 2 expr) flr)))))))
  66. X      (and (eq (math-quarter-integer (nth 2 expr)) 2)
  67. X       (let ((temp (math-simplify-sqrt)))
  68. X         (and temp
  69. X          (list '^ temp (math-mul (nth 2 expr) 2))))))
  70. )
  71. X
  72. (math-defsimplify calcFunc-log10
  73. X  (and (eq (car-safe (nth 1 expr)) '^)
  74. X       (math-equal-int (nth 1 (nth 1 expr)) 10)
  75. X       (or math-living-dangerously
  76. X       (math-known-realp (nth 2 (nth 1 expr))))
  77. X       (nth 2 (nth 1 expr)))
  78. )
  79. X
  80. X
  81. X
  82. (defun math-linear-in (expr term &optional always)
  83. X  (if (math-expr-contains expr term)
  84. X      (let* ((calc-prefer-frac t)
  85. X         (p (math-is-polynomial expr term 1)))
  86. X    (and (cdr p)
  87. X         p))
  88. X    (and always (list expr 0)))
  89. )
  90. X
  91. (defun math-multiple-of (expr term)
  92. X  (let ((p (math-linear-in expr term)))
  93. X    (and p
  94. X     (math-zerop (car p))
  95. X     (nth 1 p)))
  96. )
  97. X
  98. (defun math-integer-plus (expr)
  99. X  (cond ((Math-integerp expr)
  100. X     (list 0 expr))
  101. X    ((and (memq (car expr) '(+ -))
  102. X          (Math-integerp (nth 1 expr)))
  103. X     (list (if (eq (car expr) '+) (nth 2 expr) (math-neg (nth 2 expr)))
  104. X           (nth 1 expr)))
  105. X    ((and (memq (car expr) '(+ -))
  106. X          (Math-integerp (nth 2 expr)))
  107. X     (list (nth 1 expr)
  108. X           (if (eq (car expr) '+) (nth 2 expr) (math-neg (nth 2 expr)))))
  109. X    (t nil))   ; not perfect, but it'll do
  110. )
  111. X
  112. (defun math-is-linear (expr &optional always)
  113. X  (let ((offset nil)
  114. X    (coef nil))
  115. X    (if (eq (car-safe expr) '+)
  116. X    (if (Math-objectp (nth 1 expr))
  117. X        (setq offset (nth 1 expr)
  118. X          expr (nth 2 expr))
  119. X      (if (Math-objectp (nth 2 expr))
  120. X          (setq offset (nth 2 expr)
  121. X            expr (nth 1 expr))))
  122. X      (if (eq (car-safe expr) '-)
  123. X      (if (Math-objectp (nth 1 expr))
  124. X          (setq offset (nth 1 expr)
  125. X            expr (math-neg (nth 2 expr)))
  126. X        (if (Math-objectp (nth 2 expr))
  127. X        (setq offset (math-neg (nth 2 expr))
  128. X              expr (nth 1 expr))))))
  129. X    (setq coef (math-is-multiple expr always))
  130. X    (if offset
  131. X    (list offset (or (car coef) 1) (or (nth 1 coef) expr))
  132. X      (if coef
  133. X      (cons 0 coef))))
  134. )
  135. X
  136. (defun math-is-multiple (expr &optional always)
  137. X  (or (if (eq (car-safe expr) '*)
  138. X      (if (Math-objectp (nth 1 expr))
  139. X          (list (nth 1 expr) (nth 2 expr)))
  140. X    (if (eq (car-safe expr) '/)
  141. X        (if (and (Math-objectp (nth 1 expr))
  142. X             (not (math-equal-int (nth 1 expr) 1)))
  143. X        (list (nth 1 expr) (math-div 1 (nth 2 expr)))
  144. X          (if (Math-objectp (nth 2 expr))
  145. X          (list (math-div 1 (nth 2 expr)) (nth 1 expr))
  146. X        (let ((res (math-is-multiple (nth 1 expr))))
  147. X          (if res
  148. X              (list (car res)
  149. X                (math-div (nth 2 (nth 1 expr)) (nth 2 expr)))
  150. X            (setq res (math-is-multiple (nth 2 expr)))
  151. X            (if res
  152. X            (list (math-div 1 (car res))
  153. X                  (math-div (nth 1 expr)
  154. X                    (nth 2 (nth 2 expr)))))))))
  155. X      (if (eq (car-safe expr) 'neg)
  156. X          (list -1 (nth 1 expr)))))
  157. X      (if (Math-objvecp expr)
  158. X      (and (eq always 1)
  159. X           (list expr 1))
  160. X    (and always 
  161. X         (list 1 expr))))
  162. )
  163. X
  164. (defun calcFunc-lin (expr &optional var)
  165. X  (if var
  166. X      (let ((res (math-linear-in expr var t)))
  167. X    (or res (math-reject-arg expr "Linear term expected"))
  168. X    (list 'vec (car res) (nth 1 res) var))
  169. X    (let ((res (math-is-linear expr t)))
  170. X      (or res (math-reject-arg expr "Linear term expected"))
  171. X      (cons 'vec res)))
  172. )
  173. X
  174. (defun calcFunc-linnt (expr &optional var)
  175. X  (if var
  176. X      (let ((res (math-linear-in expr var)))
  177. X    (or res (math-reject-arg expr "Linear term expected"))
  178. X    (list 'vec (car res) (nth 1 res) var))
  179. X    (let ((res (math-is-linear expr)))
  180. X      (or res (math-reject-arg expr "Linear term expected"))
  181. X      (cons 'vec res)))
  182. )
  183. X
  184. (defun calcFunc-islin (expr &optional var)
  185. X  (if (and (Math-objvecp expr) (not var))
  186. X      0
  187. X    (calcFunc-lin expr var)
  188. X    1)
  189. )
  190. X
  191. (defun calcFunc-islinnt (expr &optional var)
  192. X  (if (Math-objvecp expr)
  193. X      0
  194. X    (calcFunc-linnt expr var)
  195. X    1)
  196. )
  197. X
  198. X
  199. X
  200. X
  201. ;;; Simple operations on expressions.
  202. X
  203. ;;; Return number of ocurrences of thing in expr, or nil if none.
  204. (defun math-expr-contains-count (expr thing)
  205. X  (cond ((equal expr thing) 1)
  206. X    ((Math-primp expr) nil)
  207. X    (t
  208. X     (let ((num 0))
  209. X       (while (setq expr (cdr expr))
  210. X         (setq num (+ num (or (math-expr-contains-count
  211. X                   (car expr) thing) 0))))
  212. X       (and (> num 0)
  213. X        num))))
  214. )
  215. X
  216. (defun math-expr-contains (expr thing)
  217. X  (cond ((equal expr thing) 1)
  218. X    ((Math-primp expr) nil)
  219. X    (t
  220. X     (while (and (setq expr (cdr expr))
  221. X             (not (math-expr-contains (car expr) thing))))
  222. X     expr))
  223. )
  224. X
  225. ;;; Return non-nil if any variable of thing occurs in expr.
  226. (defun math-expr-depends (expr thing)
  227. X  (if (Math-primp thing)
  228. X      (and (eq (car-safe thing) 'var)
  229. X       (math-expr-contains expr thing))
  230. X    (while (and (setq thing (cdr thing))
  231. X        (not (math-expr-depends expr (car thing)))))
  232. X    thing)
  233. )
  234. X
  235. ;;; Substitute all occurrences of old for new in expr (non-destructive).
  236. (defun math-expr-subst (expr old new)
  237. X  (math-expr-subst-rec expr)
  238. )
  239. (fset 'calcFunc-subst (symbol-function 'math-expr-subst))
  240. X
  241. (defun math-expr-subst-rec (expr)
  242. X  (cond ((equal expr old) new)
  243. X    ((Math-primp expr) expr)
  244. X    ((memq (car expr) '(calcFunc-deriv
  245. X                calcFunc-tderiv))
  246. X     (if (= (length expr) 2)
  247. X         (if (equal (nth 1 expr) old)
  248. X         (append expr (list new))
  249. X           expr)
  250. X       (list (car expr) (nth 1 expr)
  251. X         (math-expr-subst-rec (nth 2 expr)))))
  252. X    (t
  253. X     (cons (car expr)
  254. X           (mapcar 'math-expr-subst-rec (cdr expr)))))
  255. )
  256. X
  257. ;;; Various measures of the size of an expression.
  258. (defun math-expr-weight (expr)
  259. X  (if (Math-primp expr)
  260. X      1
  261. X    (let ((w 1))
  262. X      (while (setq expr (cdr expr))
  263. X    (setq w (+ w (math-expr-weight (car expr)))))
  264. X      w))
  265. )
  266. X
  267. (defun math-expr-height (expr)
  268. X  (if (Math-primp expr)
  269. X      0
  270. X    (let ((h 0))
  271. X      (while (setq expr (cdr expr))
  272. X    (setq h (max h (math-expr-height (car expr)))))
  273. X      (1+ h)))
  274. )
  275. X
  276. X
  277. X
  278. X
  279. ;;; Polynomial operations (to support the integrator and solve-for).
  280. X
  281. (defun calcFunc-collect (expr base)
  282. X  (let ((p (math-is-polynomial expr base 50 t)))
  283. X    (if (cdr p)
  284. X    (math-normalize   ; fix selection bug
  285. X     (math-build-polynomial-expr p base))
  286. X      expr))
  287. )
  288. X
  289. ;;; If expr is of the form "a + bx + cx^2 + ...", return the list (a b c ...),
  290. ;;; else return nil if not in polynomial form.  If "loose", coefficients
  291. ;;; may contain x, e.g., sin(x) + cos(x) x^2 is a loose polynomial in x.
  292. (defun math-is-polynomial (expr var &optional degree loose)
  293. X  (let* ((math-poly-base-variable (if loose
  294. X                      (if (eq loose 'gen) var '(var XXX XXX))
  295. X                    math-poly-base-variable))
  296. X     (poly (math-is-poly-rec expr math-poly-neg-powers)))
  297. X    (and (or (null degree)
  298. X         (<= (length poly) (1+ degree)))
  299. X     poly))
  300. )
  301. X
  302. (defun math-is-poly-rec (expr negpow)
  303. X  (math-poly-simplify
  304. X   (or (cond ((or (equal expr var)
  305. X          (eq (car-safe expr) '^))
  306. X          (let ((pow 1)
  307. X            (expr expr))
  308. X        (or (equal expr var)
  309. X            (setq pow (nth 2 expr)
  310. X              expr (nth 1 expr)))
  311. X        (or (eq math-poly-mult-powers 1)
  312. X            (setq pow (let ((m (math-is-multiple pow 1)))
  313. X                (and (eq (car-safe (car m)) 'cplx)
  314. X                     (Math-zerop (nth 1 (car m)))
  315. X                     (setq m (list (nth 2 (car m))
  316. X                           (math-mul (nth 1 m)
  317. X                                 '(var i var-i)))))
  318. X                (and (if math-poly-mult-powers
  319. X                     (equal math-poly-mult-powers
  320. X                        (nth 1 m))
  321. X                       (setq math-poly-mult-powers (nth 1 m)))
  322. X                     (or (equal expr var)
  323. X                     (eq math-poly-mult-powers 1))
  324. X                     (car m)))))
  325. X        (if (consp pow)
  326. X            (progn
  327. X              (setq pow (math-to-simple-fraction pow))
  328. X              (and (eq (car-safe pow) 'frac)
  329. X               math-poly-frac-powers
  330. X               (equal expr var)
  331. X               (setq math-poly-frac-powers
  332. X                 (calcFunc-lcm math-poly-frac-powers
  333. X                           (nth 2 pow))))))
  334. X        (or (memq math-poly-frac-powers '(1 nil))
  335. X            (setq pow (math-mul pow math-poly-frac-powers)))
  336. X        (if (integerp pow)
  337. X            (if (and (= pow 1)
  338. X                 (equal expr var))
  339. X            (list 0 1)
  340. X              (if (natnump pow)
  341. X              (let ((p1 (if (equal expr var)
  342. X                    (list 0 1)
  343. X                      (math-is-poly-rec expr nil)))
  344. X                (n pow)
  345. X                (accum (list 1)))
  346. X                (and p1
  347. X                 (or (null degree)
  348. X                     (<= (* (1- (length p1)) n) degree))
  349. X                 (progn
  350. X                   (while (>= n 1)
  351. X                     (setq accum (math-poly-mul accum p1)
  352. X                       n (1- n)))
  353. X                   accum)))
  354. X            (and negpow
  355. X                 (math-is-poly-rec expr nil)
  356. X                 (setq math-poly-neg-powers
  357. X                   (cons (math-pow expr (- pow))
  358. X                     math-poly-neg-powers))
  359. X                 (list (list '^ expr pow))))))))
  360. X         ((Math-objectp expr)
  361. X          (list expr))
  362. X         ((memq (car expr) '(+ -))
  363. X          (let ((p1 (math-is-poly-rec (nth 1 expr) negpow)))
  364. X        (and p1
  365. X             (let ((p2 (math-is-poly-rec (nth 2 expr) negpow)))
  366. X               (and p2
  367. X                (math-poly-mix p1 1 p2
  368. X                       (if (eq (car expr) '+) 1 -1)))))))
  369. X         ((eq (car expr) 'neg)
  370. X          (mapcar 'math-neg (math-is-poly-rec (nth 1 expr) negpow)))
  371. X         ((eq (car expr) '*)
  372. X          (let ((p1 (math-is-poly-rec (nth 1 expr) negpow)))
  373. X        (and p1
  374. X             (let ((p2 (math-is-poly-rec (nth 2 expr) negpow)))
  375. X               (and p2
  376. X                (or (null degree)
  377. X                (<= (- (+ (length p1) (length p2)) 2) degree))
  378. X                (math-poly-mul p1 p2))))))
  379. X         ((eq (car expr) '/)
  380. X          (and (or (not (math-poly-depends (nth 2 expr) var))
  381. X               (and negpow
  382. X                (math-is-poly-rec (nth 2 expr) nil)
  383. X                (setq math-poly-neg-powers
  384. X                  (cons (nth 2 expr) math-poly-neg-powers))))
  385. X           (not (Math-zerop (nth 2 expr)))
  386. X           (let ((p1 (math-is-poly-rec (nth 1 expr) negpow)))
  387. X             (mapcar (function (lambda (x) (math-div x (nth 2 expr))))
  388. X                 p1))))
  389. X         ((and (eq (car expr) 'calcFunc-exp)
  390. X           (equal var '(var e var-e)))
  391. X          (math-is-poly-rec (list '^ var (nth 1 expr)) negpow))
  392. X         ((and (eq (car expr) 'calcFunc-sqrt)
  393. X           math-poly-frac-powers)
  394. X          (math-is-poly-rec (list '^ (nth 1 expr) '(frac 1 2)) negpow))
  395. X         (t nil))
  396. X       (and (or (not (math-poly-depends expr var))
  397. X        loose)
  398. X        (not (eq (car expr) 'vec))
  399. X        (list expr))))
  400. )
  401. X
  402. ;;; Check if expr is a polynomial in var; if so, return its degree.
  403. (defun math-polynomial-p (expr var)
  404. X  (cond ((equal expr var) 1)
  405. X    ((Math-primp expr) 0)
  406. X    ((memq (car expr) '(+ -))
  407. X     (let ((p1 (math-polynomial-p (nth 1 expr) var))
  408. X           p2)
  409. X       (and p1 (setq p2 (math-polynomial-p (nth 2 expr) var))
  410. X        (max p1 p2))))
  411. X    ((eq (car expr) '*)
  412. X     (let ((p1 (math-polynomial-p (nth 1 expr) var))
  413. X           p2)
  414. X       (and p1 (setq p2 (math-polynomial-p (nth 2 expr) var))
  415. X        (+ p1 p2))))
  416. X    ((eq (car expr) 'neg)
  417. X     (math-polynomial-p (nth 1 expr) var))
  418. X    ((and (eq (car expr) '/)
  419. X          (not (math-poly-depends (nth 2 expr) var)))
  420. X     (math-polynomial-p (nth 1 expr) var))
  421. X    ((and (eq (car expr) '^)
  422. X          (natnump (nth 2 expr)))
  423. X     (let ((p1 (math-polynomial-p (nth 1 expr) var)))
  424. X       (and p1 (* p1 (nth 2 expr)))))
  425. X    ((math-poly-depends expr var) nil)
  426. X    (t 0))
  427. )
  428. X
  429. (defun math-poly-depends (expr var)
  430. X  (if math-poly-base-variable
  431. X      (math-expr-contains expr math-poly-base-variable)
  432. X    (math-expr-depends expr var))
  433. )
  434. X
  435. ;;; Find the variable (or sub-expression) which is the base of polynomial expr.
  436. (defun math-polynomial-base (mpb-top-expr &optional mpb-pred)
  437. X  (or mpb-pred
  438. X      (setq mpb-pred (function (lambda (base) (math-polynomial-p
  439. X                           mpb-top-expr base)))))
  440. X  (or (let ((const-ok nil))
  441. X    (math-polynomial-base-rec mpb-top-expr))
  442. X      (let ((const-ok t))
  443. X    (math-polynomial-base-rec mpb-top-expr)))
  444. )
  445. X
  446. (defun math-polynomial-base-rec (mpb-expr)
  447. X  (and (not (Math-objvecp mpb-expr))
  448. X       (or (and (memq (car mpb-expr) '(+ - *))
  449. X        (or (math-polynomial-base-rec (nth 1 mpb-expr))
  450. X            (math-polynomial-base-rec (nth 2 mpb-expr))))
  451. X       (and (memq (car mpb-expr) '(/ neg))
  452. X        (math-polynomial-base-rec (nth 1 mpb-expr)))
  453. X       (and (eq (car mpb-expr) '^)
  454. X        (math-polynomial-base-rec (nth 1 mpb-expr)))
  455. X       (and (eq (car mpb-expr) 'calcFunc-exp)
  456. X        (math-polynomial-base-rec '(var e var-e)))
  457. X       (and (or const-ok (math-expr-contains-vars mpb-expr))
  458. X        (funcall mpb-pred mpb-expr)
  459. X        mpb-expr)))
  460. )
  461. X
  462. ;;; Return non-nil if expr refers to any variables.
  463. (defun math-expr-contains-vars (expr)
  464. X  (or (eq (car-safe expr) 'var)
  465. X      (and (not (Math-primp expr))
  466. X       (progn
  467. X         (while (and (setq expr (cdr expr))
  468. X             (not (math-expr-contains-vars (car expr)))))
  469. X         expr)))
  470. )
  471. X
  472. ;;; Simplify a polynomial in list form by stripping off high-end zeros.
  473. ;;; This always leaves the constant part, i.e., nil->nil and nonnil->nonnil.
  474. (defun math-poly-simplify (p)
  475. X  (and p
  476. X       (if (Math-zerop (nth (1- (length p)) p))
  477. X       (let ((pp (copy-sequence p)))
  478. X         (while (and (cdr pp)
  479. X             (Math-zerop (nth (1- (length pp)) pp)))
  480. X           (setcdr (nthcdr (- (length pp) 2) pp) nil))
  481. X         pp)
  482. X     p))
  483. )
  484. X
  485. ;;; Compute ac*a + bc*b for polynomials in list form a, b and
  486. ;;; coefficients ac, bc.  Result may be unsimplified.
  487. (defun math-poly-mix (a ac b bc)
  488. X  (and (or a b)
  489. X       (cons (math-add (math-mul (or (car a) 0) ac)
  490. X               (math-mul (or (car b) 0) bc))
  491. X         (math-poly-mix (cdr a) ac (cdr b) bc)))
  492. )
  493. X
  494. (defun math-poly-zerop (a)
  495. X  (or (null a)
  496. X      (and (null (cdr a)) (Math-zerop (car a))))
  497. )
  498. X
  499. ;;; Multiply two polynomials in list form.
  500. (defun math-poly-mul (a b)
  501. X  (and a b
  502. X       (math-poly-mix b (car a)
  503. X              (math-poly-mul (cdr a) (cons 0 b)) 1))
  504. )
  505. X
  506. ;;; Build an expression from a polynomial list.
  507. (defun math-build-polynomial-expr (p var)
  508. X  (if p
  509. X      (if (Math-numberp var)
  510. X      (math-with-extra-prec 1
  511. X        (let* ((rp (reverse p))
  512. X           (accum (car rp)))
  513. X          (while (setq rp (cdr rp))
  514. X        (setq accum (math-add (car rp) (math-mul accum var))))
  515. X          accum))
  516. X    (let* ((rp (reverse p))
  517. X           (n (1- (length rp)))
  518. X           (accum (math-mul (car rp) (math-pow var n)))
  519. X           term)
  520. X      (while (setq rp (cdr rp))
  521. X        (setq n (1- n))
  522. X        (or (math-zerop (car rp))
  523. X        (setq accum (list (if (math-looks-negp (car rp)) '- '+)
  524. X                  accum
  525. X                  (math-mul (if (math-looks-negp (car rp))
  526. X                        (math-neg (car rp))
  527. X                          (car rp))
  528. X                        (math-pow var n))))))
  529. X      accum))
  530. X    0)
  531. )
  532. X
  533. X
  534. (defun math-to-simple-fraction (f)
  535. X  (or (and (eq (car-safe f) 'float)
  536. X       (or (and (>= (nth 2 f) 0)
  537. X            (math-scale-int (nth 1 f) (nth 2 f)))
  538. X           (and (integerp (nth 1 f))
  539. X            (> (nth 1 f) -1000)
  540. X            (< (nth 1 f) 1000)
  541. X            (math-make-frac (nth 1 f)
  542. X                    (math-scale-int 1 (- (nth 2 f)))))))
  543. X      f)
  544. )
  545. X
  546. SHAR_EOF
  547. echo 'File calc-alg.el is complete' &&
  548. chmod 0644 calc-alg.el ||
  549. echo 'restore of calc-alg.el failed'
  550. Wc_c="`wc -c < 'calc-alg.el'`"
  551. test 53736 -eq "$Wc_c" ||
  552.     echo 'calc-alg.el: original size 53736, current size' "$Wc_c"
  553. rm -f _shar_wnt_.tmp
  554. fi
  555. # ============= calc-arith.el ==============
  556. if test -f 'calc-arith.el' -a X"$1" != X"-c"; then
  557.     echo 'x - skipping calc-arith.el (File already exists)'
  558.     rm -f _shar_wnt_.tmp
  559. else
  560. > _shar_wnt_.tmp
  561. echo 'x - extracting calc-arith.el (Text)'
  562. sed 's/^X//' << 'SHAR_EOF' > 'calc-arith.el' &&
  563. ;; Calculator for GNU Emacs, part II [calc-arith.el]
  564. ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  565. ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
  566. X
  567. ;; This file is part of GNU Emacs.
  568. X
  569. ;; GNU Emacs is distributed in the hope that it will be useful,
  570. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  571. ;; accepts responsibility to anyone for the consequences of using it
  572. ;; or for whether it serves any particular purpose or works at all,
  573. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  574. ;; License for full details.
  575. X
  576. ;; Everyone is granted permission to copy, modify and redistribute
  577. ;; GNU Emacs, but only under the conditions described in the
  578. ;; GNU Emacs General Public License.   A copy of this license is
  579. ;; supposed to have been given to you along with GNU Emacs so you
  580. ;; can know your rights and responsibilities.  It should be in a
  581. ;; file named COPYING.  Among other things, the copyright notice
  582. ;; and this notice must be preserved on all copies.
  583. X
  584. X
  585. X
  586. ;; This file is autoloaded from calc-ext.el.
  587. (require 'calc-ext)
  588. X
  589. (require 'calc-macs)
  590. X
  591. (defun calc-Need-calc-arith () nil)
  592. X
  593. X
  594. ;;; Arithmetic.
  595. X
  596. (defun calc-min (arg)
  597. X  (interactive "P")
  598. X  (calc-slow-wrapper
  599. X   (calc-binary-op "min" 'calcFunc-min arg '(var inf var-inf)))
  600. )
  601. X
  602. (defun calc-max (arg)
  603. X  (interactive "P")
  604. X  (calc-slow-wrapper
  605. X   (calc-binary-op "max" 'calcFunc-max arg '(neg (var inf var-inf))))
  606. )
  607. X
  608. (defun calc-abs (arg)
  609. X  (interactive "P")
  610. X  (calc-slow-wrapper
  611. X   (calc-unary-op "abs" 'calcFunc-abs arg))
  612. )
  613. X
  614. X
  615. (defun calc-idiv (arg)
  616. X  (interactive "P")
  617. X  (calc-slow-wrapper
  618. X   (calc-binary-op "\\" 'calcFunc-idiv arg 1))
  619. )
  620. X
  621. X
  622. (defun calc-floor (arg)
  623. X  (interactive "P")
  624. X  (calc-slow-wrapper
  625. X   (if (calc-is-inverse)
  626. X       (if (calc-is-hyperbolic)
  627. X       (calc-unary-op "ceil" 'calcFunc-fceil arg)
  628. X     (calc-unary-op "ceil" 'calcFunc-ceil arg))
  629. X     (if (calc-is-hyperbolic)
  630. X     (calc-unary-op "flor" 'calcFunc-ffloor arg)
  631. X       (calc-unary-op "flor" 'calcFunc-floor arg))))
  632. )
  633. X
  634. (defun calc-ceiling (arg)
  635. X  (interactive "P")
  636. X  (calc-invert-func)
  637. X  (calc-floor arg)
  638. )
  639. X
  640. (defun calc-round (arg)
  641. X  (interactive "P")
  642. X  (calc-slow-wrapper
  643. X   (if (calc-is-inverse)
  644. X       (if (calc-is-hyperbolic)
  645. X       (calc-unary-op "trnc" 'calcFunc-ftrunc arg)
  646. X     (calc-unary-op "trnc" 'calcFunc-trunc arg))
  647. X     (if (calc-is-hyperbolic)
  648. X     (calc-unary-op "rond" 'calcFunc-fround arg)
  649. X       (calc-unary-op "rond" 'calcFunc-round arg))))
  650. )
  651. X
  652. (defun calc-trunc (arg)
  653. X  (interactive "P")
  654. X  (calc-invert-func)
  655. X  (calc-round arg)
  656. )
  657. X
  658. (defun calc-mant-part (arg)
  659. X  (interactive "P")
  660. X  (calc-slow-wrapper
  661. X   (calc-unary-op "mant" 'calcFunc-mant arg))
  662. )
  663. X
  664. (defun calc-xpon-part (arg)
  665. X  (interactive "P")
  666. X  (calc-slow-wrapper
  667. X   (calc-unary-op "xpon" 'calcFunc-xpon arg))
  668. )
  669. X
  670. (defun calc-scale-float (arg)
  671. X  (interactive "P")
  672. X  (calc-slow-wrapper
  673. X   (calc-binary-op "scal" 'calcFunc-scf arg))
  674. )
  675. X
  676. (defun calc-abssqr (arg)
  677. X  (interactive "P")
  678. X  (calc-slow-wrapper
  679. X   (calc-unary-op "absq" 'calcFunc-abssqr arg))
  680. )
  681. X
  682. (defun calc-sign (arg)
  683. X  (interactive "P")
  684. X  (calc-slow-wrapper
  685. X   (calc-unary-op "sign" 'calcFunc-sign arg))
  686. )
  687. X
  688. (defun calc-increment (arg)
  689. X  (interactive "p")
  690. X  (calc-wrapper
  691. X   (calc-enter-result 1 "incr" (list 'calcFunc-incr (calc-top-n 1) arg)))
  692. )
  693. X
  694. (defun calc-decrement (arg)
  695. X  (interactive "p")
  696. X  (calc-wrapper
  697. X   (calc-enter-result 1 "decr" (list 'calcFunc-decr (calc-top-n 1) arg)))
  698. )
  699. X
  700. X
  701. (defun math-abs-approx (a)
  702. X  (cond ((Math-negp a)
  703. X     (math-neg a))
  704. X    ((Math-anglep a)
  705. X     a)
  706. X    ((eq (car a) 'cplx)
  707. X     (math-add (math-abs (nth 1 a)) (math-abs (nth 2 a))))
  708. X    ((eq (car a) 'polar)
  709. X     (nth 1 a))
  710. X    ((eq (car a) 'sdev)
  711. X     (math-abs-approx (nth 1 a)))
  712. X    ((eq (car a) 'intv)
  713. X     (math-max (math-abs (nth 2 a)) (math-abs (nth 3 a))))
  714. X    ((eq (car a) 'date)
  715. X     a)
  716. X    ((eq (car a) 'vec)
  717. X     (math-reduce-vec 'math-add-abs-approx a))
  718. X    ((eq (car a) 'calcFunc-abs)
  719. X     (car a))
  720. X    (t a))
  721. )
  722. X
  723. (defun math-add-abs-approx (a b)
  724. X  (math-add (math-abs-approx a) (math-abs-approx b))
  725. )
  726. X
  727. X
  728. ;;;; Declarations.
  729. X
  730. (setq math-decls-cache-tag nil)
  731. (setq math-decls-cache nil)
  732. (setq math-decls-all nil)
  733. X
  734. ;;; Math-decls-cache is an a-list where each entry is a list of the form:
  735. ;;;   (VAR TYPES RANGE)
  736. ;;; where VAR is a variable name (with var- prefix) or function name;
  737. ;;;       TYPES is a list of type symbols (any, int, frac, ...)
  738. ;;;      RANGE is a sorted vector of intervals describing the range.
  739. X
  740. (defun math-setup-declarations ()
  741. X  (or (eq math-decls-cache-tag (calc-var-value 'var-Decls))
  742. X      (let ((p (calc-var-value 'var-Decls))
  743. X        vec type range)
  744. X    (setq math-decls-cache-tag p
  745. X          math-decls-cache nil)
  746. X    (and (eq (car-safe p) 'vec)
  747. X         (while (setq p (cdr p))
  748. X           (and (eq (car-safe (car p)) 'vec)
  749. X            (setq vec (nth 2 (car p)))
  750. X            (condition-case err
  751. X            (let ((v (nth 1 (car p))))
  752. X              (setq type nil range nil)
  753. X              (or (eq (car-safe vec) 'vec)
  754. X                  (setq vec (list 'vec vec)))
  755. X              (while (and (setq vec (cdr vec))
  756. X                      (not (Math-objectp (car vec))))
  757. X                (and (eq (car-safe (car vec)) 'var)
  758. X                 (let ((st (assq (nth 1 (car vec))
  759. X                         math-super-types)))
  760. X                   (cond (st (setq type (append type st)))
  761. X                     ((eq (nth 1 (car vec)) 'pos)
  762. X                      (setq type (append type
  763. X                                 '(real number))
  764. X                        range
  765. X                        '(intv 1 0 (var inf var-inf))))
  766. X                     ((eq (nth 1 (car vec)) 'nonneg)
  767. X                      (setq type (append type
  768. X                                 '(real number))
  769. X                        range
  770. X                        '(intv 3 0
  771. X                               (var inf var-inf))))))))
  772. X              (if vec
  773. X                  (setq type (append type '(real number))
  774. X                    range (math-prepare-set (cons 'vec vec))))
  775. X              (setq type (list type range))
  776. X              (or (eq (car-safe v) 'vec)
  777. X                  (setq v (list 'vec v)))
  778. X              (while (setq v (cdr v))
  779. X                (if (or (eq (car-safe (car v)) 'var)
  780. X                    (not (Math-primp (car v))))
  781. X                (setq math-decls-cache
  782. X                      (cons (cons (if (eq (car (car v)) 'var)
  783. X                              (nth 2 (car v))
  784. X                            (car (car v)))
  785. X                          type)
  786. X                        math-decls-cache)))))
  787. X              (error nil)))))
  788. X    (setq math-decls-all (assq 'var-All math-decls-cache))))
  789. )
  790. X
  791. (defvar math-super-types
  792. X  '( ( int     numint rat real number )
  793. X     ( numint  real number )
  794. X     ( frac    rat real number )
  795. X     ( rat     real number )
  796. X     ( float   real number )
  797. X     ( real    number )
  798. X     ( number  )
  799. X     ( scalar  )
  800. X     ( matrix  vector )
  801. X     ( vector )
  802. X     ( const )
  803. ))
  804. X
  805. X
  806. (defun math-known-scalarp (a &optional assume-scalar)
  807. X  (math-setup-declarations)
  808. X  (if (if calc-matrix-mode
  809. X      (eq calc-matrix-mode 'scalar)
  810. X    assume-scalar)
  811. X      (not (math-check-known-matrixp a))
  812. X    (math-check-known-scalarp a))
  813. )
  814. X
  815. (defun math-known-matrixp (a)
  816. X  (and (not (Math-scalarp a))
  817. X       (not (math-known-scalarp a t)))
  818. )
  819. X
  820. ;;; Try to prove that A is a scalar (i.e., a non-vector).
  821. (defun math-check-known-scalarp (a)
  822. X  (cond ((Math-objectp a) t)
  823. X    ((memq (car a) math-scalar-functions)
  824. X     t)
  825. X    ((memq (car a) math-real-scalar-functions)
  826. X     t)
  827. X    ((memq (car a) math-scalar-if-args-functions)
  828. X     (while (and (setq a (cdr a))
  829. X             (math-check-known-scalarp (car a))))
  830. X     (null a))
  831. X    ((eq (car a) '^)
  832. X     (math-check-known-scalarp (nth 1 a)))
  833. X    ((math-const-var a) t)
  834. X    (t
  835. X     (let ((decl (if (eq (car a) 'var)
  836. X             (or (assq (nth 2 a) math-decls-cache)
  837. X                 math-decls-all)
  838. X               (assq (car a) math-decls-cache))))
  839. X       (memq 'scalar (nth 1 decl)))))
  840. )
  841. X
  842. ;;; Try to prove that A is *not* a scalar.
  843. (defun math-check-known-matrixp (a)
  844. X  (cond ((Math-objectp a) nil)
  845. X    ((memq (car a) math-nonscalar-functions)
  846. X     t)
  847. X    ((memq (car a) math-scalar-if-args-functions)
  848. X     (while (and (setq a (cdr a))
  849. X             (not (math-check-known-matrixp (car a)))))
  850. X     a)
  851. X    ((eq (car a) '^)
  852. X     (math-check-known-matrixp (nth 1 a)))
  853. X    ((math-const-var a) nil)
  854. X    (t
  855. X     (let ((decl (if (eq (car a) 'var)
  856. X             (or (assq (nth 2 a) math-decls-cache)
  857. X                 math-decls-all)
  858. X               (assq (car a) math-decls-cache))))
  859. X       (memq 'vector (nth 1 decl)))))
  860. )
  861. X
  862. X
  863. ;;; Try to prove that A is a real (i.e., not complex).
  864. (defun math-known-realp (a)
  865. X  (< (math-possible-signs a) 8)
  866. )
  867. X
  868. ;;; Try to prove that A is real and positive.
  869. (defun math-known-posp (a)
  870. X  (eq (math-possible-signs a) 4)
  871. )
  872. X
  873. ;;; Try to prove that A is real and negative.
  874. (defun math-known-negp (a)
  875. X  (eq (math-possible-signs a) 1)
  876. )
  877. X
  878. ;;; Try to prove that A is real and nonnegative.
  879. (defun math-known-nonnegp (a)
  880. X  (memq (math-possible-signs a) '(2 4 6))
  881. )
  882. X
  883. ;;; Try to prove that A is real and nonpositive.
  884. (defun math-known-nonposp (a)
  885. X  (memq (math-possible-signs a) '(1 2 3))
  886. )
  887. X
  888. ;;; Try to prove that A is nonzero.
  889. (defun math-known-nonzerop (a)
  890. X  (memq (math-possible-signs a) '(1 4 5 8 9 12 13))
  891. )
  892. X
  893. ;;; Return true if A is negative, or looks negative but we don't know.
  894. (defun math-guess-if-neg (a)
  895. X  (let ((sgn (math-possible-signs a)))
  896. X    (if (memq sgn '(1 3))
  897. X    t
  898. X      (if (memq sgn '(2 4 6))
  899. X      nil
  900. X    (math-looks-negp a))))
  901. )
  902. X
  903. ;;; Find the possible signs of A, assuming A is a number of some kind.
  904. ;;; Returns an integer with bits:  1  may be negative,
  905. ;;;                   2  may be zero,
  906. ;;;                   4  may be positive,
  907. ;;;                   8  may be nonreal.
  908. X
  909. (defun math-possible-signs (a &optional origin)
  910. X  (cond ((Math-objectp a)
  911. X     (if origin (setq a (math-sub a origin)))
  912. X     (cond ((Math-posp a) 4)
  913. X           ((Math-negp a) 1)
  914. X           ((Math-zerop a) 2)
  915. X           ((eq (car a) 'intv)
  916. X        (cond ((Math-zerop (nth 2 a)) 6)
  917. X              ((Math-zerop (nth 3 a)) 3)
  918. X              (t 7)))
  919. X           ((eq (car a) 'sdev)
  920. X        (if (math-known-realp (nth 1 a)) 7 15))
  921. X           (t 8)))
  922. X    ((memq (car a) '(+ -))
  923. X     (cond ((Math-realp (nth 1 a))
  924. X        (if (eq (car a) '-)
  925. X            (math-neg-signs
  926. X             (math-possible-signs (nth 2 a)
  927. X                      (if origin
  928. X                          (math-add origin (nth 1 a))
  929. X                        (nth 1 a))))
  930. X          (math-possible-signs (nth 2 a)
  931. X                       (if origin
  932. X                       (math-sub origin (nth 1 a))
  933. X                     (math-neg (nth 1 a))))))
  934. X           ((Math-realp (nth 2 a))
  935. X        (let ((org (if (eq (car a) '-)
  936. X                   (nth 2 a)
  937. X                 (math-neg (nth 2 a)))))
  938. X          (math-possible-signs (nth 1 a)
  939. X                       (if origin
  940. X                       (math-add origin org)
  941. X                     org))))
  942. X           (t
  943. X        (let ((s1 (math-possible-signs (nth 1 a) origin))
  944. X              (s2 (math-possible-signs (nth 2 a))))
  945. X          (if (eq (car a) '-) (setq s2 (math-neg-signs s2)))
  946. X          (cond ((eq s1 s2) s1)
  947. X            ((eq s1 2) s2)
  948. X            ((eq s2 2) s1)
  949. X            ((>= s1 8) 15)
  950. X            ((>= s2 8) 15)
  951. X            ((and (eq s1 4) (eq s2 6)) 4)
  952. X            ((and (eq s2 4) (eq s1 6)) 4)
  953. X            ((and (eq s1 1) (eq s2 3)) 1)
  954. X            ((and (eq s2 1) (eq s1 3)) 1)
  955. X            (t 7))))))
  956. X    ((eq (car a) 'neg)
  957. X     (math-neg-signs (math-possible-signs
  958. X              (nth 1 a)
  959. X              (and origin (math-neg origin)))))
  960. X    ((and origin (Math-zerop origin) (setq origin nil)
  961. X          nil))
  962. X    ((and (or (eq (car a) '*)
  963. X          (and (eq (car a) '/) origin))
  964. X          (Math-realp (nth 1 a)))
  965. X     (let ((s (if (eq (car a) '*)
  966. X              (if (Math-zerop (nth 1 a))
  967. X              (math-possible-signs 0 origin)
  968. X            (math-possible-signs (nth 2 a)
  969. X                         (math-div (or origin 0)
  970. X                               (nth 1 a))))
  971. X            (math-neg-signs
  972. X             (math-possible-signs (nth 2 a)
  973. X                      (math-div (nth 1 a)
  974. X                            origin))))))
  975. X       (if (Math-negp (nth 1 a)) (math-neg-signs s) s)))
  976. X    ((and (memq (car a) '(* /)) (Math-realp (nth 2 a)))
  977. X     (let ((s (math-possible-signs (nth 1 a)
  978. X                       (if (eq (car a) '*)
  979. X                       (math-mul (or origin 0) (nth 2 a))
  980. X                     (math-div (or origin 0) (nth 2 a))))))
  981. X       (if (Math-negp (nth 2 a)) (math-neg-signs s) s)))
  982. X    ((eq (car a) 'vec)
  983. X     (let ((signs 0))
  984. X       (while (and (setq a (cdr a)) (< signs 15))
  985. X         (setq signs (logior signs (math-possible-signs
  986. X                    (car a) origin))))
  987. X       signs))
  988. X    (t (let ((sign
  989. X          (cond
  990. X           ((memq (car a) '(* /))
  991. X            (let ((s1 (math-possible-signs (nth 1 a)))
  992. X              (s2 (math-possible-signs (nth 2 a))))
  993. X              (cond ((>= s1 8) 15)
  994. X                ((>= s2 8) 15)
  995. X                ((and (eq (car a) '/) (memq s2 '(2 3 6 7))) 15)
  996. X                (t
  997. X                 (logior (if (memq s1 '(4 5 6 7)) s2 0)
  998. X                     (if (memq s1 '(2 3 6 7)) 2 0)
  999. X                     (if (memq s1 '(1 3 5 7))
  1000. X                     (math-neg-signs s2) 0))))))
  1001. X           ((eq (car a) '^)
  1002. X            (let ((s1 (math-possible-signs (nth 1 a)))
  1003. X              (s2 (math-possible-signs (nth 2 a))))
  1004. X              (cond ((>= s1 8) 15)
  1005. X                ((>= s2 8) 15)
  1006. X                ((eq s1 4) 4)
  1007. X                ((eq s1 2) (if (eq s2 4) 2 15))
  1008. X                ((eq s2 2) (if (memq s1 '(1 5)) 2 15))
  1009. X                ((Math-integerp (nth 2 a))
  1010. X                 (if (math-evenp (nth 2 a))
  1011. X                 (if (memq s1 '(3 6 7)) 6 4)
  1012. X                   s1))
  1013. X                ((eq s1 6) (if (eq s2 4) 6 15))
  1014. X                (t 7))))
  1015. X           ((eq (car a) '%)
  1016. X            (let ((s2 (math-possible-signs (nth 2 a))))
  1017. X              (cond ((>= s2 8) 7)
  1018. X                ((eq s2 2) 2)
  1019. X                ((memq s2 '(4 6)) 6)
  1020. X                ((memq s2 '(1 3)) 3)
  1021. X                (t 7))))
  1022. X           ((and (memq (car a) '(calcFunc-abs calcFunc-abssqr))
  1023. X             (= (length a) 2))
  1024. X            (let ((s1 (math-possible-signs (nth 1 a))))
  1025. X              (cond ((eq s1 2) 2)
  1026. X                ((memq s1 '(1 4 5)) 4)
  1027. X                (t 6))))
  1028. X           ((and (eq (car a) 'calcFunc-exp) (= (length a) 2))
  1029. X            (let ((s1 (math-possible-signs (nth 1 a))))
  1030. X              (if (>= s1 8)
  1031. X              15
  1032. X            (if (or (not origin) (math-negp origin))
  1033. X                4
  1034. X              (setq origin (math-sub (or origin 0) 1))
  1035. X              (if (Math-zerop origin) (setq origin nil))
  1036. X              s1))))
  1037. X           ((or (and (memq (car a) '(calcFunc-ln calcFunc-log10))
  1038. X                 (= (length a) 2))
  1039. X            (and (eq (car a) 'calcFunc-log)
  1040. X                 (= (length a) 3)
  1041. X                 (math-known-posp (nth 2 a))))
  1042. X            (if (math-known-nonnegp (nth 1 a))
  1043. X            (math-possible-signs (nth 1 a) 1)
  1044. X              15))
  1045. X           ((and (eq (car a) 'calcFunc-sqrt) (= (length a) 2))
  1046. X            (let ((s1 (math-possible-signs (nth 1 a))))
  1047. X              (if (memq s1 '(2 4 6)) s1 15)))
  1048. X           ((memq (car a) math-nonnegative-functions) 6)
  1049. X           ((memq (car a) math-positive-functions) 4)
  1050. X           ((memq (car a) math-real-functions) 7)
  1051. X           ((memq (car a) math-real-scalar-functions) 7)
  1052. X           ((and (memq (car a) math-real-if-arg-functions)
  1053. X             (= (length a) 2))
  1054. X            (if (math-known-realp (nth 1 a)) 7 15)))))
  1055. X         (cond (sign
  1056. X            (if origin
  1057. X            (+ (logand sign 8)
  1058. X               (if (Math-posp origin)
  1059. X                   (if (memq sign '(1 2 3 8 9 10 11)) 1 7)
  1060. X                 (if (memq sign '(2 4 6 8 10 12 14)) 4 7)))
  1061. X              sign))
  1062. X           ((math-const-var a)
  1063. X            (cond ((eq (nth 2 a) 'var-pi)
  1064. X               (if origin
  1065. X                   (math-possible-signs (math-pi) origin)
  1066. X                 4))
  1067. X              ((eq (nth 2 a) 'var-e)
  1068. X               (if origin
  1069. X                   (math-possible-signs (math-e) origin)
  1070. X                 4))
  1071. X              ((eq (nth 2 a) 'var-inf) 4)
  1072. X              ((eq (nth 2 a) 'var-uinf) 13)
  1073. X              ((eq (nth 2 a) 'var-i) 8)
  1074. X              (t 15)))
  1075. X           (t
  1076. X            (math-setup-declarations)
  1077. X            (let ((decl (if (eq (car a) 'var)
  1078. X                    (or (assq (nth 2 a) math-decls-cache)
  1079. X                    math-decls-all)
  1080. X                  (assq (car a) math-decls-cache))))
  1081. X              (if (and origin
  1082. X                   (memq 'int (nth 1 decl))
  1083. X                   (not (Math-num-integerp origin)))
  1084. X              5
  1085. X            (if (nth 2 decl)
  1086. X                (math-possible-signs (nth 2 decl) origin)
  1087. X              (if (memq 'real (nth 1 decl))
  1088. X                  7
  1089. X                15)))))))))
  1090. )
  1091. X
  1092. (defun math-neg-signs (s1)
  1093. X  (if (>= s1 8)
  1094. X      (+ 8 (math-neg-signs (- s1 8)))
  1095. X    (+ (if (memq s1 '(1 3 5 7)) 4 0)
  1096. X       (if (memq s1 '(2 3 6 7)) 2 0)
  1097. X       (if (memq s1 '(4 5 6 7)) 1 0)))
  1098. )
  1099. X
  1100. X
  1101. ;;; Try to prove that A is an integer.
  1102. (defun math-known-integerp (a)
  1103. X  (eq (math-possible-types a) 1)
  1104. )
  1105. X
  1106. (defun math-known-num-integerp (a)
  1107. X  (<= (math-possible-types a t) 3)
  1108. )
  1109. X
  1110. (defun math-known-imagp (a)
  1111. X  (= (math-possible-types a) 16)
  1112. )
  1113. X
  1114. X
  1115. ;;; Find the possible types of A.
  1116. ;;; Returns an integer with bits:  1  may be integer.
  1117. ;;;                   2  may be integer-valued float.
  1118. ;;;                   4  may be fraction.
  1119. ;;;                   8  may be non-integer-valued float.
  1120. ;;;                  16  may be imaginary.
  1121. ;;;                  32  may be non-real, non-imaginary.
  1122. ;;; Real infinities count as integers for the purposes of this function.
  1123. (defun math-possible-types (a &optional num)
  1124. X  (cond ((Math-objectp a)
  1125. X     (cond ((Math-integerp a) (if num 3 1))
  1126. X           ((Math-messy-integerp a) (if num 3 2))
  1127. X           ((eq (car a) 'frac) (if num 12 4))
  1128. X           ((eq (car a) 'float) (if num 12 8))
  1129. X           ((eq (car a) 'intv)
  1130. X        (if (equal (nth 2 a) (nth 3 a))
  1131. X            (math-possible-types (nth 2 a))
  1132. X          15))
  1133. X           ((eq (car a) 'sdev)
  1134. X        (if (math-known-realp (nth 1 a)) 15 63))
  1135. X           ((eq (car a) 'cplx)
  1136. X        (if (math-zerop (nth 1 a)) 16 32))
  1137. X           ((eq (car a) 'polar)
  1138. X        (if (or (Math-equal (nth 2 a) (math-quarter-circle nil))
  1139. X            (Math-equal (nth 2 a)
  1140. X                    (math-neg (math-quarter-circle nil))))
  1141. X            16 48))
  1142. X           (t 63)))
  1143. X    ((eq (car a) '/)
  1144. X     (let* ((t1 (math-possible-types (nth 1 a) num))
  1145. X        (t2 (math-possible-types (nth 2 a) num))
  1146. X        (t12 (logior t1 t2)))
  1147. X       (if (< t12 16)
  1148. X           (if (> (logand t12 10) 0)
  1149. X           10
  1150. X         (if (or (= t1 4) (= t2 4) calc-prefer-frac)
  1151. X             5
  1152. X           15))
  1153. X         (if (< t12 32)
  1154. X         (if (= t1 16)
  1155. X             (if (= t2 16) 15
  1156. X               (if (< t2 16) 16 31))
  1157. X           (if (= t2 16)
  1158. X               (if (< t1 16) 16 31)
  1159. X             31))
  1160. X           63))))
  1161. X    ((memq (car a) '(+ - * %))
  1162. X     (let* ((t1 (math-possible-types (nth 1 a) num))
  1163. X        (t2 (math-possible-types (nth 2 a) num))
  1164. X        (t12 (logior t1 t2)))
  1165. X       (if (eq (car a) '%)
  1166. X           (setq t1 (logand t1 15) t2 (logand t2 15) t12 (logand t12 15)))
  1167. X       (if (< t12 16)
  1168. X           (let ((mask (if (<= t12 3)
  1169. X                   1
  1170. X                 (if (and (or (and (<= t1 3) (= (logand t2 3) 0))
  1171. X                      (and (<= t2 3) (= (logand t1 3) 0)))
  1172. X                      (memq (car a) '(+ -)))
  1173. X                 4
  1174. X                   5))))
  1175. X         (if num
  1176. X             (* mask 3)
  1177. X           (logior (if (and (> (logand t1 5) 0) (> (logand t2 5) 0))
  1178. X                   mask 0)
  1179. X               (if (> (logand t12 10) 0)
  1180. X                   (* mask 2) 0))))
  1181. X         (if (< t12 32)
  1182. X         (if (eq (car a) '*)
  1183. X             (if (= t1 16)
  1184. X             (if (= t2 16) 15
  1185. X               (if (< t2 16) 16 31))
  1186. X               (if (= t2 16)
  1187. X               (if (< t1 16) 16 31)
  1188. X             31))
  1189. X           (if (= t12 16) 16
  1190. X             (if (or (and (= t1 16) (< t2 16))
  1191. X                 (and (= t2 16) (< t1 16))) 32 63)))
  1192. X           63))))
  1193. X    ((eq (car a) 'neg)
  1194. X     (math-possible-types (nth 1 a)))
  1195. X    ((eq (car a) '^)
  1196. X     (let* ((t1 (math-possible-types (nth 1 a) num))
  1197. X        (t2 (math-possible-types (nth 2 a) num))
  1198. X        (t12 (logior t1 t2)))
  1199. X       (if (and (<= t2 3) (math-known-nonnegp (nth 2 a)) (< t1 16))
  1200. X           (let ((mask (logior (if (> (logand t1 3) 0) 1 0)
  1201. X                   (logand t1 4)
  1202. X                   (if (> (logand t1 12) 0) 5 0))))
  1203. X         (if num
  1204. X             (* mask 3)
  1205. X           (logior (if (and (> (logand t1 5) 0) (> (logand t2 5) 0))
  1206. X                   mask 0)
  1207. X               (if (> (logand t12 10) 0)
  1208. X                   (* mask 2) 0))))
  1209. X         (if (and (math-known-nonnegp (nth 1 a))
  1210. X              (math-known-posp (nth 2 a)))
  1211. X         15
  1212. X           63))))
  1213. X    ((eq (car a) 'calcFunc-sqrt)
  1214. X     (let ((t1 (math-possible-signs (nth 1 a))))
  1215. X       (logior (if (> (logand t1 2) 0) 3 0)
  1216. X           (if (> (logand t1 1) 0) 16 0)
  1217. X           (if (> (logand t1 4) 0) 15 0)
  1218. X           (if (> (logand t1 8) 0) 32 0))))
  1219. X    ((eq (car a) 'vec)
  1220. X     (let ((types 0))
  1221. X       (while (and (setq a (cdr a)) (< types 63))
  1222. X         (setq types (logior types (math-possible-types (car a) t))))
  1223. X       types))
  1224. X    ((or (memq (car a) math-integer-functions)
  1225. X         (and (memq (car a) math-rounding-functions)
  1226. X          (math-known-nonnegp (or (nth 2 a) 0))))
  1227. X     1)
  1228. X    ((or (memq (car a) math-num-integer-functions)
  1229. X         (and (memq (car a) math-float-rounding-functions)
  1230. X          (math-known-nonnegp (or (nth 2 a) 0))))
  1231. X     2)
  1232. X    ((eq (car a) 'calcFunc-frac)
  1233. X     5)
  1234. X    ((and (eq (car a) 'calcFunc-float) (= (length a) 2))
  1235. X     (let ((t1 (math-possible-types (nth 1 a))))
  1236. X       (logior (if (> (logand t1 3) 0) 2 0)
  1237. X           (if (> (logand t1 12) 0) 8 0)
  1238. X           (logand t1 48))))
  1239. X    ((and (memq (car a) '(calcFunc-abs calcFunc-abssqr))
  1240. X          (= (length a) 2))
  1241. X     (let ((t1 (math-possible-types (nth 1 a))))
  1242. X       (if (>= t1 16)
  1243. X           15
  1244. X         t1)))
  1245. X    ((math-const-var a)
  1246. X     (cond ((memq (nth 2 a) '(var-e var-pi var-phi var-gamma)) 8)
  1247. X           ((eq (nth 2 a) 'var-inf) 1)
  1248. X           ((eq (nth 2 a) 'var-i) 16)
  1249. X           (t 63)))
  1250. X    (t
  1251. X     (math-setup-declarations)
  1252. X     (let ((decl (if (eq (car a) 'var)
  1253. X             (or (assq (nth 2 a) math-decls-cache)
  1254. X                 math-decls-all)
  1255. X               (assq (car a) math-decls-cache))))
  1256. X       (cond ((memq 'int (nth 1 decl))
  1257. X          1)
  1258. X         ((memq 'numint (nth 1 decl))
  1259. X          3)
  1260. X         ((memq 'frac (nth 1 decl))
  1261. X          4)
  1262. X         ((memq 'rat (nth 1 decl))
  1263. X          5)
  1264. X         ((memq 'float (nth 1 decl))
  1265. X          10)
  1266. X         ((nth 2 decl)
  1267. X          (math-possible-types (nth 2 decl)))
  1268. X         ((memq 'real (nth 1 decl))
  1269. X          15)
  1270. X         (t 63)))))
  1271. )
  1272. X
  1273. (defun math-known-evenp (a)
  1274. X  (cond ((Math-integerp a)
  1275. X     (math-evenp a))
  1276. X    ((Math-messy-integerp a)
  1277. X     (or (> (nth 2 a) 0)
  1278. X         (math-evenp (math-trunc a))))
  1279. X    ((eq (car a) '*)
  1280. X     (if (math-known-evenp (nth 1 a))
  1281. X         (math-known-num-integerp (nth 2 a))
  1282. X       (if (math-known-num-integerp (nth 1 a))
  1283. X           (math-known-evenp (nth 2 a)))))
  1284. X    ((memq (car a) '(+ -))
  1285. X     (or (and (math-known-evenp (nth 1 a))
  1286. X          (math-known-evenp (nth 2 a)))
  1287. X         (and (math-known-oddp (nth 1 a))
  1288. X          (math-known-oddp (nth 2 a)))))
  1289. X    ((eq (car a) 'neg)
  1290. X     (math-known-evenp (nth 1 a))))
  1291. )
  1292. X
  1293. (defun math-known-oddp (a)
  1294. X  (cond ((Math-integerp a)
  1295. X     (math-oddp a))
  1296. X    ((Math-messy-integerp a)
  1297. X     (and (<= (nth 2 a) 0)
  1298. X          (math-oddp (math-trunc a))))
  1299. X    ((memq (car a) '(+ -))
  1300. X     (or (and (math-known-evenp (nth 1 a))
  1301. X          (math-known-oddp (nth 2 a)))
  1302. X         (and (math-known-oddp (nth 1 a))
  1303. X          (math-known-evenp (nth 2 a)))))
  1304. X    ((eq (car a) 'neg)
  1305. X     (math-known-oddp (nth 1 a))))
  1306. )
  1307. X
  1308. X
  1309. (defun calcFunc-dreal (expr)
  1310. X  (let ((types (math-possible-types expr)))
  1311. X    (if (< types 16) 1
  1312. X      (if (= (logand types 15) 0) 0
  1313. X    (math-reject-arg expr 'realp 'quiet))))
  1314. )
  1315. X
  1316. (defun calcFunc-dimag (expr)
  1317. X  (let ((types (math-possible-types expr)))
  1318. X    (if (= types 16) 1
  1319. X      (if (= (logand types 16) 0) 0
  1320. X    (math-reject-arg expr "Expected an imaginary number"))))
  1321. )
  1322. X
  1323. (defun calcFunc-dpos (expr)
  1324. X  (let ((signs (math-possible-signs expr)))
  1325. X    (if (eq signs 4) 1
  1326. X      (if (memq signs '(1 2 3)) 0
  1327. X    (math-reject-arg expr 'posp 'quiet))))
  1328. )
  1329. X
  1330. (defun calcFunc-dneg (expr)
  1331. X  (let ((signs (math-possible-signs expr)))
  1332. X    (if (eq signs 1) 1
  1333. X      (if (memq signs '(2 4 6)) 0
  1334. X    (math-reject-arg expr 'negp 'quiet))))
  1335. )
  1336. X
  1337. (defun calcFunc-dnonneg (expr)
  1338. X  (let ((signs (math-possible-signs expr)))
  1339. X    (if (memq signs '(2 4 6)) 1
  1340. X      (if (eq signs 1) 0
  1341. X    (math-reject-arg expr 'posp 'quiet))))
  1342. )
  1343. X
  1344. (defun calcFunc-dnonzero (expr)
  1345. X  (let ((signs (math-possible-signs expr)))
  1346. X    (if (memq signs '(1 4 5 8 9 12 13)) 1
  1347. X      (if (eq signs 2) 0
  1348. X    (math-reject-arg expr 'nonzerop 'quiet))))
  1349. )
  1350. X
  1351. (defun calcFunc-dint (expr)
  1352. X  (let ((types (math-possible-types expr)))
  1353. X    (if (= types 1) 1
  1354. X      (if (= (logand types 1) 0) 0
  1355. X    (math-reject-arg expr 'integerp 'quiet))))
  1356. )
  1357. X
  1358. (defun calcFunc-dnumint (expr)
  1359. X  (let ((types (math-possible-types expr t)))
  1360. X    (if (<= types 3) 1
  1361. X      (if (= (logand types 3) 0) 0
  1362. X    (math-reject-arg expr 'integerp 'quiet))))
  1363. )
  1364. X
  1365. (defun calcFunc-dnatnum (expr)
  1366. X  (let ((res (calcFunc-dint expr)))
  1367. X    (if (eq res 1)
  1368. X    (calcFunc-dnonneg expr)
  1369. X      res))
  1370. )
  1371. X
  1372. (defun calcFunc-deven (expr)
  1373. X  (if (math-known-evenp expr)
  1374. X      1
  1375. X    (if (or (math-known-oddp expr)
  1376. X        (= (logand (math-possible-types expr) 3) 0))
  1377. X    0
  1378. X      (math-reject-arg expr "Can't tell if expression is odd or even")))
  1379. )
  1380. X
  1381. (defun calcFunc-dodd (expr)
  1382. X  (if (math-known-oddp expr)
  1383. X      1
  1384. X    (if (or (math-known-evenp expr)
  1385. X        (= (logand (math-possible-types expr) 3) 0))
  1386. X    0
  1387. X      (math-reject-arg expr "Can't tell if expression is odd or even")))
  1388. )
  1389. X
  1390. (defun calcFunc-drat (expr)
  1391. X  (let ((types (math-possible-types expr)))
  1392. X    (if (memq types '(1 4 5)) 1
  1393. X      (if (= (logand types 5) 0) 0
  1394. X    (math-reject-arg expr "Rational number expected"))))
  1395. )
  1396. X
  1397. (defun calcFunc-drange (expr)
  1398. X  (math-setup-declarations)
  1399. X  (let (range)
  1400. X    (if (Math-realp expr)
  1401. X    (list 'vec expr)
  1402. X      (if (eq (car-safe expr) 'intv)
  1403. X      expr
  1404. X    (if (eq (car-safe expr) 'var)
  1405. X        (setq range (nth 2 (or (assq (nth 2 expr) math-decls-cache)
  1406. X                   math-decls-all)))
  1407. X      (setq range (nth 2 (assq (car-safe expr) math-decls-cache))))
  1408. X    (if range
  1409. X        (math-clean-set (copy-sequence range))
  1410. X      (setq range (math-possible-signs expr))
  1411. X      (if (< range 8)
  1412. X          (aref [(vec)
  1413. X             (intv 2 (neg (var inf var-inf)) 0)
  1414. X             (vec 0)
  1415. X             (intv 3 (neg (var inf var-inf)) 0)
  1416. X             (intv 1 0 (var inf var-inf))
  1417. X             (vec (intv 2 (neg (var inf var-inf)) 0)
  1418. X              (intv 1 0 (var inf var-inf)))
  1419. X             (intv 3 0 (var inf var-inf))
  1420. X             (intv 3 (neg (var inf var-inf)) (var inf var-inf))] range)
  1421. X        (math-reject-arg expr 'realp 'quiet))))))
  1422. )
  1423. X
  1424. (defun calcFunc-dscalar (a)
  1425. X  (if (math-known-scalarp a) 1
  1426. X    (if (math-known-matrixp a) 0
  1427. X      (math-reject-arg a 'objectp 'quiet)))
  1428. )
  1429. X
  1430. X
  1431. ;;; The following lists are not exhaustive.
  1432. (defvar math-scalar-functions '(calcFunc-det
  1433. X                calcFunc-cnorm calcFunc-rnorm
  1434. X                calcFunc-vlen calcFunc-vcount
  1435. X                calcFunc-vsum calcFunc-vprod
  1436. X                calcFunc-vmin calcFunc-vmax
  1437. ))
  1438. X
  1439. (defvar math-nonscalar-functions '(vec calcFunc-idn calcFunc-diag
  1440. X                       calcFunc-cvec calcFunc-index
  1441. X                       calcFunc-trn
  1442. X                       | calcFunc-append
  1443. X                       calcFunc-cons calcFunc-rcons
  1444. X                       calcFunc-tail calcFunc-rhead
  1445. ))
  1446. X
  1447. (defvar math-scalar-if-args-functions '(+ - * / neg))
  1448. X
  1449. (defvar math-real-functions '(calcFunc-arg
  1450. X                  calcFunc-re calcFunc-im
  1451. X                  calcFunc-floor calcFunc-ceil
  1452. X                  calcFunc-trunc calcFunc-round
  1453. X                  calcFunc-rounde calcFunc-roundu
  1454. X                  calcFunc-ffloor calcFunc-fceil
  1455. X                  calcFunc-ftrunc calcFunc-fround
  1456. X                  calcFunc-frounde calcFunc-froundu
  1457. ))
  1458. X
  1459. (defvar math-positive-functions '(
  1460. ))
  1461. X
  1462. (defvar math-nonnegative-functions '(calcFunc-cnorm calcFunc-rnorm
  1463. X                     calcFunc-vlen calcFunc-vcount
  1464. ))
  1465. X
  1466. (defvar math-real-scalar-functions '(% calcFunc-idiv calcFunc-abs
  1467. X                       calcFunc-choose calcFunc-perm
  1468. X                       calcFunc-eq calcFunc-neq
  1469. X                       calcFunc-lt calcFunc-gt
  1470. X                       calcFunc-leq calcFunc-geq
  1471. X                       calcFunc-lnot
  1472. X                       calcFunc-max calcFunc-min
  1473. ))
  1474. X
  1475. (defvar math-real-if-arg-functions '(calcFunc-sin calcFunc-cos
  1476. X                     calcFunc-tan calcFunc-arctan
  1477. X                     calcFunc-sinh calcFunc-cosh
  1478. X                     calcFunc-tanh calcFunc-exp
  1479. X                     calcFunc-gamma calcFunc-fact
  1480. ))
  1481. X
  1482. (defvar math-integer-functions '(calcFunc-idiv
  1483. X                 calcFunc-isqrt calcFunc-ilog
  1484. X                 calcFunc-vlen calcFunc-vcount
  1485. ))
  1486. X
  1487. (defvar math-num-integer-functions '(
  1488. ))
  1489. X
  1490. (defvar math-rounding-functions '(calcFunc-floor
  1491. X                  calcFunc-ceil
  1492. X                  calcFunc-round calcFunc-trunc
  1493. X                  calcFunc-rounde calcFunc-roundu
  1494. ))
  1495. X
  1496. (defvar math-float-rounding-functions '(calcFunc-ffloor
  1497. X                    calcFunc-fceil
  1498. X                    calcFunc-fround calcFunc-ftrunc
  1499. X                    calcFunc-frounde calcFunc-froundu
  1500. ))
  1501. X
  1502. (defvar math-integer-if-args-functions '(+ - * % neg calcFunc-abs
  1503. X                       calcFunc-min calcFunc-max
  1504. X                       calcFunc-choose calcFunc-perm
  1505. ))
  1506. X
  1507. X
  1508. ;;;; Arithmetic.
  1509. X
  1510. (defun calcFunc-neg (a)
  1511. X  (math-normalize (list 'neg a))
  1512. )
  1513. X
  1514. (defun math-neg-fancy (a)
  1515. X  (cond ((eq (car a) 'polar)
  1516. X     (list 'polar
  1517. X           (nth 1 a)
  1518. X           (if (math-posp (nth 2 a))
  1519. X           (math-sub (nth 2 a) (math-half-circle nil))
  1520. X         (math-add (nth 2 a) (math-half-circle nil)))))
  1521. X    ((eq (car a) 'mod)
  1522. X     (if (math-zerop (nth 1 a))
  1523. X         a
  1524. X       (list 'mod (math-sub (nth 2 a) (nth 1 a)) (nth 2 a))))
  1525. X    ((eq (car a) 'sdev)
  1526. X     (list 'sdev (math-neg (nth 1 a)) (nth 2 a)))
  1527. X    ((eq (car a) 'intv)
  1528. X     (math-make-intv (aref [0 2 1 3] (nth 1 a))
  1529. X             (math-neg (nth 3 a))
  1530. X             (math-neg (nth 2 a))))
  1531. X    ((and math-simplify-only
  1532. X          (not (equal a math-simplify-only)))
  1533. X     (list 'neg a))
  1534. X    ((eq (car a) '+)
  1535. X     (math-sub (math-neg (nth 1 a)) (nth 2 a)))
  1536. X    ((eq (car a) '-)
  1537. X     (math-sub (nth 2 a) (nth 1 a)))
  1538. X    ((and (memq (car a) '(* /))
  1539. X          (math-okay-neg (nth 1 a)))
  1540. X     (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
  1541. X    ((and (memq (car a) '(* /))
  1542. X          (math-okay-neg (nth 2 a)))
  1543. X     (list (car a) (nth 1 a) (math-neg (nth 2 a))))
  1544. X    ((and (memq (car a) '(* /))
  1545. X          (or (math-objectp (nth 1 a))
  1546. X          (and (eq (car (nth 1 a)) '*)
  1547. X               (math-objectp (nth 1 (nth 1 a))))))
  1548. X     (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
  1549. X    ((and (eq (car a) '/)
  1550. X          (or (math-objectp (nth 2 a))
  1551. X          (and (eq (car (nth 2 a)) '*)
  1552. X               (math-objectp (nth 1 (nth 2 a))))))
  1553. X     (list (car a) (nth 1 a) (math-neg (nth 2 a))))
  1554. X    ((and (eq (car a) 'var) (memq (nth 2 a) '(var-uinf var-nan)))
  1555. X     a)
  1556. X    ((eq (car a) 'neg)
  1557. X     (nth 1 a))
  1558. X    (t (list 'neg a)))
  1559. )
  1560. X
  1561. (defun math-okay-neg (a)
  1562. X  (or (math-looks-negp a)
  1563. X      (eq (car-safe a) '-))
  1564. )
  1565. X
  1566. (defun math-neg-float (a)
  1567. X  (list 'float (Math-integer-neg (nth 1 a)) (nth 2 a))
  1568. )
  1569. X
  1570. X
  1571. (defun calcFunc-add (&rest rest)
  1572. X  (if rest
  1573. X      (let ((a (car rest)))
  1574. X    (while (setq rest (cdr rest))
  1575. X      (setq a (list '+ a (car rest))))
  1576. X    (math-normalize a))
  1577. X    0)
  1578. )
  1579. X
  1580. (defun calcFunc-sub (&rest rest)
  1581. X  (if rest
  1582. X      (let ((a (car rest)))
  1583. X    (while (setq rest (cdr rest))
  1584. X      (setq a (list '- a (car rest))))
  1585. X    (math-normalize a))
  1586. X    0)
  1587. )
  1588. X
  1589. (defun math-add-objects-fancy (a b)
  1590. X  (cond ((and (Math-numberp a) (Math-numberp b))
  1591. X     (let ((aa (math-complex a))
  1592. X           (bb (math-complex b)))
  1593. X       (math-normalize
  1594. X        (let ((res (list 'cplx
  1595. X                 (math-add (nth 1 aa) (nth 1 bb))
  1596. X                 (math-add (nth 2 aa) (nth 2 bb)))))
  1597. X          (if (math-want-polar a b)
  1598. X          (math-polar res)
  1599. X        res)))))
  1600. X    ((or (Math-vectorp a) (Math-vectorp b))
  1601. X     (math-map-vec-2 'math-add a b))
  1602. X    ((eq (car-safe a) 'sdev)
  1603. X     (if (eq (car-safe b) 'sdev)
  1604. X         (math-make-sdev (math-add (nth 1 a) (nth 1 b))
  1605. X                 (math-hypot (nth 2 a) (nth 2 b)))
  1606. X       (and (or (Math-scalarp b)
  1607. X            (not (Math-objvecp b)))
  1608. X        (math-make-sdev (math-add (nth 1 a) b) (nth 2 a)))))
  1609. X    ((and (eq (car-safe b) 'sdev)
  1610. X          (or (Math-scalarp a)
  1611. X          (not (Math-objvecp a))))
  1612. X     (math-make-sdev (math-add a (nth 1 b)) (nth 2 b)))
  1613. X    ((eq (car-safe a) 'intv)
  1614. X     (if (eq (car-safe b) 'intv)
  1615. X         (math-make-intv (logior (logand (nth 1 a) (nth 1 b))
  1616. X                     (if (equal (nth 2 a)
  1617. X                        '(neg (var inf var-inf)))
  1618. X                     (logand (nth 1 a) 2) 0)
  1619. X                     (if (equal (nth 2 b)
  1620. X                        '(neg (var inf var-inf)))
  1621. X                     (logand (nth 1 b) 2) 0)
  1622. X                     (if (equal (nth 3 a) '(var inf var-inf))
  1623. X                     (logand (nth 1 a) 1) 0)
  1624. X                     (if (equal (nth 3 b) '(var inf var-inf))
  1625. X                     (logand (nth 1 b) 1) 0))
  1626. X                 (math-add (nth 2 a) (nth 2 b))
  1627. X                 (math-add (nth 3 a) (nth 3 b)))
  1628. X       (and (or (Math-anglep b)
  1629. X            (eq (car b) 'date)
  1630. X            (not (Math-objvecp b)))
  1631. X        (math-make-intv (nth 1 a)
  1632. X                (math-add (nth 2 a) b)
  1633. X                (math-add (nth 3 a) b)))))
  1634. X    ((and (eq (car-safe b) 'intv)
  1635. X          (or (Math-anglep a)
  1636. X          (eq (car a) 'date)
  1637. X          (not (Math-objvecp a))))
  1638. X     (math-make-intv (nth 1 b)
  1639. X             (math-add a (nth 2 b))
  1640. X             (math-add a (nth 3 b))))
  1641. X    ((eq (car-safe a) 'date)
  1642. X     (cond ((eq (car-safe b) 'date)
  1643. X        (math-add (nth 1 a) (nth 1 b)))
  1644. X           ((eq (car-safe b) 'hms)
  1645. X        (let ((parts (math-date-parts (nth 1 a))))
  1646. X          (list 'date
  1647. X            (math-add (car parts)   ; this minimizes roundoff
  1648. X                  (math-div (math-add
  1649. X                         (math-add (nth 1 parts)
  1650. X                               (nth 2 parts))
  1651. X                         (math-add
  1652. X                          (math-mul (nth 1 b) 3600)
  1653. X                          (math-add (math-mul (nth 2 b) 60)
  1654. X                            (nth 3 b))))
  1655. X                        86400)))))
  1656. X           ((Math-realp b)
  1657. X        (list 'date (math-add (nth 1 a) b)))
  1658. X           (t nil)))
  1659. X    ((eq (car-safe b) 'date)
  1660. X     (math-add-objects-fancy b a))
  1661. X    ((and (eq (car-safe a) 'mod)
  1662. X          (eq (car-safe b) 'mod)
  1663. X          (equal (nth 2 a) (nth 2 b)))
  1664. X     (math-make-mod (math-add (nth 1 a) (nth 1 b)) (nth 2 a)))
  1665. X    ((and (eq (car-safe a) 'mod)
  1666. X          (Math-anglep b))
  1667. X     (math-make-mod (math-add (nth 1 a) b) (nth 2 a)))
  1668. X    ((and (eq (car-safe b) 'mod)
  1669. X          (Math-anglep a))
  1670. X     (math-make-mod (math-add a (nth 1 b)) (nth 2 b)))
  1671. X    ((and (or (eq (car-safe a) 'hms) (eq (car-safe b) 'hms))
  1672. X          (and (Math-anglep a) (Math-anglep b)))
  1673. X     (or (eq (car-safe a) 'hms) (setq a (math-to-hms a)))
  1674. X     (or (eq (car-safe b) 'hms) (setq b (math-to-hms b)))
  1675. X     (math-normalize
  1676. X      (if (math-negp a)
  1677. X          (math-neg (math-add (math-neg a) (math-neg b)))
  1678. X        (if (math-negp b)
  1679. X        (let* ((s (math-add (nth 3 a) (nth 3 b)))
  1680. X               (m (math-add (nth 2 a) (nth 2 b)))
  1681. X               (h (math-add (nth 1 a) (nth 1 b))))
  1682. X          (if (math-negp s)
  1683. X              (setq s (math-add s 60)
  1684. X                m (math-add m -1)))
  1685. X          (if (math-negp m)
  1686. X              (setq m (math-add m 60)
  1687. X                h (math-add h -1)))
  1688. X          (if (math-negp h)
  1689. X              (math-add b a)
  1690. X            (list 'hms h m s)))
  1691. X          (let* ((s (math-add (nth 3 a) (nth 3 b)))
  1692. X             (m (math-add (nth 2 a) (nth 2 b)))
  1693. X             (h (math-add (nth 1 a) (nth 1 b))))
  1694. X        (list 'hms h m s))))))
  1695. X    (t (calc-record-why "*Incompatible arguments for +" a b)))
  1696. )
  1697. X
  1698. (defun math-add-symb-fancy (a b)
  1699. X  (or (and math-simplify-only
  1700. X       (not (equal a math-simplify-only))
  1701. X       (list '+ a b))
  1702. X      (and (eq (car-safe b) '+)
  1703. X       (math-add (math-add a (nth 1 b))
  1704. X             (nth 2 b)))
  1705. X      (and (eq (car-safe b) '-)
  1706. X       (math-sub (math-add a (nth 1 b))
  1707. X             (nth 2 b)))
  1708. X      (and (eq (car-safe b) 'neg)
  1709. X       (eq (car-safe (nth 1 b)) '+)
  1710. X       (math-sub (math-sub a (nth 1 (nth 1 b)))
  1711. X             (nth 2 (nth 1 b))))
  1712. X      (and (or (and (Math-vectorp a) (math-known-scalarp b))
  1713. X           (and (Math-vectorp b) (math-known-scalarp a)))
  1714. X       (math-map-vec-2 'math-add a b))
  1715. X      (let ((inf (math-infinitep a)))
  1716. X    (cond
  1717. X     (inf
  1718. X      (let ((inf2 (math-infinitep b)))
  1719. X        (if inf2
  1720. X        (if (or (memq (nth 2 inf) '(var-uinf var-nan))
  1721. X            (memq (nth 2 inf2) '(var-uinf var-nan)))
  1722. X            '(var nan var-nan)
  1723. X          (let ((dir (math-infinite-dir a inf))
  1724. X            (dir2 (math-infinite-dir b inf2)))
  1725. X            (if (and (Math-objectp dir) (Math-objectp dir2))
  1726. X            (if (Math-equal dir dir2)
  1727. X                a
  1728. X              '(var nan var-nan)))))
  1729. X          (if (and (equal a '(var inf var-inf))
  1730. X               (eq (car-safe b) 'intv)
  1731. X               (memq (nth 1 b) '(2 3))
  1732. X               (equal (nth 2 b) '(neg (var inf var-inf))))
  1733. X          (list 'intv 3 (nth 2 b) a)
  1734. X        (if (and (equal a '(neg (var inf var-inf)))
  1735. X             (eq (car-safe b) 'intv)
  1736. X             (memq (nth 1 b) '(1 3))
  1737. X             (equal (nth 3 b) '(var inf var-inf)))
  1738. X            (list 'intv 3 a (nth 3 b))
  1739. X          a)))))
  1740. X     ((math-infinitep b)
  1741. X      (if (eq (car-safe a) 'intv)
  1742. X          (math-add b a)
  1743. X        b))
  1744. X     ((eq (car-safe a) '+)
  1745. X      (let ((temp (math-combine-sum (nth 2 a) b nil nil t)))
  1746. X        (and temp
  1747. X         (math-add (nth 1 a) temp))))
  1748. X     ((eq (car-safe a) '-)
  1749. X      (let ((temp (math-combine-sum (nth 2 a) b t nil t)))
  1750. X        (and temp
  1751. X         (math-add (nth 1 a) temp))))
  1752. X     ((and (Math-objectp a) (Math-objectp b))
  1753. X      nil)
  1754. X     (t
  1755. X      (math-combine-sum a b nil nil nil))))
  1756. X      (and (Math-looks-negp b)
  1757. X       (list '- a (math-neg b)))
  1758. X      (and (Math-looks-negp a)
  1759. X       (list '- b (math-neg a)))
  1760. X      (and (eq (car-safe a) 'calcFunc-idn)
  1761. X       (= (length a) 2)
  1762. X       (or (and (eq (car-safe b) 'calcFunc-idn)
  1763. X            (= (length b) 2)
  1764. X            (list 'calcFunc-idn (math-add (nth 1 a) (nth 1 b))))
  1765. X           (and (math-square-matrixp b)
  1766. X            (math-add (math-mimic-ident (nth 1 a) b) b))
  1767. X           (and (math-known-scalarp b)
  1768. X            (math-add (nth 1 a) b))))
  1769. X      (and (eq (car-safe b) 'calcFunc-idn)
  1770. X       (= (length a) 2)
  1771. X       (or (and (math-square-matrixp a)
  1772. X            (math-add a (math-mimic-ident (nth 1 b) a)))
  1773. X           (and (math-known-scalarp a)
  1774. X            (math-add a (nth 1 b)))))
  1775. X      (list '+ a b))
  1776. )
  1777. X
  1778. X
  1779. (defun calcFunc-mul (&rest rest)
  1780. X  (if rest
  1781. X      (let ((a (car rest)))
  1782. X    (while (setq rest (cdr rest))
  1783. X      (setq a (list '* a (car rest))))
  1784. X    (math-normalize a))
  1785. X    1)
  1786. )
  1787. X
  1788. (defun math-mul-objects-fancy (a b)
  1789. X  (cond ((and (Math-numberp a) (Math-numberp b))
  1790. X     (math-normalize
  1791. X      (if (math-want-polar a b)
  1792. X          (let ((a (math-polar a))
  1793. X            (b (math-polar b)))
  1794. X        (list 'polar
  1795. X              (math-mul (nth 1 a) (nth 1 b))
  1796. X              (math-fix-circular (math-add (nth 2 a) (nth 2 b)))))
  1797. X        (setq a (math-complex a)
  1798. X          b (math-complex b))
  1799. X        (list 'cplx
  1800. X          (math-sub (math-mul (nth 1 a) (nth 1 b))
  1801. X                (math-mul (nth 2 a) (nth 2 b)))
  1802. X          (math-add (math-mul (nth 1 a) (nth 2 b))
  1803. X                (math-mul (nth 2 a) (nth 1 b)))))))
  1804. X    ((Math-vectorp a)
  1805. X     (if (Math-vectorp b)
  1806. X         (if (math-matrixp a)
  1807. X         (if (math-matrixp b)
  1808. X             (if (= (length (nth 1 a)) (length b))
  1809. X             (math-mul-mats a b)
  1810. X               (math-dimension-error))
  1811. X           (if (= (length (nth 1 a)) 2)
  1812. X               (if (= (length a) (length b))
  1813. X               (math-mul-mats a (list 'vec b))
  1814. X             (math-dimension-error))
  1815. X             (if (= (length (nth 1 a)) (length b))
  1816. X             (math-mul-mat-vec a b)
  1817. X               (math-dimension-error))))
  1818. X           (if (math-matrixp b)
  1819. X           (if (= (length a) (length b))
  1820. X               (nth 1 (math-mul-mats (list 'vec a) b))
  1821. X             (math-dimension-error))
  1822. X         (if (= (length a) (length b))
  1823. X             (math-dot-product a b)
  1824. X           (math-dimension-error))))
  1825. X       (math-map-vec-2 'math-mul a b)))
  1826. X    ((Math-vectorp b)
  1827. X     (math-map-vec-2 'math-mul a b))
  1828. X    ((eq (car-safe a) 'sdev)
  1829. X     (if (eq (car-safe b) 'sdev)
  1830. X         (math-make-sdev (math-mul (nth 1 a) (nth 1 b))
  1831. X                 (math-hypot (math-mul (nth 2 a) (nth 1 b))
  1832. X                     (math-mul (nth 2 b) (nth 1 a))))
  1833. X       (and (or (Math-scalarp b)
  1834. X            (not (Math-objvecp b)))
  1835. X        (math-make-sdev (math-mul (nth 1 a) b)
  1836. X                (math-mul (nth 2 a) b)))))
  1837. X    ((and (eq (car-safe b) 'sdev)
  1838. X          (or (Math-scalarp a)
  1839. X          (not (Math-objvecp a))))
  1840. X     (math-make-sdev (math-mul a (nth 1 b)) (math-mul a (nth 2 b))))
  1841. X    ((and (eq (car-safe a) 'intv) (Math-anglep b))
  1842. X     (if (Math-negp b)
  1843. X         (math-neg (math-mul a (math-neg b)))
  1844. X       (math-make-intv (nth 1 a)
  1845. X               (math-mul (nth 2 a) b)
  1846. X               (math-mul (nth 3 a) b))))
  1847. X    ((and (eq (car-safe b) 'intv) (Math-anglep a))
  1848. X     (math-mul b a))
  1849. X    ((and (eq (car-safe a) 'intv) (math-intv-constp a)
  1850. X          (eq (car-safe b) 'intv) (math-intv-constp b))
  1851. X     (let ((lo (math-mul a (nth 2 b)))
  1852. X           (hi (math-mul a (nth 3 b))))
  1853. X       (or (eq (car-safe lo) 'intv)
  1854. X           (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0) lo lo)))
  1855. X       (or (eq (car-safe hi) 'intv)
  1856. X           (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0) hi hi)))
  1857. X       (math-combine-intervals
  1858. X        (nth 2 lo) (and (or (memq (nth 1 b) '(2 3))
  1859. X                (math-infinitep (nth 2 lo)))
  1860. X                (memq (nth 1 lo) '(2 3)))
  1861. X        (nth 3 lo) (and (or (memq (nth 1 b) '(2 3))
  1862. X                (math-infinitep (nth 3 lo)))
  1863. X                (memq (nth 1 lo) '(1 3)))
  1864. X        (nth 2 hi) (and (or (memq (nth 1 b) '(1 3))
  1865. X                (math-infinitep (nth 2 hi)))
  1866. X                (memq (nth 1 hi) '(2 3)))
  1867. X        (nth 3 hi) (and (or (memq (nth 1 b) '(1 3))
  1868. X                (math-infinitep (nth 3 hi)))
  1869. X                (memq (nth 1 hi) '(1 3))))))
  1870. X    ((and (eq (car-safe a) 'mod)
  1871. X          (eq (car-safe b) 'mod)
  1872. X          (equal (nth 2 a) (nth 2 b)))
  1873. X     (math-make-mod (math-mul (nth 1 a) (nth 1 b)) (nth 2 a)))
  1874. X    ((and (eq (car-safe a) 'mod)
  1875. X          (Math-anglep b))
  1876. X     (math-make-mod (math-mul (nth 1 a) b) (nth 2 a)))
  1877. X    ((and (eq (car-safe b) 'mod)
  1878. X          (Math-anglep a))
  1879. X     (math-make-mod (math-mul a (nth 1 b)) (nth 2 b)))
  1880. X    ((and (eq (car-safe a) 'hms) (Math-realp b))
  1881. X     (math-with-extra-prec 2
  1882. X       (math-to-hms (math-mul (math-from-hms a 'deg) b) 'deg)))
  1883. X    ((and (eq (car-safe b) 'hms) (Math-realp a))
  1884. X     (math-mul b a))
  1885. X    (t (calc-record-why "*Incompatible arguments for *" a b)))
  1886. SHAR_EOF
  1887. true || echo 'restore of calc-arith.el failed'
  1888. fi
  1889. echo 'End of  part 8'
  1890. echo 'File calc-arith.el is continued in part 9'
  1891. echo 9 > _shar_seq_.tmp
  1892. exit 0
  1893. exit 0 # Just in case...
  1894. -- 
  1895. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1896. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1897. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1898. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1899.