void nmod_poly_divrem_newton(nmod_poly_t Q, nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B) { const long lenA = A->length, lenB = B->length; mp_ptr q, r; if (lenB == 0) { printf("Exception: division by zero in nmod_poly_divrem_newton\n"); abort(); } if (lenA < lenB) { nmod_poly_set(R, A); nmod_poly_zero(Q); return; } if (Q == A || Q == B) { q = _nmod_vec_init(lenA - lenB + 1); } else { nmod_poly_fit_length(Q, lenA - lenB + 1); q = Q->coeffs; } if (R == A || R == B) { r = _nmod_vec_init(lenB - 1); } else { nmod_poly_fit_length(R, lenB - 1); r = R->coeffs; } _nmod_poly_divrem_newton(q, r, A->coeffs, lenA, B->coeffs, lenB, B->mod); if (Q == A || Q == B) { _nmod_vec_clear(Q->coeffs); Q->coeffs = q; Q->alloc = lenA - lenB + 1; } if (R == A || R == B) { _nmod_vec_clear(R->coeffs); R->coeffs = r; R->alloc = lenB - 1; } Q->length = lenA - lenB + 1; R->length = lenB - 1; _nmod_poly_normalise(R); }
void nmod_poly_compose_series_horner(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, long n) { long len1 = poly1->length; long len2 = poly2->length; long lenr; if (len2 != 0 && poly2->coeffs[0] != 0) { printf("exception: nmod_poly_compose_series_horner: inner polynomial " "must have zero constant term\n"); abort(); } if (len1 == 0 || n == 0) { nmod_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { nmod_poly_fit_length(res, 1); res->coeffs[0] = poly1->coeffs[0]; res->length = 1; _nmod_poly_normalise(res); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { nmod_poly_fit_length(res, lenr); _nmod_poly_compose_series_horner(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, res->mod); res->length = lenr; _nmod_poly_normalise(res); } else { nmod_poly_t t; nmod_poly_init2_preinv(t, res->mod.n, res->mod.ninv, lenr); _nmod_poly_compose_series_horner(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, res->mod); t->length = lenr; _nmod_poly_normalise(t); nmod_poly_swap(res, t); nmod_poly_clear(t); } }
void nmod_poly_pow(nmod_poly_t res, const nmod_poly_t poly, ulong e) { const slong len = poly->length; slong rlen; if ((len < 2) | (e < UWORD(3))) { if (len == 0) nmod_poly_zero(res); else if (len == 1) { nmod_poly_fit_length(res, 1); res->coeffs[0] = n_powmod2_ui_preinv(poly->coeffs[0], e, poly->mod.n, poly->mod.ninv); res->length = 1; _nmod_poly_normalise(res); } else if (e == UWORD(0)) { nmod_poly_set_coeff_ui(res, 0, UWORD(1)); res->length = 1; _nmod_poly_normalise(res); } else if (e == UWORD(1)) nmod_poly_set(res, poly); else /* e == UWORD(2) */ nmod_poly_mul(res, poly, poly); return; } rlen = (slong) e * (len - 1) + 1; if (res != poly) { nmod_poly_fit_length(res, rlen); _nmod_poly_pow(res->coeffs, poly->coeffs, len, e, poly->mod); } else { nmod_poly_t t; nmod_poly_init2(t, poly->mod.n, rlen); _nmod_poly_pow(t->coeffs, poly->coeffs, len, e, poly->mod); nmod_poly_swap(res, t); nmod_poly_clear(t); } res->length = rlen; _nmod_poly_normalise(res); }
void nmod_poly_product_roots_nmod_vec(nmod_poly_t poly, mp_srcptr xs, slong n) { nmod_poly_fit_length(poly, n + 1); _nmod_poly_product_roots_nmod_vec(poly->coeffs, xs, n, poly->mod); poly->length = n + 1; }
void nmod_poly_integral(nmod_poly_t x_int, const nmod_poly_t x) { nmod_poly_fit_length(x_int, x->length + 1); _nmod_poly_integral(x_int->coeffs, x->coeffs, x->length + 1, x->mod); x_int->length = x->length + 1; _nmod_poly_normalise(x_int); }
void nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len) { nmod_poly_fit_length(poly, len); _nmod_vec_randtest(poly->coeffs, state, len, poly->mod); poly->length = len; _nmod_poly_normalise(poly); }
void nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len) { nmod_poly_fit_length(poly, len); _nmod_vec_randtest(poly->coeffs, state, len - 1, poly->mod); poly->coeffs[len - 1] = 1; poly->length = len; }
void nmod_poly_cosh_series(nmod_poly_t g, const nmod_poly_t h, long n) { mp_ptr g_coeffs, h_coeffs; nmod_poly_t t1; long h_len; h_len = h->length; if (h_len > 0 && h->coeffs[0] != 0UL) { printf("Exception: nmod_poly_cosh_series: constant term != 0\n"); abort(); } if (h_len == 1 || n < 2) { nmod_poly_zero(g); if (n > 0) nmod_poly_set_coeff_ui(g, 0, 1UL); return; } if (h_len < n) { h_coeffs = _nmod_vec_init(n); mpn_copyi(h_coeffs, h->coeffs, h_len); mpn_zero(h_coeffs + h_len, n - h_len); } else h_coeffs = h->coeffs; if (h == g && h_len >= n) { nmod_poly_init2(t1, h->mod.n, n); g_coeffs = t1->coeffs; } else { nmod_poly_fit_length(g, n); g_coeffs = g->coeffs; } _nmod_poly_cosh_series(g_coeffs, h_coeffs, n, h->mod); if (h == g && h_len >= n) { nmod_poly_swap(g, t1); nmod_poly_clear(t1); } g->length = n; if (h_len < n) _nmod_vec_free(h_coeffs); _nmod_poly_normalise(g); }
int main(void) { int i, result; flint_rand_t state; flint_randinit(state); printf("bit_pack/bit_unpack...."); fflush(stdout); /* Check aliasing of a and c */ for (i = 0; i < 10000; i++) { nmod_poly_t a, b; mp_limb_t n; ulong bits; mp_ptr mpn; do { n = n_randtest_not_zero(state); } while (n == 1); bits = 2 * FLINT_BIT_COUNT(n) + n_randint(state, FLINT_BITS); nmod_poly_init(a, n); nmod_poly_init(b, n); do { nmod_poly_randtest(a, state, n_randint(state, 100)); } while (a->length == 0); mpn = malloc(sizeof(mp_limb_t) * ((bits * a->length - 1) / FLINT_BITS + 1)); _nmod_poly_bit_pack(mpn, a->coeffs, a->length, bits); nmod_poly_fit_length(b, a->length); _nmod_poly_bit_unpack(b->coeffs, a->length, mpn, bits, a->mod); b->length = a->length; result = (nmod_poly_equal(a, b)); if (!result) { printf("FAIL:\n"); nmod_poly_print(a), printf("\n\n"); nmod_poly_print(b), printf("\n\n"); abort(); } nmod_poly_clear(a); nmod_poly_clear(b); } flint_randclear(state); printf("PASS\n"); return 0; }
void nmod_poly_reverse(nmod_poly_t output, const nmod_poly_t input, long m) { nmod_poly_fit_length(output, m); _nmod_poly_reverse(output->coeffs, input->coeffs, input->length, m); output->length = m; _nmod_poly_normalise(output); }
void _pq_nmod_insure_dual(const pq_nmod_elt_t x, const pq_nmod_t A) { if (nmod_poly_is_zero(x->dual) && !nmod_poly_is_zero(x->mono)) { pq_nmod_elt_struct* tmp = (pq_nmod_elt_struct*)x; nmod_poly_fit_length(tmp->dual, nmod_poly_degree(A->M)); nmod_poly_tmulmod(tmp->dual->coeffs, A->newton->coeffs, x->mono, A->M, A->S); tmp->dual->length = nmod_poly_degree(A->M); } }
void fq_nmod_neg(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) { slong len = op->length; nmod_poly_fit_length(rop, len); _nmod_poly_set_length(rop, len); nmod_poly_neg(rop, op); }
void nmod_poly_div_basecase(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B) { mp_ptr Q_coeffs, W; nmod_poly_t t1; long Alen, Blen; Blen = B->length; if (Blen == 0) { printf("Exception: division by zero in nmod_poly_div_basecase\n"); abort(); } Alen = A->length; if (Alen < Blen) { nmod_poly_zero(Q); return; } if (Q == A || Q == B) { nmod_poly_init2_preinv(t1, B->mod.n, B->mod.ninv, Alen - Blen + 1); Q_coeffs = t1->coeffs; } else { nmod_poly_fit_length(Q, Alen - Blen + 1); Q_coeffs = Q->coeffs; } W = _nmod_vec_init(NMOD_DIV_BC_ITCH(Alen, Blen, A->mod)); _nmod_poly_div_basecase(Q_coeffs, W, A->coeffs, Alen, B->coeffs, Blen, B->mod); if (Q == A || Q == B) { nmod_poly_swap(Q, t1); nmod_poly_clear(t1); } Q->length = Alen - Blen + 1; _nmod_vec_clear(W); _nmod_poly_normalise(Q); }
void nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len) { ulong k; nmod_poly_fit_length(poly, len); _nmod_vec_zero(poly->coeffs, len); poly->coeffs[0] = n_randtest(state) % poly->mod.n; poly->coeffs[len - 1] = 1; k = (n_randtest(state) % (len - 2)) + 1; poly->coeffs[k] = n_randtest(state) % poly->mod.n; _nmod_poly_set_length(poly, len); }
void nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len) { nmod_poly_fit_length(poly, len); _nmod_vec_zero(poly->coeffs, len); poly->coeffs[0] = n_randtest(state) % poly->mod.n; poly->coeffs[1] = n_randtest(state) % poly->mod.n; poly->coeffs[2] = n_randtest(state) % poly->mod.n; poly->coeffs[3] = n_randtest(state) % poly->mod.n; poly->coeffs[len - 1] = 1; _nmod_poly_set_length(poly, len); }
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_revert_series_lagrange(nmod_poly_t Qinv, const nmod_poly_t Q, long n) { mp_ptr Qinv_coeffs, Q_coeffs; nmod_poly_t t1; long Qlen; Qlen = Q->length; if (Qlen < 2 || Q->coeffs[0] != 0 || Q->coeffs[1] == 0) { printf("exception: nmod_poly_revert_series_lagrange: input must have " "zero constant and an invertible coefficient of x^1"); abort(); } if (Qlen < n) { Q_coeffs = _nmod_vec_init(n); mpn_copyi(Q_coeffs, Q->coeffs, Qlen); mpn_zero(Q_coeffs + Qlen, n - Qlen); } else Q_coeffs = Q->coeffs; if (Q == Qinv && Qlen >= n) { nmod_poly_init2(t1, Q->mod.n, n); Qinv_coeffs = t1->coeffs; } else { nmod_poly_fit_length(Qinv, n); Qinv_coeffs = Qinv->coeffs; } _nmod_poly_revert_series_lagrange(Qinv_coeffs, Q_coeffs, n, Q->mod); if (Q == Qinv && Qlen >= n) { nmod_poly_swap(Qinv, t1); nmod_poly_clear(t1); } Qinv->length = n; if (Qlen < n) _nmod_vec_clear(Q_coeffs); _nmod_poly_normalise(Qinv); }
void nmod_poly_inv_series_basecase(nmod_poly_t Qinv, const nmod_poly_t Q, long n) { mp_ptr Qinv_coeffs, Q_coeffs; nmod_poly_t t1; long Qlen; Qlen = Q->length; if (n == 0 || Q->length == 0 || Q->coeffs[0] == 0) { printf("Exception: division by zero in nmod_poly_inv_series_basecase\n"); abort(); } if (Qlen < n) { Q_coeffs = _nmod_vec_init(n); mpn_copyi(Q_coeffs, Q->coeffs, Qlen); mpn_zero(Q_coeffs + Qlen, n - Qlen); } else Q_coeffs = Q->coeffs; if (Q == Qinv && Qlen >= n) { nmod_poly_init2(t1, Q->mod.n, n); Qinv_coeffs = t1->coeffs; } else { nmod_poly_fit_length(Qinv, n); Qinv_coeffs = Qinv->coeffs; } _nmod_poly_inv_series_basecase(Qinv_coeffs, Q_coeffs, n, Q->mod); if (Q == Qinv && Qlen >= n) { nmod_poly_swap(Qinv, t1); nmod_poly_clear(t1); } Qinv->length = n; if (Qlen < n) _nmod_vec_free(Q_coeffs); _nmod_poly_normalise(Qinv); }
void fq_nmod_pow(fq_nmod_t rop, const fq_nmod_t op, const fmpz_t e, const fq_nmod_ctx_t ctx) { if (fmpz_sgn(e) < 0) { flint_printf("Exception (fq_nmod_pow). e < 0.\n"); abort(); } if (fmpz_is_zero(e)) { fq_nmod_one(rop, ctx); } else if (fq_nmod_is_zero(op, ctx)) { fq_nmod_zero(rop, ctx); } else if (fmpz_is_one(e)) { fq_nmod_set(rop, op, ctx); } else { const slong d = fq_nmod_ctx_degree(ctx); mp_limb_t *t; if (rop == op) { t = _nmod_vec_init(2 * d - 1); } else { nmod_poly_fit_length(rop, 2 * d - 1); t = rop->coeffs; } _fq_nmod_pow(t, op->coeffs, op->length, e, ctx); if (rop == op) { _nmod_vec_clear(rop->coeffs); rop->coeffs = t; rop->alloc = 2 * d - 1; rop->length = d; } else { _nmod_poly_set_length(rop, d); } _nmod_poly_normalise(rop); } }
void nmod_poly_shift_right(nmod_poly_t res, const nmod_poly_t poly, long k) { if (k >= poly->length) /* shift all coeffs out */ res->length = 0; else { const long len = poly->length - k; nmod_poly_fit_length(res, len); _nmod_poly_shift_right(res->coeffs, poly->coeffs, len, k); res->length = len; } }
void nmod_poly_mulhigh(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, long n) { long len1, len2, len_out; len1 = poly1->length; len2 = poly2->length; len_out = poly1->length + poly2->length - 1; if (n > len_out) n = len_out; if (len1 == 0 || len2 == 0 || n == 0) { nmod_poly_zero(res); return; } if (res == poly1 || res == poly2) { nmod_poly_t temp; nmod_poly_init2(temp, poly1->mod.n, len_out); if (len1 >= len2) _nmod_poly_mulhigh(temp->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, poly1->mod); else _nmod_poly_mulhigh(temp->coeffs, poly2->coeffs, len2, poly1->coeffs, len1, n, poly1->mod); nmod_poly_swap(temp, res); nmod_poly_clear(temp); } else { nmod_poly_fit_length(res, len_out); if (len1 >= len2) _nmod_poly_mulhigh(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n, poly1->mod); else _nmod_poly_mulhigh(res->coeffs, poly2->coeffs, len2, poly1->coeffs, len1, n, poly1->mod); } res->length = len_out; _nmod_poly_normalise(res); }
void nmod_poly_mulmod(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t f) { long len1, len2, lenf; mp_ptr fcoeffs; lenf = f->length; len1 = poly1->length; len2 = poly2->length; if (lenf == 0) { printf("Exception: nmod_poly_mulmod: divide by zero\n"); abort(); } if (lenf == 1 || len1 == 0 || len2 == 0) { nmod_poly_zero(res); return; } if (len1 + len2 - lenf > 0) { if (f == res) { fcoeffs = flint_malloc(sizeof(mp_limb_t) * lenf); _nmod_vec_set(fcoeffs, f->coeffs, lenf); } else fcoeffs = f->coeffs; nmod_poly_fit_length(res, lenf - 1); _nmod_poly_mulmod(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, fcoeffs, lenf, res->mod); if (f == res) flint_free(fcoeffs); res->length = lenf - 1; _nmod_poly_normalise(res); } else { nmod_poly_mul(res, poly1, poly2); } }
void nmod_poly_mullow_KS(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, mp_bitcnt_t bits, long n) { long len_out; if ((poly1->length == 0) || (poly2->length == 0)) { nmod_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (n > len_out) n = len_out; if (res == poly1 || res == poly2) { nmod_poly_t temp; nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out); if (poly1->length >= poly2->length) _nmod_poly_mullow_KS(temp->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, bits, n, poly1->mod); else _nmod_poly_mullow_KS(temp->coeffs, poly2->coeffs, poly2->length, poly1->coeffs, poly1->length, bits, n, poly1->mod); nmod_poly_swap(res, temp); nmod_poly_clear(temp); } else { nmod_poly_fit_length(res, len_out); if (poly1->length >= poly2->length) _nmod_poly_mullow_KS(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, bits, n, poly1->mod); else _nmod_poly_mullow_KS(res->coeffs, poly2->coeffs, poly2->length, poly1->coeffs, poly1->length, bits, n, poly1->mod); } res->length = n; _nmod_poly_normalise(res); }
void nmod_poly_mullow_classical(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, slong trunc) { slong len_out; if (poly1->length == 0 || poly2->length == 0 || trunc == 0) { nmod_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (trunc > len_out) trunc = len_out; if (res == poly1 || res == poly2) { nmod_poly_t temp; nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, trunc); if (poly1->length >= poly2->length) _nmod_poly_mullow_classical(temp->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, trunc, poly1->mod); else _nmod_poly_mullow_classical(temp->coeffs, poly2->coeffs, poly2->length, poly1->coeffs, poly1->length, trunc, poly1->mod); nmod_poly_swap(res, temp); nmod_poly_clear(temp); } else { nmod_poly_fit_length(res, trunc); if (poly1->length >= poly2->length) _nmod_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, trunc, poly1->mod); else _nmod_poly_mullow_classical(res->coeffs, poly2->coeffs, poly2->length, poly1->coeffs, poly1->length, trunc, poly1->mod); } res->length = trunc; _nmod_poly_normalise(res); }
void nmod_poly_div_divconquer(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B) { nmod_poly_t tQ; mp_ptr q; long Alen, Blen; Blen = B->length; if (Blen == 0) { printf("Exception: division by zero in nmod_poly_div_divconquer\n"); abort(); } Alen = A->length; if (Alen < Blen) { nmod_poly_zero(Q); return; } if (Q == A || Q == B) { nmod_poly_init2(tQ, A->mod.n, Alen - Blen + 1); q = tQ->coeffs; } else { nmod_poly_fit_length(Q, Alen - Blen + 1); q = Q->coeffs; } _nmod_poly_div_divconquer(q, A->coeffs, Alen, B->coeffs, Blen, A->mod); if (Q == A || Q == B) { nmod_poly_swap(tQ, Q); nmod_poly_clear(tQ); } Q->length = Alen - Blen + 1; }
void nmod_poly_interpolate_nmod_vec_barycentric(nmod_poly_t poly, mp_srcptr xs, mp_srcptr ys, slong n) { if (n == 0) { nmod_poly_zero(poly); } else { nmod_poly_fit_length(poly, n); poly->length = n; _nmod_poly_interpolate_nmod_vec_barycentric(poly->coeffs, xs, ys, n, poly->mod); _nmod_poly_normalise(poly); } }
void _fmpz_vec_get_nmod_poly(nmod_poly_t res, const fmpz * coeffs, slong len) { if (len == 0) { nmod_poly_zero(res); } else { slong i; nmod_poly_fit_length(res, len); for (i = 0; i < len; i++) res->coeffs[i] = fmpz_fdiv_ui(coeffs + i, res->mod.n); _nmod_poly_set_length(res, len); _nmod_poly_normalise(res); } }
void nmod_poly_rem_basecase(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B) { const long lenA = A->length, lenB = B->length; mp_ptr r, W; nmod_poly_t t; if (lenB == 0) { printf("Exception: division by zero in nmod_poly_rem_basecase\n"); abort(); } if (lenA < lenB) { nmod_poly_set(R, A); return; } if (R == A || R == B) { nmod_poly_init2_preinv(t, B->mod.n, B->mod.ninv, lenB - 1); r = t->coeffs; } else { nmod_poly_fit_length(R, lenB - 1); r = R->coeffs; } W = _nmod_vec_init(NMOD_DIVREM_BC_ITCH(lenA, lenB, A->mod)); _nmod_poly_rem_basecase(r, W, A->coeffs, lenA, B->coeffs, lenB, B->mod); if (R == A || R == B) { nmod_poly_swap(R, t); nmod_poly_clear(t); } R->length = lenB - 1; _nmod_vec_clear(W); _nmod_poly_normalise(R); }
void fq_zech_get_fq_nmod(fq_nmod_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) { slong i; mp_limb_t q, r; nmod_poly_fit_length(rop, fq_zech_ctx_degree(ctx)); q = ctx->eval_table[op->value]; i = 0; while (q >= ctx->p) { r = n_divrem2_precomp(&q, q, ctx->p, ctx->ppre); nmod_poly_set_coeff_ui(rop, i, r); i ++; } nmod_poly_set_coeff_ui(rop, i, q); }
void nmod_poly_compose_divconquer(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2) { const long len1 = poly1->length; const long len2 = poly2->length; long lenr; if (len1 == 0) { nmod_poly_zero(res); return; } if (len1 == 1 || len2 == 0) { nmod_poly_set_coeff_ui(res, 0, poly1->coeffs[0]); nmod_poly_truncate(res, 1); return; } lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { nmod_poly_fit_length(res, lenr); _nmod_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, poly1->mod); } else { nmod_poly_t t; nmod_poly_init2(t, poly1->mod.n, lenr); _nmod_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, poly1->mod); nmod_poly_swap(res, t); nmod_poly_clear(t); } res->length = lenr; _nmod_poly_normalise(res); }