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

  1. Newsgroups: comp.sources.misc
  2. From: daveg@synaptics.com (David Gillespie)
  3. Subject:  v24i068:  gnucalc - GNU Emacs Calculator, v2.00, Part20/56
  4. Message-ID: <1991Oct31.072623.17905@sparky.imd.sterling.com>
  5. X-Md4-Signature: 11216148d336062cdeea96b5953f7641
  6. Date: Thu, 31 Oct 1991 07:26:23 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: daveg@synaptics.com (David Gillespie)
  10. Posting-number: Volume 24, Issue 68
  11. Archive-name: gnucalc/part20
  12. Environment: Emacs
  13. Supersedes: gmcalc: Volume 13, Issue 27-45
  14.  
  15. ---- Cut Here and unpack ----
  16. #!/bin/sh
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file calc-maint.el continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 20; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping calc-maint.el'
  34. else
  35. echo 'x - continuing file calc-maint.el'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'calc-maint.el' &&
  37. X    (beginning-of-line)
  38. X    (setq tutpos (point))
  39. X    (search-forward "@c [reference]")
  40. X    (beginning-of-line)
  41. X    (setq refpos (point))
  42. X    (search-forward "@c [end]")
  43. X    (beginning-of-line)
  44. X    (setq endpos (point))
  45. X    (find-file "calctut.tex")
  46. X    (erase-buffer)
  47. X    (insert-buffer-substring srcbuf 1 refpos)
  48. X    (insert-buffer-substring srcbuf endpos maxpos)
  49. X    (calc-split-volume "I" "ref" "Tutorial" "Reference")
  50. X    (save-buffer)
  51. X    (find-file "calcref.tex")
  52. X    (erase-buffer)
  53. X    (insert-buffer-substring srcbuf 1 tutpos)
  54. X    (insert "\n@tex\n\\global\\advance\\chapno by 1\n@end tex\n")
  55. X    (insert-buffer-substring srcbuf refpos maxpos)
  56. X    (calc-split-volume "II" "tut" "Reference" "Tutorial")
  57. X    (save-buffer)
  58. X    (switch-to-buffer srcbuf)
  59. X    (goto-char 1))
  60. X  (message "Wrote files calctut.tex and calcref.tex")
  61. )
  62. X
  63. (defun calc-split-volume (number fix name other-name)
  64. X  (goto-char 1)
  65. X  (search-forward "@c [title]\n")
  66. X  (search-forward "Manual")
  67. X  (delete-backward-char 6)
  68. X  (insert name)
  69. X  (search-forward "@c [volume]\n")
  70. X  (insert "@sp 1\n@center Volume " number ": " name "\n")
  71. X  (let ((pat (format "@c \\[fix-%s \\(.*\\)\\]\n" fix)))
  72. X    (while (re-search-forward pat nil t)
  73. X      (let ((topic (buffer-substring (match-beginning 1) (match-end 1))))
  74. X    (re-search-forward "@\\(p?xref\\){[^}]*}")
  75. X    (let ((cmd (buffer-substring (match-beginning 1) (match-end 1))))
  76. X      (delete-region (match-beginning 0) (match-end 0))
  77. X      (insert (if (equal cmd "pxref") "see" "See")
  78. X          " ``" topic "'' in @emph{the Calc "
  79. X          other-name "}")))))
  80. X  (goto-char 1)
  81. X  (while (search-forward "@c [when-split]\n" nil t)
  82. X    (while (looking-at "@c ")
  83. X      (delete-char 3)
  84. X      (forward-line 1)))
  85. X  (goto-char 1)
  86. X  (while (search-forward "@c [not-split]\n" nil t)
  87. X    (while (not (looking-at "@c"))
  88. X      (insert "@c ")
  89. X      (forward-line 1)))
  90. )
  91. X
  92. X
  93. (defun calc-split-summary (&optional force)
  94. X  "Make a special \"calcsum.tex\" file with just the Calc summary."
  95. X  (interactive "P")
  96. X  (or (let ((case-fold-search t))
  97. X    (string-match "calc\\.texinfo" (buffer-name)))
  98. X      force
  99. X      (error "This command should be used in the calc.texinfo buffer."))
  100. X  (let ((srcbuf (current-buffer))
  101. X    begpos sumpos endpos)
  102. X    (goto-char 1)
  103. X    (search-forward "{Calc Manual}")
  104. X    (backward-char 1)
  105. X    (delete-backward-char 6)
  106. X    (insert "Summary")
  107. X    (search-forward "@c [begin]")
  108. X    (beginning-of-line)
  109. X    (setq begpos (point))
  110. X    (search-forward "@c [summary]")
  111. X    (beginning-of-line)
  112. X    (setq sumpos (point))
  113. X    (search-forward "@c [end-summary]")
  114. X    (beginning-of-line)
  115. X    (setq endpos (point))
  116. X    (find-file "calcsum.tex")
  117. X    (erase-buffer)
  118. X    (insert-buffer-substring srcbuf 1 begpos)
  119. X    (insert "@tex\n"
  120. X        "\\global\\advance\\appendixno2\n"
  121. X        "\\gdef\\xref#1.{See ``#1.''}\n"
  122. X        "@end tex\n")
  123. X    (insert-buffer-substring srcbuf sumpos endpos)
  124. X    (insert "@bye\n")
  125. X    (goto-char 1)
  126. X    (if (search-forward "@c smallbook" nil t)
  127. X    (progn   ; activate "smallbook" format for compactness
  128. X      (beginning-of-line)
  129. X      (forward-char 1)
  130. X      (delete-char 2)))
  131. X    (save-buffer))
  132. X  (message "Wrote file calcsum.tex")
  133. )
  134. X
  135. X
  136. X
  137. (defun calc-public-autoloads ()
  138. X  "Modify the public \"default\" file to contain the necessary autoload and
  139. global-set-key commands for Calc."
  140. X  (interactive)
  141. X  (let ((home default-directory)
  142. X    (p load-path)
  143. X    instbuf name)
  144. X    (while (and p
  145. X        (not (file-exists-p
  146. X              (setq name (expand-file-name "default" (car p)))))
  147. X        (not (file-exists-p
  148. X              (setq name (expand-file-name "default.el" (car p))))))
  149. X      (setq p (cdr p)))
  150. X    (or p (error "Unable to find \"default\" file.  Create one and try again."))
  151. X    (find-file name)
  152. X    (if buffer-read-only (error "No write permission for \"%s\"" buffer-file-name))
  153. X    (goto-char (point-max))
  154. X    (calc-add-autoloads home "calc-public-autoloads"))
  155. )
  156. X
  157. (defun calc-private-autoloads ()
  158. X  "Modify the public \"default\" file to contain the necessary autoload and
  159. global-set-key commands for Calc."
  160. X  (interactive)
  161. X  (let ((home default-directory))
  162. X    (find-file "~/.emacs")
  163. X    (goto-char (point-max))
  164. X    (calc-add-autoloads home "calc-private-autoloads"))
  165. )
  166. X
  167. (defun calc-add-autoloads (home cmd)
  168. X  (barf-if-buffer-read-only)
  169. X  (let (top)
  170. X    (if (and (re-search-backward ";;; Commands added by calc-.*-autoloads"
  171. X                 nil t)
  172. X         (setq top (point))
  173. X         (search-forward ";;; End of Calc autoloads" nil t))
  174. X    (progn
  175. X      (forward-line 1)
  176. X      (message "(Removing previous autoloads)")
  177. X      (delete-region top (point)))
  178. X      (insert "\n\n")
  179. X      (backward-char 1)))
  180. X  (insert ";;; Commands added by " cmd " on "
  181. X      (current-time-string) ".
  182. \(autoload 'calc-dispatch       \"calc\" \"Calculator Options\" t)
  183. \(autoload 'full-calc           \"calc\" \"Full-screen Calculator\" t)
  184. \(autoload 'full-calc-keypad       \"calc\" \"Full-screen X Calculator\" t)
  185. \(autoload 'calc-eval           \"calc\" \"Use Calculator from Lisp\")
  186. \(autoload 'defmath           \"calc\" nil t t)
  187. \(autoload 'calc               \"calc\" \"Calculator Mode\" t)
  188. \(autoload 'quick-calc           \"calc\" \"Quick Calculator\" t)
  189. \(autoload 'calc-keypad           \"calc\" \"X windows Calculator\" t)
  190. \(autoload 'calc-embedded       \"calc\" \"Use Calc inside any buffer\" t)
  191. \(autoload 'calc-embedded-activate  \"calc\" \"Activate =>'s in buffer\" t)
  192. \(autoload 'calc-grab-region       \"calc\" \"Grab region of Calc data\" t)
  193. \(autoload 'calc-grab-rectangle       \"calc\" \"Grab rectangle of data\" t)
  194. \(autoload 'edit-kbd-macro       \"macedit\" \"Edit Keyboard Macro\" t)
  195. \(autoload 'edit-last-kbd-macro       \"macedit\" \"Edit Keyboard Macro\" t)
  196. \(autoload 'read-kbd-macro       \"macedit\" \"Read Keyboard Macro\" t)
  197. \(setq load-path (append load-path (list \"" (directory-file-name home) "\")))
  198. \(global-set-key \"\\e#\" 'calc-dispatch)
  199. ;;; End of Calc autoloads.\n")
  200. X  (save-buffer)
  201. )
  202. X
  203. X
  204. X
  205. ;;; End.
  206. SHAR_EOF
  207. echo 'File calc-maint.el is complete' &&
  208. chmod 0644 calc-maint.el ||
  209. echo 'restore of calc-maint.el failed'
  210. Wc_c="`wc -c < 'calc-maint.el'`"
  211. test 12652 -eq "$Wc_c" ||
  212.     echo 'calc-maint.el: original size 12652, current size' "$Wc_c"
  213. rm -f _shar_wnt_.tmp
  214. fi
  215. # ============= calc-map.el ==============
  216. if test -f 'calc-map.el' -a X"$1" != X"-c"; then
  217.     echo 'x - skipping calc-map.el (File already exists)'
  218.     rm -f _shar_wnt_.tmp
  219. else
  220. > _shar_wnt_.tmp
  221. echo 'x - extracting calc-map.el (Text)'
  222. sed 's/^X//' << 'SHAR_EOF' > 'calc-map.el' &&
  223. ;; Calculator for GNU Emacs, part II [calc-map.el]
  224. ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  225. ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
  226. X
  227. ;; This file is part of GNU Emacs.
  228. X
  229. ;; GNU Emacs is distributed in the hope that it will be useful,
  230. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  231. ;; accepts responsibility to anyone for the consequences of using it
  232. ;; or for whether it serves any particular purpose or works at all,
  233. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  234. ;; License for full details.
  235. X
  236. ;; Everyone is granted permission to copy, modify and redistribute
  237. ;; GNU Emacs, but only under the conditions described in the
  238. ;; GNU Emacs General Public License.   A copy of this license is
  239. ;; supposed to have been given to you along with GNU Emacs so you
  240. ;; can know your rights and responsibilities.  It should be in a
  241. ;; file named COPYING.  Among other things, the copyright notice
  242. ;; and this notice must be preserved on all copies.
  243. X
  244. X
  245. X
  246. ;; This file is autoloaded from calc-ext.el.
  247. (require 'calc-ext)
  248. X
  249. (require 'calc-macs)
  250. X
  251. (defun calc-Need-calc-map () nil)
  252. X
  253. X
  254. (defun calc-apply (&optional oper)
  255. X  (interactive)
  256. X  (calc-wrapper
  257. X   (let* ((sel-mode nil)
  258. X      (calc-dollar-values (mapcar 'calc-get-stack-element
  259. X                      (nthcdr calc-stack-top calc-stack)))
  260. X      (calc-dollar-used 0)
  261. X      (oper (or oper (calc-get-operator "Apply"
  262. X                        (if (math-vectorp (calc-top 1))
  263. X                        (1- (length (calc-top 1)))
  264. X                          -1))))
  265. X      (expr (calc-top-n (1+ calc-dollar-used))))
  266. X     (message "Working...")
  267. X     (calc-set-command-flag 'clear-message)
  268. X     (calc-enter-result (1+ calc-dollar-used)
  269. X            (concat (substring "apl" 0 (- 4 (length (nth 2 oper))))
  270. X                (nth 2 oper))
  271. X            (list 'calcFunc-apply
  272. X                  (math-calcFunc-to-var (nth 1 oper))
  273. X                  expr))))
  274. )
  275. X
  276. (defun calc-reduce (&optional oper accum)
  277. X  (interactive)
  278. X  (calc-wrapper
  279. X   (let* ((sel-mode nil)
  280. X      (nest (calc-is-hyperbolic))
  281. X      (rev (calc-is-inverse))
  282. X      (nargs (if (and nest (not rev)) 2 1))
  283. X      (calc-dollar-values (mapcar 'calc-get-stack-element
  284. X                      (nthcdr calc-stack-top calc-stack)))
  285. X      (calc-dollar-used 0)
  286. X      (calc-mapping-dir (and (not accum) (not nest) ""))
  287. X      (oper (or oper (calc-get-operator
  288. X              (if nest
  289. X                  (concat (if accum "Accumulate " "")
  290. X                      (if rev "Fixed Point" "Nest"))
  291. X                (concat (if rev "Inv " "")
  292. X                    (if accum "Accumulate" "Reduce")))
  293. X              (if nest 1 2)))))
  294. X     (message "Working...")
  295. X     (calc-set-command-flag 'clear-message)
  296. X     (calc-enter-result (+ calc-dollar-used nargs)
  297. X            (concat (substring (if nest
  298. X                           (if rev "fxp" "nst")
  299. X                         (if accum "acc" "red"))
  300. X                       0 (- 4 (length (nth 2 oper))))
  301. X                (nth 2 oper))
  302. X            (if nest
  303. X                (cons (if rev
  304. X                      (if accum 'calcFunc-afixp 'calcFunc-fixp)
  305. X                    (if accum 'calcFunc-anest 'calcFunc-nest))
  306. X                  (cons (math-calcFunc-to-var (nth 1 oper))
  307. X                    (calc-top-list-n
  308. X                     nargs (1+ calc-dollar-used))))
  309. X              (list (if accum
  310. X                    (if rev 'calcFunc-raccum 'calcFunc-accum)
  311. X                  (intern (concat "calcFunc-"
  312. X                          (if rev "r" "")
  313. X                          "reduce"
  314. X                          calc-mapping-dir)))
  315. X                (math-calcFunc-to-var (nth 1 oper))
  316. X                (calc-top-n (1+ calc-dollar-used)))))))
  317. )
  318. X
  319. (defun calc-accumulate (&optional oper)
  320. X  (interactive)
  321. X  (calc-reduce oper t)
  322. )
  323. X
  324. (defun calc-map (&optional oper)
  325. X  (interactive)
  326. X  (calc-wrapper
  327. X   (let* ((sel-mode nil)
  328. X      (calc-dollar-values (mapcar 'calc-get-stack-element
  329. X                      (nthcdr calc-stack-top calc-stack)))
  330. X      (calc-dollar-used 0)
  331. X      (calc-mapping-dir "")
  332. X      (oper (or oper (calc-get-operator "Map")))
  333. X      (nargs (car oper)))
  334. X     (message "Working...")
  335. X     (calc-set-command-flag 'clear-message)
  336. X     (calc-enter-result (+ nargs calc-dollar-used)
  337. X            (concat (substring "map" 0 (- 4 (length (nth 2 oper))))
  338. X                (nth 2 oper))
  339. X            (cons (intern (concat "calcFunc-map" calc-mapping-dir))
  340. X                  (cons (math-calcFunc-to-var (nth 1 oper))
  341. X                    (calc-top-list-n
  342. X                     nargs
  343. X                     (1+ calc-dollar-used)))))))
  344. )
  345. X
  346. (defun calc-map-equation (&optional oper)
  347. X  (interactive)
  348. X  (calc-wrapper
  349. X   (let* ((sel-mode nil)
  350. X      (calc-dollar-values (mapcar 'calc-get-stack-element
  351. X                      (nthcdr calc-stack-top calc-stack)))
  352. X      (calc-dollar-used 0)
  353. X      (oper (or oper (calc-get-operator "Map-equation")))
  354. X      (nargs (car oper)))
  355. X     (message "Working...")
  356. X     (calc-set-command-flag 'clear-message)
  357. X     (calc-enter-result (+ nargs calc-dollar-used)
  358. X            (concat (substring "map" 0 (- 4 (length (nth 2 oper))))
  359. X                (nth 2 oper))
  360. X            (cons (if (calc-is-inverse)
  361. X                  'calcFunc-mapeqr
  362. X                (if (calc-is-hyperbolic)
  363. X                    'calcFunc-mapeqp 'calcFunc-mapeq))
  364. X                  (cons (math-calcFunc-to-var (nth 1 oper))
  365. X                    (calc-top-list-n
  366. X                     nargs
  367. X                     (1+ calc-dollar-used)))))))
  368. )
  369. X
  370. (defun calc-map-stack ()
  371. X  "This is meant to be called by calc-keypad mode."
  372. X  (interactive)
  373. X  (let ((calc-verify-arglist nil))
  374. X    (setq unread-command-char ?\$)
  375. X    (calc-map))
  376. )
  377. X
  378. (defun calc-outer-product (&optional oper)
  379. X  (interactive)
  380. X  (calc-wrapper
  381. X   (let* ((sel-mode nil)
  382. X      (calc-dollar-values (mapcar 'calc-get-stack-element
  383. X                      (nthcdr calc-stack-top calc-stack)))
  384. X      (calc-dollar-used 0)
  385. X      (oper (or oper (calc-get-operator "Outer" 2))))
  386. X     (message "Working...")
  387. X     (calc-set-command-flag 'clear-message)
  388. X     (calc-enter-result (+ 2 calc-dollar-used)
  389. X            (concat (substring "out" 0 (- 4 (length (nth 2 oper))))
  390. X                (nth 2 oper))
  391. X            (cons 'calcFunc-outer
  392. X                  (cons (math-calcFunc-to-var (nth 1 oper))
  393. X                    (calc-top-list-n
  394. X                     2 (1+ calc-dollar-used)))))))
  395. )
  396. X
  397. (defun calc-inner-product (&optional mul-oper add-oper)
  398. X  (interactive)
  399. X  (calc-wrapper
  400. X   (let* ((sel-mode nil)
  401. X      (calc-dollar-values (mapcar 'calc-get-stack-element
  402. X                      (nthcdr calc-stack-top calc-stack)))
  403. X      (calc-dollar-used 0)
  404. X      (mul-oper (or mul-oper (calc-get-operator "Inner (Mult)" 2)))
  405. X      (mul-used calc-dollar-used)
  406. X      (calc-dollar-values (if (> mul-used 0)
  407. X                  (cdr calc-dollar-values)
  408. X                calc-dollar-values))
  409. X      (calc-dollar-used 0)
  410. X      (add-oper (or add-oper (calc-get-operator "Inner (Add)" 2))))
  411. X     (message "Working...")
  412. X     (calc-set-command-flag 'clear-message)
  413. X     (calc-enter-result (+ 2 mul-used calc-dollar-used)
  414. X            (concat "in"
  415. X                (substring (nth 2 mul-oper) 0 1)
  416. X                (substring (nth 2 add-oper) 0 1))
  417. X            (nconc (list 'calcFunc-inner
  418. X                     (math-calcFunc-to-var (nth 1 mul-oper))
  419. X                     (math-calcFunc-to-var (nth 1 add-oper)))
  420. X                   (calc-top-list-n
  421. X                2 (+ 1 mul-used calc-dollar-used))))))
  422. )
  423. X
  424. ;;; Return a list of the form (nargs func name)
  425. (defun calc-get-operator (msg &optional nargs)
  426. X  (setq calc-aborted-prefix nil)
  427. X  (let ((inv nil) (hyp nil) (prefix nil) (forcenargs nil)
  428. X    done key oper (which 0)
  429. X    (msgs '( "(Press ? for help)"
  430. X         "+, -, *, /, ^, %, \\, :, &, !, |, Neg"
  431. X         "SHIFT + Abs, conJ, arG; maX, miN; Floor, Round; sQrt"
  432. X         "SHIFT + Inv, Hyp; Sin, Cos, Tan; Exp, Ln, logB"
  433. X         "Algebra + Simp, Esimp, Deriv, Integ, !, =, etc."
  434. X         "Binary + And, Or, Xor, Diff; l/r/t/L/R shifts; Not, Clip"
  435. X         "Conversions + Deg, Rad, HMS; Float; SHIFT + Fraction"
  436. X         "Functions + Re, Im; Hypot; Mant, Expon, Scale; etc."
  437. X         "Kombinatorics + Dfact, Lcm, Gcd, Choose; Random; etc."
  438. X         "Time/date + newYear, Incmonth, etc."
  439. X         "Vectors + Length, Row, Col, Diag, Mask, etc."
  440. X         "_ = mapr/reducea, : = mapc/reduced, = = reducer"
  441. X         "X or Z = any function by name; ' = alg entry; $ = stack")))
  442. X    (while (not done)
  443. X      (message "%s%s: %s: %s%s%s"
  444. X           msg
  445. X           (cond ((equal calc-mapping-dir "r") " rows")
  446. X             ((equal calc-mapping-dir "c") " columns")
  447. X             ((equal calc-mapping-dir "a") " across")
  448. X             ((equal calc-mapping-dir "d") " down")
  449. X             (t ""))
  450. X           (if forcenargs
  451. X           (format "(%d arg%s)"
  452. X               forcenargs (if (= forcenargs 1) "" "s"))
  453. X         (nth which msgs))
  454. X           (if inv "Inv " "") (if hyp "Hyp " "")
  455. X           (if prefix (concat (char-to-string prefix) "-") ""))
  456. X      (setq key (read-char))
  457. X      (if (>= key 128) (setq key (- key 128)))
  458. X      (cond ((memq key '(?\C-g ?q))
  459. X         (keyboard-quit))
  460. X        ((memq key '(?\C-u ?\e)))
  461. X        ((= key ??)
  462. X         (setq which (% (1+ which) (length msgs))))
  463. X        ((and (= key ?I) (null prefix))
  464. X         (setq inv (not inv)))
  465. X        ((and (= key ?H) (null prefix))
  466. X         (setq hyp (not hyp)))
  467. X        ((and (eq key prefix) (not (eq key ?v)))
  468. X         (setq prefix nil))
  469. X        ((and (memq key '(?a ?b ?c ?f ?k ?s ?t ?u ?v ?V))
  470. X          (null prefix))
  471. X         (setq prefix (downcase key)))
  472. X        ((and (eq key ?\=) (null prefix))
  473. X         (if calc-mapping-dir
  474. X         (setq calc-mapping-dir (if (equal calc-mapping-dir "r")
  475. X                        "" "r"))
  476. X           (beep)))
  477. X        ((and (eq key ?\_) (null prefix))
  478. X         (if calc-mapping-dir
  479. X         (if (string-match "map$" msg)
  480. X             (setq calc-mapping-dir (if (equal calc-mapping-dir "r")
  481. X                        "" "r"))
  482. X           (setq calc-mapping-dir (if (equal calc-mapping-dir "a")
  483. X                          "" "a")))
  484. X           (beep)))
  485. X        ((and (eq key ?\:) (null prefix))
  486. X         (if calc-mapping-dir
  487. X         (if (string-match "map$" msg)
  488. X             (setq calc-mapping-dir (if (equal calc-mapping-dir "c")
  489. X                        "" "c"))
  490. X           (setq calc-mapping-dir (if (equal calc-mapping-dir "d")
  491. X                          "" "d")))
  492. X           (beep)))
  493. X        ((and (>= key ?0) (<= key ?9) (null prefix))
  494. X         (setq forcenargs (if (eq forcenargs (- key ?0)) nil (- key ?0)))
  495. X         (and nargs forcenargs (/= nargs forcenargs) (>= nargs 0)
  496. X          (error "Must be a %d-argument operator" nargs)))
  497. X        ((memq key '(?\$ ?\'))
  498. X         (let* ((arglist nil)
  499. X            (has-args nil)
  500. X            (record-entry nil)
  501. X            (expr (if (eq key ?\$)
  502. X                  (progn
  503. X                (setq calc-dollar-used 1)
  504. X                (if calc-dollar-values
  505. X                    (car calc-dollar-values)
  506. X                  (error "Stack underflow")))
  507. X                (let* ((calc-dollar-values calc-arg-values)
  508. X                   (calc-dollar-used 0)
  509. X                   (calc-hashes-used 0)
  510. X                   (func (calc-do-alg-entry "" "Function: ")))
  511. X                  (setq record-entry t)
  512. X                  (or (= (length func) 1)
  513. X                  (error "Bad format"))
  514. X                  (if (> calc-dollar-used 0)
  515. X                  (progn
  516. X                    (setq has-args calc-dollar-used
  517. X                      arglist (calc-invent-args has-args))
  518. X                    (math-multi-subst (car func)
  519. X                              (reverse arglist)
  520. X                              arglist))
  521. X                (if (> calc-hashes-used 0)
  522. X                    (setq has-args calc-hashes-used
  523. X                      arglist (calc-invent-args has-args)))
  524. X                (car func))))))
  525. X           (if (eq (car-safe expr) 'calcFunc-lambda)
  526. X           (setq oper (list "$" (- (length expr) 2) expr)
  527. X             done t)
  528. X         (or has-args
  529. X             (progn
  530. X               (calc-default-formula-arglist expr)
  531. X               (setq record-entry t
  532. X                 arglist (sort arglist 'string-lessp))
  533. X               (if calc-verify-arglist
  534. X               (setq arglist (read-from-minibuffer
  535. X                      "Function argument list: "
  536. X                      (if arglist
  537. X                          (prin1-to-string arglist)
  538. X                        "()")
  539. X                      minibuffer-local-map
  540. X                      t)))
  541. X               (setq arglist (mapcar (function
  542. X                          (lambda (x)
  543. X                        (list 'var
  544. X                              x
  545. X                              (intern
  546. X                               (concat
  547. X                            "var-"
  548. X                            (symbol-name x))))))
  549. X                         arglist))))
  550. X         (setq oper (list "$"
  551. X                  (length arglist)
  552. X                  (append '(calcFunc-lambda) arglist
  553. X                      (list expr)))
  554. X               done t))
  555. X           (if record-entry
  556. X           (calc-record (nth 2 oper) "oper"))))
  557. X        ((setq oper (assq key (nth (if inv (if hyp 3 1) (if hyp 2 0))
  558. X                       (if prefix
  559. X                       (symbol-value
  560. X                        (intern (format "calc-%c-oper-keys"
  561. X                                prefix)))
  562. X                     calc-oper-keys))))
  563. X         (if (eq (nth 1 oper) 'user)
  564. X         (let ((func (intern
  565. X                  (completing-read "Function name: "
  566. X                           obarray 'fboundp
  567. X                           nil "calcFunc-"))))
  568. X           (if (or forcenargs nargs)
  569. X               (setq oper (list "z" (or forcenargs nargs) func)
  570. X                 done t)
  571. X             (if (fboundp func)
  572. X             (let* ((defn (symbol-function func)))
  573. X               (and (symbolp defn)
  574. X                (setq defn (symbol-function defn)))
  575. X               (if (eq (car-safe defn) 'lambda)
  576. X                   (let ((args (nth 1 defn))
  577. X                     (nargs 0))
  578. X                 (while (not (memq (car args) '(&optional
  579. X                                &rest nil)))
  580. X                   (setq nargs (1+ nargs)
  581. X                     args (cdr args)))
  582. X                 (setq oper (list "z" nargs func)
  583. X                       done t))
  584. X                 (error
  585. X                  "Function is not suitable for this operation")))
  586. X               (message "Number of arguments: ")
  587. X               (let ((nargs (read-char)))
  588. X             (if (and (>= nargs ?0) (<= nargs ?9))
  589. X                 (setq oper (list "z" (- nargs ?0) func)
  590. X                   done t)
  591. X               (beep))))))
  592. X           (if (or (and (eq prefix ?v) (memq key '(?A ?I ?M ?O ?R ?U)))
  593. X               (and (eq prefix ?a) (eq key ?M)))
  594. X           (let* ((dir (cond ((and (equal calc-mapping-dir "")
  595. X                       (string-match "map$" msg))
  596. X                      (setq calc-mapping-dir "r")
  597. X                      " rows")
  598. X                     ((equal calc-mapping-dir "r") " rows")
  599. X                     ((equal calc-mapping-dir "c") " columns")
  600. X                     ((equal calc-mapping-dir "a") " across")
  601. X                     ((equal calc-mapping-dir "d") " down")
  602. X                     (t "")))
  603. X              (calc-mapping-dir (and (memq (nth 2 oper)
  604. X                               '(calcFunc-map
  605. X                             calcFunc-reduce
  606. X                             calcFunc-rreduce))
  607. X                         ""))
  608. X              (oper2 (calc-get-operator
  609. X                  (format "%s%s, %s%s" msg dir
  610. X                      (substring (symbol-name (nth 2 oper))
  611. X                             9)
  612. X                      (if (eq key ?I) " (mult)" ""))
  613. X                  (cdr (assq (nth 2 oper)
  614. X                         '((calcFunc-reduce  . 2)
  615. X                           (calcFunc-rreduce . 2)
  616. X                           (calcFunc-accum   . 2)
  617. X                           (calcFunc-raccum  . 2)
  618. X                           (calcFunc-nest    . 2)
  619. X                           (calcFunc-anest   . 2)
  620. X                           (calcFunc-fixp    . 2)
  621. X                           (calcFunc-afixp   . 2))))))
  622. X              (oper3 (if (eq (nth 2 oper) 'calcFunc-inner)
  623. X                     (calc-get-operator
  624. X                      (format "%s%s, inner (add)" msg dir
  625. X                          (substring
  626. X                           (symbol-name (nth 2 oper))
  627. X                           9)))
  628. X                   '(0 0 0)))
  629. X              (args nil)
  630. X              (nargs (if (> (nth 1 oper) 0)
  631. X                     (nth 1 oper)
  632. X                   (car oper2)))
  633. X              (n nargs)
  634. X              (p calc-arg-values))
  635. X             (while (and p (> n 0))
  636. X               (or (math-expr-contains (nth 1 oper2) (car p))
  637. X               (math-expr-contains (nth 1 oper3) (car p))
  638. X               (setq args (nconc args (list (car p)))
  639. X                 n (1- n)))
  640. X               (setq p (cdr p)))
  641. X             (setq oper (list "" nargs
  642. X                      (append
  643. X                       '(calcFunc-lambda)
  644. X                       args
  645. X                       (list (math-build-call
  646. X                          (intern
  647. X                           (concat
  648. X                        (symbol-name (nth 2 oper))
  649. X                        calc-mapping-dir))
  650. X                          (cons (math-calcFunc-to-var
  651. X                             (nth 1 oper2))
  652. X                            (if (eq key ?I)
  653. X                            (cons
  654. X                             (math-calcFunc-to-var
  655. X                              (nth 1 oper3))
  656. X                             args)
  657. X                              args))))))
  658. X               done t))
  659. X         (setq done t))))
  660. X        (t (beep))))
  661. X    (and nargs (>= nargs 0)
  662. X     (/= nargs (nth 1 oper))
  663. X     (error "Must be a %d-argument operator" nargs))
  664. X    (append (if forcenargs
  665. X        (cons forcenargs (cdr (cdr oper)))
  666. X          (cdr oper))
  667. X        (list
  668. X         (let ((name (concat (if inv "I" "") (if hyp "H" "")
  669. X                 (if prefix (char-to-string prefix) "")
  670. X                 (char-to-string key))))
  671. X           (if (> (length name) 3)
  672. X           (substring name 0 3)
  673. X         name)))))
  674. )
  675. (setq calc-verify-arglist t)
  676. (setq calc-mapping-dir nil)
  677. X
  678. (defconst calc-oper-keys '( ( ( ?+ 2 calcFunc-add )
  679. X                  ( ?- 2 calcFunc-sub )
  680. X                  ( ?* 2 calcFunc-mul )
  681. X                  ( ?/ 2 calcFunc-div )
  682. X                  ( ?^ 2 calcFunc-pow )
  683. X                  ( ?| 2 calcFunc-vconcat )
  684. X                  ( ?% 2 calcFunc-mod )
  685. X                  ( ?\\ 2 calcFunc-idiv )
  686. X                  ( ?! 1 calcFunc-fact )
  687. X                  ( ?& 1 calcFunc-inv )
  688. X                  ( ?n 1 calcFunc-neg )
  689. X                  ( ?x user )
  690. X                  ( ?z user )
  691. X                  ( ?A 1 calcFunc-abs )
  692. X                  ( ?J 1 calcFunc-conj )
  693. X                  ( ?G 1 calcFunc-arg )
  694. X                  ( ?Q 1 calcFunc-sqrt )
  695. X                  ( ?N 2 calcFunc-min )
  696. X                  ( ?X 2 calcFunc-max )
  697. X                  ( ?F 1 calcFunc-floor )
  698. X                  ( ?R 1 calcFunc-round )
  699. X                  ( ?S 1 calcFunc-sin )
  700. X                  ( ?C 1 calcFunc-cos )
  701. X                  ( ?T 1 calcFunc-tan )
  702. X                  ( ?L 1 calcFunc-ln )
  703. X                  ( ?E 1 calcFunc-exp )
  704. X                  ( ?B 2 calcFunc-log ) )
  705. X                ( ( ?F 1 calcFunc-ceil )     ; inverse
  706. X                  ( ?R 1 calcFunc-trunc )
  707. X                  ( ?Q 1 calcFunc-sqr )
  708. X                  ( ?S 1 calcFunc-arcsin )
  709. X                  ( ?C 1 calcFunc-arccos )
  710. X                  ( ?T 1 calcFunc-arctan )
  711. X                  ( ?L 1 calcFunc-exp )
  712. X                  ( ?E 1 calcFunc-ln )
  713. X                  ( ?B 2 calcFunc-alog )
  714. X                  ( ?^ 2 calcFunc-nroot )
  715. X                  ( ?| 2 calcFunc-vconcatrev ) )
  716. X                ( ( ?F 1 calcFunc-ffloor )   ; hyperbolic
  717. X                  ( ?R 1 calcFunc-fround )
  718. X                  ( ?S 1 calcFunc-sinh )
  719. X                  ( ?C 1 calcFunc-cosh )
  720. X                  ( ?T 1 calcFunc-tanh )
  721. X                  ( ?L 1 calcFunc-log10 )
  722. X                  ( ?E 1 calcFunc-exp10 )
  723. X                  ( ?| 2 calcFunc-append ) )
  724. X                ( ( ?F 1 calcFunc-fceil )    ; inverse-hyperbolic
  725. X                  ( ?R 1 calcFunc-ftrunc )
  726. X                  ( ?S 1 calcFunc-arcsinh )
  727. X                  ( ?C 1 calcFunc-arccosh )
  728. X                  ( ?T 1 calcFunc-arctanh )
  729. X                  ( ?L 1 calcFunc-exp10 )
  730. X                  ( ?E 1 calcFunc-log10 )
  731. X                  ( ?| 2 calcFunc-appendrev ) )
  732. ))
  733. (defconst calc-a-oper-keys '( ( ( ?a 3 calcFunc-apart )
  734. X                ( ?b 3 calcFunc-subst )
  735. X                ( ?c 2 calcFunc-collect )
  736. X                ( ?d 2 calcFunc-deriv )
  737. X                ( ?e 1 calcFunc-esimplify )
  738. X                ( ?f 2 calcFunc-factor )
  739. X                ( ?g 2 calcFunc-pgcd )
  740. X                ( ?i 2 calcFunc-integ )
  741. X                ( ?m 2 calcFunc-match )
  742. X                ( ?n 1 calcFunc-nrat )
  743. X                ( ?r 2 calcFunc-rewrite )
  744. X                ( ?s 1 calcFunc-simplify )
  745. X                ( ?t 3 calcFunc-taylor )
  746. X                ( ?x 1 calcFunc-expand )
  747. X                ( ?M 2 calcFunc-mapeq )
  748. X                ( ?N 3 calcFunc-minimize )
  749. X                ( ?P 2 calcFunc-roots )
  750. X                ( ?R 3 calcFunc-root )
  751. X                ( ?S 2 calcFunc-solve )
  752. X                ( ?T 4 calcFunc-table )
  753. X                ( ?X 3 calcFunc-maximize )
  754. X                ( ?= 2 calcFunc-eq )
  755. X                ( ?\# 2 calcFunc-neq )
  756. X                ( ?< 2 calcFunc-lt )
  757. X                ( ?> 2 calcFunc-gt )
  758. X                ( ?\[ 2 calcFunc-leq )
  759. X                ( ?\] 2 calcFunc-geq )
  760. X                ( ?{ 2 calcFunc-in )
  761. X                ( ?! 1 calcFunc-lnot )
  762. X                ( ?& 2 calcFunc-land )
  763. X                ( ?\| 2 calcFunc-lor )
  764. X                ( ?: 3 calcFunc-if )
  765. X                ( ?. 2 calcFunc-rmeq )
  766. X                ( ?+ 4 calcFunc-sum )
  767. X                ( ?- 4 calcFunc-asum )
  768. X                ( ?* 4 calcFunc-prod )
  769. X                ( ?_ 2 calcFunc-subscr )
  770. X                ( ?\\ 2 calcFunc-pdiv )
  771. X                ( ?% 2 calcFunc-prem )
  772. X                ( ?/ 2 calcFunc-pdivrem ) )
  773. X                  ( ( ?m 2 calcFunc-matchnot )
  774. X                ( ?M 2 calcFunc-mapeqr )
  775. X                ( ?S 2 calcFunc-finv ) )
  776. X                  ( ( ?d 2 calcFunc-tderiv )
  777. X                ( ?f 2 calcFunc-factors )
  778. X                ( ?M 2 calcFunc-mapeqp )
  779. X                ( ?N 3 calcFunc-wminimize )
  780. X                ( ?R 3 calcFunc-wroot )
  781. X                ( ?S 2 calcFunc-fsolve )
  782. X                ( ?X 3 calcFunc-wmaximize )
  783. X                ( ?/ 2 calcFunc-pdivide ) )
  784. X                  ( ( ?S 2 calcFunc-ffinv ) )
  785. ))
  786. (defconst calc-b-oper-keys '( ( ( ?a 2 calcFunc-and )
  787. X                ( ?o 2 calcFunc-or )
  788. X                ( ?x 2 calcFunc-xor )
  789. X                ( ?d 2 calcFunc-diff )
  790. X                ( ?n 1 calcFunc-not )
  791. X                ( ?c 1 calcFunc-clip )
  792. X                ( ?l 2 calcFunc-lsh )
  793. X                ( ?r 2 calcFunc-rsh )
  794. X                ( ?L 2 calcFunc-ash )
  795. X                ( ?R 2 calcFunc-rash )
  796. X                ( ?t 2 calcFunc-rot )
  797. X                ( ?p 1 calcFunc-vpack )
  798. X                ( ?u 1 calcFunc-vunpack )
  799. X                ( ?D 4 calcFunc-ddb )
  800. X                ( ?F 3 calcFunc-fv )
  801. X                ( ?I 1 calcFunc-irr )
  802. X                ( ?M 3 calcFunc-pmt )
  803. X                ( ?N 2 calcFunc-npv )
  804. X                ( ?P 3 calcFunc-pv )
  805. X                ( ?S 3 calcFunc-sln )
  806. X                ( ?T 3 calcFunc-rate )
  807. X                ( ?Y 4 calcFunc-syd )
  808. X                ( ?\# 3 calcFunc-nper ) )
  809. X                  ( ( ?F 3 calcFunc-fvb )
  810. X                ( ?I 1 calcFunc-irrb )
  811. X                ( ?M 3 calcFunc-pmtb )
  812. X                ( ?N 2 calcFunc-npvb )
  813. X                ( ?P 3 calcFunc-pvb )
  814. X                ( ?T 3 calcFunc-rateb )
  815. X                ( ?\# 3 calcFunc-nperb ) )
  816. X                  ( ( ?F 3 calcFunc-fvl )
  817. X                ( ?M 3 calcFunc-pmtl )
  818. X                ( ?P 3 calcFunc-pvl )
  819. X                ( ?T 3 calcFunc-ratel )
  820. X                ( ?\# 3 calcFunc-nperl ) )
  821. ))
  822. (defconst calc-c-oper-keys '( ( ( ?d 1 calcFunc-deg )
  823. X                ( ?r 1 calcFunc-rad )
  824. X                ( ?h 1 calcFunc-hms )
  825. X                ( ?f 1 calcFunc-float )
  826. X                ( ?F 1 calcFunc-frac ) )
  827. ))
  828. (defconst calc-f-oper-keys '( ( ( ?b 2 calcFunc-beta )
  829. X                ( ?e 1 calcFunc-erf )
  830. X                ( ?g 1 calcFunc-gamma )
  831. X                ( ?h 2 calcFunc-hypot )
  832. X                ( ?i 1 calcFunc-im )
  833. X                ( ?j 2 calcFunc-besJ )
  834. X                ( ?n 2 calcFunc-min )
  835. X                ( ?r 1 calcFunc-re )
  836. X                ( ?s 1 calcFunc-sign )
  837. X                ( ?x 2 calcFunc-max )
  838. X                ( ?y 2 calcFunc-besY )
  839. X                ( ?A 1 calcFunc-abssqr )
  840. X                ( ?B 3 calcFunc-betaI )
  841. X                ( ?E 1 calcFunc-expm1 )
  842. X                ( ?G 2 calcFunc-gammaP )
  843. X                ( ?I 2 calcFunc-ilog )
  844. X                ( ?L 1 calcFunc-lnp1 )
  845. X                ( ?M 1 calcFunc-mant )
  846. X                ( ?Q 1 calcFunc-isqrt )
  847. X                ( ?S 1 calcFunc-scf )
  848. X                ( ?T 2 calcFunc-arctan2 )
  849. X                ( ?X 1 calcFunc-xpon )
  850. X                ( ?\[ 2 calcFunc-decr )
  851. X                ( ?\] 2 calcFunc-incr ) )
  852. X                  ( ( ?e 1 calcFunc-erfc )
  853. X                ( ?E 1 calcFunc-lnp1 )
  854. X                ( ?G 2 calcFunc-gammaQ )
  855. X                ( ?L 1 calcFunc-expm1 ) )
  856. X                  ( ( ?B 3 calcFunc-betaB )
  857. X                ( ?G 2 calcFunc-gammag) )
  858. X                  ( ( ?G 2 calcFunc-gammaG ) )
  859. ))
  860. (defconst calc-k-oper-keys '( ( ( ?b 1 calcFunc-bern )
  861. X                ( ?c 2 calcFunc-choose )
  862. X                ( ?d 1 calcFunc-dfact )
  863. X                ( ?e 1 calcFunc-euler )
  864. X                ( ?f 1 calcFunc-prfac )
  865. X                ( ?g 2 calcFunc-gcd )
  866. X                ( ?h 2 calcFunc-shuffle )
  867. X                ( ?l 2 calcFunc-lcm )
  868. X                ( ?m 1 calcFunc-moebius )
  869. X                ( ?n 1 calcFunc-nextprime )
  870. X                ( ?r 1 calcFunc-random )
  871. X                ( ?s 2 calcFunc-stir1 )
  872. X                ( ?t 1 calcFunc-totient )
  873. X                ( ?B 3 calcFunc-utpb )
  874. X                ( ?C 2 calcFunc-utpc )
  875. X                ( ?F 3 calcFunc-utpf )
  876. X                ( ?N 3 calcFunc-utpn )
  877. X                ( ?P 2 calcFunc-utpp )
  878. X                ( ?T 2 calcFunc-utpt ) )
  879. X                  ( ( ?n 1 calcFunc-prevprime )
  880. X                ( ?B 3 calcFunc-ltpb )
  881. X                ( ?C 2 calcFunc-ltpc )
  882. X                ( ?F 3 calcFunc-ltpf )
  883. X                ( ?N 3 calcFunc-ltpn )
  884. X                ( ?P 2 calcFunc-ltpp )
  885. X                ( ?T 2 calcFunc-ltpt ) )
  886. X                  ( ( ?b 2 calcFunc-bern )
  887. X                ( ?c 2 calcFunc-perm )
  888. X                ( ?e 2 calcFunc-euler )
  889. X                ( ?s 2 calcFunc-stir2 ) )
  890. ))
  891. (defconst calc-s-oper-keys '( ( ( ?: 2 calcFunc-assign )
  892. X                ( ?= 1 calcFunc-evalto ) )
  893. ))
  894. (defconst calc-t-oper-keys '( ( ( ?C 3 calcFunc-tzconv )
  895. X                ( ?D 1 calcFunc-date )
  896. X                ( ?I 2 calcFunc-incmonth )
  897. X                ( ?J 1 calcFunc-julian )
  898. X                ( ?M 1 calcFunc-newmonth )
  899. X                ( ?W 1 calcFunc-newweek )
  900. X                ( ?U 1 calcFunc-unixtime )
  901. X                ( ?Y 1 calcFunc-newyear ) )
  902. ))
  903. (defconst calc-u-oper-keys '( ( ( ?C 2 calcFunc-vcov )
  904. X                ( ?G 1 calcFunc-vgmean )
  905. X                ( ?M 1 calcFunc-vmean )
  906. X                ( ?N 1 calcFunc-vmin )
  907. X                ( ?S 1 calcFunc-vsdev )
  908. X                ( ?X 1 calcFunc-vmax ) )
  909. X                  ( ( ?C 2 calcFunc-vpcov )
  910. X                ( ?M 1 calcFunc-vmeane )
  911. X                ( ?S 1 calcFunc-vpsdev ) )
  912. X                  ( ( ?C 2 calcFunc-vcorr )
  913. X                ( ?G 1 calcFunc-agmean )
  914. X                ( ?M 1 calcFunc-vmedian )
  915. X                ( ?S 1 calcFunc-vvar ) )
  916. X                  ( ( ?M 1 calcFunc-vhmean )
  917. X                ( ?S 1 calcFunc-vpvar ) )
  918. ))
  919. (defconst calc-v-oper-keys '( ( ( ?a 2 calcFunc-arrange )
  920. X                ( ?b 2 calcFunc-cvec )
  921. X                ( ?c 2 calcFunc-mcol )
  922. X                ( ?d 2 calcFunc-diag )
  923. X                ( ?e 2 calcFunc-vexp )
  924. X                ( ?f 2 calcFunc-find )
  925. X                ( ?h 1 calcFunc-head )
  926. X                ( ?k 2 calcFunc-cons )
  927. X                ( ?l 1 calcFunc-vlen )
  928. X                ( ?m 2 calcFunc-vmask )
  929. X                ( ?n 1 calcFunc-rnorm )
  930. X                ( ?p 2 calcFunc-pack )
  931. X                ( ?r 2 calcFunc-mrow )
  932. X                ( ?s 3 calcFunc-subvec )
  933. X                ( ?t 1 calcFunc-trn )
  934. X                ( ?u 1 calcFunc-unpack )
  935. X                ( ?v 1 calcFunc-rev )
  936. X                ( ?x 1 calcFunc-index )
  937. X                ( ?A 1 calcFunc-apply )
  938. X                ( ?C 1 calcFunc-cross )
  939. X                ( ?D 1 calcFunc-det )
  940. X                ( ?E 1 calcFunc-venum )
  941. X                ( ?F 1 calcFunc-vfloor )
  942. X                ( ?G 1 calcFunc-grade )
  943. X                ( ?H 2 calcFunc-histogram )
  944. X                ( ?I 2 calcFunc-inner )
  945. X                ( ?L 1 calcFunc-lud )
  946. X                ( ?M 0 calcFunc-map )
  947. X                ( ?N 1 calcFunc-cnorm )
  948. X                ( ?O 2 calcFunc-outer )
  949. X                ( ?R 1 calcFunc-reduce )
  950. X                ( ?S 1 calcFunc-sort )
  951. X                ( ?T 1 calcFunc-tr )
  952. X                ( ?U 1 calcFunc-accum )
  953. X                ( ?V 2 calcFunc-vunion )
  954. X                ( ?X 2 calcFunc-vxor )
  955. X                ( ?- 2 calcFunc-vdiff )
  956. X                ( ?^ 2 calcFunc-vint )
  957. X                ( ?~ 1 calcFunc-vcompl )
  958. X                ( ?# 1 calcFunc-vcard )
  959. X                ( ?: 1 calcFunc-vspan )
  960. X                ( ?+ 1 calcFunc-rdup ) )
  961. X                  ( ( ?h 1 calcFunc-tail )
  962. X                ( ?s 3 calcFunc-rsubvec )
  963. X                ( ?G 1 calcFunc-rgrade )
  964. X                ( ?R 1 calcFunc-rreduce )
  965. X                ( ?S 1 calcFunc-rsort )
  966. X                ( ?U 1 calcFunc-raccum ) )
  967. X                  ( ( ?e 3 calcFunc-vexp )
  968. X                ( ?h 1 calcFunc-rhead )
  969. X                ( ?k 2 calcFunc-rcons )
  970. X                ( ?H 3 calcFunc-histogram )
  971. X                ( ?R 2 calcFunc-nest )
  972. X                ( ?U 2 calcFunc-anest ) )
  973. X                  ( ( ?h 1 calcFunc-rtail )
  974. X                ( ?R 1 calcFunc-fixp )
  975. X                ( ?U 1 calcFunc-afixp ) )
  976. ))
  977. X
  978. X
  979. ;;; Convert a variable name (as a formula) into a like-looking function name.
  980. (defun math-var-to-calcFunc (f)
  981. X  (if (eq (car-safe f) 'var)
  982. X      (if (fboundp (nth 2 f))
  983. X      (nth 2 f)
  984. X    (intern (concat "calcFunc-" (symbol-name (nth 1 f)))))
  985. X    (if (memq (car-safe f) '(lambda calcFunc-lambda))
  986. X    f
  987. X      (math-reject-arg f "*Expected a function name")))
  988. )
  989. X
  990. ;;; Convert a function name into a like-looking variable name formula.
  991. (defun math-calcFunc-to-var (f)
  992. X  (if (symbolp f)
  993. X      (let* ((func (or (cdr (assq f '( ( + . calcFunc-add )
  994. X                       ( - . calcFunc-sub )
  995. X                       ( * . calcFunc-mul )
  996. X                       ( / . calcFunc-div )
  997. X                       ( ^ . calcFunc-pow )
  998. X                       ( % . calcFunc-mod )
  999. X                       ( neg . calcFunc-neg )
  1000. X                       ( | . calcFunc-vconcat ) )))
  1001. X               f))
  1002. X         (base (if (string-match "\\`calcFunc-\\(.+\\)\\'"
  1003. X                     (symbol-name func))
  1004. X               (math-match-substring (symbol-name func) 1)
  1005. X             (symbol-name func))))
  1006. X    (list 'var
  1007. X          (intern base)
  1008. X          (intern (concat "var-" base))))
  1009. X    f)
  1010. )
  1011. X
  1012. ;;; Expand a function call using "lambda" notation.
  1013. (defun math-build-call (f args)
  1014. X  (if (eq (car-safe f) 'calcFunc-lambda)
  1015. X      (if (= (length args) (- (length f) 2))
  1016. X      (math-multi-subst (nth (1- (length f)) f) (cdr f) args)
  1017. X    (calc-record-why "*Wrong number of arguments" f)
  1018. X    (cons 'calcFunc-call (cons (math-calcFunc-to-var f) args)))
  1019. X    (if (and (eq f 'calcFunc-neg)
  1020. X         (= (length args) 1))
  1021. X    (list 'neg (car args))
  1022. X      (let ((func (assq f '( ( calcFunc-add . + )
  1023. X                 ( calcFunc-sub . - )
  1024. X                 ( calcFunc-mul . * )
  1025. X                 ( calcFunc-div . / )
  1026. X                 ( calcFunc-pow . ^ )
  1027. X                 ( calcFunc-mod . % )
  1028. X                 ( calcFunc-vconcat . | ) ))))
  1029. X    (if (and func (= (length args) 2))
  1030. X        (cons (cdr func) args)
  1031. X      (cons f args)))))
  1032. )
  1033. X
  1034. ;;; Do substitutions in parallel to avoid crosstalk.
  1035. (defun math-multi-subst (expr olds news)
  1036. X  (let ((args nil)
  1037. X    temp)
  1038. X    (while (and olds news)
  1039. X      (setq args (cons (cons (car olds) (car news)) args)
  1040. X        olds (cdr olds)
  1041. X        news (cdr news)))
  1042. X    (math-multi-subst-rec expr))
  1043. )
  1044. X
  1045. (defun math-multi-subst-rec (expr)
  1046. X  (cond ((setq temp (assoc expr args)) (cdr temp))
  1047. X    ((Math-primp expr) expr)
  1048. X    ((and (eq (car expr) 'calcFunc-lambda) (> (length expr) 2))
  1049. X     (let ((new (list (car expr)))
  1050. X           (args args))
  1051. X       (while (cdr (setq expr (cdr expr)))
  1052. X         (setq new (cons (car expr) new))
  1053. X         (if (assoc (car expr) args)
  1054. X         (setq args (cons (cons (car expr) (car expr)) args))))
  1055. X       (nreverse (cons (math-multi-subst-rec (car expr)) new))))
  1056. X    (t
  1057. X     (cons (car expr)
  1058. X           (mapcar 'math-multi-subst-rec (cdr expr)))))
  1059. )
  1060. X
  1061. (defun calcFunc-call (f &rest args)
  1062. X  (setq args (math-build-call (math-var-to-calcFunc f) args))
  1063. X  (if (eq (car-safe args) 'calcFunc-call)
  1064. X      args
  1065. X    (math-normalize args))
  1066. )
  1067. X
  1068. (defun calcFunc-apply (f args)
  1069. X  (or (Math-vectorp args)
  1070. X      (math-reject-arg args 'vectorp))
  1071. X  (apply 'calcFunc-call (cons f (cdr args)))
  1072. )
  1073. X
  1074. X
  1075. X
  1076. X
  1077. ;;; Map a function over a vector symbolically. [Public]
  1078. (defun math-symb-map (f mode args)
  1079. X  (let* ((func (math-var-to-calcFunc f))
  1080. X     (nargs (length args))
  1081. X     (ptrs (vconcat args))
  1082. X     (vflags (make-vector nargs nil))
  1083. X     (heads '(vec))
  1084. X     (head nil)
  1085. X     (vec nil)
  1086. X     (i -1)
  1087. X     (math-working-step 0)
  1088. X     (math-working-step-2 nil)
  1089. X     len cols obj expr)
  1090. X    (if (eq mode 'eqn)
  1091. X    (setq mode 'elems
  1092. X          heads '(calcFunc-eq calcFunc-neq calcFunc-lt calcFunc-gt
  1093. X                  calcFunc-leq calcFunc-geq))
  1094. X      (while (and (< (setq i (1+ i)) nargs)
  1095. X          (not (math-matrixp (aref ptrs i)))))
  1096. X      (if (< i nargs)
  1097. X      (if (eq mode 'elems)
  1098. X          (setq func (list 'lambda '(&rest x)
  1099. X                   (list 'math-symb-map
  1100. X                     (list 'quote f) '(quote elems) 'x))
  1101. X            mode 'rows)
  1102. X        (if (eq mode 'cols)
  1103. X        (while (< i nargs)
  1104. X          (if (math-matrixp (aref ptrs i))
  1105. X              (aset ptrs i (math-transpose (aref ptrs i))))
  1106. X          (setq i (1+ i)))))
  1107. X    (setq mode 'elems))
  1108. X      (setq i -1))
  1109. X    (while (< (setq i (1+ i)) nargs)
  1110. X      (setq obj (aref ptrs i))
  1111. X      (if (and (memq (car-safe obj) heads)
  1112. X           (or (eq mode 'elems)
  1113. X           (math-matrixp obj)))
  1114. X      (progn
  1115. X        (aset vflags i t)
  1116. X        (if head
  1117. X        (if (cdr heads)
  1118. X            (setq head (nth
  1119. X                (aref (aref [ [0 1 2 3 4 5]
  1120. X                          [1 1 2 3 2 3]
  1121. X                          [2 2 2 1 2 1]
  1122. X                          [3 3 1 3 1 3]
  1123. X                          [4 2 2 1 4 1]
  1124. X                          [5 3 1 3 1 5] ]
  1125. X                        (- 6 (length (memq head heads))))
  1126. X                      (- 6 (length (memq (car obj) heads))))
  1127. X                heads)))
  1128. X          (setq head (car obj)))
  1129. X        (if len
  1130. X        (or (= (length obj) len)
  1131. X            (math-dimension-error))
  1132. X          (setq len (length obj))))))
  1133. X    (or len
  1134. X    (if (= nargs 1)
  1135. X        (math-reject-arg (aref ptrs 0) 'vectorp)
  1136. X      (math-reject-arg nil "At least one argument must be a vector")))
  1137. X    (setq math-working-step-2 (1- len))
  1138. X    (while (> (setq len (1- len)) 0)
  1139. X      (setq expr nil
  1140. X        i -1)
  1141. X      (while (< (setq i (1+ i)) nargs)
  1142. X    (if (aref vflags i)
  1143. X        (progn
  1144. X          (aset ptrs i (cdr (aref ptrs i)))
  1145. X          (setq expr (nconc expr (list (car (aref ptrs i))))))
  1146. X      (setq expr (nconc expr (list (aref ptrs i))))))
  1147. X      (setq math-working-step (1+ math-working-step)
  1148. X        vec (cons (math-normalize (math-build-call func expr)) vec)))
  1149. X    (setq vec (cons head (nreverse vec)))
  1150. X    (if (and (eq mode 'cols) (math-matrixp vec))
  1151. X    (math-transpose vec)
  1152. X      vec))
  1153. )
  1154. X
  1155. (defun calcFunc-map (func &rest args)
  1156. X  (math-symb-map func 'elems args)
  1157. )
  1158. X
  1159. (defun calcFunc-mapr (func &rest args)
  1160. X  (math-symb-map func 'rows args)
  1161. )
  1162. X
  1163. (defun calcFunc-mapc (func &rest args)
  1164. X  (math-symb-map func 'cols args)
  1165. )
  1166. X
  1167. (defun calcFunc-mapa (func arg)
  1168. X  (if (math-matrixp arg)
  1169. X      (math-symb-map func 'elems (cdr (math-transpose arg)))
  1170. X    (math-symb-map func 'elems arg))
  1171. )
  1172. X
  1173. (defun calcFunc-mapd (func arg)
  1174. X  (if (math-matrixp arg)
  1175. X      (math-symb-map func 'elems (cdr arg))
  1176. X    (math-symb-map func 'elems arg))
  1177. )
  1178. X
  1179. (defun calcFunc-mapeq (func &rest args)
  1180. X  (if (and (or (equal func '(var mul var-mul))
  1181. X           (equal func '(var div var-div)))
  1182. X       (= (length args) 2))
  1183. X      (if (math-negp (car args))
  1184. X      (let ((func (nth 1 (assq (car-safe (nth 1 args))
  1185. X                   calc-tweak-eqn-table))))
  1186. X        (and func (setq args (list (car args)
  1187. X                       (cons func (cdr (nth 1 args)))))))
  1188. X    (if (math-negp (nth 1 args))
  1189. X        (let ((func (nth 1 (assq (car-safe (car args))
  1190. X                     calc-tweak-eqn-table))))
  1191. X          (and func (setq args (list (cons func (cdr (car args)))
  1192. X                     (nth 1 args))))))))
  1193. X  (if (or (and (equal func '(var div var-div))
  1194. X           (assq (car-safe (nth 1 args)) calc-tweak-eqn-table))
  1195. X      (equal func '(var neg var-neg))
  1196. X      (equal func '(var inv var-inv)))
  1197. X      (apply 'calcFunc-mapeqr func args)
  1198. X    (apply 'calcFunc-mapeqp func args))
  1199. )
  1200. X
  1201. (defun calcFunc-mapeqr (func &rest args)
  1202. X  (setq args (mapcar (function (lambda (x)
  1203. X                 (let ((func (assq (car-safe x)
  1204. X                           calc-tweak-eqn-table)))
  1205. X                   (if func
  1206. X                       (cons (nth 1 func) (cdr x))
  1207. X                     x))))
  1208. X             args))
  1209. X  (apply 'calcFunc-mapeqp func args)
  1210. )
  1211. X
  1212. (defun calcFunc-mapeqp (func &rest args)
  1213. X  (if (or (and (memq (car-safe (car args)) '(calcFunc-lt calcFunc-leq))
  1214. X           (memq (car-safe (nth 1 args)) '(calcFunc-gt calcFunc-geq)))
  1215. X      (and (memq (car-safe (car args)) '(calcFunc-gt calcFunc-geq))
  1216. X           (memq (car-safe (nth 1 args)) '(calcFunc-lt calcFunc-leq))))
  1217. X      (setq args (cons (car args)
  1218. X               (cons (list (nth 1 (assq (car (nth 1 args))
  1219. X                        calc-tweak-eqn-table))
  1220. X                   (nth 2 (nth 1 args))
  1221. X                   (nth 1 (nth 1 args)))
  1222. X                 (cdr (cdr args))))))
  1223. X  (math-symb-map func 'eqn args)
  1224. )
  1225. X
  1226. X
  1227. X
  1228. ;;; Reduce a function over a vector symbolically. [Public]
  1229. (defun calcFunc-reduce (func vec)
  1230. X  (if (math-matrixp vec)
  1231. X      (let (expr row)
  1232. X    (setq func (math-var-to-calcFunc func))
  1233. X    (while (setq vec (cdr vec))
  1234. X      (setq row (car vec))
  1235. X      (while (setq row (cdr row))
  1236. X        (setq expr (if expr
  1237. X               (math-build-call func (list expr (car row)))
  1238. X             (car row)))))
  1239. X    (math-normalize expr))
  1240. X    (calcFunc-reducer func vec))
  1241. )
  1242. X
  1243. (defun calcFunc-rreduce (func vec)
  1244. X  (if (math-matrixp vec)
  1245. X      (let (expr row)
  1246. X    (setq func (math-var-to-calcFunc func)
  1247. X          vec (reverse (cdr vec)))
  1248. X    (while vec
  1249. X      (setq row (reverse (cdr (car vec))))
  1250. X      (while row
  1251. X        (setq expr (if expr
  1252. X               (math-build-call func (list (car row) expr))
  1253. X             (car row))
  1254. X          row (cdr row)))
  1255. X      (setq vec (cdr vec)))
  1256. X    (math-normalize expr))
  1257. X    (calcFunc-rreducer func vec))
  1258. )
  1259. X
  1260. (defun calcFunc-reducer (func vec)
  1261. X  (setq func (math-var-to-calcFunc func))
  1262. X  (or (math-vectorp vec)
  1263. X      (math-reject-arg vec 'vectorp))
  1264. X  (let ((expr (car (setq vec (cdr vec)))))
  1265. X    (if expr
  1266. X    (progn
  1267. X      (while (setq vec (cdr vec))
  1268. X        (setq expr (math-build-call func (list expr (car vec)))))
  1269. X      (math-normalize expr))
  1270. X      (or (math-identity-value func)
  1271. X      (math-reject-arg vec "*Vector is empty"))))
  1272. )
  1273. X
  1274. (defun math-identity-value (func)
  1275. X  (cdr (assq func '( (calcFunc-add . 0) (calcFunc-sub . 0)
  1276. X             (calcFunc-mul . 1) (calcFunc-div . 1)
  1277. X             (calcFunc-idiv . 1) (calcFunc-fdiv . 1)
  1278. X             (calcFunc-min . (var inf var-inf))
  1279. X             (calcFunc-max . (neg (var inf var-inf)))
  1280. X             (calcFunc-vconcat . (vec))
  1281. X             (calcFunc-append . (vec)) )))
  1282. )
  1283. X
  1284. (defun calcFunc-rreducer (func vec)
  1285. X  (setq func (math-var-to-calcFunc func))
  1286. X  (or (math-vectorp vec)
  1287. X      (math-reject-arg vec 'vectorp))
  1288. X  (if (eq func 'calcFunc-sub)   ; do this in a way that looks nicer
  1289. X      (let ((expr (car (setq vec (cdr vec)))))
  1290. X    (if expr
  1291. X        (progn
  1292. X          (while (setq vec (cdr vec))
  1293. X        (setq expr (math-build-call func (list expr (car vec)))
  1294. X              func (if (eq func 'calcFunc-sub)
  1295. X                   'calcFunc-add 'calcFunc-sub)))
  1296. X          (math-normalize expr))
  1297. X      0))
  1298. X    (let ((expr (car (setq vec (reverse (cdr vec))))))
  1299. X      (if expr
  1300. X      (progn
  1301. X        (while (setq vec (cdr vec))
  1302. X          (setq expr (math-build-call func (list (car vec) expr))))
  1303. X        (math-normalize expr))
  1304. X    (or (math-identity-value func)
  1305. X        (math-reject-arg vec "*Vector is empty")))))
  1306. )
  1307. X
  1308. (defun calcFunc-reducec (func vec)
  1309. X  (if (math-matrixp vec)
  1310. X      (calcFunc-reducer func (math-transpose vec))
  1311. X    (calcFunc-reducer func vec))
  1312. )
  1313. X
  1314. (defun calcFunc-rreducec (func vec)
  1315. X  (if (math-matrixp vec)
  1316. X      (calcFunc-rreducer func (math-transpose vec))
  1317. X    (calcFunc-rreducer func vec))
  1318. )
  1319. X
  1320. (defun calcFunc-reducea (func vec)
  1321. X  (if (math-matrixp vec)
  1322. X      (cons 'vec
  1323. X        (mapcar (function (lambda (x) (calcFunc-reducer func x)))
  1324. X            (cdr vec)))
  1325. X    (calcFunc-reducer func vec))
  1326. )
  1327. X
  1328. (defun calcFunc-rreducea (func vec)
  1329. X  (if (math-matrixp vec)
  1330. X      (cons 'vec
  1331. X        (mapcar (function (lambda (x) (calcFunc-rreducer func x)))
  1332. X            (cdr vec)))
  1333. X    (calcFunc-rreducer func vec))
  1334. )
  1335. X
  1336. (defun calcFunc-reduced (func vec)
  1337. X  (if (math-matrixp vec)
  1338. X      (cons 'vec
  1339. X        (mapcar (function (lambda (x) (calcFunc-reducer func x)))
  1340. X            (cdr (math-transpose vec))))
  1341. X    (calcFunc-reducer func vec))
  1342. )
  1343. X
  1344. (defun calcFunc-rreduced (func vec)
  1345. X  (if (math-matrixp vec)
  1346. X      (cons 'vec
  1347. X        (mapcar (function (lambda (x) (calcFunc-rreducer func x)))
  1348. X            (cdr (math-transpose vec))))
  1349. X    (calcFunc-rreducer func vec))
  1350. )
  1351. X
  1352. (defun calcFunc-accum (func vec)
  1353. X  (setq func (math-var-to-calcFunc func))
  1354. X  (or (math-vectorp vec)
  1355. X      (math-reject-arg vec 'vectorp))
  1356. X  (let* ((expr (car (setq vec (cdr vec))))
  1357. X     (res (list 'vec expr)))
  1358. X    (or expr
  1359. X    (math-reject-arg vec "*Vector is empty"))
  1360. X    (while (setq vec (cdr vec))
  1361. X      (setq expr (math-build-call func (list expr (car vec)))
  1362. X        res (nconc res (list expr))))
  1363. X    (math-normalize res))
  1364. )
  1365. X
  1366. (defun calcFunc-raccum (func vec)
  1367. X  (setq func (math-var-to-calcFunc func))
  1368. X  (or (math-vectorp vec)
  1369. X      (math-reject-arg vec 'vectorp))
  1370. X  (let* ((expr (car (setq vec (reverse (cdr vec)))))
  1371. X     (res (list expr)))
  1372. X    (or expr
  1373. X    (math-reject-arg vec "*Vector is empty"))
  1374. X    (while (setq vec (cdr vec))
  1375. X      (setq expr (math-build-call func (list (car vec) expr))
  1376. X        res (cons (list expr) res)))
  1377. X    (math-normalize (cons 'vec res)))
  1378. )
  1379. X
  1380. X
  1381. (defun math-nest-calls (func base iters accum tol)
  1382. X  (or (symbolp tol)
  1383. X      (if (math-realp tol)
  1384. X      (or (math-numberp base) (math-reject-arg base 'numberp))
  1385. X    (math-reject-arg tol 'realp)))
  1386. X  (setq func (math-var-to-calcFunc func))
  1387. X  (or (null iters)
  1388. X      (if (equal iters '(var inf var-inf))
  1389. X      (setq iters nil)
  1390. X    (progn
  1391. X      (if (math-messy-integerp iters)
  1392. X          (setq iters (math-trunc iters)))
  1393. X      (or (integerp iters) (math-reject-arg iters 'fixnump))
  1394. X      (or (not tol) (natnump iters) (math-reject-arg iters 'fixnatnump))
  1395. X      (if (< iters 0)
  1396. X          (let* ((dummy '(var DummyArg var-DummyArg))
  1397. X             (dummy2 '(var DummyArg2 var-DummyArg2))
  1398. X             (finv (math-solve-for (math-build-call func (list dummy2))
  1399. X                       dummy dummy2 nil)))
  1400. X        (or finv (math-reject-arg nil "*Unable to find an inverse"))
  1401. X        (if (and (= (length finv) 2)
  1402. X             (equal (nth 1 finv) dummy))
  1403. X            (setq func (car finv))
  1404. X          (setq func (list 'calcFunc-lambda dummy finv)))
  1405. X        (setq iters (- iters)))))))
  1406. X  (math-with-extra-prec 1
  1407. X    (let ((value base)
  1408. X      (ovalue nil)
  1409. X      (avalues (list base))
  1410. X      (math-working-step 0)
  1411. X      (math-working-step-2 iters))
  1412. X      (while (and (or (null iters)
  1413. X              (>= (setq iters (1- iters)) 0))
  1414. X          (or (null tol)
  1415. X              (null ovalue)
  1416. X              (if (eq tol t)
  1417. X              (not (if (and (Math-numberp value)
  1418. X                    (Math-numberp ovalue))
  1419. X                   (math-nearly-equal value ovalue)
  1420. X                 (Math-equal value ovalue)))
  1421. X            (if (math-numberp value)
  1422. X                (Math-lessp tol (math-abs (math-sub value ovalue)))
  1423. X              (math-reject-arg value 'numberp)))))
  1424. X    (setq ovalue value
  1425. X          math-working-step (1+ math-working-step)
  1426. X          value (math-normalize (math-build-call func (list value))))
  1427. X    (if accum
  1428. X        (setq avalues (cons value avalues))))
  1429. X      (if accum
  1430. X      (cons 'vec (nreverse avalues))
  1431. X    value)))
  1432. )
  1433. X
  1434. (defun calcFunc-nest (func base iters)
  1435. X  (math-nest-calls func base iters nil nil)
  1436. )
  1437. X
  1438. (defun calcFunc-anest (func base iters)
  1439. X  (math-nest-calls func base iters t nil)
  1440. )
  1441. X
  1442. (defun calcFunc-fixp (func base &optional iters tol)
  1443. X  (math-nest-calls func base iters nil (or tol t))
  1444. )
  1445. X
  1446. (defun calcFunc-afixp (func base &optional iters tol)
  1447. X  (math-nest-calls func base iters t (or tol t))
  1448. )
  1449. X
  1450. X
  1451. (defun calcFunc-outer (func a b)
  1452. X  (or (math-vectorp a) (math-reject-arg a 'vectorp))
  1453. X  (or (math-vectorp b) (math-reject-arg b 'vectorp))
  1454. X  (setq func (math-var-to-calcFunc func))
  1455. X  (let ((mat nil))
  1456. X    (while (setq a (cdr a))
  1457. X      (setq mat (cons (cons 'vec
  1458. X                (mapcar (function (lambda (x)
  1459. X                        (math-build-call func
  1460. X                                 (list (car a)
  1461. X                                       x))))
  1462. X                    (cdr b)))
  1463. X              mat)))
  1464. X    (math-normalize (cons 'vec (nreverse mat))))
  1465. )
  1466. X
  1467. X
  1468. (defun calcFunc-inner (mul-func add-func a b)
  1469. X  (or (math-vectorp a) (math-reject-arg a 'vectorp))
  1470. X  (or (math-vectorp b) (math-reject-arg b 'vectorp))
  1471. X  (if (math-matrixp a)
  1472. X      (if (math-matrixp b)
  1473. X      (if (= (length (nth 1 a)) (length b))
  1474. X          (math-inner-mats a b)
  1475. X        (math-dimension-error))
  1476. X    (if (= (length (nth 1 a)) 2)
  1477. X        (if (= (length a) (length b))
  1478. X        (math-inner-mats a (list 'vec b))
  1479. X          (math-dimension-error))
  1480. X      (if (= (length (nth 1 a)) (length b))
  1481. X          (math-mat-col (math-inner-mats a (math-col-matrix b))
  1482. X                1)
  1483. X        (math-dimension-error))))
  1484. X    (if (math-matrixp b)
  1485. X    (nth 1 (math-inner-mats (list 'vec a) b))
  1486. X      (calcFunc-reduce add-func (calcFunc-map mul-func a b))))
  1487. )
  1488. X
  1489. (defun math-inner-mats (a b)
  1490. X  (let ((mat nil)
  1491. X    (cols (length (nth 1 b)))
  1492. X    row col ap bp accum)
  1493. X    (while (setq a (cdr a))
  1494. X      (setq col cols
  1495. X        row nil)
  1496. X      (while (> (setq col (1- col)) 0)
  1497. X    (setq row (cons (calcFunc-reduce add-func
  1498. X                     (calcFunc-map mul-func
  1499. X                               (car a)
  1500. X                               (math-mat-col b col)))
  1501. X            row)))
  1502. X      (setq mat (cons (cons 'vec row) mat)))
  1503. X    (cons 'vec (nreverse mat)))
  1504. )
  1505. X
  1506. X
  1507. X
  1508. SHAR_EOF
  1509. chmod 0644 calc-map.el ||
  1510. echo 'restore of calc-map.el failed'
  1511. Wc_c="`wc -c < 'calc-map.el'`"
  1512. test 39224 -eq "$Wc_c" ||
  1513.     echo 'calc-map.el: original size 39224, current size' "$Wc_c"
  1514. rm -f _shar_wnt_.tmp
  1515. fi
  1516. # ============= calc-mat.el ==============
  1517. if test -f 'calc-mat.el' -a X"$1" != X"-c"; then
  1518.     echo 'x - skipping calc-mat.el (File already exists)'
  1519.     rm -f _shar_wnt_.tmp
  1520. else
  1521. > _shar_wnt_.tmp
  1522. echo 'x - extracting calc-mat.el (Text)'
  1523. sed 's/^X//' << 'SHAR_EOF' > 'calc-mat.el' &&
  1524. ;; Calculator for GNU Emacs, part II [calc-mat.el]
  1525. ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  1526. ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
  1527. X
  1528. ;; This file is part of GNU Emacs.
  1529. X
  1530. ;; GNU Emacs is distributed in the hope that it will be useful,
  1531. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  1532. ;; accepts responsibility to anyone for the consequences of using it
  1533. ;; or for whether it serves any particular purpose or works at all,
  1534. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  1535. ;; License for full details.
  1536. X
  1537. ;; Everyone is granted permission to copy, modify and redistribute
  1538. ;; GNU Emacs, but only under the conditions described in the
  1539. ;; GNU Emacs General Public License.   A copy of this license is
  1540. ;; supposed to have been given to you along with GNU Emacs so you
  1541. ;; can know your rights and responsibilities.  It should be in a
  1542. ;; file named COPYING.  Among other things, the copyright notice
  1543. ;; and this notice must be preserved on all copies.
  1544. X
  1545. X
  1546. X
  1547. ;; This file is autoloaded from calc-ext.el.
  1548. (require 'calc-ext)
  1549. X
  1550. (require 'calc-macs)
  1551. X
  1552. (defun calc-Need-calc-mat () nil)
  1553. X
  1554. X
  1555. (defun calc-mdet (arg)
  1556. X  (interactive "P")
  1557. X  (calc-slow-wrapper
  1558. X   (calc-unary-op "mdet" 'calcFunc-det arg))
  1559. )
  1560. X
  1561. (defun calc-mtrace (arg)
  1562. X  (interactive "P")
  1563. X  (calc-slow-wrapper
  1564. X   (calc-unary-op "mtr" 'calcFunc-tr arg))
  1565. )
  1566. X
  1567. (defun calc-mlud (arg)
  1568. X  (interactive "P")
  1569. X  (calc-slow-wrapper
  1570. X   (calc-unary-op "mlud" 'calcFunc-lud arg))
  1571. )
  1572. X
  1573. X
  1574. ;;; Coerce row vector A to be a matrix.  [V V]
  1575. (defun math-row-matrix (a)
  1576. X  (if (and (Math-vectorp a)
  1577. X       (not (math-matrixp a)))
  1578. X      (list 'vec a)
  1579. X    a)
  1580. )
  1581. X
  1582. ;;; Coerce column vector A to be a matrix.  [V V]
  1583. (defun math-col-matrix (a)
  1584. X  (if (and (Math-vectorp a)
  1585. X       (not (math-matrixp a)))
  1586. X      (cons 'vec (mapcar (function (lambda (x) (list 'vec x))) (cdr a)))
  1587. X    a)
  1588. )
  1589. X
  1590. X
  1591. X
  1592. ;;; Multiply matrices A and B.  [V V V]
  1593. (defun math-mul-mats (a b)
  1594. X  (let ((mat nil)
  1595. X    (cols (length (nth 1 b)))
  1596. X    row col ap bp accum)
  1597. X    (while (setq a (cdr a))
  1598. X      (setq col cols
  1599. X        row nil)
  1600. X      (while (> (setq col (1- col)) 0)
  1601. X    (setq ap (cdr (car a))
  1602. X          bp (cdr b)
  1603. X          accum (math-mul (car ap) (nth col (car bp))))
  1604. X    (while (setq ap (cdr ap) bp (cdr bp))
  1605. X      (setq accum (math-add accum (math-mul (car ap) (nth col (car bp))))))
  1606. X    (setq row (cons accum row)))
  1607. X      (setq mat (cons (cons 'vec row) mat)))
  1608. X    (cons 'vec (nreverse mat)))
  1609. )
  1610. X
  1611. (defun math-mul-mat-vec (a b)
  1612. X  (cons 'vec (mapcar (function (lambda (row)
  1613. X                 (math-dot-product row b)))
  1614. X             (cdr a)))
  1615. )
  1616. X
  1617. X
  1618. X
  1619. (defun calcFunc-tr (mat)   ; [Public]
  1620. X  (if (math-square-matrixp mat)
  1621. X      (math-matrix-trace-step 2 (1- (length mat)) mat (nth 1 (nth 1 mat)))
  1622. X    (math-reject-arg mat 'square-matrixp))
  1623. )
  1624. X
  1625. (defun math-matrix-trace-step (n size mat sum)
  1626. X  (if (<= n size)
  1627. X      (math-matrix-trace-step (1+ n) size mat
  1628. X                  (math-add sum (nth n (nth n mat))))
  1629. X    sum)
  1630. )
  1631. X
  1632. X
  1633. ;;; Matrix inverse and determinant.
  1634. (defun math-matrix-inv-raw (m)
  1635. X  (let ((n (1- (length m))))
  1636. X    (if (<= n 3)
  1637. X    (let ((det (math-det-raw m)))
  1638. X      (and (not (math-zerop det))
  1639. X           (math-div
  1640. X        (cond ((= n 1) 1)
  1641. X              ((= n 2)
  1642. X               (list 'vec
  1643. X                 (list 'vec
  1644. X                   (nth 2 (nth 2 m))
  1645. X                   (math-neg (nth 2 (nth 1 m))))
  1646. X                 (list 'vec
  1647. X                   (math-neg (nth 1 (nth 2 m)))
  1648. X                   (nth 1 (nth 1 m)))))
  1649. X              ((= n 3)
  1650. X               (list 'vec
  1651. X                 (list 'vec
  1652. X                   (math-sub (math-mul (nth 3 (nth 3 m))
  1653. X                               (nth 2 (nth 2 m)))
  1654. X                         (math-mul (nth 3 (nth 2 m))
  1655. X                               (nth 2 (nth 3 m))))
  1656. X                   (math-sub (math-mul (nth 3 (nth 1 m))
  1657. X                               (nth 2 (nth 3 m)))
  1658. X                         (math-mul (nth 3 (nth 3 m))
  1659. X                               (nth 2 (nth 1 m))))
  1660. X                   (math-sub (math-mul (nth 3 (nth 2 m))
  1661. X                               (nth 2 (nth 1 m)))
  1662. X                         (math-mul (nth 3 (nth 1 m))
  1663. X                               (nth 2 (nth 2 m)))))
  1664. X                 (list 'vec
  1665. X                   (math-sub (math-mul (nth 3 (nth 2 m))
  1666. X                               (nth 1 (nth 3 m)))
  1667. X                         (math-mul (nth 3 (nth 3 m))
  1668. X                               (nth 1 (nth 2 m))))
  1669. X                   (math-sub (math-mul (nth 3 (nth 3 m))
  1670. X                               (nth 1 (nth 1 m)))
  1671. X                         (math-mul (nth 3 (nth 1 m))
  1672. X                               (nth 1 (nth 3 m))))
  1673. X                   (math-sub (math-mul (nth 3 (nth 1 m))
  1674. X                               (nth 1 (nth 2 m)))
  1675. X                         (math-mul (nth 3 (nth 2 m))
  1676. X                               (nth 1 (nth 1 m)))))
  1677. X                 (list 'vec
  1678. X                   (math-sub (math-mul (nth 2 (nth 3 m))
  1679. X                               (nth 1 (nth 2 m)))
  1680. X                         (math-mul (nth 2 (nth 2 m))
  1681. X                               (nth 1 (nth 3 m))))
  1682. X                   (math-sub (math-mul (nth 2 (nth 1 m))
  1683. X                               (nth 1 (nth 3 m)))
  1684. X                         (math-mul (nth 2 (nth 3 m))
  1685. X                               (nth 1 (nth 1 m))))
  1686. X                   (math-sub (math-mul (nth 2 (nth 2 m))
  1687. X                               (nth 1 (nth 1 m)))
  1688. X                         (math-mul (nth 2 (nth 1 m))
  1689. X                               (nth 1 (nth 2 m))))))))
  1690. X        det)))
  1691. X      (let ((lud (math-matrix-lud m)))
  1692. X    (and lud
  1693. X         (math-lud-solve lud (calcFunc-idn 1 n))))))
  1694. )
  1695. X
  1696. (defun calcFunc-det (m)
  1697. X  (if (math-square-matrixp m)
  1698. X      (math-with-extra-prec 2 (math-det-raw m))
  1699. X    (if (and (eq (car-safe m) 'calcFunc-idn)
  1700. X         (or (math-zerop (nth 1 m))
  1701. X         (math-equal-int (nth 1 m) 1)))
  1702. X    (nth 1 m)
  1703. X      (math-reject-arg m 'square-matrixp)))
  1704. )
  1705. X
  1706. (defun math-det-raw (m)
  1707. X  (let ((n (1- (length m))))
  1708. X    (cond ((= n 1)
  1709. X       (nth 1 (nth 1 m)))
  1710. X      ((= n 2)
  1711. X       (math-sub (math-mul (nth 1 (nth 1 m))
  1712. X                   (nth 2 (nth 2 m)))
  1713. X             (math-mul (nth 2 (nth 1 m))
  1714. X                   (nth 1 (nth 2 m)))))
  1715. X      ((= n 3)
  1716. X       (math-sub
  1717. X        (math-sub
  1718. X         (math-sub
  1719. X          (math-add
  1720. X           (math-add
  1721. X        (math-mul (nth 1 (nth 1 m))
  1722. X              (math-mul (nth 2 (nth 2 m))
  1723. X                    (nth 3 (nth 3 m))))
  1724. X        (math-mul (nth 2 (nth 1 m))
  1725. X              (math-mul (nth 3 (nth 2 m))
  1726. X                    (nth 1 (nth 3 m)))))
  1727. X           (math-mul (nth 3 (nth 1 m))
  1728. X             (math-mul (nth 1 (nth 2 m))
  1729. X                   (nth 2 (nth 3 m)))))
  1730. X          (math-mul (nth 3 (nth 1 m))
  1731. X            (math-mul (nth 2 (nth 2 m))
  1732. X                  (nth 1 (nth 3 m)))))
  1733. X         (math-mul (nth 1 (nth 1 m))
  1734. X               (math-mul (nth 3 (nth 2 m))
  1735. X                 (nth 2 (nth 3 m)))))
  1736. X        (math-mul (nth 2 (nth 1 m))
  1737. X              (math-mul (nth 1 (nth 2 m))
  1738. X                (nth 3 (nth 3 m))))))
  1739. X      (t (let ((lud (math-matrix-lud m)))
  1740. X           (if lud
  1741. X           (let ((lu (car lud)))
  1742. X             (math-det-step n (nth 2 lud)))
  1743. X         0)))))
  1744. )
  1745. X
  1746. (defun math-det-step (n prod)
  1747. X  (if (> n 0)
  1748. X      (math-det-step (1- n) (math-mul prod (nth n (nth n lu))))
  1749. X    prod)
  1750. )
  1751. X
  1752. ;;; This returns a list (LU index d), or NIL if not possible.
  1753. ;;; Argument M must be a square matrix.
  1754. (defun math-matrix-lud (m)
  1755. X  (let ((old (assoc m math-lud-cache))
  1756. X    (context (list calc-internal-prec calc-prefer-frac)))
  1757. X    (if (and old (equal (nth 1 old) context))
  1758. X    (cdr (cdr old))
  1759. X      (let* ((lud (catch 'singular (math-do-matrix-lud m)))
  1760. X         (entry (cons context lud)))
  1761. X    (if old
  1762. X        (setcdr old entry)
  1763. X      (setq math-lud-cache (cons (cons m entry) math-lud-cache)))
  1764. X    lud)))
  1765. )
  1766. (defvar math-lud-cache nil)
  1767. X
  1768. ;;; Numerical Recipes section 2.3; implicit pivoting omitted.
  1769. (defun math-do-matrix-lud (m)
  1770. X  (let* ((lu (math-copy-matrix m))
  1771. X     (n (1- (length lu)))
  1772. X     i (j 1) k imax sum big
  1773. X     (d 1) (index nil))
  1774. X    (while (<= j n)
  1775. X      (setq i 1
  1776. X        big 0
  1777. X        imax j)
  1778. X      (while (< i j)
  1779. X    (math-working "LUD step" (format "%d/%d" j i))
  1780. X    (setq sum (nth j (nth i lu))
  1781. X          k 1)
  1782. X    (while (< k i)
  1783. X      (setq sum (math-sub sum (math-mul (nth k (nth i lu))
  1784. X                        (nth j (nth k lu))))
  1785. X        k (1+ k)))
  1786. X    (setcar (nthcdr j (nth i lu)) sum)
  1787. X    (setq i (1+ i)))
  1788. X      (while (<= i n)
  1789. X    (math-working "LUD step" (format "%d/%d" j i))
  1790. X    (setq sum (nth j (nth i lu))
  1791. X          k 1)
  1792. X    (while (< k j)
  1793. X      (setq sum (math-sub sum (math-mul (nth k (nth i lu))
  1794. SHAR_EOF
  1795. true || echo 'restore of calc-mat.el failed'
  1796. fi
  1797. echo 'End of  part 20'
  1798. echo 'File calc-mat.el is continued in part 21'
  1799. echo 21 > _shar_seq_.tmp
  1800. exit 0
  1801. exit 0 # Just in case...
  1802. -- 
  1803. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1804. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1805. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1806. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1807.