void F_mpz_mod_poly_mul_trunc_left(F_mpz_mod_poly_t res, const F_mpz_mod_poly_t poly1, const F_mpz_mod_poly_t poly2, ulong trunc) { if ((poly1->length == 0) || (poly2->length == 0) || (poly1->length + poly2->length <= trunc + 1)) // special case if either poly is zero { F_mpz_mod_poly_zero(res); return; } if ((poly1 == res) || (poly2 == res)) // aliased inputs { F_mpz_mod_poly_t output; // create temporary F_mpz_mod_poly_init2(output, res->P, poly1->length + poly2->length - 1); if (poly1->length >= poly2->length) _F_mpz_mod_poly_mul_trunc_left(output, poly1, poly2, trunc); else _F_mpz_mod_poly_mul_trunc_left(output, poly2, poly1, trunc); F_mpz_mod_poly_swap(output, res); // swap temporary with real output F_mpz_mod_poly_clear(output); } else // ordinary case { F_mpz_mod_poly_fit_length(res, poly1->length + poly2->length - 1); if (poly1->length >= poly2->length) _F_mpz_mod_poly_mul_trunc_left(res, poly1, poly2, trunc); else _F_mpz_mod_poly_mul_trunc_left(res, poly2, poly1, trunc); } }
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); }