1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | DEBUG_POWER = false
|
11 |
|
12 | Eval_power = ->
|
13 | if DEBUG_POWER then debugger
|
14 | push(cadr(p1))
|
15 | Eval()
|
16 | push(caddr(p1))
|
17 | Eval()
|
18 | power()
|
19 |
|
20 | power = ->
|
21 | save()
|
22 | yypower()
|
23 | restore()
|
24 |
|
25 | yypower = ->
|
26 | if DEBUG_POWER then debugger
|
27 | n = 0
|
28 |
|
29 | p2 = pop()
|
30 | p1 = pop()
|
31 |
|
32 | inputExp = p2
|
33 | inputBase = p1
|
34 |
|
35 |
|
36 | if DEBUG_POWER
|
37 | console.log("POWER: " + p1 + " ^ " + p2)
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | if (equal(p1, one) || iszero(p2))
|
44 | if evaluatingAsFloats then push_double(1.0) else push(one)
|
45 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
46 | return
|
47 |
|
48 |
|
49 | if (equal(p2, one))
|
50 | push(p1)
|
51 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
52 | return
|
53 |
|
54 |
|
55 | if (isminusone(p1) and isminusone(p2))
|
56 | if evaluatingAsFloats then push_double(1.0) else push(one)
|
57 | negate()
|
58 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
59 | return
|
60 |
|
61 |
|
62 | if (isminusone(p1) and (isoneovertwo(p2)))
|
63 | push(imaginaryunit)
|
64 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
65 | return
|
66 |
|
67 |
|
68 | if (isminusone(p1) and isminusoneovertwo(p2))
|
69 | push(imaginaryunit)
|
70 | negate()
|
71 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
72 | return
|
73 |
|
74 |
|
75 | if (isminusone(p1) and !isdouble(p1) and isrational(p2) and !isinteger(p2) and ispositivenumber(p2) and !evaluatingAsFloats)
|
76 | if DEBUG_POWER then console.log(" power: -1 ^ rational")
|
77 | if DEBUG_POWER then console.log " trick: p2.q.a , p2.q.b " + p2.q.a + " , " + p2.q.b
|
78 | if p2.q.a < p2.q.b
|
79 | push_symbol(POWER)
|
80 | push(p1)
|
81 | push(p2)
|
82 | list(3)
|
83 | else
|
84 | push_symbol(MULTIPLY)
|
85 |
|
86 | push(p1)
|
87 |
|
88 | push_symbol(POWER)
|
89 | push(p1)
|
90 | push_rational(p2.q.a.mod(p2.q.b), p2.q.b)
|
91 | list(3)
|
92 |
|
93 | list(3)
|
94 | if DEBUG_POWER then console.log " trick applied : " + stack[tos-1]
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | rect()
|
100 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
101 | return
|
102 |
|
103 |
|
104 |
|
105 |
|
106 | if (isrational(p1) && isrational(p2))
|
107 | if DEBUG_POWER then console.log(" power: isrational(p1) && isrational(p2)")
|
108 | push(p1)
|
109 | push(p2)
|
110 | qpow()
|
111 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
112 | return
|
113 |
|
114 |
|
115 | if (isnum(p1) && isnum(p2))
|
116 | if DEBUG_POWER then console.log " power: both base and exponent are either rational or double "
|
117 | if DEBUG_POWER then console.log("POWER - isnum(p1) && isnum(p2)")
|
118 | push(p1)
|
119 | push(p2)
|
120 | dpow()
|
121 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
122 | return
|
123 |
|
124 | if (istensor(p1))
|
125 | if DEBUG_POWER then console.log " power: istensor(p1) "
|
126 | power_tensor()
|
127 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
128 | return
|
129 |
|
130 |
|
131 |
|
132 | if (car(p1) == symbol(ABS) && iseveninteger(p2) and !iszero(get_binding(symbol(ASSUME_REAL_VARIABLES))))
|
133 | if DEBUG_POWER then console.log " power: even power of absolute of real value "
|
134 | push(cadr(p1))
|
135 | push(p2)
|
136 | power()
|
137 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
138 | return
|
139 |
|
140 |
|
141 | if (p1 == symbol(E) && car(p2) == symbol(LOG))
|
142 | push(cadr(p2))
|
143 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
144 | return
|
145 |
|
146 |
|
147 | if (p1 == symbol(E) && isdouble(p2))
|
148 | if DEBUG_POWER then console.log " power: p1 == symbol(E) && isdouble(p2) "
|
149 | push_double(Math.exp(p2.d))
|
150 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
151 | return
|
152 |
|
153 |
|
154 |
|
155 |
|
156 | if (p1 == symbol(E) && Find(p2, imaginaryunit) != 0 and Find(p2, symbol(PI))!= 0 and !evaluatingPolar)
|
157 | push_symbol(POWER)
|
158 | push(p1)
|
159 | push(p2)
|
160 | list(3)
|
161 | if DEBUG_POWER then console.log " power: turning complex exponential to rect: " + stack[tos-1]
|
162 | rect()
|
163 |
|
164 | hopefullySimplified = pop();
|
165 | if Find(hopefullySimplified, symbol(PI)) == 0
|
166 | if DEBUG_POWER then console.log " power: turned complex exponential to rect: " + hopefullySimplified
|
167 | push hopefullySimplified
|
168 | return
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 | if (car(p1) == symbol(MULTIPLY) && isinteger(p2))
|
178 | if DEBUG_POWER then console.log " power: (a * b) ^ c -> (a ^ c) * (b ^ c) "
|
179 | p1 = cdr(p1)
|
180 | push(car(p1))
|
181 | push(p2)
|
182 | power()
|
183 | p1 = cdr(p1)
|
184 | while (iscons(p1))
|
185 | push(car(p1))
|
186 | push(p2)
|
187 | power()
|
188 | multiply()
|
189 | p1 = cdr(p1)
|
190 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
191 | return
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 | is_a_moreThanZero = false
|
202 | if isnum(cadr(p1))
|
203 | is_a_moreThanZero = sign(compare_numbers(cadr(p1), zero))
|
204 |
|
205 | if (car(p1) == symbol(POWER) && (
|
206 | isinteger(p2) or
|
207 | is_a_moreThanZero
|
208 | ))
|
209 | push(cadr(p1))
|
210 | push(caddr(p1))
|
211 | push(p2)
|
212 | multiply()
|
213 | power()
|
214 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
215 | return
|
216 |
|
217 | b_isEven_and_c_isItsInverse = false
|
218 | if iseveninteger(caddr(p1))
|
219 | push caddr(p1)
|
220 | push p2
|
221 | multiply()
|
222 |
|
223 | isThisOne = pop()
|
224 | if isone(isThisOne)
|
225 | b_isEven_and_c_isItsInverse = true
|
226 |
|
227 | if (car(p1) == symbol(POWER) && b_isEven_and_c_isItsInverse)
|
228 | if DEBUG_POWER then console.log " power: car(p1) == symbol(POWER) && b_isEven_and_c_isItsInverse "
|
229 | push(cadr(p1))
|
230 | abs()
|
231 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
232 | return
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 | if (expanding && isadd(p1) && isnum(p2))
|
239 | push(p2)
|
240 | n = pop_integer()
|
241 | if (n > 1 && !isNaN(n))
|
242 | if DEBUG_POWER then console.log " power: expanding && isadd(p1) && isnum(p2) "
|
243 | power_sum(n)
|
244 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
245 | return
|
246 |
|
247 |
|
248 |
|
249 | if (trigmode == 1 && car(p1) == symbol(SIN) && iseveninteger(p2))
|
250 | if DEBUG_POWER then console.log " power: trigmode == 1 && car(p1) == symbol(SIN) && iseveninteger(p2) "
|
251 | push_integer(1)
|
252 | push(cadr(p1))
|
253 | cosine()
|
254 | push_integer(2)
|
255 | power()
|
256 | subtract()
|
257 | push(p2)
|
258 | push_rational(1, 2)
|
259 | multiply()
|
260 | power()
|
261 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
262 | return
|
263 |
|
264 |
|
265 |
|
266 | if (trigmode == 2 && car(p1) == symbol(COS) && iseveninteger(p2))
|
267 | if DEBUG_POWER then console.log " power: trigmode == 2 && car(p1) == symbol(COS) && iseveninteger(p2) "
|
268 | push_integer(1)
|
269 | push(cadr(p1))
|
270 | sine()
|
271 | push_integer(2)
|
272 | power()
|
273 | subtract()
|
274 | push(p2)
|
275 | push_rational(1, 2)
|
276 | multiply()
|
277 | power()
|
278 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
279 | return
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 | if (iscomplexnumber(p1))
|
286 |
|
287 | if DEBUG_POWER then console.log " power - handling the case (a + ib) ^ n"
|
288 |
|
289 |
|
290 |
|
291 |
|
292 | if (isinteger(p2))
|
293 |
|
294 |
|
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 | push(p1)
|
301 | conjugate()
|
302 | p3 = pop()
|
303 | push(p3)
|
304 |
|
305 |
|
306 | push(p3)
|
307 | push(p1)
|
308 | multiply()
|
309 |
|
310 | divide()
|
311 |
|
312 | if !isone(p2)
|
313 | push(p2)
|
314 | negate()
|
315 | power()
|
316 |
|
317 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
318 | return
|
319 |
|
320 |
|
321 |
|
322 | if (isnum(p2))
|
323 | push(p1)
|
324 | abs()
|
325 | push(p2)
|
326 | power()
|
327 | push_integer(-1)
|
328 | push(p1)
|
329 | arg()
|
330 | push(p2)
|
331 | multiply()
|
332 | if evaluatingAsFloats or (iscomplexnumberdouble(p1) and isdouble(p2))
|
333 |
|
334 |
|
335 |
|
336 |
|
337 | push_double(Math.PI)
|
338 | else
|
339 |
|
340 | push(symbol(PI))
|
341 | divide()
|
342 | power()
|
343 | multiply()
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 |
|
350 | if avoidCalculatingPowersIntoArctans
|
351 | if Find(stack[tos-1], symbol(ARCTAN))
|
352 | pop()
|
353 | push_symbol(POWER)
|
354 | push(p1)
|
355 | push(p2)
|
356 | list(3)
|
357 |
|
358 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
359 | return
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 |
|
377 | if (simplify_polar())
|
378 | if DEBUG_POWER then console.log " power: using simplify_polar"
|
379 | return
|
380 |
|
381 |
|
382 |
|
383 | if DEBUG_POWER then console.log " power: nothing can be done "
|
384 | push_symbol(POWER)
|
385 | push(p1)
|
386 | push(p2)
|
387 | list(3)
|
388 | if DEBUG_POWER then console.log " power of " + inputBase + " ^ " + inputExp + ": " + stack[tos-1]
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 |
|
399 |
|
400 |
|
401 |
|
402 |
|
403 |
|
404 |
|
405 |
|
406 |
|
407 |
|
408 |
|
409 |
|
410 |
|
411 |
|
412 |
|
413 |
|
414 |
|
415 |
|
416 | power_sum = (n) ->
|
417 | a = []
|
418 | i = 0
|
419 | j = 0
|
420 | k = 0
|
421 |
|
422 |
|
423 |
|
424 | k = length(p1) - 1
|
425 |
|
426 |
|
427 |
|
428 | push_frame(k * (n + 1))
|
429 |
|
430 |
|
431 |
|
432 | p1 = cdr(p1)
|
433 | for i in [0...k]
|
434 | for j in [0..n]
|
435 | push(car(p1))
|
436 | push_integer(j)
|
437 | power()
|
438 | stack[frame + (i) * (n + 1) + (j)] = pop()
|
439 | p1 = cdr(p1)
|
440 |
|
441 | push_integer(n)
|
442 | factorial()
|
443 | p1 = pop()
|
444 |
|
445 | for i in [0...k]
|
446 | a[i] = 0
|
447 |
|
448 | push(zero)
|
449 |
|
450 | multinomial_sum(k, n, a, 0, n)
|
451 |
|
452 | pop_frame(k * (n + 1))
|
453 |
|
454 |
|
455 |
|
456 |
|
457 |
|
458 |
|
459 |
|
460 |
|
461 |
|
462 |
|
463 |
|
464 |
|
465 |
|
466 |
|
467 |
|
468 |
|
469 |
|
470 |
|
471 |
|
472 |
|
473 |
|
474 |
|
475 |
|
476 |
|
477 |
|
478 |
|
479 |
|
480 |
|
481 | multinomial_sum = (k,n,a,i,m) ->
|
482 | j = 0
|
483 |
|
484 | if (i < k - 1)
|
485 | for j in [0..m]
|
486 | a[i] = j
|
487 | multinomial_sum(k, n, a, i + 1, m - j)
|
488 | return
|
489 |
|
490 | a[i] = m
|
491 |
|
492 |
|
493 |
|
494 | push(p1)
|
495 |
|
496 | for j in [0...k]
|
497 | push_integer(a[j])
|
498 | factorial()
|
499 | divide()
|
500 |
|
501 |
|
502 |
|
503 | for j in [0...k]
|
504 | push(stack[frame + (j) * (n + 1) + a[j]])
|
505 | multiply()
|
506 |
|
507 | add()
|
508 |
|
509 |
|
510 |
|
511 |
|
512 |
|
513 |
|
514 |
|
515 | simplify_polar = ->
|
516 | n = 0
|
517 |
|
518 | n = isquarterturn(p2)
|
519 |
|
520 | switch(n)
|
521 | when 0
|
522 | doNothing = 1
|
523 | when 1
|
524 | push_integer(1)
|
525 | return 1
|
526 | when 2
|
527 | push_integer(-1)
|
528 | return 1
|
529 | when 3
|
530 | push(imaginaryunit)
|
531 | return 1
|
532 | when 4
|
533 | push(imaginaryunit)
|
534 | negate()
|
535 | return 1
|
536 |
|
537 | if (car(p2) == symbol(ADD))
|
538 | p3 = cdr(p2)
|
539 | while (iscons(p3))
|
540 | n = isquarterturn(car(p3))
|
541 | if (n)
|
542 | break
|
543 | p3 = cdr(p3)
|
544 | switch (n)
|
545 | when 0
|
546 | return 0
|
547 | when 1
|
548 | push_integer(1)
|
549 | when 2
|
550 | push_integer(-1)
|
551 | when 3
|
552 | push(imaginaryunit)
|
553 | when 4
|
554 | push(imaginaryunit)
|
555 | negate()
|
556 | push(p2)
|
557 | push(car(p3))
|
558 | subtract()
|
559 | exponential()
|
560 | multiply()
|
561 | return 1
|
562 |
|
563 | return 0
|
564 |
|
565 |
|
566 |
|