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

  1. Newsgroups: comp.sources.misc
  2. From: daveg@synaptics.com (David Gillespie)
  3. Subject:  v24i054:  gnucalc - GNU Emacs Calculator, v2.00, Part06/56
  4. Message-ID: <1991Oct29.042514.7256@sparky.imd.sterling.com>
  5. X-Md4-Signature: 9f30cde948d4d7fb5331e55ee96320de
  6. Date: Tue, 29 Oct 1991 04:25:14 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: daveg@synaptics.com (David Gillespie)
  10. Posting-number: Volume 24, Issue 54
  11. Archive-name: gnucalc/part06
  12. Environment: Emacs
  13. Supersedes: gmcalc: Volume 13, Issue 27-45
  14.  
  15. ---- Cut Here and unpack ----
  16. #!/bin/sh
  17. # this is Part.06 (part 6 of a multipart archive)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file calc-alg-2.el continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 6; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping calc-alg-2.el'
  35. else
  36. echo 'x - continuing file calc-alg-2.el'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'calc-alg-2.el' &&
  38. X         (mapcar (function (lambda (x) (cons 'calcFunc-eq x))) solns)
  39. X           (mapcar 'car eqn-list))))))
  40. )
  41. X
  42. (defun math-solve-system-subst (x)    ; uses "res" and "v"
  43. X  (let ((accum nil)
  44. X    (res2 res))
  45. X    (while x
  46. X      (setq accum (nconc accum
  47. X             (mapcar (function
  48. X                  (lambda (r)
  49. X                    (if math-solve-simplifying
  50. X                    (math-simplify
  51. X                     (math-expr-subst (car x) vv r))
  52. X                      (math-expr-subst (car x) vv r))))
  53. X                 (car res2)))
  54. X        x (cdr x)
  55. X        res2 (cdr res2)))
  56. X    accum)
  57. )
  58. X
  59. X
  60. (defun math-get-from-counter (name)
  61. X  (let ((ctr (assq name calc-command-flags)))
  62. X    (if ctr
  63. X    (setcdr ctr (1+ (cdr ctr)))
  64. X      (setq ctr (cons name 1)
  65. X        calc-command-flags (cons ctr calc-command-flags)))
  66. X    (cdr ctr))
  67. )
  68. X
  69. (defun math-solve-get-sign (val)
  70. X  (setq val (math-simplify val))
  71. X  (if (and (eq (car-safe val) '*)
  72. X       (Math-numberp (nth 1 val)))
  73. X      (list '* (nth 1 val) (math-solve-get-sign (nth 2 val)))
  74. X    (and (eq (car-safe val) 'calcFunc-sqrt)
  75. X     (eq (car-safe (nth 1 val)) '^)
  76. X     (setq val (math-normalize (list '^
  77. X                     (nth 1 (nth 1 val))
  78. X                     (math-div (nth 2 (nth 1 val)) 2)))))
  79. X    (if solve-full
  80. X    (if (and (calc-var-value 'var-GenCount)
  81. X         (Math-natnump var-GenCount)
  82. X         (not (eq solve-full 'all)))
  83. X        (prog1
  84. X        (math-mul (list 'calcFunc-as var-GenCount) val)
  85. X          (setq var-GenCount (math-add var-GenCount 1))
  86. X          (calc-refresh-evaltos 'var-GenCount))
  87. X      (let* ((var (concat "s" (math-get-from-counter 'solve-sign)))
  88. X         (var2 (list 'var (intern var) (intern (concat "var-" var)))))
  89. X        (if (eq solve-full 'all)
  90. X        (setq math-solve-ranges (cons (list var2 1 -1)
  91. X                          math-solve-ranges)))
  92. X        (math-mul var2 val)))
  93. X      (calc-record-why "*Choosing positive solution")
  94. X      val))
  95. )
  96. X
  97. (defun math-solve-get-int (val &optional range first)
  98. X  (if solve-full
  99. X      (if (and (calc-var-value 'var-GenCount)
  100. X           (Math-natnump var-GenCount)
  101. X           (not (eq solve-full 'all)))
  102. X      (prog1
  103. X          (math-mul val (list 'calcFunc-an var-GenCount))
  104. X        (setq var-GenCount (math-add var-GenCount 1))
  105. X        (calc-refresh-evaltos 'var-GenCount))
  106. X    (let* ((var (concat "n" (math-get-from-counter 'solve-int)))
  107. X           (var2 (list 'var (intern var) (intern (concat "var-" var)))))
  108. X      (if (and range (eq solve-full 'all))
  109. X          (setq math-solve-ranges (cons (cons var2
  110. X                          (cdr (calcFunc-index
  111. X                            range (or first 0))))
  112. X                        math-solve-ranges)))
  113. X      (math-mul val var2)))
  114. X    (calc-record-why "*Choosing 0 for arbitrary integer in solution")
  115. X    0)
  116. )
  117. X
  118. (defun math-solve-sign (sign expr)
  119. X  (and sign
  120. X       (let ((s1 (math-possible-signs expr)))
  121. X     (cond ((memq s1 '(4 6))
  122. X        sign)
  123. X           ((memq s1 '(1 3))
  124. X        (- sign)))))
  125. )
  126. X
  127. (defun math-looks-evenp (expr)
  128. X  (if (Math-integerp expr)
  129. X      (math-evenp expr)
  130. X    (if (memq (car expr) '(* /))
  131. X    (math-looks-evenp (nth 1 expr))))
  132. )
  133. X
  134. (defun math-solve-for (lhs rhs solve-var solve-full &optional sign)
  135. X  (if (math-expr-contains rhs solve-var)
  136. X      (math-solve-for (math-sub lhs rhs) 0 solve-var solve-full)
  137. X    (and (math-expr-contains lhs solve-var)
  138. X     (math-with-extra-prec 1
  139. X       (let* ((math-poly-base-variable solve-var)
  140. X          (res (math-try-solve-for lhs rhs sign)))
  141. X         (if (and (eq solve-full 'all)
  142. X              (math-known-realp solve-var))
  143. X         (let ((old-len (length res))
  144. X               new-len)
  145. X           (setq res (delq nil
  146. X                   (mapcar (function
  147. X                        (lambda (x)
  148. X                          (and (not (memq (car-safe x)
  149. X                                  '(cplx polar)))
  150. X                           x)))
  151. X                       res))
  152. X             new-len (length res))
  153. X           (if (< new-len old-len)
  154. X               (calc-record-why (if (= new-len 1)
  155. X                        "*All solutions were complex"
  156. X                      (format
  157. X                       "*Omitted %d complex solutions"
  158. X                       (- old-len new-len)))))))
  159. X         res))))
  160. )
  161. X
  162. (defun math-solve-eqn (expr var full)
  163. X  (if (memq (car-safe expr) '(calcFunc-neq calcFunc-lt calcFunc-gt
  164. X                       calcFunc-leq calcFunc-geq))
  165. X      (let ((res (math-solve-for (cons '- (cdr expr))
  166. X                 0 var full
  167. X                 (if (eq (car expr) 'calcFunc-neq) nil 1))))
  168. X    (and res
  169. X         (if (eq math-solve-sign 1)
  170. X         (list (car expr) var res)
  171. X           (if (eq math-solve-sign -1)
  172. X           (list (car expr) res var)
  173. X         (or (eq (car expr) 'calcFunc-neq)
  174. X             (calc-record-why
  175. X              "*Can't determine direction of inequality"))
  176. X         (and (memq (car expr) '(calcFunc-neq calcFunc-lt calcFunc-gt))
  177. X              (list 'calcFunc-neq var res))))))
  178. X    (let ((res (math-solve-for expr 0 var full)))
  179. X      (and res
  180. X       (list 'calcFunc-eq var res))))
  181. )
  182. X
  183. (defun math-reject-solution (expr var func)
  184. X  (if (math-expr-contains expr var)
  185. X      (or (equal (car calc-next-why) '(* "Unable to find a symbolic solution"))
  186. X      (calc-record-why "*Unable to find a solution")))
  187. X  (list func expr var)
  188. )
  189. X
  190. (defun calcFunc-solve (expr var)
  191. X  (or (if (or (Math-vectorp expr) (Math-vectorp var))
  192. X      (math-solve-system expr var nil)
  193. X    (math-solve-eqn expr var nil))
  194. X      (math-reject-solution expr var 'calcFunc-solve))
  195. )
  196. X
  197. (defun calcFunc-fsolve (expr var)
  198. X  (or (if (or (Math-vectorp expr) (Math-vectorp var))
  199. X      (math-solve-system expr var t)
  200. X    (math-solve-eqn expr var t))
  201. X      (math-reject-solution expr var 'calcFunc-fsolve))
  202. )
  203. X
  204. (defun calcFunc-roots (expr var)
  205. X  (let ((math-solve-ranges nil))
  206. X    (or (if (or (Math-vectorp expr) (Math-vectorp var))
  207. X        (math-solve-system expr var 'all)
  208. X      (math-solve-for expr 0 var 'all))
  209. X      (math-reject-solution expr var 'calcFunc-roots)))
  210. )
  211. X
  212. (defun calcFunc-finv (expr var)
  213. X  (let ((res (math-solve-for expr math-integ-var var nil)))
  214. X    (if res
  215. X    (math-normalize (math-expr-subst res math-integ-var var))
  216. X      (math-reject-solution expr var 'calcFunc-finv)))
  217. )
  218. X
  219. (defun calcFunc-ffinv (expr var)
  220. X  (let ((res (math-solve-for expr math-integ-var var t)))
  221. X    (if res
  222. X    (math-normalize (math-expr-subst res math-integ-var var))
  223. X      (math-reject-solution expr var 'calcFunc-finv)))
  224. )
  225. X
  226. X
  227. (put 'calcFunc-inv 'math-inverse
  228. X     (function (lambda (x) (math-div 1 x))))
  229. (put 'calcFunc-inv 'math-inverse-sign -1)
  230. X
  231. (put 'calcFunc-sqrt 'math-inverse
  232. X     (function (lambda (x) (math-sqr x))))
  233. X
  234. (put 'calcFunc-conj 'math-inverse
  235. X     (function (lambda (x) (list 'calcFunc-conj x))))
  236. X
  237. (put 'calcFunc-abs 'math-inverse
  238. X     (function (lambda (x) (math-solve-get-sign x))))
  239. X
  240. (put 'calcFunc-deg 'math-inverse
  241. X     (function (lambda (x) (list 'calcFunc-rad x))))
  242. (put 'calcFunc-deg 'math-inverse-sign 1)
  243. X
  244. (put 'calcFunc-rad 'math-inverse
  245. X     (function (lambda (x) (list 'calcFunc-deg x))))
  246. (put 'calcFunc-rad 'math-inverse-sign 1)
  247. X
  248. (put 'calcFunc-ln 'math-inverse
  249. X     (function (lambda (x) (list 'calcFunc-exp x))))
  250. (put 'calcFunc-ln 'math-inverse-sign 1)
  251. X
  252. (put 'calcFunc-log10 'math-inverse
  253. X     (function (lambda (x) (list 'calcFunc-exp10 x))))
  254. (put 'calcFunc-log10 'math-inverse-sign 1)
  255. X
  256. (put 'calcFunc-lnp1 'math-inverse
  257. X     (function (lambda (x) (list 'calcFunc-expm1 x))))
  258. (put 'calcFunc-lnp1 'math-inverse-sign 1)
  259. X
  260. (put 'calcFunc-exp 'math-inverse
  261. X     (function (lambda (x) (math-add (math-normalize (list 'calcFunc-ln x))
  262. X                     (math-mul 2
  263. X                           (math-mul '(var pi var-pi)
  264. X                             (math-solve-get-int
  265. X                              '(var i var-i))))))))
  266. (put 'calcFunc-exp 'math-inverse-sign 1)
  267. X
  268. (put 'calcFunc-expm1 'math-inverse
  269. X     (function (lambda (x) (math-add (math-normalize (list 'calcFunc-lnp1 x))
  270. X                     (math-mul 2
  271. X                           (math-mul '(var pi var-pi)
  272. X                             (math-solve-get-int
  273. X                              '(var i var-i))))))))
  274. (put 'calcFunc-expm1 'math-inverse-sign 1)
  275. X
  276. (put 'calcFunc-sin 'math-inverse
  277. X     (function (lambda (x) (let ((n (math-solve-get-int 1)))
  278. X                 (math-add (math-mul (math-normalize
  279. X                          (list 'calcFunc-arcsin x))
  280. X                         (math-pow -1 n))
  281. X                       (math-mul (math-half-circle t)
  282. X                         n))))))
  283. X
  284. (put 'calcFunc-cos 'math-inverse
  285. X     (function (lambda (x) (math-add (math-solve-get-sign
  286. X                      (math-normalize
  287. X                       (list 'calcFunc-arccos x)))
  288. X                     (math-solve-get-int
  289. X                      (math-full-circle t))))))
  290. X
  291. (put 'calcFunc-tan 'math-inverse
  292. X     (function (lambda (x) (math-add (math-normalize (list 'calcFunc-arctan x))
  293. X                     (math-solve-get-int
  294. X                      (math-half-circle t))))))
  295. X
  296. (put 'calcFunc-arcsin 'math-inverse
  297. X     (function (lambda (x) (math-normalize (list 'calcFunc-sin x)))))
  298. X
  299. (put 'calcFunc-arccos 'math-inverse
  300. X     (function (lambda (x) (math-normalize (list 'calcFunc-cos x)))))
  301. X
  302. (put 'calcFunc-arctan 'math-inverse
  303. X     (function (lambda (x) (math-normalize (list 'calcFunc-tan x)))))
  304. X
  305. (put 'calcFunc-sinh 'math-inverse
  306. X     (function (lambda (x) (let ((n (math-solve-get-int 1)))
  307. X                 (math-add (math-mul (math-normalize
  308. X                          (list 'calcFunc-arcsinh x))
  309. X                         (math-pow -1 n))
  310. X                       (math-mul (math-half-circle t)
  311. X                         (math-mul
  312. X                          '(var i var-i)
  313. X                          n)))))))
  314. (put 'calcFunc-sinh 'math-inverse-sign 1)
  315. X
  316. (put 'calcFunc-cosh 'math-inverse
  317. X     (function (lambda (x) (math-add (math-solve-get-sign
  318. X                      (math-normalize
  319. X                       (list 'calcFunc-arccosh x)))
  320. X                     (math-mul (math-full-circle t)
  321. X                           (math-solve-get-int
  322. X                        '(var i var-i)))))))
  323. X
  324. (put 'calcFunc-tanh 'math-inverse
  325. X     (function (lambda (x) (math-add (math-normalize
  326. X                      (list 'calcFunc-arctanh x))
  327. X                     (math-mul (math-half-circle t)
  328. X                           (math-solve-get-int
  329. X                        '(var i var-i)))))))
  330. (put 'calcFunc-tanh 'math-inverse-sign 1)
  331. X
  332. (put 'calcFunc-arcsinh 'math-inverse
  333. X     (function (lambda (x) (math-normalize (list 'calcFunc-sinh x)))))
  334. (put 'calcFunc-arcsinh 'math-inverse-sign 1)
  335. X
  336. (put 'calcFunc-arccosh 'math-inverse
  337. X     (function (lambda (x) (math-normalize (list 'calcFunc-cosh x)))))
  338. X
  339. (put 'calcFunc-arctanh 'math-inverse
  340. X     (function (lambda (x) (math-normalize (list 'calcFunc-tanh x)))))
  341. (put 'calcFunc-arctanh 'math-inverse-sign 1)
  342. X
  343. X
  344. X
  345. (defun calcFunc-taylor (expr var num)
  346. X  (let ((x0 0) (v var))
  347. X    (if (memq (car-safe var) '(+ - calcFunc-eq))
  348. X    (setq x0 (if (eq (car var) '+) (math-neg (nth 2 var)) (nth 2 var))
  349. X          v (nth 1 var)))
  350. X    (or (and (eq (car-safe v) 'var)
  351. X         (math-expr-contains expr v)
  352. X         (natnump num)
  353. X         (let ((accum (math-expr-subst expr v x0))
  354. X           (var2 (if (eq (car var) 'calcFunc-eq)
  355. X                 (cons '- (cdr var))
  356. X               var))
  357. X           (n 0)
  358. X           (nfac 1)
  359. X           (fprime expr))
  360. X           (while (and (<= (setq n (1+ n)) num)
  361. X               (setq fprime (calcFunc-deriv fprime v nil t)))
  362. X         (setq fprime (math-simplify fprime)
  363. X               nfac (math-mul nfac n)
  364. X               accum (math-add accum
  365. X                       (math-div (math-mul (math-pow var2 n)
  366. X                               (math-expr-subst
  367. X                                fprime v x0))
  368. X                         nfac))))
  369. X           (and fprime
  370. X            (math-normalize accum))))
  371. X    (list 'calcFunc-taylor expr var num)))
  372. )
  373. X
  374. X
  375. X
  376. X
  377. SHAR_EOF
  378. echo 'File calc-alg-2.el is complete' &&
  379. chmod 0644 calc-alg-2.el ||
  380. echo 'restore of calc-alg-2.el failed'
  381. Wc_c="`wc -c < 'calc-alg-2.el'`"
  382. test 108099 -eq "$Wc_c" ||
  383.     echo 'calc-alg-2.el: original size 108099, current size' "$Wc_c"
  384. rm -f _shar_wnt_.tmp
  385. fi
  386. # ============= calc-alg-3.el ==============
  387. if test -f 'calc-alg-3.el' -a X"$1" != X"-c"; then
  388.     echo 'x - skipping calc-alg-3.el (File already exists)'
  389.     rm -f _shar_wnt_.tmp
  390. else
  391. > _shar_wnt_.tmp
  392. echo 'x - extracting calc-alg-3.el (Text)'
  393. sed 's/^X//' << 'SHAR_EOF' > 'calc-alg-3.el' &&
  394. ;; Calculator for GNU Emacs, part II [calc-alg-3.el]
  395. ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  396. ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
  397. X
  398. ;; This file is part of GNU Emacs.
  399. X
  400. ;; GNU Emacs is distributed in the hope that it will be useful,
  401. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  402. ;; accepts responsibility to anyone for the consequences of using it
  403. ;; or for whether it serves any particular purpose or works at all,
  404. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  405. ;; License for full details.
  406. X
  407. ;; Everyone is granted permission to copy, modify and redistribute
  408. ;; GNU Emacs, but only under the conditions described in the
  409. ;; GNU Emacs General Public License.   A copy of this license is
  410. ;; supposed to have been given to you along with GNU Emacs so you
  411. ;; can know your rights and responsibilities.  It should be in a
  412. ;; file named COPYING.  Among other things, the copyright notice
  413. ;; and this notice must be preserved on all copies.
  414. X
  415. X
  416. X
  417. ;; This file is autoloaded from calc-ext.el.
  418. (require 'calc-ext)
  419. X
  420. (require 'calc-macs)
  421. X
  422. (defun calc-Need-calc-alg-3 () nil)
  423. X
  424. X
  425. (defun calc-find-root (var)
  426. X  (interactive "sVariable(s) to solve for: ")
  427. X  (calc-slow-wrapper
  428. X   (let ((func (if (calc-is-hyperbolic) 'calcFunc-wroot 'calcFunc-root)))
  429. X     (if (or (equal var "") (equal var "$"))
  430. X     (calc-enter-result 2 "root" (list func
  431. X                       (calc-top-n 3)
  432. X                       (calc-top-n 1)
  433. X                       (calc-top-n 2)))
  434. X       (let ((var (if (and (string-match ",\\|[^ ] +[^ ]" var)
  435. X               (not (string-match "\\[" var)))
  436. X              (math-read-expr (concat "[" var "]"))
  437. X            (math-read-expr var))))
  438. X     (if (eq (car-safe var) 'error)
  439. X         (error "Bad format in expression: %s" (nth 1 var)))
  440. X     (calc-enter-result 1 "root" (list func
  441. X                       (calc-top-n 2)
  442. X                       var
  443. X                       (calc-top-n 1)))))))
  444. )
  445. X
  446. (defun calc-find-minimum (var)
  447. X  (interactive "sVariable(s) to minimize over: ")
  448. X  (calc-slow-wrapper
  449. X   (let ((func (if (calc-is-inverse)
  450. X           (if (calc-is-hyperbolic)
  451. X               'calcFunc-wmaximize 'calcFunc-maximize)
  452. X         (if (calc-is-hyperbolic)
  453. X             'calcFunc-wminimize 'calcFunc-minimize)))
  454. X     (tag (if (calc-is-inverse) "max" "min")))
  455. X     (if (or (equal var "") (equal var "$"))
  456. X     (calc-enter-result 2 tag (list func
  457. X                    (calc-top-n 3)
  458. X                    (calc-top-n 1)
  459. X                    (calc-top-n 2)))
  460. X       (let ((var (if (and (string-match ",\\|[^ ] +[^ ]" var)
  461. X               (not (string-match "\\[" var)))
  462. X              (math-read-expr (concat "[" var "]"))
  463. X            (math-read-expr var))))
  464. X     (if (eq (car-safe var) 'error)
  465. X         (error "Bad format in expression: %s" (nth 1 var)))
  466. X     (calc-enter-result 1 tag (list func
  467. X                    (calc-top-n 2)
  468. X                    var
  469. X                    (calc-top-n 1)))))))
  470. )
  471. X
  472. (defun calc-find-maximum (var)
  473. X  (interactive "sVariable to maximize over: ")
  474. X  (calc-invert-func)
  475. X  (calc-find-minimum var)
  476. )
  477. X
  478. X
  479. (defun calc-poly-interp (arg)
  480. X  (interactive "P")
  481. X  (calc-slow-wrapper
  482. X   (let ((data (calc-top 2)))
  483. X     (if (or (consp arg) (eq arg 0) (eq arg 2))
  484. X     (setq data (cons 'vec (calc-top-list 2 2)))
  485. X       (or (null arg)
  486. X       (error "Bad prefix argument")))
  487. X     (if (calc-is-hyperbolic)
  488. X     (calc-enter-result 1 "rati" (list 'calcFunc-ratint data (calc-top 1)))
  489. X       (calc-enter-result 1 "poli" (list 'calcFunc-polint data
  490. X                     (calc-top 1))))))
  491. )
  492. X
  493. X
  494. (defun calc-curve-fit (arg &optional model coefnames varnames)
  495. X  (interactive "P")
  496. X  (calc-slow-wrapper
  497. X   (setq calc-aborted-prefix nil)
  498. X   (let ((func (if (calc-is-inverse) 'calcFunc-xfit
  499. X         (if (calc-is-hyperbolic) 'calcFunc-efit
  500. X           'calcFunc-fit)))
  501. X     key (which 0)
  502. X     n nvars temp data
  503. X     (homog nil)
  504. X     (msgs '( "(Press ? for help)"
  505. X          "1 = linear or multilinear"
  506. X          "2-9 = polynomial fits; i = interpolating polynomial"
  507. X          "p = a x^b, ^ = a b^x"
  508. X          "e = a exp(b x), x = exp(a + b x), l = a + b ln(x)"
  509. X          "E = a 10^(b x), X = 10^(a + b x), L = a + b log10(x)"
  510. X          "q = a + b (x-c)^2"
  511. X          "g = (a/b sqrt(2 pi)) exp(-0.5*((x-c)/b)^2)"
  512. X          "h prefix = homogeneous model (no constant term)"
  513. X          "' = alg entry, $ = stack, u = Model1, U = Model2")))
  514. X     (while (not model)
  515. X       (message "Fit to model: %s:%s"
  516. X        (nth which msgs)
  517. X        (if homog " h" ""))
  518. X       (setq key (read-char))
  519. X       (cond ((= key ?\C-g)
  520. X          (keyboard-quit))
  521. X         ((= key ??)
  522. X          (setq which (% (1+ which) (length msgs))))
  523. X         ((memq key '(?h ?H))
  524. X          (setq homog (not homog)))
  525. X         ((progn
  526. X        (if (eq key ?\$)
  527. X            (setq n 1)
  528. X          (setq n 0))
  529. X        (cond ((null arg)
  530. X               (setq n (1+ n)
  531. X                 data (calc-top n)))
  532. X              ((or (consp arg) (eq arg 0))
  533. X               (setq n (+ n 2)
  534. X                 data (calc-top n)
  535. X                 data (if (math-matrixp data)
  536. X                      (append data (list (calc-top (1- n))))
  537. X                    (list 'vec data (calc-top (1- n))))))
  538. X              ((> (setq arg (prefix-numeric-value arg)) 0)
  539. X               (setq data (cons 'vec (calc-top-list arg (1+ n)))
  540. X                 n (+ n arg)))
  541. X              (t (error "Bad prefix argument")))
  542. X        (or (math-matrixp data) (not (cdr (cdr data)))
  543. X            (error "Data matrix is not a matrix!"))
  544. X        (setq nvars (- (length data) 2)
  545. X              coefnames nil
  546. X              varnames nil)
  547. X        nil))
  548. X         ((= key ?1)  ; linear or multilinear
  549. X          (calc-get-fit-variables nvars (1+ nvars) (and homog 0))
  550. X          (setq model (math-mul coefnames
  551. X                    (cons 'vec (cons 1 (cdr varnames))))))
  552. X         ((and (>= key ?2) (<= key ?9))   ; polynomial
  553. X          (calc-get-fit-variables 1 (- key ?0 -1) (and homog 0))
  554. X          (setq model (math-build-polynomial-expr (cdr coefnames)
  555. X                              (nth 1 varnames))))
  556. X         ((= key ?i)  ; exact polynomial
  557. X          (calc-get-fit-variables 1 (1- (length (nth 1 data)))
  558. X                      (and homog 0))
  559. X          (setq model (math-build-polynomial-expr (cdr coefnames)
  560. X                              (nth 1 varnames))))
  561. X         ((= key ?p)  ; power law
  562. X          (calc-get-fit-variables nvars (1+ nvars) (and homog 1))
  563. X          (setq model (math-mul (nth 1 coefnames)
  564. X                    (calcFunc-reduce
  565. X                     '(var mul var-mul)
  566. X                     (calcFunc-map
  567. X                      '(var pow var-pow)
  568. X                      varnames
  569. X                      (cons 'vec (cdr (cdr coefnames))))))))
  570. X         ((= key ?^)  ; exponential law
  571. X          (calc-get-fit-variables nvars (1+ nvars) (and homog 1))
  572. X          (setq model (math-mul (nth 1 coefnames)
  573. X                    (calcFunc-reduce
  574. X                     '(var mul var-mul)
  575. X                     (calcFunc-map
  576. X                      '(var pow var-pow)
  577. X                      (cons 'vec (cdr (cdr coefnames)))
  578. X                      varnames)))))
  579. X         ((memq key '(?e ?E))
  580. X          (calc-get-fit-variables nvars (1+ nvars) (and homog 1))
  581. X          (setq model (math-mul (nth 1 coefnames)
  582. X                    (calcFunc-reduce
  583. X                     '(var mul var-mul)
  584. X                     (calcFunc-map
  585. X                      (if (eq key ?e)
  586. X                      '(var exp var-exp)
  587. X                    '(calcFunc-lambda
  588. X                      (var a var-a)
  589. X                      (^ 10 (var a var-a))))
  590. X                      (calcFunc-map
  591. X                       '(var mul var-mul)
  592. X                       (cons 'vec (cdr (cdr coefnames)))
  593. X                       varnames))))))
  594. X         ((memq key '(?x ?X))
  595. X          (calc-get-fit-variables nvars (1+ nvars) (and homog 0))
  596. X          (setq model (math-mul coefnames
  597. X                    (cons 'vec (cons 1 (cdr varnames)))))
  598. X          (setq model (if (eq key ?x)
  599. X                  (list 'calcFunc-exp model)
  600. X                (list '^ 10 model))))
  601. X         ((memq key '(?l ?L))
  602. X          (calc-get-fit-variables nvars (1+ nvars) (and homog 0))
  603. X          (setq model (math-mul coefnames
  604. X                    (cons 'vec
  605. X                      (cons 1 (cdr (calcFunc-map
  606. X                            (if (eq key ?l)
  607. X                                '(var ln var-ln)
  608. X                              '(var log10
  609. X                                var-log10))
  610. X                            varnames)))))))
  611. X         ((= key ?q)
  612. X          (calc-get-fit-variables nvars (1+ (* 2 nvars)) (and homog 0))
  613. X          (let ((c coefnames)
  614. X            (v varnames))
  615. X        (setq model (nth 1 c))
  616. X        (while (setq v (cdr v) c (cdr (cdr c)))
  617. X          (setq model (math-add
  618. X                   model
  619. X                   (list '*
  620. X                     (car c)
  621. X                     (list '^
  622. X                       (list '- (car v) (nth 1 c))
  623. X                       2)))))))
  624. X         ((= key ?g)
  625. X          (setq model (math-read-expr "(AFit / BFit sqrt(2 pi)) exp(-0.5 * ((XFit - CFit) / BFit)^2)")
  626. X            varnames '(vec (var XFit var-XFit))
  627. X            coefnames '(vec (var AFit var-AFit)
  628. X                    (var BFit var-BFit)
  629. X                    (var CFit var-CFit)))
  630. X          (calc-get-fit-variables 1 (1- (length coefnames)) (and homog 1)))
  631. X         ((memq key '(?\$ ?\' ?u ?U))
  632. X          (let* ((defvars nil)
  633. X             (record-entry nil))
  634. X        (if (eq key ?\')
  635. X            (let* ((calc-dollar-values calc-arg-values)
  636. X               (calc-dollar-used 0)
  637. X               (calc-hashes-used 0))
  638. X              (setq model (calc-do-alg-entry "" "Model formula: "))
  639. X              (if (/= (length model) 1)
  640. X              (error "Bad format"))
  641. X              (setq model (car model)
  642. X                record-entry t)
  643. X              (if (> calc-dollar-used 0)
  644. X              (setq coefnames
  645. X                (cons 'vec
  646. X                      (nthcdr (- (length calc-arg-values)
  647. X                         calc-dollar-used)
  648. X                          (reverse calc-arg-values))))
  649. X            (if (> calc-hashes-used 0)
  650. X                (setq coefnames
  651. X                  (cons 'vec (calc-invent-args
  652. X                          calc-hashes-used))))))
  653. X          (progn
  654. X            (setq model (cond ((eq key ?u)
  655. X                       (calc-var-value 'var-Model1))
  656. X                      ((eq key ?U)
  657. X                       (calc-var-value 'var-Model2))
  658. X                      (t (calc-top 1))))
  659. X            (or model (error "User model not yet defined"))
  660. X            (if (math-vectorp model)
  661. X            (if (and (memq (length model) '(3 4))
  662. X                 (not (math-objvecp (nth 1 model)))
  663. X                 (math-vectorp (nth 2 model))
  664. X                 (or (null (nth 3 model))
  665. X                     (math-vectorp (nth 3 model))))
  666. X                (setq varnames (nth 2 model)
  667. X                  coefnames (or (nth 3 model)
  668. X                        (cons 'vec
  669. X                              (math-all-vars-but
  670. X                               model varnames)))
  671. X                  model (nth 1 model))
  672. X              (error "Incorrect model specifier")))))
  673. X        (or varnames
  674. X            (let ((with-y (eq (car-safe model) 'calcFunc-eq)))
  675. X              (if coefnames
  676. X              (calc-get-fit-variables (if with-y (1+ nvars) nvars)
  677. X                          (1- (length coefnames))
  678. X                          (math-all-vars-but
  679. X                           model coefnames)
  680. X                          nil with-y)
  681. X            (let* ((coefs (math-all-vars-but model nil))
  682. X                   (vars nil)
  683. X                   (n (- (length coefs) nvars (if with-y 2 1)))
  684. X                   p)
  685. X              (if (< n 0)
  686. X                  (error "Not enough variables in model"))
  687. X              (setq p (nthcdr n coefs))
  688. X              (setq vars (cdr p))
  689. X              (setcdr p nil)
  690. X              (calc-get-fit-variables (if with-y (1+ nvars) nvars)
  691. X                          (length coefs)
  692. X                          vars coefs with-y)))))
  693. X        (if record-entry
  694. X            (calc-record (list 'vec model varnames coefnames)
  695. X                 "modl"))))
  696. X         (t (beep))))
  697. X     (let ((calc-fit-to-trail t))
  698. X       (calc-enter-result n (substring (symbol-name func) 9)
  699. X              (list func model
  700. X                (if (= (length varnames) 2)
  701. X                    (nth 1 varnames)
  702. X                  varnames)
  703. X                (if (= (length coefnames) 2)
  704. X                    (nth 1 coefnames)
  705. X                  coefnames)
  706. X                data))
  707. X       (if (consp calc-fit-to-trail)
  708. X       (calc-record (calc-normalize calc-fit-to-trail) "parm")))))
  709. )
  710. X
  711. (defun calc-invent-independent-variables (n &optional but)
  712. X  (calc-invent-variables n but '(x y z t) "x")
  713. )
  714. X
  715. (defun calc-invent-parameter-variables (n &optional but)
  716. X  (calc-invent-variables n but '(a b c d) "a")
  717. )
  718. X
  719. (defun calc-invent-variables (num but names base)
  720. X  (let ((vars nil)
  721. X    (n num) (nn 0)
  722. X    var)
  723. X    (while (and (> n 0) names)
  724. X      (setq var (math-build-var-name (if (consp names)
  725. X                     (car names)
  726. X                       (concat base (setq nn (1+ nn))))))
  727. X      (or (math-expr-contains (cons 'vec but) var)
  728. X      (setq vars (cons var vars)
  729. X        n (1- n)))
  730. X      (or (symbolp names) (setq names (cdr names))))
  731. X    (if (= n 0)
  732. X    (nreverse vars)
  733. X      (calc-invent-variables num but t base)))
  734. )
  735. X
  736. (defun calc-get-fit-variables (nv nc &optional defv defc with-y homog)
  737. X  (or (= nv (if with-y (1+ nvars) nvars))
  738. X      (error "Wrong number of data vectors for this type of model"))
  739. X  (if (integerp defv)
  740. X      (setq homog defv
  741. X        defv nil))
  742. X  (if homog
  743. X      (setq nc (1- nc)))
  744. X  (or defv
  745. X      (setq defv (calc-invent-independent-variables nv)))
  746. X  (or defc
  747. X      (setq defc (calc-invent-parameter-variables nc defv)))
  748. X  (let ((vars (read-string (format "Fitting variables: (default %s; %s) "
  749. X                   (mapconcat 'symbol-name
  750. X                          (mapcar (function (lambda (v)
  751. X                                  (nth 1 v)))
  752. X                              defv)
  753. X                          ",")
  754. X                   (mapconcat 'symbol-name
  755. X                          (mapcar (function (lambda (v)
  756. X                                  (nth 1 v)))
  757. X                              defc)
  758. X                          ","))))
  759. X    (coefs nil))
  760. X    (setq vars (if (string-match "\\[" vars)
  761. X           (math-read-expr vars)
  762. X         (math-read-expr (concat "[" vars "]"))))
  763. X    (if (eq (car-safe vars) 'error)
  764. X    (error "Bad format in expression: %s" (nth 2 vars)))
  765. X    (or (math-vectorp vars)
  766. X    (error "Expected a variable or vector of variables"))
  767. X    (if (equal vars '(vec))
  768. X    (setq vars (cons 'vec defv)
  769. X          coefs (cons 'vec defc))
  770. X      (if (math-vectorp (nth 1 vars))
  771. X      (if (and (= (length vars) 3)
  772. X           (math-vectorp (nth 2 vars)))
  773. X          (setq coefs (nth 2 vars)
  774. X            vars (nth 1 vars))
  775. X        (error
  776. X         "Expected independent variables vector, then parameters vector"))
  777. X    (setq coefs (cons 'vec defc))))
  778. X    (or (= nv (1- (length vars)))
  779. X    (and (not with-y) (= (1+ nv) (1- (length vars))))
  780. X    (error "Expected %d independent variable%s" nv (if (= nv 1) "" "s")))
  781. X    (or (= nc (1- (length coefs)))
  782. X    (error "Expected %d parameter variable%s" nc (if (= nc 1) "" "s")))
  783. X    (if homog
  784. X    (setq coefs (cons 'vec (cons homog (cdr coefs)))))
  785. X    (if varnames
  786. X    (setq model (math-multi-subst model (cdr varnames) (cdr vars))))
  787. X    (if coefnames
  788. X    (setq model (math-multi-subst model (cdr coefnames) (cdr coefs))))
  789. X    (setq varnames vars
  790. X      coefnames coefs))
  791. )
  792. X
  793. X
  794. X
  795. X
  796. ;;; The following algorithms are from Numerical Recipes chapter 9.
  797. X
  798. ;;; "rtnewt" with safety kludges
  799. (defun math-newton-root (expr deriv guess orig-guess limit)
  800. X  (math-working "newton" guess)
  801. X  (let* ((var-DUMMY guess)
  802. X     next dval)
  803. X    (setq next (math-evaluate-expr expr)
  804. X      dval (math-evaluate-expr deriv))
  805. X    (if (and (Math-numberp next)
  806. X         (Math-numberp dval)
  807. X         (not (Math-zerop dval)))
  808. X    (progn
  809. X      (setq next (math-sub guess (math-div next dval)))
  810. X      (if (math-nearly-equal guess (setq next (math-float next)))
  811. X          (progn
  812. X        (setq var-DUMMY next)
  813. X        (list 'vec next (math-evaluate-expr expr)))
  814. X        (if (Math-lessp (math-abs-approx (math-sub next orig-guess))
  815. X                limit)
  816. X        (math-newton-root expr deriv next orig-guess limit)
  817. X          (math-reject-arg next "*Newton's method failed to converge"))))
  818. X      (math-reject-arg next "*Newton's method encountered a singularity")))
  819. )
  820. X
  821. ;;; Inspired by "rtsafe"
  822. (defun math-newton-search-root (expr deriv guess vguess ostep oostep
  823. X                     low vlow high vhigh)
  824. X  (let ((var-DUMMY guess)
  825. X    (better t)
  826. X    pos step next vnext)
  827. X    (if guess
  828. X    (math-working "newton" (list 'intv 0 low high))
  829. X      (math-working "bisect" (list 'intv 0 low high))
  830. X      (setq ostep (math-mul-float (math-sub-float high low)
  831. X                  '(float 5 -1))
  832. X        guess (math-add-float low ostep)
  833. X        var-DUMMY guess
  834. X        vguess (math-evaluate-expr expr))
  835. X      (or (Math-realp vguess)
  836. X      (progn
  837. X        (setq ostep (math-mul-float ostep '(float 6 -1))
  838. X          guess (math-add-float low ostep)
  839. X          var-DUMMY guess
  840. X          vguess (math-evaluate-expr expr))
  841. X        (or (math-realp vguess)
  842. X        (progn
  843. X          (setq ostep (math-mul-float ostep '(float 123456 -5))
  844. X            guess (math-add-float low ostep)
  845. X            var-DUMMY guess
  846. X            vguess nil))))))
  847. X    (or vguess
  848. X    (setq vguess (math-evaluate-expr expr)))
  849. X    (or (Math-realp vguess)
  850. X    (math-reject-arg guess "*Newton's method encountered a singularity"))
  851. X    (setq vguess (math-float vguess))
  852. X    (if (eq (Math-negp vlow) (setq pos (Math-posp vguess)))
  853. X    (setq high guess
  854. X          vhigh vguess)
  855. X      (if (eq (Math-negp vhigh) pos)
  856. X      (setq low guess
  857. X        vlow vguess)
  858. X    (setq better nil)))
  859. X    (if (or (Math-zerop vguess)
  860. X        (math-nearly-equal low high))
  861. X    (list 'vec guess vguess)
  862. X      (setq step (math-evaluate-expr deriv))
  863. X      (if (and (Math-realp step)
  864. X           (not (Math-zerop step))
  865. X           (setq step (math-div-float vguess (math-float step))
  866. X             next (math-sub-float guess step))
  867. X           (not (math-lessp-float high next))
  868. X           (not (math-lessp-float next low)))
  869. X      (progn
  870. X        (setq var-DUMMY next
  871. X          vnext (math-evaluate-expr expr))
  872. X        (if (or (Math-zerop vnext)
  873. X            (math-nearly-equal next guess))
  874. X        (list 'vec next vnext)
  875. X          (if (and better
  876. X               (math-lessp-float (math-abs (or oostep
  877. X                               (math-sub-float
  878. X                            high low)))
  879. X                     (math-abs
  880. X                      (math-mul-float '(float 2 0)
  881. X                              step))))
  882. X          (math-newton-search-root expr deriv nil nil nil ostep
  883. X                       low vlow high vhigh)
  884. X        (math-newton-search-root expr deriv next vnext step ostep
  885. X                     low vlow high vhigh))))
  886. X    (if (or (and (Math-posp vlow) (Math-posp vhigh))
  887. X        (and (Math-negp vlow) (Math-negp vhigh)))
  888. X        (math-search-root expr deriv low vlow high vhigh)
  889. X      (math-newton-search-root expr deriv nil nil nil ostep
  890. X                   low vlow high vhigh)))))
  891. )
  892. X
  893. ;;; Search for a root in an interval with no overt zero crossing.
  894. (defun math-search-root (expr deriv low vlow high vhigh)
  895. X  (let (found)
  896. X    (if root-widen
  897. X    (let ((iters 0)
  898. X          (iterlim (if (eq root-widen 'point)
  899. X               (+ calc-internal-prec 10)
  900. X             20))
  901. X          (factor (if (eq root-widen 'point)
  902. X              '(float 9 0)
  903. X            '(float 16 -1)))
  904. X          (prev nil) vprev waslow
  905. X          diff)
  906. X      (while (or (and (math-posp vlow) (math-posp vhigh))
  907. X             (and (math-negp vlow) (math-negp vhigh)))
  908. X        (math-working "widen" (list 'intv 0 low high))
  909. X        (if (> (setq iters (1+ iters)) iterlim)
  910. X        (math-reject-arg (list 'intv 0 low high)
  911. X                 "*Unable to bracket root"))
  912. X        (if (= iters calc-internal-prec)
  913. X        (setq factor '(float 16 -1)))
  914. X        (setq diff (math-mul-float (math-sub-float high low) factor))
  915. X        (if (Math-zerop diff)
  916. X        (setq high (calcFunc-incr high 10))
  917. X          (if (math-lessp-float (math-abs vlow) (math-abs vhigh))
  918. X          (setq waslow t
  919. X            prev low
  920. X            low (math-sub low diff)
  921. X            var-DUMMY low
  922. X            vprev vlow
  923. X            vlow (math-evaluate-expr expr))
  924. X        (setq waslow nil
  925. X              prev high
  926. X              high (math-add high diff)
  927. X              var-DUMMY high
  928. X              vprev vhigh
  929. X              vhigh (math-evaluate-expr expr)))))
  930. X      (if prev
  931. X          (if waslow
  932. X          (setq high prev vhigh vprev)
  933. X        (setq low prev vlow vprev)))
  934. X      (setq found t))
  935. X      (or (Math-realp vlow)
  936. X      (math-reject-arg vlow 'realp))
  937. X      (or (Math-realp vhigh)
  938. X      (math-reject-arg vhigh 'realp))
  939. X      (let ((xvals (list low high))
  940. X        (yvals (list vlow vhigh))
  941. X        (pos (Math-posp vlow))
  942. X        (levels 0)
  943. X        (step (math-sub-float high low))
  944. X        xp yp var-DUMMY)
  945. X    (while (and (<= (setq levels (1+ levels)) 5)
  946. X            (not found))
  947. X      (setq xp xvals
  948. X        yp yvals
  949. X        step (math-mul-float step '(float 497 -3)))
  950. X      (while (and (cdr xp) (not found))
  951. X        (if (Math-realp (car yp))
  952. X        (setq low (car xp)
  953. X              vlow (car yp)))
  954. X        (setq high (math-add-float (car xp) step)
  955. X          var-DUMMY high
  956. X          vhigh (math-evaluate-expr expr))
  957. X        (math-working "search" high)
  958. X        (if (and (Math-realp vhigh)
  959. X             (eq (math-negp vhigh) pos))
  960. X        (setq found t)
  961. X          (setcdr xp (cons high (cdr xp)))
  962. X          (setcdr yp (cons vhigh (cdr yp)))
  963. X          (setq xp (cdr (cdr xp))
  964. X            yp (cdr (cdr yp))))))))
  965. X    (if found
  966. X    (if (Math-zerop vhigh)
  967. X        (list 'vec high vhigh)
  968. X      (if (Math-zerop vlow)
  969. X          (list 'vec low vlow)
  970. X        (if deriv
  971. X        (math-newton-search-root expr deriv nil nil nil nil
  972. X                     low vlow high vhigh)
  973. X          (math-bisect-root expr low vlow high vhigh))))
  974. X      (math-reject-arg (list 'intv 3 low high)
  975. X               "*Unable to find a sign change in this interval")))
  976. )
  977. X
  978. ;;; "rtbis"  (but we should be using Brent's method)
  979. (defun math-bisect-root (expr low vlow high vhigh)
  980. X  (let ((step (math-sub-float high low))
  981. X    (pos (Math-posp vhigh))
  982. X    var-DUMMY
  983. X    mid vmid)
  984. X    (while (not (or (math-nearly-equal low
  985. X                       (setq step (math-mul-float
  986. X                           step '(float 5 -1))
  987. X                         mid (math-add-float low step)))
  988. X            (progn
  989. X              (setq var-DUMMY mid
  990. X                vmid (math-evaluate-expr expr))
  991. X              (Math-zerop vmid))))
  992. X      (math-working "bisect" mid)
  993. X      (if (eq (Math-posp vmid) pos)
  994. X      (setq high mid
  995. X        vhigh vmid)
  996. X    (setq low mid
  997. X          vlow vmid)))
  998. X    (list 'vec mid vmid))
  999. )
  1000. X
  1001. ;;; "mnewt"
  1002. (defun math-newton-multi (expr jacob n guess orig-guess limit)
  1003. X  (let ((m -1)
  1004. X    (p guess)
  1005. X    p2 expr-val jacob-val next)
  1006. X    (while (< (setq p (cdr p) m (1+ m)) n)
  1007. X      (set (nth 2 (aref math-root-vars m)) (car p)))
  1008. X    (setq expr-val (math-evaluate-expr expr)
  1009. X      jacob-val (math-evaluate-expr jacob))
  1010. X    (or (and (math-constp expr-val)
  1011. X         (math-constp jacob-val))
  1012. X    (math-reject-arg guess "*Newton's method encountered a singularity"))
  1013. X    (setq next (math-add guess (math-div (math-float (math-neg expr-val))
  1014. X                     (math-float jacob-val)))
  1015. X      p guess p2 next)
  1016. X    (math-working "newton" next)
  1017. X    (while (and (setq p (cdr p) p2 (cdr p2))
  1018. X        (math-nearly-equal (car p) (car p2))))
  1019. X    (if p
  1020. X    (if (Math-lessp (math-abs-approx (math-sub next orig-guess))
  1021. X            limit)
  1022. X        (math-newton-multi expr jacob n next orig-guess limit)
  1023. X      (math-reject-arg nil "*Newton's method failed to converge"))
  1024. X      (list 'vec next expr-val)))
  1025. )
  1026. X
  1027. (defvar math-root-vars [(var DUMMY var-DUMMY)])
  1028. X
  1029. (defun math-find-root (expr var guess root-widen)
  1030. X  (if (eq (car-safe expr) 'vec)
  1031. X      (let ((n (1- (length expr)))
  1032. X        (calc-symbolic-mode nil)
  1033. X        (var-DUMMY nil)
  1034. X        (jacob (list 'vec))
  1035. X        p p2 m row)
  1036. X    (or (eq (car-safe var) 'vec)
  1037. X        (math-reject-arg var 'vectorp))
  1038. X    (or (= (length var) (1+ n))
  1039. X        (math-dimension-error))
  1040. X    (setq expr (copy-sequence expr))
  1041. X    (while (>= n (length math-root-vars))
  1042. X      (let ((symb (intern (concat "math-root-v"
  1043. X                      (int-to-string
  1044. X                       (length math-root-vars))))))
  1045. X        (setq math-root-vars (vconcat math-root-vars
  1046. X                      (vector (list 'var symb symb))))))
  1047. X    (setq m -1)
  1048. X    (while (< (setq m (1+ m)) n)
  1049. X      (set (nth 2 (aref math-root-vars m)) nil))
  1050. X    (setq m -1 p var)
  1051. X    (while (setq m (1+ m) p (cdr p))
  1052. X      (or (eq (car-safe (car p)) 'var)
  1053. X          (math-reject-arg var "*Expected a variable"))
  1054. X      (setq p2 expr)
  1055. X      (while (setq p2 (cdr p2))
  1056. X        (setcar p2 (math-expr-subst (car p2) (car p)
  1057. X                    (aref math-root-vars m)))))
  1058. X    (or (eq (car-safe guess) 'vec)
  1059. X        (math-reject-arg guess 'vectorp))
  1060. X    (or (= (length guess) (1+ n))
  1061. X        (math-dimension-error))
  1062. X    (setq guess (copy-sequence guess)
  1063. X          p guess)
  1064. X    (while (setq p (cdr p))
  1065. X      (or (Math-numberp (car guess))
  1066. X          (math-reject-arg guess 'numberp))
  1067. X      (setcar p (math-float (car p))))
  1068. X    (setq p expr)
  1069. X    (while (setq p (cdr p))
  1070. X      (if (assq (car-safe (car p)) calc-tweak-eqn-table)
  1071. X          (setcar p (math-sub (nth 1 (car p)) (nth 2 (car p)))))
  1072. X      (setcar p (math-evaluate-expr (car p)))
  1073. X      (setq row (list 'vec)
  1074. X        m -1)
  1075. X      (while (< (setq m (1+ m)) n)
  1076. X        (nconc row (list (math-evaluate-expr
  1077. X                  (or (calcFunc-deriv (car p)
  1078. X                          (aref math-root-vars m)
  1079. X                          nil t)
  1080. X                  (math-reject-arg
  1081. X                   expr
  1082. X                   "*Formulas must be differentiable"))))))
  1083. X      (nconc jacob (list row)))
  1084. X    (setq m (math-abs-approx guess))
  1085. X    (math-newton-multi expr jacob n guess guess
  1086. X               (if (math-zerop m) '(float 1 3) (math-mul m 10))))
  1087. X    (or (eq (car-safe var) 'var)
  1088. X    (math-reject-arg var "*Expected a variable"))
  1089. X    (or (math-expr-contains expr var)
  1090. X    (math-reject-arg expr "*Formula does not contain specified variable"))
  1091. X    (if (assq (car expr) calc-tweak-eqn-table)
  1092. X    (setq expr (math-sub (nth 1 expr) (nth 2 expr))))
  1093. X    (math-with-extra-prec 2
  1094. X      (setq expr (math-expr-subst expr var '(var DUMMY var-DUMMY)))
  1095. X      (let* ((calc-symbolic-mode nil)
  1096. X         (var-DUMMY nil)
  1097. X         (expr (math-evaluate-expr expr))
  1098. X         (deriv (calcFunc-deriv expr '(var DUMMY var-DUMMY) nil t))
  1099. X         low high vlow vhigh)
  1100. X    (and deriv (setq deriv (math-evaluate-expr deriv)))
  1101. X    (setq guess (math-float guess))
  1102. X    (if (and (math-numberp guess)
  1103. X         deriv)
  1104. X        (math-newton-root expr deriv guess guess
  1105. X                  (if (math-zerop guess) '(float 1 6)
  1106. X                (math-mul (math-abs-approx guess) 100)))
  1107. X      (if (Math-realp guess)
  1108. X          (setq low guess
  1109. X            high guess
  1110. X            var-DUMMY guess
  1111. X            vlow (math-evaluate-expr expr)
  1112. X            vhigh vlow
  1113. X            root-widen 'point)
  1114. X        (if (eq (car guess) 'intv)
  1115. X        (progn
  1116. X          (or (math-constp guess) (math-reject-arg guess 'constp))
  1117. X          (setq low (nth 2 guess)
  1118. X            high (nth 3 guess))
  1119. X          (if (memq (nth 1 guess) '(0 1))
  1120. X              (setq low (calcFunc-incr low 1 high)))
  1121. X          (if (memq (nth 1 guess) '(0 2))
  1122. X              (setq high (calcFunc-incr high -1 low)))
  1123. X          (setq var-DUMMY low
  1124. X            vlow (math-evaluate-expr expr)
  1125. X            var-DUMMY high
  1126. X            vhigh (math-evaluate-expr expr)))
  1127. X          (if (math-complexp guess)
  1128. X          (math-reject-arg "*Complex root finder must have derivative")
  1129. X        (math-reject-arg guess 'realp))))
  1130. X      (if (Math-zerop vlow)
  1131. X          (list 'vec low vlow)
  1132. X        (if (Math-zerop vhigh)
  1133. X        (list 'vec high vhigh)
  1134. X          (if (and deriv (Math-numberp vlow) (Math-numberp vhigh))
  1135. X          (math-newton-search-root expr deriv nil nil nil nil
  1136. X                       low vlow high vhigh)
  1137. X        (if (or (and (Math-posp vlow) (Math-posp vhigh))
  1138. X            (and (Math-negp vlow) (Math-negp vhigh))
  1139. X            (not (Math-numberp vlow))
  1140. X            (not (Math-numberp vhigh)))
  1141. X            (math-search-root expr deriv low vlow high vhigh)
  1142. X          (math-bisect-root expr low vlow high vhigh)))))))))
  1143. )
  1144. X
  1145. (defun calcFunc-root (expr var guess)
  1146. X  (math-find-root expr var guess nil)
  1147. )
  1148. X
  1149. (defun calcFunc-wroot (expr var guess)
  1150. X  (math-find-root expr var guess t)
  1151. )
  1152. X
  1153. X
  1154. X
  1155. X
  1156. ;;; The following algorithms come from Numerical Recipes, chapter 10.
  1157. X
  1158. (defun math-min-eval (expr a)
  1159. X  (if (Math-vectorp a)
  1160. X      (let ((m -1))
  1161. X    (while (setq m (1+ m) a (cdr a))
  1162. X      (set (nth 2 (aref math-min-vars m)) (car a))))
  1163. X    (setq var-DUMMY a))
  1164. X  (setq a (math-evaluate-expr expr))
  1165. X  (if (Math-ratp a)
  1166. X      (math-float a)
  1167. X    (if (eq (car a) 'float)
  1168. X    a
  1169. X      (math-reject-arg a 'realp)))
  1170. )
  1171. X
  1172. X
  1173. ;;; A bracket for a minimum is a < b < c where f(b) < f(a) and f(b) < f(c).
  1174. X
  1175. ;;; "mnbrak"
  1176. (defun math-widen-min (expr a b)
  1177. X  (let ((done nil)
  1178. X    (iters 30)
  1179. X    incr c va vb vc u vu r q ulim bc ba qr)
  1180. X    (or b (setq b (math-mul a '(float 101 -2))))
  1181. X    (setq va (math-min-eval expr a)
  1182. X      vb (math-min-eval expr b))
  1183. X    (if (math-lessp-float va vb)
  1184. X    (setq u a a b b u
  1185. X          vu va va vb vb vu))
  1186. X    (setq c (math-add-float b (math-mul-float '(float 161803 -5)
  1187. X                          (math-sub-float b a)))
  1188. X      vc (math-min-eval expr c))
  1189. X    (while (and (not done) (math-lessp-float vc vb))
  1190. X      (math-working "widen" (list 'intv 0 a c))
  1191. X      (if (= (setq iters (1- iters)) 0)
  1192. X      (math-reject-arg nil (format "*Unable to find a %s near the interval"
  1193. X                       math-min-or-max)))
  1194. X      (setq bc (math-sub-float b c)
  1195. X        ba (math-sub-float b a)
  1196. X        r (math-mul-float ba (math-sub-float vb vc))
  1197. X        q (math-mul-float bc (math-sub-float vb va))
  1198. X        qr (math-sub-float q r))
  1199. X      (if (math-lessp-float (math-abs qr) '(float 1 -20))
  1200. X      (setq qr (if (math-negp qr) '(float -1 -20) '(float 1 -20))))
  1201. X      (setq u (math-sub-float
  1202. X           b
  1203. X           (math-div-float (math-sub-float (math-mul-float bc q)
  1204. X                           (math-mul-float ba r))
  1205. X                   (math-mul-float '(float 2 0) qr)))
  1206. X        ulim (math-add-float b (math-mul-float '(float -1 2) bc))
  1207. X        incr (math-negp bc))
  1208. X      (if (if incr (math-lessp-float b u) (math-lessp-float u b))
  1209. X      (if (if incr (math-lessp-float u c) (math-lessp-float c u))
  1210. X          (if (math-lessp-float (setq vu (math-min-eval expr u)) vc)
  1211. X          (setq a b  va vb
  1212. X            b u  vb vu
  1213. X            done t)
  1214. X        (if (math-lessp-float vb vu)
  1215. X            (setq c u  vc vu
  1216. X              done t)
  1217. X          (setq u (math-add-float c (math-mul-float '(float -161803 -5)
  1218. X                                bc))
  1219. X            vu (math-min-eval expr u))))
  1220. X        (if (if incr (math-lessp-float u ulim) (math-lessp-float ulim u))
  1221. X        (if (math-lessp-float (setq vu (math-min-eval expr u)) vc)
  1222. X            (setq b c  vb vc
  1223. X              c u  vc vu
  1224. X              u (math-add-float c (math-mul-float
  1225. X                           '(float -161803 -5)
  1226. X                           (math-sub-float b c)))
  1227. X              vu (math-min-eval expr u)))
  1228. X          (setq u ulim
  1229. X            vu (math-min-eval expr u))))
  1230. X    (setq u (math-add-float c (math-mul-float '(float -161803 -5)
  1231. X                          bc))
  1232. X          vu (math-min-eval expr u)))
  1233. X      (setq a b  va vb
  1234. X        b c  vb vc
  1235. X        c u  vc vu))
  1236. X    (if (math-lessp-float a c)
  1237. X    (list a va b vb c vc)
  1238. X      (list c vc b vb a va)))
  1239. )
  1240. X
  1241. (defun math-narrow-min (expr a c intv)
  1242. X  (let ((xvals (list a c))
  1243. X    (yvals (list (math-min-eval expr a)
  1244. X             (math-min-eval expr c)))
  1245. X    (levels 0)
  1246. X    (step (math-sub-float c a))
  1247. X    (found nil)
  1248. X    xp yp b)
  1249. X    (while (and (<= (setq levels (1+ levels)) 5)
  1250. X        (not found))
  1251. X      (setq xp xvals
  1252. X        yp yvals
  1253. X        step (math-mul-float step '(float 497 -3)))
  1254. X      (while (and (cdr xp) (not found))
  1255. X    (setq b (math-add-float (car xp) step))
  1256. X    (math-working "search" b)
  1257. X    (setcdr xp (cons b (cdr xp)))
  1258. X    (setcdr yp (cons (math-min-eval expr b) (cdr yp)))
  1259. X    (if (and (math-lessp-float (nth 1 yp) (car yp))
  1260. X         (math-lessp-float (nth 1 yp) (nth 2 yp)))
  1261. X        (setq found t)
  1262. X      (setq xp (cdr xp)
  1263. X        yp (cdr yp))
  1264. X      (if (and (cdr (cdr yp))
  1265. X           (math-lessp-float (nth 1 yp) (car yp))
  1266. X           (math-lessp-float (nth 1 yp) (nth 2 yp)))
  1267. X          (setq found t)
  1268. X        (setq xp (cdr xp)
  1269. X          yp (cdr yp))))))
  1270. X    (if found
  1271. X    (list (car xp) (car yp)
  1272. X          (nth 1 xp) (nth 1 yp)
  1273. X          (nth 2 xp) (nth 2 yp))
  1274. X      (or (if (math-lessp-float (car yvals) (nth 1 yvals))
  1275. X          (and (memq (nth 1 intv) '(2 3))
  1276. X           (let ((min (car yvals)))
  1277. X             (while (and (setq yvals (cdr yvals))
  1278. X                 (math-lessp-float min (car yvals))))
  1279. X             (and (not yvals)
  1280. X              (list (nth 2 intv) min))))
  1281. X        (and (memq (nth 1 intv) '(1 3))
  1282. X         (setq yvals (nreverse yvals))
  1283. X         (let ((min (car yvals)))
  1284. X           (while (and (setq yvals (cdr yvals))
  1285. X                   (math-lessp-float min (car yvals))))
  1286. X           (and (not yvals)
  1287. X            (list (nth 3 intv) min)))))
  1288. X      (math-reject-arg nil (format "*Unable to find a %s in the interval"
  1289. X                       math-min-or-max)))))
  1290. )
  1291. X
  1292. ;;; "brent"
  1293. (defun math-brent-min (expr prec a va x vx b vb)
  1294. X  (let ((iters (+ 20 (* 5 prec)))
  1295. X    (w x)
  1296. X    (vw vx)
  1297. X    (v x)
  1298. X    (vv vx)
  1299. X    (tol (list 'float 1 (- -1 prec)))
  1300. X    (zeps (list 'float 1 (- -5 prec)))
  1301. X    (e '(float 0 0))
  1302. X    u vu xm tol1 tol2 etemp p q r xv xw)
  1303. X    (while (progn
  1304. X         (setq xm (math-mul-float '(float 5 -1)
  1305. X                      (math-add-float a b))
  1306. X           tol1 (math-add-float
  1307. X             zeps
  1308. X             (math-mul-float tol (math-abs x)))
  1309. X           tol2 (math-mul-float tol1 '(float 2 0)))
  1310. X         (math-lessp-float (math-sub-float tol2
  1311. X                           (math-mul-float
  1312. X                        '(float 5 -1)
  1313. X                        (math-sub-float b a)))
  1314. X                   (math-abs (math-sub-float x xm))))
  1315. X      (if (= (setq iters (1- iters)) 0)
  1316. X      (math-reject-arg nil (format "*Unable to converge on a %s"
  1317. X                       math-min-or-max)))
  1318. X      (math-working "brent" x)
  1319. X      (if (math-lessp-float (math-abs e) tol1)
  1320. X      (setq e (if (math-lessp-float x xm)
  1321. X              (math-sub-float b x)
  1322. X            (math-sub-float a x))
  1323. X        d (math-mul-float '(float 381966 -6) e))
  1324. X    (setq xw (math-sub-float x w)
  1325. X          r (math-mul-float xw (math-sub-float vx vv))
  1326. X          xv (math-sub-float x v)
  1327. X          q (math-mul-float xv (math-sub-float vx vw))
  1328. X          p (math-sub-float (math-mul-float xv q)
  1329. X                (math-mul-float xw r))
  1330. X          q (math-mul-float '(float 2 0) (math-sub-float q r)))
  1331. X    (if (math-posp q)
  1332. X        (setq p (math-neg-float p))
  1333. X      (setq q (math-neg-float q)))
  1334. X    (setq etemp e
  1335. X          e d)
  1336. X    (if (and (math-lessp-float (math-abs p)
  1337. X                   (math-abs (math-mul-float
  1338. X                          '(float 5 -1)
  1339. X                          (math-mul-float q etemp))))
  1340. X         (math-lessp-float (math-mul-float
  1341. X                    q (math-sub-float a x)) p)
  1342. X         (math-lessp-float p (math-mul-float
  1343. X                      q (math-sub-float b x))))
  1344. X        (progn
  1345. X          (setq d (math-div-float p q)
  1346. X            u (math-add-float x d))
  1347. X          (if (or (math-lessp-float (math-sub-float u a) tol2)
  1348. X              (math-lessp-float (math-sub-float b u) tol2))
  1349. X          (setq d (if (math-lessp-float xm x)
  1350. X                  (math-neg-float tol1)
  1351. X                tol1))))
  1352. X      (setq e (if (math-lessp-float x xm)
  1353. X              (math-sub-float b x)
  1354. X            (math-sub-float a x))
  1355. X        d (math-mul-float '(float 381966 -6) e))))
  1356. X      (setq u (math-add-float x
  1357. X                  (if (math-lessp-float (math-abs d) tol1)
  1358. X                  (if (math-negp d)
  1359. X                      (math-neg-float tol1)
  1360. X                    tol1)
  1361. X                d))
  1362. X        vu (math-min-eval expr u))
  1363. X      (if (math-lessp-float vx vu)
  1364. X      (progn
  1365. X        (if (math-lessp-float u x)
  1366. X        (setq a u)
  1367. X          (setq b u))
  1368. X        (if (or (equal w x)
  1369. X            (not (math-lessp-float vw vu)))
  1370. X        (setq v w  vv vw
  1371. X              w u  vw vu)
  1372. X          (if (or (equal v x)
  1373. X              (equal v w)
  1374. X              (not (math-lessp-float vv vu)))
  1375. X          (setq v u  vv vu))))
  1376. X    (if (math-lessp-float u x)
  1377. X        (setq b x)
  1378. X      (setq a x))
  1379. X    (setq v w  vv vw
  1380. X          w x  vw vx
  1381. X          x u  vx vu)))
  1382. X    (list 'vec x vx))
  1383. )
  1384. X
  1385. ;;; "powell"
  1386. (defun math-powell-min (expr n guesses prec)
  1387. X  (let* ((f1dim (math-line-min-func expr n))
  1388. X     (xi (calcFunc-idn 1 n))
  1389. X     (p (cons 'vec (mapcar 'car guesses)))
  1390. X     (pt p)
  1391. X     (ftol (list 'float 1 (- prec)))
  1392. X     (fret (math-min-eval expr p))
  1393. X     fp ptt fptt xit i ibig del diff res)
  1394. X    (while (progn
  1395. X         (setq fp fret
  1396. X           ibig 0
  1397. X           del '(float 0 0)
  1398. X           i 0)
  1399. X         (while (<= (setq i (1+ i)) n)
  1400. X           (setq fptt fret
  1401. X             res (math-line-min f1dim p
  1402. X                    (math-mat-col xi i)
  1403. X                    n prec)
  1404. X             p (let ((calc-internal-prec prec))
  1405. X             (math-normalize (car res)))
  1406. X             fret (nth 2 res)
  1407. X             diff (math-abs (math-sub-float fptt fret)))
  1408. X           (if (math-lessp-float del diff)
  1409. X           (setq del diff
  1410. X             ibig i)))
  1411. X         (math-lessp-float
  1412. X          (math-mul-float ftol
  1413. X                  (math-add-float (math-abs fp)
  1414. X                          (math-abs fret)))
  1415. X          (math-mul-float '(float 2 0)
  1416. X                  (math-abs (math-sub-float fp
  1417. X                            fret)))))
  1418. X      (setq ptt (math-sub (math-mul '(float 2 0) p) pt)
  1419. X        xit (math-sub p pt)
  1420. X        pt p
  1421. X        fptt (math-min-eval expr ptt))
  1422. X      (if (and (math-lessp-float fptt fp)
  1423. X           (math-lessp-float
  1424. X        (math-mul-float
  1425. X         (math-mul-float '(float 2 0)
  1426. X                 (math-add-float
  1427. X                  (math-sub-float fp
  1428. X                          (math-mul-float '(float 2 0)
  1429. X                                  fret))
  1430. X                  fptt))
  1431. X         (math-sqr-float (math-sub-float
  1432. X                  (math-sub-float fp fret) del)))
  1433. X        (math-mul-float del
  1434. X                (math-sqr-float (math-sub-float fp fptt)))))
  1435. X      (progn
  1436. X        (setq res (math-line-min f1dim p xit n prec)
  1437. X          p (car res)
  1438. X          fret (nth 2 res)
  1439. X          i 0)
  1440. X        (while (<= (setq i (1+ i)) n)
  1441. X          (setcar (nthcdr ibig (nth i xi))
  1442. X              (nth i (nth 1 res)))))))
  1443. X    (list 'vec p fret))
  1444. )
  1445. X
  1446. (defun math-line-min-func (expr n)
  1447. X  (let ((m -1))
  1448. X    (while (< (setq m (1+ m)) n)
  1449. X      (set (nth 2 (aref math-min-vars m))
  1450. X       (list '+
  1451. X         (list '*
  1452. X               '(var DUMMY var-DUMMY)
  1453. X               (list 'calcFunc-mrow '(var line-xi line-xi) (1+ m)))
  1454. X         (list 'calcFunc-mrow '(var line-p line-p) (1+ m)))))
  1455. X    (math-evaluate-expr expr))
  1456. )
  1457. X
  1458. (defun math-line-min (f1dim line-p line-xi n prec)
  1459. X  (let* ((var-DUMMY nil)
  1460. X     (expr (math-evaluate-expr f1dim))
  1461. X     (params (math-widen-min expr '(float 0 0) '(float 1 0)))
  1462. X     (res (apply 'math-brent-min expr prec params))
  1463. X     (xi (math-mul (nth 1 res) line-xi)))
  1464. X    (list (math-add line-p xi) xi (nth 2 res)))
  1465. )
  1466. X
  1467. X
  1468. (defvar math-min-vars [(var DUMMY var-DUMMY)])
  1469. X
  1470. (defun math-find-minimum (expr var guess min-widen)
  1471. X  (let* ((calc-symbolic-mode nil)
  1472. X     (n 0)
  1473. X     (var-DUMMY nil)
  1474. X     (isvec (math-vectorp var))
  1475. X     g guesses)
  1476. X    (or (math-vectorp var)
  1477. X    (setq var (list 'vec var)))
  1478. X    (or (math-vectorp guess)
  1479. X    (setq guess (list 'vec guess)))
  1480. X    (or (= (length var) (length guess))
  1481. X    (math-dimension-error))
  1482. X    (while (setq var (cdr var) guess (cdr guess))
  1483. X      (or (eq (car-safe (car var)) 'var)
  1484. X      (math-reject-arg (car vg) "*Expected a variable"))
  1485. X      (or (math-expr-contains expr (car var))
  1486. X      (math-reject-arg (car var)
  1487. X               "*Formula does not contain specified variable"))
  1488. X      (while (>= (1+ n) (length math-min-vars))
  1489. X    (let ((symb (intern (concat "math-min-v"
  1490. X                    (int-to-string
  1491. X                     (length math-min-vars))))))
  1492. X      (setq math-min-vars (vconcat math-min-vars
  1493. X                       (vector (list 'var symb symb))))))
  1494. X      (set (nth 2 (aref math-min-vars n)) nil)
  1495. X      (set (nth 2 (aref math-min-vars (1+ n))) nil)
  1496. X      (if (math-complexp (car guess))
  1497. X      (setq expr (math-expr-subst expr
  1498. X                      (car var)
  1499. X                      (list '+ (aref math-min-vars n)
  1500. X                        (list '*
  1501. X                          (aref math-min-vars (1+ n))
  1502. X                          '(cplx 0 1))))
  1503. X        guesses (let ((g (math-float (math-complex (car guess)))))
  1504. X              (cons (list (nth 2 g) nil nil)
  1505. X                (cons (list (nth 1 g) nil nil t)
  1506. X                      guesses)))
  1507. X        n (+ n 2))
  1508. X    (setq expr (math-expr-subst expr
  1509. X                    (car var)
  1510. X                    (aref math-min-vars n))
  1511. X          guesses (cons (if (math-realp (car guess))
  1512. X                (list (math-float (car guess)) nil nil)
  1513. X                  (if (and (eq (car-safe (car guess)) 'intv)
  1514. X                       (math-constp (car guess)))
  1515. X                  (list (math-mul
  1516. X                     (math-add (nth 2 (car guess))
  1517. X                           (nth 3 (car guess)))
  1518. X                     '(float 5 -1))
  1519. X                    (math-float (nth 2 (car guess)))
  1520. X                    (math-float (nth 3 (car guess)))
  1521. X                    (car guess))
  1522. X                (math-reject-arg (car guess) 'realp)))
  1523. X                guesses)
  1524. X          n (1+ n))))
  1525. X    (setq guesses (nreverse guesses)
  1526. X      expr (math-evaluate-expr expr))
  1527. X    (if (= n 1)
  1528. X    (let* ((params (if (nth 1 (car guesses))
  1529. X               (if min-widen
  1530. X                   (math-widen-min expr
  1531. X                           (nth 1 (car guesses))
  1532. X                           (nth 2 (car guesses)))
  1533. X                 (math-narrow-min expr
  1534. X                          (nth 1 (car guesses))
  1535. X                          (nth 2 (car guesses))
  1536. X                          (nth 3 (car guesses))))
  1537. X             (math-widen-min expr
  1538. X                     (car (car guesses))
  1539. X                     nil)))
  1540. X           (prec calc-internal-prec)
  1541. X           (res (if (cdr (cdr params))
  1542. X            (math-with-extra-prec (+ calc-internal-prec 2)
  1543. X              (apply 'math-brent-min expr prec params))
  1544. X              (cons 'vec params))))
  1545. X      (if isvec
  1546. X          (list 'vec (list 'vec (nth 1 res)) (nth 2 res))
  1547. X        res))
  1548. X      (let* ((prec calc-internal-prec)
  1549. X         (res (math-with-extra-prec (+ calc-internal-prec 2)
  1550. X            (math-powell-min expr n guesses prec)))
  1551. X         (p (nth 1 res))
  1552. X         (vec (list 'vec)))
  1553. X    (while (setq p (cdr p))
  1554. X      (if (nth 3 (car guesses))
  1555. X          (progn
  1556. X        (nconc vec (list (math-normalize
  1557. X                  (list 'cplx (car p) (nth 1 p)))))
  1558. X        (setq p (cdr p)
  1559. X              guesses (cdr guesses)))
  1560. X        (nconc vec (list (car p))))
  1561. X      (setq guesses (cdr guesses)))
  1562. X    (if isvec
  1563. X        (list 'vec vec (nth 2 res))
  1564. X      (list 'vec (nth 1 vec) (nth 2 res))))))
  1565. )
  1566. (setq math-min-or-max "minimum")
  1567. X
  1568. (defun calcFunc-minimize (expr var guess)
  1569. X  (let ((calc-internal-prec (max (/ calc-internal-prec 2) 3))
  1570. X    (math-min-or-max "minimum"))
  1571. X    (math-find-minimum (math-normalize expr)
  1572. X               (math-normalize var)
  1573. X               (math-normalize guess) nil))
  1574. )
  1575. X
  1576. (defun calcFunc-wminimize (expr var guess)
  1577. X  (let ((calc-internal-prec (max (/ calc-internal-prec 2) 3))
  1578. X    (math-min-or-max "minimum"))
  1579. X    (math-find-minimum (math-normalize expr)
  1580. X               (math-normalize var)
  1581. X               (math-normalize guess) t))
  1582. )
  1583. X
  1584. (defun calcFunc-maximize (expr var guess)
  1585. X  (let* ((calc-internal-prec (max (/ calc-internal-prec 2) 3))
  1586. X     (math-min-or-max "maximum")
  1587. X     (res (math-find-minimum (math-normalize (math-neg expr))
  1588. X                 (math-normalize var)
  1589. X                 (math-normalize guess) nil)))
  1590. X    (list 'vec (nth 1 res) (math-neg (nth 2 res))))
  1591. )
  1592. X
  1593. (defun calcFunc-wmaximize (expr var guess)
  1594. X  (let* ((calc-internal-prec (max (/ calc-internal-prec 2) 3))
  1595. X     (math-min-or-max "maximum")
  1596. X     (res (math-find-minimum (math-normalize (math-neg expr))
  1597. X                 (math-normalize var)
  1598. X                 (math-normalize guess) t)))
  1599. X    (list 'vec (nth 1 res) (math-neg (nth 2 res))))
  1600. )
  1601. X
  1602. X
  1603. X
  1604. X
  1605. ;;; The following algorithms come from Numerical Recipes, chapter 3.
  1606. X
  1607. (defun calcFunc-polint (data x)
  1608. X  (or (math-matrixp data) (math-reject-arg data 'matrixp))
  1609. X  (or (= (length data) 3)
  1610. X      (math-reject-arg data "*Wrong number of data rows"))
  1611. X  (or (> (length (nth 1 data)) 2)
  1612. X      (math-reject-arg data "*Too few data points"))
  1613. X  (if (and (math-vectorp x) (or (math-constp x) math-expand-formulas))
  1614. X      (cons 'vec (mapcar (function (lambda (x) (calcFunc-polint data x)))
  1615. X             (cdr x)))
  1616. X    (or (math-objectp x) math-expand-formulas (math-reject-arg x 'objectp))
  1617. X    (math-with-extra-prec 2
  1618. X      (cons 'vec (math-poly-interp (cdr (nth 1 data)) (cdr (nth 2 data)) x
  1619. X                   nil))))
  1620. )
  1621. (put 'calcFunc-polint 'math-expandable t)
  1622. X
  1623. X
  1624. (defun calcFunc-ratint (data x)
  1625. X  (or (math-matrixp data) (math-reject-arg data 'matrixp))
  1626. X  (or (= (length data) 3)
  1627. X      (math-reject-arg data "*Wrong number of data rows"))
  1628. X  (or (> (length (nth 1 data)) 2)
  1629. X      (math-reject-arg data "*Too few data points"))
  1630. X  (if (and (math-vectorp x) (or (math-constp x) math-expand-formulas))
  1631. X      (cons 'vec (mapcar (function (lambda (x) (calcFunc-ratint data x)))
  1632. X             (cdr x)))
  1633. X    (or (math-objectp x) math-expand-formulas (math-reject-arg x 'objectp))
  1634. X    (math-with-extra-prec 2
  1635. X      (cons 'vec (math-poly-interp (cdr (nth 1 data)) (cdr (nth 2 data)) x
  1636. X                   (cdr (cdr (cdr (nth 1 data))))))))
  1637. )
  1638. (put 'calcFunc-ratint 'math-expandable t)
  1639. X
  1640. X
  1641. (defun math-poly-interp (xa ya x ratp)
  1642. X  (let ((n (length xa))
  1643. X    (dif nil)
  1644. X    (ns nil)
  1645. X    (xax nil)
  1646. X    (c (copy-sequence ya))
  1647. X    (d (copy-sequence ya))
  1648. X    (i 0)
  1649. X    (m 0)
  1650. X    y dy (xp xa) xpm cp dp temp)
  1651. X    (while (<= (setq i (1+ i)) n)
  1652. X      (setq xax (cons (math-sub (car xp) x) xax)
  1653. X        xp (cdr xp)
  1654. X        temp (math-abs (car xax)))
  1655. X      (if (or (null dif) (math-lessp temp dif))
  1656. X      (setq dif temp
  1657. X        ns i)))
  1658. X    (setq xax (nreverse xax)
  1659. X      ns (1- ns)
  1660. X      y (nth ns ya))
  1661. X    (if (math-zerop dif)
  1662. X    (list y 0)
  1663. X      (while (< (setq m (1+ m)) n)
  1664. X    (setq i 0
  1665. X          xp xax
  1666. X          xpm (nthcdr m xax)
  1667. X          cp c
  1668. X          dp d)
  1669. X    (while (<= (setq i (1+ i)) (- n m))
  1670. X      (if ratp
  1671. X          (let ((t2 (math-div (math-mul (car xp) (car dp)) (car xpm))))
  1672. X        (setq temp (math-div (math-sub (nth 1 cp) (car dp))
  1673. X                     (math-sub t2 (nth 1 cp))))
  1674. X        (setcar dp (math-mul (nth 1 cp) temp))
  1675. X        (setcar cp (math-mul t2 temp)))
  1676. X        (if (math-equal (car xp) (car xpm))
  1677. X        (math-reject-arg (cons 'vec xa) "*Duplicate X values"))
  1678. X        (setq temp (math-div (math-sub (nth 1 cp) (car dp))
  1679. X                 (math-sub (car xp) (car xpm))))
  1680. X        (setcar dp (math-mul (car xpm) temp))
  1681. X        (setcar cp (math-mul (car xp) temp)))
  1682. X      (setq cp (cdr cp)
  1683. X        dp (cdr dp)
  1684. X        xp (cdr xp)
  1685. X        xpm (cdr xpm)))
  1686. X    (if (< (+ ns ns) (- n m))
  1687. X        (setq dy (nth ns c))
  1688. X      (setq ns (1- ns)
  1689. X        dy (nth ns d)))
  1690. X    (setq y (math-add y dy)))
  1691. X      (list y dy)))
  1692. )
  1693. X
  1694. X
  1695. X
  1696. ;;; The following algorithms come from Numerical Recipes, chapter 4.
  1697. X
  1698. (defun calcFunc-ninteg (expr var lo hi)
  1699. X  (setq lo (math-evaluate-expr lo)
  1700. X    hi (math-evaluate-expr hi))
  1701. X  (or (math-numberp lo) (math-infinitep lo) (math-reject-arg lo 'numberp))
  1702. X  (or (math-numberp hi) (math-infinitep hi) (math-reject-arg hi 'numberp))
  1703. X  (if (math-lessp hi lo)
  1704. X      (math-neg (calcFunc-ninteg expr var hi lo))
  1705. X    (setq expr (math-expr-subst expr var '(var DUMMY var-DUMMY)))
  1706. X    (let ((var-DUMMY nil)
  1707. X      (calc-symbolic-mode nil)
  1708. X      (calc-prefer-frac nil)
  1709. X      (sum 0))
  1710. X      (setq expr (math-evaluate-expr expr))
  1711. X      (if (equal lo '(neg (var inf var-inf)))
  1712. X      (let ((thi (if (math-lessp hi '(float -2 0))
  1713. X             hi '(float -2 0))))
  1714. X        (setq sum (math-ninteg-romberg
  1715. X               'math-ninteg-midpoint expr
  1716. X             (math-float lo) (math-float thi) 'inf)
  1717. X          lo thi)))
  1718. X      (if (equal hi '(var inf var-inf))
  1719. X      (let ((tlo (if (math-lessp '(float 2 0) lo)
  1720. X             lo '(float 2 0))))
  1721. X        (setq sum (math-add sum
  1722. X                (math-ninteg-romberg
  1723. X                 'math-ninteg-midpoint expr
  1724. SHAR_EOF
  1725. true || echo 'restore of calc-alg-3.el failed'
  1726. fi
  1727. echo 'End of  part 6'
  1728. echo 'File calc-alg-3.el is continued in part 7'
  1729. echo 7 > _shar_seq_.tmp
  1730. exit 0
  1731. exit 0 # Just in case...
  1732. -- 
  1733. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1734. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1735. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1736. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1737.