home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume13 / gmcalc / part07 < prev    next >
Encoding:
Text File  |  1990-06-05  |  57.1 KB  |  1,916 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@csvax.caltech.edu (David Gillespie)
  3. Subject: v13i033: Emacs Calculator 1.01, part 07/19
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 13, Issue 33
  7. Submitted-by: daveg@csvax.caltech.edu (David Gillespie)
  8. Archive-name: gmcalc/part07
  9.  
  10. ---- Cut Here and unpack ----
  11. #!/bin/sh
  12. # this is part 7 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file calc-ext.el continued
  15. #
  16. CurArch=7
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file calc-ext.el"
  27. sed 's/^X//' << 'SHAR_EOF' >> calc-ext.el
  28. X
  29. X;;; Create a vector of consecutive integers. [Public]
  30. X(defun math-vec-index (n)
  31. X  (and (not (integerp n))
  32. X       (setq n (math-check-fixnum n)))
  33. X  (or (natnump n) (math-reject-arg n 'natnump))
  34. X  (let ((vec nil))
  35. X    (while (> n 0)
  36. X      (setq vec (cons n vec)
  37. X        n (1- n)))
  38. X    (cons 'vec vec))
  39. X)
  40. X(fset 'calcFunc-index (symbol-function 'math-vec-index))
  41. X
  42. X
  43. X;;; Compute the row and column norms of a vector or matrix.  [Public]
  44. X(defun math-rnorm (a)
  45. X  (if (and (Math-vectorp a)
  46. X       (math-constp a))
  47. X      (if (math-matrixp a)
  48. X      (math-reduce-vec 'math-max (math-map-vec 'math-cnorm a))
  49. X    (math-reduce-vec 'math-max (math-map-vec 'math-abs a)))
  50. X    (calc-record-why 'vectorp a)
  51. X    (list 'calcFunc-rnorm a))
  52. X)
  53. X(fset 'calcFunc-rnorm (symbol-function 'math-rnorm))
  54. X
  55. X(defun math-cnorm (a)
  56. X  (if (and (Math-vectorp a)
  57. X       (math-constp a))
  58. X      (if (math-matrixp a)
  59. X      (math-reduce-vec 'math-max
  60. X               (math-reduce-cols 'math-add-abs a))
  61. X    (math-reduce-vec 'math-add-abs a))
  62. X    (calc-record-why 'vectorp a)
  63. X    (list 'calcFunc-cnorm a))
  64. X)
  65. X(fset 'calcFunc-cnorm (symbol-function 'math-cnorm))
  66. X
  67. X(defun math-add-abs (a b)
  68. X  (math-add (math-abs a) (math-abs b))
  69. X)
  70. X
  71. X
  72. X;;; Sort the elements of a vector into increasing order.
  73. X(defun math-sort-vector (vec)   ; [Public]
  74. X  (if (math-vectorp vec)
  75. X      (cons 'vec (sort (copy-sequence (cdr vec)) 'math-beforep))
  76. X    (math-reject-arg vec 'vectorp))
  77. X)
  78. X(fset 'calcFunc-sort (symbol-function 'math-sort-vector))
  79. X
  80. X(defun math-rsort-vector (vec)   ; [Public]
  81. X  (if (math-vectorp vec)
  82. X      (cons 'vec (nreverse (sort (copy-sequence (cdr vec)) 'math-beforep)))
  83. X    (math-reject-arg vec 'vectorp))
  84. X)
  85. X(fset 'calcFunc-rsort (symbol-function 'math-rsort-vector))
  86. X
  87. X
  88. X;;; Compile a histogram of data from a vector.
  89. X(defun math-histogram (vec wts n)
  90. X  (or (Math-vectorp vec)
  91. X      (math-reject-arg vec 'vectorp))
  92. X  (if (Math-vectorp wts)
  93. X      (or (= (length vec) (length wts))
  94. X      (math-dimension-error)))
  95. X  (or (natnump n)
  96. X      (math-reject-arg n 'natnump))
  97. X  (let ((res (make-vector n 0))
  98. X    (vp vec)
  99. X    (wvec (Math-vectorp wts))
  100. X    (wp wts)
  101. X    bin)
  102. X    (while (setq vp (cdr vp))
  103. X      (setq bin (car vp))
  104. X      (or (natnump bin)
  105. X      (setq bin (math-floor bin)))
  106. X      (and (natnump bin)
  107. X       (< bin n)
  108. X       (aset res bin (math-add (aref res bin)
  109. X                   (if wvec (car (setq wp (cdr wp))) wts)))))
  110. X    (cons 'vec (append res nil)))
  111. X)
  112. X(fset 'calcFunc-histogram (symbol-function 'math-histogram))
  113. X
  114. X
  115. X(defun math-matrix-trace (mat)   ; [Public]
  116. X  (if (math-square-matrixp mat)
  117. X      (math-matrix-trace-step 2 (1- (length mat)) mat (nth 1 (nth 1 mat)))
  118. X    (math-reject-arg mat 'square-matrixp))
  119. X)
  120. X(fset 'calcFunc-tr (symbol-function 'math-matrix-trace))
  121. X
  122. X(defun math-matrix-trace-step (n size mat sum)
  123. X  (if (<= n size)
  124. X      (math-matrix-trace-step (1+ n) size mat
  125. X                  (math-add sum (nth n (nth n mat))))
  126. X    sum)
  127. X)
  128. X
  129. X
  130. X;;; Matrix inverse and determinant.
  131. X(defun math-matrix-inv-raw (m)
  132. X  (let ((n (1- (length m))))
  133. X    (if (<= n 3)
  134. X    (let ((det (math-det-raw m)))
  135. X      (and (not (math-zerop det))
  136. X           (math-div
  137. X        (cond ((= n 1) 1)
  138. X              ((= n 2)
  139. X               (list 'vec
  140. X                 (list 'vec
  141. X                   (nth 2 (nth 2 m))
  142. X                   (math-neg (nth 2 (nth 1 m))))
  143. X                 (list 'vec
  144. X                   (math-neg (nth 1 (nth 2 m)))
  145. X                   (nth 1 (nth 1 m)))))
  146. X              ((= n 3)
  147. X               (list 'vec
  148. X                 (list 'vec
  149. X                   (math-sub (math-mul (nth 3 (nth 3 m))
  150. X                               (nth 2 (nth 2 m)))
  151. X                         (math-mul (nth 3 (nth 2 m))
  152. X                               (nth 2 (nth 3 m))))
  153. X                   (math-sub (math-mul (nth 3 (nth 1 m))
  154. X                               (nth 2 (nth 3 m)))
  155. X                         (math-mul (nth 3 (nth 3 m))
  156. X                               (nth 2 (nth 1 m))))
  157. X                   (math-sub (math-mul (nth 3 (nth 2 m))
  158. X                               (nth 2 (nth 1 m)))
  159. X                         (math-mul (nth 3 (nth 1 m))
  160. X                               (nth 2 (nth 2 m)))))
  161. X                 (list 'vec
  162. X                   (math-sub (math-mul (nth 3 (nth 2 m))
  163. X                               (nth 1 (nth 3 m)))
  164. X                         (math-mul (nth 3 (nth 3 m))
  165. X                               (nth 1 (nth 2 m))))
  166. X                   (math-sub (math-mul (nth 3 (nth 3 m))
  167. X                               (nth 1 (nth 1 m)))
  168. X                         (math-mul (nth 3 (nth 1 m))
  169. X                               (nth 1 (nth 3 m))))
  170. X                   (math-sub (math-mul (nth 3 (nth 1 m))
  171. X                               (nth 1 (nth 2 m)))
  172. X                         (math-mul (nth 3 (nth 2 m))
  173. X                               (nth 1 (nth 1 m)))))
  174. X                 (list 'vec
  175. X                   (math-sub (math-mul (nth 2 (nth 3 m))
  176. X                               (nth 1 (nth 2 m)))
  177. X                         (math-mul (nth 2 (nth 2 m))
  178. X                               (nth 1 (nth 3 m))))
  179. X                   (math-sub (math-mul (nth 2 (nth 1 m))
  180. X                               (nth 1 (nth 3 m)))
  181. X                         (math-mul (nth 2 (nth 3 m))
  182. X                               (nth 1 (nth 1 m))))
  183. X                   (math-sub (math-mul (nth 2 (nth 2 m))
  184. X                               (nth 1 (nth 1 m)))
  185. X                         (math-mul (nth 2 (nth 1 m))
  186. X                               (nth 1 (nth 2 m))))))))
  187. X        det)))
  188. X      (let ((lud (math-matrix-lud m)))
  189. X    (and lud
  190. X         (math-lud-solve lud (math-diag-matrix 1 n))))))
  191. X)
  192. X
  193. X(defun math-matrix-det (m)
  194. X  (if (math-square-matrixp m)
  195. X      (math-with-extra-prec 2 (math-det-raw m))
  196. X    (math-reject-arg m 'square-matrixp))
  197. X)
  198. X(fset 'calcFunc-det (symbol-function 'math-matrix-det))
  199. X
  200. X(defun math-det-raw (m)
  201. X  (let ((n (1- (length m))))
  202. X    (cond ((= n 1)
  203. X       (nth 1 (nth 1 m)))
  204. X      ((= n 2)
  205. X       (math-sub (math-mul (nth 1 (nth 1 m))
  206. X                   (nth 2 (nth 2 m)))
  207. X             (math-mul (nth 2 (nth 1 m))
  208. X                   (nth 1 (nth 2 m)))))
  209. X      ((= n 3)
  210. X       (math-sub
  211. X        (math-sub
  212. X         (math-sub
  213. X          (math-add
  214. X           (math-add
  215. X        (math-mul (nth 1 (nth 1 m))
  216. X              (math-mul (nth 2 (nth 2 m))
  217. X                    (nth 3 (nth 3 m))))
  218. X        (math-mul (nth 2 (nth 1 m))
  219. X              (math-mul (nth 3 (nth 2 m))
  220. X                    (nth 1 (nth 3 m)))))
  221. X           (math-mul (nth 3 (nth 1 m))
  222. X             (math-mul (nth 1 (nth 2 m))
  223. X                   (nth 2 (nth 3 m)))))
  224. X          (math-mul (nth 3 (nth 1 m))
  225. X            (math-mul (nth 2 (nth 2 m))
  226. X                  (nth 1 (nth 3 m)))))
  227. X         (math-mul (nth 1 (nth 1 m))
  228. X               (math-mul (nth 3 (nth 2 m))
  229. X                 (nth 2 (nth 3 m)))))
  230. X        (math-mul (nth 2 (nth 1 m))
  231. X              (math-mul (nth 1 (nth 2 m))
  232. X                (nth 3 (nth 3 m))))))
  233. X      (t (let ((lud (math-matrix-lud m)))
  234. X           (if lud
  235. X           (let ((lu (car lud)))
  236. X             (math-det-step n (nth 2 lud)))
  237. X         0)))))
  238. X)
  239. X
  240. X(defun math-det-step (n prod)
  241. X  (if (> n 0)
  242. X      (math-det-step (1- n) (math-mul prod (nth n (nth n lu))))
  243. X    prod)
  244. X)
  245. X
  246. X;;; This returns a list (LU index d), or NIL if not possible.
  247. X;;; Argument M must be a square matrix.
  248. X(defun math-matrix-lud (m)
  249. X  (let ((old (assoc m math-lud-cache))
  250. X    (context (list calc-internal-prec calc-prefer-frac)))
  251. X    (if (and old (equal (nth 1 old) context))
  252. X    (cdr (cdr old))
  253. X      (let* ((lud (catch 'singular (math-do-matrix-lud m)))
  254. X         (entry (cons context lud)))
  255. X    (if old
  256. X        (setcdr old entry)
  257. X      (setq math-lud-cache (cons (cons m entry) math-lud-cache)))
  258. X    lud)))
  259. X)
  260. X(defvar math-lud-cache nil)
  261. X
  262. X;;; Numerical Recipes section 2.3; implicit pivoting omitted.
  263. X(defun math-do-matrix-lud (m)
  264. X  (let* ((lu (math-copy-matrix m))
  265. X     (n (1- (length lu)))
  266. X     i (j 1) k imax sum big
  267. X     (d 1) (index nil))
  268. X    (while (<= j n)
  269. X      (setq i 1
  270. X        big 0
  271. X        imax j)
  272. X      (while (< i j)
  273. X    (math-working "LUD step" (format "%d/%d" j i))
  274. X    (setq sum (nth j (nth i lu))
  275. X          k 1)
  276. X    (while (< k i)
  277. X      (setq sum (math-sub sum (math-mul (nth k (nth i lu))
  278. X                        (nth j (nth k lu))))
  279. X        k (1+ k)))
  280. X    (setcar (nthcdr j (nth i lu)) sum)
  281. X    (setq i (1+ i)))
  282. X      (while (<= i n)
  283. X    (math-working "LUD step" (format "%d/%d" j i))
  284. X    (setq sum (nth j (nth i lu))
  285. X          k 1)
  286. X    (while (< k j)
  287. X      (setq sum (math-sub sum (math-mul (nth k (nth i lu))
  288. X                        (nth j (nth k lu))))
  289. X        k (1+ k)))
  290. X    (setcar (nthcdr j (nth i lu)) sum)
  291. X    (let ((dum (math-abs-approx sum)))
  292. X      (if (Math-lessp big dum)
  293. X          (setq big dum
  294. X            imax i)))
  295. X    (setq i (1+ i)))
  296. X      (if (> imax j)
  297. X      (setq lu (math-swap-rows lu j imax)
  298. X        d (- d)))
  299. X      (setq index (cons imax index))
  300. X      (let ((pivot (nth j (nth j lu))))
  301. X    (if (math-zerop pivot)
  302. X        (throw 'singular nil)
  303. X      (setq i j)
  304. X      (while (<= (setq i (1+ i)) n)
  305. X        (setcar (nthcdr j (nth i lu))
  306. X            (math-div (nth j (nth i lu)) pivot)))))
  307. X      (setq j (1+ j)))
  308. X    (list lu (nreverse index) d))
  309. X)
  310. X
  311. X(defun math-swap-rows (m r1 r2)
  312. X  (or (= r1 r2)
  313. X      (let* ((r1prev (nthcdr (1- r1) m))
  314. X         (row1 (cdr r1prev))
  315. X         (r2prev (nthcdr (1- r2) m))
  316. X         (row2 (cdr r2prev))
  317. X         (r2next (cdr row2)))
  318. X    (setcdr r2prev row1)
  319. X    (setcdr r1prev row2)
  320. X    (setcdr row2 (cdr row1))
  321. X    (setcdr row1 r2next)))
  322. X  m
  323. X)
  324. X
  325. X(defun math-abs-approx (a)
  326. X  (cond ((Math-negp a)
  327. X     (math-neg a))
  328. X    ((Math-anglep a)
  329. X     a)
  330. X    ((eq (car a) 'cplx)
  331. X     (math-add (math-abs (nth 1 a)) (math-abs (nth 2 a))))
  332. X    ((eq (car a) 'polar)
  333. X     (nth 1 a))
  334. X    ((eq (car a) 'sdev)
  335. X     (math-abs (nth 1 a)))
  336. X    ((eq (car a) 'intv)
  337. X     (math-max (math-abs (nth 2 a)) (math-abs (nth 3 a))))
  338. X    ((eq (car a) 'vec)
  339. X     (math-cnorm a))
  340. X    ((eq (car a) 'calcFunc-abs)
  341. X     (car a))
  342. X    (t a))
  343. X)
  344. X
  345. X(defun math-lud-solve (lud b)
  346. X  (and lud
  347. X     (let* ((x (math-copy-matrix b))
  348. X        (n (1- (length x)))
  349. X        (m (1- (length (nth 1 x))))
  350. X        (lu (car lud))
  351. X        (col 1)
  352. X        i j ip ii index sum)
  353. X       (while (<= col m)
  354. X         (math-working "LUD solver step" col)
  355. X         (setq i 1
  356. X           ii nil
  357. X           index (nth 1 lud))
  358. X         (while (<= i n)
  359. X           (setq ip (car index)
  360. X             index (cdr index)
  361. X             sum (nth col (nth ip x)))
  362. X           (setcar (nthcdr col (nth ip x)) (nth col (nth i x)))
  363. X           (if (null ii)
  364. X           (or (math-zerop sum)
  365. X               (setq ii i))
  366. X         (setq j ii)
  367. X         (while (< j i)
  368. X           (setq sum (math-sub sum (math-mul (nth j (nth i lu))
  369. X                             (nth col (nth j x))))
  370. X             j (1+ j))))
  371. X           (setcar (nthcdr col (nth i x)) sum)
  372. X           (setq i (1+ i)))
  373. X         (while (>= (setq i (1- i)) 1)
  374. X           (setq sum (nth col (nth i x))
  375. X             j i)
  376. X           (while (<= (setq j (1+ j)) n)
  377. X         (setq sum (math-sub sum (math-mul (nth j (nth i lu))
  378. X                           (nth col (nth j x))))))
  379. X           (setcar (nthcdr col (nth i x))
  380. X               (math-div sum (nth i (nth i lu)))))
  381. X         (setq col (1+ col)))
  382. X       x))
  383. X)
  384. X
  385. X(defun calcFunc-lud (m)
  386. X  (if (math-square-matrixp m)
  387. X      (or (math-with-extra-prec 2
  388. X        (let ((lud (math-matrix-lud m)))
  389. X          (and lud
  390. X           (let* ((lmat (math-copy-matrix (car lud)))
  391. X              (umat (math-copy-matrix (car lud)))
  392. X              (n (1- (length (car lud))))
  393. X              (perm (math-diag-matrix 1 n))
  394. X              i (j 1))
  395. X             (while (<= j n)
  396. X               (setq i 1)
  397. X               (while (< i j)
  398. X             (setcar (nthcdr j (nth i lmat)) 0)
  399. X             (setq i (1+ i)))
  400. X               (setcar (nthcdr j (nth j lmat)) 1)
  401. X               (while (<= (setq i (1+ i)) n)
  402. X             (setcar (nthcdr j (nth i umat)) 0))
  403. X               (setq j (1+ j)))
  404. X             (while (>= (setq j (1- j)) 1)
  405. X               (let ((pos (nth (1- j) (nth 1 lud))))
  406. X             (or (= pos j)
  407. X                 (setq perm (math-swap-rows perm j pos)))))
  408. X             (list 'vec perm lmat umat)))))
  409. X      (math-reject-arg m "Singular matrix"))
  410. X    (math-reject-arg m 'square-matrixp))
  411. X)
  412. X
  413. X;;; Compute a right-handed vector cross product.  [O O O] [Public]
  414. X(defun math-cross (a b)
  415. X  (if (and (eq (car-safe a) 'vec)
  416. X       (= (length a) 4))
  417. X      (if (and (eq (car-safe b) 'vec)
  418. X           (= (length b) 4))
  419. X      (list 'vec
  420. X        (math-sub (math-mul (nth 2 a) (nth 3 b))
  421. X              (math-mul (nth 3 a) (nth 2 b)))
  422. X        (math-sub (math-mul (nth 3 a) (nth 1 b))
  423. X              (math-mul (nth 1 a) (nth 3 b)))
  424. X        (math-sub (math-mul (nth 1 a) (nth 2 b))
  425. X              (math-mul (nth 2 a) (nth 1 b))))
  426. X    (math-reject-arg b "Three-vector expected"))
  427. X    (math-reject-arg a "Three-vector expected"))
  428. X)
  429. X(fset 'calcFunc-cross (symbol-function 'math-cross))
  430. X
  431. X
  432. X
  433. X
  434. X;;;; Hours-minutes-seconds forms.
  435. X
  436. X(defun math-normalize-hms (a)
  437. X  (let ((h (math-normalize (nth 1 a)))
  438. X    (m (math-normalize (nth 2 a)))
  439. X    (s (let ((calc-internal-prec (max (- calc-internal-prec 4) 3)))
  440. X         (math-normalize (nth 3 a)))))
  441. X    (if (math-negp h)
  442. X    (progn
  443. X      (if (math-posp s)
  444. X          (setq s (math-add s -60)
  445. X            m (math-add m 1)))
  446. X      (if (math-posp m)
  447. X          (setq m (math-add m -60)
  448. X            h (math-add h 1)))
  449. X      (if (not (math-lessp -60 s))
  450. X          (setq s (math-add s 60)
  451. X            m (math-add m -1)))
  452. X      (if (not (math-lessp -60 m))
  453. X          (setq m (math-add m 60)
  454. X            h (math-add h -1))))
  455. X      (if (math-negp s)
  456. X      (setq s (math-add s 60)
  457. X        m (math-add m -1)))
  458. X      (if (math-negp m)
  459. X      (setq m (math-add m 60)
  460. X        h (math-add h -1)))
  461. X      (if (not (math-lessp s 60))
  462. X      (setq s (math-add s -60)
  463. X        m (math-add m 1)))
  464. X      (if (not (math-lessp m 60))
  465. X      (setq m (math-add m -60)
  466. X        h (math-add h 1))))
  467. X    (if (and (eq (car-safe s) 'float)
  468. X         (<= (+ (math-numdigs (nth 1 s)) (nth 2 s))
  469. X         (- 2 calc-internal-prec)))
  470. X    (setq s 0))
  471. X    (list 'hms h m s))
  472. X)
  473. X
  474. X;;; Convert A from ANG or current angular mode to HMS format.
  475. X(defun math-to-hms (a &optional ang)   ; [X R] [Public]
  476. X  (cond ((eq (car-safe a) 'hms) a)
  477. X    ((eq (car-safe a) 'sdev)
  478. X     (math-make-sdev (math-to-hms (nth 1 a))
  479. X             (math-to-hms (nth 2 a))))
  480. X    ((not (Math-numberp a))
  481. X     (list 'calcFunc-hms a))
  482. X    ((math-negp a)
  483. X     (math-neg (math-to-hms (math-neg a) ang)))
  484. X    ((eq (or ang calc-angle-mode) 'rad)
  485. X     (math-to-hms (math-div a (math-pi-over-180)) 'deg))
  486. X    ((memq (car-safe a) '(cplx polar)) a)
  487. X    (t
  488. X     ;(setq a (let ((calc-internal-prec (max (1- calc-internal-prec) 3)))
  489. X     ;        (math-normalize a)))
  490. X     (math-normalize
  491. X      (let* ((b (math-mul a 3600))
  492. X         (hm (math-trunc (math-div b 60)))
  493. X         (hmd (math-idivmod hm 60)))
  494. X        (list 'hms
  495. X          (car hmd)
  496. X          (cdr hmd)
  497. X          (math-sub b (math-mul hm 60)))))))
  498. X)
  499. X(fset 'calcFunc-hms (symbol-function 'math-to-hms))
  500. X
  501. X;;; Convert A from HMS format to ANG or current angular mode.
  502. X(defun math-from-hms (a &optional ang)   ; [R X] [Public]
  503. X  (cond ((not (eq (car-safe a) 'hms))
  504. X     (if (Math-numberp a)
  505. X         a
  506. X       (if (eq (car-safe a) 'sdev)
  507. X         (math-make-sdev (math-from-hms (nth 1 a))
  508. X                 (math-from-hms (nth 2 a)))
  509. X         (if (eq (or ang calc-angle-mode) 'rad)
  510. X         (list '>rad a)
  511. X           (list '>deg a)))))
  512. X    ((math-negp a)
  513. X     (math-neg (math-from-hms (math-neg a) ang)))
  514. X    ((eq (or ang calc-angle-mode) 'rad)
  515. X     (math-mul (math-from-hms a 'deg) (math-pi-over-180)))
  516. X    ((memq (car-safe a) '(cplx polar)) a)
  517. X    (t
  518. X     (math-add (math-div (math-add (math-div (nth 3 a)
  519. X                         '(float 6 1))
  520. X                       (nth 2 a))
  521. X                 60)
  522. X           (nth 1 a))))
  523. X)
  524. X
  525. X
  526. X
  527. X;;;; Complex numbers.
  528. X
  529. X(defun math-normalize-polar (a)
  530. X  (let ((r (math-normalize (nth 1 a)))
  531. X    (th (math-normalize (nth 2 a))))
  532. X    (cond ((math-zerop r)
  533. X       '(polar 0 0))
  534. X      ((or (math-zerop th))
  535. X       r)
  536. X      ((and (not (eq calc-angle-mode 'rad))
  537. X        (or (equal th '(float 18 1))
  538. X            (equal th 180)))
  539. X       (math-neg r))
  540. X      ((math-negp r)
  541. X       (math-neg (list 'polar (math-neg r) th)))
  542. X      (t
  543. X       (list 'polar r th))))
  544. X)
  545. X
  546. X
  547. X;;; Coerce A to be complex (rectangular form).  [c N]
  548. X(defun math-complex (a)
  549. X  (cond ((eq (car-safe a) 'cplx) a)
  550. X    ((eq (car-safe a) 'polar)
  551. X     (if (math-zerop (nth 1 a))
  552. X         (nth 1 a)
  553. X       (let ((sc (math-sin-cos (nth 2 a))))
  554. X         (list 'cplx
  555. X           (math-mul (nth 1 a) (nth 1 sc))
  556. X           (math-mul (nth 1 a) (nth 2 sc))))))
  557. X    (t (list 'cplx a 0)))
  558. X)
  559. X
  560. X;;; Coerce A to be complex (polar form).  [c N]
  561. X(defun math-polar (a)
  562. X  (cond ((eq (car-safe a) 'polar) a)
  563. X    ((math-zerop a) '(polar 0 0))
  564. X    (t
  565. X     (list 'polar
  566. X           (math-abs a)
  567. X           (math-cplx-arg a))))
  568. X)
  569. X
  570. X;;; Multiply A by the imaginary constant i.  [N N] [Public]
  571. X(defun math-imaginary (a)
  572. X  (if (and (Math-objvecp a)
  573. X       (not calc-symbolic-mode))
  574. X      (math-mul a
  575. X        (if (or (eq (car-safe a) 'polar)
  576. X            (and (not (eq (car-safe a) 'cplx))
  577. X                 (eq calc-complex-mode 'polar)))
  578. X            (list 'polar 1 (math-quarter-circle nil))
  579. X          '(cplx 0 1)))
  580. X    (math-mul a '(var i var-i)))
  581. X)
  582. X
  583. X
  584. X;;;; Error forms.
  585. X
  586. X;;; Build a standard deviation form.  [X X X]
  587. X(defun math-make-sdev (x sigma)
  588. X  (if (memq (car-safe x) '(cplx polar mod sdev intv vec))
  589. X      (math-reject-arg x 'realp))
  590. X  (if (memq (car-safe sigma) '(cplx polar mod sdev intv vec))
  591. X      (math-reject-arg sigma 'realp))
  592. X  (if (math-negp sigma)
  593. X      (list 'sdev x (math-neg sigma))
  594. X    (if (and (math-zerop sigma) (Math-scalarp x))
  595. X    x
  596. X      (list 'sdev x sigma)))
  597. X)
  598. X(defun calcFunc-sdev (x sigma)
  599. X  (math-make-sdev x sigma)
  600. X)
  601. X
  602. X
  603. X
  604. X;;;; Modulo forms.
  605. X
  606. X(defun math-normalize-mod (a)
  607. X  (let ((n (math-normalize (nth 1 a)))
  608. X    (m (math-normalize (nth 2 a))))
  609. X    (if (and (math-anglep n) (math-anglep m) (math-posp m))
  610. X    (math-make-mod n m)
  611. X      (if (math-anglep n)
  612. X      (if (math-anglep m)
  613. X          (calc-record-why "Modulus must be positive" m)
  614. X        (calc-record-why "Modulus must be real" m))
  615. X    (calc-record-why "Value must be real" n))
  616. X      (list 'calcFunc-makemod n m)))
  617. X)
  618. X
  619. X;;; Build a modulo form.  [N R R]
  620. X(defun math-make-mod (n m)
  621. X  (setq calc-previous-modulo m)
  622. X  (and n
  623. X       (if (not (and (Math-anglep n) (Math-anglep m)))
  624. X       (math-reject-arg n 'anglep)
  625. X     (if (or (Math-negp n)
  626. X         (not (Math-lessp n m)))
  627. X         (list 'mod (math-mod n m) m)
  628. X       (list 'mod n m))))
  629. X)
  630. X(defun calcFunc-makemod (n m)
  631. X  (math-make-mod n m)
  632. X)
  633. X
  634. X
  635. X
  636. X;;;; Interval forms.
  637. X
  638. X;;; Build an interval form.  [X I X X]
  639. X(defun math-make-intv (mask lo hi)
  640. X  (if (memq (car-safe lo) '(cplx polar mod sdev intv vec))
  641. X      (math-reject-arg lo 'realp))
  642. X  (if (memq (car-safe hi) '(cplx polar mod sdev intv vec))
  643. X      (math-reject-arg hi 'realp))
  644. X  (if (and (Math-realp lo) (Math-realp hi))
  645. X      (let ((cmp (math-compare lo hi)))
  646. X    (if (= cmp 0)
  647. X        (if (= mask 3)
  648. X        lo
  649. X          (list 'intv mask lo hi))
  650. X      (if (> cmp 0)
  651. X          (if (= mask 3)
  652. X          (list 'intv 2 lo lo)
  653. X        (list 'intv mask lo lo))
  654. X        (list 'intv mask lo hi))))
  655. X    (list 'intv mask lo hi))
  656. X)
  657. X
  658. X(defun math-sort-intv (mask lo hi)
  659. X  (if (Math-lessp hi lo)
  660. X      (math-make-intv (aref [0 2 1 3] mask) hi lo)
  661. X    (math-make-intv mask lo hi))
  662. X)
  663. X
  664. X
  665. X
  666. X;;;; Arithmetic.
  667. X
  668. X(defun math-neg-fancy (a)
  669. X  (cond ((eq (car a) 'polar)
  670. X     (list 'polar
  671. X           (nth 1 a)
  672. X           (if (math-posp (nth 2 a))
  673. X           (math-sub (nth 2 a) (math-half-circle nil))
  674. X         (math-add (nth 2 a) (math-half-circle nil)))))
  675. X    ((eq (car a) 'mod)
  676. X     (if (math-zerop (nth 1 a))
  677. X         a
  678. X       (list 'mod (math-sub (nth 2 a) (nth 1 a)) (nth 2 a))))
  679. X    ((eq (car a) 'sdev)
  680. X     (list 'sdev (math-neg (nth 1 a)) (nth 2 a)))
  681. X    ((eq (car a) 'intv)
  682. X     (math-make-intv (aref [0 2 1 3] (nth 1 a))
  683. X             (math-neg (nth 3 a))
  684. X             (math-neg (nth 2 a))))
  685. X    ((eq (car a) '-)
  686. X     (math-sub (nth 2 a) (nth 1 a)))
  687. X    ((and (memq (car a) '(* /))
  688. X          (math-looks-negp (nth 1 a)))
  689. X     (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
  690. X    ((and (memq (car a) '(* /))
  691. X          (math-looks-negp (nth 2 a)))
  692. X     (list (car a) (nth 1 a) (math-neg (nth 2 a))))
  693. X    ((and (memq (car a) '(* /))
  694. X          (or (math-numberp (nth 1 a))
  695. X          (and (eq (car (nth 1 a)) '*)
  696. X               (math-numberp (nth 1 (nth 1 a))))))
  697. X     (list (car a) (math-neg (nth 1 a)) (nth 2 a)))
  698. X    ((and (eq (car a) '/)
  699. X          (or (math-numberp (nth 2 a))
  700. X          (and (eq (car (nth 2 a)) '*)
  701. X               (math-numberp (nth 1 (nth 2 a))))))
  702. X     (list (car a) (nth 1 a) (math-neg (nth 2 a))))
  703. X    ((eq (car a) 'neg)
  704. X     (nth 1 a))
  705. X    (t (list 'neg a)))
  706. X)
  707. X
  708. X(defun math-neg-float (a)
  709. X  (list 'float (Math-integer-neg (nth 1 a)) (nth 2 a))
  710. X)
  711. X
  712. X(defun math-add-objects-fancy (a b)
  713. X  (cond ((and (Math-numberp a) (Math-numberp b))
  714. X     (setq aa (math-complex a)
  715. X           bb (math-complex b))
  716. X     (math-normalize
  717. X      (let ((res (list 'cplx
  718. X               (math-add (nth 1 aa) (nth 1 bb))
  719. X               (math-add (nth 2 aa) (nth 2 bb)))))
  720. X        (if (math-want-polar a b)
  721. X        (math-polar res)
  722. X          res))))
  723. X    ((or (Math-vectorp a) (Math-vectorp b))
  724. X     (math-map-vec-2 'math-add a b))
  725. X    ((eq (car-safe a) 'sdev)
  726. X     (if (eq (car-safe b) 'sdev)
  727. X         (math-make-sdev (math-add (nth 1 a) (nth 1 b))
  728. X                 (math-hypot (nth 2 a) (nth 2 b)))
  729. X       (and (or (Math-anglep b)
  730. X            (not (Math-objvecp b)))
  731. X        (math-make-sdev (math-add (nth 1 a) b)
  732. X                (nth 2 a)))))
  733. X    ((and (eq (car-safe b) 'sdev)
  734. X          (or (Math-anglep a)
  735. X          (not (Math-objvecp a))))
  736. X     (math-make-sdev (math-add a (nth 1 b))
  737. X             (nth 2 b)))
  738. X    ((eq (car-safe a) 'intv)
  739. X     (if (eq (car-safe b) 'intv)
  740. X         (math-make-intv (logand (nth 1 a) (nth 1 b))
  741. X                 (math-add (nth 2 a) (nth 2 b))
  742. X                 (math-add (nth 3 a) (nth 3 b)))
  743. X       (and (or (Math-anglep b)
  744. X            (not (Math-objvecp b)))
  745. X        (math-make-intv (nth 1 a)
  746. X                (math-add (nth 2 a) b)
  747. X                (math-add (nth 3 a) b)))))
  748. X    ((and (eq (car-safe b) 'intv)
  749. X          (or (Math-anglep a)
  750. X          (not (Math-objvecp a))))
  751. X     (math-make-intv (nth 1 b)
  752. X             (math-add a (nth 2 b))
  753. X             (math-add a (nth 3 b))))
  754. X    ((and (eq (car-safe a) 'mod)
  755. X          (eq (car-safe b) 'mod)
  756. X          (equal (nth 2 a) (nth 2 b)))
  757. X     (math-make-mod (math-add (nth 1 a) (nth 1 b)) (nth 2 a)))
  758. X    ((and (eq (car-safe a) 'mod)
  759. X          (Math-anglep b))
  760. X     (math-make-mod (math-add (nth 1 a) b) (nth 2 a)))
  761. X    ((and (eq (car-safe b) 'mod)
  762. X          (Math-anglep a))
  763. X     (math-make-mod (math-add a (nth 1 b)) (nth 2 b)))
  764. X    ((and (or (eq (car-safe a) 'hms) (eq (car-safe b) 'hms))
  765. X          (and (Math-anglep a) (Math-anglep b)))
  766. X     (or (eq (car-safe a) 'hms) (setq a (math-to-hms a)))
  767. X     (or (eq (car-safe b) 'hms) (setq b (math-to-hms b)))
  768. X     (math-normalize
  769. X      (if (math-negp a)
  770. X          (math-neg (math-add (math-neg a) (math-neg b)))
  771. X        (if (math-negp b)
  772. X        (let* ((s (math-add (nth 3 a) (nth 3 b)))
  773. X               (m (math-add (nth 2 a) (nth 2 b)))
  774. X               (h (math-add (nth 1 a) (nth 1 b))))
  775. X          (if (math-negp s)
  776. X              (setq s (math-add s 60)
  777. X                m (math-add m -1)))
  778. X          (if (math-negp m)
  779. X              (setq m (math-add m 60)
  780. X                h (math-add h -1)))
  781. X          (if (math-negp h)
  782. X              (math-add b a)
  783. X            (list 'hms h m s)))
  784. X          (let* ((s (math-add (nth 3 a) (nth 3 b)))
  785. X             (m (math-add (nth 2 a) (nth 2 b)))
  786. X             (h (math-add (nth 1 a) (nth 1 b))))
  787. X        (list 'hms h m s))))))
  788. X    (t (calc-record-why "Incompatible arguments" a b)))
  789. X)
  790. X
  791. X(defun math-add-symb-fancy (a b)
  792. X  (or (and (eq (car-safe b) '+)
  793. X       (math-add (math-add a (nth 1 b))
  794. X             (nth 2 b)))
  795. X      (and (eq (car-safe b) '-)
  796. X       (math-sub (math-add a (nth 1 b))
  797. X             (nth 2 b)))
  798. X      (and (eq (car-safe b) 'neg)
  799. X       (eq (car-safe (nth 1 b)) '+)
  800. X       (math-sub (math-sub a (nth 1 (nth 1 b)))
  801. X             (nth 2 (nth 1 b))))
  802. X      (cond
  803. X       ((eq (car-safe a) '+)
  804. X    (let ((temp (math-combine-sum (nth 2 a) b nil nil t)))
  805. X      (and temp
  806. X           (math-add (nth 1 a) temp))))
  807. X       ((eq (car-safe a) '-)
  808. X    (let ((temp (math-combine-sum (nth 2 a) b t nil t)))
  809. X      (and temp
  810. X           (math-add (nth 1 a) temp))))
  811. X       ((and (Math-objectp a) (Math-objectp b))
  812. X    nil)
  813. X       (t
  814. X    (math-combine-sum a b nil nil nil)))
  815. X      (and (Math-looks-negp b)
  816. X       (list '- a (math-neg b)))
  817. X      (and (Math-looks-negp a)
  818. X       (list '- b (math-neg a)))
  819. X      (list '+ a b))
  820. X)
  821. X
  822. X
  823. X(defun math-mul-objects-fancy (a b)
  824. X  (cond ((and (Math-numberp a) (Math-numberp b))
  825. X     (math-normalize
  826. X      (if (math-want-polar a b)
  827. X          (let ((a (math-polar a))
  828. X            (b (math-polar b)))
  829. X        (list 'polar
  830. X              (math-mul (nth 1 a) (nth 1 b))
  831. X              (math-fix-circular (math-add (nth 2 a) (nth 2 b)))))
  832. X        (setq a (math-complex a)
  833. X          b (math-complex b))
  834. X        (list 'cplx
  835. X          (math-sub (math-mul (nth 1 a) (nth 1 b))
  836. X                (math-mul (nth 2 a) (nth 2 b)))
  837. X          (math-add (math-mul (nth 1 a) (nth 2 b))
  838. X                (math-mul (nth 2 a) (nth 1 b)))))))
  839. X    ((Math-vectorp a)
  840. X     (if (Math-vectorp b)
  841. X         (if (math-matrixp a)
  842. X         (if (math-matrixp b)
  843. X             (cons 'vec (math-mul-mats (cdr a)
  844. X                           (mapcar 'cdr
  845. X                               (cdr b))))
  846. X           (math-mat-col
  847. X            (cons 'vec
  848. X              (if (= (length (nth 1 a)) 2)
  849. X                  (math-mul-mats (cdr a)
  850. X                         (mapcar 'cdr
  851. X                             (cdr (math-row-matrix
  852. X                               b))))
  853. X                (math-mul-mats (cdr a)
  854. X                       (mapcar 'cdr
  855. X                           (cdr (math-col-matrix
  856. X                             b))))))
  857. X            1))
  858. X           (if (math-matrixp b)
  859. X           (cons 'vec (math-mul-mat-row a (mapcar 'cdr (cdr b))))
  860. X         (car (math-mul-mat-row a
  861. X                    (mapcar 'cdr
  862. X                        (cdr (math-col-matrix
  863. X                              b)))))))
  864. X       (math-map-vec-2 'math-mul a b)))
  865. X    ((Math-vectorp b)
  866. X     (math-map-vec-2 'math-mul a b))
  867. X    ((eq (car-safe a) 'sdev)
  868. X     (if (eq (car-safe b) 'sdev)
  869. X         (math-make-sdev (math-mul (nth 1 a) (nth 1 b))
  870. X                 (math-hypot (math-mul (nth 2 a) (nth 1 b))
  871. X                     (math-mul (nth 2 b) (nth 1 a))))
  872. X       (and (or (Math-anglep b)
  873. X            (not (Math-objvecp b)))
  874. X        (math-make-sdev (math-mul (nth 1 a) b)
  875. X                (math-abs (math-mul (nth 2 a) b))))))
  876. X    ((and (eq (car-safe b) 'sdev)
  877. X          (or (Math-anglep a)
  878. X          (not (Math-objvecp a))))
  879. X     (math-make-sdev (math-mul a (nth 1 b))
  880. X             (math-abs (math-mul a (nth 2 b)))))
  881. X    ((and (eq (car-safe a) 'intv) (Math-anglep b))
  882. X     (if (Math-negp b)
  883. X         (math-neg (math-mul a (math-neg b)))
  884. X       (math-make-intv (nth 1 a)
  885. X               (math-mul (nth 2 a) b)
  886. X               (math-mul (nth 3 a) b))))
  887. X    ((and (eq (car-safe b) 'intv) (Math-anglep a))
  888. X     (math-mul b a))
  889. X    ((and (eq (car-safe a) 'intv) (math-constp a)
  890. X          (eq (car-safe b) 'intv) (math-constp b))
  891. X     (let ((lo (math-mul a (nth 2 b)))
  892. X           (hi (math-mul a (nth 3 b))))
  893. X       (and (Math-anglep lo)
  894. X        (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0) lo lo)))
  895. X       (and (Math-anglep hi)
  896. X        (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0) hi hi)))
  897. X       (math-combine-intervals (nth 2 lo) (and (memq (nth 1 b) '(2 3))
  898. X                           (memq (nth 1 lo) '(2 3)))
  899. X                   (nth 3 lo) (and (memq (nth 1 b) '(2 3))
  900. X                           (memq (nth 1 lo) '(1 3)))
  901. X                   (nth 2 hi) (and (memq (nth 1 b) '(1 3))
  902. X                           (memq (nth 1 hi) '(2 3)))
  903. X                   (nth 3 hi) (and (memq (nth 1 b) '(1 3))
  904. X                           (memq (nth 1 hi) '(1 3))))))
  905. X    ((and (eq (car-safe a) 'mod)
  906. X          (eq (car-safe b) 'mod)
  907. X          (equal (nth 2 a) (nth 2 b)))
  908. X     (math-make-mod (math-mul (nth 1 a) (nth 1 b)) (nth 2 a)))
  909. X    ((and (eq (car-safe a) 'mod)
  910. X          (Math-anglep b))
  911. X     (math-make-mod (math-mul (nth 1 a) b) (nth 2 a)))
  912. X    ((and (eq (car-safe b) 'mod)
  913. X          (Math-anglep a))
  914. X     (math-make-mod (math-mul a (nth 1 b)) (nth 2 b)))
  915. X    ((and (eq (car-safe a) 'hms) (Math-realp b))
  916. X     (math-with-extra-prec 2
  917. X       (math-to-hms (math-mul (math-from-hms a 'deg) b) 'deg)))
  918. X    ((and (eq (car-safe b) 'hms) (Math-realp a))
  919. X     (math-mul b a))
  920. X    (t (calc-record-why "Incompatible arguments" a b)))
  921. X)
  922. X
  923. X;;; Fast function to multiply floating-point numbers.
  924. X(defun math-mul-float (a b)   ; [F F F]
  925. X  (math-make-float (math-mul (nth 1 a) (nth 1 b))
  926. X           (+ (nth 2 a) (nth 2 b)))
  927. X)
  928. X
  929. X(defun math-sqr-float (a)   ; [F F]
  930. X  (math-make-float (math-mul (nth 1 a) (nth 1 a))
  931. X           (+ (nth 2 a) (nth 2 a)))
  932. X)
  933. X
  934. X(defun math-combine-intervals (a am b bm c cm d dm)
  935. X  (let (res)
  936. X    (if (= (setq res (math-compare a c)) 1)
  937. X    (setq a c am cm)
  938. X      (if (= res 0)
  939. X      (setq am (or am cm))))
  940. X    (if (= (setq res (math-compare b d)) -1)
  941. X    (setq b d bm dm)
  942. X      (if (= res 0)
  943. X      (setq bm (or bm dm))))
  944. X    (math-make-intv (+ (if am 2 0) (if bm 1 0)) a b))
  945. X)
  946. X
  947. X(defun math-mul-symb-fancy (a b)
  948. X  (or (and (Math-equal-int a 1)
  949. X       b)
  950. X      (and (Math-equal-int a -1)
  951. X       (math-neg b))
  952. X      (and (Math-numberp b)
  953. X       (math-mul b a))
  954. X      (and (eq (car-safe a) 'neg)
  955. X       (math-neg (math-mul (nth 1 a) b)))
  956. X      (and (eq (car-safe b) 'neg)
  957. X       (math-neg (math-mul a (nth 1 b))))
  958. X      (and (eq (car-safe a) '*)
  959. X       (math-mul (nth 1 a)
  960. X             (math-mul (nth 2 a) b)))
  961. X      (and (eq (car-safe a) '^)
  962. X       (Math-looks-negp (nth 2 a))
  963. X       (not (and (eq (car-safe b) '^) (Math-looks-negp (nth 2 b))))
  964. X       (math-div b (math-normalize
  965. X            (list '^ (nth 1 a) (math-neg (nth 2 a))))))
  966. X      (and (eq (car-safe b) '^)
  967. X       (Math-looks-negp (nth 2 b))
  968. X       (not (and (eq (car-safe a) '^) (Math-looks-negp (nth 2 a))))
  969. X       (math-div a (math-normalize
  970. X            (list '^ (nth 1 b) (math-neg (nth 2 b))))))
  971. X      (and (eq (car-safe a) '/)
  972. X       (math-div (math-mul (nth 1 a) b) (nth 2 a)))
  973. X      (and (eq (car-safe b) '/)
  974. X       (math-div (math-mul a (nth 1 b)) (nth 2 b)))
  975. X      (and (eq (car-safe b) '+)
  976. X       (Math-numberp a)
  977. X       (or (Math-numberp (nth 1 b))
  978. X           (Math-numberp (nth 2 b)))
  979. X       (math-add (math-mul a (nth 1 b))
  980. X             (math-mul a (nth 2 b))))
  981. X      (and (eq (car-safe b) '-)
  982. X       (Math-numberp a)
  983. X       (or (Math-numberp (nth 1 b))
  984. X           (Math-numberp (nth 2 b)))
  985. X       (math-sub (math-mul a (nth 1 b))
  986. X             (math-mul a (nth 2 b))))
  987. X      (and (eq (car-safe b) '*)
  988. X       (Math-numberp (nth 1 b))
  989. X       (not (Math-numberp a))
  990. X       (math-mul (nth 1 b) (math-mul a (nth 2 b))))
  991. X      (and (or t  ; this seems more reasonable...
  992. X           (eq (car-safe a) '-)
  993. X           (math-looks-negp a))
  994. X       (math-looks-negp b)
  995. X       (math-mul (math-neg a) (math-neg b)))
  996. X      (and (eq (car-safe b) '-)
  997. X       (math-looks-negp a)
  998. X       (math-mul (math-neg a) (math-neg b)))
  999. X      (cond
  1000. X       ((eq (car-safe b) '*)
  1001. X    (let ((temp (math-combine-prod a (nth 1 b) nil nil t)))
  1002. X      (and temp
  1003. X           (math-mul temp (nth 2 b)))))
  1004. X       (t
  1005. X    (math-combine-prod a b nil nil nil)))
  1006. X      (list '* a b))
  1007. X)
  1008. X
  1009. X(defun math-want-polar (a b)
  1010. X  (cond ((eq (car-safe a) 'polar)
  1011. X     (if (eq (car-safe b) 'cplx)
  1012. X         (eq car-complex-mode 'polar)
  1013. X       t))
  1014. X    ((eq (car-safe a) 'cplx)
  1015. X     (if (eq (car-safe b) 'polar)
  1016. X         (eq car-complex-mode 'polar)
  1017. X       nil))
  1018. X    ((eq (car-safe b) 'polar)
  1019. X     t)
  1020. X    ((eq (car-safe b) 'cplx)
  1021. X     nil)
  1022. X    (t (eq (car-complex-mode 'polar))))
  1023. X)
  1024. X
  1025. X;;; Force A to be in the (-pi,pi] or (-180,180] range.
  1026. X(defun math-fix-circular (a &optional dir)   ; [R R]
  1027. X  (cond ((eq calc-angle-mode 'deg)
  1028. X     (cond ((and (Math-lessp '(float 18 1) a) (not (eq dir 1)))
  1029. X        (math-fix-circular (math-add a '(float -36 1)) -1))
  1030. X           ((or (Math-lessp '(float -18 1) a) (eq dir -1))
  1031. X        a)
  1032. X           (t
  1033. X        (math-fix-circular (math-add a '(float 36 1)) 1))))
  1034. X    ((eq calc-angle-mode 'hms)
  1035. X     (cond ((and (Math-lessp 180 (nth 1 a)) (not (eq dir 1)))
  1036. X        (math-fix-circular (math-add a '(float -36 1)) -1))
  1037. X           ((or (Math-lessp -180 (nth 1 a)) (eq dir -1))
  1038. X        a)
  1039. X           (t
  1040. X        (math-fix-circular (math-add a '(float 36 1)) 1))))
  1041. X    (t
  1042. X     (cond ((and (Math-lessp (math-pi) a) (not (eq dir 1)))
  1043. X        (math-fix-circular (math-sub a (math-two-pi)) -1))
  1044. X           ((or (Math-lessp (math-neg (math-pi)) a) (eq dir -1))
  1045. X        a)
  1046. X           (t
  1047. X        (math-fix-circular (math-add a (math-two-pi)) 1)))))
  1048. X)
  1049. X
  1050. X
  1051. X(defun math-div-objects-fancy (a b)
  1052. X  (cond ((and (Math-numberp a) (Math-numberp b))
  1053. X     (math-normalize
  1054. X      (cond ((math-want-polar a b)
  1055. X         (let ((a (math-polar a))
  1056. X               (b (math-polar b)))
  1057. X           (list 'polar
  1058. X             (math-div (nth 1 a) (nth 1 b))
  1059. X             (math-fix-circular (math-sub (nth 2 a)
  1060. X                              (nth 2 b))))))
  1061. X        ((Math-realp b)
  1062. X         (setq a (math-complex a))
  1063. X         (list 'cplx (math-div (nth 1 a) b)
  1064. X               (math-div (nth 2 a) b)))
  1065. X        (t
  1066. X         (setq a (math-complex a)
  1067. X               b (math-complex b))
  1068. X         (math-div
  1069. X          (list 'cplx
  1070. X            (math-add (math-mul (nth 1 a) (nth 1 b))
  1071. X                  (math-mul (nth 2 a) (nth 2 b)))
  1072. X            (math-sub (math-mul (nth 2 a) (nth 1 b))
  1073. X                  (math-mul (nth 1 a) (nth 2 b))))
  1074. X          (math-add (math-sqr (nth 1 b))
  1075. X                (math-sqr (nth 2 b))))))))
  1076. X    ((math-matrixp b)
  1077. X     (if (math-square-matrixp b)
  1078. X         (let ((n1 (length b)))
  1079. X           (if (Math-vectorp a)
  1080. X           (if (math-matrixp a)
  1081. X               (if (= (length a) n1)
  1082. X               (math-lud-solve (math-matrix-lud b) a)
  1083. X             (if (= (length (nth 1 a)) n1)
  1084. X                 (math-transpose
  1085. X                  (math-lud-solve (math-matrix-lud
  1086. X                           (math-transpose b))
  1087. X                          (math-transpose a)))
  1088. X               (math-dimension-error)))
  1089. X             (if (= (length a) n1)
  1090. X             (math-mat-col (math-lud-solve (math-matrix-lud b)
  1091. X                               (math-col-matrix a))
  1092. X                       1)
  1093. X               (math-dimension-error)))
  1094. X         (if (Math-equal-int a 1)
  1095. X             (math-inv b)
  1096. X           (math-mul a (math-inv b)))))
  1097. X       (math-reject-arg b 'square-matrixp)))
  1098. X    ((Math-vectorp a)
  1099. X     (math-map-vec-2 'math-div a b))
  1100. X    ((eq (car-safe a) 'sdev)
  1101. X     (if (eq (car-safe b) 'sdev)
  1102. X         (let ((x (math-div (nth 1 a) (nth 1 b))))
  1103. X           (math-make-sdev
  1104. X        x
  1105. X        (math-div
  1106. X         (math-hypot (nth 2 a) (math-mul (nth 2 b) x))
  1107. X         (math-abs (nth 1 b)))))
  1108. X       (and (or (Math-anglep b)
  1109. X            (not (Math-objvecp b)))
  1110. X        (math-make-sdev (math-div (nth 1 a) b)
  1111. X                (math-abs (math-div (nth 2 a) b))))))
  1112. X    ((and (eq (car-safe b) 'sdev)
  1113. X          (or (Math-anglep a)
  1114. X          (not (Math-objvecp a))))
  1115. X     (let ((x (math-div a (nth 1 b))))
  1116. X       (math-make-sdev x
  1117. X               (math-abs (math-div (math-mul (nth 2 b) x)
  1118. X                           (nth 1 b))))))
  1119. X    ((and (eq (car-safe a) 'intv) (Math-anglep b))
  1120. X     (if (Math-negp b)
  1121. X         (math-neg (math-div a (math-neg b)))
  1122. X       (math-make-intv (nth 1 a)
  1123. X               (math-div (nth 2 a) b)
  1124. X               (math-div (nth 3 a) b))))
  1125. X    ((and (eq (car-safe b) 'intv) (Math-anglep a))
  1126. X     (if (Math-posp (nth 2 b))
  1127. X         (if (Math-negp a)
  1128. X         (math-neg (math-div (math-neg a) b))
  1129. X           (math-make-intv (aref [0 2 1 3] (nth 1 b))
  1130. X                   (math-div a (nth 3 b))
  1131. X                   (math-div a (nth 2 b))))
  1132. X       (if (Math-negp (nth 3 b))
  1133. X           (math-neg (math-div a (math-neg b)))
  1134. X         (calc-record-why "Division by zero" b)
  1135. X         nil)))
  1136. X    ((and (eq (car-safe a) 'intv) (math-constp a)
  1137. X          (eq (car-safe b) 'intv) (math-constp b))
  1138. X     (if (or (Math-posp (nth 2 b)) (Math-negp (nth 3 b)))
  1139. X         (let ((lo (math-div a (nth 2 b)))
  1140. X           (hi (math-div a (nth 3 b))))
  1141. X           (and (Math-anglep lo)
  1142. X            (setq lo (list 'intv (if (memq (nth 1 b) '(2 3)) 3 0)
  1143. X                   lo lo)))
  1144. X           (and (Math-anglep hi)
  1145. X            (setq hi (list 'intv (if (memq (nth 1 b) '(1 3)) 3 0)
  1146. X                   hi hi)))
  1147. X           (math-combine-intervals
  1148. X        (nth 2 lo) (and (memq (nth 1 b) '(2 3))
  1149. X                (memq (nth 1 lo) '(2 3)))
  1150. X        (nth 3 lo) (and (memq (nth 1 b) '(2 3))
  1151. X                (memq (nth 1 lo) '(1 3)))
  1152. X        (nth 2 hi) (and (memq (nth 1 b) '(1 3))
  1153. X                (memq (nth 1 hi) '(2 3)))
  1154. X        (nth 3 hi) (and (memq (nth 1 b) '(1 3))
  1155. X                (memq (nth 1 hi) '(1 3)))))
  1156. X       (calc-record-why "Division by zero" b)
  1157. X       nil))
  1158. X    ((and (eq (car-safe a) 'mod)
  1159. X          (eq (car-safe b) 'mod)
  1160. X          (equal (nth 2 a) (nth 2 b)))
  1161. X     (math-make-mod (math-div-mod (nth 1 a) (nth 1 b) (nth 2 a))
  1162. X            (nth 2 a)))
  1163. X    ((and (eq (car-safe a) 'mod)
  1164. X          (Math-anglep b))
  1165. X     (math-make-mod (math-div-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
  1166. X    ((and (eq (car-safe b) 'mod)
  1167. X          (Math-anglep a))
  1168. X     (math-make-mod (math-div-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
  1169. X    ((eq (car-safe a) 'hms)
  1170. X     (if (eq (car-safe b) 'hms)
  1171. X         (math-with-extra-prec 1
  1172. X           (math-div (math-from-hms a 'deg)
  1173. X             (math-from-hms b 'deg)))
  1174. X       (math-with-extra-prec 2
  1175. X         (math-to-hms (math-div (math-from-hms a 'deg) b) 'deg))))
  1176. X    (t (calc-record-why "Incompatible arguments" a b)))
  1177. X)
  1178. X
  1179. X(defun math-div-symb-fancy (a b)
  1180. X  (or (and (Math-equal-int b 1) a)
  1181. X      (and (Math-equal-int b -1) (math-neg a))
  1182. X      (and (eq (car-safe b) '^)
  1183. X       (or (Math-looks-negp (nth 2 b)) (Math-equal-int a 1))
  1184. X       (math-mul a (math-normalize
  1185. X            (list '^ (nth 1 b) (math-neg (nth 2 b))))))
  1186. X      (and (eq (car-safe a) 'neg)
  1187. X       (math-neg (math-div (nth 1 a) b)))
  1188. X      (and (eq (car-safe b) 'neg)
  1189. X       (math-neg (math-div a (nth 1 b))))
  1190. X      (and (eq (car-safe a) '/)
  1191. X       (math-div (nth 1 a) (math-mul (nth 2 a) b)))
  1192. X      (and (eq (car-safe b) '/)
  1193. X       (math-div (math-mul a (nth 2 b)) (nth 1 b)))
  1194. X      (and (eq (car-safe b) 'frac)
  1195. X       (math-mul a (math-make-frac (nth 2 b) (nth 1 b))))
  1196. X      (and (eq (car-safe a) '+)
  1197. X       (or (Math-numberp (nth 1 a))
  1198. X           (Math-numberp (nth 2 a)))
  1199. X       (Math-numberp b)
  1200. X       (math-add (math-div (nth 1 a) b)
  1201. X             (math-div (nth 2 a) b)))
  1202. X      (and (eq (car-safe a) '-)
  1203. X       (or (Math-numberp (nth 1 a))
  1204. X           (Math-numberp (nth 2 a)))
  1205. X       (Math-numberp b)
  1206. X       (math-sub (math-div (nth 1 a) b)
  1207. X             (math-div (nth 2 a) b)))
  1208. X      (and (or (eq (car-safe a) '-)
  1209. X           (math-looks-negp a))
  1210. X       (math-looks-negp b)
  1211. X       (math-div (math-neg a) (math-neg b)))
  1212. X      (and (eq (car-safe b) '-)
  1213. X       (math-looks-negp a)
  1214. X       (math-div (math-neg a) (math-neg b)))
  1215. X      (if (eq (car-safe a) '*)
  1216. X      (if (eq (car-safe b) '*)
  1217. X          (let ((c (math-combine-prod (nth 1 a) (nth 1 b) nil t t)))
  1218. X        (and c
  1219. X             (math-div (math-mul c (nth 2 a)) (nth 2 b))))
  1220. X        (let ((c (math-combine-prod (nth 1 a) b nil t t)))
  1221. X          (and c
  1222. X           (math-mul c (nth 2 a)))))
  1223. X    (if (eq (car-safe b) '*)
  1224. X        (let ((c (math-combine-prod a (nth 1 b) nil t t)))
  1225. X          (and c
  1226. X           (math-div c (nth 2 b))))
  1227. X      (math-combine-prod a b nil t nil)))
  1228. X      (list '/ a b))
  1229. X)
  1230. X
  1231. X(defun math-div-mod (a b m)   ; [R R R R]  (Returns nil if no solution)
  1232. X  (and (Math-integerp a) (Math-integerp b) (Math-integerp m)
  1233. X       (let ((u1 1) (u3 b) (v1 0) (v3 m))
  1234. X     (while (not (eq v3 0))   ; See Knuth sec 4.5.2, exercise 15
  1235. X       (let* ((q (math-idivmod u3 v3))
  1236. X          (t1 (math-sub u1 (math-mul v1 (car q)))))
  1237. X         (setq u1 v1  u3 v3  v1 t1  v3 (cdr q))))
  1238. X     (let ((q (math-idivmod a u3)))
  1239. X       (and (eq (cdr q) 0)
  1240. X        (math-mod (math-mul (car q) u1) m)))))
  1241. X)
  1242. X
  1243. X(defun math-mod-intv (a b)
  1244. X  (let* ((q1 (math-floor (math-div (nth 2 a) b)))
  1245. X     (q2 (math-floor (math-div (nth 3 a) b)))
  1246. X     (m1 (math-sub (nth 2 a) (math-mul q1 b)))
  1247. X     (m2 (math-sub (nth 3 a) (math-mul q2 b))))
  1248. X    (cond ((equal q1 q2)
  1249. X       (math-sort-intv (nth 1 a) m1 m2))
  1250. X      ((and (math-equal-int (math-sub q2 q1) 1)
  1251. X        (math-zerop m2)
  1252. X        (memq (nth 1 a) '(0 2)))
  1253. X       (math-make-intv (nth 1 a) m1 b))
  1254. X      (t
  1255. X       (math-make-intv 2 0 b))))
  1256. X)
  1257. X
  1258. X(defun math-pow-fancy (a b)
  1259. X  (cond ((and (Math-numberp a) (Math-numberp b))
  1260. X     (cond ((and (eq (car-safe b) 'frac)
  1261. X             (equal (nth 2 b) 2))
  1262. X        (math-ipow (math-sqrt-raw (math-float a)) (nth 1 b)))
  1263. X           ((equal b '(float 5 -1))
  1264. X        (math-sqrt-raw (math-float a)))
  1265. X           (t
  1266. X        (math-with-extra-prec 2
  1267. X          (math-exp-raw
  1268. X           (math-float (math-mul b (math-ln-raw (math-float a)))))))))
  1269. X    ((or (not (Math-objvecp a))
  1270. X         (not (Math-objectp b)))
  1271. X     (cond ((and (eq (car-safe a) 'calcFunc-sqrt)
  1272. X             (math-evenp b))
  1273. X        (math-pow (nth 1 a) (math-div2 b)))
  1274. X           ((eq (car-safe a) '*)
  1275. X        (math-mul (math-pow (nth 1 a) b)
  1276. X              (math-pow (nth 2 a) b)))
  1277. X           ((eq (car-safe a) '/)
  1278. X        (math-div (math-pow (nth 1 a) b)
  1279. X              (math-pow (nth 2 a) b)))
  1280. X           ((and (eq (car-safe a) '^)
  1281. X             (Math-integerp b))
  1282. X        (math-pow (nth 1 a) (math-mul (nth 2 a) b)))
  1283. X           ((and (math-looks-negp a)
  1284. X             (Math-integerp b))
  1285. X        (if (math-evenp b)
  1286. X            (math-pow (math-neg a) b)
  1287. X          (math-neg (math-pow (math-neg a) b))))
  1288. X           (t (if (Math-objectp a)
  1289. X              (calc-record-why 'objectp b)
  1290. X            (calc-record-why 'objectp a))
  1291. X          (list '^ a b))))
  1292. X    ((and (eq (car-safe a) 'sdev) (eq (car-safe b) 'sdev))
  1293. X     (if (and (math-constp a) (math-constp b))
  1294. X         (math-with-extra-prec 2
  1295. X           (let* ((ln (math-ln-raw (math-float (nth 1 a))))
  1296. X              (pow (math-exp-raw
  1297. X                (math-float (math-mul (nth 1 b) ln)))))
  1298. X         (list 'sdev
  1299. X               pow
  1300. X               (math-mul
  1301. X            pow
  1302. X            (math-hypot (math-mul (nth 2 a)
  1303. X                          (math-div (nth 1 b)
  1304. X                            (nth 1 a)))
  1305. X                    (math-mul (nth 2 b) ln))))))
  1306. X       (let ((pow (math-pow (nth 1 a) (nth 1 b))))
  1307. X         (list 'sdev
  1308. X           pow
  1309. X           (math-mul pow
  1310. X                 (math-hypot (math-mul (nth 2 a)
  1311. X                           (math-div (nth 1 b)
  1312. X                                 (nth 1 a)))
  1313. X                     (math-mul (nth 2 b)
  1314. X                           (math-ln
  1315. X                            (nth 1 a)))))))))
  1316. X    ((and (eq (car-safe a) 'sdev) (Math-realp b))
  1317. X     (if (math-constp a)
  1318. X         (math-with-extra-prec 2
  1319. X           (let ((pow (math-pow (nth 1 a) (math-sub b 1))))
  1320. X         (list 'sdev
  1321. X               (math-mul pow (nth 1 a))
  1322. X               (math-mul pow (math-mul (nth 2 a) b)))))
  1323. X       (list 'sdev
  1324. X         (math-mul (math-pow (nth 1 a) b))
  1325. X         (math-mul (math-pow (nth 1 a) (math-add b -1))
  1326. X               (math-mul (nth 2 a) b)))))
  1327. X    ((and (eq (car-safe b) 'sdev) (Math-realp a))
  1328. X     (math-with-extra-prec 2
  1329. X       (let* ((ln (math-ln-raw (math-float a)))
  1330. X          (pow (math-exp (math-mul (nth 1 b) ln))))
  1331. X         (list 'sdev
  1332. X           pow
  1333. X           (math-mul pow (math-mul (nth 2 b) ln))))))
  1334. X    ((and (eq (car-safe a) 'intv) (math-constp a)
  1335. X          (Math-realp b)
  1336. X          (or (Math-posp (nth 2 a))
  1337. X          (Math-natnump b)
  1338. X          (and (math-zerop (nth 2 a))
  1339. X               (Math-posp b))))
  1340. X     (if (math-evenp b)
  1341. X         (setq a (math-abs a)))
  1342. X     (math-sort-intv (nth 1 a)
  1343. X             (math-pow (nth 2 a) b)
  1344. X             (math-pow (nth 3 a) b)))
  1345. X    ((and (eq (car-safe b) 'intv) (math-constp b)
  1346. X          (Math-posp a))
  1347. X     (math-sort-intv (nth 1 b)
  1348. X             (math-pow a (nth 2 b))
  1349. X             (math-pow a (nth 3 b))))
  1350. X    ((and (eq (car-safe a) 'intv) (math-constp a)
  1351. X          (eq (car-safe b) 'intv) (math-constp b)
  1352. X          (or (and (not (Math-negp (nth 2 a)))
  1353. X               (not (Math-negp (nth 2 b))))
  1354. X          (and (Math-posp (nth 2 a))
  1355. X               (not (Math-posp (nth 3 b))))))
  1356. X     (let ((lo (math-pow a (nth 2 a)))
  1357. X           (hi (math-pow a (nth 3 a))))
  1358. X       (math-combine-intervals (nth 2 lo) (and (memq (nth 1 a) '(2 3))
  1359. X                           (memq (nth 1 lo) '(2 3)))
  1360. X                   (nth 3 lo) (and (memq (nth 1 a) '(2 3))
  1361. X                           (memq (nth 1 lo) '(1 3)))
  1362. X                   (nth 2 hi) (and (memq (nth 1 a) '(1 3))
  1363. X                           (memq (nth 1 hi) '(2 3)))
  1364. X                   (nth 3 hi) (and (memq (nth 1 a) '(1 3))
  1365. X                           (memq (nth 1 hi) '(1 3))))))
  1366. X    ((and (eq (car-safe a) 'mod) (eq (car-safe b) 'mod)
  1367. X          (equal (nth 2 a) (nth 2 b)))
  1368. X     (math-make-mod (math-pow-mod (nth 1 a) (nth 1 b) (nth 2 a))
  1369. X            (nth 2 a)))
  1370. X    ((and (eq (car-safe a) 'mod) (Math-anglep b))
  1371. X     (math-make-mod (math-pow-mod (nth 1 a) b (nth 2 a)) (nth 2 a)))
  1372. X    ((and (eq (car-safe b) 'mod) (Math-anglep a))
  1373. X     (math-make-mod (math-pow-mod a (nth 1 b) (nth 2 b)) (nth 2 b)))
  1374. X    ((not (Math-numberp a))
  1375. X     (math-reject-arg a 'numberp))
  1376. X    (t
  1377. X     (math-reject-arg b 'numberp)))
  1378. X)
  1379. X
  1380. X;;; This assumes A < M and M > 0.
  1381. X(defun math-pow-mod (a b m)   ; [R R R R]
  1382. X  (if (and (Math-integerp a) (Math-integerp b) (Math-integerp m))
  1383. X      (if (Math-negp b)
  1384. X      (math-div-mod 1 (math-pow-mod a (Math-integer-neg b) m) m)
  1385. X    (if (eq m 1)
  1386. X        0
  1387. X      (math-pow-mod-step a b m)))
  1388. X    (math-mod (math-pow a b) m))
  1389. X)
  1390. X
  1391. X(defun math-pow-mod-step (a n m)   ; [I I I I]
  1392. X  (math-working "pow" a)
  1393. X  (let ((val (cond
  1394. X          ((eq n 0) 1)
  1395. X          ((eq n 1) a)
  1396. X          (t
  1397. X           (let ((rest (math-pow-mod-step
  1398. X                (math-imod (math-mul a a) m)
  1399. X                (math-div2 n)
  1400. X                m)))
  1401. X         (if (math-evenp n)
  1402. X             rest
  1403. X           (math-mod (math-mul a rest) m)))))))
  1404. X    (math-working "pow" val)
  1405. X    val)
  1406. X)
  1407. X
  1408. X(defvar math-power-of-2-cache (list 1 2 4 8 16 32 64 128 256 512 1024))
  1409. X(defvar math-big-power-of-2-cache nil)
  1410. X(defun math-power-of-2 (n)    ;  [I I] [Public]
  1411. X  (if (and (natnump n) (<= n 100))
  1412. X      (or (nth n math-power-of-2-cache)
  1413. X      (let* ((i (length math-power-of-2-cache))
  1414. X         (val (nth (1- i) math-power-of-2-cache)))
  1415. X        (while (<= i n)
  1416. X          (setq val (math-mul val 2)
  1417. X            math-power-of-2-cache (nconc math-power-of-2-cache
  1418. X                         (list val))
  1419. X            i (1+ i)))
  1420. X        val))
  1421. X    (let ((found (assq n math-big-power-of-2-cache)))
  1422. X      (if found
  1423. X      (cdr found)
  1424. X    (let ((po2 (math-ipow 2 n)))
  1425. X      (setq math-big-power-of-2-cache
  1426. X        (cons (cons n po2) math-big-power-of-2-cache))
  1427. X      po2))))
  1428. X)
  1429. X
  1430. X(defun math-integer-log2 (n)    ; [I I] [Public]
  1431. X  (let ((i 0)
  1432. X    (p math-power-of-2-cache)
  1433. X    val)
  1434. X    (while (and p (Math-natnum-lessp (setq val (car p)) n))
  1435. X      (setq p (cdr p)
  1436. X        i (1+ i)))
  1437. X    (if p
  1438. X    (and (equal val n)
  1439. X         i)
  1440. X      (while (Math-natnum-lessp
  1441. X          (prog1
  1442. X          (setq val (math-mul val 2))
  1443. X        (setq math-power-of-2-cache (nconc math-power-of-2-cache
  1444. X                           (list val))))
  1445. X          n)
  1446. X    (setq i (1+ i)))
  1447. X      (and (equal val n)
  1448. X       i)))
  1449. X)
  1450. X
  1451. X
  1452. X
  1453. X;;; Compute the integer square-root floor(sqrt(A)).  A > 0.  [I I] [Public]
  1454. X;;; This method takes advantage of the fact that Newton's method starting
  1455. X;;; with an overestimate always works, even using truncating integer division!
  1456. X(defun math-isqrt (a)
  1457. X  (cond ((Math-zerop a) a)
  1458. X    ((Math-negp a)
  1459. X     (math-imaginary (math-isqrt (math-neg a))))
  1460. X    ((integerp a)
  1461. X     (math-isqrt-small a))
  1462. X    ((eq (car a) 'bigpos)
  1463. X     (math-normalize (cons 'bigpos (cdr (math-isqrt-bignum (cdr a))))))
  1464. X    (t
  1465. X     (math-floor (math-sqrt a))))
  1466. X)
  1467. X
  1468. X;;; This returns (flag . result) where the flag is T if A is a perfect square.
  1469. X(defun math-isqrt-bignum (a)   ; [P.l L]
  1470. X  (let ((len (length a)))
  1471. X    (if (= (% len 2) 0)
  1472. X    (let* ((top (nthcdr (- len 2) a)))
  1473. X      (math-isqrt-bignum-iter
  1474. X       a
  1475. X       (math-scale-bignum-3
  1476. X        (math-bignum-big
  1477. X         (1+ (math-isqrt-small
  1478. X          (+ (* (nth 1 top) 1000) (car top)))))
  1479. X        (1- (/ len 2)))))
  1480. X      (let* ((top (nth (1- len) a)))
  1481. X    (math-isqrt-bignum-iter
  1482. X     a
  1483. X     (math-scale-bignum-3
  1484. X      (list (1+ (math-isqrt-small top)))
  1485. X      (/ len 2))))))
  1486. X)
  1487. X
  1488. X(defun math-isqrt-bignum-iter (a guess)   ; [l L l]
  1489. X  (math-working "isqrt" (cons 'bigpos guess))
  1490. X  (let* ((q (math-div-bignum a guess))
  1491. X     (s (math-add-bignum (car q) guess))
  1492. X     (g2 (math-div2-bignum s))
  1493. X     (comp (math-compare-bignum g2 guess)))
  1494. X    (if (< comp 0)
  1495. X    (math-isqrt-bignum-iter a g2)
  1496. X      (cons (and (= comp 0)
  1497. X         (math-zerop-bignum (cdr q))
  1498. X         (= (% (car s) 2) 0))
  1499. X        guess)))
  1500. X)
  1501. X
  1502. X(defun math-scale-bignum-3 (a n)   ; [L L S]
  1503. X  (while (> n 0)
  1504. X    (setq a (cons 0 a)
  1505. X      n (1- n)))
  1506. X  a
  1507. X)
  1508. X
  1509. X(defun math-isqrt-small (a)   ; A > 0.  [S S]
  1510. X  (let ((g (cond ((>= a 10000) 1000)
  1511. X         ((>= a 100) 100)
  1512. X         (t 10)))
  1513. X    g2)
  1514. X    (while (< (setq g2 (/ (+ g (/ a g)) 2)) g)
  1515. X      (setq g g2))
  1516. X    g)
  1517. X)
  1518. X
  1519. X
  1520. X(defun math-inexact-result ()
  1521. X  (and calc-symbolic-mode
  1522. X       (signal 'inexact-result nil))
  1523. X)
  1524. X
  1525. X
  1526. X;;; Compute the square root of a number.
  1527. X;;; [T N] if possible, else [F N] if possible, else [C N].  [Public]
  1528. X(defun math-sqrt (a)
  1529. X  (or
  1530. X   (and (Math-zerop a) a)
  1531. X   (and (Math-negp a)
  1532. X    (math-imaginary (math-sqrt (math-neg a))))
  1533. X   (and (integerp a)
  1534. X    (let ((sqrt (math-isqrt-small a)))
  1535. X      (if (= (* sqrt sqrt) a)
  1536. X          sqrt
  1537. X        (math-sqrt-float (math-float a) (math-float sqrt)))))
  1538. X   (and (eq (car-safe a) 'bigpos)
  1539. X    (let* ((res (math-isqrt-bignum (cdr a)))
  1540. X           (sqrt (math-normalize (cons 'bigpos (cdr res)))))
  1541. X      (if (car res)
  1542. X          sqrt
  1543. X        (math-sqrt-float (math-float a) (math-float sqrt)))))
  1544. X   (and (eq (car-safe a) 'frac)
  1545. X    (let* ((num-res (math-isqrt-bignum (cdr (Math-bignum-test (nth 1 a)))))
  1546. X           (num-sqrt (math-normalize (cons 'bigpos (cdr num-res))))
  1547. X           (den-res (math-isqrt-bignum (cdr (Math-bignum-test (nth 2 a)))))
  1548. X           (den-sqrt (math-normalize (cons 'bigpos (cdr den-res)))))
  1549. X      (if (and (car num-res) (car den-res))
  1550. X          (list 'frac num-sqrt den-sqrt)
  1551. X        (math-sqrt-float (math-float a)
  1552. X                 (math-div (math-float num-sqrt) den-sqrt)))))
  1553. X   (and (eq (car-safe a) 'float)
  1554. X    (if calc-symbolic-mode
  1555. X        (if (= (% (nth 2 a) 2) 0)
  1556. X        (let ((res (math-isqrt-bignum
  1557. X                (cdr (Math-bignum-test (nth 1 a))))))
  1558. X          (if (car res)
  1559. X              (math-make-float (math-normalize
  1560. X                    (cons 'bigpos (cdr res)))
  1561. X                       (/ (nth 2 a) 2))
  1562. X            (signal 'inexact-result nil)))
  1563. X          (signal 'inexact-result nil))
  1564. X      (math-sqrt-float a)))
  1565. X   (and (eq (car-safe a) 'cplx)
  1566. X    (math-with-extra-prec 2
  1567. X      (let* ((d (math-abs a))
  1568. X         (imag (math-sqrt (math-mul (math-sub d (nth 1 a))
  1569. X                        '(float 5 -1)))))
  1570. X        (list 'cplx
  1571. X          (math-sqrt (math-mul (math-add d (nth 1 a)) '(float 5 -1)))
  1572. X          (if (math-negp (nth 2 a)) (math-neg imag) imag)))))
  1573. X   (and (eq (car-safe a) 'polar)
  1574. X    (list 'polar
  1575. X          (math-sqrt (nth 1 a))
  1576. X          (math-mul (nth 2 a) '(float 5 -1))))
  1577. X   (and (eq (car-safe a) 'sdev) (not (math-negp (nth 1 a)))
  1578. X    (let ((sqrt (math-sqrt (nth 1 a))))
  1579. X      (math-make-sdev sqrt
  1580. X              (math-div (nth 2 a) (math-mul sqrt 2)))))
  1581. X   (and (eq (car-safe a) 'intv)
  1582. X    (math-make-intv (nth 1 a) (math-sqrt (nth 2 a)) (math-sqrt (nth 3 a))))
  1583. X   (and (memq (car-safe a) '(* /))
  1584. X    (let ((s1 (math-sqrt (nth 1 a)))
  1585. X          (s2 (math-sqrt (nth 2 a))))
  1586. X      (and (not (and (eq (car-safe s1) 'calcFunc-sqrt)
  1587. X             (eq (car-safe s2) 'calcFunc-sqrt)))
  1588. X           (if (eq (car a) '*)
  1589. X           (math-mul s1 s2)
  1590. X         (math-div s1 s2)))))
  1591. X   (progn
  1592. X     (calc-record-why 'numberp a)
  1593. X     (list 'calcFunc-sqrt a)))
  1594. X)
  1595. X(fset 'calcFunc-sqrt (symbol-function 'math-sqrt))
  1596. X
  1597. X(defun math-sqrt-float (a &optional guess)   ; [F F F]
  1598. X  (if calc-symbolic-mode
  1599. X      (signal 'inexact-result nil)
  1600. X    (math-with-extra-prec 1 (math-sqrt-raw a guess)))
  1601. X)
  1602. X
  1603. X(defun math-sqrt-raw (a &optional guess)   ; [F F F]
  1604. X  (if (not (Math-posp a))
  1605. X      (math-sqrt a)
  1606. X    (if (null guess)
  1607. X    (let ((ldiff (- (math-numdigs (nth 1 a)) 6)))
  1608. X      (or (= (% (+ (nth 2 a) ldiff) 2) 0) (setq ldiff (1+ ldiff)))
  1609. X      (setq guess (math-make-float (math-isqrt-small
  1610. X                    (math-scale-int (nth 1 a) (- ldiff)))
  1611. X                       (/ (+ (nth 2 a) ldiff) 2)))))
  1612. X    (math-sqrt-float-iter a guess))
  1613. X)
  1614. X
  1615. X(defun math-sqrt-float-iter (a guess)   ; [F F F]
  1616. X  (math-working "sqrt" guess)
  1617. X  (let ((g2 (math-mul-float (math-add-float guess (math-div-float a guess))
  1618. X                '(float 5 -1))))
  1619. X     (if (math-nearly-equal-float g2 guess)
  1620. X     g2
  1621. X       (math-sqrt-float-iter a g2)))
  1622. X)
  1623. X
  1624. X;;; True if A and B differ only in the last digit of precision.  [P F F]
  1625. X(defun math-nearly-equal-float (a b)
  1626. X  (let ((diff (nth 1 (math-sub-float a b))))
  1627. X    (or (eq diff 0)
  1628. X    (and (not (consp diff))
  1629. X         (< diff 10)
  1630. X         (> diff -10)
  1631. X         (= diff (if (< (nth 2 a) (nth 2 b))
  1632. X             (nth 2 a) (nth 2 b)))
  1633. X         (or (= (math-numdigs (nth 1 a)) calc-internal-prec)
  1634. X         (= (math-numdigs (nth 1 b)) calc-internal-prec)))))
  1635. X)
  1636. X
  1637. X(defun math-nearly-equal (a b)   ;  [P R R] [Public]
  1638. X  (math-nearly-equal-float (math-float a) (math-float b))
  1639. X)
  1640. X
  1641. X;;; True if A is nearly zero compared to B.  [P F F]
  1642. X(defun math-nearly-zerop-float (a b)
  1643. X  (or (eq (nth 1 a) 0)
  1644. X      (<= (+ (math-numdigs (nth 1 a)) (nth 2 a))
  1645. X      (1+ (- (+ (math-numdigs (nth 1 b)) (nth 2 b)) calc-internal-prec))))
  1646. X)
  1647. X
  1648. X(defun math-nearly-zerop (a b)
  1649. X  (math-nearly-zerop-float (math-float a) (math-float b))
  1650. X)
  1651. X
  1652. X;;; This implementation could be improved, accuracy-wise.
  1653. X(defun math-hypot (a b)
  1654. X  (cond ((Math-zerop a) (math-abs b))
  1655. X    ((Math-zerop b) (math-abs a))
  1656. X    ((not (Math-scalarp a))
  1657. X     (calc-record-why 'scalarp a)
  1658. X     (list 'calcFunc-hypot a b))
  1659. X    ((not (Math-scalarp b))
  1660. X     (calc-record-why 'scalarp b)
  1661. X     (list 'calcFunc-hypot a b))
  1662. X    ((and (Math-realp a) (Math-realp b))
  1663. X     (math-with-extra-prec 1
  1664. X       (math-sqrt (math-add (math-sqr a) (math-sqr b)))))
  1665. X    ((eq (car-safe a) 'hms)
  1666. X     (if (eq (car-safe b) 'hms)   ; this helps sdev's of hms forms
  1667. X         (math-to-hms (math-hypot (math-from-hms a 'deg)
  1668. X                      (math-from-hms b 'deg)))
  1669. X       (math-to-hms (math-hypot (math-from-hms a 'deg) b))))
  1670. X    ((eq (car-safe b) 'hms)
  1671. X     (math-to-hms (math-hypot a (math-from-hms b 'deg))))
  1672. X    (t nil))
  1673. X)
  1674. X(fset 'calcFunc-hypot (symbol-function 'math-hypot))
  1675. X
  1676. X(defun calcFunc-sqr (x)
  1677. X  (math-pow x 2)
  1678. X)
  1679. X
  1680. X
  1681. X
  1682. X;;; Compute the minimum of two real numbers.  [R R R] [Public]
  1683. X(defun math-min (a b)
  1684. X  (if (and (consp a) (eq (car a) 'intv))
  1685. X      (if (and (consp b) (eq (car b) 'intv))
  1686. X      (let ((lo (nth 2 a))
  1687. X        (lom (memq (nth 1 a) '(2 3)))
  1688. X        (hi (nth 3 a))
  1689. X        (him (memq (nth 1 a) '(1 3)))
  1690. X        res)
  1691. X        (if (= (setq res (math-compare (nth 2 b) lo)) -1)
  1692. X        (setq lo (nth 2 b) lom (memq (nth 1 b) '(2 3)))
  1693. X          (if (= res 0)
  1694. X          (setq lom (or lom (memq (nth 1 b) '(2 3))))))
  1695. X        (if (= (setq res (math-compare (nth 3 b) hi)) -1)
  1696. X        (setq hi (nth 3 b) him (memq (nth 1 b) '(1 3)))
  1697. X          (if (= res 0)
  1698. X          (setq him (or him (memq (nth 1 b) '(1 3))))))
  1699. X        (math-make-intv (+ (if lom 2 0) (if him 1 0)) lo hi))
  1700. X    (math-min a (list 'intv 3 b b)))
  1701. X    (if (and (consp b) (eq (car b) 'intv))
  1702. X    (math-min (list 'intv 3 a a) b)
  1703. X      (if (Math-lessp a b)
  1704. X      a
  1705. X    b)))
  1706. X)
  1707. X
  1708. X(defun calcFunc-min (a &rest b)
  1709. X  (if (not (or (Math-anglep a)
  1710. X           (and (eq (car a) 'intv) (math-constp a))))
  1711. X      (math-reject-arg a 'anglep))
  1712. X  (math-min-list a b)
  1713. X)
  1714. X
  1715. X(defun math-min-list (a b)
  1716. X  (if b
  1717. X      (if (or (Math-anglep (car b))
  1718. X          (and (eq (car (car b)) 'intv) (math-constp (car b))))
  1719. X      (math-min-list (math-min a (car b)) (cdr b))
  1720. X    (math-reject-arg (car b) 'anglep))
  1721. X    a)
  1722. X)
  1723. X
  1724. X;;; Compute the maximum of two real numbers.  [R R R] [Public]
  1725. X(defun math-max (a b)
  1726. X  (if (or (and (consp a) (eq (car a) 'intv))
  1727. X      (and (consp b) (eq (car b) 'intv)))
  1728. X      (math-neg (math-min (math-neg a) (math-neg b)))
  1729. X    (if (Math-lessp a b)
  1730. X    b
  1731. X      a))
  1732. X)
  1733. X
  1734. X(defun calcFunc-max (a &rest b)
  1735. X  (if (not (or (Math-anglep a)
  1736. X           (and (eq (car a) 'intv) (math-constp a))))
  1737. X      (math-reject-arg a 'anglep))
  1738. X  (math-max-list a b)
  1739. X)
  1740. X
  1741. X(defun math-max-list (a b)
  1742. X  (if b
  1743. X      (if (or (Math-anglep (car b))
  1744. X          (and (eq (car (car b)) 'intv) (math-constp (car b))))
  1745. X      (math-max-list (math-max a (car b)) (cdr b))
  1746. X    (math-reject-arg (car b) 'anglep))
  1747. X    a)
  1748. X)
  1749. X
  1750. X
  1751. X;;; Compute the absolute value of A.  [O O; r r] [Public]
  1752. X(defun math-abs (a)
  1753. X  (cond ((Math-negp a)
  1754. X     (math-neg a))
  1755. X    ((Math-anglep a)
  1756. X     a)
  1757. X    ((eq (car a) 'cplx)
  1758. X     (math-hypot (nth 1 a) (nth 2 a)))
  1759. X    ((eq (car a) 'polar)
  1760. X     (nth 1 a))
  1761. X    ((eq (car a) 'vec)
  1762. X     (if (cdr (cdr (cdr a)))
  1763. X         (math-sqrt (math-abssqr a))
  1764. X       (if (cdr (cdr a))
  1765. X           (math-hypot (nth 1 a) (nth 2 a))
  1766. X         (if (cdr a)
  1767. X         (math-abs (nth 1 a))
  1768. X           a))))
  1769. X    ((eq (car a) 'sdev)
  1770. X     (list 'sdev (math-abs (nth 1 a)) (nth 2 a)))
  1771. X    ((and (eq (car a) 'intv) (math-constp a))
  1772. X     (if (Math-posp a)
  1773. X         a
  1774. X       (let* ((nlo (math-neg (nth 2 a)))
  1775. X          (res (math-compare nlo (nth 3 a))))
  1776. X         (cond ((= res 1)
  1777. X            (math-make-intv (if (memq (nth 1 a) '(0 1)) 2 3) 0 nlo))
  1778. X           ((= res 0)
  1779. X            (math-make-intv (if (eq (nth 1 a) 0) 2 3) 0 nlo))
  1780. X           (t
  1781. X            (math-make-intv (if (memq (nth 1 a) '(0 2)) 2 3)
  1782. X                    0 (nth 3 a)))))))
  1783. X    ((eq (car a) 'calcFunc-abs)
  1784. X     (car a))
  1785. X    ((math-looks-negp a)
  1786. X     (list 'calcFunc-abs (math-neg a)))
  1787. X    (t (calc-record-why 'numvecp a)
  1788. X       (list 'calcFunc-abs a)))
  1789. X)
  1790. X(fset 'calcFunc-abs (symbol-function 'math-abs))
  1791. X
  1792. X
  1793. X(defun math-trunc-fancy (a)
  1794. X  (cond ((eq (car a) 'cplx) (math-trunc (nth 1 a)))
  1795. X    ((eq (car a) 'polar) (math-trunc (math-complex a)))
  1796. X    ((eq (car a) 'hms) (list 'hms (nth 1 a) 0 0))
  1797. X    ((eq (car a) 'mod)
  1798. X     (if (math-messy-integerp (nth 2 a))
  1799. X         (math-trunc (math-make-mod (nth 1 a) (math-trunc (nth 2 a))))
  1800. X       (math-make-mod (math-trunc (nth 1 a)) (nth 2 a))))
  1801. X    ((eq (car a) 'intv)
  1802. X     (math-make-intv 3
  1803. X             (if (and (Math-negp (nth 2 a))
  1804. X                  (Math-num-integerp (nth 2 a))
  1805. X                  (memq (nth 1 a) '(0 1)))
  1806. X                 (math-add (math-trunc (nth 2 a)) 1)
  1807. X               (math-trunc (nth 2 a)))
  1808. X             (if (and (Math-posp (nth 3 a))
  1809. X                  (Math-num-integerp (nth 3 a))
  1810. X                  (memq (nth 1 a) '(0 2)))
  1811. X                 (math-add (math-trunc (nth 3 a)) -1)
  1812. X               (math-trunc (nth 3 a)))))
  1813. X    ((math-provably-integerp a) a)
  1814. X    (t (math-reject-arg a 'numberp)))
  1815. X)
  1816. X(defun calcFunc-ftrunc (a)
  1817. X  (math-float (math-trunc a))
  1818. X)
  1819. X
  1820. X(defun math-floor-fancy (a)
  1821. X  (cond ((math-provably-integerp a) a)
  1822. X    ((eq (car a) 'hms)
  1823. X     (if (or (math-posp a)
  1824. X         (and (math-zerop (nth 2 a))
  1825. X              (math-zerop (nth 3 a))))
  1826. X         (math-trunc a)
  1827. X       (math-add (math-trunc a) -1)))
  1828. X    ((eq (car a) 'intv)
  1829. X     (math-make-intv 3
  1830. X             (math-floor (nth 2 a))
  1831. X             (if (and (Math-num-integerp (nth 3 a))
  1832. X                  (memq (nth 1 a) '(0 2)))
  1833. X                 (math-add (math-floor (nth 3 a)) -1)
  1834. X               (math-floor (nth 3 a)))))
  1835. X    (t (math-reject-arg a 'anglep)))
  1836. X)
  1837. X(defun calcFunc-ffloor (a)
  1838. X  (math-float (math-floor a))
  1839. X)
  1840. X
  1841. X;;; Coerce A to be an integer (by truncation toward plus infinity).  [I N]
  1842. X(defun math-ceiling (a)   ;  [Public]
  1843. X  (cond ((Math-integerp a) a)
  1844. X    ((Math-messy-integerp a) (math-trunc a))
  1845. X    ((Math-realp a)
  1846. X     (if (Math-posp a)
  1847. X         (math-add (math-trunc a) 1)
  1848. X       (math-trunc a)))
  1849. X    ((math-provably-integerp a) a)
  1850. X    ((eq (car a) 'hms)
  1851. X     (if (or (math-negp a)
  1852. X         (and (math-zerop (nth 2 a))
  1853. X              (math-zerop (nth 3 a))))
  1854. X         (math-trunc a)
  1855. X       (math-add (math-trunc a) 1)))
  1856. X    ((eq (car a) 'intv)
  1857. X     (math-make-intv 3
  1858. X             (if (and (Math-num-integerp (nth 2 a))
  1859. X                  (memq (nth 1 a) '(0 1)))
  1860. X                 (math-add (math-floor (nth 2 a)) 1)
  1861. X               (math-ceiling (nth 2 a)))
  1862. X             (math-ceiling (nth 3 a))))
  1863. X    (t (math-reject-arg a 'anglep)))
  1864. X)
  1865. X(fset 'calcFunc-ceil (symbol-function 'math-ceiling))
  1866. X(defun calcFunc-fceil (a)
  1867. X  (math-float (math-ceiling a))
  1868. X)
  1869. X
  1870. X;;; Coerce A to be an integer (by rounding to nearest integer).  [I N] [Public]
  1871. X(defun math-round (a)
  1872. X  (cond ((Math-anglep a)
  1873. X     (if (Math-num-integerp a)
  1874. X         (math-trunc a)
  1875. X       (if (Math-negp a)
  1876. X           (math-neg (math-round (math-neg a)))
  1877. X         (math-floor
  1878. X          (let ((calc-angle-mode 'deg))   ; in case of HMS forms
  1879. X        (math-add a (if (Math-ratp a)
  1880. X                '(frac 1 2)
  1881. X                  '(float 5 -1))))))))
  1882. X    ((math-provably-integerp a) a)
  1883. X    ((eq (car a) 'intv)
  1884. X     (math-floor (math-add a '(frac 1 2))))
  1885. X    (t (math-reject-arg a 'anglep)))
  1886. X)
  1887. X(fset 'calcFunc-round (symbol-function 'math-round))
  1888. X(defun calcFunc-fround (a)
  1889. X  (math-float (math-round a))
  1890. X)
  1891. X
  1892. X
  1893. X;;; Convert a real value to fractional form.  [T R I; T R F] [Public]
  1894. X(defun math-to-fraction (a &optional tol)
  1895. X  (or tol (setq tol 0))
  1896. X  (cond ((Math-ratp a)
  1897. X     a)
  1898. X    ((memq (car a) '(cplx polar vec hms sdev intv mod))
  1899. X     (cons (car a) (mapcar (function
  1900. X                (lambda (x)
  1901. X                  (math-to-fraction x tol)))
  1902. X                   (cdr a))))
  1903. X    ((Math-negp a)
  1904. X     (math-neg (math-to-fraction (math-neg a) tol)))
  1905. X    ((not (eq (car a) 'float))
  1906. X     (math-reject-arg a 'numberp))
  1907. X    ((integerp tol)
  1908. X     (if (<= tol 0)
  1909. X         (setq tol (+ tol calc-internal-prec)))
  1910. X     (math-to-fraction a (list 'float 5
  1911. SHAR_EOF
  1912. echo "End of part 7"
  1913. echo "File calc-ext.el is continued in part 8"
  1914. echo "8" > s2_seq_.tmp
  1915. exit 0
  1916.