void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, const fmpz_t c) { fmpz_t gcd; /* GCD( den, c ) */ if (fmpz_is_zero(c)) { _fmpz_vec_zero(rpoly, len); fmpz_one(rden); return; } fmpz_init(gcd); fmpz_one(gcd); if (*c != 1L) fmpz_gcd(gcd, c, den); if (*gcd == 1L) { _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c); fmpz_set(rden, den); } else { fmpz_t c2; fmpz_init(c2); fmpz_divexact(c2, c, gcd); _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c2); fmpz_divexact(rden, den, gcd); fmpz_clear(c2); } fmpz_clear(gcd); }
void fmpq_poly_compose(fmpq_poly_t res, const fmpq_poly_t poly1, const fmpq_poly_t poly2) { const long len1 = poly1->length; const long len2 = poly2->length; long lenr; if (len1 == 0L) { fmpq_poly_zero(res); return; } if (len1 == 1L || len2 == 0L) { fmpq_poly_fit_length(res, 1); fmpz_set(res->coeffs, poly1->coeffs); fmpz_set(res->den, poly1->den); { fmpz_t d; fmpz_init(d); fmpz_gcd(d, res->coeffs, res->den); if (*d != 1L) { fmpz_divexact(res->coeffs, res->coeffs, d); fmpz_divexact(res->den, res->den, d); } fmpz_clear(d); } _fmpq_poly_set_length(res, 1); _fmpq_poly_normalise(res); return; } lenr = (len1 - 1L) * (len2 - 1L) + 1L; if ((res != poly1) && (res != poly2)) { fmpq_poly_fit_length(res, lenr); _fmpq_poly_compose(res->coeffs, res->den, poly1->coeffs, poly1->den, len1, poly2->coeffs, poly2->den, len2); _fmpq_poly_set_length(res, lenr); _fmpq_poly_normalise(res); } else { fmpq_poly_t t; fmpq_poly_init2(t, lenr); _fmpq_poly_compose(t->coeffs, t->den, poly1->coeffs, poly1->den, len1, poly2->coeffs, poly2->den, len2); _fmpq_poly_set_length(t, lenr); _fmpq_poly_normalise(t); fmpq_poly_swap(res, t); fmpq_poly_clear(t); } }
void _fmpq_poly_canonicalise(fmpz * poly, fmpz_t den, slong len) { if (*den == WORD(1)) return; if (*den == WORD(-1)) { _fmpz_vec_neg(poly, poly, len); fmpz_one(den); } else if (len == 0) { fmpz_one(den); } else { fmpz_t gcd; fmpz_init(gcd); _fmpz_vec_content(gcd, poly, len); if (*gcd != WORD(1)) fmpz_gcd(gcd, gcd, den); if (fmpz_sgn(den) < 0) fmpz_neg(gcd, gcd); if (*gcd != WORD(1)) { _fmpz_vec_scalar_divexact_fmpz(poly, poly, len, gcd); fmpz_divexact(den, den, gcd); } fmpz_clear(gcd); } }
static void _padic_log_bsplit(fmpz_t z, const fmpz_t y, long v, const fmpz_t p, long N) { fmpz_t P, B, T; long n; if (fmpz_fits_si(p)) n = _padic_log_bound(v, N, fmpz_get_si(p)); else n = (N - 1) / v; n = FLINT_MAX(n, 2); fmpz_init(P); fmpz_init(B); fmpz_init(T); _padic_log_bsplit_series(P, B, T, y, 1, n); n = fmpz_remove(B, B, p); fmpz_pow_ui(P, p, n); fmpz_divexact(T, T, P); _padic_inv(B, B, p, N); fmpz_mul(z, T, B); fmpz_clear(P); fmpz_clear(B); fmpz_clear(T); }
void fmpz_mat_solve_fflu_precomp(fmpz_mat_t X, const long * perm, const fmpz_mat_t FFLU, const fmpz_mat_t B) { fmpz_t T; long i, j, k, m, n; n = X->r; m = X->c; fmpz_init(T); fmpz_mat_set_perm(X, perm, B); for (k = 0; k < m; k++) { /* Fraction-free forward substitution */ for (i = 0; i < n - 1; i++) { for (j = i + 1; j < n; j++) { fmpz_mul(XX(j, k), XX(j, k), LU(i, i)); fmpz_mul(T, LU(j, i), XX(i, k)); fmpz_sub(XX(j, k), XX(j, k), T); if (i > 0) fmpz_divexact(XX(j, k), XX(j, k), LU(i-1, i-1)); } } /* Fraction-free back substitution */ for (i = n - 2; i >= 0; i--) { fmpz_mul(XX(i, k), XX(i, k), LU(n-1, n-1)); for (j = i + 1; j < n; j++) { fmpz_mul(T, XX(j, k), LU(i, j)); fmpz_sub(XX(i, k), XX(i, k), T); } fmpz_divexact(XX(i, k), XX(i, k), LU(i, i)); } } fmpz_clear(T); }
void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, long x) { fmpz_t cont, fx, gcd; if (fmpz_poly_q_is_zero(op) || (x == 0)) { fmpz_poly_q_zero(rop); return; } if (x == 1) { fmpz_poly_q_set(rop, op); return; } fmpz_init(cont); fmpz_poly_content(cont, op->den); if (fmpz_is_one(cont)) { fmpz_poly_scalar_mul_si(rop->num, op->num, x); fmpz_poly_set(rop->den, op->den); fmpz_clear(cont); return; } fmpz_init(fx); fmpz_init(gcd); fmpz_set_si(fx, x); fmpz_gcd(gcd, cont, fx); if (fmpz_is_one(gcd)) { fmpz_poly_scalar_mul_si(rop->num, op->num, x); fmpz_poly_set(rop->den, op->den); } else { fmpz_divexact(fx, fx, gcd); fmpz_poly_scalar_mul_fmpz(rop->num, op->num, fx); fmpz_poly_scalar_divexact_fmpz(rop->den, op->den, gcd); } fmpz_clear(cont); fmpz_clear(fx); fmpz_clear(gcd); }
void _fmpq_mat_get_fmpz_mat_rowwise(fmpz_mat_struct ** num, fmpz * den, const fmpq_mat_struct ** mat, slong n) { fmpz_t t, lcm; slong i, j, k; if (fmpq_mat_is_empty(mat[0])) return; fmpz_init(t); fmpz_init(lcm); for (i = 0; i < mat[0]->r; i++) { /* Compute common denominator of row */ fmpz_set(lcm, fmpq_mat_entry_den(mat[0], i, 0)); for (k = 0; k < n; k++) for (j = (k == 0); j < mat[k]->c; j++) fmpz_lcm(lcm, lcm, fmpq_mat_entry_den(mat[k], i, j)); if (den != NULL) fmpz_set(den + i, lcm); for (k = 0; k < n; k++) { /* Rescale numerators in row */ if (fmpz_is_one(lcm)) { for (j = 0; j < mat[k]->c; j++) fmpz_set(fmpz_mat_entry(num[k], i, j), fmpq_mat_entry_num(mat[k], i, j)); } else { for (j = 0; j < mat[k]->c; j++) { fmpz_divexact(t, lcm, fmpq_mat_entry_den(mat[k], i, j)); fmpz_mul(fmpz_mat_entry(num[k], i, j), fmpq_mat_entry_num(mat[k], i, j), t); } } } } fmpz_clear(t); fmpz_clear(lcm); }
void _fmpz_poly_pow_multinomial(fmpz * res, const fmpz * poly, long len, ulong e) { long k, low, rlen; fmpz_t d, t; fmpz * P; rlen = (long) e * (len - 1L) + 1L; _fmpz_vec_zero(res, rlen); for (low = 0L; poly[low] == 0L; low++) ; if (low == 0L) { P = (fmpz *) poly; } else { P = (fmpz *) poly + low; len -= low; res += (long) e * low; rlen -= (long) e * low; } fmpz_init(d); fmpz_init(t); fmpz_pow_ui(res, P, e); for (k = 1; k < rlen; k++) { long i, u = -k; for (i = 1; i <= FLINT_MIN(k, len - 1); i++) { fmpz_mul(t, P + i, res + (k - i)); u += (long) e + 1; if (u >= 0) fmpz_addmul_ui(res + k, t, (ulong) u); else fmpz_submul_ui(res + k, t, - ((ulong) u)); } fmpz_add(d, d, P); fmpz_divexact(res + k, res + k, d); } fmpz_clear(d); fmpz_clear(t); }
static void _set_vec(fmpz * rnum, fmpz_t den, const fmpz * xnum, const fmpz * xden, slong len) { slong j; fmpz_t t; fmpz_init(t); fmpz_one(den); for (j = 0; j < len; j++) fmpz_lcm(den, den, xden + j); for (j = 0; j < len; j++) { fmpz_divexact(t, den, xden + j); fmpz_mul(rnum + j, xnum + j, t); } fmpz_clear(t); }
int main(void) { int i, result; flint_rand_t state; printf("div_basecase...."); fflush(stdout); flint_randinit(state); /* Compare to divrem_basecase */ for (i = 0; i < 5000; i++) { fmpz_t p; fmpz_mod_poly_t a, b, q, q2, r2; fmpz_init(p); fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); fmpz_add_ui(p, p, 2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_init(b, p); fmpz_mod_poly_init(q, p); fmpz_mod_poly_init(q2, p); fmpz_mod_poly_init(r2, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); { fmpz_t d; fmpz *leadB = fmpz_mod_poly_lead(b); fmpz_init(d); fmpz_gcd(d, p, leadB); while (!fmpz_is_one(d)) { fmpz_divexact(leadB, leadB, d); fmpz_gcd(d, p, leadB); } fmpz_clear(d); } fmpz_mod_poly_div_basecase(q, a, b); fmpz_mod_poly_divrem_basecase(q2, r2, a, b); result = (fmpz_mod_poly_equal(q, q2)); if (!result) { printf("FAIL:\n"); printf("p = "), fmpz_print(p), printf("\n\n"); printf("a = "), fmpz_mod_poly_print(a), printf("\n\n"); printf("b = "), fmpz_mod_poly_print(b), printf("\n\n"); printf("q = "), fmpz_mod_poly_print(q), printf("\n\n"); printf("q2 = "), fmpz_mod_poly_print(q2), printf("\n\n"); printf("r2 = "), fmpz_mod_poly_print(r2), printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_mod_poly_clear(b); fmpz_mod_poly_clear(q); fmpz_mod_poly_clear(q2); fmpz_mod_poly_clear(r2); fmpz_clear(p); } /* Alias a and q */ for (i = 0; i < 500; i++) { fmpz_t p; fmpz_mod_poly_t a, b, q; fmpz_init(p); fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); fmpz_add_ui(p, p, 2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_init(b, p); fmpz_mod_poly_init(q, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); { fmpz_t d; fmpz *leadB = fmpz_mod_poly_lead(b); fmpz_init(d); fmpz_gcd(d, p, leadB); while (!fmpz_is_one(d)) { fmpz_divexact(leadB, leadB, d); fmpz_gcd(d, p, leadB); } fmpz_clear(d); } fmpz_mod_poly_div_basecase(q, a, b); fmpz_mod_poly_div_basecase(a, a, b); result = (fmpz_mod_poly_equal(q, a)); if (!result) { printf("FAIL:\n"); printf("p = "), fmpz_print(p), printf("\n\n"); printf("a = "), fmpz_mod_poly_print(a), printf("\n\n"); printf("b = "), fmpz_mod_poly_print(b), printf("\n\n"); printf("q = "), fmpz_mod_poly_print(q), printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_mod_poly_clear(b); fmpz_mod_poly_clear(q); fmpz_clear(p); } /* Alias b and q */ for (i = 0; i < 500; i++) { fmpz_t p; fmpz_mod_poly_t a, b, q; fmpz_init(p); fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); fmpz_add_ui(p, p, 2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_init(b, p); fmpz_mod_poly_init(q, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); { fmpz_t d; fmpz *leadB = fmpz_mod_poly_lead(b); fmpz_init(d); fmpz_gcd(d, p, leadB); while (!fmpz_is_one(d)) { fmpz_divexact(leadB, leadB, d); fmpz_gcd(d, p, leadB); } fmpz_clear(d); } fmpz_mod_poly_div_basecase(q, a, b); fmpz_mod_poly_div_basecase(b, a, b); result = (fmpz_mod_poly_equal(q, b)); if (!result) { printf("FAIL:\n"); printf("p = "), fmpz_print(p), printf("\n\n"); printf("a = "), fmpz_mod_poly_print(a), printf("\n\n"); printf("b = "), fmpz_mod_poly_print(b), printf("\n\n"); printf("q = "), fmpz_mod_poly_print(q), printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_mod_poly_clear(b); fmpz_mod_poly_clear(q); fmpz_clear(p); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("divexact...."); fflush(stdout); for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c; mpz_t d, e, f, g; fmpz_init(a); fmpz_init(b); fmpz_init(c); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_mul(c, a, b); fmpz_get_mpz(d, b); fmpz_get_mpz(e, c); fmpz_divexact(a, c, b); mpz_divexact(f, e, d); fmpz_get_mpz(g, a); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); } /* Check aliasing of a and b */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, c; mpz_t d, f, g; fmpz_init(a); fmpz_init(c); mpz_init(d); mpz_init(f); mpz_init(g); fmpz_randtest_not_zero(a, state, 200); fmpz_get_mpz(d, a); fmpz_divexact(c, a, a); mpz_divexact(f, d, d); fmpz_get_mpz(g, c); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); abort(); } fmpz_clear(a); fmpz_clear(c); mpz_clear(d); mpz_clear(f); mpz_clear(g); } /* Test aliasing of a and c */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c; mpz_t d, e, f, g; fmpz_init(a); fmpz_init(b); fmpz_init(c); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_mul(c, a, b); fmpz_get_mpz(d, c); fmpz_get_mpz(e, b); fmpz_divexact(c, c, b); mpz_divexact(f, d, e); fmpz_get_mpz(g, c); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); } /* Test aliasing of b and c */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c; mpz_t d, e, f, g; fmpz_init(a); fmpz_init(b); fmpz_init(c); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_mul(c, a, b); fmpz_get_mpz(d, c); fmpz_get_mpz(e, b); fmpz_divexact(b, c, b); mpz_divexact(f, d, e); fmpz_get_mpz(g, b); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
void _fmpz_poly_resultant(fmpz_t res, const fmpz * poly1, long len1, const fmpz * poly2, long len2) { if (len2 == 1) { fmpz_pow_ui(res, poly2, len1 - 1); } else { fmpz_t a, b, g, h, t; fmpz *A, *B, *W; const long alloc = len1 + len2; long sgn = 1; fmpz_init(a); fmpz_init(b); fmpz_init(g); fmpz_init(h); fmpz_init(t); A = W = _fmpz_vec_init(alloc); B = W + len1; _fmpz_poly_content(a, poly1, len1); _fmpz_poly_content(b, poly2, len2); _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, a); _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, b); fmpz_set_ui(g, 1); fmpz_set_ui(h, 1); fmpz_pow_ui(a, a, len2 - 1); fmpz_pow_ui(b, b, len1 - 1); fmpz_mul(t, a, b); do { const long d = len1 - len2; if (!(len1 & 1L) & !(len2 & 1L)) sgn = -sgn; _fmpz_poly_pseudo_rem_cohen(A, A, len1, B, len2); for (len1--; len1 >= 0 && !A[len1]; len1--) ; len1++; if (len1 == 0) { fmpz_zero(res); goto cleanup; } { fmpz * T; long len; T = A, A = B, B = T; len = len1, len1 = len2, len2 = len; } fmpz_pow_ui(a, h, d); fmpz_mul(b, g, a); _fmpz_vec_scalar_divexact_fmpz(B, B, len2, b); fmpz_pow_ui(g, A + (len1 - 1), d); fmpz_mul(b, h, g); fmpz_divexact(h, b, a); fmpz_set(g, A + (len1 - 1)); } while (len2 > 1); fmpz_pow_ui(g, h, len1 - 1); fmpz_pow_ui(b, B + (len2 - 1), len1 - 1); fmpz_mul(a, h, b); fmpz_divexact(h, a, g); fmpz_mul(res, t, h); if (sgn < 0) fmpz_neg(res, res); cleanup: fmpz_clear(a); fmpz_clear(b); fmpz_clear(g); fmpz_clear(h); fmpz_clear(t); _fmpz_vec_clear(W, alloc); } }
void fmpz_holonomic_get_nth_fmpq(fmpq_t res, const fmpz_holonomic_t op, const fmpq * initial, long n0, long n) { long r = fmpz_holonomic_order(op); if (r == 0) { fmpq_zero(res); return; } else if (n < n0) { printf("not implemented\n"); abort(); } else if (n - n0 < r) { fmpq_set(res, initial + n - n0); return; } else { fmpz_mat_t M; long i; fmpz_t Q; fmpz_mat_init(M, r, r); fmpz_init(Q); fmpz_holonomic_forward_fmpz_mat(M, Q, op, n0, n - n0 - r + 1); { fmpz_t g, t; fmpz_init(g); fmpz_init(t); fmpz_one(g); for (i = 0; i < r; i++) fmpz_lcm(g, g, fmpq_denref(initial + i)); fmpz_divexact(t, g, fmpq_denref(initial + 0)); fmpz_mul(t, t, fmpq_numref(initial + 0)); fmpz_mul(fmpz_mat_entry(M, r - 1, 0), fmpz_mat_entry(M, r - 1, 0), t); for (i = 1; i < r; i++) { fmpz_divexact(t, g, fmpq_denref(initial + i)); fmpz_mul(t, t, fmpq_numref(initial + i)); fmpz_addmul(fmpz_mat_entry(M, r - 1, 0), fmpz_mat_entry(M, r - 1, i), t); } fmpz_set(fmpq_numref(res), fmpz_mat_entry(M, r - 1, 0)); fmpz_mul(fmpq_denref(res), Q, g); fmpq_canonicalise(res); fmpz_clear(g); fmpz_clear(t); } fmpz_mat_clear(M); fmpz_clear(Q); } }
void _fmpq_sub(fmpz_t rnum, fmpz_t rden, const fmpz_t p, const fmpz_t q, const fmpz_t r, const fmpz_t s) { fmpz_t g, a, b, t, u; /* Same denominator */ if (fmpz_equal(q, s)) { fmpz_sub(rnum, p, r); /* Both are integers */ if (fmpz_is_one(q)) { fmpz_set(rden, q); } else { fmpz_init(g); fmpz_gcd(g, rnum, q); if (fmpz_is_one(g)) { fmpz_set(rden, q); } else { fmpz_divexact(rnum, rnum, g); fmpz_divexact(rden, q, g); } fmpz_clear(g); } return; } /* p/q is an integer */ if (fmpz_is_one(q)) { fmpz_init(t); fmpz_mul(t, p, s); fmpz_sub(rnum, t, r); fmpz_set(rden, s); fmpz_clear(t); return; } /* r/s is an integer */ if (fmpz_is_one(s)) { fmpz_init(t); fmpz_mul(t, r, q); fmpz_sub(rnum, p, t); fmpz_set(rden, q); fmpz_clear(t); return; } fmpz_init(g); fmpz_gcd(g, q, s); if (fmpz_is_one(g)) { fmpz_init(t); fmpz_init(u); fmpz_mul(t, p, s); fmpz_mul(u, q, r); fmpz_sub(rnum, t, u); fmpz_mul(rden, q, s); fmpz_clear(t); fmpz_clear(u); } else { fmpz_init(a); fmpz_init(b); fmpz_init(t); fmpz_init(u); fmpz_divexact(a, q, g); fmpz_divexact(b, s, g); fmpz_mul(t, p, b); fmpz_mul(u, r, a); fmpz_sub(rnum, t, u); fmpz_gcd(t, rnum, g); if (fmpz_is_one(t)) { fmpz_mul(rden, q, b); } else { fmpz_divexact(rnum, rnum, t); fmpz_divexact(g, q, t); fmpz_mul(rden, g, b); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(t); fmpz_clear(u); } fmpz_clear(g); }
void eis_series(fmpz_poly_t *eis, ulong k, ulong prec) { ulong i, p, ee, p_pow, ind; fmpz_t last, last_m1, mult, fp, t_coeff, term, term_m1; long bern_fac[15] = {0, 0, 0, 0, 240, 0, -504, 0, 480, 0, -264, 0, 0, 0, -24}; // Now, we compute the eisenstein series // First, compute primes by sieving. // allocate memory for the array. /* char *primes; primes = calloc(prec + 1, sizeof(char)); for(i = 0; i <= prec; i++) { primes[i] = 1; } primes[0] = 0; primes[1] = 0; p = 2; while(p*p <= prec) { j = p*p; while(j <= prec) { primes[j] = 0; j += p; } p += 1; while(primes[p] != 1) p += 1; } */ // Now, create the eisenstein series. // We build up each coefficient using the multiplicative properties of the // divisor sum function. fmpz_poly_set_coeff_si(*eis, 0, 1); for(i = 1; i <= prec; i++) fmpz_poly_set_coeff_si(*eis, i, bern_fac[k]); fmpz_init(last); fmpz_init(last_m1); fmpz_init(mult); fmpz_init(fp); fmpz_init(t_coeff); fmpz_init(term); fmpz_init(term_m1); ee = k - 1; p = 2; while(p <= prec) { p_pow = p; fmpz_set_ui(fp, p); fmpz_pow_ui(mult, fp, ee); fmpz_pow_ui(term, mult, 2); fmpz_set(last, mult); while(p_pow <= prec) { ind = p_pow; fmpz_sub_ui(term_m1, term, 1); fmpz_sub_ui(last_m1, last, 1); while(ind <= prec) { fmpz_poly_get_coeff_fmpz(t_coeff, *eis, ind); fmpz_mul(t_coeff, t_coeff, term_m1); fmpz_divexact(t_coeff, t_coeff, last_m1); fmpz_poly_set_coeff_fmpz(*eis, ind, t_coeff); ind += p_pow; } p_pow *= p; fmpz_set(last, term); fmpz_mul(term, term, mult); } p = n_nextprime(p, 1); } fmpz_clear(last); fmpz_clear(last_m1); fmpz_clear(mult); fmpz_clear(fp); fmpz_clear(t_coeff); fmpz_clear(term); fmpz_clear(term_m1); }
void nf_elem_rep_mat_fmpz_mat_den(fmpz_mat_t res, fmpz_t den, const nf_elem_t a, const nf_t nf) { if (nf->flag & NF_LINEAR) { fmpz_set(fmpz_mat_entry(res, 0, 0), LNF_ELEM_NUMREF(a)); fmpz_set(den, LNF_ELEM_DENREF(a)); } else if (nf->flag & NF_QUADRATIC) { nf_elem_t t; const fmpz * const anum = QNF_ELEM_NUMREF(a); const fmpz * const aden = QNF_ELEM_DENREF(a); fmpz * const tnum = QNF_ELEM_NUMREF(t); fmpz * const tden = QNF_ELEM_DENREF(t); nf_elem_init(t, nf); nf_elem_mul_gen(t, a, nf); if (fmpz_equal(tden, aden)) { fmpz_set(fmpz_mat_entry(res, 0, 0), anum); fmpz_set(fmpz_mat_entry(res, 0, 1), anum + 1); fmpz_set(fmpz_mat_entry(res, 1, 0), tnum); fmpz_set(fmpz_mat_entry(res, 1, 1), tnum + 1); fmpz_set(den, tden); } else { fmpz_lcm(den, tden, aden); fmpz_divexact(fmpz_mat_entry(res, 0, 0), den, aden); fmpz_mul(fmpz_mat_entry(res, 0, 1), anum + 1, fmpz_mat_entry(res, 0, 0)); fmpz_mul(fmpz_mat_entry(res, 0, 0), anum, fmpz_mat_entry(res, 0, 0)); fmpz_divexact(fmpz_mat_entry(res, 1, 0), den, tden); fmpz_mul(fmpz_mat_entry(res, 1, 1), tnum + 1, fmpz_mat_entry(res, 1, 0)); fmpz_mul(fmpz_mat_entry(res, 1, 0), tnum, fmpz_mat_entry(res, 1, 0)); } nf_elem_clear(t, nf); } else { slong i, j; nf_elem_t t; slong d = fmpq_poly_degree(nf->pol); nf_elem_init(t, nf); nf_elem_set(t, a, nf); if (NF_ELEM(a)->length == 0) { fmpz_mat_zero(res); fmpz_one(den); } else if (NF_ELEM(a)->length == 1) { fmpz_mat_zero(res); for (i = 0; i <= d - 1; i++) { fmpz_set(fmpz_mat_entry(res, i, i), fmpq_poly_numref(NF_ELEM(a))); } fmpz_set(den, fmpq_poly_denref(NF_ELEM(a))); } else { /* Special case if defining polynomial is monic and integral and the element also has trivial denominator */ if (nf->flag & NF_MONIC && fmpz_is_one(fmpq_poly_denref(nf->pol)) && fmpz_is_one(fmpq_poly_denref(NF_ELEM(a)))) { fmpz_one(den); for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, 0, i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, 0, i)); for (j = 1; j <= d - NF_ELEM(a)->length; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i < j; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, j, j + i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = j + NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); } for (j = d - NF_ELEM(a)->length + 1; j <= d - 1; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i <= d - 1; i++) fmpz_set(fmpz_mat_entry(res, j, i), fmpq_poly_numref(NF_ELEM(t)) + i); } } else { /* Now the general case. For 0 <= j < d - 2 we store the * denominator for row j at res[d - 1, j]. At the end we * divide the lcm of all of them by the corresponding * denominator of the row to get the correct multiplier for * row. */ for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, 0, i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, 0, i)); fmpz_set(fmpz_mat_entry(res, d - 1, 0), fmpq_poly_denref(NF_ELEM(a))); for (j = 1; j <= d - NF_ELEM(a)->length; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i < j; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, j, j + i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = j + NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); fmpz_set(fmpz_mat_entry(res, d - 1, j), fmpq_poly_denref(NF_ELEM(a))); } for (j = d - NF_ELEM(a)->length + 1; j <= d - 2; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i <= d - 1; i++) fmpz_set(fmpz_mat_entry(res, j, i), fmpq_poly_numref(NF_ELEM(t)) + i); fmpz_set(fmpz_mat_entry(res, d - 1, j), fmpq_poly_denref(NF_ELEM(t))); } nf_elem_mul_gen(t, t, nf); /* Now compute the correct denominator */ fmpz_set(fmpz_mat_entry(res, d - 1, d - 1), fmpq_poly_denref(NF_ELEM(t))); fmpz_set(den, fmpq_poly_denref(NF_ELEM(t))); for (j = 0; j <= d - 2; j++) fmpz_lcm(den, den, fmpz_mat_entry(res, d - 1, j)); for (j = 0; j <= d - 2; j++) { if (!fmpz_equal(den, fmpz_mat_entry(res, d - 1, j))) { fmpz_divexact(fmpz_mat_entry(res, d - 1, j), den, fmpz_mat_entry(res, d - 1, j)); for (i = 0; i <= d - 1; i++) fmpz_mul(fmpz_mat_entry(res, j, i), fmpz_mat_entry(res, j, i), fmpz_mat_entry(res, d - 1, j)); } } if (fmpz_equal(den, fmpz_mat_entry(res, d - 1, d - 1))) { for (i = 0; i < d; i++) fmpz_set(fmpz_mat_entry(res, d - 1, i), fmpq_poly_numref(NF_ELEM(t)) + i); } else { fmpz_divexact(fmpz_mat_entry(res, d - 1, d - 1), den, fmpq_poly_denref(NF_ELEM(t))); for (i = 0; i < d; i++) fmpz_mul(fmpz_mat_entry(res, d - 1, i), fmpq_poly_numref(NF_ELEM(t)) + i, fmpz_mat_entry(res, d - 1, d - 1)); } } } nf_elem_clear(t, nf); } }
void _fmpq_mul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den) { /* Common special cases: squaring, same denominator (e.g. both integers) */ if (((op1num == op2num) && (op1den == op2den)) || fmpz_equal(op1den, op2den)) { fmpz_mul(rnum, op1num, op2num); fmpz_mul(rden, op1den, op2den); } /* Exactly one argument is an integer */ else if (fmpz_is_one(op1den)) { fmpz_t t, x; fmpz_init(t); fmpz_init(x); fmpz_gcd(t, op1num, op2den); fmpz_divexact(x, op1num, t); fmpz_mul(rnum, x, op2num); fmpz_divexact(t, op2den, t); fmpz_mul(rden, op1den, t); fmpz_clear(t); fmpz_clear(x); } else if (fmpz_is_one(op2den)) { fmpz_t t, x; fmpz_init(t); fmpz_init(x); fmpz_gcd(t, op2num, op1den); fmpz_divexact(x, op2num, t); fmpz_mul(rnum, x, op1num); fmpz_divexact(t, op1den, t); fmpz_mul(rden, op2den, t); fmpz_clear(t); fmpz_clear(x); } else { fmpz_t t, u, x, y; fmpz_init(t); fmpz_init(u); fmpz_init(x); fmpz_init(y); fmpz_gcd(t, op1num, op2den); fmpz_gcd(u, op1den, op2num); fmpz_divexact(x, op1num, t); fmpz_divexact(y, op2num, u); fmpz_mul(rnum, x, y); fmpz_divexact(x, op1den, u); fmpz_divexact(y, op2den, t); fmpz_mul(rden, x, y); fmpz_clear(t); fmpz_clear(u); fmpz_clear(x); fmpz_clear(y); } }
void precompute_muex(fmpz **mu, long M, const long **C, const long *lenC, const fmpz *a, long n, long p, long N) { const long ve = (p == 2) ? M / 4 + 1 : M / (p * (p - 1)) + 1; fmpz_t P, pNe, pe; fmpz_t apow, f, g, h; fmpz *nu; long *v; long i, j; fmpz_init_set_ui(P, p); fmpz_init(pNe); fmpz_init(pe); fmpz_pow_ui(pNe, P, N + ve); fmpz_pow_ui(pe, P, ve); fmpz_init(apow); fmpz_init(f); fmpz_init(g); fmpz_init(h); /* Precompute $(l!)^{-1}$ */ nu = _fmpz_vec_init(M + 1); v = malloc((M + 1) * sizeof(long)); { long *D, lenD = 0, k = 0; for (i = 0; i <= n; i++) lenD += lenC[i]; D = malloc(lenD * sizeof(long)); for (i = 0; i <= n; i++) for (j = 0; j < lenC[i]; j++) D[k++] = C[i][j]; _remove_duplicates(D, &lenD); _sort(D, lenD); precompute_nu(nu, v, M, D, lenD, p, N + ve); free(D); } for (i = 0; i <= n; i++) { long m = -1, quo, idx, w; fmpz *z; /* Set apow = a[i]^{-(p-1)} mod p^N */ fmpz_invmod(apow, a + i, pNe); fmpz_powm_ui(apow, apow, p - 1, pNe); /* Run over all relevant m in [0, M]. Note that lenC[i] > 0 for all i. */ for (quo = 0; m <= M; quo++) { for (idx = 0; idx < lenC[i]; idx++) { m = quo * p + C[i][idx]; if (m > M) break; /* Note that $\mu_m$ is equal to $\sum_{k=0}^{\floor{m/p}} p^{\floor{m/p}-k}\nu_{m-pk}\nu_k$ where $\nu_i$ denotes the number with unit part nu[i] and valuation v[i]. */ w = (p == 2) ? (3 * m) / 4 - (m == 3 || m == 7) : m / p; z = mu[i] + lenC[i] * quo + idx; fmpz_zero(z); fmpz_one(h); for (j = 0; j <= m / p; j++) { fmpz_pow_ui(f, P, ve + w - j + v[m - p*j] + v[j]); fmpz_mul(g, nu + (m - p*j), nu + j); fmpz_mul(f, f, g); fmpz_mul(f, f, h); fmpz_add(z, z, f); fmpz_mod(z, z, pNe); /* Set h = a[i]^{- (j+1)(p-1)} mod p^{N+e} */ fmpz_mul(h, h, apow); fmpz_mod(h, h, pNe); } fmpz_divexact(z, z, pe); } } } fmpz_clear(P); fmpz_clear(pNe); fmpz_clear(pe); fmpz_clear(apow); fmpz_clear(f); fmpz_clear(g); fmpz_clear(h); _fmpz_vec_clear(nu, M + 1); free(v); }
void _nf_elem_sub_qf(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf, int can) { fmpz_t d; const fmpz * const bnum = QNF_ELEM_NUMREF(b); const fmpz * const bden = QNF_ELEM_DENREF(b); const fmpz * const cnum = QNF_ELEM_NUMREF(c); const fmpz * const cden = QNF_ELEM_DENREF(c); fmpz * const anum = QNF_ELEM_NUMREF(a); fmpz * const aden = QNF_ELEM_DENREF(a); fmpz_init(d); fmpz_one(d); if (fmpz_equal(bden, cden)) { fmpz_sub(anum, bnum, cnum); fmpz_sub(anum + 1, bnum + 1, cnum + 1); fmpz_sub(anum + 2, bnum + 2, cnum + 2); fmpz_set(aden, bden); if (can && !fmpz_is_one(aden)) { fmpz_gcd(d, anum, anum + 1); fmpz_gcd(d, d, anum + 2); if (!fmpz_is_one(d)) { fmpz_gcd(d, d, aden); if (!fmpz_is_one(d)) { fmpz_divexact(anum, anum, d); fmpz_divexact(anum + 1, anum + 1, d); fmpz_divexact(anum + 2, anum + 2, d); fmpz_divexact(aden, aden, d); } } } fmpz_clear(d); return; } if (!fmpz_is_one(bden) && !fmpz_is_one(cden)) fmpz_gcd(d, bden, cden); if (fmpz_is_one(d)) { fmpz_mul(anum, bnum, cden); fmpz_mul(anum + 1, bnum + 1, cden); fmpz_mul(anum + 2, bnum + 2, cden); fmpz_submul(anum, cnum, bden); fmpz_submul(anum + 1, cnum + 1, bden); fmpz_submul(anum + 2, cnum + 2, bden); fmpz_mul(aden, bden, cden); } else { fmpz_t bden1; fmpz_t cden1; fmpz_init(bden1); fmpz_init(cden1); fmpz_divexact(bden1, bden, d); fmpz_divexact(cden1, cden, d); fmpz_mul(anum, bnum, cden1); fmpz_mul(anum + 1, bnum + 1, cden1); fmpz_mul(anum + 2, bnum + 2, cden1); fmpz_submul(anum, cnum, bden1); fmpz_submul(anum + 1, cnum + 1, bden1); fmpz_submul(anum + 2, cnum + 2, bden1); if (fmpz_is_zero(anum) && fmpz_is_zero(anum + 1) && fmpz_is_zero(anum + 2)) fmpz_one(aden); else { if (can) { fmpz_t e; fmpz_init(e); fmpz_gcd(e, anum, anum + 1); fmpz_gcd(e, e, anum + 2); if (!fmpz_is_one(e)) fmpz_gcd(e, e, d); if (fmpz_is_one(e)) fmpz_mul(aden, bden, cden1); else { fmpz_divexact(anum, anum, e); fmpz_divexact(anum + 1, anum + 1, e); fmpz_divexact(anum + 2, anum + 2, e); fmpz_divexact(bden1, bden, e); fmpz_mul(aden, bden1, cden1); } fmpz_clear(e); } else fmpz_mul(aden, bden, cden1); } fmpz_clear(bden1); fmpz_clear(cden1); } fmpz_clear(d); }
void _fmpz_poly_signature(long * r1, long * r2, fmpz * poly, long len) { fmpz *A, *B, *f, *g, *h, *w; long lenA, lenB; int s, t; if (len <= 2) { *r1 = (len == 2); *r2 = 0; return; } w = _fmpz_vec_init(2 * len + 2); A = w; B = w + len; lenA = len; lenB = lenA - 1; f = w + 2 * len - 1; g = w + 2 * len; h = w + 2 * len + 1; _fmpz_poly_primitive_part(A, poly, lenA); _fmpz_poly_derivative(B, A, lenA); _fmpz_poly_primitive_part(B, B, lenB); fmpz_one(g); fmpz_one(h); s = 1; t = (lenA & 1L) ? -s : s; *r1 = 1; while (1) { long delta = lenA - lenB; int sgnA; _fmpz_poly_pseudo_rem_cohen(A, A, lenA, B, lenB); lenA = lenB; FMPZ_VEC_NORM(A, lenA); if (lenA == 0) { printf("Exception: non-squarefree polynomial detected in fmpz_poly_signature\n"); _fmpz_vec_clear(w, 2 * len + 2); abort(); } if ((fmpz_sgn(B + (lenB - 1)) > 0) || (delta & 1L)) _fmpz_vec_neg(A, A, lenA); sgnA = fmpz_sgn(A + (lenA - 1)); if (sgnA != s) { s = -s; (*r1)--; } if (sgnA != ((lenA & 1L) ? t : -t)) { t = -t; (*r1)++; } if (lenA == 1) { *r2 = ((len - 1) - *r1) / 2; _fmpz_vec_clear(w, 2 * len + 2); return; } else { { fmpz * temp = A; A = B; B = temp; } { long temp = lenA; lenA = lenB; lenB = temp; } if (delta == 1) { fmpz_mul(f, g, h); _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f); fmpz_set(g, A + (lenA - 1)); fmpz_set(h, g); } else { fmpz_pow_ui(f, h, delta); fmpz_mul(f, f, g); _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f); fmpz_pow_ui(f, h, delta - 1); fmpz_pow_ui(g, A + (lenA - 1), delta); fmpz_divexact(h, g, f); fmpz_set(g, A + (lenA - 1)); } } } }
void fmpq_poly_compose_series_horner(fmpq_poly_t res, const fmpq_poly_t poly1, const fmpq_poly_t poly2, long n) { long len1 = poly1->length; long len2 = poly2->length; long lenr; if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) { printf("exception: fmpq_poly_compose_series_horner: inner polynomial " "must have zero constant term\n"); abort(); } if (len1 == 0 || n == 0) { fmpq_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { fmpq_poly_fit_length(res, 1); fmpz_set(res->coeffs, poly1->coeffs); fmpz_set(res->den, poly1->den); { fmpz_t d; fmpz_init(d); fmpz_gcd(d, res->coeffs, res->den); if (!fmpz_is_one(d)) { fmpz_divexact(res->coeffs, res->coeffs, d); fmpz_divexact(res->den, res->den, d); } fmpz_clear(d); } _fmpq_poly_set_length(res, 1); _fmpq_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)) { fmpq_poly_fit_length(res, lenr); _fmpq_poly_compose_series_horner(res->coeffs, res->den, poly1->coeffs, poly1->den, len1, poly2->coeffs, poly2->den, len2, lenr); _fmpq_poly_set_length(res, lenr); _fmpq_poly_normalise(res); } else { fmpq_poly_t t; fmpq_poly_init2(t, lenr); _fmpq_poly_compose_series_horner(t->coeffs, t->den, poly1->coeffs, poly1->den, len1, poly2->coeffs, poly2->den, len2, lenr); _fmpq_poly_set_length(t, lenr); _fmpq_poly_normalise(t); fmpq_poly_swap(res, t); fmpq_poly_clear(t); } }
static void __ramanujan_even_common_denom(fmpz * num, fmpz * den, long start, long n) { fmpz_t t, c, d, cden; long j, k, m, mcase; int prodsize; if (start >= n) return; fmpz_init(t); fmpz_init(c); fmpz_init(d); fmpz_init(cden); /* Common denominator */ fmpz_primorial(cden, n + 1); start += start % 2; /* Convert initial values to common denominator */ for (k = 0; k < start; k += 2) { fmpz_divexact(t, cden, den + k); fmpz_mul(num + k, num + k, t); } /* Ramanujan's recursive formula */ for (m = start; m < n; m += 2) { mcase = m % 6; fmpz_mul_ui(num + m, cden, m + 3UL); fmpz_divexact_ui(num + m, num + m, 3UL); if (mcase == 4) { fmpz_neg(num + m, num + m); fmpz_divexact_ui(num + m, num + m, 2UL); } /* All factors are strictly smaller than m + 4; choose prodsize such that (m + 4)^prodsize fits in a signed long. */ { #if FLINT64 if (m < 1444L) prodsize = 6; else if (m < 2097148L) prodsize = 3; else if (m < 3037000495L) prodsize = 2; /* not very likely... */ else abort(); #else if (m < 32L) prodsize = 6; else if (m < 1286L) prodsize = 3; else if (m < 46336L) prodsize = 2; else abort(); #endif } /* c = t = binomial(m+3, m) */ fmpz_set_ui(t, m + 1UL); fmpz_mul_ui(t, t, m + 2UL); fmpz_mul_ui(t, t, m + 3UL); fmpz_divexact_ui(t, t, 6UL); fmpz_set(c, t); for (j = 6; j <= m; j += 6) { long r = m - j; /* c = binomial(m+3, m-j); */ switch (prodsize) { case 2: fmpz_mul_ui(c, c, (r+6)*(r+5)); fmpz_mul_ui(c, c, (r+4)*(r+3)); fmpz_mul_ui(c, c, (r+2)*(r+1)); fmpz_set_ui(d, (j+0)*(j+3)); fmpz_mul_ui(d, d, (j-2)*(j+2)); fmpz_mul_ui(d, d, (j-1)*(j+1)); fmpz_divexact(c, c, d); break; case 3: fmpz_mul_ui(c, c, (r+6)*(r+5)*(r+4)); fmpz_mul_ui(c, c, (r+3)*(r+2)*(r+1)); fmpz_set_ui(d, (j+0)*(j+3)*(j-2)); fmpz_mul_ui(d, d, (j+2)*(j-1)*(j+1)); fmpz_divexact(c, c, d); break; case 6: fmpz_mul_ui(c, c, (r+6)*(r+5)*(r+4)*(r+3)*(r+2)*(r+1)); fmpz_divexact_ui(c, c, (j+0)*(j+3)*(j-2)*(j+2)*(j-1)*(j+1)); break; } fmpz_submul(num + m, c, num + (m - j)); } fmpz_divexact(num + m, num + m, t); } /* Convert to separate denominators */ for (k = 0; k < n; k += 2) { bernoulli_number_denom(den + k, k); fmpz_divexact(t, cden, den + k); fmpz_divexact(num + k, num + k, t); } fmpz_clear(t); fmpz_clear(c); fmpz_clear(d); fmpz_clear(cden); }
void _fmpq_poly_scalar_div_mpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, const fmpz_t r, const fmpz_t s) { fmpz_t gcd1; /* GCD( poly, r ) */ fmpz_t gcd2; /* GCD( s, den ) */ fmpz_init(gcd1); fmpz_init(gcd2); fmpz_set_ui(gcd1, 1); fmpz_set_ui(gcd2, 1); if (*r != 1L) { _fmpz_vec_content(gcd1, poly, len); if (*gcd1 != 1L) fmpz_gcd(gcd1, gcd1, r); } if (*den != 1L && *s != 1L) fmpz_gcd(gcd2, s, den); if (*gcd1 == 1L) { if (*gcd2 == 1L) { _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s); fmpz_mul(rden, den, r); } else { fmpz_t s2; fmpz_init(s2); fmpz_divexact(s2, s, gcd2); _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s2); fmpz_divexact(rden, den, gcd2); fmpz_mul(rden, rden, r); fmpz_clear(s2); } } else { fmpz_t r2; fmpz_init(r2); fmpz_divexact(r2, r, gcd1); if (*gcd2 == 1L) { _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s); fmpz_mul(rden, den, r2); } else { fmpz_t s2; fmpz_init(s2); fmpz_divexact(s2, s, gcd2); _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s2); fmpz_divexact(rden, den, gcd2); fmpz_mul(rden, rden, r2); fmpz_clear(s2); } fmpz_clear(r2); } if (_fmpz_vec_is_zero(rpoly, len)) fmpz_set_ui(rden, 1); if (fmpz_sgn(rden) < 0) { _fmpz_vec_neg(rpoly, rpoly, len); fmpz_neg(rden, rden); } fmpz_clear(gcd1); fmpz_clear(gcd2); }
char * _padic_get_str(char * str, const padic_t op, const padic_ctx_t ctx) { const fmpz * u = padic_unit(op); const long v = padic_val(op); if (fmpz_is_zero(u)) { if (!str) { str = flint_malloc(2); } str[0] = '0'; str[1] = '\0'; return str; } if (ctx->mode == PADIC_TERSE) { if (v == 0) { str = fmpz_get_str(str, 10, u); } else if (v > 0) { fmpz_t t; fmpz_init(t); fmpz_pow_ui(t, ctx->p, v); fmpz_mul(t, t, u); str = fmpz_get_str(str, 10, t); fmpz_clear(t); } else /* v < 0 */ { fmpz_t t; fmpz_init(t); fmpz_pow_ui(t, ctx->p, -v); str = _fmpq_get_str(str, 10, u, t); fmpz_clear(t); } } else if (ctx->mode == PADIC_SERIES) { char *s; fmpz_t x; fmpz_t d; long j, N; if (fmpz_sgn(u) < 0) { printf("ERROR (_padic_get_str). u < 0 in SERIES mode.\n"); abort(); } N = fmpz_clog(u, ctx->p) + v; if (!str) { long b = (N - v) * (2 * fmpz_sizeinbase(ctx->p, 10) + z_sizeinbase(FLINT_MAX(FLINT_ABS(v), FLINT_ABS(N)), 10) + 5) + 1; str = flint_malloc(b); if (!str) { printf("ERROR (_padic_get_str). Memory allocation failed.\n"); abort(); } } s = str; fmpz_init(d); fmpz_init(x); fmpz_set(x, u); /* Unroll first step */ j = 0; { fmpz_mod(d, x, ctx->p); /* d = u mod p^{j+1} */ fmpz_sub(x, x, d); /* x = x - d */ fmpz_divexact(x, x, ctx->p); /* x = x / p */ if (!fmpz_is_zero(d)) { if (j + v != 0) { fmpz_get_str(s, 10, d); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); while (*++s != '\0') ; *s++ = '^'; sprintf(s, "%ld", j + v); while (*++s != '\0') ; } else { fmpz_get_str(s, 10, d); while (*++s != '\0') ; } } j++; } for ( ; !fmpz_is_zero(x); j++) { fmpz_mod(d, x, ctx->p); /* d = u mod p^{j+1} */ fmpz_sub(x, x, d); /* x = x - d */ fmpz_divexact(x, x, ctx->p); /* x = x / p */ if (!fmpz_is_zero(d)) { if (j + v != 0) { *s++ = ' '; *s++ = '+'; *s++ = ' '; fmpz_get_str(s, 10, d); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); while (*++s != '\0') ; *s++ = '^'; sprintf(s, "%ld", j + v); while (*++s != '\0') ; } else { *s++ = ' '; *s++ = '+'; *s++ = ' '; fmpz_get_str(s, 10, d); while (*++s != '\0') ; } } } fmpz_clear(x); fmpz_clear(d); } else /* ctx->mode == PADIC_VAL_UNIT */ { if (!str) { long b = fmpz_sizeinbase(u, 10) + fmpz_sizeinbase(ctx->p, 10) + z_sizeinbase(v, 10) + 4; str = flint_malloc(b); if (!str) { printf("ERROR (_padic_get_str). Memory allocation failed.\n"); abort(); } } if (v == 0) { str = fmpz_get_str(str, 10, u); } else if (v == 1) { char *s = str; fmpz_get_str(s, 10, u); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); } else { char *s = str; fmpz_get_str(s, 10, u); while (*++s != '\0') ; *s++ = '*'; fmpz_get_str(s, 10, ctx->p); while (*++s != '\0') ; *s++ = '^'; sprintf(s, "%ld", v); } } return str; }
void _qseive(const mp_limb_t n, const mp_limb_t B) { nmod_sparse_mat_t M; mp_limb_t quad, *quads, *xs, x, i = 0, j, piB = n_prime_pi(B); const mp_limb_t * ps = n_primes_arr_readonly(piB + 2); const double * pinvs = n_prime_inverses_arr_readonly(piB + 2); mzd_t *K; /* init */ quads = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *)); xs = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *)); K = mzd_init(piB + 1, 1); nmod_sparse_mat_init(M, piB + 1, piB + 1, 2); printf("init done\n"); printf("using %ld primes\n", piB); /* seive */ for (x = n_sqrt(n), i = 0; i <= piB; x++) { quad = x*x - n; if (quad == 0) continue; for (j = 0; j < piB; j++) n_remove2_precomp(&quad, ps[j], pinvs[j]); if (quad == 1) /* was B-smooth */ { quads[i] = x*x - n; quad = x*x - n; for (j = 0; j < piB; j++) { if (n_remove2_precomp(&quad, ps[j], pinvs[j]) % 2) _nmod_sparse_mat_set_entry(M, j, i, M->row_supports[j], 1); } xs[i] = x; i++; } } printf("data collection done\n"); n_cleanup_primes(); _bw(K, M, 1, 2, 7, 7); printf("procesing complete\n"); mzd_print(K); int done = 0; for (j = 0; !done; j++) { fmpz_t a, b, diff, N; fmpz_init_set_ui(a, 1); fmpz_init_set_ui(b, 1); fmpz_init_set_ui(N, n); fmpz_init(diff); for (i = 0; i < piB; i++) { if (mzd_read_bit(K, i, j)) { fmpz_mul_ui(a, a, xs[i]); fmpz_mul_ui(b, b, quads[i]); } } assert(fmpz_is_square(b)); fmpz_sqrt(b, b); if (fmpz_mod_ui(a, a, n) != fmpz_mod_ui(b, b, n) && fmpz_mod_ui(a, a, n) != n - fmpz_mod_ui(b, b, n)) { done = 1; fmpz_print(a); printf("\n"); fmpz_print(b); printf("\n"); fmpz_sub(diff, a, b); fmpz_gcd(a, diff, N); fmpz_divexact(b, N, a); fmpz_print(a); printf("\n"); fmpz_print(b); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(N); fmpz_clear(diff); } /* cleanup */ free(quads); free(xs); mzd_free(K); nmod_sparse_mat_clear(M); return; }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("divrem_f...."); fflush(stdout); /* Check q*b + r = a when gcd(lead(B),p) = 1, no aliasing */ for (i = 0; i < 5000; i++) { fmpz_t f, p; fmpz_mod_poly_t a, b, q, r, t; fmpz_init(f); fmpz_init(p); fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); fmpz_add_ui(p, p, 2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_init(b, p); fmpz_mod_poly_init(q, p); fmpz_mod_poly_init(r, p); fmpz_mod_poly_init(t, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); { fmpz_t d; fmpz *leadB = fmpz_mod_poly_lead(b); fmpz_init(d); fmpz_gcd(d, p, leadB); while (!fmpz_is_one(d)) { fmpz_divexact(leadB, leadB, d); fmpz_gcd(d, p, leadB); } fmpz_clear(d); } fmpz_mod_poly_divrem_f(f, q, r, a, b); fmpz_mod_poly_mul(t, q, b); fmpz_mod_poly_add(t, t, r); result = (fmpz_is_one(f) && fmpz_mod_poly_equal(a, t)); if (!result) { flint_printf("FAIL (divrem):\n"); flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); flint_printf("f = "), fmpz_print(f), flint_printf("\n\n"); flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_mod_poly_clear(b); fmpz_mod_poly_clear(q); fmpz_mod_poly_clear(r); fmpz_mod_poly_clear(t); fmpz_clear(f); fmpz_clear(p); } /* Check f | p when gcd(lead(B),p) > 1 */ for (i = 0; i < 5000; i++) { fmpz_t f, p, q1, q2; fmpz_mod_poly_t a, b, q, r, t; fmpz_init(f); fmpz_init(p); fmpz_init(q1); fmpz_init(q2); fmpz_randtest_unsigned(q1, state, 2 * FLINT_BITS); fmpz_randtest_unsigned(q2, state, 2 * FLINT_BITS); fmpz_add_ui(q1, q1, 2); fmpz_add_ui(q2, q2, 2); fmpz_mul(p, q1, q2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_init(b, p); fmpz_mod_poly_init(q, p); fmpz_mod_poly_init(r, p); fmpz_mod_poly_init(t, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); { fmpz_t d; fmpz *leadB = fmpz_mod_poly_lead(b); fmpz_init(d); fmpz_gcd(d, p, leadB); if (fmpz_is_one(d)) fmpz_set(leadB, q1); fmpz_clear(d); } fmpz_mod_poly_divrem_f(f, q, r, a, b); fmpz_mod_poly_mul(t, q, b); fmpz_mod_poly_add(t, t, r); result = (fmpz_cmp_ui(f, 1) > 0 && fmpz_cmp(f, p) < 0 && fmpz_divisible(p, f)); if (!result) { flint_printf("FAIL (factor):\n"); flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); flint_printf("f = "), fmpz_print(f), flint_printf("\n\n"); flint_printf("q1 = "), fmpz_print(q1), flint_printf("\n\n"); flint_printf("q2 = "), fmpz_print(q2), flint_printf("\n\n"); flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_mod_poly_clear(b); fmpz_mod_poly_clear(q); fmpz_mod_poly_clear(r); fmpz_mod_poly_clear(t); fmpz_clear(f); fmpz_clear(p); fmpz_clear(q1); fmpz_clear(q2); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
void _fmpq_poly_interpolate_fmpz_vec(fmpz * poly, fmpz_t den, const fmpz * xs, const fmpz * ys, long n) { fmpz *P, *Q, *w; fmpz_t t; long i, j; /* Constant */ if (n == 1) { fmpz_set(poly, ys); fmpz_one(den); return; } /* Linear */ if (n == 2) { fmpz_sub(den, xs, xs + 1); fmpz_sub(poly + 1, ys, ys + 1); fmpz_mul(poly, xs, ys + 1); fmpz_submul(poly, xs + 1, ys); return; } fmpz_init(t); P = _fmpz_vec_init(n + 1); Q = _fmpz_vec_init(n); w = _fmpz_vec_init(n); /* P = (x-x[0])*(x-x[1])*...*(x-x[n-1]) */ _fmpz_poly_product_roots_fmpz_vec(P, xs, n); /* Weights */ for (i = 0; i < n; i++) { fmpz_one(w + i); for (j = 0; j < n; j++) { if (i != j) { fmpz_sub(t, xs + i, xs + j); fmpz_mul(w + i, w + i, t); } } } _fmpz_vec_zero(poly, n); _fmpz_vec_lcm(den, w, n); for (i = 0; i < n; i++) { /* Q = P / (x - x[i]) */ _fmpz_poly_div_root(Q, P, n + 1, xs + i); /* result += Q * weight(i) */ fmpz_divexact(t, den, w + i); fmpz_mul(t, t, ys + i); _fmpz_vec_scalar_addmul_fmpz(poly, Q, n, t); } _fmpz_vec_clear(P, n + 1); _fmpz_vec_clear(Q, n); _fmpz_vec_clear(w, n); fmpz_clear(t); }