#ifndef _INPOLY_H_ #define _INPOLY_H_ #include "ACvar.h" /* Very basic polynomials that are not necessarily kept in simplified form. They are used to pass information in, but are quickly converted into a different, more easily manipulated, form. */ /* Each term is an int times 0 or more ACvars or components of point-valued ACvars. E.g., p[1] * x has vars={p, x} and components={1, -999} and coeff=1. */ class InTerm { public: InTerm(ACvar *v, int i) : vars(cons(v)), components(cons(i)), coeff(1) {} InTerm(ACvar *v) : vars(cons(v)), components(cons(-999)), coeff(1) {} InTerm(int i) : vars(NULL), components(NULL), coeff(i) {} InTerm (llist *vars_, llist *components_, int coeff_) : vars(vars_), components(components_), coeff(coeff_) {} InTerm *mult(ACvar *v, int component) const { return new InTerm(cons(v, vars), cons(component, components), coeff); } InTerm *mult(ACvar *v) const { return mult(v, -999); } InTerm *mult(int i) const { return new InTerm(vars, components, coeff * i); } void print(ostream &o) const { bool first = true; if (vars == NULL || coeff == 0) { o << coeff; return; } if (coeff != 1) { o << coeff; first = false; } llist *v = vars; llist *c = components; while (v != NULL) { if (first) first = false; else o << " * "; v->front()->print(o); if (c->front() > 0) o << '[' << c->front() << ']'; v = v->tail(); c = c->tail(); } assert(v == NULL && c == NULL); } private: llist *vars; llist *components; int coeff; }; // The sum of 0 or more terms. class InPoly { public: InPoly(ACvar *v, int component) : terms(cons(new InTerm(v, component))) {} InPoly(InTerm *t) : terms(cons(t)) {} InPoly(llist *t) : terms(t) {} InPoly *add(InPoly *p) const { return new InPoly(append(terms, p->terms)); } InPoly *add(InTerm *t) const { return add(new InPoly(t)); } InPoly *add(int i) const { return add(new InTerm(i)); } InPoly *mult(int i) const { llist *result = NULL; for (llist *t = terms; t != NULL; t = t->tail()) result = cons(t->front()->mult(i), result); return new InPoly(result); } InPoly *mult(ACvar *v) const { llist *result = NULL; for (llist *t = terms; t != NULL; t = t->tail()) result = cons(t->front()->mult(v), result); return new InPoly(result); } InPoly *mult(ACvar *v, int component) const { llist *result = NULL; for (llist *t = terms; t != NULL; t = t->tail()) result = cons(t->front()->mult(v, component), result); return new InPoly(result); } void print(ostream &o) const { if (terms == NULL) o << "0"; else { bool first = true; for (llist *t = terms; t != NULL; t = t->tail()) { if (first) first = false; else o << " + "; t->front()->print(o); } } } llist *terms; }; static inline void print(llist *p, ostream &o) { bool first = true; while (p != NULL) { if (first) first = false; else o << ", "; p->front()->print(o); p = p->tail(); } } #endif // _INPOLY_H_