Little fix after the last commit (mostly a git fail)
[eigenmath-fx.git] / is.cpp
blob4af807d3ce81f72023fbad9a82204f66a97efc8b
1 #include "stdafx.h"
2 #include "defs.h"
4 int
5 iszero(U *p)
7 int i;
8 switch (p->k) {
9 case NUM:
10 if (MZERO(p->u.q.a))
11 return 1;
12 break;
13 case DOUBLE:
14 if (p->u.d == 0.0)
15 return 1;
16 break;
17 case TENSOR:
18 for (i = 0; i < p->u.tensor->nelem; i++)
19 if (!iszero(p->u.tensor->elem[i]))
20 return 0;
21 return 1;
22 default:
23 break;
25 return 0;
28 int
29 isnegativenumber(U *p)
31 switch (p->k) {
32 case NUM:
33 if (MSIGN(p->u.q.a) == -1)
34 return 1;
35 break;
36 case DOUBLE:
37 if (p->u.d < 0.0)
38 return 1;
39 break;
40 default:
41 break;
43 return 0;
46 int
47 isplusone(U *p)
49 switch (p->k) {
50 case NUM:
51 if (MEQUAL(p->u.q.a, 1) && MEQUAL(p->u.q.b, 1))
52 return 1;
53 break;
54 case DOUBLE:
55 if (p->u.d == 1.0)
56 return 1;
57 break;
58 default:
59 break;
61 return 0;
64 int
65 isminusone(U *p)
67 switch (p->k) {
68 case NUM:
69 if (MEQUAL(p->u.q.a, -1) && MEQUAL(p->u.q.b, 1))
70 return 1;
71 break;
72 case DOUBLE:
73 if (p->u.d == -1.0)
74 return 1;
75 break;
76 default:
77 break;
79 return 0;
82 int
83 isinteger(U *p)
85 if (p->k == NUM && MEQUAL(p->u.q.b, 1))
86 return 1;
87 else
88 return 0;
91 int
92 isnonnegativeinteger(U *p)
94 if (isrational(p) && MEQUAL(p->u.q.b, 1) && MSIGN(p->u.q.a) == 1)
95 return 1;
96 else
97 return 0;
101 isposint(U *p)
103 if (isinteger(p) && MSIGN(p->u.q.a) == 1)
104 return 1;
105 else
106 return 0;
110 ispoly(U *p, U *x)
112 if (find(p, x))
113 return ispoly_expr(p, x);
114 else
115 return 0;
119 ispoly_expr(U *p, U *x)
121 if (car(p) == symbol(ADD)) {
122 p = cdr(p);
123 while (iscons(p)) {
124 if (!ispoly_term(car(p), x))
125 return 0;
126 p = cdr(p);
128 return 1;
129 } else
130 return ispoly_term(p, x);
134 ispoly_term(U *p, U *x)
136 if (car(p) == symbol(MULTIPLY)) {
137 p = cdr(p);
138 while (iscons(p)) {
139 if (!ispoly_factor(car(p), x))
140 return 0;
141 p = cdr(p);
143 return 1;
144 } else
145 return ispoly_factor(p, x);
149 ispoly_factor(U *p, U *x)
151 if (equal(p, x))
152 return 1;
153 if (car(p) == symbol(POWER) && equal(cadr(p), x)) {
154 if (isposint(caddr(p)))
155 return 1;
156 else
157 return 0;
159 if (find(p, x))
160 return 0;
161 else
162 return 1;
166 isnegativeterm(U *p)
168 if (isnegativenumber(p))
169 return 1;
170 else if (car(p) == symbol(MULTIPLY) && isnegativenumber(cadr(p)))
171 return 1;
172 else
173 return 0;
177 isimaginarynumber(U *p)
179 if ((car(p) == symbol(MULTIPLY)
180 && length(p) == 3
181 && isnum(cadr(p))
182 && equal(caddr(p), imaginaryunit))
183 || equal(p, imaginaryunit))
184 return 1;
185 else
187 return 0;
191 iscomplexnumber(U *p)
193 if ((car(p) == symbol(ADD)
194 && length(p) == 3
195 && isnum(cadr(p))
196 && isimaginarynumber(caddr(p)))
197 || isimaginarynumber(p))
198 return 1;
199 else
200 return 0;
204 iseveninteger(U *p)
206 if (isinteger(p) && (p->u.q.a[0] & 1) == 0)
207 return 1;
208 else
209 return 0;
213 isnegative(U *p)
215 if (car(p) == symbol(ADD) && isnegativeterm(cadr(p)))
216 return 1;
217 else if (isnegativeterm(p))
218 return 1;
219 else
220 return 0;
223 // returns 1 if there's a symbol somewhere
226 issymbolic(U *p)
228 if (issymbol(p))
229 return 1;
230 else {
231 while (iscons(p)) {
232 if (issymbolic(car(p)))
233 return 1;
234 p = cdr(p);
236 return 0;
240 // i.e. 2, 2^3, etc.
243 isintegerfactor(U *p)
245 if (isinteger(p) || car(p) == symbol(POWER)
246 && isinteger(cadr(p))
247 && isinteger(caddr(p)))
248 return 1;
249 else
250 return 0;
254 isoneover(U *p)
256 if (car(p) == symbol(POWER)
257 && isminusone(caddr(p)))
258 return 1;
259 else
260 return 0;
264 isfraction(U *p)
266 if (p->k == NUM && !MEQUAL(p->u.q.b, 1))
267 return 1;
268 else
269 return 0;
273 equaln(U *p, int n)
275 switch (p->k) {
276 case NUM:
277 if (MEQUAL(p->u.q.a, n) && MEQUAL(p->u.q.b, 1))
278 return 1;
279 break;
280 case DOUBLE:
281 if (p->u.d == (double) n)
282 return 1;
283 break;
284 default:
285 break;
287 return 0;
291 equalq(U *p, int a, int b)
293 switch (p->k) {
294 case NUM:
295 if (MEQUAL(p->u.q.a, a) && MEQUAL(p->u.q.b, b))
296 return 1;
297 break;
298 case DOUBLE:
299 if (p->u.d == (double) a / b)
300 return 1;
301 break;
302 default:
303 break;
305 return 0;
308 // p == 1/sqrt(2) ?
311 isoneoversqrttwo(U *p)
313 if (car(p) == symbol(POWER)
314 && equaln(cadr(p), 2)
315 && equalq(caddr(p), -1, 2))
316 return 1;
317 else
318 return 0;
321 // p == -1/sqrt(2) ?
324 isminusoneoversqrttwo(U *p)
326 if (car(p) == symbol(MULTIPLY)
327 && equaln(cadr(p), -1)
328 && isoneoversqrttwo(caddr(p))
329 && length(p) == 3)
330 return 1;
331 else
332 return 0;
336 isfloating(U *p)
338 if (p->k == DOUBLE)
339 return 1;
340 while (iscons(p)) {
341 if (isfloating(car(p)))
342 return 1;
343 p = cdr(p);
345 return 0;
349 isimaginaryunit(U *p)
351 if (equal(p, imaginaryunit))
352 return 1;
353 else
354 return 0;
357 // n/2 * i * pi ?
359 // return value:
361 // 0 no
363 // 1 1
365 // 2 -1
367 // 3 i
369 // 4 -i
372 isquarterturn(U *p)
374 int n, minussign = 0;
376 if (car(p) != symbol(MULTIPLY))
377 return 0;
379 if (equal(cadr(p), imaginaryunit)) {
381 if (caddr(p) != symbol(PI))
382 return 0;
384 if (length(p) != 3)
385 return 0;
387 return 2;
390 if (!isnum(cadr(p)))
391 return 0;
393 if (!equal(caddr(p), imaginaryunit))
394 return 0;
396 if (cadddr(p) != symbol(PI))
397 return 0;
399 if (length(p) != 4)
400 return 0;
402 push(cadr(p));
403 push_integer(2);
404 multiply();
406 n = pop_integer();
408 if (n == (int) 0x80000000)
409 return 0;
411 if (n < 1) {
412 minussign = 1;
413 n = -n;
416 switch (n % 4) {
417 case 0:
418 n = 1;
419 break;
420 case 1:
421 if (minussign)
422 n = 4;
423 else
424 n = 3;
425 break;
426 case 2:
427 n = 2;
428 break;
429 case 3:
430 if (minussign)
431 n = 3;
432 else
433 n = 4;
434 break;
437 return n;
440 // special multiple of pi?
442 // returns for the following multiples of pi...
444 // -4/2 -3/2 -2/2 -1/2 1/2 2/2 3/2 4/2
446 // 4 1 2 3 1 2 3 4
449 isnpi(U *p)
451 int n;
452 if (p == symbol(PI))
453 return 2;
454 if (car(p) == symbol(MULTIPLY)
455 && isnum(cadr(p))
456 && caddr(p) == symbol(PI)
457 && length(p) == 3)
459 else
460 return 0;
461 push(cadr(p));
462 push_integer(2);
463 multiply();
464 n = pop_integer();
465 if (n == (int) 0x80000000)
466 return 0;
467 if (n < 0)
468 n = 4 - (-n) % 4;
469 else
470 n = 1 + (n - 1) % 4;
471 return n;