1 |
|
2 |
|
3 | DEBUG_IS = false
|
4 |
|
5 |
|
6 | iszero = (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 |
|
23 | isnegativenumber = (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 |
|
34 | ispositivenumber = (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 |
|
45 | isplustwo = (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 |
|
56 | isplusone = (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 |
|
66 | isminusone = (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 |
|
76 | isone = (p) ->
|
77 | return isplusone(p) or isminusone(p)
|
78 |
|
79 | isinteger = (p) ->
|
80 | if (p.k == NUM && MEQUAL(p.q.b, 1))
|
81 | return 1
|
82 | else
|
83 | return 0
|
84 |
|
85 | isintegerorintegerfloat = (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 |
|
92 | isnonnegativeinteger = (p) ->
|
93 | if (isrational(p) && MEQUAL(p.q.b, 1) && MSIGN(p.q.a) == 1)
|
94 | return 1
|
95 | else
|
96 | return 0
|
97 |
|
98 | isposint = (p) ->
|
99 | if (isinteger(p) && MSIGN(p.q.a) == 1)
|
100 | return 1
|
101 | else
|
102 | return 0
|
103 |
|
104 |
|
105 | ispoly = (p,x) ->
|
106 | if (Find(p, x))
|
107 | return ispoly_expr(p, x)
|
108 | else
|
109 | return 0
|
110 |
|
111 | ispoly_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 |
|
122 | ispoly_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 |
|
133 | ispoly_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 |
|
146 | isnegativeterm = (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 |
|
154 | hasNegativeRationalExponent = (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 |
|
164 | isimaginarynumberdouble = (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 |
|
174 | isimaginarynumber = (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 |
|
188 | iscomplexnumberdouble = (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 |
|
198 | iscomplexnumber = (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 |
|
211 | iseveninteger = (p) ->
|
212 | if isinteger(p) && p.q.a.isEven()
|
213 | return 1
|
214 | else
|
215 | return 0
|
216 |
|
217 | isnegative = (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 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 | issymbolic = (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 |
|
241 |
|
242 | isintegerfactor = (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 |
|
250 | isnumberoneoversomething = (p) ->
|
251 | if isfraction(p) \
|
252 | && Math.abs(p.q.a.value) == 1
|
253 | return 1
|
254 | else
|
255 | return 0
|
256 |
|
257 |
|
258 | isoneover = (p) ->
|
259 | if (car(p) == symbol(POWER) \
|
260 | && isminusone(caddr(p)))
|
261 | return 1
|
262 | else
|
263 | return 0
|
264 |
|
265 | isfraction = (p) ->
|
266 | if (p.k == NUM && !MEQUAL(p.q.b, 1))
|
267 | return 1
|
268 | else
|
269 | return 0
|
270 |
|
271 |
|
272 | equaln = (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 |
|
283 | equalq = (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 |
|
294 |
|
295 | isoneovertwo = (p) ->
|
296 | if equalq(p, 1, 2)
|
297 | return 1
|
298 | else
|
299 | return 0
|
300 |
|
301 |
|
302 | isminusoneovertwo = (p) ->
|
303 | if equalq(p, -1, 2)
|
304 | return 1
|
305 | else
|
306 | return 0
|
307 |
|
308 |
|
309 |
|
310 |
|
311 | isoneoversqrttwo = (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 |
|
320 |
|
321 | isminusoneoversqrttwo = (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 |
|
330 | isfloating = (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 |
|
339 | isimaginaryunit = (p) ->
|
340 | if (equal(p, imaginaryunit))
|
341 | return 1
|
342 | else
|
343 | return 0
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 |
|
353 |
|
354 |
|
355 |
|
356 |
|
357 |
|
358 |
|
359 | isquarterturn = (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 |
|
420 |
|
421 |
|
422 |
|
423 |
|
424 |
|
425 |
|
426 |
|
427 | isnpi = (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 |
|