void _nmod_poly_div_basecase_2(mp_ptr Q, mp_ptr W, mp_srcptr A, long A_len, mp_srcptr B, long B_len, nmod_t mod) { long coeff, i, len; mp_limb_t lead_inv = n_invmod(B[B_len - 1], mod.n); mp_ptr B2, R2; mp_srcptr Btop; B2 = W; for (i = 0; i < B_len - 1; i++) { B2[2 * i] = B[i]; B2[2 * i + 1] = 0; } Btop = B2 + 2*(B_len - 1); R2 = W + 2*(B_len - 1); for (i = 0; i < A_len - B_len + 1; i++) { R2[2 * i] = A[B_len + i - 1]; R2[2 * i + 1] = 0; } coeff = A_len - B_len; while (coeff >= 0) { mp_limb_t r_coeff; r_coeff = n_ll_mod_preinv(R2[2 * coeff + 1], R2[2 * coeff], mod.n, mod.ninv); while (coeff >= 0 && r_coeff == 0L) { Q[coeff--] = 0L; if (coeff >= 0) r_coeff = n_ll_mod_preinv(R2[2 * coeff + 1], R2[2 * coeff], mod.n, mod.ninv); } if (coeff >= 0) { mp_limb_t c, * R_sub; Q[coeff] = n_mulmod2_preinv(r_coeff, lead_inv, mod.n, mod.ninv); c = n_negmod(Q[coeff], mod.n); len = FLINT_MIN(B_len - 1, coeff); R_sub = R2 + 2 * (coeff - len); if (len > 0) mpn_addmul_1(R_sub, Btop - 2*len, 2 * len, c); coeff--; } } }
void _nmod_poly_divrem_basecase_1(mp_ptr Q, mp_ptr R, mp_ptr W, mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod) { const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); slong iR; mp_ptr ptrQ = Q - lenB + 1; mp_ptr R1 = W; flint_mpn_copyi(R1, A, lenA); for (iR = lenA - 1; iR >= lenB - 1; iR--) { if (R1[iR] == 0) { ptrQ[iR] = WORD(0); } else { ptrQ[iR] = n_mulmod2_preinv(R1[iR], invL, mod.n, mod.ninv); if (lenB > 1) { const mp_limb_t c = n_negmod(ptrQ[iR], mod.n); mpn_addmul_1(R1 + iR - lenB + 1, B, lenB - 1, c); } } } if (lenB > 1) _nmod_vec_reduce(R, R1, lenB - 1, mod); }
void _nmod_poly_rem_basecase_1(mp_ptr R, mp_ptr W, mp_srcptr A, long lenA, mp_srcptr B, long lenB, nmod_t mod) { if (lenB > 1) { const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); long iR; mp_ptr R1 = W; mpn_copyi(R1, A, lenA); for (iR = lenA - 1; iR >= lenB - 1; iR--) { if (R1[iR] != 0) { const mp_limb_t q = n_mulmod2_preinv(R1[iR], invL, mod.n, mod.ninv); const mp_limb_t c = n_negmod(q, mod.n); mpn_addmul_1(R1 + iR - lenB + 1, B, lenB - 1, c); } } _nmod_vec_reduce(R, R1, lenB - 1, mod); } }
static __inline__ mp_limb_t nmod_set_si(long v, nmod_t mod) { mp_limb_t u = n_mod2_preinv(FLINT_ABS(v), mod.n, mod.ninv); if (v < 0) u = n_negmod(u, mod.n); return u; }
void _nmod_poly_divrem_basecase_3(mp_ptr Q, mp_ptr R, mp_ptr W, mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod) { const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); slong iR, i; mp_ptr B3 = W, R3 = W + 3*(lenB - 1), ptrQ = Q - lenB + 1; for (i = 0; i < lenB - 1; i++) { B3[3 * i] = B[i]; B3[3 * i + 1] = 0; B3[3 * i + 2] = 0; } for (i = 0; i < lenA; i++) { R3[3 * i] = A[i]; R3[3 * i + 1] = 0; R3[3 * i + 2] = 0; } for (iR = lenA - 1; iR >= lenB - 1; ) { mp_limb_t r = n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], R3[3 * iR], mod.n, mod.ninv); while ((iR + 1 >= lenB) && (r == WORD(0))) { ptrQ[iR--] = WORD(0); if (iR + 1 >= lenB) r = n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], R3[3 * iR], mod.n, mod.ninv); } if (iR + 1 >= lenB) { ptrQ[iR] = n_mulmod2_preinv(r, invL, mod.n, mod.ninv); if (lenB > 1) { const mp_limb_t c = n_negmod(ptrQ[iR], mod.n); mpn_addmul_1(R3 + 3 * (iR - lenB + 1), B3, 3 * lenB - 3, c); } iR--; } } for (iR = 0; iR < lenB - 1; iR++) R[iR] = n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], R3[3 * iR], mod.n, mod.ninv); }
void _fq_nmod_trace(fmpz_t rop2, const mp_limb_t *op, slong len, const fq_nmod_ctx_t ctx) { const slong d = fq_nmod_ctx_degree(ctx); ulong i, l; mp_limb_t *t, rop; t = _nmod_vec_init(d); _nmod_vec_zero(t, d); t[0] = n_mod2_preinv(d, ctx->mod.n, ctx->mod.ninv); for (i = 1; i < d; i++) { for (l = ctx->len - 2; l >= 0 && ctx->j[l] >= d - (i - 1); l--) { t[i] = n_addmod(t[i], n_mulmod2_preinv(t[ctx->j[l] + i - d], ctx->a[l], ctx->mod.n, ctx->mod.ninv), ctx->mod.n); } if (l >= 0 && ctx->j[l] == d - i) { t[i] = n_addmod(t[i], n_mulmod2_preinv(ctx->a[l], i, ctx->mod.n, ctx->mod.ninv), ctx->mod.n); } t[i] = n_negmod(t[i], ctx->mod.n); } rop = WORD(0); for (i = 0; i < d; i++) { rop = n_addmod(rop, n_mulmod2_preinv(op[i], t[i], ctx->mod.n, ctx->mod.ninv), ctx->mod.n); } _nmod_vec_clear(t); fmpz_set_ui(rop2, rop); }
void _nmod_poly_div_basecase_1(mp_ptr Q, mp_ptr W, mp_srcptr A, long A_len, mp_srcptr B, long B_len, nmod_t mod) { mp_limb_t lead_inv = n_invmod(B[B_len - 1], mod.n); long len, coeff = A_len - B_len; mp_ptr R1 = W; mp_srcptr Btop = B + B_len - 1; mpn_copyi(R1, A + B_len - 1, A_len - B_len + 1); while (coeff >= 0) { R1[coeff] = n_mod2_preinv(R1[coeff], mod.n, mod.ninv); while (coeff >= 0 && R1[coeff] == 0L) { Q[coeff--] = 0L; if (coeff >= 0) R1[coeff] = n_mod2_preinv(R1[coeff], mod.n, mod.ninv); } if (coeff >= 0) { mp_limb_t c, * R_sub; Q[coeff] = n_mulmod2_preinv(R1[coeff], lead_inv, mod.n, mod.ninv); c = n_negmod(Q[coeff], mod.n); len = FLINT_MIN(B_len - 1, coeff); R_sub = R1 + coeff - len; if (len > 0) mpn_addmul_1(R_sub, Btop - len, len, c); coeff--; } } }
void _nmod_poly_rem_basecase_3(mp_ptr R, mp_ptr W, mp_srcptr A, long lenA, mp_srcptr B, long lenB, nmod_t mod) { if (lenB > 1) { const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); long iR, i; mp_ptr B3 = W, R3 = W + 3*(lenB - 1); for (i = 0; i < lenB - 1; i++) { B3[3 * i] = B[i]; B3[3 * i + 1] = 0; B3[3 * i + 2] = 0; } for (i = 0; i < lenA; i++) { R3[3 * i] = A[i]; R3[3 * i + 1] = 0; R3[3 * i + 2] = 0; } for (iR = lenA - 1; iR >= lenB - 1; iR--) { const mp_limb_t r = n_lll_mod_preinv(R3[3*iR + 2], R3[3*iR + 1], R3[3*iR], mod.n, mod.ninv); if (r != 0) { const mp_limb_t q = n_mulmod2_preinv(r, invL, mod.n, mod.ninv); const mp_limb_t c = n_negmod(q, mod.n); mpn_addmul_1(R3 + 3 * (iR - lenB + 1), B3, 3 * lenB - 3, c); } } for (iR = 0; iR < lenB - 1; iR++) R[iR] = n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], R3[3 * iR], mod.n, mod.ninv); } }
void fmpz_powm_ui(fmpz_t f, const fmpz_t g, ulong e, const fmpz_t m) { if (fmpz_sgn(m) <= 0) { printf("Exception (fmpz_powm_ui). Modulus is less than 1.\n"); abort(); } if (fmpz_is_one(m)) { fmpz_zero(f); } else if (e == 0) { fmpz_one(f); } else /* e != 0, m > 0 */ { fmpz g2 = *g; fmpz m2 = *m; if (!COEFF_IS_MPZ(m2)) /* m is small */ { if (!COEFF_IS_MPZ(g2)) /* g is small */ { mp_limb_t minv = n_preinvert_limb(m2); _fmpz_demote(f); if (g2 >= 0) { g2 = n_mod2_preinv(g2, m2, minv); *f = n_powmod2_preinv(g2, e, m2, minv); } else { g2 = n_mod2_preinv(-g2, m2, minv); *f = n_powmod2_preinv(g2, e, m2, minv); if ((e & 1UL)) *f = n_negmod(*f, m2); } } else /* g is large */ { __mpz_struct *ptr = _fmpz_promote(f); mpz_t m3; mpz_init_set_ui(m3, m2); mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, m3); mpz_clear(m3); _fmpz_demote_val(f); } } else /* m is large */ { if (!COEFF_IS_MPZ(g2)) /* g is small */ { __mpz_struct *ptr = _fmpz_promote(f); mpz_t g3; mpz_init_set_si(g3, g2); mpz_powm_ui(ptr, g3, e, COEFF_TO_PTR(m2)); mpz_clear(g3); _fmpz_demote_val(f); } else /* g is large */ { __mpz_struct *ptr = _fmpz_promote(f); mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, COEFF_TO_PTR(m2)); _fmpz_demote_val(f); } } } }