void nmod_poly_exp_series_monomial_ui(nmod_poly_t res, mp_limb_t coeff, ulong power, slong n) { if (n == 0) { nmod_poly_zero(res); return; } if (coeff == UWORD(0)) { nmod_poly_fit_length(res, 1); res->coeffs[0] = UWORD(1); res->length = 1; return; } if (power == 0) { flint_printf("Exception (nmod_poly_exp_series_monomial_ui). \n" "Constant term != 0.\n"); abort(); } if (coeff != UWORD(1)) coeff = n_mod2_preinv(coeff, res->mod.n, res->mod.ninv); if (n == 1 || power >= n) { nmod_poly_fit_length(res, 1); res->coeffs[0] = UWORD(1); res->length = 1; } nmod_poly_fit_length(res, n); _nmod_poly_exp_series_monomial_ui(res->coeffs, coeff, power, n, res->mod); res->length = n; _nmod_poly_normalise(res); }
void nmod_poly_exp_series(nmod_poly_t f, const nmod_poly_t h, long n) { mp_ptr f_coeffs, h_coeffs; nmod_poly_t t1; long hlen, k; nmod_poly_fit_length(f, n); hlen = h->length; if (hlen > 0 && h->coeffs[0] != 0UL) { printf("Exception: nmod_poly_exp_series: constant term != 0\n"); abort(); } if (n <= 1 || hlen == 0) { if (n == 0) { nmod_poly_zero(f); } else { f->coeffs[0] = 1UL; f->length = 1; } return; } /* Handle monomials */ for (k = 0; h->coeffs[k] == 0UL && k < n - 1; k++); if (k == hlen - 1 || k == n - 1) { hlen = FLINT_MIN(hlen, n); _nmod_poly_exp_series_monomial_ui(f->coeffs, h->coeffs[hlen-1], hlen - 1, n, f->mod); f->length = n; _nmod_poly_normalise(f); return; } if (n < NMOD_NEWTON_EXP_CUTOFF2) { _nmod_poly_exp_series_basecase(f->coeffs, h->coeffs, hlen, n, f->mod); f->length = n; _nmod_poly_normalise(f); return; } if (hlen < n) { h_coeffs = _nmod_vec_init(n); mpn_copyi(h_coeffs, h->coeffs, hlen); mpn_zero(h_coeffs + hlen, n - hlen); } else h_coeffs = h->coeffs; if (h == f && hlen >= n) { nmod_poly_init2(t1, h->mod.n, n); f_coeffs = t1->coeffs; } else { nmod_poly_fit_length(f, n); f_coeffs = f->coeffs; } _nmod_poly_exp_series(f_coeffs, h_coeffs, n, f->mod); if (h == f && hlen >= n) { nmod_poly_swap(f, t1); nmod_poly_clear(t1); } f->length = n; if (hlen < n) _nmod_vec_free(h_coeffs); _nmod_poly_normalise(f); }