eigenmath/bake.cpp

187 lines
2.5 KiB
C++
Raw Permalink Normal View History

2008-04-20 00:36:37 +02:00
// pretty print
2006-02-10 17:21:52 +01:00
#include "stdafx.h"
#include "defs.h"
void
bake(void)
{
2008-04-20 00:36:37 +02:00
int h, s, t, x, y, z;
2006-02-10 17:21:52 +01:00
2006-11-23 22:00:12 +01:00
expanding++;
2006-02-10 17:21:52 +01:00
save();
p1 = pop();
2008-04-20 00:36:37 +02:00
s = ispoly(p1, symbol(SYMBOL_S));
2006-02-10 17:21:52 +01:00
t = ispoly(p1, symbol(SYMBOL_T));
x = ispoly(p1, symbol(SYMBOL_X));
y = ispoly(p1, symbol(SYMBOL_Y));
z = ispoly(p1, symbol(SYMBOL_Z));
2008-04-20 00:36:37 +02:00
if (s == 1 && t == 0 && x == 0 && y == 0 && z == 0) {
p2 = symbol(SYMBOL_S);
bake_poly();
} else if (s == 0 && t == 1 && x == 0 && y == 0 && z == 0) {
2006-02-10 17:21:52 +01:00
p2 = symbol(SYMBOL_T);
bake_poly();
2008-04-20 00:36:37 +02:00
} else if (s == 0 && t == 0 && x == 1 && y == 0 && z == 0) {
2006-02-10 17:21:52 +01:00
p2 = symbol(SYMBOL_X);
bake_poly();
2008-04-20 00:36:37 +02:00
} else if (s == 0 && t == 0 && x == 0 && y == 1 && z == 0) {
2006-02-10 17:21:52 +01:00
p2 = symbol(SYMBOL_Y);
bake_poly();
2008-04-20 00:36:37 +02:00
} else if (s == 0 && t == 0 && x == 0 && y == 0 && z == 1) {
2006-02-10 17:21:52 +01:00
p2 = symbol(SYMBOL_Z);
bake_poly();
2006-02-10 18:01:28 +01:00
} else if (iscons(p1)) {
h = tos;
push(car(p1));
p1 = cdr(p1);
while (iscons(p1)) {
push(car(p1));
bake();
p1 = cdr(p1);
}
list(tos - h);
2006-02-10 17:21:52 +01:00
} else
push(p1);
restore();
2006-11-23 22:00:12 +01:00
expanding--;
2006-02-10 17:21:52 +01:00
}
2006-06-10 01:52:24 +02:00
void
polyform(void)
{
int h;
save();
p2 = pop();
p1 = pop();
if (ispoly(p1, p2))
bake_poly();
else if (iscons(p1)) {
h = tos;
push(car(p1));
p1 = cdr(p1);
while (iscons(p1)) {
push(car(p1));
push(p2);
polyform();
p1 = cdr(p1);
}
list(tos - h);
} else
push(p1);
restore();
}
2006-02-10 17:21:52 +01:00
void
bake_poly()
{
int h, i, k, n;
U **a;
a = stack + tos;
push(p1); // p(x)
push(p2); // x
k = coeff();
h = tos;
for (i = k - 1; i >= 0; i--) {
p1 = a[i];
bake_poly_term(i);
}
n = tos - h;
if (n > 1) {
list(n);
push(symbol(ADD));
swap();
cons();
}
p1 = pop();
tos -= k;
push(p1);
}
// p1 points to coefficient of p2 ^ k
void
bake_poly_term(int k)
{
int h, n;
if (iszero(p1))
return;
// constant term?
if (k == 0) {
if (car(p1) == symbol(ADD)) {
p1 = cdr(p1);
while (iscons(p1)) {
push(car(p1));
p1 = cdr(p1);
}
} else
push(p1);
return;
}
h = tos;
// coefficient
if (car(p1) == symbol(MULTIPLY)) {
p1 = cdr(p1);
while (iscons(p1)) {
push(car(p1));
p1 = cdr(p1);
}
} else if (!equaln(p1, 1))
push(p1);
// x ^ k
if (k == 1)
push(p2);
else {
push(symbol(POWER));
push(p2);
push_integer(k);
list(3);
}
n = tos - h;
if (n > 1) {
list(n);
push(symbol(MULTIPLY));
swap();
cons();
}
}
2006-02-10 17:33:41 +01:00
2007-05-08 16:57:30 +02:00
#if SELFTEST
2006-02-10 17:33:41 +01:00
static char *s[] = {
"(x+3)^3",
"x^3+9*x^2+27*x+27",
2006-02-10 18:01:28 +01:00
"factor",
"(x+3)^3",
2006-02-10 17:33:41 +01:00
};
void
test_bake(void)
{
test(__FILE__, s, sizeof s / sizeof (char *));
}
2007-05-08 16:57:30 +02:00
#endif