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