Mercurial > emacs
comparison lisp/calc/calcalg2.el @ 41047:73f364fd8aaa
Style cleanup; don't put closing parens on their
own line, add "foo.el ends here" to each file, and update
copyright date.
author | Colin Walters <walters@gnu.org> |
---|---|
date | Wed, 14 Nov 2001 09:09:09 +0000 |
parents | 2fb9d407ae73 |
children | fcd507927105 |
comparison
equal
deleted
inserted
replaced
41046:14b73d89514a | 41047:73f364fd8aaa |
---|---|
1 ;; Calculator for GNU Emacs, part II [calc-alg-2.el] | 1 ;; Calculator for GNU Emacs, part II [calc-alg-2.el] |
2 ;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc. |
3 ;; Written by Dave Gillespie, daveg@synaptics.com. | 3 ;; Written by Dave Gillespie, daveg@synaptics.com. |
4 | 4 |
5 ;; This file is part of GNU Emacs. | 5 ;; This file is part of GNU Emacs. |
6 | 6 |
7 ;; GNU Emacs is distributed in the hope that it will be useful, | 7 ;; GNU Emacs is distributed in the hope that it will be useful, |
44 (error "Bad format in expression: %s" (nth 1 var))) | 44 (error "Bad format in expression: %s" (nth 1 var))) |
45 (setq n 1 | 45 (setq n 1 |
46 expr (calc-top-n 1))) | 46 expr (calc-top-n 1))) |
47 (while (>= (setq num (1- num)) 0) | 47 (while (>= (setq num (1- num)) 0) |
48 (setq expr (list func expr var))) | 48 (setq expr (list func expr var))) |
49 (calc-enter-result n "derv" expr))) | 49 (calc-enter-result n "derv" expr)))) |
50 ) | |
51 | 50 |
52 (defun calc-integral (var) | 51 (defun calc-integral (var) |
53 (interactive "sIntegration variable: ") | 52 (interactive "sIntegration variable: ") |
54 (calc-slow-wrapper | 53 (calc-slow-wrapper |
55 (if (or (equal var "") (equal var "$")) | 54 (if (or (equal var "") (equal var "$")) |
59 (let ((var (math-read-expr var))) | 58 (let ((var (math-read-expr var))) |
60 (if (eq (car-safe var) 'error) | 59 (if (eq (car-safe var) 'error) |
61 (error "Bad format in expression: %s" (nth 1 var))) | 60 (error "Bad format in expression: %s" (nth 1 var))) |
62 (calc-enter-result 1 "intg" (list 'calcFunc-integ | 61 (calc-enter-result 1 "intg" (list 'calcFunc-integ |
63 (calc-top-n 1) | 62 (calc-top-n 1) |
64 var))))) | 63 var)))))) |
65 ) | |
66 | 64 |
67 (defun calc-num-integral (&optional varname lowname highname) | 65 (defun calc-num-integral (&optional varname lowname highname) |
68 (interactive "sIntegration variable: ") | 66 (interactive "sIntegration variable: ") |
69 (calc-tabular-command 'calcFunc-ninteg "Integration" "nint" | 67 (calc-tabular-command 'calcFunc-ninteg "Integration" "nint" |
70 nil varname lowname highname) | 68 nil varname lowname highname)) |
71 ) | |
72 | 69 |
73 (defun calc-summation (arg &optional varname lowname highname) | 70 (defun calc-summation (arg &optional varname lowname highname) |
74 (interactive "P\nsSummation variable: ") | 71 (interactive "P\nsSummation variable: ") |
75 (calc-tabular-command 'calcFunc-sum "Summation" "sum" | 72 (calc-tabular-command 'calcFunc-sum "Summation" "sum" |
76 arg varname lowname highname) | 73 arg varname lowname highname)) |
77 ) | |
78 | 74 |
79 (defun calc-alt-summation (arg &optional varname lowname highname) | 75 (defun calc-alt-summation (arg &optional varname lowname highname) |
80 (interactive "P\nsSummation variable: ") | 76 (interactive "P\nsSummation variable: ") |
81 (calc-tabular-command 'calcFunc-asum "Summation" "asum" | 77 (calc-tabular-command 'calcFunc-asum "Summation" "asum" |
82 arg varname lowname highname) | 78 arg varname lowname highname)) |
83 ) | |
84 | 79 |
85 (defun calc-product (arg &optional varname lowname highname) | 80 (defun calc-product (arg &optional varname lowname highname) |
86 (interactive "P\nsIndex variable: ") | 81 (interactive "P\nsIndex variable: ") |
87 (calc-tabular-command 'calcFunc-prod "Index" "prod" | 82 (calc-tabular-command 'calcFunc-prod "Index" "prod" |
88 arg varname lowname highname) | 83 arg varname lowname highname)) |
89 ) | |
90 | 84 |
91 (defun calc-tabulate (arg &optional varname lowname highname) | 85 (defun calc-tabulate (arg &optional varname lowname highname) |
92 (interactive "P\nsIndex variable: ") | 86 (interactive "P\nsIndex variable: ") |
93 (calc-tabular-command 'calcFunc-table "Index" "tabl" | 87 (calc-tabular-command 'calcFunc-table "Index" "tabl" |
94 arg varname lowname highname) | 88 arg varname lowname highname)) |
95 ) | |
96 | 89 |
97 (defun calc-tabular-command (func prompt prefix arg varname lowname highname) | 90 (defun calc-tabular-command (func prompt prefix arg varname lowname highname) |
98 (calc-slow-wrapper | 91 (calc-slow-wrapper |
99 (let (var (low nil) (high nil) (step nil) stepname stepnum (num 1) expr) | 92 (let (var (low nil) (high nil) (step nil) stepname stepnum (num 1) expr) |
100 (if (consp arg) | 93 (if (consp arg) |
148 (setq step (calc-top-n 1)) | 141 (setq step (calc-top-n 1)) |
149 (if arg | 142 (if arg |
150 (setq step (prefix-numeric-value arg))))) | 143 (setq step (prefix-numeric-value arg))))) |
151 (setq expr (calc-top-n num)) | 144 (setq expr (calc-top-n num)) |
152 (calc-enter-result num prefix (append (list func expr var low high) | 145 (calc-enter-result num prefix (append (list func expr var low high) |
153 (and step (list step)))))) | 146 (and step (list step))))))) |
154 ) | |
155 | 147 |
156 (defun calc-solve-for (var) | 148 (defun calc-solve-for (var) |
157 (interactive "sVariable to solve for: ") | 149 (interactive "sVariable to solve for: ") |
158 (calc-slow-wrapper | 150 (calc-slow-wrapper |
159 (let ((func (if (calc-is-inverse) | 151 (let ((func (if (calc-is-inverse) |
169 (math-read-expr var)))) | 161 (math-read-expr var)))) |
170 (if (eq (car-safe var) 'error) | 162 (if (eq (car-safe var) 'error) |
171 (error "Bad format in expression: %s" (nth 1 var))) | 163 (error "Bad format in expression: %s" (nth 1 var))) |
172 (calc-enter-result 1 "solv" (list func | 164 (calc-enter-result 1 "solv" (list func |
173 (calc-top-n 1) | 165 (calc-top-n 1) |
174 var)))))) | 166 var))))))) |
175 ) | |
176 | 167 |
177 (defun calc-poly-roots (var) | 168 (defun calc-poly-roots (var) |
178 (interactive "sVariable to solve for: ") | 169 (interactive "sVariable to solve for: ") |
179 (calc-slow-wrapper | 170 (calc-slow-wrapper |
180 (if (or (equal var "") (equal var "$")) | 171 (if (or (equal var "") (equal var "$")) |
187 (math-read-expr var)))) | 178 (math-read-expr var)))) |
188 (if (eq (car-safe var) 'error) | 179 (if (eq (car-safe var) 'error) |
189 (error "Bad format in expression: %s" (nth 1 var))) | 180 (error "Bad format in expression: %s" (nth 1 var))) |
190 (calc-enter-result 1 "prts" (list 'calcFunc-roots | 181 (calc-enter-result 1 "prts" (list 'calcFunc-roots |
191 (calc-top-n 1) | 182 (calc-top-n 1) |
192 var))))) | 183 var)))))) |
193 ) | |
194 | 184 |
195 (defun calc-taylor (var nterms) | 185 (defun calc-taylor (var nterms) |
196 (interactive "sTaylor expansion variable: \nNNumber of terms: ") | 186 (interactive "sTaylor expansion variable: \nNNumber of terms: ") |
197 (calc-slow-wrapper | 187 (calc-slow-wrapper |
198 (let ((var (math-read-expr var))) | 188 (let ((var (math-read-expr var))) |
199 (if (eq (car-safe var) 'error) | 189 (if (eq (car-safe var) 'error) |
200 (error "Bad format in expression: %s" (nth 1 var))) | 190 (error "Bad format in expression: %s" (nth 1 var))) |
201 (calc-enter-result 1 "tylr" (list 'calcFunc-taylor | 191 (calc-enter-result 1 "tylr" (list 'calcFunc-taylor |
202 (calc-top-n 1) | 192 (calc-top-n 1) |
203 var | 193 var |
204 (prefix-numeric-value nterms))))) | 194 (prefix-numeric-value nterms)))))) |
205 ) | |
206 | 195 |
207 | 196 |
208 (defun math-derivative (expr) ; uses global values: deriv-var, deriv-total. | 197 (defun math-derivative (expr) ; uses global values: deriv-var, deriv-total. |
209 (cond ((equal expr deriv-var) | 198 (cond ((equal expr deriv-var) |
210 1) | 199 1) |
330 (not (get func | 319 (not (get func |
331 'calc-user-defn))) | 320 'calc-user-defn))) |
332 (throw 'math-deriv nil) | 321 (throw 'math-deriv nil) |
333 (cons func (cdr expr)))))))))) | 322 (cons func (cdr expr)))))))))) |
334 (setq n (1+ n))) | 323 (setq n (1+ n))) |
335 accum))))) | 324 accum)))))) |
336 ) | |
337 | 325 |
338 (defun calcFunc-deriv (expr deriv-var &optional deriv-value deriv-symb) | 326 (defun calcFunc-deriv (expr deriv-var &optional deriv-value deriv-symb) |
339 (let* ((deriv-total nil) | 327 (let* ((deriv-total nil) |
340 (res (catch 'math-deriv (math-derivative expr)))) | 328 (res (catch 'math-deriv (math-derivative expr)))) |
341 (or (eq (car-safe res) 'calcFunc-deriv) | 329 (or (eq (car-safe res) 'calcFunc-deriv) |
342 (null res) | 330 (null res) |
343 (setq res (math-normalize res))) | 331 (setq res (math-normalize res))) |
344 (and res | 332 (and res |
345 (if deriv-value | 333 (if deriv-value |
346 (math-expr-subst res deriv-var deriv-value) | 334 (math-expr-subst res deriv-var deriv-value) |
347 res))) | 335 res)))) |
348 ) | |
349 | 336 |
350 (defun calcFunc-tderiv (expr deriv-var &optional deriv-value deriv-symb) | 337 (defun calcFunc-tderiv (expr deriv-var &optional deriv-value deriv-symb) |
351 (math-setup-declarations) | 338 (math-setup-declarations) |
352 (let* ((deriv-total t) | 339 (let* ((deriv-total t) |
353 (res (catch 'math-deriv (math-derivative expr)))) | 340 (res (catch 'math-deriv (math-derivative expr)))) |
355 (null res) | 342 (null res) |
356 (setq res (math-normalize res))) | 343 (setq res (math-normalize res))) |
357 (and res | 344 (and res |
358 (if deriv-value | 345 (if deriv-value |
359 (math-expr-subst res deriv-var deriv-value) | 346 (math-expr-subst res deriv-var deriv-value) |
360 res))) | 347 res)))) |
361 ) | |
362 | 348 |
363 (put 'calcFunc-inv\' 'math-derivative-1 | 349 (put 'calcFunc-inv\' 'math-derivative-1 |
364 (function (lambda (u) (math-neg (math-div 1 (math-sqr u)))))) | 350 (function (lambda (u) (math-neg (math-div 1 (math-sqr u)))))) |
365 | 351 |
366 (put 'calcFunc-sqrt\' 'math-derivative-1 | 352 (put 'calcFunc-sqrt\' 'math-derivative-1 |
490 a))))))) | 476 a))))))) |
491 | 477 |
492 (defun math-deriv-gamma (a x scale) | 478 (defun math-deriv-gamma (a x scale) |
493 (math-mul scale | 479 (math-mul scale |
494 (math-mul (math-pow x (math-add a -1)) | 480 (math-mul (math-pow x (math-add a -1)) |
495 (list 'calcFunc-exp (math-neg x)))) | 481 (list 'calcFunc-exp (math-neg x))))) |
496 ) | |
497 | 482 |
498 (put 'calcFunc-betaB\' 'math-derivative-3 | 483 (put 'calcFunc-betaB\' 'math-derivative-3 |
499 (function (lambda (x a b) (math-deriv-beta x a b 1)))) | 484 (function (lambda (x a b) (math-deriv-beta x a b 1)))) |
500 | 485 |
501 (put 'calcFunc-betaI\' 'math-derivative-3 | 486 (put 'calcFunc-betaI\' 'math-derivative-3 |
505 a b)))))) | 490 a b)))))) |
506 | 491 |
507 (defun math-deriv-beta (x a b scale) | 492 (defun math-deriv-beta (x a b scale) |
508 (math-mul (math-mul (math-pow x (math-add a -1)) | 493 (math-mul (math-mul (math-pow x (math-add a -1)) |
509 (math-pow (math-sub 1 x) (math-add b -1))) | 494 (math-pow (math-sub 1 x) (math-add b -1))) |
510 scale) | 495 scale)) |
511 ) | |
512 | 496 |
513 (put 'calcFunc-erf\' 'math-derivative-1 | 497 (put 'calcFunc-erf\' 'math-derivative-1 |
514 (function (lambda (x) (math-div 2 | 498 (function (lambda (x) (math-div 2 |
515 (math-mul (list 'calcFunc-exp | 499 (math-mul (list 'calcFunc-exp |
516 (math-sqr x)) | 500 (math-sqr x)) |
630 (format "%2d " math-integ-depth) | 614 (format "%2d " math-integ-depth) |
631 (make-string math-integ-level 32))) | 615 (make-string math-integ-level 32))) |
632 ;;(list 'condition-case 'err | 616 ;;(list 'condition-case 'err |
633 (cons 'insert parts) | 617 (cons 'insert parts) |
634 ;; '(error (insert (prin1-to-string err)))) | 618 ;; '(error (insert (prin1-to-string err)))) |
635 '(sit-for 0))) | 619 '(sit-for 0)))) |
636 ) | |
637 | 620 |
638 ;;; The following wrapper caches results and avoids infinite recursion. | 621 ;;; The following wrapper caches results and avoids infinite recursion. |
639 ;;; Each cache entry is: ( A B ) Integral of A is B; | 622 ;;; Each cache entry is: ( A B ) Integral of A is B; |
640 ;;; ( A N ) Integral of A failed at level N; | 623 ;;; ( A N ) Integral of A failed at level N; |
641 ;;; ( A busy ) Currently working on integral of A; | 624 ;;; ( A busy ) Currently working on integral of A; |
722 (math-tracing-integral "Integral of " | 705 (math-tracing-integral "Integral of " |
723 (math-format-value expr 1000) | 706 (math-format-value expr 1000) |
724 " is " | 707 " is " |
725 (math-format-value val 1000) | 708 (math-format-value val 1000) |
726 "\n") | 709 "\n") |
727 val) | 710 val)) |
728 ) | |
729 (defvar math-integral-cache nil) | 711 (defvar math-integral-cache nil) |
730 (defvar math-integral-cache-state nil) | 712 (defvar math-integral-cache-state nil) |
731 | 713 |
732 (defun math-integral-contains-parts (expr) | 714 (defun math-integral-contains-parts (expr) |
733 (if (Math-primp expr) | 715 (if (Math-primp expr) |
734 (and (eq (car-safe expr) 'var) | 716 (and (eq (car-safe expr) 'var) |
735 (eq (nth 1 expr) 'PARTS) | 717 (eq (nth 1 expr) 'PARTS) |
736 (listp (nth 2 expr))) | 718 (listp (nth 2 expr))) |
737 (while (and (setq expr (cdr expr)) | 719 (while (and (setq expr (cdr expr)) |
738 (not (math-integral-contains-parts (car expr))))) | 720 (not (math-integral-contains-parts (car expr))))) |
739 expr) | 721 expr)) |
740 ) | |
741 | 722 |
742 (defun math-replace-integral-parts (expr) | 723 (defun math-replace-integral-parts (expr) |
743 (or (Math-primp expr) | 724 (or (Math-primp expr) |
744 (while (setq expr (cdr expr)) | 725 (while (setq expr (cdr expr)) |
745 (and (consp (car expr)) | 726 (and (consp (car expr)) |
749 (if (listp (nth 1 (nth 2 (car expr)))) | 730 (if (listp (nth 1 (nth 2 (car expr)))) |
750 (progn | 731 (progn |
751 (setcar expr (nth 1 (nth 2 (car expr)))) | 732 (setcar expr (nth 1 (nth 2 (car expr)))) |
752 (math-replace-integral-parts (cons 'foo expr))) | 733 (math-replace-integral-parts (cons 'foo expr))) |
753 (setcar (cdr cur-record) 'cancelled))) | 734 (setcar (cdr cur-record) 'cancelled))) |
754 (math-replace-integral-parts (car expr)))))) | 735 (math-replace-integral-parts (car expr))))))) |
755 ) | |
756 | 736 |
757 (defun math-do-integral (expr) | 737 (defun math-do-integral (expr) |
758 (let (t1 t2) | 738 (let (t1 t2) |
759 (or (cond ((not (math-expr-contains expr math-integ-var)) | 739 (or (cond ((not (math-expr-contains expr math-integ-var)) |
760 (math-mul expr math-integ-var)) | 740 (math-mul expr math-integ-var)) |
972 (math-do-integral-methods expr)) | 952 (math-do-integral-methods expr)) |
973 | 953 |
974 ;; Try expanding the function's definition. | 954 ;; Try expanding the function's definition. |
975 (let ((res (math-expand-formula expr))) | 955 (let ((res (math-expand-formula expr))) |
976 (and res | 956 (and res |
977 (math-integral res))))) | 957 (math-integral res)))))) |
978 ) | |
979 | 958 |
980 (defun math-sub-integration (expr &rest rest) | 959 (defun math-sub-integration (expr &rest rest) |
981 (or (if (or (not rest) | 960 (or (if (or (not rest) |
982 (and (< math-integ-level math-integral-limit) | 961 (and (< math-integ-level math-integral-limit) |
983 (eq (car rest) math-integ-var))) | 962 (eq (car rest) math-integ-var))) |
984 (math-integral expr) | 963 (math-integral expr) |
985 (let ((res (apply math-old-integ expr rest))) | 964 (let ((res (apply math-old-integ expr rest))) |
986 (and (or (= math-integ-level math-integral-limit) | 965 (and (or (= math-integ-level math-integral-limit) |
987 (not (math-expr-calls res 'calcFunc-integ))) | 966 (not (math-expr-calls res 'calcFunc-integ))) |
988 res))) | 967 res))) |
989 (list 'calcFunc-integfailed expr)) | 968 (list 'calcFunc-integfailed expr))) |
990 ) | |
991 | 969 |
992 (defun math-do-integral-methods (expr) | 970 (defun math-do-integral-methods (expr) |
993 (let ((so-far math-integ-var-list-list) | 971 (let ((so-far math-integ-var-list-list) |
994 rat-in) | 972 rat-in) |
995 | 973 |
1072 | 1050 |
1073 ;; Try integration by parts. | 1051 ;; Try integration by parts. |
1074 (math-integ-try-parts expr) | 1052 (math-integ-try-parts expr) |
1075 | 1053 |
1076 ;; Give up. | 1054 ;; Give up. |
1077 nil)) | 1055 nil))) |
1078 ) | |
1079 | 1056 |
1080 (defun math-integ-parts-easy (expr) | 1057 (defun math-integ-parts-easy (expr) |
1081 (cond ((Math-primp expr) t) | 1058 (cond ((Math-primp expr) t) |
1082 ((memq (car expr) '(+ - *)) | 1059 ((memq (car expr) '(+ - *)) |
1083 (and (math-integ-parts-easy (nth 1 expr)) | 1060 (and (math-integ-parts-easy (nth 1 expr)) |
1088 ((eq (car expr) '^) | 1065 ((eq (car expr) '^) |
1089 (and (natnump (nth 2 expr)) | 1066 (and (natnump (nth 2 expr)) |
1090 (math-integ-parts-easy (nth 1 expr)))) | 1067 (math-integ-parts-easy (nth 1 expr)))) |
1091 ((eq (car expr) 'neg) | 1068 ((eq (car expr) 'neg) |
1092 (math-integ-parts-easy (nth 1 expr))) | 1069 (math-integ-parts-easy (nth 1 expr))) |
1093 (t t)) | 1070 (t t))) |
1094 ) | |
1095 | 1071 |
1096 (defun math-integ-try-parts (expr &optional math-good-parts) | 1072 (defun math-integ-try-parts (expr &optional math-good-parts) |
1097 ;; Integration by parts: | 1073 ;; Integration by parts: |
1098 ;; integ(f(x) g(x),x) = f(x) h(x) - integ(h(x) f'(x),x) | 1074 ;; integ(f(x) g(x),x) = f(x) h(x) - integ(h(x) f'(x),x) |
1099 ;; where h(x) = integ(g(x),x). | 1075 ;; where h(x) = integ(g(x),x). |
1115 (or (math-integrate-by-parts (nth 1 expr) recip) | 1091 (or (math-integrate-by-parts (nth 1 expr) recip) |
1116 (math-integrate-by-parts recip (nth 1 expr))))) | 1092 (math-integrate-by-parts recip (nth 1 expr))))) |
1117 (and (eq (car expr) '^) | 1093 (and (eq (car expr) '^) |
1118 (math-integrate-by-parts (math-pow (nth 1 expr) | 1094 (math-integrate-by-parts (math-pow (nth 1 expr) |
1119 (math-sub (nth 2 expr) 1)) | 1095 (math-sub (nth 2 expr) 1)) |
1120 (nth 1 expr)))) | 1096 (nth 1 expr))))) |
1121 ) | |
1122 | 1097 |
1123 (defun math-integrate-by-parts (u vprime) | 1098 (defun math-integrate-by-parts (u vprime) |
1124 (let ((math-integ-level (if (or math-good-parts | 1099 (let ((math-integ-level (if (or math-good-parts |
1125 (math-polynomial-p u math-integ-var)) | 1100 (math-polynomial-p u math-integ-var)) |
1126 math-integ-level | 1101 math-integ-level |
1147 var-thing (list 'vec (math-sub v temp) v) | 1122 var-thing (list 'vec (math-sub v temp) v) |
1148 temp (let (calc-next-why) | 1123 temp (let (calc-next-why) |
1149 (math-solve-for (math-sub v temp) 0 v nil))) | 1124 (math-solve-for (math-sub v temp) 0 v nil))) |
1150 (and temp (not (integerp temp)) | 1125 (and temp (not (integerp temp)) |
1151 (math-simplify-extended temp))))) | 1126 (math-simplify-extended temp))))) |
1152 (setcar (cdr cur-record) 'busy)))) | 1127 (setcar (cdr cur-record) 'busy))))) |
1153 ) | |
1154 | 1128 |
1155 ;;; This tries two different formulations, hoping the algebraic simplifier | 1129 ;;; This tries two different formulations, hoping the algebraic simplifier |
1156 ;;; will be strong enough to handle at least one. | 1130 ;;; will be strong enough to handle at least one. |
1157 (defun math-integrate-by-substitution (expr u &optional user uinv uinvprime) | 1131 (defun math-integrate-by-substitution (expr u &optional user uinv uinvprime) |
1158 (and (> math-integ-level 0) | 1132 (and (> math-integ-level 0) |
1159 (let ((math-integ-level (max (- math-integ-level 2) 0))) | 1133 (let ((math-integ-level (max (- math-integ-level 2) 0))) |
1160 (math-integrate-by-good-substitution expr u user uinv uinvprime))) | 1134 (math-integrate-by-good-substitution expr u user uinv uinvprime)))) |
1161 ) | |
1162 | 1135 |
1163 (defun math-integrate-by-good-substitution (expr u &optional user | 1136 (defun math-integrate-by-good-substitution (expr u &optional user |
1164 uinv uinvprime) | 1137 uinv uinvprime) |
1165 (let ((math-living-dangerously t) | 1138 (let ((math-living-dangerously t) |
1166 deriv temp) | 1139 deriv temp) |
1206 math-integ-var-2 | 1179 math-integ-var-2 |
1207 math-integ-var) | 1180 math-integ-var) |
1208 deriv) | 1181 deriv) |
1209 'yes))))) | 1182 'yes))))) |
1210 (math-simplify-extended | 1183 (math-simplify-extended |
1211 (math-expr-subst temp math-integ-var u)))) | 1184 (math-expr-subst temp math-integ-var u))))) |
1212 ) | |
1213 | 1185 |
1214 ;;; Look for substitutions of the form u = a x + b. | 1186 ;;; Look for substitutions of the form u = a x + b. |
1215 (defun math-integ-try-linear-substitutions (sub-expr) | 1187 (defun math-integ-try-linear-substitutions (sub-expr) |
1216 (and (not (Math-primp sub-expr)) | 1188 (and (not (Math-primp sub-expr)) |
1217 (or (and (not (memq (car sub-expr) '(+ - * / neg))) | 1189 (or (and (not (memq (car sub-expr) '(+ - * / neg))) |
1232 res)) | 1204 res)) |
1233 (let ((res nil)) | 1205 (let ((res nil)) |
1234 (while (and (setq sub-expr (cdr sub-expr)) | 1206 (while (and (setq sub-expr (cdr sub-expr)) |
1235 (not (setq res (math-integ-try-linear-substitutions | 1207 (not (setq res (math-integ-try-linear-substitutions |
1236 (car sub-expr)))))) | 1208 (car sub-expr)))))) |
1237 res))) | 1209 res)))) |
1238 ) | |
1239 | 1210 |
1240 ;;; Recursively try different substitutions based on various sub-expressions. | 1211 ;;; Recursively try different substitutions based on various sub-expressions. |
1241 (defun math-integ-try-substitutions (sub-expr &optional allow-rat) | 1212 (defun math-integ-try-substitutions (sub-expr &optional allow-rat) |
1242 (and (not (Math-primp sub-expr)) | 1213 (and (not (Math-primp sub-expr)) |
1243 (not (assoc sub-expr so-far)) | 1214 (not (assoc sub-expr so-far)) |
1258 (let ((res nil)) | 1229 (let ((res nil)) |
1259 (setq so-far (cons (list sub-expr) so-far)) | 1230 (setq so-far (cons (list sub-expr) so-far)) |
1260 (while (and (setq sub-expr (cdr sub-expr)) | 1231 (while (and (setq sub-expr (cdr sub-expr)) |
1261 (not (setq res (math-integ-try-substitutions | 1232 (not (setq res (math-integ-try-substitutions |
1262 (car sub-expr) allow-rat))))) | 1233 (car sub-expr) allow-rat))))) |
1263 res))) | 1234 res)))) |
1264 ) | |
1265 | 1235 |
1266 (defun math-expr-rational-in (expr) | 1236 (defun math-expr-rational-in (expr) |
1267 (let ((parts nil)) | 1237 (let ((parts nil)) |
1268 (math-expr-rational-in-rec expr) | 1238 (math-expr-rational-in-rec expr) |
1269 (mapcar 'car parts)) | 1239 (mapcar 'car parts))) |
1270 ) | |
1271 | 1240 |
1272 (defun math-expr-rational-in-rec (expr) | 1241 (defun math-expr-rational-in-rec (expr) |
1273 (cond ((Math-primp expr) | 1242 (cond ((Math-primp expr) |
1274 (and (equal expr math-integ-var) | 1243 (and (equal expr math-integ-var) |
1275 (not (assoc expr parts)) | 1244 (not (assoc expr parts)) |
1282 (eq (math-quarter-integer (nth 2 expr)) 2)) | 1251 (eq (math-quarter-integer (nth 2 expr)) 2)) |
1283 (math-expr-rational-in-rec (list 'calcFunc-sqrt (nth 1 expr)))) | 1252 (math-expr-rational-in-rec (list 'calcFunc-sqrt (nth 1 expr)))) |
1284 (t | 1253 (t |
1285 (and (not (assoc expr parts)) | 1254 (and (not (assoc expr parts)) |
1286 (math-expr-contains expr math-integ-var) | 1255 (math-expr-contains expr math-integ-var) |
1287 (setq parts (cons (list expr) parts))))) | 1256 (setq parts (cons (list expr) parts)))))) |
1288 ) | |
1289 | 1257 |
1290 (defun math-expr-calls (expr funcs &optional arg-contains) | 1258 (defun math-expr-calls (expr funcs &optional arg-contains) |
1291 (if (consp expr) | 1259 (if (consp expr) |
1292 (if (or (memq (car expr) funcs) | 1260 (if (or (memq (car expr) funcs) |
1293 (and (eq (car expr) '^) (eq (car funcs) 'calcFunc-sqrt) | 1261 (and (eq (car expr) '^) (eq (car funcs) 'calcFunc-sqrt) |
1298 (and (not (Math-primp expr)) | 1266 (and (not (Math-primp expr)) |
1299 (let ((res nil)) | 1267 (let ((res nil)) |
1300 (while (and (setq expr (cdr expr)) | 1268 (while (and (setq expr (cdr expr)) |
1301 (not (setq res (math-expr-calls | 1269 (not (setq res (math-expr-calls |
1302 (car expr) funcs arg-contains))))) | 1270 (car expr) funcs arg-contains))))) |
1303 res)))) | 1271 res))))) |
1304 ) | |
1305 | 1272 |
1306 (defun math-fix-const-terms (expr except-vars) | 1273 (defun math-fix-const-terms (expr except-vars) |
1307 (cond ((not (math-expr-depends expr except-vars)) 0) | 1274 (cond ((not (math-expr-depends expr except-vars)) 0) |
1308 ((Math-primp expr) expr) | 1275 ((Math-primp expr) expr) |
1309 ((eq (car expr) '+) | 1276 ((eq (car expr) '+) |
1310 (math-add (math-fix-const-terms (nth 1 expr) except-vars) | 1277 (math-add (math-fix-const-terms (nth 1 expr) except-vars) |
1311 (math-fix-const-terms (nth 2 expr) except-vars))) | 1278 (math-fix-const-terms (nth 2 expr) except-vars))) |
1312 ((eq (car expr) '-) | 1279 ((eq (car expr) '-) |
1313 (math-sub (math-fix-const-terms (nth 1 expr) except-vars) | 1280 (math-sub (math-fix-const-terms (nth 1 expr) except-vars) |
1314 (math-fix-const-terms (nth 2 expr) except-vars))) | 1281 (math-fix-const-terms (nth 2 expr) except-vars))) |
1315 (t expr)) | 1282 (t expr))) |
1316 ) | |
1317 | 1283 |
1318 ;; Command for debugging the Calculator's symbolic integrator. | 1284 ;; Command for debugging the Calculator's symbolic integrator. |
1319 (defun calc-dump-integral-cache (&optional arg) | 1285 (defun calc-dump-integral-cache (&optional arg) |
1320 (interactive "P") | 1286 (interactive "P") |
1321 (let ((buf (current-buffer))) | 1287 (let ((buf (current-buffer))) |
1334 (concat "(" (symbol-name (nth 1 cur-record)) ")") | 1300 (concat "(" (symbol-name (nth 1 cur-record)) ")") |
1335 (math-format-flat-expr (nth 1 cur-record) 0)) | 1301 (math-format-flat-expr (nth 1 cur-record) 0)) |
1336 "\n") | 1302 "\n") |
1337 (setq p (cdr p))) | 1303 (setq p (cdr p))) |
1338 (goto-char (point-min))) | 1304 (goto-char (point-min))) |
1339 (set-buffer buf))) | 1305 (set-buffer buf)))) |
1340 ) | |
1341 | 1306 |
1342 (defun math-try-integral (expr) | 1307 (defun math-try-integral (expr) |
1343 (let ((math-integ-level math-integral-limit) | 1308 (let ((math-integ-level math-integral-limit) |
1344 (math-integ-depth 0) | 1309 (math-integ-depth 0) |
1345 (math-integ-msg "Working...done") | 1310 (math-integ-msg "Working...done") |
1353 (setq math-enable-subst t) | 1318 (setq math-enable-subst t) |
1354 (math-integral expr 'yes)) | 1319 (math-integral expr 'yes)) |
1355 (and (> math-max-integral-limit math-integral-limit) | 1320 (and (> math-max-integral-limit math-integral-limit) |
1356 (setq math-integral-limit math-max-integral-limit | 1321 (setq math-integral-limit math-max-integral-limit |
1357 math-integ-level math-integral-limit) | 1322 math-integ-level math-integral-limit) |
1358 (math-integral expr 'yes)))) | 1323 (math-integral expr 'yes))))) |
1359 ) | |
1360 | 1324 |
1361 (defun calcFunc-integ (expr var &optional low high) | 1325 (defun calcFunc-integ (expr var &optional low high) |
1362 (cond | 1326 (cond |
1363 ;; Do these even if the parts turn out not to be integrable. | 1327 ;; Do these even if the parts turn out not to be integrable. |
1364 ((eq (car-safe expr) '+) | 1328 ((eq (car-safe expr) '+) |
1466 (if low | 1430 (if low |
1467 (math-expr-subst res math-integ-var low) | 1431 (math-expr-subst res math-integ-var low) |
1468 (math-expr-subst res math-integ-var var))))) | 1432 (math-expr-subst res math-integ-var var))))) |
1469 (append (list 'calcFunc-integ expr var) | 1433 (append (list 'calcFunc-integ expr var) |
1470 (and low (list low)) | 1434 (and low (list low)) |
1471 (and high (list high))))))) | 1435 (and high (list high)))))))) |
1472 ) | |
1473 | 1436 |
1474 | 1437 |
1475 (math-defintegral calcFunc-inv | 1438 (math-defintegral calcFunc-inv |
1476 (math-integral (math-div 1 u))) | 1439 (math-integral (math-div 1 u))) |
1477 | 1440 |
1680 (math-add (math-mul b math-integ-var) | 1643 (math-add (math-mul b math-integ-var) |
1681 (math-mul 2 a)) | 1644 (math-mul 2 a)) |
1682 (math-mul n (math-mul q (math-pow v n))))) | 1645 (math-mul n (math-mul q (math-pow v n))))) |
1683 (math-mul-thru (math-div (math-mul b (1- (* 2 n))) | 1646 (math-mul-thru (math-div (math-mul b (1- (* 2 n))) |
1684 (math-mul n q)) | 1647 (math-mul n q)) |
1685 (math-integral-q02 a b c v n))))))) | 1648 (math-integral-q02 a b c v n)))))))) |
1686 ) | |
1687 | 1649 |
1688 (defun math-integral-q02 (a b c v vpow) | 1650 (defun math-integral-q02 (a b c v vpow) |
1689 (let (q rq part) | 1651 (let (q rq part) |
1690 (cond ((not c) | 1652 (cond ((not c) |
1691 (cond ((= vpow 1) | 1653 (cond ((= vpow 1) |
1720 (t | 1682 (t |
1721 (setq rq (list 'calcFunc-sqrt q)) | 1683 (setq rq (list 'calcFunc-sqrt q)) |
1722 (math-div (math-mul 2 (math-to-radians-2 | 1684 (math-div (math-mul 2 (math-to-radians-2 |
1723 (list 'calcFunc-arctan | 1685 (list 'calcFunc-arctan |
1724 (math-div part rq)))) | 1686 (math-div part rq)))) |
1725 rq)))) | 1687 rq))))) |
1726 ) | |
1727 | 1688 |
1728 | 1689 |
1729 (math-defintegral calcFunc-erf | 1690 (math-defintegral calcFunc-erf |
1730 (and (equal u math-integ-var) | 1691 (and (equal u math-integ-var) |
1731 (math-add (math-mul u (list 'calcFunc-erf u)) | 1692 (math-add (math-mul u (list 'calcFunc-erf u)) |
1796 (append (list (or math-tabulate-function 'calcFunc-table) | 1757 (append (list (or math-tabulate-function 'calcFunc-table) |
1797 expr var) | 1758 expr var) |
1798 (and (not (and (equal low '(neg (var inf var-inf))) | 1759 (and (not (and (equal low '(neg (var inf var-inf))) |
1799 (equal high '(var inf var-inf)))) | 1760 (equal high '(var inf var-inf)))) |
1800 (list low high)) | 1761 (list low high)) |
1801 (and step (list step))))) | 1762 (and step (list step)))))) |
1802 ) | |
1803 | 1763 |
1804 (setq math-tabulate-initial nil) | 1764 (setq math-tabulate-initial nil) |
1805 (setq math-tabulate-function nil) | 1765 (setq math-tabulate-function nil) |
1806 | 1766 |
1807 (defun math-scan-for-limits (x) | 1767 (defun math-scan-for-limits (x) |
1820 (setq temp low-val low-val high-val high-val temp)) | 1780 (setq temp low-val low-val high-val high-val temp)) |
1821 (setq low (math-max low (math-ceiling low-val)) | 1781 (setq low (math-max low (math-ceiling low-val)) |
1822 high (math-min high (math-floor high-val))))) | 1782 high (math-min high (math-floor high-val))))) |
1823 (t | 1783 (t |
1824 (while (setq x (cdr x)) | 1784 (while (setq x (cdr x)) |
1825 (math-scan-for-limits (car x))))) | 1785 (math-scan-for-limits (car x)))))) |
1826 ) | |
1827 | 1786 |
1828 | 1787 |
1829 (defun calcFunc-sum (expr var &optional low high step) | 1788 (defun calcFunc-sum (expr var &optional low high step) |
1830 (if math-disable-sums (math-reject-arg)) | 1789 (if math-disable-sums (math-reject-arg)) |
1831 (let* ((res (let* ((calc-internal-prec (+ calc-internal-prec 2))) | 1790 (let* ((res (let* ((calc-internal-prec (+ calc-internal-prec 2))) |
1832 (math-sum-rec expr var low high step))) | 1791 (math-sum-rec expr var low high step))) |
1833 (math-disable-sums t)) | 1792 (math-disable-sums t)) |
1834 (math-normalize res)) | 1793 (math-normalize res))) |
1835 ) | |
1836 (setq math-disable-sums nil) | 1794 (setq math-disable-sums nil) |
1837 | 1795 |
1838 (defun math-sum-rec (expr var &optional low high step) | 1796 (defun math-sum-rec (expr var &optional low high step) |
1839 (or low (setq low '(neg (var inf var-inf)) high '(var inf var-inf))) | 1797 (or low (setq low '(neg (var inf var-inf)) high '(var inf var-inf))) |
1840 (and low (not high) (setq high low low 1)) | 1798 (and low (not high) (setq high low low 1)) |
1935 (nth 2 expr))))) | 1893 (nth 2 expr))))) |
1936 (if (equal val '(var nan var-nan)) (setq val nil)) | 1894 (if (equal val '(var nan var-nan)) (setq val nil)) |
1937 (or val | 1895 (or val |
1938 (let* ((math-tabulate-initial 0) | 1896 (let* ((math-tabulate-initial 0) |
1939 (math-tabulate-function 'calcFunc-sum)) | 1897 (math-tabulate-function 'calcFunc-sum)) |
1940 (calcFunc-table expr var low high)))) | 1898 (calcFunc-table expr var low high))))) |
1941 ) | |
1942 | 1899 |
1943 (defun calcFunc-asum (expr var low &optional high step no-mul-flag) | 1900 (defun calcFunc-asum (expr var low &optional high step no-mul-flag) |
1944 (or high (setq high low low 1)) | 1901 (or high (setq high low low 1)) |
1945 (if (and step (not (math-equal-int step 1))) | 1902 (if (and step (not (math-equal-int step 1))) |
1946 (if (math-negp step) | 1903 (if (math-negp step) |
1958 low))) | 1915 low))) |
1959 var 0 | 1916 var 0 |
1960 (math-simplify (math-div (math-sub high low) | 1917 (math-simplify (math-div (math-sub high low) |
1961 step)))))) | 1918 step)))))) |
1962 (math-mul (if no-mul-flag 1 (math-pow -1 low)) | 1919 (math-mul (if no-mul-flag 1 (math-pow -1 low)) |
1963 (calcFunc-sum (math-mul (math-pow -1 var) expr) var low high))) | 1920 (calcFunc-sum (math-mul (math-pow -1 var) expr) var low high)))) |
1964 ) | |
1965 | 1921 |
1966 (defun math-sum-const-factors (expr var) | 1922 (defun math-sum-const-factors (expr var) |
1967 (let ((const nil) | 1923 (let ((const nil) |
1968 (not-const nil) | 1924 (not-const nil) |
1969 (p expr)) | 1925 (p expr)) |
1981 (setq temp (list '* (car const) temp))) | 1937 (setq temp (list '* (car const) temp))) |
1982 temp) | 1938 temp) |
1983 (let ((temp (or (car not-const) 1))) | 1939 (let ((temp (or (car not-const) 1))) |
1984 (while (setq not-const (cdr not-const)) | 1940 (while (setq not-const (cdr not-const)) |
1985 (setq temp (list '* (car not-const) temp))) | 1941 (setq temp (list '* (car not-const) temp))) |
1986 temp)))) | 1942 temp))))) |
1987 ) | |
1988 | 1943 |
1989 ;; Following is from CRC Math Tables, 27th ed, pp. 52-53. | 1944 ;; Following is from CRC Math Tables, 27th ed, pp. 52-53. |
1990 (defun math-sum-integer-power (pow) | 1945 (defun math-sum-integer-power (pow) |
1991 (let ((calc-prefer-frac t) | 1946 (let ((calc-prefer-frac t) |
1992 (n (length math-sum-int-pow-cache))) | 1947 (n (length math-sum-int-pow-cache))) |
2005 pp (cdr pp))) | 1960 pp (cdr pp))) |
2006 (setcar lin (math-sub 1 (math-mul n sum))) | 1961 (setcar lin (math-sub 1 (math-mul n sum))) |
2007 (setq math-sum-int-pow-cache | 1962 (setq math-sum-int-pow-cache |
2008 (nconc math-sum-int-pow-cache (list (nreverse new))) | 1963 (nconc math-sum-int-pow-cache (list (nreverse new))) |
2009 n (1+ n)))) | 1964 n (1+ n)))) |
2010 (nth pow math-sum-int-pow-cache)) | 1965 (nth pow math-sum-int-pow-cache))) |
2011 ) | |
2012 (setq math-sum-int-pow-cache (list '(0 1))) | 1966 (setq math-sum-int-pow-cache (list '(0 1))) |
2013 | 1967 |
2014 (defun math-to-exponentials (expr) | 1968 (defun math-to-exponentials (expr) |
2015 (and (consp expr) | 1969 (and (consp expr) |
2016 (= (length expr) 2) | 1970 (= (length expr) 2) |
2044 ((eq (car expr) 'calcFunc-cosh) | 1998 ((eq (car expr) 'calcFunc-cosh) |
2045 (list '/ (list '+ | 1999 (list '/ (list '+ |
2046 (list '^ '(var e var-e) x) | 2000 (list '^ '(var e var-e) x) |
2047 (list '^ '(var e var-e) (list 'neg x))) | 2001 (list '^ '(var e var-e) (list 'neg x))) |
2048 2)) | 2002 2)) |
2049 (t nil)))) | 2003 (t nil))))) |
2050 ) | |
2051 | 2004 |
2052 (defun math-to-exps (expr) | 2005 (defun math-to-exps (expr) |
2053 (cond (calc-symbolic-mode expr) | 2006 (cond (calc-symbolic-mode expr) |
2054 ((Math-primp expr) | 2007 ((Math-primp expr) |
2055 (if (equal expr '(var e var-e)) (math-e) expr)) | 2008 (if (equal expr '(var e var-e)) (math-e) expr)) |
2056 ((and (eq (car expr) '^) | 2009 ((and (eq (car expr) '^) |
2057 (equal (nth 1 expr) '(var e var-e))) | 2010 (equal (nth 1 expr) '(var e var-e))) |
2058 (list 'calcFunc-exp (nth 2 expr))) | 2011 (list 'calcFunc-exp (nth 2 expr))) |
2059 (t | 2012 (t |
2060 (cons (car expr) (mapcar 'math-to-exps (cdr expr))))) | 2013 (cons (car expr) (mapcar 'math-to-exps (cdr expr)))))) |
2061 ) | |
2062 | 2014 |
2063 | 2015 |
2064 (defun calcFunc-prod (expr var &optional low high step) | 2016 (defun calcFunc-prod (expr var &optional low high step) |
2065 (if math-disable-prods (math-reject-arg)) | 2017 (if math-disable-prods (math-reject-arg)) |
2066 (let* ((res (let* ((calc-internal-prec (+ calc-internal-prec 2))) | 2018 (let* ((res (let* ((calc-internal-prec (+ calc-internal-prec 2))) |
2067 (math-prod-rec expr var low high step))) | 2019 (math-prod-rec expr var low high step))) |
2068 (math-disable-prods t)) | 2020 (math-disable-prods t)) |
2069 (math-normalize res)) | 2021 (math-normalize res))) |
2070 ) | |
2071 (setq math-disable-prods nil) | 2022 (setq math-disable-prods nil) |
2072 | 2023 |
2073 (defun math-prod-rec (expr var &optional low high step) | 2024 (defun math-prod-rec (expr var &optional low high step) |
2074 (or low (setq low '(neg (var inf var-inf)) high '(var inf var-inf))) | 2025 (or low (setq low '(neg (var inf var-inf)) high '(var inf var-inf))) |
2075 (and low (not high) (setq high '(var inf var-inf))) | 2026 (and low (not high) (setq high '(var inf var-inf))) |
2207 t2))) | 2158 t2))) |
2208 (if (equal val '(var nan var-nan)) (setq val nil)) | 2159 (if (equal val '(var nan var-nan)) (setq val nil)) |
2209 (or val | 2160 (or val |
2210 (let* ((math-tabulate-initial 1) | 2161 (let* ((math-tabulate-initial 1) |
2211 (math-tabulate-function 'calcFunc-prod)) | 2162 (math-tabulate-function 'calcFunc-prod)) |
2212 (calcFunc-table expr var low high)))) | 2163 (calcFunc-table expr var low high))))) |
2213 ) | |
2214 | 2164 |
2215 | 2165 |
2216 | 2166 |
2217 | 2167 |
2218 ;;; Attempt to reduce lhs = rhs to solve-var = rhs', where solve-var appears | 2168 ;;; Attempt to reduce lhs = rhs to solve-var = rhs', where solve-var appears |
2357 t2) | 2307 t2) |
2358 ((setq t1 (math-expand-formula lhs)) | 2308 ((setq t1 (math-expand-formula lhs)) |
2359 (math-try-solve-for t1 rhs sign)) | 2309 (math-try-solve-for t1 rhs sign)) |
2360 (t | 2310 (t |
2361 (calc-record-why "*No inverse known" lhs) | 2311 (calc-record-why "*No inverse known" lhs) |
2362 nil))) | 2312 nil)))) |
2363 ) | |
2364 | 2313 |
2365 (setq math-solve-ranges nil) | 2314 (setq math-solve-ranges nil) |
2366 | 2315 |
2367 (defun math-try-solve-prod () | 2316 (defun math-try-solve-prod () |
2368 (cond ((eq (car lhs) '*) | 2317 (cond ((eq (car lhs) '*) |
2468 rhs | 2417 rhs |
2469 (nth 2 lhs)))) | 2418 (nth 2 lhs)))) |
2470 (and sign | 2419 (and sign |
2471 (math-oddp (nth 2 lhs)) | 2420 (math-oddp (nth 2 lhs)) |
2472 (math-solve-sign sign (nth 2 lhs))))))))) | 2421 (math-solve-sign sign (nth 2 lhs))))))))) |
2473 (t nil)) | 2422 (t nil))) |
2474 ) | |
2475 | 2423 |
2476 (defun math-solve-prod (lsoln rsoln) | 2424 (defun math-solve-prod (lsoln rsoln) |
2477 (cond ((null lsoln) | 2425 (cond ((null lsoln) |
2478 rsoln) | 2426 rsoln) |
2479 ((null rsoln) | 2427 ((null rsoln) |
2483 (solve-full | 2431 (solve-full |
2484 (list 'calcFunc-if | 2432 (list 'calcFunc-if |
2485 (list 'calcFunc-gt (math-solve-get-sign 1) 0) | 2433 (list 'calcFunc-gt (math-solve-get-sign 1) 0) |
2486 lsoln | 2434 lsoln |
2487 rsoln)) | 2435 rsoln)) |
2488 (t lsoln)) | 2436 (t lsoln))) |
2489 ) | |
2490 | 2437 |
2491 ;;; This deals with negative, fractional, and symbolic powers of "x". | 2438 ;;; This deals with negative, fractional, and symbolic powers of "x". |
2492 (defun math-solve-poly-funny-powers (sub-rhs) ; uses "t1", "t2" | 2439 (defun math-solve-poly-funny-powers (sub-rhs) ; uses "t1", "t2" |
2493 (setq t1 lhs) | 2440 (setq t1 lhs) |
2494 (let ((pp math-poly-neg-powers) | 2441 (let ((pp math-poly-neg-powers) |
2501 (if sub-rhs (setq t1 (math-sub t1 rhs))) | 2448 (if sub-rhs (setq t1 (math-sub t1 rhs))) |
2502 (let ((math-poly-neg-powers nil)) | 2449 (let ((math-poly-neg-powers nil)) |
2503 (setq t2 (math-mul (or math-poly-mult-powers 1) | 2450 (setq t2 (math-mul (or math-poly-mult-powers 1) |
2504 (let ((calc-prefer-frac t)) | 2451 (let ((calc-prefer-frac t)) |
2505 (math-div 1 math-poly-frac-powers))) | 2452 (math-div 1 math-poly-frac-powers))) |
2506 t1 (math-is-polynomial (math-simplify (calcFunc-expand t1)) b 50))) | 2453 t1 (math-is-polynomial (math-simplify (calcFunc-expand t1)) b 50)))) |
2507 ) | |
2508 | 2454 |
2509 ;;; This converts "a x^8 + b x^5 + c x^2" to "(a (x^3)^2 + b (x^3) + c) * x^2". | 2455 ;;; This converts "a x^8 + b x^5 + c x^2" to "(a (x^3)^2 + b (x^3) + c) * x^2". |
2510 (defun math-solve-crunch-poly (max-degree) ; uses "t1", "t3" | 2456 (defun math-solve-crunch-poly (max-degree) ; uses "t1", "t3" |
2511 (let ((count 0)) | 2457 (let ((count 0)) |
2512 (while (and t1 (Math-zerop (car t1))) | 2458 (while (and t1 (Math-zerop (car t1))) |
2531 (if okay | 2477 (if okay |
2532 (setq t3 (cons scale (cdr t3)) | 2478 (setq t3 (cons scale (cdr t3)) |
2533 t1 new-t1)))) | 2479 t1 new-t1)))) |
2534 (setq scale (1- scale))) | 2480 (setq scale (1- scale))) |
2535 (setq t3 (list (math-mul (car t3) t2) (math-mul count t2))) | 2481 (setq t3 (list (math-mul (car t3) t2) (math-mul count t2))) |
2536 (<= (1- (length t1)) max-degree)))) | 2482 (<= (1- (length t1)) max-degree))))) |
2537 ) | |
2538 | 2483 |
2539 (defun calcFunc-poly (expr var &optional degree) | 2484 (defun calcFunc-poly (expr var &optional degree) |
2540 (if degree | 2485 (if degree |
2541 (or (natnump degree) (math-reject-arg degree 'fixnatnump)) | 2486 (or (natnump degree) (math-reject-arg degree 'fixnatnump)) |
2542 (setq degree 50)) | 2487 (setq degree 50)) |
2543 (let ((p (math-is-polynomial expr var degree 'gen))) | 2488 (let ((p (math-is-polynomial expr var degree 'gen))) |
2544 (if p | 2489 (if p |
2545 (if (equal p '(0)) | 2490 (if (equal p '(0)) |
2546 (list 'vec) | 2491 (list 'vec) |
2547 (cons 'vec p)) | 2492 (cons 'vec p)) |
2548 (math-reject-arg expr "Expected a polynomial"))) | 2493 (math-reject-arg expr "Expected a polynomial")))) |
2549 ) | |
2550 | 2494 |
2551 (defun calcFunc-gpoly (expr var &optional degree) | 2495 (defun calcFunc-gpoly (expr var &optional degree) |
2552 (if degree | 2496 (if degree |
2553 (or (natnump degree) (math-reject-arg degree 'fixnatnump)) | 2497 (or (natnump degree) (math-reject-arg degree 'fixnatnump)) |
2554 (setq degree 50)) | 2498 (setq degree 50)) |
2555 (let* ((math-poly-base-variable var) | 2499 (let* ((math-poly-base-variable var) |
2556 (d (math-decompose-poly expr var degree nil))) | 2500 (d (math-decompose-poly expr var degree nil))) |
2557 (if d | 2501 (if d |
2558 (cons 'vec d) | 2502 (cons 'vec d) |
2559 (math-reject-arg expr "Expected a polynomial"))) | 2503 (math-reject-arg expr "Expected a polynomial")))) |
2560 ) | |
2561 | 2504 |
2562 (defun math-decompose-poly (lhs solve-var degree sub-rhs) | 2505 (defun math-decompose-poly (lhs solve-var degree sub-rhs) |
2563 (let ((rhs (or sub-rhs 1)) | 2506 (let ((rhs (or sub-rhs 1)) |
2564 t1 t2 t3) | 2507 t1 t2 t3) |
2565 (setq t2 (math-polynomial-base | 2508 (setq t2 (math-polynomial-base |
2587 (if t2 | 2530 (if t2 |
2588 (list (math-pow t2 (car t3)) | 2531 (list (math-pow t2 (car t3)) |
2589 (cons 'vec t1) | 2532 (cons 'vec t1) |
2590 (if sub-rhs | 2533 (if sub-rhs |
2591 (math-pow t2 (nth 1 t3)) | 2534 (math-pow t2 (nth 1 t3)) |
2592 (math-div (math-pow t2 (nth 1 t3)) rhs))))) | 2535 (math-div (math-pow t2 (nth 1 t3)) rhs)))))) |
2593 ) | |
2594 | 2536 |
2595 (defun math-solve-linear (var sign b a) | 2537 (defun math-solve-linear (var sign b a) |
2596 (math-try-solve-for var | 2538 (math-try-solve-for var |
2597 (math-div (math-neg b) a) | 2539 (math-div (math-neg b) a) |
2598 (math-solve-sign sign a) | 2540 (math-solve-sign sign a) |
2599 t) | 2541 t)) |
2600 ) | |
2601 | 2542 |
2602 (defun math-solve-quadratic (var c b a) | 2543 (defun math-solve-quadratic (var c b a) |
2603 (math-try-solve-for | 2544 (math-try-solve-for |
2604 var | 2545 var |
2605 (if (math-looks-evenp b) | 2546 (if (math-looks-evenp b) |
2620 (math-normalize | 2561 (math-normalize |
2621 (list 'calcFunc-sqrt | 2562 (list 'calcFunc-sqrt |
2622 (math-add (math-sqr b) | 2563 (math-add (math-sqr b) |
2623 (math-mul 4 (math-mul (math-neg c) a))))))) | 2564 (math-mul 4 (math-mul (math-neg c) a))))))) |
2624 (math-mul 2 a))) | 2565 (math-mul 2 a))) |
2625 nil t) | 2566 nil t)) |
2626 ) | |
2627 | 2567 |
2628 (defun math-solve-cubic (var d c b a) | 2568 (defun math-solve-cubic (var d c b a) |
2629 (let* ((p (math-div b a)) | 2569 (let* ((p (math-div b a)) |
2630 (q (math-div c a)) | 2570 (q (math-div c a)) |
2631 (r (math-div d a)) | 2571 (r (math-div d a)) |
2663 1 3)) | 2603 1 3)) |
2664 (math-half-circle | 2604 (math-half-circle |
2665 calc-symbolic-mode)))) | 2605 calc-symbolic-mode)))) |
2666 3)))) | 2606 3)))) |
2667 (math-div p 3)) | 2607 (math-div p 3)) |
2668 nil t)))) | 2608 nil t))))) |
2669 ) | |
2670 | 2609 |
2671 (defun math-solve-quartic (var d c b a aa) | 2610 (defun math-solve-quartic (var d c b a aa) |
2672 (setq a (math-div a aa)) | 2611 (setq a (math-div a aa)) |
2673 (setq b (math-div b aa)) | 2612 (setq b (math-div b aa)) |
2674 (setq c (math-div c aa)) | 2613 (setq c (math-div c aa)) |
2713 rsqr)))))) | 2652 rsqr)))))) |
2714 (math-normalize | 2653 (math-normalize |
2715 (math-sub (math-add (math-mul sign1 (math-div r 2)) | 2654 (math-sub (math-add (math-mul sign1 (math-div r 2)) |
2716 (math-solve-get-sign (math-div de 2))) | 2655 (math-solve-get-sign (math-div de 2))) |
2717 (math-div a 4)))) | 2656 (math-div a 4)))) |
2718 nil t) | 2657 nil t)) |
2719 ) | |
2720 | 2658 |
2721 (defun math-poly-all-roots (var p &optional math-factoring) | 2659 (defun math-poly-all-roots (var p &optional math-factoring) |
2722 (catch 'ouch | 2660 (catch 'ouch |
2723 (let* ((math-symbolic-solve calc-symbolic-mode) | 2661 (let* ((math-symbolic-solve calc-symbolic-mode) |
2724 (roots nil) | 2662 (roots nil) |
2809 (setq vec (math-normalize vec))) | 2747 (setq vec (math-normalize vec))) |
2810 (if (eq solve-full t) | 2748 (if (eq solve-full t) |
2811 (list 'calcFunc-subscr | 2749 (list 'calcFunc-subscr |
2812 vec | 2750 vec |
2813 (math-solve-get-int 1 (1- (length orig-p)) 1)) | 2751 (math-solve-get-int 1 (1- (length orig-p)) 1)) |
2814 vec))))) | 2752 vec)))))) |
2815 ) | |
2816 (setq math-symbolic-solve nil) | 2753 (setq math-symbolic-solve nil) |
2817 | 2754 |
2818 (defun math-lcm-denoms (&rest fracs) | 2755 (defun math-lcm-denoms (&rest fracs) |
2819 (let ((den 1)) | 2756 (let ((den 1)) |
2820 (while fracs | 2757 (while fracs |
2821 (if (eq (car-safe (car fracs)) 'frac) | 2758 (if (eq (car-safe (car fracs)) 'frac) |
2822 (setq den (calcFunc-lcm den (nth 2 (car fracs))))) | 2759 (setq den (calcFunc-lcm den (nth 2 (car fracs))))) |
2823 (setq fracs (cdr fracs))) | 2760 (setq fracs (cdr fracs))) |
2824 den) | 2761 den)) |
2825 ) | |
2826 | 2762 |
2827 (defun math-poly-any-root (p x polish) ; p is a reverse poly coeff list | 2763 (defun math-poly-any-root (p x polish) ; p is a reverse poly coeff list |
2828 (let* ((newt (if (math-zerop x) | 2764 (let* ((newt (if (math-zerop x) |
2829 (math-poly-newton-root | 2765 (math-poly-newton-root |
2830 p '(cplx (float 123 -6) (float 1 -4)) 4) | 2766 p '(cplx (float 123 -6) (float 1 -4)) 4) |
2836 (if (math-zerop (cdr newt)) | 2772 (if (math-zerop (cdr newt)) |
2837 (car newt) | 2773 (car newt) |
2838 (math-poly-laguerre-root p x polish))))) | 2774 (math-poly-laguerre-root p x polish))))) |
2839 (and math-symbolic-solve (math-floatp res) | 2775 (and math-symbolic-solve (math-floatp res) |
2840 (throw 'ouch nil)) | 2776 (throw 'ouch nil)) |
2841 res) | 2777 res)) |
2842 ) | |
2843 | 2778 |
2844 (defun math-poly-newton-root (p x iters) | 2779 (defun math-poly-newton-root (p x iters) |
2845 (let* ((calc-prefer-frac nil) | 2780 (let* ((calc-prefer-frac nil) |
2846 (calc-symbolic-mode nil) | 2781 (calc-symbolic-mode nil) |
2847 (try-integer math-int-coefs) | 2782 (try-integer math-int-coefs) |
2867 (setq try-integer nil)))))) | 2802 (setq try-integer nil)))))) |
2868 (or (not (or (eq dx 0) | 2803 (or (not (or (eq dx 0) |
2869 (math-nearly-zerop dx (math-abs-approx x)))) | 2804 (math-nearly-zerop dx (math-abs-approx x)))) |
2870 (progn (setq dx 0) nil))))) | 2805 (progn (setq dx 0) nil))))) |
2871 (cons x (if (math-zerop x) | 2806 (cons x (if (math-zerop x) |
2872 1 (math-div (math-abs-approx dx) (math-abs-approx x))))) | 2807 1 (math-div (math-abs-approx dx) (math-abs-approx x)))))) |
2873 ) | |
2874 | 2808 |
2875 (defun math-poly-integer-root (x) | 2809 (defun math-poly-integer-root (x) |
2876 (and (math-lessp (calcFunc-xpon (math-abs-approx x)) calc-internal-prec) | 2810 (and (math-lessp (calcFunc-xpon (math-abs-approx x)) calc-internal-prec) |
2877 math-int-coefs | 2811 math-int-coefs |
2878 (let* ((calc-prefer-frac t) | 2812 (let* ((calc-prefer-frac t) |
2933 math-int-factors))) | 2867 math-int-factors))) |
2934 (math-add aa | 2868 (math-add aa |
2935 (let ((calc-symbolic-mode math-symbolic-solve)) | 2869 (let ((calc-symbolic-mode math-symbolic-solve)) |
2936 (math-mul (math-sqrt (math-sub (math-sqr aa) | 2870 (math-mul (math-sqrt (math-sub (math-sqr aa) |
2937 rnd0)) | 2871 rnd0)) |
2938 (if (math-negp xim) -1 1)))))))))) | 2872 (if (math-negp xim) -1 1))))))))))) |
2939 ) | |
2940 (setq math-int-coefs nil) | 2873 (setq math-int-coefs nil) |
2941 | 2874 |
2942 ;;; The following routine is from Numerical Recipes, section 9.5. | 2875 ;;; The following routine is from Numerical Recipes, section 9.5. |
2943 (defun math-poly-laguerre-root (p x polish) | 2876 (defun math-poly-laguerre-root (p x polish) |
2944 (let* ((calc-prefer-frac nil) | 2877 (let* ((calc-prefer-frac nil) |
3016 (math-lessp (calcFunc-scf (math-abs-approx x) | 2949 (math-lessp (calcFunc-scf (math-abs-approx x) |
3017 (- calc-internal-prec)) | 2950 (- calc-internal-prec)) |
3018 dxold)))) | 2951 dxold)))) |
3019 (or (and (math-floatp x) | 2952 (or (and (math-floatp x) |
3020 (math-poly-integer-root x)) | 2953 (math-poly-integer-root x)) |
3021 x)) | 2954 x))) |
3022 ) | |
3023 | 2955 |
3024 (defun math-solve-above-dummy (x) | 2956 (defun math-solve-above-dummy (x) |
3025 (and (not (Math-primp x)) | 2957 (and (not (Math-primp x)) |
3026 (if (and (equal (nth 1 x) '(var SOLVEDUM SOLVEDUM)) | 2958 (if (and (equal (nth 1 x) '(var SOLVEDUM SOLVEDUM)) |
3027 (= (length x) 2)) | 2959 (= (length x) 2)) |
3028 x | 2960 x |
3029 (let ((res nil)) | 2961 (let ((res nil)) |
3030 (while (and (setq x (cdr x)) | 2962 (while (and (setq x (cdr x)) |
3031 (not (setq res (math-solve-above-dummy (car x)))))) | 2963 (not (setq res (math-solve-above-dummy (car x)))))) |
3032 res))) | 2964 res)))) |
3033 ) | |
3034 | 2965 |
3035 (defun math-solve-find-root-term (x neg) ; sets "t2", "t3" | 2966 (defun math-solve-find-root-term (x neg) ; sets "t2", "t3" |
3036 (if (math-solve-find-root-in-prod x) | 2967 (if (math-solve-find-root-in-prod x) |
3037 (setq t3 neg | 2968 (setq t3 neg |
3038 t1 x) | 2969 t1 x) |
3039 (and (memq (car-safe x) '(+ -)) | 2970 (and (memq (car-safe x) '(+ -)) |
3040 (or (math-solve-find-root-term (nth 1 x) neg) | 2971 (or (math-solve-find-root-term (nth 1 x) neg) |
3041 (math-solve-find-root-term (nth 2 x) | 2972 (math-solve-find-root-term (nth 2 x) |
3042 (if (eq (car x) '-) (not neg) neg))))) | 2973 (if (eq (car x) '-) (not neg) neg)))))) |
3043 ) | |
3044 | 2974 |
3045 (defun math-solve-find-root-in-prod (x) | 2975 (defun math-solve-find-root-in-prod (x) |
3046 (and (consp x) | 2976 (and (consp x) |
3047 (math-expr-contains x solve-var) | 2977 (math-expr-contains x solve-var) |
3048 (or (and (eq (car x) 'calcFunc-sqrt) | 2978 (or (and (eq (car x) 'calcFunc-sqrt) |
3055 (setq t2 3)))) | 2985 (setq t2 3)))) |
3056 (and (memq (car x) '(* /)) | 2986 (and (memq (car x) '(* /)) |
3057 (or (and (not (math-expr-contains (nth 1 x) solve-var)) | 2987 (or (and (not (math-expr-contains (nth 1 x) solve-var)) |
3058 (math-solve-find-root-in-prod (nth 2 x))) | 2988 (math-solve-find-root-in-prod (nth 2 x))) |
3059 (and (not (math-expr-contains (nth 2 x) solve-var)) | 2989 (and (not (math-expr-contains (nth 2 x) solve-var)) |
3060 (math-solve-find-root-in-prod (nth 1 x))))))) | 2990 (math-solve-find-root-in-prod (nth 1 x)))))))) |
3061 ) | |
3062 | 2991 |
3063 | 2992 |
3064 (defun math-solve-system (exprs solve-vars solve-full) | 2993 (defun math-solve-system (exprs solve-vars solve-full) |
3065 (setq exprs (mapcar 'list (if (Math-vectorp exprs) | 2994 (setq exprs (mapcar 'list (if (Math-vectorp exprs) |
3066 (cdr exprs) | 2995 (cdr exprs) |
3069 (cdr solve-vars) | 2998 (cdr solve-vars) |
3070 (list solve-vars))) | 2999 (list solve-vars))) |
3071 (or (let ((math-solve-simplifying nil)) | 3000 (or (let ((math-solve-simplifying nil)) |
3072 (math-solve-system-rec exprs solve-vars nil)) | 3001 (math-solve-system-rec exprs solve-vars nil)) |
3073 (let ((math-solve-simplifying t)) | 3002 (let ((math-solve-simplifying t)) |
3074 (math-solve-system-rec exprs solve-vars nil))) | 3003 (math-solve-system-rec exprs solve-vars nil)))) |
3075 ) | |
3076 | 3004 |
3077 ;;; The following backtracking solver works by choosing a variable | 3005 ;;; The following backtracking solver works by choosing a variable |
3078 ;;; and equation, and trying to solve the equation for the variable. | 3006 ;;; and equation, and trying to solve the equation for the variable. |
3079 ;;; If it succeeds it calls itself recursively with that variable and | 3007 ;;; If it succeeds it calls itself recursively with that variable and |
3080 ;;; equation removed from their respective lists, and with the solution | 3008 ;;; equation removed from their respective lists, and with the solution |
3165 (mapcar (function (lambda (x) (cons 'vec x))) eqn-list))))) | 3093 (mapcar (function (lambda (x) (cons 'vec x))) eqn-list))))) |
3166 (math-normalize | 3094 (math-normalize |
3167 (cons 'vec | 3095 (cons 'vec |
3168 (if solns | 3096 (if solns |
3169 (mapcar (function (lambda (x) (cons 'calcFunc-eq x))) solns) | 3097 (mapcar (function (lambda (x) (cons 'calcFunc-eq x))) solns) |
3170 (mapcar 'car eqn-list)))))) | 3098 (mapcar 'car eqn-list))))))) |
3171 ) | |
3172 | 3099 |
3173 (defun math-solve-system-subst (x) ; uses "res" and "v" | 3100 (defun math-solve-system-subst (x) ; uses "res" and "v" |
3174 (let ((accum nil) | 3101 (let ((accum nil) |
3175 (res2 res)) | 3102 (res2 res)) |
3176 (while x | 3103 (while x |
3182 (math-expr-subst (car x) vv r)) | 3109 (math-expr-subst (car x) vv r)) |
3183 (math-expr-subst (car x) vv r)))) | 3110 (math-expr-subst (car x) vv r)))) |
3184 (car res2))) | 3111 (car res2))) |
3185 x (cdr x) | 3112 x (cdr x) |
3186 res2 (cdr res2))) | 3113 res2 (cdr res2))) |
3187 accum) | 3114 accum)) |
3188 ) | |
3189 | 3115 |
3190 | 3116 |
3191 (defun math-get-from-counter (name) | 3117 (defun math-get-from-counter (name) |
3192 (let ((ctr (assq name calc-command-flags))) | 3118 (let ((ctr (assq name calc-command-flags))) |
3193 (if ctr | 3119 (if ctr |
3194 (setcdr ctr (1+ (cdr ctr))) | 3120 (setcdr ctr (1+ (cdr ctr))) |
3195 (setq ctr (cons name 1) | 3121 (setq ctr (cons name 1) |
3196 calc-command-flags (cons ctr calc-command-flags))) | 3122 calc-command-flags (cons ctr calc-command-flags))) |
3197 (cdr ctr)) | 3123 (cdr ctr))) |
3198 ) | |
3199 | 3124 |
3200 (defun math-solve-get-sign (val) | 3125 (defun math-solve-get-sign (val) |
3201 (setq val (math-simplify val)) | 3126 (setq val (math-simplify val)) |
3202 (if (and (eq (car-safe val) '*) | 3127 (if (and (eq (car-safe val) '*) |
3203 (Math-numberp (nth 1 val))) | 3128 (Math-numberp (nth 1 val))) |
3220 (if (eq solve-full 'all) | 3145 (if (eq solve-full 'all) |
3221 (setq math-solve-ranges (cons (list var2 1 -1) | 3146 (setq math-solve-ranges (cons (list var2 1 -1) |
3222 math-solve-ranges))) | 3147 math-solve-ranges))) |
3223 (math-mul var2 val))) | 3148 (math-mul var2 val))) |
3224 (calc-record-why "*Choosing positive solution") | 3149 (calc-record-why "*Choosing positive solution") |
3225 val)) | 3150 val))) |
3226 ) | |
3227 | 3151 |
3228 (defun math-solve-get-int (val &optional range first) | 3152 (defun math-solve-get-int (val &optional range first) |
3229 (if solve-full | 3153 (if solve-full |
3230 (if (and (calc-var-value 'var-GenCount) | 3154 (if (and (calc-var-value 'var-GenCount) |
3231 (Math-natnump var-GenCount) | 3155 (Math-natnump var-GenCount) |
3241 (cdr (calcFunc-index | 3165 (cdr (calcFunc-index |
3242 range (or first 0)))) | 3166 range (or first 0)))) |
3243 math-solve-ranges))) | 3167 math-solve-ranges))) |
3244 (math-mul val var2))) | 3168 (math-mul val var2))) |
3245 (calc-record-why "*Choosing 0 for arbitrary integer in solution") | 3169 (calc-record-why "*Choosing 0 for arbitrary integer in solution") |
3246 0) | 3170 0)) |
3247 ) | |
3248 | 3171 |
3249 (defun math-solve-sign (sign expr) | 3172 (defun math-solve-sign (sign expr) |
3250 (and sign | 3173 (and sign |
3251 (let ((s1 (math-possible-signs expr))) | 3174 (let ((s1 (math-possible-signs expr))) |
3252 (cond ((memq s1 '(4 6)) | 3175 (cond ((memq s1 '(4 6)) |
3253 sign) | 3176 sign) |
3254 ((memq s1 '(1 3)) | 3177 ((memq s1 '(1 3)) |
3255 (- sign))))) | 3178 (- sign)))))) |
3256 ) | |
3257 | 3179 |
3258 (defun math-looks-evenp (expr) | 3180 (defun math-looks-evenp (expr) |
3259 (if (Math-integerp expr) | 3181 (if (Math-integerp expr) |
3260 (math-evenp expr) | 3182 (math-evenp expr) |
3261 (if (memq (car expr) '(* /)) | 3183 (if (memq (car expr) '(* /)) |
3262 (math-looks-evenp (nth 1 expr)))) | 3184 (math-looks-evenp (nth 1 expr))))) |
3263 ) | |
3264 | 3185 |
3265 (defun math-solve-for (lhs rhs solve-var solve-full &optional sign) | 3186 (defun math-solve-for (lhs rhs solve-var solve-full &optional sign) |
3266 (if (math-expr-contains rhs solve-var) | 3187 (if (math-expr-contains rhs solve-var) |
3267 (math-solve-for (math-sub lhs rhs) 0 solve-var solve-full) | 3188 (math-solve-for (math-sub lhs rhs) 0 solve-var solve-full) |
3268 (and (math-expr-contains lhs solve-var) | 3189 (and (math-expr-contains lhs solve-var) |
3285 (calc-record-why (if (= new-len 1) | 3206 (calc-record-why (if (= new-len 1) |
3286 "*All solutions were complex" | 3207 "*All solutions were complex" |
3287 (format | 3208 (format |
3288 "*Omitted %d complex solutions" | 3209 "*Omitted %d complex solutions" |
3289 (- old-len new-len))))))) | 3210 (- old-len new-len))))))) |
3290 res)))) | 3211 res))))) |
3291 ) | |
3292 | 3212 |
3293 (defun math-solve-eqn (expr var full) | 3213 (defun math-solve-eqn (expr var full) |
3294 (if (memq (car-safe expr) '(calcFunc-neq calcFunc-lt calcFunc-gt | 3214 (if (memq (car-safe expr) '(calcFunc-neq calcFunc-lt calcFunc-gt |
3295 calcFunc-leq calcFunc-geq)) | 3215 calcFunc-leq calcFunc-geq)) |
3296 (let ((res (math-solve-for (cons '- (cdr expr)) | 3216 (let ((res (math-solve-for (cons '- (cdr expr)) |
3306 "*Can't determine direction of inequality")) | 3226 "*Can't determine direction of inequality")) |
3307 (and (memq (car expr) '(calcFunc-neq calcFunc-lt calcFunc-gt)) | 3227 (and (memq (car expr) '(calcFunc-neq calcFunc-lt calcFunc-gt)) |
3308 (list 'calcFunc-neq var res)))))) | 3228 (list 'calcFunc-neq var res)))))) |
3309 (let ((res (math-solve-for expr 0 var full))) | 3229 (let ((res (math-solve-for expr 0 var full))) |
3310 (and res | 3230 (and res |
3311 (list 'calcFunc-eq var res)))) | 3231 (list 'calcFunc-eq var res))))) |
3312 ) | |
3313 | 3232 |
3314 (defun math-reject-solution (expr var func) | 3233 (defun math-reject-solution (expr var func) |
3315 (if (math-expr-contains expr var) | 3234 (if (math-expr-contains expr var) |
3316 (or (equal (car calc-next-why) '(* "Unable to find a symbolic solution")) | 3235 (or (equal (car calc-next-why) '(* "Unable to find a symbolic solution")) |
3317 (calc-record-why "*Unable to find a solution"))) | 3236 (calc-record-why "*Unable to find a solution"))) |
3318 (list func expr var) | 3237 (list func expr var)) |
3319 ) | |
3320 | 3238 |
3321 (defun calcFunc-solve (expr var) | 3239 (defun calcFunc-solve (expr var) |
3322 (or (if (or (Math-vectorp expr) (Math-vectorp var)) | 3240 (or (if (or (Math-vectorp expr) (Math-vectorp var)) |
3323 (math-solve-system expr var nil) | 3241 (math-solve-system expr var nil) |
3324 (math-solve-eqn expr var nil)) | 3242 (math-solve-eqn expr var nil)) |
3325 (math-reject-solution expr var 'calcFunc-solve)) | 3243 (math-reject-solution expr var 'calcFunc-solve))) |
3326 ) | |
3327 | 3244 |
3328 (defun calcFunc-fsolve (expr var) | 3245 (defun calcFunc-fsolve (expr var) |
3329 (or (if (or (Math-vectorp expr) (Math-vectorp var)) | 3246 (or (if (or (Math-vectorp expr) (Math-vectorp var)) |
3330 (math-solve-system expr var t) | 3247 (math-solve-system expr var t) |
3331 (math-solve-eqn expr var t)) | 3248 (math-solve-eqn expr var t)) |
3332 (math-reject-solution expr var 'calcFunc-fsolve)) | 3249 (math-reject-solution expr var 'calcFunc-fsolve))) |
3333 ) | |
3334 | 3250 |
3335 (defun calcFunc-roots (expr var) | 3251 (defun calcFunc-roots (expr var) |
3336 (let ((math-solve-ranges nil)) | 3252 (let ((math-solve-ranges nil)) |
3337 (or (if (or (Math-vectorp expr) (Math-vectorp var)) | 3253 (or (if (or (Math-vectorp expr) (Math-vectorp var)) |
3338 (math-solve-system expr var 'all) | 3254 (math-solve-system expr var 'all) |
3339 (math-solve-for expr 0 var 'all)) | 3255 (math-solve-for expr 0 var 'all)) |
3340 (math-reject-solution expr var 'calcFunc-roots))) | 3256 (math-reject-solution expr var 'calcFunc-roots)))) |
3341 ) | |
3342 | 3257 |
3343 (defun calcFunc-finv (expr var) | 3258 (defun calcFunc-finv (expr var) |
3344 (let ((res (math-solve-for expr math-integ-var var nil))) | 3259 (let ((res (math-solve-for expr math-integ-var var nil))) |
3345 (if res | 3260 (if res |
3346 (math-normalize (math-expr-subst res math-integ-var var)) | 3261 (math-normalize (math-expr-subst res math-integ-var var)) |
3347 (math-reject-solution expr var 'calcFunc-finv))) | 3262 (math-reject-solution expr var 'calcFunc-finv)))) |
3348 ) | |
3349 | 3263 |
3350 (defun calcFunc-ffinv (expr var) | 3264 (defun calcFunc-ffinv (expr var) |
3351 (let ((res (math-solve-for expr math-integ-var var t))) | 3265 (let ((res (math-solve-for expr math-integ-var var t))) |
3352 (if res | 3266 (if res |
3353 (math-normalize (math-expr-subst res math-integ-var var)) | 3267 (math-normalize (math-expr-subst res math-integ-var var)) |
3354 (math-reject-solution expr var 'calcFunc-finv))) | 3268 (math-reject-solution expr var 'calcFunc-finv)))) |
3355 ) | |
3356 | 3269 |
3357 | 3270 |
3358 (put 'calcFunc-inv 'math-inverse | 3271 (put 'calcFunc-inv 'math-inverse |
3359 (function (lambda (x) (math-div 1 x)))) | 3272 (function (lambda (x) (math-div 1 x)))) |
3360 (put 'calcFunc-inv 'math-inverse-sign -1) | 3273 (put 'calcFunc-inv 'math-inverse-sign -1) |
3497 (math-expr-subst | 3410 (math-expr-subst |
3498 fprime v x0)) | 3411 fprime v x0)) |
3499 nfac)))) | 3412 nfac)))) |
3500 (and fprime | 3413 (and fprime |
3501 (math-normalize accum)))) | 3414 (math-normalize accum)))) |
3502 (list 'calcFunc-taylor expr var num))) | 3415 (list 'calcFunc-taylor expr var num)))) |
3503 ) | 3416 |
3504 | 3417 ;;; calcalg2.el ends here |
3505 | |
3506 | |
3507 |