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_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_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); }
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_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 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_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 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_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 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_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_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_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 _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_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 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 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); }
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 embeddings_isomorphism(nmod_poly_t G, mp_srcptr F, const embeddings_t FP, const embeddings_t FQ, const embeddings_t FR){ long m = nmod_poly_degree(FP->P); long n = nmod_poly_degree(FQ->P); long i; nmod_poly_t tmpF, tmpG, S, X; nmod_t mod = FP->P->mod; nmod_poly_init(tmpF, mod.n); nmod_poly_init(tmpG, mod.n); nmod_poly_init(S, mod.n); nmod_poly_init(X, mod.n); nmod_poly_zero(G); nmod_poly_zero(X); nmod_poly_set_coeff_ui(X, 1, 1); embeddings_embed(S, X, FP, FQ, FR); for (i = m-1; i >= 0; i--){ nmod_poly_fit_length(tmpF, n); long j; long offset = i*n; for (j = 0; j < n; j++) tmpF->coeffs[j] = F[offset+j]; tmpF->length = n; _nmod_poly_normalise(tmpF); embeddings_embed(tmpG, tmpF, FQ, FP, FR); nmod_poly_mulmod(G, G, S, FR->P); nmod_poly_add(G, G, tmpG); } nmod_poly_clear(tmpF); nmod_poly_clear(tmpG); nmod_poly_clear(X); nmod_poly_clear(S); }
void nmod_poly_asin_series(nmod_poly_t g, const nmod_poly_t h, slong n) { mp_ptr h_coeffs; slong h_len = h->length; if (h_len > 0 && h->coeffs[0] != UWORD(0)) { flint_printf("Exception (nmod_poly_asin_series). Constant term != 0.\n"); abort(); } if (h_len == 1 || n < 2) { nmod_poly_zero(g); return; } nmod_poly_fit_length(g, n); if (h_len < n) { h_coeffs = _nmod_vec_init(n); flint_mpn_copyi(h_coeffs, h->coeffs, h_len); flint_mpn_zero(h_coeffs + h_len, n - h_len); } else h_coeffs = h->coeffs; _nmod_poly_asin_series(g->coeffs, h_coeffs, n, h->mod); if (h_len < n) _nmod_vec_clear(h_coeffs); g->length = n; _nmod_poly_normalise(g); }
void nmod_poly_tanh_series(nmod_poly_t g, const nmod_poly_t h, long n) { mp_ptr h_coeffs; long h_len = h->length; if (h_len > 0 && h->coeffs[0] != 0UL) { printf("Exception: nmod_poly_tanh_series: constant term != 0\n"); abort(); } if (h_len == 1 || n < 2) { nmod_poly_zero(g); return; } nmod_poly_fit_length(g, n); 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; _nmod_poly_tanh_series(g->coeffs, h_coeffs, n, h->mod); if (h_len < n) _nmod_vec_free(h_coeffs); g->length = n; _nmod_poly_normalise(g); }
/*------------------------------------------------------------*/ void check(int opt){ mp_limb_t n = 12345; nmod_t Zn; nmod_init(&Zn, n); sage_output_init(Zn); nmod_poly_t a; nmod_poly_init2(a, n, 10); long i; for (i = 0; i < 10; i++) a->coeffs[i] = i; a->length = 10; _nmod_poly_normalise(a); sage_output_print_poly(a); printf("\n"); nmod_poly_zero(a); sage_output_print_poly(a); printf("\n"); nmod_poly_clear(a); }
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); }
void nmod_poly_compose_mod_brent_kung(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t poly3) { long len1 = poly1->length; long len2 = poly2->length; long len3 = poly3->length; long len = len3 - 1; mp_ptr ptr2; if (len3 == 0) { printf("exception: division by zero in " "nmod_poly_compose_mod_brent_kung\n"); abort(); } if (len1 >= len3) { printf("exception: nmod_poly_compose_brent_kung: the degree of the" " first polynomial must be smaller than that of the modulus\n"); abort(); } if (len1 == 0 || len3 == 1) { nmod_poly_zero(res); return; } if (len1 == 1) { nmod_poly_set(res, poly1); return; } if (res == poly3 || res == poly1) { nmod_poly_t tmp; nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); nmod_poly_compose_mod_brent_kung(tmp, poly1, poly2, poly3); nmod_poly_swap(tmp, res); nmod_poly_clear(tmp); return; } ptr2 = _nmod_vec_init(len); if (len2 <= len) { mpn_copyi(ptr2, poly2->coeffs, len2); mpn_zero(ptr2 + len2, len - len2); } else { _nmod_poly_rem(ptr2, poly2->coeffs, len2, poly3->coeffs, len3, res->mod); } nmod_poly_fit_length(res, len); _nmod_poly_compose_mod_brent_kung(res->coeffs, poly1->coeffs, len1, ptr2, poly3->coeffs, len3, res->mod); res->length = len; _nmod_poly_normalise(res); _nmod_vec_clear(ptr2); }
void nmod_poly_compose_mod_horner(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t poly3) { long len1 = poly1->length; long len2 = poly2->length; long len3 = poly3->length; long len = len3 - 1; mp_ptr ptr2; if (len3 == 0) { printf("exception: division by zero in nmod_poly_compose_mod_horner\n"); abort(); } if (len1 == 0 || len3 == 1) { nmod_poly_zero(res); return; } if (len1 == 1) { nmod_poly_set(res, poly1); return; } if (res == poly3 || res == poly1) { nmod_poly_t tmp; nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); nmod_poly_compose_mod_horner(tmp, poly1, poly2, poly3); nmod_poly_swap(tmp, res); nmod_poly_clear(tmp); return; } ptr2 = _nmod_vec_init(len); if (len2 <= len) { mpn_copyi(ptr2, poly2->coeffs, len2); mpn_zero(ptr2 + len2, len - len2); } else { _nmod_poly_rem(ptr2, poly2->coeffs, len2, poly3->coeffs, len3, res->mod); } nmod_poly_fit_length(res, len); _nmod_poly_compose_mod_horner(res->coeffs, poly1->coeffs, len1, ptr2, poly3->coeffs, len3, res->mod); res->length = len; _nmod_poly_normalise(res); _nmod_vec_clear(ptr2); }
int main(void) { int i; flint_rand_t state; printf("sqrt... "); fflush(stdout); flint_randinit(state); /* Test aliasing */ for (i = 0; i < 2000; i++) { nmod_poly_t a, b; int square1, square2; mp_limb_t mod; mod = n_randtest_prime(state, 0); nmod_poly_init(a, mod); nmod_poly_init(b, mod); nmod_poly_randtest(a, state, 1 + n_randint(state, 50)); if (n_randint(state, 2)) nmod_poly_mul(a, a, a); square1 = nmod_poly_sqrt(b, a); square2 = nmod_poly_sqrt(a, a); if ((square1 != square2) || (square1 && !nmod_poly_equal(a, b))) { printf("FAIL: aliasing:\n"); printf("square1 = %d, square2 = %d\n\n", square1, square2); printf("a: "); nmod_poly_print(a); printf("\n\n"); printf("b: "); nmod_poly_print(b); printf("\n\n"); abort(); } nmod_poly_clear(a); nmod_poly_clear(b); } /* Test random squares */ for (i = 0; i < 2000; i++) { nmod_poly_t a, b, c; int square; mp_limb_t mod; mod = n_randtest_prime(state, 0); nmod_poly_init(a, mod); nmod_poly_init(b, mod); nmod_poly_init(c, mod); nmod_poly_randtest(a, state, 1 + n_randint(state, 50)); nmod_poly_mul(b, a, a); square = nmod_poly_sqrt(c, b); if (!square) { printf("FAIL: square reported nonsquare:\n"); printf("a: "); nmod_poly_print(a); printf("\n\n"); printf("b: "); nmod_poly_print(b); printf("\n\n"); printf("c: "); nmod_poly_print(c); printf("\n\n"); abort(); } nmod_poly_mul(c, c, c); if (!nmod_poly_equal(c, b)) { printf("FAIL: sqrt(b)^2 != b:\n"); printf("a: "); nmod_poly_print(a); printf("\n\n"); printf("b: "); nmod_poly_print(b); printf("\n\n"); printf("c: "); nmod_poly_print(c); printf("\n\n"); abort(); } nmod_poly_clear(a); nmod_poly_clear(b); nmod_poly_clear(c); } /* Test "almost" squares */ for (i = 0; i < 2000; i++) { nmod_poly_t a, b, c; long j; int square; mp_limb_t mod; mod = n_randtest_prime(state, 0); nmod_poly_init(a, mod); nmod_poly_init(b, mod); nmod_poly_init(c, mod); nmod_poly_randtest_not_zero(a, state, 1 + n_randint(state, 50)); nmod_poly_mul(b, a, a); j = n_randint(state, nmod_poly_length(b)); b->coeffs[j] = n_randint(state, mod); _nmod_poly_normalise(b); square = nmod_poly_sqrt(c, b); if (square) { nmod_poly_mul(c, c, c); if (!nmod_poly_equal(c, b)) { printf("FAIL: sqrt(b)^2 != b:\n"); printf("a: "); nmod_poly_print(a); printf("\n\n"); printf("b: "); nmod_poly_print(b); printf("\n\n"); printf("c: "); nmod_poly_print(c); printf("\n\n"); abort(); } } nmod_poly_clear(a); nmod_poly_clear(b); nmod_poly_clear(c); } flint_randclear(state); printf("PASS\n"); return 0; }
void nmod_poly_divrem_basecase(nmod_poly_t Q, nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B) { const slong lenA = A->length, lenB = B->length; mp_ptr Q_coeffs, R_coeffs, W; nmod_poly_t t1, t2; TMP_INIT; if (lenB == 0) { flint_printf("Exception (nmod_poly_divrem). Division by zero.\n"); abort(); } if (lenA < lenB) { nmod_poly_set(R, A); nmod_poly_zero(Q); return; } if (Q == A || Q == B) { nmod_poly_init2_preinv(t1, B->mod.n, B->mod.ninv, lenA - lenB + 1); Q_coeffs = t1->coeffs; } else { nmod_poly_fit_length(Q, lenA - lenB + 1); Q_coeffs = Q->coeffs; } if (R == A || R == B) { nmod_poly_init2_preinv(t2, B->mod.n, B->mod.ninv, lenB - 1); R_coeffs = t2->coeffs; } else { nmod_poly_fit_length(R, lenB - 1); R_coeffs = R->coeffs; } TMP_START; W = TMP_ALLOC(NMOD_DIVREM_BC_ITCH(lenA, lenB, A->mod)*sizeof(mp_limb_t)); _nmod_poly_divrem_basecase(Q_coeffs, R_coeffs, W, A->coeffs, lenA, B->coeffs, lenB, B->mod); if (Q == A || Q == B) { nmod_poly_swap(Q, t1); nmod_poly_clear(t1); } if (R == A || R == B) { nmod_poly_swap(R, t2); nmod_poly_clear(t2); } Q->length = lenA - lenB + 1; R->length = lenB - 1; TMP_END; _nmod_poly_normalise(R); }