// combines terms, gets ried of any 0 terms // actually recreates the polynomial with accurate space void deep_reduce_poly(Polynomial **orig) { int orig_num; Polynomial *newp; Polynomial *p = *orig; orig_num = p->num_terms; // just lazy reduce, and then resize if necessary reduce_poly(p); // no reduction needed if (p->num_terms == orig_num) return; newp = (Polynomial *) malloc(sizeof(Polynomial)); newp->vars = (char *) malloc(sizeof(char) * p->num_vars); memcpy(newp->vars, p->vars, sizeof(char) * p->num_vars); newp->num_vars = p->num_vars; newp->num_terms = p->num_terms; newp->ordering = p->ordering; newp->terms = (Term *) malloc(sizeof(Term) * p->num_terms); for (int i = 0; i < p->num_terms; i++) { newp->terms[i].coeff.num = p->terms[i].coeff.num; newp->terms[i].coeff.den = p->terms[i].coeff.den; newp->terms[i].pow = (int *) malloc(sizeof(int) * p->num_vars); memcpy(newp->terms[i].pow, p->terms[i].pow, sizeof(int) * p->num_vars); } p->num_terms = orig_num; free_polynomial(p); *orig = newp; }
static void delete_polys(void) { uint32_t i; for (i=0; i<NPOLYS; i++) { if (poly[i] != NULL) { free_polynomial(poly[i]); } } }
// returns the S-polynomial Polynomial *s_poly(Polynomial *p1, Polynomial *p2){ Term *t1, *t2, *m1, *m2; Term *lcm, *f1, *f2; Polynomial *new1, *new2, *res; t1 = leading_term(p1); t2 = leading_term(p2); m1 = leading_monomial(p1); m2 = leading_monomial(p2); lcm = term_lcm(m1, m2, p1->num_vars); f1 = (Term *) malloc(sizeof(Term)); f2 = (Term *) malloc(sizeof(Term)); f1->pow = (int *) malloc(sizeof(int) * p1->num_vars); f2->pow = (int *) malloc(sizeof(int) * p1->num_vars); divide_terms(lcm, m1, f1, p1->num_vars); divide_terms(lcm, m2, f2, p1->num_vars); // mutiply factors by opposite leading coefficients f1->coeff.num = f1->coeff.num * t2->coeff.num; f1->coeff.den = f1->coeff.den * t2->coeff.den; f2->coeff.num = f2->coeff.num * t1->coeff.num; f2->coeff.den = f2->coeff.den * t1->coeff.den; new1 = term_multiply_poly(p1, f1); new2 = term_multiply_poly(p2, f2); res = subtract_polys(new1, new2); // free all this intermediate stuff free_term(t1); free_term(t2); free_term(m1); free_term(m2); free_term(f1); free_term(f2); free_term(lcm); free_polynomial(new1); free_polynomial(new2); sort_polynomial(res); return res; }
// resizes the existing polynomial to hold twice the terms void double_poly(Polynomial *p) { Polynomial *newp; newp = empty_poly(p->num_vars, 2*p->num_terms, p->vars); newp->ordering = p->ordering; memcpy(newp->vars, p->vars, sizeof(char) * p->num_vars); for (int i = 0; i < p->num_terms; i++){ newp->terms[i].coeff.num = p->terms[i].coeff.num; newp->terms[i].coeff.den = p->terms[i].coeff.den; memcpy(newp->terms[i].pow, p->terms[i].pow, sizeof(int) * p->num_vars); } free_polynomial(p); p = newp; }
/* * Delete the arrays */ static void delete_poly_table(poly_table_t *table) { polynomial_t *p; uint32_t i, n; n = table->npolys; for (i=1; i<n; i++) { p = table->poly[i]; if (p != NULL) { free_polynomial(p); } } safe_free(table->poly); safe_free(table->var); table->poly = NULL; table->var = NULL; }