UNPKG

8.55 kBtext/coffeescriptView Raw
1
2
3DEBUG_IS = false
4
5# p is a U
6iszero = (p) ->
7 i = 0
8 switch (p.k)
9 when NUM
10 if (MZERO(p.q.a))
11 return 1
12 when DOUBLE
13 if (p.d == 0.0)
14 return 1
15 when TENSOR
16 for i in [0...p.tensor.nelem]
17 if (!iszero(p.tensor.elem[i]))
18 return 0
19 return 1
20 return 0
21
22# p is a U
23isnegativenumber = (p) ->
24 switch (p.k)
25 when NUM
26 if (MSIGN(p.q.a) == -1)
27 return 1
28 when DOUBLE
29 if (p.d < 0.0)
30 return 1
31 return 0
32
33# p is a U
34ispositivenumber = (p) ->
35 switch (p.k)
36 when NUM
37 if (MSIGN(p.q.a) == 1)
38 return 1
39 when DOUBLE
40 if (p.d > 0.0)
41 return 1
42 return 0
43
44# p is a U
45isplustwo = (p) ->
46 switch (p.k)
47 when NUM
48 if (MEQUAL(p.q.a, 2) && MEQUAL(p.q.b, 1))
49 return 1
50 when DOUBLE
51 if (p.d == 2.0)
52 return 1
53 return 0
54
55# p is a U
56isplusone = (p) ->
57 switch (p.k)
58 when NUM
59 if (MEQUAL(p.q.a, 1) && MEQUAL(p.q.b, 1))
60 return 1
61 when DOUBLE
62 if (p.d == 1.0)
63 return 1
64 return 0
65
66isminusone = (p) ->
67 switch (p.k)
68 when NUM
69 if (MEQUAL(p.q.a, -1) && MEQUAL(p.q.b, 1))
70 return 1
71 when DOUBLE
72 if (p.d == -1.0)
73 return 1
74 return 0
75
76isone = (p) ->
77 return isplusone(p) or isminusone(p)
78
79isinteger = (p) ->
80 if (p.k == NUM && MEQUAL(p.q.b, 1))
81 return 1
82 else
83 return 0
84
85isintegerorintegerfloat = (p) ->
86 if p.k == DOUBLE
87 if (p.d == Math.round(p.d))
88 return 1
89 return 0
90 return isinteger(p)
91
92isnonnegativeinteger = (p) ->
93 if (isrational(p) && MEQUAL(p.q.b, 1) && MSIGN(p.q.a) == 1)
94 return 1
95 else
96 return 0
97
98isposint = (p) ->
99 if (isinteger(p) && MSIGN(p.q.a) == 1)
100 return 1
101 else
102 return 0
103
104# both p,x are U
105ispoly = (p,x) ->
106 if (Find(p, x))
107 return ispoly_expr(p, x)
108 else
109 return 0
110
111ispoly_expr = (p,x) ->
112 if (car(p) == symbol(ADD))
113 p = cdr(p)
114 while (iscons(p))
115 if (!ispoly_term(car(p), x))
116 return 0
117 p = cdr(p)
118 return 1
119 else
120 return ispoly_term(p, x)
121
122ispoly_term = (p,x) ->
123 if (car(p) == symbol(MULTIPLY))
124 p = cdr(p)
125 while (iscons(p))
126 if (!ispoly_factor(car(p), x))
127 return 0
128 p = cdr(p)
129 return 1
130 else
131 return ispoly_factor(p, x)
132
133ispoly_factor = (p,x) ->
134 if (equal(p, x))
135 return 1
136 if (car(p) == symbol(POWER) && equal(cadr(p), x))
137 if (isposint(caddr(p)))
138 return 1
139 else
140 return 0
141 if (Find(p, x))
142 return 0
143 else
144 return 1
145
146isnegativeterm = (p) ->
147 if (isnegativenumber(p))
148 return 1
149 else if (car(p) == symbol(MULTIPLY) && isnegativenumber(cadr(p)))
150 return 1
151 else
152 return 0
153
154hasNegativeRationalExponent = (p) ->
155 if (car(p) == symbol(POWER) \
156 && isrational(car(cdr(cdr(p)))) \
157 && isnegativenumber(car(cdr(p))))
158 if DEBUG_IS then console.log "hasNegativeRationalExponent: " + p.toString() + " has imaginary component"
159 return 1
160 else
161 if DEBUG_IS then console.log "hasNegativeRationalExponent: " + p.toString() + " has NO imaginary component"
162 return 0
163
164isimaginarynumberdouble = (p) ->
165 if ((car(p) == symbol(MULTIPLY) \
166 && length(p) == 3 \
167 && isdouble(cadr(p)) \
168 && hasNegativeRationalExponent(caddr(p))) \
169 || equal(p, imaginaryunit))
170 return 1
171 else
172 return 0
173
174isimaginarynumber = (p) ->
175 if ((car(p) == symbol(MULTIPLY) \
176 && length(p) == 3 \
177 && isnum(cadr(p)) \
178 && equal(caddr(p), imaginaryunit)) \
179 || equal(p, imaginaryunit) \
180 || hasNegativeRationalExponent(caddr(p))
181 )
182 if DEBUG_IS then console.log "isimaginarynumber: " + p.toString() + " is imaginary number"
183 return 1
184 else
185 if DEBUG_IS then console.log "isimaginarynumber: " + p.toString() + " isn't an imaginary number"
186 return 0
187
188iscomplexnumberdouble = (p) ->
189 if ((car(p) == symbol(ADD) \
190 && length(p) == 3 \
191 && isdouble(cadr(p)) \
192 && isimaginarynumberdouble(caddr(p))) \
193 || isimaginarynumberdouble(p))
194 return 1
195 else
196 return 0
197
198iscomplexnumber = (p) ->
199 if DEBUG_IS then debugger
200 if ((car(p) == symbol(ADD) \
201 && length(p) == 3 \
202 && isnum(cadr(p)) \
203 && isimaginarynumber(caddr(p))) \
204 || isimaginarynumber(p))
205 if DEBUG then console.log "iscomplexnumber: " + p.toString() + " is imaginary number"
206 return 1
207 else
208 if DEBUG then console.log "iscomplexnumber: " + p.toString() + " is imaginary number"
209 return 0
210
211iseveninteger = (p) ->
212 if isinteger(p) && p.q.a.isEven()
213 return 1
214 else
215 return 0
216
217isnegative = (p) ->
218 if (car(p) == symbol(ADD) && isnegativeterm(cadr(p)))
219 return 1
220 else if (isnegativeterm(p))
221 return 1
222 else
223 return 0
224
225# returns 1 if there's a symbol somewhere.
226# not used anywhere. Note that PI and POWER are symbols,
227# so for example 2^3 would be symbolic
228# while -1^(1/2) i.e. 'i' is not, so this can
229# be tricky to use.
230issymbolic = (p) ->
231 if (issymbol(p))
232 return 1
233 else
234 while (iscons(p))
235 if (issymbolic(car(p)))
236 return 1
237 p = cdr(p)
238 return 0
239
240# i.e. 2, 2^3, etc.
241
242isintegerfactor = (p) ->
243 if (isinteger(p) || car(p) == symbol(POWER) \
244 && isinteger(cadr(p)) \
245 && isinteger(caddr(p)))
246 return 1
247 else
248 return 0
249
250isnumberoneoversomething = (p) ->
251 if isfraction(p) \
252 && Math.abs(p.q.a.value) == 1
253 return 1
254 else
255 return 0
256
257
258isoneover = (p) ->
259 if (car(p) == symbol(POWER) \
260 && isminusone(caddr(p)))
261 return 1
262 else
263 return 0
264
265isfraction = (p) ->
266 if (p.k == NUM && !MEQUAL(p.q.b, 1))
267 return 1
268 else
269 return 0
270
271# p is a U, n an int
272equaln = (p,n) ->
273 switch (p.k)
274 when NUM
275 if (MEQUAL(p.q.a, n) && MEQUAL(p.q.b, 1))
276 return 1
277 when DOUBLE
278 if (p.d == n)
279 return 1
280 return 0
281
282# p is a U, a and b ints
283equalq = (p, a, b) ->
284 switch (p.k)
285 when NUM
286 if (MEQUAL(p.q.a, a) && MEQUAL(p.q.b, b))
287 return 1
288 when DOUBLE
289 if (p.d == a / b)
290 return 1
291 return 0
292
293# p == 1/2 ?
294
295isoneovertwo = (p) ->
296 if equalq(p, 1, 2)
297 return 1
298 else
299 return 0
300
301# p == -1/2 ?
302isminusoneovertwo = (p) ->
303 if equalq(p, -1, 2)
304 return 1
305 else
306 return 0
307
308
309# p == 1/sqrt(2) ?
310
311isoneoversqrttwo = (p) ->
312 if (car(p) == symbol(POWER) \
313 && equaln(cadr(p), 2) \
314 && equalq(caddr(p), -1, 2))
315 return 1
316 else
317 return 0
318
319# p == -1/sqrt(2) ?
320
321isminusoneoversqrttwo = (p) ->
322 if (car(p) == symbol(MULTIPLY) \
323 && equaln(cadr(p), -1) \
324 && isoneoversqrttwo(caddr(p)) \
325 && length(p) == 3)
326 return 1
327 else
328 return 0
329
330isfloating = (p) ->
331 if p.k == DOUBLE or p == symbol(FLOATF)
332 return 1
333 while (iscons(p))
334 if (isfloating(car(p)))
335 return 1
336 p = cdr(p)
337 return 0
338
339isimaginaryunit = (p) ->
340 if (equal(p, imaginaryunit))
341 return 1
342 else
343 return 0
344
345# n/2 * i * pi ?
346
347# return value:
348
349# 0 no
350
351# 1 1
352
353# 2 -1
354
355# 3 i
356
357# 4 -i
358
359isquarterturn = (p) ->
360 n = 0
361 minussign = 0
362
363 if (car(p) != symbol(MULTIPLY))
364 return 0
365
366 if (equal(cadr(p), imaginaryunit))
367
368 if (caddr(p) != symbol(PI))
369 return 0
370
371 if (length(p) != 3)
372 return 0
373
374 return 2
375
376 if (!isnum(cadr(p)))
377 return 0
378
379 if (!equal(caddr(p), imaginaryunit))
380 return 0
381
382 if (cadddr(p) != symbol(PI))
383 return 0
384
385 if (length(p) != 4)
386 return 0
387
388 push(cadr(p))
389 push_integer(2)
390 multiply()
391
392 n = pop_integer()
393
394 if (isNaN(n))
395 return 0
396
397 if (n < 1)
398 minussign = 1
399 n = -n
400
401 switch (n % 4)
402 when 0
403 n = 1
404 when 1
405 if (minussign)
406 n = 4
407 else
408 n = 3
409 when 2
410 n = 2
411 when 3
412 if (minussign)
413 n = 3
414 else
415 n = 4
416
417 return n
418
419# special multiple of pi?
420
421# returns for the following multiples of pi...
422
423# -4/2 -3/2 -2/2 -1/2 1/2 2/2 3/2 4/2
424
425# 4 1 2 3 1 2 3 4
426
427isnpi = (p) ->
428 n = 0
429 if (p == symbol(PI))
430 return 2
431 if (car(p) == symbol(MULTIPLY) \
432 && isnum(cadr(p)) \
433 && caddr(p) == symbol(PI) \
434 && length(p) == 3)
435 doNothing = 0
436 else
437 return 0
438 push(cadr(p))
439 push_integer(2)
440 multiply()
441 n = pop_integer()
442 if (isNaN(n))
443 return 0
444 if (n < 0)
445 n = 4 - (-n) % 4
446 else
447 n = 1 + (n - 1) % 4
448 return n
449
450
451
452$.iszero = iszero
453$.isnegativenumber = isnegativenumber
454$.isplusone = isplusone
455$.isminusone = isminusone
456$.isinteger = isinteger
457$.isnonnegativeinteger = isnonnegativeinteger
458$.isposint = isposint
459$.isnegativeterm = isnegativeterm
460$.isimaginarynumber = isimaginarynumber
461$.iscomplexnumber = iscomplexnumber
462$.iseveninteger = iseveninteger
463$.isnegative = isnegative
464$.issymbolic = issymbolic
465$.isintegerfactor = isintegerfactor
466$.isoneover = isoneover
467$.isfraction = isfraction
468$.isoneoversqrttwo = isoneoversqrttwo
469$.isminusoneoversqrttwo = isminusoneoversqrttwo
470$.isfloating = isfloating
471$.isimaginaryunit = isimaginaryunit
472$.isquarterturn = isquarterturn
473$.isnpi = isnpi
474