void fmpz_mod_poly_make_monic(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) { const slong len = poly->length; fmpz_t inv; if (len == 0) { fmpz_mod_poly_zero(res); return; } fmpz_init(inv); fmpz_invmod(inv, fmpz_mod_poly_lead(poly), &(poly->p)); fmpz_mod_poly_fit_length(res, len); _fmpz_mod_poly_set_length(res, len); _fmpz_mod_poly_scalar_mul_fmpz(res->coeffs, poly->coeffs, len, inv, &(poly->p)); fmpz_clear(inv); }
void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, long len1, const fmpz *poly2, long len2, const fmpz_t p) { if (len1 == 1 || len2 == 0) { fmpz_set(res, poly1); } else { const long alloc = (len1 - 1) * (len2 - 1) + 1; long i = len1 - 1, lenr = len2; fmpz * t = _fmpz_vec_init(alloc); /* Perform the first two steps as one, "res = a(m) * poly2 + a(m-1)". */ { _fmpz_mod_poly_scalar_mul_fmpz(res, poly2, len2, poly1 + i, p); i--; fmpz_add(res, res, poly1 + i); if (fmpz_cmpabs(res, p) >= 0) fmpz_sub(res, res, p); } while (i > 0) { i--; _fmpz_mod_poly_mul(t, res, lenr, poly2, len2, p); lenr += len2 - 1; _fmpz_mod_poly_add(res, t, lenr, poly1 + i, 1, p); } _fmpz_vec_clear(t, alloc); } }