void F_mpz_poly_to_F_mpz_mod_poly(F_mpz_mod_poly_t F_poly, const F_mpz_poly_t poly) { F_mpz_mod_poly_fit_length(F_poly, poly->length); _F_mpz_mod_poly_set_length(F_poly, poly->length); for (ulong i = 0; i < poly->length; i++) { F_mpz_set(F_poly->coeffs + i, poly->coeffs + i); F_mpz_mod(F_poly->coeffs + i, F_poly->coeffs + i, F_poly->P); } _F_mpz_mod_poly_normalise(F_poly); }
void mpz_poly_to_F_mpz_mod_poly(F_mpz_mod_poly_t F_poly, const mpz_poly_t m_poly) { F_mpz_mod_poly_fit_length(F_poly, m_poly->length); _F_mpz_mod_poly_set_length(F_poly, m_poly->length); for (ulong i = 0; i < m_poly->length; i++) { F_mpz_set_mpz(F_poly->coeffs + i, m_poly->coeffs[i]); F_mpz_mod(F_poly->coeffs + i, F_poly->coeffs + i, F_poly->P); } _F_mpz_mod_poly_normalise(F_poly); }
void F_mpz_mod_poly_divrem_divconquer(F_mpz_mod_poly_t Q, F_mpz_mod_poly_t R, const F_mpz_mod_poly_t A, const F_mpz_mod_poly_t B) { F_mpz_mod_poly_t QB; F_mpz_mod_poly_init(QB, Q->P); F_mpz_mod_poly_div_divconquer_recursive(Q, QB, A, B); F_mpz_mod_poly_fit_length(R, A->length); _F_mpz_mod_poly_sub(R, A, QB); _F_mpz_mod_poly_normalise(R); F_mpz_mod_poly_clear(QB); }
void _F_mpz_mod_poly_mul(F_mpz_mod_poly_t res, const F_mpz_mod_poly_t pol1, const F_mpz_mod_poly_t pol2) { F_mpz_poly_t p1, p2, r; _F_mpz_poly_attach_F_mpz_mod_poly(p1, pol1); _F_mpz_poly_attach_F_mpz_mod_poly(p2, pol2); _F_mpz_poly_attach_F_mpz_mod_poly(r, res); _F_mpz_poly_mul(r, p1, p2); _F_mpz_poly_reduce_coeffs(r, res->P); _F_mpz_mod_poly_attach_F_mpz_poly(res, r); _F_mpz_mod_poly_normalise(res); }
void F_mpz_mod_poly_scalar_mul(F_mpz_mod_poly_t res, const F_mpz_mod_poly_t pol1, const F_mpz_t x) { F_mpz_poly_t p1, r; F_mpz_mod_poly_fit_length(res, pol1->length); _F_mpz_poly_attach_F_mpz_mod_poly(p1, pol1); _F_mpz_poly_attach_F_mpz_mod_poly(r, res); F_mpz_poly_scalar_mul(r, p1, x); _F_mpz_poly_reduce_coeffs(r, res->P); _F_mpz_mod_poly_attach_F_mpz_poly(res, r); _F_mpz_mod_poly_normalise(res); }
void zmod_poly_to_F_mpz_mod_poly(F_mpz_mod_poly_t fpol, const zmod_poly_t zpol) { if (zpol->length == 0) { F_mpz_mod_poly_zero(fpol); return; } F_mpz_mod_poly_fit_length(fpol, zpol->length); for (ulong i = 0; i < zpol->length; i++) F_mpz_set_ui(fpol->coeffs + i, zpol->coeffs[i]); _F_mpz_mod_poly_set_length(fpol, zpol->length); _F_mpz_mod_poly_normalise(fpol); }
void _F_mpz_mod_poly_mul_trunc_left(F_mpz_mod_poly_t res, const F_mpz_mod_poly_t pol1, const F_mpz_mod_poly_t pol2, ulong trunc) { F_mpz_poly_t p1, p2, r; if (trunc + 1 > pol1->length + pol2->length) trunc = pol1->length + pol2->length - 1; if (!pol1->length && !pol2->length) trunc = 0; _F_mpz_poly_attach_F_mpz_mod_poly(p1, pol1); _F_mpz_poly_attach_F_mpz_mod_poly(p2, pol2); _F_mpz_poly_attach_F_mpz_mod_poly(r, res); _F_mpz_poly_mul_trunc_left(r, p1, p2, trunc); _F_mpz_poly_reduce_coeffs(r, res->P); _F_mpz_mod_poly_attach_F_mpz_poly(res, r); _F_mpz_mod_poly_normalise(res); }
void _F_mpz_mod_poly_sub(F_mpz_mod_poly_t res, const F_mpz_mod_poly_t pol1, const F_mpz_mod_poly_t pol2) { F_mpz_poly_t p1, p2, r; _F_mpz_poly_attach_F_mpz_mod_poly(p1, pol1); _F_mpz_poly_attach_F_mpz_mod_poly(p2, pol2); _F_mpz_poly_attach_F_mpz_mod_poly(r, res); _F_mpz_poly_sub(r, p1, p2); for (ulong i = 0; i < r->length; i++) { if (F_mpz_sgn(r->coeffs + i) < 0) F_mpz_add(r->coeffs + i, r->coeffs + i, res->P); } _F_mpz_mod_poly_attach_F_mpz_poly(res, r); _F_mpz_mod_poly_normalise(res); }
void F_mpz_mod_poly_divrem_basecase(F_mpz_mod_poly_t Q, F_mpz_mod_poly_t R, const F_mpz_mod_poly_t A, const F_mpz_mod_poly_t B) { if (B->length == 0) { printf("Error: Divide by zero\n"); abort(); } if (A->length < B->length) { F_mpz_mod_poly_set(R, A); F_mpz_mod_poly_zero(Q); return; } F_mpz_t lead_inv; F_mpz_init(lead_inv); F_mpz_invert(lead_inv, B->coeffs + B->length - 1, B->P); F_mpz * coeff_Q; F_mpz_mod_poly_t qB; F_mpz_mod_poly_init2(qB, B->P, B->length); F_mpz_mod_poly_t Bm1; _F_mpz_mod_poly_attach_truncate(Bm1, B, B->length - 1); long coeff = A->length - 1; F_mpz_mod_poly_set(R, A); if (A->length >= B->length) { F_mpz_mod_poly_fit_length(Q, A->length - B->length + 1); _F_mpz_mod_poly_set_length(Q, A->length - B->length + 1); } else F_mpz_mod_poly_zero(Q); coeff_Q = Q->coeffs - B->length + 1; while (coeff >= (long) B->length - 1) { while ((coeff >= (long) B->length - 1) && (F_mpz_is_zero(R->coeffs + coeff))) { F_mpz_zero(coeff_Q + coeff); coeff--; } if (coeff >= (long) B->length - 1) { F_mpz_mulmod2(coeff_Q + coeff, R->coeffs + coeff, lead_inv, B->P); F_mpz_mod_poly_scalar_mul(qB, Bm1, coeff_Q + coeff); F_mpz_mod_poly_t R_sub; F_mpz_init(R_sub->P); F_mpz_set(R_sub->P, B->P); R_sub->coeffs = R->coeffs + coeff - B->length + 1; R_sub->length = B->length - 1; _F_mpz_mod_poly_sub(R_sub, R_sub, qB); F_mpz_clear(R_sub->P); coeff--; } } _F_mpz_mod_poly_set_length(R, B->length - 1); _F_mpz_mod_poly_normalise(R); F_mpz_mod_poly_clear(qB); F_mpz_clear(lead_inv); }
void F_mpz_mod_poly_gcd_euclidean(F_mpz_mod_poly_t res, F_mpz_mod_poly_t poly1, F_mpz_mod_poly_t poly2) { F_mpz_mod_poly_t R, A, B; F_mpz_poly_t r; int steps = 0; if (poly1->length == 0) { if (poly2->length == 0) F_mpz_mod_poly_zero(res); else F_mpz_mod_poly_make_monic(res, poly2); return; } if (poly2->length == 0) { F_mpz_mod_poly_make_monic(res, poly1); return; } if ((poly1->length == 1) || (poly2->length == 1)) { _F_mpz_poly_attach_F_mpz_mod_poly(r, res); F_mpz_poly_set_coeff_ui(r, 0, 1L); _F_mpz_mod_poly_attach_F_mpz_poly(res, r); _F_mpz_mod_poly_normalise(res); return; } F_mpz_t P; F_mpz_init(P); F_mpz_set(P, poly1->P); F_mpz_mod_poly_init(R, P); if (poly1->length > poly2->length) { _F_mpz_mod_poly_attach(A, poly1); _F_mpz_mod_poly_attach(B, poly2); } else { _F_mpz_mod_poly_attach(A, poly2); _F_mpz_mod_poly_attach(B, poly1); } F_mpz_mod_poly_rem(R, A, B); F_mpz_mod_poly_swap(A, B); F_mpz_mod_poly_swap(B, R); F_mpz_mod_poly_init(R, P); if (B->length > 1) { F_mpz_mod_poly_rem(R, A, B); F_mpz_mod_poly_swap(A, B); F_mpz_mod_poly_swap(B, R); F_mpz_mod_poly_init(R, P); steps = 1; } while (B->length > 1) { F_mpz_mod_poly_rem(A, A, B); F_mpz_mod_poly_swap(A, B); } if (B->length == 1) { _F_mpz_poly_attach_F_mpz_mod_poly(r, res); F_mpz_poly_set_coeff_ui(r, 0, 1L); _F_mpz_mod_poly_attach_F_mpz_poly(res, r); res->length = 1; } else F_mpz_mod_poly_make_monic(res, A); if (steps) { F_mpz_mod_poly_clear(A); } F_mpz_mod_poly_clear(B); F_mpz_mod_poly_clear(R); }