poly_t poly_gcd(poly_t p1, poly_t p2) { poly_t a, b, c; a = poly_copy(p1); b = poly_copy(p2); if (poly_deg(a) < poly_deg(b)) c = poly_copy(poly_gcd_aux(b, a)); else c = poly_copy(poly_gcd_aux(a, b)); poly_free(a); poly_free(b); return c; }
void poly_mul_inp(Poly** lhs, const Poly* rhs) { Poly* p1; Poly* res = NULL; const Poly* p2; //think about the situation that: lhs and rhs are the same poly ? Poly* origin_lhs = poly_copy(*lhs); //we append {-1, 0} to rhs to balance out the origin lhs for (p2 = rhs; NULL != p2; p2 = p2->next) { Poly* tmp = poly_copy(origin_lhs); for (p1 = tmp; NULL != p1; p1 = p1->next) { p1->coeff *= p2->coeff; p1->index += p2->index; } poly_add_inp(&res, tmp); } destroy_poly(lhs); *lhs = res; destroy_poly(&origin_lhs); }
void poly_pow_inp(Poly** poly, int n) { int i; Poly* origin; if (0 == n) { *poly = create_poly(1, 0); return; } origin = poly_copy(*poly); for (i = 0; i < n - 1; i++) poly_mul_inp(poly, origin); destroy_poly(&origin); }
/** *negative index is not allowed *@return: stored quotient in plhs */ void poly_div_inp(Poly** plhs, const Poly* rhs) { Poly* lhs = *plhs; Poly odd = {.next = lhs}; Poly* res = NULL; if (NULL == lhs || NULL == rhs) return; if (*plhs == rhs) { //lhs and rhs are the same poly destroy_poly(plhs); *plhs = create_poly(1, 0); return; } for (; NULL != lhs && lhs->index >= rhs->index;) { Poly *p1, *q1; const Poly* p2; Poly* item = create_poly(lhs->coeff / rhs->coeff, lhs->index - rhs->index); poly_add_inp(&res, poly_copy(item)); //printf("res: \n"); //print_poly(res); for (p1 = lhs, q1 = &odd, p2 = rhs; NULL != p1 && NULL != p2;) { //print_poly(p2); if (p1->index - p2->index == item->index) { p1->coeff -= p2->coeff * item->coeff; //coeff may be zero if (DOUBLE_EQUAL(p1->coeff, 0)) { destroy_poly_head(&p1); //move forward q1->next = p1; } p2 = p2->next; } else if (p1->index - p2->index > item->index) { q1 = p1; p1 = p1->next; } else p2 = p2->next; } lhs = odd.next; //printf("lhs: \n"); //print_poly(lhs); } *plhs = odd.next; destroy_poly(plhs); *plhs = res; }
poly_t poly_quo(poly_t p, poly_t d) { int i, j, dd, dp; gf_t a, b; poly_t quo, rem; dd = poly_calcule_deg(d); dp = poly_calcule_deg(p); rem = poly_copy(p); quo = poly_alloc(dp - dd); poly_set_deg(quo, dp - dd); a = gf_inv(poly_coeff(d, dd)); for (i = dp; i >= dd; --i) { b = gf_mul_fast(a, poly_coeff(rem, i)); poly_set_coeff(quo, i - dd, b); if (b != gf_zero()) { poly_set_coeff(rem, i, gf_zero()); for (j = i - 1; j >= i - dd; --j) poly_addto_coeff(rem, j, gf_mul_fast(b, poly_coeff(d, dd - i + j))); } } poly_free(rem); return quo; }