/* * Build P(b, v) (i.e., convert b to a polynomial then reset b). * SIDE EFFECT: b is reset to the zero polynomial. */ polynomial_t *arith_buffer_get_poly(arith_buffer_t *b, int32_t *v) { polynomial_t *tmp; mlist_t *q, *next; uint32_t n, i; n = b->nterms; tmp = alloc_raw_polynomial(n); q = b->list; for (i=0; i<n; i++) { assert(q->prod != end_pp && v[i] < max_idx); // monomial i: coeff = q->coeff, var = v[i] tmp->mono[i].var = v[i]; q_copy_and_clear(&tmp->mono[i].coeff, &q->coeff); // delete the list element next = q->next; objstore_free(b->store, q); q = next; } // empty the monomial list in b assert(q->next == NULL && q->prod == end_pp); b->nterms = 0; b->list = q; assert(tmp->mono[n].var == max_idx); return tmp; }
/* * Normalize an array of monomials a or size n: * 1) merge monomials with identical variables: * (c * v + d * v) --> (c + d) * v * 2) remove monomials with zero coefficients * 3) add end marker. * - a must be sorted. * - the function returns the size of the result = number of monomials * in a after normalization. */ uint32_t normalize_monarray(monomial_t *a, uint32_t n) { uint32_t i, j, v; rational_t c; if (n == 0) return n; j = 0; q_init(&c); v = a[0].var; // c := a[0].coeff, clear a[0].coeff to prevent memory leak q_copy_and_clear(&c, &a[0].coeff); for (i=1; i<n; i++) { if (a[i].var == v) { q_add(&c, &a[i].coeff); q_clear(&a[i].coeff); } else { if (q_is_nonzero(&c)) { a[j].var = v; // copy c into a[j].coeff, then clear c q_copy_and_clear(&a[j].coeff, &c); j ++; } v = a[i].var; // copy a[i].coeff in c then clear a[i].coeff q_copy_and_clear(&c, &a[i].coeff); } } if (q_is_nonzero(&c)) { a[j].var = v; q_copy_and_clear(&a[j].coeff, &c); j ++; } // set end-marker a[j].var = max_idx; return j; }
/* * Allocate a polynomial_t object and copy a into it. * - a must be normalized. * - side effect: a is reset to 0. */ polynomial_t *monarray_get_poly(monomial_t *a, uint32_t n) { polynomial_t *p; uint32_t i; if (n >= MAX_POLY_SIZE) { out_of_memory(); } p = (polynomial_t *) safe_malloc(sizeof(polynomial_t) + (n + 1) * sizeof(monomial_t)); p->nterms = n; for (i=0; i<n; i++) { p->mono[i].var = a[i].var; q_copy_and_clear(&p->mono[i].coeff, &a[i].coeff); } // end-marker p->mono[i].var = max_idx; q_init(&p->mono[i].coeff); return p; }