Mercurial > emacs
annotate lisp/calc/calc-math.el @ 53879:e3771c262410
New file. Move original fringe related declarations
and code from dispextern.h and xdisp.c here.
Rework code to support user defined fringe bitmaps, redefining
standard bitmaps, ability to overlay user defined bitmap with
overlay arrow bitmap, and add faces to bitmaps.
(Voverflow_newline_into_fringe): Declare here.
(enum fringe_bitmap_align): New enum.
(..._bits): All bitmaps are now defined without bitswapping; that
is now done in init_fringe_once (if necessary).
(standard_bitmaps): New array with specifications for the
standard fringe bitmaps.
(fringe_faces): New array.
(valid_fringe_bitmap_id_p): New function.
(draw_fringe_bitmap_1): Rename from draw_fringe_bitmap.
(draw_fringe_bitmap): New function which draws fringe bitmap,
possibly overlaying bitmap with cursor in right fringe or the
overlay arrow in the left fringe.
(update_window_fringes): Do not handle overlay arrow here.
Compare and copy fringe bitmap faces.
(init_fringe_bitmap): New function.
(Fdefine_fringe_bitmap, Fdestroy_fringe_bitmap): New DEFUNs to
define and destroy user defined fringe bitmaps.
(Fset_fringe_bitmap_face): New DEFUN to set face for a fringe bitmap.
(Ffringe_bitmaps_at_pos): New DEFUN to read current fringe bitmaps.
(syms_of_fringe): New function. Defsubr new DEFUNs.
DEFVAR_LISP Voverflow_newline_into_fringe.
(init_fringe_once, init_fringe): New functions.
(w32_init_fringe, w32_reset_fringes) [WINDOWS_NT]: New functions.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 08 Feb 2004 23:18:16 +0000 |
parents | 695cf19ef79e |
children | 647b2f6dac36 375f2633d815 |
rev | line source |
---|---|
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
1 ;;; calc-math.el --- mathematical functions for Calc |
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
2 |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
3 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc. |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
4 |
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
5 ;; Author: David Gillespie <daveg@synaptics.com> |
49598
0d8b17d428b5
Trailing whitepace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
49263
diff
changeset
|
6 ;; Maintainers: D. Goel <deego@gnufans.org> |
49263
f4d68f97221e
Add new maintainer (deego).
Deepak Goel <deego@gnufans.org>
parents:
42206
diff
changeset
|
7 ;; Colin Walters <walters@debian.org> |
40785 | 8 |
9 ;; This file is part of GNU Emacs. | |
10 | |
11 ;; GNU Emacs is distributed in the hope that it will be useful, | |
12 ;; but WITHOUT ANY WARRANTY. No author or distributor | |
13 ;; accepts responsibility to anyone for the consequences of using it | |
14 ;; or for whether it serves any particular purpose or works at all, | |
15 ;; unless he says so in writing. Refer to the GNU Emacs General Public | |
16 ;; License for full details. | |
17 | |
18 ;; Everyone is granted permission to copy, modify and redistribute | |
19 ;; GNU Emacs, but only under the conditions described in the | |
20 ;; GNU Emacs General Public License. A copy of this license is | |
21 ;; supposed to have been given to you along with GNU Emacs so you | |
22 ;; can know your rights and responsibilities. It should be in a | |
23 ;; file named COPYING. Among other things, the copyright notice | |
24 ;; and this notice must be preserved on all copies. | |
25 | |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
26 ;;; Commentary: |
40785 | 27 |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
28 ;;; Code: |
40785 | 29 |
30 ;; This file is autoloaded from calc-ext.el. | |
31 (require 'calc-ext) | |
32 | |
33 (require 'calc-macs) | |
34 | |
35 (defun calc-Need-calc-math () nil) | |
36 | |
37 | |
38 (defun calc-sqrt (arg) | |
39 (interactive "P") | |
40 (calc-slow-wrapper | |
41 (if (calc-is-inverse) | |
42 (calc-unary-op "^2" 'calcFunc-sqr arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
43 (calc-unary-op "sqrt" 'calcFunc-sqrt arg)))) |
40785 | 44 |
45 (defun calc-isqrt (arg) | |
46 (interactive "P") | |
47 (calc-slow-wrapper | |
48 (if (calc-is-inverse) | |
49 (calc-unary-op "^2" 'calcFunc-sqr arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
50 (calc-unary-op "isqt" 'calcFunc-isqrt arg)))) |
40785 | 51 |
52 | |
53 (defun calc-hypot (arg) | |
54 (interactive "P") | |
55 (calc-slow-wrapper | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
56 (calc-binary-op "hypt" 'calcFunc-hypot arg))) |
40785 | 57 |
58 (defun calc-ln (arg) | |
59 (interactive "P") | |
60 (calc-invert-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
61 (calc-exp arg)) |
40785 | 62 |
63 (defun calc-log10 (arg) | |
64 (interactive "P") | |
65 (calc-hyperbolic-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
66 (calc-ln arg)) |
40785 | 67 |
68 (defun calc-log (arg) | |
69 (interactive "P") | |
70 (calc-slow-wrapper | |
71 (if (calc-is-inverse) | |
72 (calc-binary-op "alog" 'calcFunc-alog arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
73 (calc-binary-op "log" 'calcFunc-log arg)))) |
40785 | 74 |
75 (defun calc-ilog (arg) | |
76 (interactive "P") | |
77 (calc-slow-wrapper | |
78 (if (calc-is-inverse) | |
79 (calc-binary-op "alog" 'calcFunc-alog arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
80 (calc-binary-op "ilog" 'calcFunc-ilog arg)))) |
40785 | 81 |
82 (defun calc-lnp1 (arg) | |
83 (interactive "P") | |
84 (calc-invert-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
85 (calc-expm1 arg)) |
40785 | 86 |
87 (defun calc-exp (arg) | |
88 (interactive "P") | |
89 (calc-slow-wrapper | |
90 (if (calc-is-hyperbolic) | |
91 (if (calc-is-inverse) | |
92 (calc-unary-op "lg10" 'calcFunc-log10 arg) | |
93 (calc-unary-op "10^" 'calcFunc-exp10 arg)) | |
94 (if (calc-is-inverse) | |
95 (calc-unary-op "ln" 'calcFunc-ln arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
96 (calc-unary-op "exp" 'calcFunc-exp arg))))) |
40785 | 97 |
98 (defun calc-expm1 (arg) | |
99 (interactive "P") | |
100 (calc-slow-wrapper | |
101 (if (calc-is-inverse) | |
102 (calc-unary-op "ln+1" 'calcFunc-lnp1 arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
103 (calc-unary-op "ex-1" 'calcFunc-expm1 arg)))) |
40785 | 104 |
105 (defun calc-pi () | |
106 (interactive) | |
107 (calc-slow-wrapper | |
108 (if (calc-is-inverse) | |
109 (if (calc-is-hyperbolic) | |
110 (if calc-symbolic-mode | |
111 (calc-pop-push-record 0 "phi" '(var phi var-phi)) | |
112 (calc-pop-push-record 0 "phi" (math-phi))) | |
113 (if calc-symbolic-mode | |
114 (calc-pop-push-record 0 "gmma" '(var gamma var-gamma)) | |
115 (calc-pop-push-record 0 "gmma" (math-gamma-const)))) | |
116 (if (calc-is-hyperbolic) | |
117 (if calc-symbolic-mode | |
118 (calc-pop-push-record 0 "e" '(var e var-e)) | |
119 (calc-pop-push-record 0 "e" (math-e))) | |
120 (if calc-symbolic-mode | |
121 (calc-pop-push-record 0 "pi" '(var pi var-pi)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
122 (calc-pop-push-record 0 "pi" (math-pi))))))) |
40785 | 123 |
124 (defun calc-sin (arg) | |
125 (interactive "P") | |
126 (calc-slow-wrapper | |
127 (if (calc-is-hyperbolic) | |
128 (if (calc-is-inverse) | |
129 (calc-unary-op "asnh" 'calcFunc-arcsinh arg) | |
130 (calc-unary-op "sinh" 'calcFunc-sinh arg)) | |
131 (if (calc-is-inverse) | |
132 (calc-unary-op "asin" 'calcFunc-arcsin arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
133 (calc-unary-op "sin" 'calcFunc-sin arg))))) |
40785 | 134 |
135 (defun calc-arcsin (arg) | |
136 (interactive "P") | |
137 (calc-invert-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
138 (calc-sin arg)) |
40785 | 139 |
140 (defun calc-sinh (arg) | |
141 (interactive "P") | |
142 (calc-hyperbolic-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
143 (calc-sin arg)) |
40785 | 144 |
145 (defun calc-arcsinh (arg) | |
146 (interactive "P") | |
147 (calc-invert-func) | |
148 (calc-hyperbolic-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
149 (calc-sin arg)) |
40785 | 150 |
151 (defun calc-cos (arg) | |
152 (interactive "P") | |
153 (calc-slow-wrapper | |
154 (if (calc-is-hyperbolic) | |
155 (if (calc-is-inverse) | |
156 (calc-unary-op "acsh" 'calcFunc-arccosh arg) | |
157 (calc-unary-op "cosh" 'calcFunc-cosh arg)) | |
158 (if (calc-is-inverse) | |
159 (calc-unary-op "acos" 'calcFunc-arccos arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
160 (calc-unary-op "cos" 'calcFunc-cos arg))))) |
40785 | 161 |
162 (defun calc-arccos (arg) | |
163 (interactive "P") | |
164 (calc-invert-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
165 (calc-cos arg)) |
40785 | 166 |
167 (defun calc-cosh (arg) | |
168 (interactive "P") | |
169 (calc-hyperbolic-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
170 (calc-cos arg)) |
40785 | 171 |
172 (defun calc-arccosh (arg) | |
173 (interactive "P") | |
174 (calc-invert-func) | |
175 (calc-hyperbolic-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
176 (calc-cos arg)) |
40785 | 177 |
178 (defun calc-sincos () | |
179 (interactive) | |
180 (calc-slow-wrapper | |
181 (if (calc-is-inverse) | |
182 (calc-enter-result 1 "asnc" (list 'calcFunc-arcsincos (calc-top-n 1))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
183 (calc-enter-result 1 "sncs" (list 'calcFunc-sincos (calc-top-n 1)))))) |
40785 | 184 |
185 (defun calc-tan (arg) | |
186 (interactive "P") | |
187 (calc-slow-wrapper | |
188 (if (calc-is-hyperbolic) | |
189 (if (calc-is-inverse) | |
190 (calc-unary-op "atnh" 'calcFunc-arctanh arg) | |
191 (calc-unary-op "tanh" 'calcFunc-tanh arg)) | |
192 (if (calc-is-inverse) | |
193 (calc-unary-op "atan" 'calcFunc-arctan arg) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
194 (calc-unary-op "tan" 'calcFunc-tan arg))))) |
40785 | 195 |
196 (defun calc-arctan (arg) | |
197 (interactive "P") | |
198 (calc-invert-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
199 (calc-tan arg)) |
40785 | 200 |
201 (defun calc-tanh (arg) | |
202 (interactive "P") | |
203 (calc-hyperbolic-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
204 (calc-tan arg)) |
40785 | 205 |
206 (defun calc-arctanh (arg) | |
207 (interactive "P") | |
208 (calc-invert-func) | |
209 (calc-hyperbolic-func) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
210 (calc-tan arg)) |
40785 | 211 |
212 (defun calc-arctan2 () | |
213 (interactive) | |
214 (calc-slow-wrapper | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
215 (calc-enter-result 2 "atn2" (cons 'calcFunc-arctan2 (calc-top-list-n 2))))) |
40785 | 216 |
217 (defun calc-conj (arg) | |
218 (interactive "P") | |
219 (calc-wrapper | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
220 (calc-unary-op "conj" 'calcFunc-conj arg))) |
40785 | 221 |
222 (defun calc-imaginary () | |
223 (interactive) | |
224 (calc-slow-wrapper | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
225 (calc-pop-push-record 1 "i*" (math-imaginary (calc-top-n 1))))) |
40785 | 226 |
227 | |
228 | |
229 (defun calc-to-degrees (arg) | |
230 (interactive "P") | |
231 (calc-wrapper | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
232 (calc-unary-op ">deg" 'calcFunc-deg arg))) |
40785 | 233 |
234 (defun calc-to-radians (arg) | |
235 (interactive "P") | |
236 (calc-wrapper | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
237 (calc-unary-op ">rad" 'calcFunc-rad arg))) |
40785 | 238 |
239 | |
240 (defun calc-degrees-mode (arg) | |
241 (interactive "p") | |
242 (cond ((= arg 1) | |
243 (calc-wrapper | |
244 (calc-change-mode 'calc-angle-mode 'deg) | |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
245 (message "Angles measured in degrees"))) |
40785 | 246 ((= arg 2) (calc-radians-mode)) |
247 ((= arg 3) (calc-hms-mode)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
248 (t (error "Prefix argument out of range")))) |
40785 | 249 |
250 (defun calc-radians-mode () | |
251 (interactive) | |
252 (calc-wrapper | |
253 (calc-change-mode 'calc-angle-mode 'rad) | |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
254 (message "Angles measured in radians"))) |
40785 | 255 |
256 | |
257 ;;; Compute the integer square-root floor(sqrt(A)). A > 0. [I I] [Public] | |
258 ;;; This method takes advantage of the fact that Newton's method starting | |
259 ;;; with an overestimate always works, even using truncating integer division! | |
260 (defun math-isqrt (a) | |
261 (cond ((Math-zerop a) a) | |
262 ((not (math-natnump a)) | |
263 (math-reject-arg a 'natnump)) | |
264 ((integerp a) | |
265 (math-isqrt-small a)) | |
266 (t | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
267 (math-normalize (cons 'bigpos (cdr (math-isqrt-bignum (cdr a)))))))) |
40785 | 268 |
269 (defun calcFunc-isqrt (a) | |
270 (if (math-realp a) | |
271 (math-isqrt (math-floor a)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
272 (math-floor (math-sqrt a)))) |
40785 | 273 |
274 | |
42206 | 275 ;;; This returns (flag . result) where the flag is t if A is a perfect square. |
40785 | 276 (defun math-isqrt-bignum (a) ; [P.l L] |
277 (let ((len (length a))) | |
278 (if (= (% len 2) 0) | |
279 (let* ((top (nthcdr (- len 2) a))) | |
280 (math-isqrt-bignum-iter | |
281 a | |
282 (math-scale-bignum-3 | |
283 (math-bignum-big | |
284 (1+ (math-isqrt-small | |
285 (+ (* (nth 1 top) 1000) (car top))))) | |
286 (1- (/ len 2))))) | |
287 (let* ((top (nth (1- len) a))) | |
288 (math-isqrt-bignum-iter | |
289 a | |
290 (math-scale-bignum-3 | |
291 (list (1+ (math-isqrt-small top))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
292 (/ len 2))))))) |
40785 | 293 |
294 (defun math-isqrt-bignum-iter (a guess) ; [l L l] | |
295 (math-working "isqrt" (cons 'bigpos guess)) | |
296 (let* ((q (math-div-bignum a guess)) | |
297 (s (math-add-bignum (car q) guess)) | |
298 (g2 (math-div2-bignum s)) | |
299 (comp (math-compare-bignum g2 guess))) | |
300 (if (< comp 0) | |
301 (math-isqrt-bignum-iter a g2) | |
302 (cons (and (= comp 0) | |
303 (math-zerop-bignum (cdr q)) | |
304 (= (% (car s) 2) 0)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
305 guess)))) |
40785 | 306 |
307 (defun math-zerop-bignum (a) | |
308 (and (eq (car a) 0) | |
309 (progn | |
310 (while (eq (car (setq a (cdr a))) 0)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
311 (null a)))) |
40785 | 312 |
313 (defun math-scale-bignum-3 (a n) ; [L L S] | |
314 (while (> n 0) | |
315 (setq a (cons 0 a) | |
316 n (1- n))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
317 a) |
40785 | 318 |
319 (defun math-isqrt-small (a) ; A > 0. [S S] | |
320 (let ((g (cond ((>= a 10000) 1000) | |
321 ((>= a 100) 100) | |
322 (t 10))) | |
323 g2) | |
324 (while (< (setq g2 (/ (+ g (/ a g)) 2)) g) | |
325 (setq g g2)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
326 g)) |
40785 | 327 |
328 | |
329 | |
330 | |
331 ;;; Compute the square root of a number. | |
332 ;;; [T N] if possible, else [F N] if possible, else [C N]. [Public] | |
333 (defun math-sqrt (a) | |
334 (or | |
335 (and (Math-zerop a) a) | |
336 (and (math-known-nonposp a) | |
337 (math-imaginary (math-sqrt (math-neg a)))) | |
338 (and (integerp a) | |
339 (let ((sqrt (math-isqrt-small a))) | |
340 (if (= (* sqrt sqrt) a) | |
341 sqrt | |
342 (if calc-symbolic-mode | |
343 (list 'calcFunc-sqrt a) | |
344 (math-sqrt-float (math-float a) (math-float sqrt)))))) | |
345 (and (eq (car-safe a) 'bigpos) | |
346 (let* ((res (math-isqrt-bignum (cdr a))) | |
347 (sqrt (math-normalize (cons 'bigpos (cdr res))))) | |
348 (if (car res) | |
349 sqrt | |
350 (if calc-symbolic-mode | |
351 (list 'calcFunc-sqrt a) | |
352 (math-sqrt-float (math-float a) (math-float sqrt)))))) | |
353 (and (eq (car-safe a) 'frac) | |
354 (let* ((num-res (math-isqrt-bignum (cdr (Math-bignum-test (nth 1 a))))) | |
355 (num-sqrt (math-normalize (cons 'bigpos (cdr num-res)))) | |
356 (den-res (math-isqrt-bignum (cdr (Math-bignum-test (nth 2 a))))) | |
357 (den-sqrt (math-normalize (cons 'bigpos (cdr den-res))))) | |
358 (if (and (car num-res) (car den-res)) | |
359 (list 'frac num-sqrt den-sqrt) | |
360 (if calc-symbolic-mode | |
361 (if (or (car num-res) (car den-res)) | |
362 (math-div (if (car num-res) | |
363 num-sqrt (list 'calcFunc-sqrt (nth 1 a))) | |
364 (if (car den-res) | |
365 den-sqrt (list 'calcFunc-sqrt (nth 2 a)))) | |
366 (list 'calcFunc-sqrt a)) | |
367 (math-sqrt-float (math-float a) | |
368 (math-div (math-float num-sqrt) den-sqrt)))))) | |
369 (and (eq (car-safe a) 'float) | |
370 (if calc-symbolic-mode | |
371 (if (= (% (nth 2 a) 2) 0) | |
372 (let ((res (math-isqrt-bignum | |
373 (cdr (Math-bignum-test (nth 1 a)))))) | |
374 (if (car res) | |
375 (math-make-float (math-normalize | |
376 (cons 'bigpos (cdr res))) | |
377 (/ (nth 2 a) 2)) | |
378 (signal 'inexact-result nil))) | |
379 (signal 'inexact-result nil)) | |
380 (math-sqrt-float a))) | |
381 (and (eq (car-safe a) 'cplx) | |
382 (math-with-extra-prec 2 | |
383 (let* ((d (math-abs a)) | |
384 (imag (math-sqrt (math-mul (math-sub d (nth 1 a)) | |
385 '(float 5 -1))))) | |
386 (list 'cplx | |
387 (math-sqrt (math-mul (math-add d (nth 1 a)) '(float 5 -1))) | |
388 (if (math-negp (nth 2 a)) (math-neg imag) imag))))) | |
389 (and (eq (car-safe a) 'polar) | |
390 (list 'polar | |
391 (math-sqrt (nth 1 a)) | |
392 (math-mul (nth 2 a) '(float 5 -1)))) | |
393 (and (eq (car-safe a) 'sdev) | |
394 (let ((sqrt (math-sqrt (nth 1 a)))) | |
395 (math-make-sdev sqrt | |
396 (math-div (nth 2 a) (math-mul sqrt 2))))) | |
397 (and (eq (car-safe a) 'intv) | |
398 (not (math-negp (nth 2 a))) | |
399 (math-make-intv (nth 1 a) (math-sqrt (nth 2 a)) (math-sqrt (nth 3 a)))) | |
400 (and (eq (car-safe a) '*) | |
401 (or (math-known-nonnegp (nth 1 a)) | |
402 (math-known-nonnegp (nth 2 a))) | |
403 (math-mul (math-sqrt (nth 1 a)) (math-sqrt (nth 2 a)))) | |
404 (and (eq (car-safe a) '/) | |
405 (or (and (math-known-nonnegp (nth 2 a)) | |
406 (math-div (math-sqrt (nth 1 a)) (math-sqrt (nth 2 a)))) | |
407 (and (math-known-nonnegp (nth 1 a)) | |
408 (not (math-equal-int (nth 1 a) 1)) | |
409 (math-mul (math-sqrt (nth 1 a)) | |
410 (math-sqrt (math-div 1 (nth 2 a))))))) | |
411 (and (eq (car-safe a) '^) | |
412 (math-known-evenp (nth 2 a)) | |
413 (math-known-realp (nth 1 a)) | |
414 (math-abs (math-pow (nth 1 a) (math-div (nth 2 a) 2)))) | |
415 (let ((inf (math-infinitep a))) | |
416 (and inf | |
417 (math-mul (math-sqrt (math-infinite-dir a inf)) inf))) | |
418 (progn | |
419 (calc-record-why 'numberp a) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
420 (list 'calcFunc-sqrt a)))) |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
421 (defalias 'calcFunc-sqrt 'math-sqrt) |
40785 | 422 |
423 (defun math-infinite-dir (a &optional inf) | |
424 (or inf (setq inf (math-infinitep a))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
425 (math-normalize (math-expr-subst a inf 1))) |
40785 | 426 |
427 (defun math-sqrt-float (a &optional guess) ; [F F F] | |
428 (if calc-symbolic-mode | |
429 (signal 'inexact-result nil) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
430 (math-with-extra-prec 1 (math-sqrt-raw a guess)))) |
40785 | 431 |
432 (defun math-sqrt-raw (a &optional guess) ; [F F F] | |
433 (if (not (Math-posp a)) | |
434 (math-sqrt a) | |
435 (if (null guess) | |
436 (let ((ldiff (- (math-numdigs (nth 1 a)) 6))) | |
437 (or (= (% (+ (nth 2 a) ldiff) 2) 0) (setq ldiff (1+ ldiff))) | |
438 (setq guess (math-make-float (math-isqrt-small | |
439 (math-scale-int (nth 1 a) (- ldiff))) | |
440 (/ (+ (nth 2 a) ldiff) 2))))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
441 (math-sqrt-float-iter a guess))) |
40785 | 442 |
443 (defun math-sqrt-float-iter (a guess) ; [F F F] | |
444 (math-working "sqrt" guess) | |
445 (let ((g2 (math-mul-float (math-add-float guess (math-div-float a guess)) | |
446 '(float 5 -1)))) | |
447 (if (math-nearly-equal-float g2 guess) | |
448 g2 | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
449 (math-sqrt-float-iter a g2)))) |
40785 | 450 |
451 ;;; True if A and B differ only in the last digit of precision. [P F F] | |
452 (defun math-nearly-equal-float (a b) | |
453 (let ((ediff (- (nth 2 a) (nth 2 b)))) | |
454 (cond ((= ediff 0) ;; Expanded out for speed | |
455 (setq ediff (math-add (Math-integer-neg (nth 1 a)) (nth 1 b))) | |
456 (or (eq ediff 0) | |
457 (and (not (consp ediff)) | |
458 (< ediff 10) | |
459 (> ediff -10) | |
460 (= (math-numdigs (nth 1 a)) calc-internal-prec)))) | |
461 ((= ediff 1) | |
462 (setq ediff (math-add (Math-integer-neg (nth 1 b)) | |
463 (math-scale-int (nth 1 a) 1))) | |
464 (and (not (consp ediff)) | |
465 (< ediff 10) | |
466 (> ediff -10) | |
467 (= (math-numdigs (nth 1 b)) calc-internal-prec))) | |
468 ((= ediff -1) | |
469 (setq ediff (math-add (Math-integer-neg (nth 1 a)) | |
470 (math-scale-int (nth 1 b) 1))) | |
471 (and (not (consp ediff)) | |
472 (< ediff 10) | |
473 (> ediff -10) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
474 (= (math-numdigs (nth 1 a)) calc-internal-prec)))))) |
40785 | 475 |
476 (defun math-nearly-equal (a b) ; [P N N] [Public] | |
477 (setq a (math-float a)) | |
478 (setq b (math-float b)) | |
479 (if (eq (car a) 'polar) (setq a (math-complex a))) | |
480 (if (eq (car b) 'polar) (setq b (math-complex b))) | |
481 (if (eq (car a) 'cplx) | |
482 (if (eq (car b) 'cplx) | |
483 (and (or (math-nearly-equal-float (nth 1 a) (nth 1 b)) | |
484 (and (math-nearly-zerop-float (nth 1 a) (nth 2 a)) | |
485 (math-nearly-zerop-float (nth 1 b) (nth 2 b)))) | |
486 (or (math-nearly-equal-float (nth 2 a) (nth 2 b)) | |
487 (and (math-nearly-zerop-float (nth 2 a) (nth 1 a)) | |
488 (math-nearly-zerop-float (nth 2 b) (nth 1 b))))) | |
489 (and (math-nearly-equal-float (nth 1 a) b) | |
490 (math-nearly-zerop-float (nth 2 a) b))) | |
491 (if (eq (car b) 'cplx) | |
492 (and (math-nearly-equal-float a (nth 1 b)) | |
493 (math-nearly-zerop-float a (nth 2 b))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
494 (math-nearly-equal-float a b)))) |
40785 | 495 |
496 ;;; True if A is nearly zero compared to B. [P F F] | |
497 (defun math-nearly-zerop-float (a b) | |
498 (or (eq (nth 1 a) 0) | |
499 (<= (+ (math-numdigs (nth 1 a)) (nth 2 a)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
500 (1+ (- (+ (math-numdigs (nth 1 b)) (nth 2 b)) calc-internal-prec))))) |
40785 | 501 |
502 (defun math-nearly-zerop (a b) ; [P N R] [Public] | |
503 (setq a (math-float a)) | |
504 (setq b (math-float b)) | |
505 (if (eq (car a) 'cplx) | |
506 (and (math-nearly-zerop-float (nth 1 a) b) | |
507 (math-nearly-zerop-float (nth 2 a) b)) | |
508 (if (eq (car a) 'polar) | |
509 (math-nearly-zerop-float (nth 1 a) b) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
510 (math-nearly-zerop-float a b)))) |
40785 | 511 |
512 ;;; This implementation could be improved, accuracy-wise. | |
513 (defun math-hypot (a b) | |
514 (cond ((Math-zerop a) (math-abs b)) | |
515 ((Math-zerop b) (math-abs a)) | |
516 ((not (Math-scalarp a)) | |
517 (if (math-infinitep a) | |
518 (if (math-infinitep b) | |
519 (if (equal a b) | |
520 a | |
521 '(var nan var-nan)) | |
522 a) | |
523 (calc-record-why 'scalarp a) | |
524 (list 'calcFunc-hypot a b))) | |
525 ((not (Math-scalarp b)) | |
526 (if (math-infinitep b) | |
527 b | |
528 (calc-record-why 'scalarp b) | |
529 (list 'calcFunc-hypot a b))) | |
530 ((and (Math-numberp a) (Math-numberp b)) | |
531 (math-with-extra-prec 1 | |
532 (math-sqrt (math-add (calcFunc-abssqr a) (calcFunc-abssqr b))))) | |
533 ((eq (car-safe a) 'hms) | |
534 (if (eq (car-safe b) 'hms) ; this helps sdev's of hms forms | |
535 (math-to-hms (math-hypot (math-from-hms a 'deg) | |
536 (math-from-hms b 'deg))) | |
537 (math-to-hms (math-hypot (math-from-hms a 'deg) b)))) | |
538 ((eq (car-safe b) 'hms) | |
539 (math-to-hms (math-hypot a (math-from-hms b 'deg)))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
540 (t nil))) |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
541 (defalias 'calcFunc-hypot 'math-hypot) |
40785 | 542 |
543 (defun calcFunc-sqr (x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
544 (math-pow x 2)) |
40785 | 545 |
546 | |
547 | |
548 (defun math-nth-root (a n) | |
549 (cond ((= n 2) (math-sqrt a)) | |
550 ((Math-zerop a) a) | |
551 ((Math-negp a) nil) | |
552 ((Math-integerp a) | |
553 (let ((root (math-nth-root-integer a n))) | |
554 (if (car root) | |
555 (cdr root) | |
556 (and (not calc-symbolic-mode) | |
557 (math-nth-root-float (math-float a) n | |
558 (math-float (cdr root))))))) | |
559 ((eq (car-safe a) 'frac) | |
560 (let* ((num-root (math-nth-root-integer (nth 1 a) n)) | |
561 (den-root (math-nth-root-integer (nth 2 a) n))) | |
562 (if (and (car num-root) (car den-root)) | |
563 (list 'frac (cdr num-root) (cdr den-root)) | |
564 (and (not calc-symbolic-mode) | |
565 (math-nth-root-float | |
566 (math-float a) n | |
567 (math-div-float (math-float (cdr num-root)) | |
568 (math-float (cdr den-root)))))))) | |
569 ((eq (car-safe a) 'float) | |
570 (and (not calc-symbolic-mode) | |
571 (math-nth-root-float a n))) | |
572 ((eq (car-safe a) 'polar) | |
573 (let ((root (math-nth-root (nth 1 a) n))) | |
574 (and root (list 'polar root (math-div (nth 2 a) n))))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
575 (t nil))) |
40785 | 576 |
577 (defun math-nth-root-float (a n &optional guess) | |
578 (math-inexact-result) | |
579 (math-with-extra-prec 1 | |
580 (let ((nf (math-float n)) | |
581 (nfm1 (math-float (1- n)))) | |
582 (math-nth-root-float-iter a (or guess | |
583 (math-make-float | |
584 1 (/ (+ (math-numdigs (nth 1 a)) | |
585 (nth 2 a) | |
586 (/ n 2)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
587 n))))))) |
40785 | 588 |
589 (defun math-nth-root-float-iter (a guess) ; uses "n", "nf", "nfm1" | |
590 (math-working "root" guess) | |
591 (let ((g2 (math-div-float (math-add-float (math-mul nfm1 guess) | |
592 (math-div-float | |
593 a (math-ipow guess (1- n)))) | |
594 nf))) | |
595 (if (math-nearly-equal-float g2 guess) | |
596 g2 | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
597 (math-nth-root-float-iter a g2)))) |
40785 | 598 |
599 (defun math-nth-root-integer (a n &optional guess) ; [I I S] | |
600 (math-nth-root-int-iter a (or guess | |
601 (math-scale-int 1 (/ (+ (math-numdigs a) | |
602 (1- n)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
603 n))))) |
40785 | 604 |
605 (defun math-nth-root-int-iter (a guess) ; uses "n" | |
606 (math-working "root" guess) | |
607 (let* ((q (math-idivmod a (math-ipow guess (1- n)))) | |
608 (s (math-add (car q) (math-mul (1- n) guess))) | |
609 (g2 (math-idivmod s n))) | |
610 (if (Math-natnum-lessp (car g2) guess) | |
611 (math-nth-root-int-iter a (car g2)) | |
612 (cons (and (equal (car g2) guess) | |
613 (eq (cdr q) 0) | |
614 (eq (cdr g2) 0)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
615 guess)))) |
40785 | 616 |
617 (defun calcFunc-nroot (x n) | |
618 (calcFunc-pow x (if (integerp n) | |
619 (math-make-frac 1 n) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
620 (math-div 1 n)))) |
40785 | 621 |
622 | |
623 | |
624 | |
625 ;;;; Transcendental functions. | |
626 | |
627 ;;; All of these functions are defined on the complex plane. | |
628 ;;; (Branch cuts, etc. follow Steele's Common Lisp book.) | |
629 | |
630 ;;; Most functions increase calc-internal-prec by 2 digits, then round | |
631 ;;; down afterward. "-raw" functions use the current precision, require | |
632 ;;; their arguments to be in float (or complex float) format, and always | |
633 ;;; work in radians (where applicable). | |
634 | |
635 (defun math-to-radians (a) ; [N N] | |
636 (cond ((eq (car-safe a) 'hms) | |
637 (math-from-hms a 'rad)) | |
638 ((memq calc-angle-mode '(deg hms)) | |
639 (math-mul a (math-pi-over-180))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
640 (t a))) |
40785 | 641 |
642 (defun math-from-radians (a) ; [N N] | |
643 (cond ((eq calc-angle-mode 'deg) | |
644 (if (math-constp a) | |
645 (math-div a (math-pi-over-180)) | |
646 (list 'calcFunc-deg a))) | |
647 ((eq calc-angle-mode 'hms) | |
648 (math-to-hms a 'rad)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
649 (t a))) |
40785 | 650 |
651 (defun math-to-radians-2 (a) ; [N N] | |
652 (cond ((eq (car-safe a) 'hms) | |
653 (math-from-hms a 'rad)) | |
654 ((memq calc-angle-mode '(deg hms)) | |
655 (if calc-symbolic-mode | |
656 (math-div (math-mul a '(var pi var-pi)) 180) | |
657 (math-mul a (math-pi-over-180)))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
658 (t a))) |
40785 | 659 |
660 (defun math-from-radians-2 (a) ; [N N] | |
661 (cond ((memq calc-angle-mode '(deg hms)) | |
662 (if calc-symbolic-mode | |
663 (math-div (math-mul 180 a) '(var pi var-pi)) | |
664 (math-div a (math-pi-over-180)))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
665 (t a))) |
40785 | 666 |
667 | |
668 | |
669 ;;; Sine, cosine, and tangent. | |
670 | |
671 (defun calcFunc-sin (x) ; [N N] [Public] | |
672 (cond ((and (integerp x) | |
673 (if (eq calc-angle-mode 'deg) | |
674 (= (% x 90) 0) | |
675 (= x 0))) | |
676 (aref [0 1 0 -1] (math-mod (/ x 90) 4))) | |
677 ((Math-scalarp x) | |
678 (math-with-extra-prec 2 | |
679 (math-sin-raw (math-to-radians (math-float x))))) | |
680 ((eq (car x) 'sdev) | |
681 (if (math-constp x) | |
682 (math-with-extra-prec 2 | |
683 (let* ((xx (math-to-radians (math-float (nth 1 x)))) | |
684 (xs (math-to-radians (math-float (nth 2 x)))) | |
685 (sc (math-sin-cos-raw xx))) | |
686 (math-make-sdev (car sc) (math-mul xs (cdr sc))))) | |
687 (math-make-sdev (calcFunc-sin (nth 1 x)) | |
688 (math-mul (nth 2 x) (calcFunc-cos (nth 1 x)))))) | |
689 ((and (eq (car x) 'intv) (math-intv-constp x)) | |
690 (calcFunc-cos (math-sub x (math-quarter-circle nil)))) | |
691 ((equal x '(var nan var-nan)) | |
692 x) | |
693 (t (calc-record-why 'scalarp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
694 (list 'calcFunc-sin x)))) |
40785 | 695 |
696 (defun calcFunc-cos (x) ; [N N] [Public] | |
697 (cond ((and (integerp x) | |
698 (if (eq calc-angle-mode 'deg) | |
699 (= (% x 90) 0) | |
700 (= x 0))) | |
701 (aref [1 0 -1 0] (math-mod (/ x 90) 4))) | |
702 ((Math-scalarp x) | |
703 (math-with-extra-prec 2 | |
704 (math-cos-raw (math-to-radians (math-float x))))) | |
705 ((eq (car x) 'sdev) | |
706 (if (math-constp x) | |
707 (math-with-extra-prec 2 | |
708 (let* ((xx (math-to-radians (math-float (nth 1 x)))) | |
709 (xs (math-to-radians (math-float (nth 2 x)))) | |
710 (sc (math-sin-cos-raw xx))) | |
711 (math-make-sdev (cdr sc) (math-mul xs (car sc))))) | |
712 (math-make-sdev (calcFunc-cos (nth 1 x)) | |
713 (math-mul (nth 2 x) (calcFunc-sin (nth 1 x)))))) | |
714 ((and (eq (car x) 'intv) (math-intv-constp x)) | |
715 (math-with-extra-prec 2 | |
716 (let* ((xx (math-to-radians (math-float x))) | |
717 (na (math-floor (math-div (nth 2 xx) (math-pi)))) | |
718 (nb (math-floor (math-div (nth 3 xx) (math-pi)))) | |
719 (span (math-sub nb na))) | |
720 (if (memq span '(0 1)) | |
721 (let ((int (math-sort-intv (nth 1 x) | |
722 (math-cos-raw (nth 2 xx)) | |
723 (math-cos-raw (nth 3 xx))))) | |
724 (if (eq span 1) | |
725 (if (math-evenp na) | |
726 (math-make-intv (logior (nth 1 x) 2) | |
727 -1 | |
728 (nth 3 int)) | |
729 (math-make-intv (logior (nth 1 x) 1) | |
730 (nth 2 int) | |
731 1)) | |
732 int)) | |
733 (list 'intv 3 -1 1))))) | |
734 ((equal x '(var nan var-nan)) | |
735 x) | |
736 (t (calc-record-why 'scalarp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
737 (list 'calcFunc-cos x)))) |
40785 | 738 |
739 (defun calcFunc-sincos (x) ; [V N] [Public] | |
740 (if (Math-scalarp x) | |
741 (math-with-extra-prec 2 | |
742 (let ((sc (math-sin-cos-raw (math-to-radians (math-float x))))) | |
743 (list 'vec (cdr sc) (car sc)))) ; the vector [cos, sin] | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
744 (list 'vec (calcFunc-sin x) (calcFunc-cos x)))) |
40785 | 745 |
746 (defun calcFunc-tan (x) ; [N N] [Public] | |
747 (cond ((and (integerp x) | |
748 (if (eq calc-angle-mode 'deg) | |
749 (= (% x 180) 0) | |
750 (= x 0))) | |
751 0) | |
752 ((Math-scalarp x) | |
753 (math-with-extra-prec 2 | |
754 (math-tan-raw (math-to-radians (math-float x))))) | |
755 ((eq (car x) 'sdev) | |
756 (if (math-constp x) | |
757 (math-with-extra-prec 2 | |
758 (let* ((xx (math-to-radians (math-float (nth 1 x)))) | |
759 (xs (math-to-radians (math-float (nth 2 x)))) | |
760 (sc (math-sin-cos-raw xx))) | |
761 (if (and (math-zerop (cdr sc)) (not calc-infinite-mode)) | |
762 (progn | |
763 (calc-record-why "*Division by zero") | |
764 (list 'calcFunc-tan x)) | |
765 (math-make-sdev (math-div-float (car sc) (cdr sc)) | |
766 (math-div-float xs (math-sqr (cdr sc))))))) | |
767 (math-make-sdev (calcFunc-tan (nth 1 x)) | |
768 (math-div (nth 2 x) | |
769 (math-sqr (calcFunc-cos (nth 1 x))))))) | |
770 ((and (eq (car x) 'intv) (math-intv-constp x)) | |
771 (or (math-with-extra-prec 2 | |
772 (let* ((xx (math-to-radians (math-float x))) | |
773 (na (math-floor (math-div (math-sub (nth 2 xx) | |
774 (math-pi-over-2)) | |
775 (math-pi)))) | |
776 (nb (math-floor (math-div (math-sub (nth 3 xx) | |
777 (math-pi-over-2)) | |
778 (math-pi))))) | |
779 (and (equal na nb) | |
780 (math-sort-intv (nth 1 x) | |
781 (math-tan-raw (nth 2 xx)) | |
782 (math-tan-raw (nth 3 xx)))))) | |
783 '(intv 3 (neg (var inf var-inf)) (var inf var-inf)))) | |
784 ((equal x '(var nan var-nan)) | |
785 x) | |
786 (t (calc-record-why 'scalarp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
787 (list 'calcFunc-tan x)))) |
40785 | 788 |
789 (defun math-sin-raw (x) ; [N N] | |
790 (cond ((eq (car x) 'cplx) | |
791 (let* ((expx (math-exp-raw (nth 2 x))) | |
792 (expmx (math-div-float '(float 1 0) expx)) | |
793 (sc (math-sin-cos-raw (nth 1 x)))) | |
794 (list 'cplx | |
795 (math-mul-float (car sc) | |
796 (math-mul-float (math-add-float expx expmx) | |
797 '(float 5 -1))) | |
798 (math-mul-float (cdr sc) | |
799 (math-mul-float (math-sub-float expx expmx) | |
800 '(float 5 -1)))))) | |
801 ((eq (car x) 'polar) | |
802 (math-polar (math-sin-raw (math-complex x)))) | |
803 ((Math-integer-negp (nth 1 x)) | |
804 (math-neg-float (math-sin-raw (math-neg-float x)))) | |
805 ((math-lessp-float '(float 7 0) x) ; avoid inf loops due to roundoff | |
806 (math-sin-raw (math-mod x (math-two-pi)))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
807 (t (math-sin-raw-2 x x)))) |
40785 | 808 |
809 (defun math-cos-raw (x) ; [N N] | |
810 (if (eq (car-safe x) 'polar) | |
811 (math-polar (math-cos-raw (math-complex x))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
812 (math-sin-raw (math-sub (math-pi-over-2) x)))) |
40785 | 813 |
814 ;;; This could use a smarter method: Reduce x as in math-sin-raw, then | |
815 ;;; compute either sin(x) or cos(x), whichever is smaller, and compute | |
816 ;;; the other using the identity sin(x)^2 + cos(x)^2 = 1. | |
817 (defun math-sin-cos-raw (x) ; [F.F F] (result is (sin x . cos x)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
818 (cons (math-sin-raw x) (math-cos-raw x))) |
40785 | 819 |
820 (defun math-tan-raw (x) ; [N N] | |
821 (cond ((eq (car x) 'cplx) | |
822 (let* ((x (math-mul x '(float 2 0))) | |
823 (expx (math-exp-raw (nth 2 x))) | |
824 (expmx (math-div-float '(float 1 0) expx)) | |
825 (sc (math-sin-cos-raw (nth 1 x))) | |
826 (d (math-add-float (cdr sc) | |
827 (math-mul-float (math-add-float expx expmx) | |
828 '(float 5 -1))))) | |
829 (and (not (eq (nth 1 d) 0)) | |
830 (list 'cplx | |
831 (math-div-float (car sc) d) | |
832 (math-div-float (math-mul-float (math-sub-float expx | |
833 expmx) | |
834 '(float 5 -1)) d))))) | |
835 ((eq (car x) 'polar) | |
836 (math-polar (math-tan-raw (math-complex x)))) | |
837 (t | |
838 (let ((sc (math-sin-cos-raw x))) | |
839 (if (eq (nth 1 (cdr sc)) 0) | |
840 (math-div (car sc) 0) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
841 (math-div-float (car sc) (cdr sc))))))) |
40785 | 842 |
843 (defun math-sin-raw-2 (x orgx) ; This avoids poss of inf recursion. [F F] | |
844 (let ((xmpo2 (math-sub-float (math-pi-over-2) x))) | |
845 (cond ((Math-integer-negp (nth 1 xmpo2)) | |
846 (math-neg-float (math-sin-raw-2 (math-sub-float x (math-pi)) | |
847 orgx))) | |
848 ((math-lessp-float (math-pi-over-4) x) | |
849 (math-cos-raw-2 xmpo2 orgx)) | |
850 ((math-lessp-float x (math-neg (math-pi-over-4))) | |
851 (math-neg (math-cos-raw-2 (math-add (math-pi-over-2) x) orgx))) | |
852 ((math-nearly-zerop-float x orgx) '(float 0 0)) | |
853 (calc-symbolic-mode (signal 'inexact-result nil)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
854 (t (math-sin-series x 6 4 x (math-neg-float (math-sqr-float x))))))) |
40785 | 855 |
856 (defun math-cos-raw-2 (x orgx) ; [F F] | |
857 (cond ((math-nearly-zerop-float x orgx) '(float 1 0)) | |
858 (calc-symbolic-mode (signal 'inexact-result nil)) | |
859 (t (let ((xnegsqr (math-neg-float (math-sqr-float x)))) | |
860 (math-sin-series | |
861 (math-add-float '(float 1 0) | |
862 (math-mul-float xnegsqr '(float 5 -1))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
863 24 5 xnegsqr xnegsqr))))) |
40785 | 864 |
865 (defun math-sin-series (sum nfac n x xnegsqr) | |
866 (math-working "sin" sum) | |
867 (let* ((nextx (math-mul-float x xnegsqr)) | |
868 (nextsum (math-add-float sum (math-div-float nextx | |
869 (math-float nfac))))) | |
870 (if (math-nearly-equal-float sum nextsum) | |
871 sum | |
872 (math-sin-series nextsum (math-mul nfac (* n (1+ n))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
873 (+ n 2) nextx xnegsqr)))) |
40785 | 874 |
875 | |
876 ;;; Inverse sine, cosine, tangent. | |
877 | |
878 (defun calcFunc-arcsin (x) ; [N N] [Public] | |
879 (cond ((eq x 0) 0) | |
880 ((and (eq x 1) (eq calc-angle-mode 'deg)) 90) | |
881 ((and (eq x -1) (eq calc-angle-mode 'deg)) -90) | |
882 (calc-symbolic-mode (signal 'inexact-result nil)) | |
883 ((Math-numberp x) | |
884 (math-with-extra-prec 2 | |
885 (math-from-radians (math-arcsin-raw (math-float x))))) | |
886 ((eq (car x) 'sdev) | |
887 (math-make-sdev (calcFunc-arcsin (nth 1 x)) | |
888 (math-from-radians | |
889 (math-div (nth 2 x) | |
890 (math-sqrt | |
891 (math-sub 1 (math-sqr (nth 1 x)))))))) | |
892 ((eq (car x) 'intv) | |
893 (math-sort-intv (nth 1 x) | |
894 (calcFunc-arcsin (nth 2 x)) | |
895 (calcFunc-arcsin (nth 3 x)))) | |
896 ((equal x '(var nan var-nan)) | |
897 x) | |
898 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
899 (list 'calcFunc-arcsin x)))) |
40785 | 900 |
901 (defun calcFunc-arccos (x) ; [N N] [Public] | |
902 (cond ((eq x 1) 0) | |
903 ((and (eq x 0) (eq calc-angle-mode 'deg)) 90) | |
904 ((and (eq x -1) (eq calc-angle-mode 'deg)) 180) | |
905 (calc-symbolic-mode (signal 'inexact-result nil)) | |
906 ((Math-numberp x) | |
907 (math-with-extra-prec 2 | |
908 (math-from-radians (math-arccos-raw (math-float x))))) | |
909 ((eq (car x) 'sdev) | |
910 (math-make-sdev (calcFunc-arccos (nth 1 x)) | |
911 (math-from-radians | |
912 (math-div (nth 2 x) | |
913 (math-sqrt | |
914 (math-sub 1 (math-sqr (nth 1 x)))))))) | |
915 ((eq (car x) 'intv) | |
916 (math-sort-intv (nth 1 x) | |
917 (calcFunc-arccos (nth 2 x)) | |
918 (calcFunc-arccos (nth 3 x)))) | |
919 ((equal x '(var nan var-nan)) | |
920 x) | |
921 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
922 (list 'calcFunc-arccos x)))) |
40785 | 923 |
924 (defun calcFunc-arctan (x) ; [N N] [Public] | |
925 (cond ((eq x 0) 0) | |
926 ((and (eq x 1) (eq calc-angle-mode 'deg)) 45) | |
927 ((and (eq x -1) (eq calc-angle-mode 'deg)) -45) | |
928 ((Math-numberp x) | |
929 (math-with-extra-prec 2 | |
930 (math-from-radians (math-arctan-raw (math-float x))))) | |
931 ((eq (car x) 'sdev) | |
932 (math-make-sdev (calcFunc-arctan (nth 1 x)) | |
933 (math-from-radians | |
934 (math-div (nth 2 x) | |
935 (math-add 1 (math-sqr (nth 1 x))))))) | |
936 ((eq (car x) 'intv) | |
937 (math-sort-intv (nth 1 x) | |
938 (calcFunc-arctan (nth 2 x)) | |
939 (calcFunc-arctan (nth 3 x)))) | |
940 ((equal x '(var inf var-inf)) | |
941 (math-quarter-circle t)) | |
942 ((equal x '(neg (var inf var-inf))) | |
943 (math-neg (math-quarter-circle t))) | |
944 ((equal x '(var nan var-nan)) | |
945 x) | |
946 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
947 (list 'calcFunc-arctan x)))) |
40785 | 948 |
949 (defun math-arcsin-raw (x) ; [N N] | |
950 (let ((a (math-sqrt-raw (math-sub '(float 1 0) (math-sqr x))))) | |
951 (if (or (memq (car x) '(cplx polar)) | |
952 (memq (car a) '(cplx polar))) | |
953 (math-with-extra-prec 2 ; use extra precision for difficult case | |
954 (math-mul '(cplx 0 -1) | |
955 (math-ln-raw (math-add (math-mul '(cplx 0 1) x) a)))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
956 (math-arctan2-raw x a)))) |
40785 | 957 |
958 (defun math-arccos-raw (x) ; [N N] | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
959 (math-sub (math-pi-over-2) (math-arcsin-raw x))) |
40785 | 960 |
961 (defun math-arctan-raw (x) ; [N N] | |
962 (cond ((memq (car x) '(cplx polar)) | |
963 (math-with-extra-prec 2 ; extra-extra | |
964 (math-div (math-sub | |
965 (math-ln-raw (math-add 1 (math-mul '(cplx 0 1) x))) | |
966 (math-ln-raw (math-add 1 (math-mul '(cplx 0 -1) x)))) | |
967 '(cplx 0 2)))) | |
968 ((Math-integer-negp (nth 1 x)) | |
969 (math-neg-float (math-arctan-raw (math-neg-float x)))) | |
970 ((math-zerop x) x) | |
971 (calc-symbolic-mode (signal 'inexact-result nil)) | |
972 ((math-equal-int x 1) (math-pi-over-4)) | |
973 ((math-equal-int x -1) (math-neg (math-pi-over-4))) | |
974 ((math-lessp-float '(float 414214 -6) x) ; if x > sqrt(2) - 1, reduce | |
975 (if (math-lessp-float '(float 1 0) x) | |
976 (math-sub-float (math-mul-float (math-pi) '(float 5 -1)) | |
977 (math-arctan-raw (math-div-float '(float 1 0) x))) | |
978 (math-sub-float (math-mul-float (math-pi) '(float 25 -2)) | |
979 (math-arctan-raw (math-div-float | |
980 (math-sub-float '(float 1 0) x) | |
981 (math-add-float '(float 1 0) | |
982 x)))))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
983 (t (math-arctan-series x 3 x (math-neg-float (math-sqr-float x)))))) |
40785 | 984 |
985 (defun math-arctan-series (sum n x xnegsqr) | |
986 (math-working "arctan" sum) | |
987 (let* ((nextx (math-mul-float x xnegsqr)) | |
988 (nextsum (math-add-float sum (math-div-float nextx (math-float n))))) | |
989 (if (math-nearly-equal-float sum nextsum) | |
990 sum | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
991 (math-arctan-series nextsum (+ n 2) nextx xnegsqr)))) |
40785 | 992 |
993 (defun calcFunc-arctan2 (y x) ; [F R R] [Public] | |
994 (if (Math-anglep y) | |
995 (if (Math-anglep x) | |
996 (math-with-extra-prec 2 | |
997 (math-from-radians (math-arctan2-raw (math-float y) | |
998 (math-float x)))) | |
999 (calc-record-why 'anglep x) | |
1000 (list 'calcFunc-arctan2 y x)) | |
1001 (if (and (or (math-infinitep x) (math-anglep x)) | |
1002 (or (math-infinitep y) (math-anglep y))) | |
1003 (progn | |
1004 (if (math-posp x) | |
1005 (setq x 1) | |
1006 (if (math-negp x) | |
1007 (setq x -1) | |
1008 (or (math-zerop x) | |
1009 (setq x nil)))) | |
1010 (if (math-posp y) | |
1011 (setq y 1) | |
1012 (if (math-negp y) | |
1013 (setq y -1) | |
1014 (or (math-zerop y) | |
1015 (setq y nil)))) | |
1016 (if (and y x) | |
1017 (calcFunc-arctan2 y x) | |
1018 '(var nan var-nan))) | |
1019 (calc-record-why 'anglep y) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1020 (list 'calcFunc-arctan2 y x)))) |
40785 | 1021 |
1022 (defun math-arctan2-raw (y x) ; [F R R] | |
1023 (cond ((math-zerop y) | |
1024 (if (math-negp x) (math-pi) | |
1025 (if (or (math-floatp x) (math-floatp y)) '(float 0 0) 0))) | |
1026 ((math-zerop x) | |
1027 (if (math-posp y) | |
1028 (math-pi-over-2) | |
1029 (math-neg (math-pi-over-2)))) | |
1030 ((math-posp x) | |
1031 (math-arctan-raw (math-div-float y x))) | |
1032 ((math-posp y) | |
1033 (math-add-float (math-arctan-raw (math-div-float y x)) | |
1034 (math-pi))) | |
1035 (t | |
1036 (math-sub-float (math-arctan-raw (math-div-float y x)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1037 (math-pi))))) |
40785 | 1038 |
1039 (defun calcFunc-arcsincos (x) ; [V N] [Public] | |
1040 (if (and (Math-vectorp x) | |
1041 (= (length x) 3)) | |
1042 (calcFunc-arctan2 (nth 2 x) (nth 1 x)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1043 (math-reject-arg x "*Two-element vector expected"))) |
40785 | 1044 |
1045 | |
1046 | |
1047 ;;; Exponential function. | |
1048 | |
1049 (defun calcFunc-exp (x) ; [N N] [Public] | |
1050 (cond ((eq x 0) 1) | |
1051 ((and (memq x '(1 -1)) calc-symbolic-mode) | |
1052 (if (eq x 1) '(var e var-e) (math-div 1 '(var e var-e)))) | |
1053 ((Math-numberp x) | |
1054 (math-with-extra-prec 2 (math-exp-raw (math-float x)))) | |
1055 ((eq (car-safe x) 'sdev) | |
1056 (let ((ex (calcFunc-exp (nth 1 x)))) | |
1057 (math-make-sdev ex (math-mul (nth 2 x) ex)))) | |
1058 ((eq (car-safe x) 'intv) | |
1059 (math-make-intv (nth 1 x) (calcFunc-exp (nth 2 x)) | |
1060 (calcFunc-exp (nth 3 x)))) | |
1061 ((equal x '(var inf var-inf)) | |
1062 x) | |
1063 ((equal x '(neg (var inf var-inf))) | |
1064 0) | |
1065 ((equal x '(var nan var-nan)) | |
1066 x) | |
1067 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1068 (list 'calcFunc-exp x)))) |
40785 | 1069 |
1070 (defun calcFunc-expm1 (x) ; [N N] [Public] | |
1071 (cond ((eq x 0) 0) | |
1072 ((math-zerop x) '(float 0 0)) | |
1073 (calc-symbolic-mode (signal 'inexact-result nil)) | |
1074 ((Math-numberp x) | |
1075 (math-with-extra-prec 2 | |
1076 (let ((x (math-float x))) | |
1077 (if (and (eq (car x) 'float) | |
1078 (math-lessp-float x '(float 1 0)) | |
1079 (math-lessp-float '(float -1 0) x)) | |
1080 (math-exp-minus-1-raw x) | |
1081 (math-add (math-exp-raw x) -1))))) | |
1082 ((eq (car-safe x) 'sdev) | |
1083 (if (math-constp x) | |
1084 (let ((ex (calcFunc-expm1 (nth 1 x)))) | |
1085 (math-make-sdev ex (math-mul (nth 2 x) (math-add ex 1)))) | |
1086 (math-make-sdev (calcFunc-expm1 (nth 1 x)) | |
1087 (math-mul (nth 2 x) (calcFunc-exp (nth 1 x)))))) | |
1088 ((eq (car-safe x) 'intv) | |
1089 (math-make-intv (nth 1 x) | |
1090 (calcFunc-expm1 (nth 2 x)) | |
1091 (calcFunc-expm1 (nth 3 x)))) | |
1092 ((equal x '(var inf var-inf)) | |
1093 x) | |
1094 ((equal x '(neg (var inf var-inf))) | |
1095 -1) | |
1096 ((equal x '(var nan var-nan)) | |
1097 x) | |
1098 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1099 (list 'calcFunc-expm1 x)))) |
40785 | 1100 |
1101 (defun calcFunc-exp10 (x) ; [N N] [Public] | |
1102 (if (eq x 0) | |
1103 1 | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1104 (math-pow '(float 1 1) x))) |
40785 | 1105 |
1106 (defun math-exp-raw (x) ; [N N] | |
1107 (cond ((math-zerop x) '(float 1 0)) | |
1108 (calc-symbolic-mode (signal 'inexact-result nil)) | |
1109 ((eq (car x) 'cplx) | |
1110 (let ((expx (math-exp-raw (nth 1 x))) | |
1111 (sc (math-sin-cos-raw (nth 2 x)))) | |
1112 (list 'cplx | |
1113 (math-mul-float expx (cdr sc)) | |
1114 (math-mul-float expx (car sc))))) | |
1115 ((eq (car x) 'polar) | |
1116 (let ((xc (math-complex x))) | |
1117 (list 'polar | |
1118 (math-exp-raw (nth 1 xc)) | |
1119 (math-from-radians (nth 2 xc))))) | |
1120 ((or (math-lessp-float '(float 5 -1) x) | |
1121 (math-lessp-float x '(float -5 -1))) | |
1122 (if (math-lessp-float '(float 921035 1) x) | |
1123 (math-overflow) | |
1124 (if (math-lessp-float x '(float -921035 1)) | |
1125 (math-underflow))) | |
1126 (let* ((two-x (math-mul-float x '(float 2 0))) | |
1127 (hint (math-scale-int (nth 1 two-x) (nth 2 two-x))) | |
1128 (hfrac (math-sub-float x (math-mul-float (math-float hint) | |
1129 '(float 5 -1))))) | |
1130 (math-mul-float (math-ipow (math-sqrt-e) hint) | |
1131 (math-add-float '(float 1 0) | |
1132 (math-exp-minus-1-raw hfrac))))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1133 (t (math-add-float '(float 1 0) (math-exp-minus-1-raw x))))) |
40785 | 1134 |
1135 (defun math-exp-minus-1-raw (x) ; [F F] | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1136 (math-exp-series x 2 3 x x)) |
40785 | 1137 |
1138 (defun math-exp-series (sum nfac n xpow x) | |
1139 (math-working "exp" sum) | |
1140 (let* ((nextx (math-mul-float xpow x)) | |
1141 (nextsum (math-add-float sum (math-div-float nextx | |
1142 (math-float nfac))))) | |
1143 (if (math-nearly-equal-float sum nextsum) | |
1144 sum | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1145 (math-exp-series nextsum (math-mul nfac n) (1+ n) nextx x)))) |
40785 | 1146 |
1147 | |
1148 | |
1149 ;;; Logarithms. | |
1150 | |
1151 (defun calcFunc-ln (x) ; [N N] [Public] | |
1152 (cond ((math-zerop x) | |
1153 (if calc-infinite-mode | |
1154 '(neg (var inf var-inf)) | |
1155 (math-reject-arg x "*Logarithm of zero"))) | |
1156 ((eq x 1) 0) | |
1157 ((Math-numberp x) | |
1158 (math-with-extra-prec 2 (math-ln-raw (math-float x)))) | |
1159 ((eq (car-safe x) 'sdev) | |
1160 (math-make-sdev (calcFunc-ln (nth 1 x)) | |
1161 (math-div (nth 2 x) (nth 1 x)))) | |
1162 ((and (eq (car-safe x) 'intv) (or (Math-posp (nth 2 x)) | |
1163 (Math-zerop (nth 2 x)) | |
1164 (not (math-intv-constp x)))) | |
1165 (let ((calc-infinite-mode t)) | |
1166 (math-make-intv (nth 1 x) (calcFunc-ln (nth 2 x)) | |
1167 (calcFunc-ln (nth 3 x))))) | |
1168 ((equal x '(var e var-e)) | |
1169 1) | |
1170 ((and (eq (car-safe x) '^) | |
1171 (equal (nth 1 x) '(var e var-e)) | |
1172 (math-known-realp (nth 2 x))) | |
1173 (nth 2 x)) | |
1174 ((math-infinitep x) | |
1175 (if (equal x '(var nan var-nan)) | |
1176 x | |
1177 '(var inf var-inf))) | |
1178 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1179 (list 'calcFunc-ln x)))) |
40785 | 1180 |
1181 (defun calcFunc-log10 (x) ; [N N] [Public] | |
1182 (cond ((math-equal-int x 1) | |
1183 (if (math-floatp x) '(float 0 0) 0)) | |
1184 ((and (Math-integerp x) | |
1185 (math-posp x) | |
1186 (let ((res (math-integer-log x 10))) | |
1187 (and (car res) | |
1188 (setq x (cdr res))))) | |
1189 x) | |
1190 ((and (eq (car-safe x) 'frac) | |
1191 (eq (nth 1 x) 1) | |
1192 (let ((res (math-integer-log (nth 2 x) 10))) | |
1193 (and (car res) | |
1194 (setq x (- (cdr res)))))) | |
1195 x) | |
1196 ((math-zerop x) | |
1197 (if calc-infinite-mode | |
1198 '(neg (var inf var-inf)) | |
1199 (math-reject-arg x "*Logarithm of zero"))) | |
1200 (calc-symbolic-mode (signal 'inexact-result nil)) | |
1201 ((Math-numberp x) | |
1202 (math-with-extra-prec 2 | |
1203 (let ((xf (math-float x))) | |
1204 (if (eq (nth 1 xf) 0) | |
1205 (math-reject-arg x "*Logarithm of zero")) | |
1206 (if (Math-integer-posp (nth 1 xf)) | |
1207 (if (eq (nth 1 xf) 1) ; log10(1*10^n) = n | |
1208 (math-float (nth 2 xf)) | |
1209 (let ((xdigs (1- (math-numdigs (nth 1 xf))))) | |
1210 (math-add-float | |
1211 (math-div-float (math-ln-raw-2 | |
1212 (list 'float (nth 1 xf) (- xdigs))) | |
1213 (math-ln-10)) | |
1214 (math-float (+ (nth 2 xf) xdigs))))) | |
1215 (math-div (calcFunc-ln xf) (math-ln-10)))))) | |
1216 ((eq (car-safe x) 'sdev) | |
1217 (math-make-sdev (calcFunc-log10 (nth 1 x)) | |
1218 (math-div (nth 2 x) | |
1219 (math-mul (nth 1 x) (math-ln-10))))) | |
1220 ((and (eq (car-safe x) 'intv) (or (Math-posp (nth 2 x)) | |
1221 (not (math-intv-constp x)))) | |
1222 (math-make-intv (nth 1 x) | |
1223 (calcFunc-log10 (nth 2 x)) | |
1224 (calcFunc-log10 (nth 3 x)))) | |
1225 ((math-infinitep x) | |
1226 (if (equal x '(var nan var-nan)) | |
1227 x | |
1228 '(var inf var-inf))) | |
1229 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1230 (list 'calcFunc-log10 x)))) |
40785 | 1231 |
1232 (defun calcFunc-log (x &optional b) ; [N N N] [Public] | |
1233 (cond ((or (null b) (equal b '(var e var-e))) | |
1234 (math-normalize (list 'calcFunc-ln x))) | |
1235 ((or (eq b 10) (equal b '(float 1 1))) | |
1236 (math-normalize (list 'calcFunc-log10 x))) | |
1237 ((math-zerop x) | |
1238 (if calc-infinite-mode | |
1239 (math-div (calcFunc-ln x) (calcFunc-ln b)) | |
1240 (math-reject-arg x "*Logarithm of zero"))) | |
1241 ((math-zerop b) | |
1242 (if calc-infinite-mode | |
1243 (math-div (calcFunc-ln x) (calcFunc-ln b)) | |
1244 (math-reject-arg b "*Logarithm of zero"))) | |
1245 ((math-equal-int b 1) | |
1246 (if calc-infinite-mode | |
1247 (math-div (calcFunc-ln x) 0) | |
1248 (math-reject-arg b "*Logarithm base one"))) | |
1249 ((math-equal-int x 1) | |
1250 (if (or (math-floatp a) (math-floatp b)) '(float 0 0) 0)) | |
1251 ((and (Math-ratp x) (Math-ratp b) | |
1252 (math-posp x) (math-posp b) | |
1253 (let* ((sign 1) (inv nil) | |
1254 (xx (if (Math-lessp 1 x) | |
1255 x | |
1256 (setq sign -1) | |
1257 (math-div 1 x))) | |
1258 (bb (if (Math-lessp 1 b) | |
1259 b | |
1260 (setq sign (- sign)) | |
1261 (math-div 1 b))) | |
1262 (res (if (Math-lessp xx bb) | |
1263 (setq inv (math-integer-log bb xx)) | |
1264 (math-integer-log xx bb)))) | |
1265 (and (car res) | |
1266 (setq x (if inv | |
1267 (math-div 1 (* sign (cdr res))) | |
1268 (* sign (cdr res))))))) | |
1269 x) | |
1270 (calc-symbolic-mode (signal 'inexact-result nil)) | |
1271 ((and (Math-numberp x) (Math-numberp b)) | |
1272 (math-with-extra-prec 2 | |
1273 (math-div (math-ln-raw (math-float x)) | |
1274 (math-log-base-raw b)))) | |
1275 ((and (eq (car-safe x) 'sdev) | |
1276 (Math-numberp b)) | |
1277 (math-make-sdev (calcFunc-log (nth 1 x) b) | |
1278 (math-div (nth 2 x) | |
1279 (math-mul (nth 1 x) | |
1280 (math-log-base-raw b))))) | |
1281 ((and (eq (car-safe x) 'intv) (or (Math-posp (nth 2 x)) | |
1282 (not (math-intv-constp x))) | |
1283 (math-realp b)) | |
1284 (math-make-intv (nth 1 x) | |
1285 (calcFunc-log (nth 2 x) b) | |
1286 (calcFunc-log (nth 3 x) b))) | |
1287 ((or (eq (car-safe x) 'intv) (eq (car-safe b) 'intv)) | |
1288 (math-div (calcFunc-ln x) (calcFunc-ln b))) | |
1289 ((or (math-infinitep x) | |
1290 (math-infinitep b)) | |
1291 (math-div (calcFunc-ln x) (calcFunc-ln b))) | |
1292 (t (if (Math-numberp b) | |
1293 (calc-record-why 'numberp x) | |
1294 (calc-record-why 'numberp b)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1295 (list 'calcFunc-log x b)))) |
40785 | 1296 |
1297 (defun calcFunc-alog (x &optional b) | |
1298 (cond ((or (null b) (equal b '(var e var-e))) | |
1299 (math-normalize (list 'calcFunc-exp x))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1300 (t (math-pow b x)))) |
40785 | 1301 |
1302 (defun calcFunc-ilog (x b) | |
1303 (if (and (math-natnump x) (not (eq x 0)) | |
1304 (math-natnump b) (not (eq b 0))) | |
1305 (if (eq b 1) | |
1306 (math-reject-arg x "*Logarithm base one") | |
1307 (if (Math-natnum-lessp x b) | |
1308 0 | |
1309 (cdr (math-integer-log x b)))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1310 (math-floor (calcFunc-log x b)))) |
40785 | 1311 |
1312 (defun math-integer-log (x b) | |
1313 (let ((pows (list b)) | |
1314 (pow (math-sqr b)) | |
1315 next | |
1316 sum n) | |
1317 (while (not (Math-lessp x pow)) | |
1318 (setq pows (cons pow pows) | |
1319 pow (math-sqr pow))) | |
1320 (setq n (lsh 1 (1- (length pows))) | |
1321 sum n | |
1322 pow (car pows)) | |
1323 (while (and (setq pows (cdr pows)) | |
1324 (Math-lessp pow x)) | |
1325 (setq n (/ n 2) | |
1326 next (math-mul pow (car pows))) | |
1327 (or (Math-lessp x next) | |
1328 (setq pow next | |
1329 sum (+ sum n)))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1330 (cons (equal pow x) sum))) |
40785 | 1331 |
1332 | |
41271
fcd507927105
Change all toplevel `setq' forms to `defvar' forms, and move them
Colin Walters <walters@gnu.org>
parents:
41044
diff
changeset
|
1333 (defvar math-log-base-cache nil) |
40785 | 1334 (defun math-log-base-raw (b) ; [N N] |
1335 (if (not (and (equal (car math-log-base-cache) b) | |
1336 (eq (nth 1 math-log-base-cache) calc-internal-prec))) | |
1337 (setq math-log-base-cache (list b calc-internal-prec | |
1338 (math-ln-raw (math-float b))))) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1339 (nth 2 math-log-base-cache)) |
40785 | 1340 |
1341 (defun calcFunc-lnp1 (x) ; [N N] [Public] | |
1342 (cond ((Math-equal-int x -1) | |
1343 (if calc-infinite-mode | |
1344 '(neg (var inf var-inf)) | |
1345 (math-reject-arg x "*Logarithm of zero"))) | |
1346 ((eq x 0) 0) | |
1347 ((math-zerop x) '(float 0 0)) | |
1348 (calc-symbolic-mode (signal 'inexact-result nil)) | |
1349 ((Math-numberp x) | |
1350 (math-with-extra-prec 2 | |
1351 (let ((x (math-float x))) | |
1352 (if (and (eq (car x) 'float) | |
1353 (math-lessp-float x '(float 5 -1)) | |
1354 (math-lessp-float '(float -5 -1) x)) | |
1355 (math-ln-plus-1-raw x) | |
1356 (math-ln-raw (math-add-float x '(float 1 0))))))) | |
1357 ((eq (car-safe x) 'sdev) | |
1358 (math-make-sdev (calcFunc-lnp1 (nth 1 x)) | |
1359 (math-div (nth 2 x) (math-add (nth 1 x) 1)))) | |
1360 ((and (eq (car-safe x) 'intv) (or (Math-posp (nth 2 x)) | |
1361 (not (math-intv-constp x)))) | |
1362 (math-make-intv (nth 1 x) | |
1363 (calcFunc-lnp1 (nth 2 x)) | |
1364 (calcFunc-lnp1 (nth 3 x)))) | |
1365 ((math-infinitep x) | |
1366 (if (equal x '(var nan var-nan)) | |
1367 x | |
1368 '(var inf var-inf))) | |
1369 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1370 (list 'calcFunc-lnp1 x)))) |
40785 | 1371 |
1372 (defun math-ln-raw (x) ; [N N] --- must be float format! | |
1373 (cond ((eq (car-safe x) 'cplx) | |
1374 (list 'cplx | |
1375 (math-mul-float (math-ln-raw | |
1376 (math-add-float (math-sqr-float (nth 1 x)) | |
1377 (math-sqr-float (nth 2 x)))) | |
1378 '(float 5 -1)) | |
1379 (math-arctan2-raw (nth 2 x) (nth 1 x)))) | |
1380 ((eq (car x) 'polar) | |
1381 (math-polar (list 'cplx | |
1382 (math-ln-raw (nth 1 x)) | |
1383 (math-to-radians (nth 2 x))))) | |
1384 ((Math-equal-int x 1) | |
1385 '(float 0 0)) | |
1386 (calc-symbolic-mode (signal 'inexact-result nil)) | |
1387 ((math-posp (nth 1 x)) ; positive and real | |
1388 (let ((xdigs (1- (math-numdigs (nth 1 x))))) | |
1389 (math-add-float (math-ln-raw-2 (list 'float (nth 1 x) (- xdigs))) | |
1390 (math-mul-float (math-float (+ (nth 2 x) xdigs)) | |
1391 (math-ln-10))))) | |
1392 ((math-zerop x) | |
1393 (math-reject-arg x "*Logarithm of zero")) | |
1394 ((eq calc-complex-mode 'polar) ; negative and real | |
1395 (math-polar | |
1396 (list 'cplx ; negative and real | |
1397 (math-ln-raw (math-neg-float x)) | |
1398 (math-pi)))) | |
1399 (t (list 'cplx ; negative and real | |
1400 (math-ln-raw (math-neg-float x)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1401 (math-pi))))) |
40785 | 1402 |
1403 (defun math-ln-raw-2 (x) ; [F F] | |
1404 (cond ((math-lessp-float '(float 14 -1) x) | |
1405 (math-add-float (math-ln-raw-2 (math-mul-float x '(float 5 -1))) | |
1406 (math-ln-2))) | |
1407 (t ; now .7 < x <= 1.4 | |
1408 (math-ln-raw-3 (math-div-float (math-sub-float x '(float 1 0)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1409 (math-add-float x '(float 1 0))))))) |
40785 | 1410 |
1411 (defun math-ln-raw-3 (x) ; [F F] | |
1412 (math-mul-float (math-ln-raw-series x 3 x (math-sqr-float x)) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1413 '(float 2 0))) |
40785 | 1414 |
1415 ;;; Compute ln((1+x)/(1-x)) | |
1416 (defun math-ln-raw-series (sum n x xsqr) | |
1417 (math-working "log" sum) | |
1418 (let* ((nextx (math-mul-float x xsqr)) | |
1419 (nextsum (math-add-float sum (math-div-float nextx (math-float n))))) | |
1420 (if (math-nearly-equal-float sum nextsum) | |
1421 sum | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1422 (math-ln-raw-series nextsum (+ n 2) nextx xsqr)))) |
40785 | 1423 |
1424 (defun math-ln-plus-1-raw (x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1425 (math-lnp1-series x 2 x (math-neg x))) |
40785 | 1426 |
1427 (defun math-lnp1-series (sum n xpow x) | |
1428 (math-working "lnp1" sum) | |
1429 (let* ((nextx (math-mul-float xpow x)) | |
1430 (nextsum (math-add-float sum (math-div-float nextx (math-float n))))) | |
1431 (if (math-nearly-equal-float sum nextsum) | |
1432 sum | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1433 (math-lnp1-series nextsum (1+ n) nextx x)))) |
40785 | 1434 |
1435 (math-defcache math-ln-10 (float (bigpos 018 684 045 994 092 585 302 2) -21) | |
1436 (math-ln-raw-2 '(float 1 1))) | |
1437 | |
1438 (math-defcache math-ln-2 (float (bigpos 417 309 945 559 180 147 693) -21) | |
1439 (math-ln-raw-3 (math-float '(frac 1 3)))) | |
1440 | |
1441 | |
1442 | |
1443 ;;; Hyperbolic functions. | |
1444 | |
1445 (defun calcFunc-sinh (x) ; [N N] [Public] | |
1446 (cond ((eq x 0) 0) | |
1447 (math-expand-formulas | |
1448 (math-normalize | |
1449 (list '/ (list '- (list 'calcFunc-exp x) | |
1450 (list 'calcFunc-exp (list 'neg x))) 2))) | |
1451 ((Math-numberp x) | |
1452 (if calc-symbolic-mode (signal 'inexact-result nil)) | |
1453 (math-with-extra-prec 2 | |
1454 (let ((expx (math-exp-raw (math-float x)))) | |
1455 (math-mul (math-add expx (math-div -1 expx)) '(float 5 -1))))) | |
1456 ((eq (car-safe x) 'sdev) | |
1457 (math-make-sdev (calcFunc-sinh (nth 1 x)) | |
1458 (math-mul (nth 2 x) (calcFunc-cosh (nth 1 x))))) | |
1459 ((eq (car x) 'intv) | |
1460 (math-sort-intv (nth 1 x) | |
1461 (calcFunc-sinh (nth 2 x)) | |
1462 (calcFunc-sinh (nth 3 x)))) | |
1463 ((or (equal x '(var inf var-inf)) | |
1464 (equal x '(neg (var inf var-inf))) | |
1465 (equal x '(var nan var-nan))) | |
1466 x) | |
1467 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1468 (list 'calcFunc-sinh x)))) |
40785 | 1469 (put 'calcFunc-sinh 'math-expandable t) |
1470 | |
1471 (defun calcFunc-cosh (x) ; [N N] [Public] | |
1472 (cond ((eq x 0) 1) | |
1473 (math-expand-formulas | |
1474 (math-normalize | |
1475 (list '/ (list '+ (list 'calcFunc-exp x) | |
1476 (list 'calcFunc-exp (list 'neg x))) 2))) | |
1477 ((Math-numberp x) | |
1478 (if calc-symbolic-mode (signal 'inexact-result nil)) | |
1479 (math-with-extra-prec 2 | |
1480 (let ((expx (math-exp-raw (math-float x)))) | |
1481 (math-mul (math-add expx (math-div 1 expx)) '(float 5 -1))))) | |
1482 ((eq (car-safe x) 'sdev) | |
1483 (math-make-sdev (calcFunc-cosh (nth 1 x)) | |
1484 (math-mul (nth 2 x) | |
1485 (calcFunc-sinh (nth 1 x))))) | |
1486 ((and (eq (car x) 'intv) (math-intv-constp x)) | |
1487 (setq x (math-abs x)) | |
1488 (math-sort-intv (nth 1 x) | |
1489 (calcFunc-cosh (nth 2 x)) | |
1490 (calcFunc-cosh (nth 3 x)))) | |
1491 ((or (equal x '(var inf var-inf)) | |
1492 (equal x '(neg (var inf var-inf))) | |
1493 (equal x '(var nan var-nan))) | |
1494 (math-abs x)) | |
1495 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1496 (list 'calcFunc-cosh x)))) |
40785 | 1497 (put 'calcFunc-cosh 'math-expandable t) |
1498 | |
1499 (defun calcFunc-tanh (x) ; [N N] [Public] | |
1500 (cond ((eq x 0) 0) | |
1501 (math-expand-formulas | |
1502 (math-normalize | |
1503 (let ((expx (list 'calcFunc-exp x)) | |
1504 (expmx (list 'calcFunc-exp (list 'neg x)))) | |
1505 (math-normalize | |
1506 (list '/ (list '- expx expmx) (list '+ expx expmx)))))) | |
1507 ((Math-numberp x) | |
1508 (if calc-symbolic-mode (signal 'inexact-result nil)) | |
1509 (math-with-extra-prec 2 | |
1510 (let* ((expx (calcFunc-exp (math-float x))) | |
1511 (expmx (math-div 1 expx))) | |
1512 (math-div (math-sub expx expmx) | |
1513 (math-add expx expmx))))) | |
1514 ((eq (car-safe x) 'sdev) | |
1515 (math-make-sdev (calcFunc-tanh (nth 1 x)) | |
1516 (math-div (nth 2 x) | |
1517 (math-sqr (calcFunc-cosh (nth 1 x)))))) | |
1518 ((eq (car x) 'intv) | |
1519 (math-sort-intv (nth 1 x) | |
1520 (calcFunc-tanh (nth 2 x)) | |
1521 (calcFunc-tanh (nth 3 x)))) | |
1522 ((equal x '(var inf var-inf)) | |
1523 1) | |
1524 ((equal x '(neg (var inf var-inf))) | |
1525 -1) | |
1526 ((equal x '(var nan var-nan)) | |
1527 x) | |
1528 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1529 (list 'calcFunc-tanh x)))) |
40785 | 1530 (put 'calcFunc-tanh 'math-expandable t) |
1531 | |
1532 (defun calcFunc-arcsinh (x) ; [N N] [Public] | |
1533 (cond ((eq x 0) 0) | |
1534 (math-expand-formulas | |
1535 (math-normalize | |
1536 (list 'calcFunc-ln (list '+ x (list 'calcFunc-sqrt | |
1537 (list '+ (list '^ x 2) 1)))))) | |
1538 ((Math-numberp x) | |
1539 (if calc-symbolic-mode (signal 'inexact-result nil)) | |
1540 (math-with-extra-prec 2 | |
1541 (math-ln-raw (math-add x (math-sqrt-raw (math-add (math-sqr x) | |
1542 '(float 1 0))))))) | |
1543 ((eq (car-safe x) 'sdev) | |
1544 (math-make-sdev (calcFunc-arcsinh (nth 1 x)) | |
1545 (math-div (nth 2 x) | |
1546 (math-sqrt | |
1547 (math-add (math-sqr (nth 1 x)) 1))))) | |
1548 ((eq (car x) 'intv) | |
1549 (math-sort-intv (nth 1 x) | |
1550 (calcFunc-arcsinh (nth 2 x)) | |
1551 (calcFunc-arcsinh (nth 3 x)))) | |
1552 ((or (equal x '(var inf var-inf)) | |
1553 (equal x '(neg (var inf var-inf))) | |
1554 (equal x '(var nan var-nan))) | |
1555 x) | |
1556 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1557 (list 'calcFunc-arcsinh x)))) |
40785 | 1558 (put 'calcFunc-arcsinh 'math-expandable t) |
1559 | |
1560 (defun calcFunc-arccosh (x) ; [N N] [Public] | |
1561 (cond ((eq x 1) 0) | |
1562 ((and (eq x -1) calc-symbolic-mode) | |
1563 '(var pi var-pi)) | |
1564 ((and (eq x 0) calc-symbolic-mode) | |
1565 (math-div (math-mul '(var pi var-pi) '(var i var-i)) 2)) | |
1566 (math-expand-formulas | |
1567 (math-normalize | |
1568 (list 'calcFunc-ln (list '+ x (list 'calcFunc-sqrt | |
1569 (list '- (list '^ x 2) 1)))))) | |
1570 ((Math-numberp x) | |
1571 (if calc-symbolic-mode (signal 'inexact-result nil)) | |
1572 (if (Math-equal-int x -1) | |
1573 (math-imaginary (math-pi)) | |
1574 (math-with-extra-prec 2 | |
1575 (if (or t ; need to do this even in the real case! | |
1576 (memq (car-safe x) '(cplx polar))) | |
1577 (let ((xp1 (math-add 1 x))) ; this gets the branch cuts right | |
1578 (math-ln-raw | |
1579 (math-add x (math-mul xp1 | |
1580 (math-sqrt-raw | |
1581 (math-div (math-sub | |
1582 x | |
1583 '(float 1 0)) | |
1584 xp1)))))) | |
1585 (math-ln-raw | |
1586 (math-add x (math-sqrt-raw (math-add (math-sqr x) | |
1587 '(float -1 0))))))))) | |
1588 ((eq (car-safe x) 'sdev) | |
1589 (math-make-sdev (calcFunc-arccosh (nth 1 x)) | |
1590 (math-div (nth 2 x) | |
1591 (math-sqrt | |
1592 (math-add (math-sqr (nth 1 x)) -1))))) | |
1593 ((eq (car x) 'intv) | |
1594 (math-sort-intv (nth 1 x) | |
1595 (calcFunc-arccosh (nth 2 x)) | |
1596 (calcFunc-arccosh (nth 3 x)))) | |
1597 ((or (equal x '(var inf var-inf)) | |
1598 (equal x '(neg (var inf var-inf))) | |
1599 (equal x '(var nan var-nan))) | |
1600 x) | |
1601 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1602 (list 'calcFunc-arccosh x)))) |
40785 | 1603 (put 'calcFunc-arccosh 'math-expandable t) |
1604 | |
1605 (defun calcFunc-arctanh (x) ; [N N] [Public] | |
1606 (cond ((eq x 0) 0) | |
1607 ((and (Math-equal-int x 1) calc-infinite-mode) | |
1608 '(var inf var-inf)) | |
1609 ((and (Math-equal-int x -1) calc-infinite-mode) | |
1610 '(neg (var inf var-inf))) | |
1611 (math-expand-formulas | |
1612 (list '/ (list '- | |
1613 (list 'calcFunc-ln (list '+ 1 x)) | |
1614 (list 'calcFunc-ln (list '- 1 x))) 2)) | |
1615 ((Math-numberp x) | |
1616 (if calc-symbolic-mode (signal 'inexact-result nil)) | |
1617 (math-with-extra-prec 2 | |
1618 (if (or (memq (car-safe x) '(cplx polar)) | |
1619 (Math-lessp 1 x)) | |
1620 (math-mul (math-sub (math-ln-raw (math-add '(float 1 0) x)) | |
1621 (math-ln-raw (math-sub '(float 1 0) x))) | |
1622 '(float 5 -1)) | |
1623 (if (and (math-equal-int x 1) calc-infinite-mode) | |
1624 '(var inf var-inf) | |
1625 (if (and (math-equal-int x -1) calc-infinite-mode) | |
1626 '(neg (var inf var-inf)) | |
1627 (math-mul (math-ln-raw (math-div (math-add '(float 1 0) x) | |
1628 (math-sub 1 x))) | |
1629 '(float 5 -1))))))) | |
1630 ((eq (car-safe x) 'sdev) | |
1631 (math-make-sdev (calcFunc-arctanh (nth 1 x)) | |
1632 (math-div (nth 2 x) | |
1633 (math-sub 1 (math-sqr (nth 1 x)))))) | |
1634 ((eq (car x) 'intv) | |
1635 (math-sort-intv (nth 1 x) | |
1636 (calcFunc-arctanh (nth 2 x)) | |
1637 (calcFunc-arctanh (nth 3 x)))) | |
1638 ((equal x '(var nan var-nan)) | |
1639 x) | |
1640 (t (calc-record-why 'numberp x) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1641 (list 'calcFunc-arctanh x)))) |
40785 | 1642 (put 'calcFunc-arctanh 'math-expandable t) |
1643 | |
1644 | |
1645 ;;; Convert A from HMS or degrees to radians. | |
1646 (defun calcFunc-rad (a) ; [R R] [Public] | |
1647 (cond ((or (Math-numberp a) | |
1648 (eq (car a) 'intv)) | |
1649 (math-with-extra-prec 2 | |
1650 (math-mul a (math-pi-over-180)))) | |
1651 ((eq (car a) 'hms) | |
1652 (math-from-hms a 'rad)) | |
1653 ((eq (car a) 'sdev) | |
1654 (math-make-sdev (calcFunc-rad (nth 1 a)) | |
1655 (calcFunc-rad (nth 2 a)))) | |
1656 (math-expand-formulas | |
1657 (math-div (math-mul a '(var pi var-pi)) 180)) | |
1658 ((math-infinitep a) a) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1659 (t (list 'calcFunc-rad a)))) |
40785 | 1660 (put 'calcFunc-rad 'math-expandable t) |
1661 | |
1662 ;;; Convert A from HMS or radians to degrees. | |
1663 (defun calcFunc-deg (a) ; [R R] [Public] | |
1664 (cond ((or (Math-numberp a) | |
1665 (eq (car a) 'intv)) | |
1666 (math-with-extra-prec 2 | |
1667 (math-div a (math-pi-over-180)))) | |
1668 ((eq (car a) 'hms) | |
1669 (math-from-hms a 'deg)) | |
1670 ((eq (car a) 'sdev) | |
1671 (math-make-sdev (calcFunc-deg (nth 1 a)) | |
1672 (calcFunc-deg (nth 2 a)))) | |
1673 (math-expand-formulas | |
1674 (math-div (math-mul 180 a) '(var pi var-pi))) | |
1675 ((math-infinitep a) a) | |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1676 (t (list 'calcFunc-deg a)))) |
40785 | 1677 (put 'calcFunc-deg 'math-expandable t) |
1678 | |
52401 | 1679 ;;; arch-tag: c7367e8e-d0b8-4f70-8577-2fb3f31dbb4c |
41044
4549dec29728
(calcFunc-sqrt, calcFunc-hypot): Use `defalias' instead of `fset' and
Colin Walters <walters@gnu.org>
parents:
40785
diff
changeset
|
1680 ;;; calc-math.el ends here |