UNPKG

3.36 kBtext/coffeescriptView Raw
1### arg =====================================================================
2
3Tags
4----
5scripting, JS, internal, treenode, general concept
6
7Parameters
8----------
9z
10
11General description
12-------------------
13Returns the angle of complex z.
14
15###
16
17###
18 Argument (angle) of complex z
19
20 z arg(z)
21 - ------
22
23 a 0
24
25 -a -pi See note 3 below
26
27 (-1)^a a pi
28
29 exp(a + i b) b
30
31 a b arg(a) + arg(b)
32
33 a + i b arctan(b/a)
34
35Result by quadrant
36
37 z arg(z)
38 - ------
39
40 1 + i 1/4 pi
41
42 1 - i -1/4 pi
43
44 -1 + i 3/4 pi
45
46 -1 - i -3/4 pi
47
48Notes
49
50 1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3)
51
52 2. Symbols in z are assumed to be positive and real.
53
54 3. Negative direction adds -pi to angle.
55
56 Example: z = (-1)^(1/3), abs(z) = 1/3 pi, abs(-z) = -2/3 pi
57
58 4. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then
59
60 arg(numerator(z)) - arg(denominator(z))
61
62 must be used to get the correct answer. Now the operation is
63 automatic.
64###
65
66DEBUG_ARG = false
67
68Eval_arg = ->
69 push(cadr(p1))
70 Eval()
71 arg()
72
73arg = ->
74 save()
75 p1 = pop()
76 push(p1)
77 numerator()
78 yyarg()
79 push(p1)
80 denominator()
81 yyarg()
82 subtract()
83 restore()
84
85#define RE p2
86#define IM p3
87
88yyarg = ->
89 save()
90 p1 = pop()
91
92 # case of plain number
93 if (ispositivenumber(p1) or p1 == symbol(PI))
94 if isdouble(p1) or evaluatingAsFloats
95 push_double(0)
96 else
97 push_integer(0)
98 else if (isnegativenumber(p1))
99 if isdouble(p1) or evaluatingAsFloats
100 push_double(Math.PI)
101 else
102 push(symbol(PI))
103 negate()
104
105 # you'd think that something like
106 # arg(a) is always 0 when a is real but no,
107 # arg(a) is pi when a is negative so we have
108 # to leave unexpressed
109 else if (issymbol(p1))
110 push_symbol(ARG)
111 push(p1)
112 list(2)
113
114 else if (car(p1) == symbol(POWER) && equaln(cadr(p1), -1))
115 # -1 to a power
116 if evaluatingAsFloats
117 push_double(Math.PI)
118 else
119 push(symbol(PI))
120 push(caddr(p1))
121 multiply()
122 else if (car(p1) == symbol(POWER) && cadr(p1) == symbol(E))
123 # exponential
124 push(caddr(p1))
125 imag()
126 # arg(a^(1/2)) is always equal to 1/2 * arg(a)
127 # this can obviously be made more generic TODO
128 else if (car(p1) == symbol(POWER) && isoneovertwo(caddr(p1)))
129 if DEBUG_ARG then console.log "arg of a sqrt: " + p1
130 if DEBUG_ARG then debugger
131 push(cadr(p1))
132 arg()
133 if DEBUG_ARG then console.log " = 1/2 * " + stack[tos-1]
134 push(caddr(p1))
135 multiply()
136 else if (car(p1) == symbol(MULTIPLY))
137 # product of factors
138 push_integer(0)
139 p1 = cdr(p1)
140 while (iscons(p1))
141 push(car(p1))
142 arg()
143 add()
144 p1 = cdr(p1)
145 else if (car(p1) == symbol(ADD))
146 # sum of terms
147 push(p1)
148 rect()
149 p1 = pop()
150 push(p1)
151 real()
152 p2 = pop()
153 push(p1)
154 imag()
155 p3 = pop()
156 if (iszero(p2))
157 if evaluatingAsFloats
158 push_double(Math.PI)
159 else
160 push(symbol(PI))
161 if (isnegative(p3))
162 negate()
163 else
164 push(p3)
165 push(p2)
166 divide()
167 arctan()
168 if (isnegative(p2))
169 if evaluatingAsFloats
170 push_double(Math.PI)
171 else
172 push_symbol(PI)
173 if (isnegative(p3))
174 subtract(); # quadrant 1 -> 3
175 else
176 add(); # quadrant 4 -> 2
177 else
178
179 if (!iszero(get_binding(symbol(ASSUME_REAL_VARIABLES))))
180 # if we assume all passed values are real
181 push_integer(0)
182 else
183 # if we don't assume all passed values are real, all
184 # we con do is to leave unexpressed
185 push_symbol(ARG)
186 push(p1)
187 list(2)
188
189
190 restore()
191
192