Commit | Line | Data |
---|---|---|
3132f345 CW |
1 | ;;; calc-cplx.el --- Complex number functions for Calc |
2 | ||
f8fc5256 | 3 | ;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2005 Free Software Foundation, Inc. |
3132f345 CW |
4 | |
5 | ;; Author: David Gillespie <daveg@synaptics.com> | |
b96bd98c | 6 | ;; Maintainer: Jay Belanger <belanger@truman.edu> |
136211a9 EZ |
7 | |
8 | ;; This file is part of GNU Emacs. | |
9 | ||
10 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
11 | ;; but WITHOUT ANY WARRANTY. No author or distributor | |
12 | ;; accepts responsibility to anyone for the consequences of using it | |
13 | ;; or for whether it serves any particular purpose or works at all, | |
14 | ;; unless he says so in writing. Refer to the GNU Emacs General Public | |
15 | ;; License for full details. | |
16 | ||
17 | ;; Everyone is granted permission to copy, modify and redistribute | |
18 | ;; GNU Emacs, but only under the conditions described in the | |
19 | ;; GNU Emacs General Public License. A copy of this license is | |
20 | ;; supposed to have been given to you along with GNU Emacs so you | |
21 | ;; can know your rights and responsibilities. It should be in a | |
22 | ;; file named COPYING. Among other things, the copyright notice | |
23 | ;; and this notice must be preserved on all copies. | |
24 | ||
3132f345 | 25 | ;;; Commentary: |
136211a9 | 26 | |
3132f345 | 27 | ;;; Code: |
136211a9 EZ |
28 | |
29 | ;; This file is autoloaded from calc-ext.el. | |
136211a9 | 30 | |
b96bd98c | 31 | (require 'calc-ext) |
136211a9 EZ |
32 | (require 'calc-macs) |
33 | ||
136211a9 EZ |
34 | (defun calc-argument (arg) |
35 | (interactive "P") | |
36 | (calc-slow-wrapper | |
bf77c646 | 37 | (calc-unary-op "arg" 'calcFunc-arg arg))) |
136211a9 EZ |
38 | |
39 | (defun calc-re (arg) | |
40 | (interactive "P") | |
41 | (calc-slow-wrapper | |
bf77c646 | 42 | (calc-unary-op "re" 'calcFunc-re arg))) |
136211a9 EZ |
43 | |
44 | (defun calc-im (arg) | |
45 | (interactive "P") | |
46 | (calc-slow-wrapper | |
bf77c646 | 47 | (calc-unary-op "im" 'calcFunc-im arg))) |
136211a9 EZ |
48 | |
49 | ||
50 | (defun calc-polar () | |
51 | (interactive) | |
52 | (calc-slow-wrapper | |
53 | (let ((arg (calc-top-n 1))) | |
54 | (if (or (calc-is-inverse) | |
55 | (eq (car-safe arg) 'polar)) | |
56 | (calc-enter-result 1 "p-r" (list 'calcFunc-rect arg)) | |
bf77c646 | 57 | (calc-enter-result 1 "r-p" (list 'calcFunc-polar arg)))))) |
136211a9 EZ |
58 | |
59 | ||
60 | ||
61 | ||
62 | (defun calc-complex-notation () | |
63 | (interactive) | |
64 | (calc-wrapper | |
65 | (calc-change-mode 'calc-complex-format nil t) | |
3132f345 | 66 | (message "Displaying complex numbers in (X,Y) format"))) |
136211a9 EZ |
67 | |
68 | (defun calc-i-notation () | |
69 | (interactive) | |
70 | (calc-wrapper | |
71 | (calc-change-mode 'calc-complex-format 'i t) | |
3132f345 | 72 | (message "Displaying complex numbers in X+Yi format"))) |
136211a9 EZ |
73 | |
74 | (defun calc-j-notation () | |
75 | (interactive) | |
76 | (calc-wrapper | |
77 | (calc-change-mode 'calc-complex-format 'j t) | |
3132f345 | 78 | (message "Displaying complex numbers in X+Yj format"))) |
136211a9 EZ |
79 | |
80 | ||
81 | (defun calc-polar-mode (n) | |
82 | (interactive "P") | |
83 | (calc-wrapper | |
84 | (if (if n | |
85 | (> (prefix-numeric-value n) 0) | |
86 | (eq calc-complex-mode 'cplx)) | |
87 | (progn | |
88 | (calc-change-mode 'calc-complex-mode 'polar) | |
3132f345 | 89 | (message "Preferred complex form is polar")) |
136211a9 | 90 | (calc-change-mode 'calc-complex-mode 'cplx) |
3132f345 | 91 | (message "Preferred complex form is rectangular")))) |
136211a9 EZ |
92 | |
93 | ||
94 | ;;;; Complex numbers. | |
95 | ||
96 | (defun math-normalize-polar (a) | |
97 | (let ((r (math-normalize (nth 1 a))) | |
98 | (th (math-normalize (nth 2 a)))) | |
99 | (cond ((math-zerop r) | |
100 | '(polar 0 0)) | |
101 | ((or (math-zerop th)) | |
102 | r) | |
103 | ((and (not (eq calc-angle-mode 'rad)) | |
104 | (or (equal th '(float 18 1)) | |
105 | (equal th 180))) | |
106 | (math-neg r)) | |
107 | ((math-negp r) | |
108 | (math-neg (list 'polar (math-neg r) th))) | |
109 | (t | |
bf77c646 | 110 | (list 'polar r th))))) |
136211a9 EZ |
111 | |
112 | ||
113 | ;;; Coerce A to be complex (rectangular form). [c N] | |
114 | (defun math-complex (a) | |
115 | (cond ((eq (car-safe a) 'cplx) a) | |
116 | ((eq (car-safe a) 'polar) | |
117 | (if (math-zerop (nth 1 a)) | |
118 | (nth 1 a) | |
119 | (let ((sc (calcFunc-sincos (nth 2 a)))) | |
120 | (list 'cplx | |
121 | (math-mul (nth 1 a) (nth 1 sc)) | |
122 | (math-mul (nth 1 a) (nth 2 sc)))))) | |
bf77c646 | 123 | (t (list 'cplx a 0)))) |
136211a9 EZ |
124 | |
125 | ;;; Coerce A to be complex (polar form). [c N] | |
126 | (defun math-polar (a) | |
127 | (cond ((eq (car-safe a) 'polar) a) | |
128 | ((math-zerop a) '(polar 0 0)) | |
129 | (t | |
130 | (list 'polar | |
131 | (math-abs a) | |
bf77c646 | 132 | (calcFunc-arg a))))) |
136211a9 EZ |
133 | |
134 | ;;; Multiply A by the imaginary constant i. [N N] [Public] | |
135 | (defun math-imaginary (a) | |
136 | (if (and (or (Math-objvecp a) (math-infinitep a)) | |
137 | (not calc-symbolic-mode)) | |
138 | (math-mul a | |
139 | (if (or (eq (car-safe a) 'polar) | |
140 | (and (not (eq (car-safe a) 'cplx)) | |
141 | (eq calc-complex-mode 'polar))) | |
142 | (list 'polar 1 (math-quarter-circle nil)) | |
143 | '(cplx 0 1))) | |
bf77c646 | 144 | (math-mul a '(var i var-i)))) |
136211a9 EZ |
145 | |
146 | ||
147 | ||
148 | ||
149 | (defun math-want-polar (a b) | |
150 | (cond ((eq (car-safe a) 'polar) | |
151 | (if (eq (car-safe b) 'cplx) | |
152 | (eq calc-complex-mode 'polar) | |
153 | t)) | |
154 | ((eq (car-safe a) 'cplx) | |
155 | (if (eq (car-safe b) 'polar) | |
156 | (eq calc-complex-mode 'polar) | |
157 | nil)) | |
158 | ((eq (car-safe b) 'polar) | |
159 | t) | |
160 | ((eq (car-safe b) 'cplx) | |
161 | nil) | |
bf77c646 | 162 | (t (eq calc-complex-mode 'polar)))) |
136211a9 EZ |
163 | |
164 | ;;; Force A to be in the (-pi,pi] or (-180,180] range. | |
165 | (defun math-fix-circular (a &optional dir) ; [R R] | |
166 | (cond ((eq (car-safe a) 'hms) | |
167 | (cond ((and (Math-lessp 180 (nth 1 a)) (not (eq dir 1))) | |
168 | (math-fix-circular (math-add a '(float -36 1)) -1)) | |
169 | ((or (Math-lessp -180 (nth 1 a)) (eq dir -1)) | |
170 | a) | |
171 | (t | |
172 | (math-fix-circular (math-add a '(float 36 1)) 1)))) | |
173 | ((eq calc-angle-mode 'rad) | |
174 | (cond ((and (Math-lessp (math-pi) a) (not (eq dir 1))) | |
175 | (math-fix-circular (math-sub a (math-two-pi)) -1)) | |
176 | ((or (Math-lessp (math-neg (math-pi)) a) (eq dir -1)) | |
177 | a) | |
178 | (t | |
179 | (math-fix-circular (math-add a (math-two-pi)) 1)))) | |
180 | (t | |
181 | (cond ((and (Math-lessp '(float 18 1) a) (not (eq dir 1))) | |
182 | (math-fix-circular (math-add a '(float -36 1)) -1)) | |
183 | ((or (Math-lessp '(float -18 1) a) (eq dir -1)) | |
184 | a) | |
185 | (t | |
bf77c646 | 186 | (math-fix-circular (math-add a '(float 36 1)) 1)))))) |
136211a9 EZ |
187 | |
188 | ||
189 | ;;;; Complex numbers. | |
190 | ||
191 | (defun calcFunc-polar (a) ; [C N] [Public] | |
192 | (cond ((Math-vectorp a) | |
193 | (math-map-vec 'calcFunc-polar a)) | |
194 | ((Math-realp a) a) | |
195 | ((Math-numberp a) | |
196 | (math-normalize (math-polar a))) | |
bf77c646 | 197 | (t (list 'calcFunc-polar a)))) |
136211a9 EZ |
198 | |
199 | (defun calcFunc-rect (a) ; [N N] [Public] | |
200 | (cond ((Math-vectorp a) | |
201 | (math-map-vec 'calcFunc-rect a)) | |
202 | ((Math-realp a) a) | |
203 | ((Math-numberp a) | |
204 | (math-normalize (math-complex a))) | |
bf77c646 | 205 | (t (list 'calcFunc-rect a)))) |
136211a9 EZ |
206 | |
207 | ;;; Compute the complex conjugate of A. [O O] [Public] | |
208 | (defun calcFunc-conj (a) | |
209 | (let (aa bb) | |
210 | (cond ((Math-realp a) | |
211 | a) | |
212 | ((eq (car a) 'cplx) | |
213 | (list 'cplx (nth 1 a) (math-neg (nth 2 a)))) | |
214 | ((eq (car a) 'polar) | |
215 | (list 'polar (nth 1 a) (math-neg (nth 2 a)))) | |
216 | ((eq (car a) 'vec) | |
217 | (math-map-vec 'calcFunc-conj a)) | |
218 | ((eq (car a) 'calcFunc-conj) | |
219 | (nth 1 a)) | |
220 | ((math-known-realp a) | |
221 | a) | |
222 | ((and (equal a '(var i var-i)) | |
223 | (math-imaginary-i)) | |
224 | (math-neg a)) | |
225 | ((and (memq (car a) '(+ - * /)) | |
226 | (progn | |
227 | (setq aa (calcFunc-conj (nth 1 a)) | |
228 | bb (calcFunc-conj (nth 2 a))) | |
229 | (or (not (eq (car-safe aa) 'calcFunc-conj)) | |
230 | (not (eq (car-safe bb) 'calcFunc-conj))))) | |
231 | (if (eq (car a) '+) | |
232 | (math-add aa bb) | |
233 | (if (eq (car a) '-) | |
234 | (math-sub aa bb) | |
235 | (if (eq (car a) '*) | |
236 | (math-mul aa bb) | |
237 | (math-div aa bb))))) | |
238 | ((eq (car a) 'neg) | |
239 | (math-neg (calcFunc-conj (nth 1 a)))) | |
240 | ((let ((inf (math-infinitep a))) | |
241 | (and inf | |
242 | (math-mul (calcFunc-conj (math-infinite-dir a inf)) inf)))) | |
243 | (t (calc-record-why 'numberp a) | |
bf77c646 | 244 | (list 'calcFunc-conj a))))) |
136211a9 EZ |
245 | |
246 | ||
247 | ;;; Compute the complex argument of A. [F N] [Public] | |
248 | (defun calcFunc-arg (a) | |
249 | (cond ((Math-anglep a) | |
250 | (if (math-negp a) (math-half-circle nil) 0)) | |
251 | ((eq (car-safe a) 'cplx) | |
252 | (calcFunc-arctan2 (nth 2 a) (nth 1 a))) | |
253 | ((eq (car-safe a) 'polar) | |
254 | (nth 2 a)) | |
255 | ((eq (car a) 'vec) | |
256 | (math-map-vec 'calcFunc-arg a)) | |
257 | ((and (equal a '(var i var-i)) | |
258 | (math-imaginary-i)) | |
259 | (math-quarter-circle t)) | |
260 | ((and (equal a '(neg (var i var-i))) | |
261 | (math-imaginary-i)) | |
262 | (math-neg (math-quarter-circle t))) | |
263 | ((let ((signs (math-possible-signs a))) | |
264 | (or (and (memq signs '(2 4 6)) 0) | |
265 | (and (eq signs 1) (math-half-circle nil))))) | |
266 | ((math-infinitep a) | |
267 | (if (or (equal a '(var uinf var-uinf)) | |
268 | (equal a '(var nan var-nan))) | |
269 | '(var nan var-nan) | |
270 | (calcFunc-arg (math-infinite-dir a)))) | |
271 | (t (calc-record-why 'numvecp a) | |
bf77c646 | 272 | (list 'calcFunc-arg a)))) |
136211a9 EZ |
273 | |
274 | (defun math-imaginary-i () | |
275 | (let ((val (calc-var-value 'var-i))) | |
276 | (or (eq (car-safe val) 'special-const) | |
277 | (equal val '(cplx 0 1)) | |
278 | (and (eq (car-safe val) 'polar) | |
279 | (eq (nth 1 val) 0) | |
bf77c646 | 280 | (Math-equal (nth 1 val) (math-quarter-circle nil)))))) |
136211a9 EZ |
281 | |
282 | ;;; Extract the real or complex part of a complex number. [R N] [Public] | |
283 | ;;; Also extracts the real part of a modulo form. | |
284 | (defun calcFunc-re (a) | |
285 | (let (aa bb) | |
286 | (cond ((Math-realp a) a) | |
287 | ((memq (car a) '(mod cplx)) | |
288 | (nth 1 a)) | |
289 | ((eq (car a) 'polar) | |
290 | (math-mul (nth 1 a) (calcFunc-cos (nth 2 a)))) | |
291 | ((eq (car a) 'vec) | |
292 | (math-map-vec 'calcFunc-re a)) | |
293 | ((math-known-realp a) a) | |
294 | ((eq (car a) 'calcFunc-conj) | |
295 | (calcFunc-re (nth 1 a))) | |
296 | ((and (equal a '(var i var-i)) | |
297 | (math-imaginary-i)) | |
298 | 0) | |
299 | ((and (memq (car a) '(+ - *)) | |
300 | (progn | |
301 | (setq aa (calcFunc-re (nth 1 a)) | |
302 | bb (calcFunc-re (nth 2 a))) | |
303 | (or (not (eq (car-safe aa) 'calcFunc-re)) | |
304 | (not (eq (car-safe bb) 'calcFunc-re))))) | |
305 | (if (eq (car a) '+) | |
306 | (math-add aa bb) | |
307 | (if (eq (car a) '-) | |
308 | (math-sub aa bb) | |
309 | (math-sub (math-mul aa bb) | |
310 | (math-mul (calcFunc-im (nth 1 a)) | |
311 | (calcFunc-im (nth 2 a))))))) | |
312 | ((and (eq (car a) '/) | |
313 | (math-known-realp (nth 2 a))) | |
314 | (math-div (calcFunc-re (nth 1 a)) (nth 2 a))) | |
315 | ((eq (car a) 'neg) | |
316 | (math-neg (calcFunc-re (nth 1 a)))) | |
317 | (t (calc-record-why 'numberp a) | |
bf77c646 | 318 | (list 'calcFunc-re a))))) |
136211a9 EZ |
319 | |
320 | (defun calcFunc-im (a) | |
321 | (let (aa bb) | |
322 | (cond ((Math-realp a) | |
323 | (if (math-floatp a) '(float 0 0) 0)) | |
324 | ((eq (car a) 'cplx) | |
325 | (nth 2 a)) | |
326 | ((eq (car a) 'polar) | |
327 | (math-mul (nth 1 a) (calcFunc-sin (nth 2 a)))) | |
328 | ((eq (car a) 'vec) | |
329 | (math-map-vec 'calcFunc-im a)) | |
330 | ((math-known-realp a) | |
331 | 0) | |
332 | ((eq (car a) 'calcFunc-conj) | |
333 | (math-neg (calcFunc-im (nth 1 a)))) | |
334 | ((and (equal a '(var i var-i)) | |
335 | (math-imaginary-i)) | |
336 | 1) | |
337 | ((and (memq (car a) '(+ - *)) | |
338 | (progn | |
339 | (setq aa (calcFunc-im (nth 1 a)) | |
340 | bb (calcFunc-im (nth 2 a))) | |
341 | (or (not (eq (car-safe aa) 'calcFunc-im)) | |
342 | (not (eq (car-safe bb) 'calcFunc-im))))) | |
343 | (if (eq (car a) '+) | |
344 | (math-add aa bb) | |
345 | (if (eq (car a) '-) | |
346 | (math-sub aa bb) | |
347 | (math-add (math-mul (calcFunc-re (nth 1 a)) bb) | |
348 | (math-mul aa (calcFunc-re (nth 2 a))))))) | |
349 | ((and (eq (car a) '/) | |
350 | (math-known-realp (nth 2 a))) | |
351 | (math-div (calcFunc-im (nth 1 a)) (nth 2 a))) | |
352 | ((eq (car a) 'neg) | |
353 | (math-neg (calcFunc-im (nth 1 a)))) | |
354 | (t (calc-record-why 'numberp a) | |
bf77c646 | 355 | (list 'calcFunc-im a))))) |
136211a9 | 356 | |
b96bd98c JB |
357 | (provide 'calc-cplx) |
358 | ||
ab5796a9 | 359 | ;;; arch-tag: de73a331-941c-4507-ae76-46c76adc70dd |
bf77c646 | 360 | ;;; calc-cplx.el ends here |