void _fmpz_poly_revert_series_lagrange(fmpz * Qinv, const fmpz * Q, slong n) { slong i; fmpz *R, *S, *T, *tmp; if (n <= 2) { _fmpz_vec_set(Qinv, Q, n); return; } R = _fmpz_vec_init(n - 1); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); fmpz_zero(Qinv); fmpz_set(Qinv + 1, Q + 1); _fmpz_poly_inv_series(R, Q + 1, n - 1); _fmpz_vec_set(S, R, n - 1); for (i = 2; i < n; i++) { _fmpz_poly_mullow(T, S, n - 1, R, n - 1, n - 1); fmpz_divexact_ui(Qinv + i, T + i - 1, i); tmp = S; S = T; T = tmp; } _fmpz_vec_clear(R, n - 1); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); }
int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, const fmpz_mat_t A, const fmpz_mat_t B) { long i, dim = fmpz_mat_nrows(A); if (dim == 0) { fmpz_one(den); return 1; } else if (dim == 1) { fmpz_set(den, fmpz_mat_entry(A, 0, 0)); if (fmpz_is_zero(den)) return 0; if (!fmpz_mat_is_empty(B)) _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B)); return 1; } else if (dim == 2) { fmpz_t t, u; _fmpz_mat_det_cofactor_2x2(den, A->rows); if (fmpz_is_zero(den)) return 0; fmpz_init(t); fmpz_init(u); for (i = 0; i < fmpz_mat_ncols(B); i++) { fmpz_mul (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i)); fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i)); fmpz_mul (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i)); fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i)); fmpz_swap(fmpz_mat_entry(X, 0, i), t); fmpz_swap(fmpz_mat_entry(X, 1, i), u); } fmpz_clear(t); fmpz_clear(u); return 1; } else if (dim == 3) { return _fmpz_mat_solve_cramer_3x3(X, den, A, B); } else { printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented"); abort(); } }
void fmpq_poly_get_slice(fmpq_poly_t rop, const fmpq_poly_t op, long i, long j) { i = FLINT_MAX(i, 0); j = FLINT_MIN(j, op->length); if (i < j) { long k; if (rop == op) { for (k = 0; k < i; k++) fmpz_zero(rop->coeffs + k); for (k = j; k < rop->length; k++) fmpz_zero(rop->coeffs + k); fmpq_poly_canonicalise(rop); } else { fmpq_poly_fit_length(rop, j); _fmpq_poly_set_length(rop, j); _fmpz_vec_set(rop->coeffs + i, op->coeffs + i, j - i); fmpz_set(rop->den, op->den); fmpq_poly_canonicalise(rop); } } else { fmpq_poly_zero(rop); } }
void _fmpz_mod_poly_radix(fmpz **B, const fmpz *F, fmpz **Rpow, fmpz **Rinv, long degR, long k, long i, fmpz *W, const fmpz_t p) { if (i == -1) { _fmpz_vec_set(B[k], F, degR); } else { const long lenQ = (1L << i) * degR; fmpz *Frev = W; fmpz *Q = W + lenQ; fmpz *S = W; _fmpz_poly_reverse(Frev, F + lenQ, lenQ, lenQ); _fmpz_mod_poly_mullow(Q, Frev, lenQ, Rinv[i], lenQ, p, lenQ); _fmpz_poly_reverse(Q, Q, lenQ, lenQ); _fmpz_mod_poly_radix(B, Q, Rpow, Rinv, degR, k + (1L << i), i-1, W, p); _fmpz_mod_poly_mullow(S, Rpow[i], lenQ, Q, lenQ, p, lenQ); _fmpz_mod_poly_sub(S, F, lenQ, S, lenQ, p); _fmpz_mod_poly_radix(B, S, Rpow, Rinv, degR, k, i-1, W + lenQ, p); } }
static void _fmpz_poly_compose_pow(fmpz *rop, const fmpz *op, long len, long k) { if (k == 1) { if (rop != op) { _fmpz_vec_set(rop, op, len); } } else if (len == 1) { fmpz_set(rop, op); } else { long i, j, h; for (i = len - 1, j = (len - 1) * k ; i >= 0; i--, j -= k) { fmpz_set(rop + j, op + i); if (i != 0) for (h = 1; h < k; h++) fmpz_zero(rop + (j - h)); } } }
int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op, const padic_ctx_t ctx) { const slong len = op->length; if (op->val < 0) { return 0; } if (padic_poly_is_zero(op)) { fmpz_poly_zero(rop); return 1; } fmpz_poly_fit_length(rop, len); _fmpz_poly_set_length(rop, len); if (op->val == 0) { _fmpz_vec_set(rop->coeffs, op->coeffs, len); } else /* op->val > 0 */ { fmpz_t pow; fmpz_init(pow); fmpz_pow_ui(pow, ctx->p, op->val); _fmpz_vec_scalar_mul_fmpz(rop->coeffs, op->coeffs, len, pow); fmpz_clear(pow); } return 1; }
void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, ulong c) { if (c == 1UL) { if (rpoly != poly) _fmpz_vec_set(rpoly, poly, len); fmpz_set(rden, den); } else { fmpz_t d, fc; ulong ud; fmpz_init(d); fmpz_init(fc); _fmpz_vec_content(d, poly, len); fmpz_set_ui(fc, c); fmpz_gcd(d, d, fc); ud = fmpz_get_ui(d); /* gcd of d and c fits into a ulong */ _fmpz_vec_scalar_divexact_ui(rpoly, poly, len, ud); fmpz_mul_ui(rden, den, c / ud); fmpz_clear(d); fmpz_clear(fc); } }
void _fmpz_poly_pseudo_divrem_cohen(fmpz * Q, fmpz * R, const fmpz * A, long lenA, const fmpz * B, long lenB) { const fmpz * leadB = B + (lenB - 1); long e, lenQ; fmpz_t pow; if (lenB == 1) { fmpz_init(pow); fmpz_pow_ui(pow, leadB, lenA - 1); _fmpz_vec_scalar_mul_fmpz(Q, A, lenA, pow); _fmpz_vec_zero(R, lenA); fmpz_clear(pow); return; } lenQ = lenA - lenB + 1; _fmpz_vec_zero(Q, lenQ); if (R != A) _fmpz_vec_set(R, A, lenA); e = lenA - lenB; /* Unroll the first run of the while loop */ { fmpz_set(Q + (lenQ - 1), R + (lenA - 1)); _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB); _fmpz_vec_scalar_submul_fmpz(R + (lenA - lenB), B, lenB - 1, R + (lenA - 1)); fmpz_zero(R + (lenA - 1)); for (lenA -= 2; (lenA >= 0) && (R[lenA] == 0L); lenA--) ; lenA++; } while (lenA >= lenB) { _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, leadB); fmpz_add(Q + (lenA - lenB), Q + (lenA - lenB), R + (lenA - 1)); _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB); _fmpz_vec_scalar_submul_fmpz(R + lenA - lenB, B, lenB - 1, R + (lenA - 1)); fmpz_zero(R + (lenA - 1)); for (lenA -= 2; (lenA >= 0) && (R[lenA] == 0L); lenA--) ; lenA++; e--; } fmpz_init(pow); fmpz_pow_ui(pow, leadB, e); _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, pow); _fmpz_vec_scalar_mul_fmpz(R, R, lenA, pow); fmpz_clear(pow); }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("scalar_submul_si_2exp...."); fflush(stdout); /* Compare with alternative method of computation */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpz *a, *b, *c, *d; slong len = n_randint(state, 100), x; mp_bitcnt_t exp; a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); c = _fmpz_vec_init(len); d = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_randtest(b, state, len, 200); _fmpz_vec_set(c, b, len); x = z_randtest(state); exp = n_randint(state, 200); _fmpz_vec_scalar_submul_si_2exp(b, a, len, x, exp); _fmpz_vec_scalar_mul_2exp(d, a, len, exp); _fmpz_vec_scalar_submul_si(c, d, len, x); result = (_fmpz_vec_equal(b, c, len)); if (!result) { flint_printf("FAIL:\n"); flint_printf("x = %wd, exp = %wu\n", x, exp); _fmpz_vec_print(b, len), flint_printf("\n\n"); _fmpz_vec_print(c, len), flint_printf("\n\n"); abort(); } _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); _fmpz_vec_clear(c, len); _fmpz_vec_clear(d, len); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
/* Applies the operator $\sigma^e$ to all elements in the matrix \code{op}, setting the corresponding elements in \code{rop} to the results. */ static void fmpz_poly_mat_frobenius(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, long e, const fmpz_t p, long N, const qadic_ctx_t ctx) { const long d = qadic_ctx_degree(ctx); e = e % d; if (e < 0) e += d; if (e == 0) { fmpz_t pN; fmpz_init(pN); fmpz_pow_ui(pN, p, N); fmpz_poly_mat_scalar_mod_fmpz(B, A, pN); fmpz_clear(pN); } else { long i, j; fmpz *t = _fmpz_vec_init(2 * d - 1); for (i = 0; i < B->r; i++) for (j = 0; j < B->c; j++) { const fmpz_poly_struct *a = fmpz_poly_mat_entry(A, i, j); fmpz_poly_struct *b = fmpz_poly_mat_entry(B, i, j); if (a->length == 0) { fmpz_poly_zero(b); } else { _qadic_frobenius(t, a->coeffs, a->length, e, ctx->a, ctx->j, ctx->len, p, N); fmpz_poly_fit_length(b, d); _fmpz_vec_set(b->coeffs, t, d); _fmpz_poly_set_length(b, d); _fmpz_poly_normalise(b); } } _fmpz_vec_clear(t, 2 * d - 1); } }
void _fmpz_poly_divrem_divconquer(fmpz *Q, fmpz *R, const fmpz *A, long lenA, const fmpz *B, long lenB) { if (lenA <= 2 * lenB - 1) { __fmpz_poly_divrem_divconquer(Q, R, A, lenA, B, lenB); } else /* lenA > 2 * lenB - 1 */ { fmpz *S, *T; S = _fmpz_vec_init(2 * lenA + 2 * (2 * lenB - 1)); T = S + lenA; _fmpz_vec_set(S, A, lenA); __fmpz_poly_divrem_divconquer(Q, T, S, lenA, B, lenB); _fmpz_vec_set(R, T, lenA); _fmpz_vec_clear(S, 2 * lenA + 2 * (2 * lenB - 1)); } }
void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, long c) { if (c == 1) { if (rpoly != poly) { _fmpz_vec_set(rpoly, poly, len); fmpz_set(rden, den); } } else if (c == -1) { _fmpz_vec_neg(rpoly, poly, len); fmpz_set(rden, den); } else { fmpz_t d, f; fmpz_init(d); fmpz_init(f); fmpz_set_si(f, c); _fmpz_vec_content(d, poly, len); fmpz_gcd(d, d, f); if (c > 0) { _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); fmpz_mul_si(rden, den, c / fmpz_get_si(d)); } else { ulong q = (- (ulong) c) / fmpz_get_ui(d); fmpz_neg(d, d); _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); fmpz_mul_ui(rden, den, q); } fmpz_clear(d); fmpz_clear(f); } }
slong renf_set_embeddings_fmpz_poly(renf * nf, fmpz_poly_t pol, slong lim, slong prec) { slong i, n, n_exact, n_interval; fmpq_poly_t p2; arb_t a; fmpz * c; slong * k; n = fmpz_poly_num_real_roots_upper_bound(pol); c = _fmpz_vec_init(n); k = (slong *) flint_malloc(n * sizeof(slong)); fmpz_poly_isolate_real_roots(NULL, &n_exact, c, k, &n_interval, pol); if (n_exact) { fprintf(stderr, "ERROR (fmpz_poly_real_embeddings): rational roots\n"); abort(); } arb_init(a); fmpq_poly_init(p2); fmpz_one(fmpq_poly_denref(p2)); fmpq_poly_fit_length(p2, pol->length); _fmpz_vec_set(p2->coeffs, pol->coeffs, pol->length); p2->length = pol->length; for (i = 0; i < FLINT_MIN(lim, n_interval); i++) { arb_set_fmpz(a, c + i); arb_mul_2exp_si(a, a, 1); arb_add_si(a, a, 1, prec); mag_one(arb_radref(a)); arb_mul_2exp_si(a, a, k[i] - 1); renf_init(nf + i, p2, a, prec); } arb_clear(a); fmpq_poly_clear(p2); _fmpz_vec_clear(c, n); flint_free(k); return n_interval; }
void _fmpz_poly_revert_series_newton(fmpz * Qinv, const fmpz * Q, long n) { if (n <= 2) { _fmpz_vec_set(Qinv, Q, n); return; } else { long *a, i, k; fmpz *T, *U, *V; T = _fmpz_vec_init(n); U = _fmpz_vec_init(n); V = _fmpz_vec_init(n); k = n; for (i = 1; (1L << i) < k; i++); a = (long *) flint_malloc(i * sizeof(long)); a[i = 0] = k; while (k >= FLINT_REVERSE_NEWTON_CUTOFF) a[++i] = (k = (k + 1) / 2); _fmpz_poly_revert_series_lagrange(Qinv, Q, k); _fmpz_vec_zero(Qinv + k, n - k); for (i--; i >= 0; i--) { k = a[i]; _fmpz_poly_compose_series(T, Q, k, Qinv, k, k); _fmpz_poly_derivative(U, T, k); fmpz_zero(U + k - 1); fmpz_zero(T + 1); _fmpz_poly_div_series(V, T, U, k); _fmpz_poly_derivative(T, Qinv, k); _fmpz_poly_mullow(U, V, k, T, k, k); _fmpz_vec_sub(Qinv, Qinv, U, k); } flint_free(a); _fmpz_vec_clear(T, n); _fmpz_vec_clear(U, n); _fmpz_vec_clear(V, n); } }
void _fmpz_mod_poly_radix_init(fmpz **Rpow, fmpz **Rinv, const fmpz *R, long lenR, long k, const fmpz_t invL, const fmpz_t p) { const long degR = lenR - 1; long i; fmpz_t invLP; fmpz *W; fmpz_init_set(invLP, invL); W = flint_malloc((1L << (k - 1)) * degR * sizeof(fmpz)); _fmpz_vec_set(Rpow[0], R, lenR); for (i = 1; i < k; i++) { _fmpz_mod_poly_sqr(Rpow[i], Rpow[i - 1], degR * (1L << (i - 1)) + 1, p); } for (i = 0; i < k; i++) { const long lenQ = (1L << i) * degR; long j; /* W := rev{Rpow[i], lenQ} */ for (j = 0; j < lenQ; j++) { W[j] = Rpow[i][lenQ - j]; } _fmpz_mod_poly_inv_series_newton(Rinv[i], W, lenQ, invLP, p); /* invLP := inv{lead{R^{2^i}}} */ if (i != k - 1) { fmpz_mul(invLP, invLP, invLP); fmpz_mod(invLP, invLP, p); } } fmpz_clear(invLP); flint_free(W); }
void fmpq_poly_log_series(fmpq_poly_t res, const fmpq_poly_t f, long n) { fmpz * f_coeffs; long flen = f->length; if (flen < 1 || !fmpz_equal(f->coeffs, f->den)) { printf("Exception: fmpq_poly_log_series: constant term != 1\n"); abort(); } if (flen == 1 || n < 2) { fmpq_poly_zero(res); return; } fmpq_poly_fit_length(res, n); if (flen < n) { f_coeffs = _fmpz_vec_init(n); _fmpz_vec_set(f_coeffs, f->coeffs, flen); } else { f_coeffs = f->coeffs; } _fmpq_poly_log_series(res->coeffs, res->den, f_coeffs, f->den, n); if (flen < n) { _fmpz_vec_clear(f_coeffs, n); } _fmpq_poly_set_length(res, n); _fmpq_poly_normalise(res); }
void _fmpz_mod_poly_div_basecase(fmpz *Q, fmpz *R, const fmpz *A, long lenA, const fmpz *B, long lenB, const fmpz_t invB, const fmpz_t p) { const long alloc = (R == NULL) ? lenA : 0; long lenR = lenB - 1, iQ; if (alloc) R = _fmpz_vec_init(alloc); if (R != A) _fmpz_vec_set(R + lenR, A + lenR, lenA - lenR); for (iQ = lenA - lenB; iQ >= 0; iQ--) { if (fmpz_is_zero(R + lenA - 1)) { fmpz_zero(Q + iQ); } else { fmpz_mul(Q + iQ, R + lenA - 1, invB); fmpz_mod(Q + iQ, Q + iQ, p); _fmpz_vec_scalar_submul_fmpz(R + lenA - lenR - 1, B, lenR, Q + iQ); _fmpz_vec_scalar_mod_fmpz(R + lenA - lenR - 1, R + lenA - lenR - 1, lenR, p); } if (lenR - 1 >= iQ) { B++; lenR--; } lenA--; } if (alloc) _fmpz_vec_clear(R, alloc); }
void _fmpz_poly_pseudo_divrem_basecase(fmpz * Q, fmpz * R, ulong * d, const fmpz * A, long lenA, const fmpz * B, long lenB) { const fmpz * leadB = B + (lenB - 1); long iQ = lenA - lenB, iR = lenA - 1; fmpz_t rem; fmpz_init(rem); *d = 0; _fmpz_vec_zero(Q, lenA - lenB + 1); if (R != A) _fmpz_vec_set(R, A, lenA); while (iR >= lenB - 1) { fmpz_fdiv_qr(Q + iQ, rem, R + iR, leadB); if (!fmpz_is_zero(rem)) { _fmpz_vec_scalar_mul_fmpz(Q, Q, lenA - lenB + 1, leadB); fmpz_set(Q + iQ, R + iR); _fmpz_vec_scalar_mul_fmpz(R, R, lenA, leadB); (*d)++; } if (lenB > 1) _fmpz_vec_scalar_submul_fmpz(R + (iR - lenB + 1), B, lenB - 1, Q + iQ); fmpz_zero(R + iR); iR--; iQ--; } fmpz_clear(rem); }
void _fmpz_poly_compose_divconquer(fmpz * res, const fmpz * poly1, long len1, const fmpz * poly2, long len2) { long i, j, k, n; long *hlen, alloc, powlen; fmpz *v, **h, *pow, *temp; if (len1 == 1) { fmpz_set(res, poly1); return; } if (len2 == 1) { _fmpz_poly_evaluate_fmpz(res, poly1, len1, poly2); return; } if (len1 == 2) { _fmpz_poly_compose_horner(res, poly1, len1, poly2, len2); return; } /* Initialisation */ hlen = (long *) malloc(((len1 + 1) / 2) * sizeof(long)); for (k = 1; (2 << k) < len1; k++) ; hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1; for (i = k - 1; i > 0; i--) { long hi = (len1 + (1 << i) - 1) / (1 << i); for (n = (hi + 1) / 2; n < hi; n++) hlen[n] = ((1 << i) - 1) * (len2 - 1) + 1; } powlen = (1 << k) * (len2 - 1) + 1; alloc = 0; for (i = 0; i < (len1 + 1) / 2; i++) alloc += hlen[i]; v = _fmpz_vec_init(alloc + 2 * powlen); h = (fmpz **) malloc(((len1 + 1) / 2) * sizeof(fmpz *)); h[0] = v; for (i = 0; i < (len1 - 1) / 2; i++) { h[i + 1] = h[i] + hlen[i]; hlen[i] = 0; } hlen[(len1 - 1) / 2] = 0; pow = v + alloc; temp = pow + powlen; /* Let's start the actual work */ for (i = 0, j = 0; i < len1 / 2; i++, j += 2) { if (poly1[j + 1] != 0L) { _fmpz_vec_scalar_mul_fmpz(h[i], poly2, len2, poly1 + j + 1); fmpz_add(h[i], h[i], poly1 + j); hlen[i] = len2; } else if (poly1[j] != 0L) { fmpz_set(h[i], poly1 + j); hlen[i] = 1; } } if ((len1 & 1L)) { if (poly1[j] != 0L) { fmpz_set(h[i], poly1 + j); hlen[i] = 1; } } _fmpz_poly_mul(pow, poly2, len2, poly2, len2); powlen = 2 * len2 - 1; for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) { if (hlen[1] > 0) { long templen = powlen + hlen[1] - 1; _fmpz_poly_mul(temp, pow, powlen, h[1], hlen[1]); _fmpz_poly_add(h[0], temp, templen, h[0], hlen[0]); hlen[0] = FLINT_MAX(hlen[0], templen); } for (i = 1; i < n / 2; i++) { if (hlen[2*i + 1] > 0) { _fmpz_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1]); hlen[i] = hlen[2*i + 1] + powlen - 1; } else hlen[i] = 0; _fmpz_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i]); hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]); } if ((n & 1L)) { _fmpz_vec_set(h[i], h[2*i], hlen[2*i]); hlen[i] = hlen[2*i]; } _fmpz_poly_mul(temp, pow, powlen, pow, powlen); powlen += powlen - 1; { fmpz * t = pow; pow = temp; temp = t; } } _fmpz_poly_mul(res, pow, powlen, h[1], hlen[1]); _fmpz_vec_add(res, res, h[0], hlen[0]); _fmpz_vec_clear(v, alloc + 2 * powlen); free(h); free(hlen); }
void _fmpq_poly_revert_series_lagrange_fast(fmpz * Qinv, fmpz_t den, const fmpz * Q, const fmpz_t Qden, slong n) { slong i, j, k, m; fmpz *R, *Rden, *S, *T, *dens, *tmp; fmpz_t Sden, Tden, t; if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) { _fmpz_poly_revert_series(Qinv, Q, n); fmpz_one(den); return; } if (n <= 2) { fmpz_zero(Qinv); if (n == 2) { fmpz_set(Qinv + 1, Qden); fmpz_set(den, Q + 1); _fmpq_poly_canonicalise(Qinv, den, 2); } return; } m = n_sqrt(n); fmpz_init(t); dens = _fmpz_vec_init(n); R = _fmpz_vec_init((n - 1) * m); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); Rden = _fmpz_vec_init(m); fmpz_init(Sden); fmpz_init(Tden); fmpz_zero(Qinv); fmpz_one(dens); _fmpq_poly_inv_series(Ri(1), Rdeni(1), Q + 1, Qden, n - 1); _fmpq_poly_canonicalise(Ri(1), Rdeni(1), n - 1); for (i = 2; i <= m; i++) { _fmpq_poly_mullow(Ri(i), Rdeni(i), Ri(i-1), Rdeni(i-1), n - 1, Ri(1), Rdeni(1), n - 1, n - 1); _fmpq_poly_canonicalise(Ri(i), Rdeni(i), n - 1); } for (i = 1; i < m; i++) { fmpz_set(Qinv + i, Ri(i) + i - 1); fmpz_mul_ui(dens + i, Rdeni(i), i); } _fmpz_vec_set(S, Ri(m), n - 1); fmpz_set(Sden, Rdeni(m)); for (i = m; i < n; i += m) { fmpz_set(Qinv + i, S + i - 1); fmpz_mul_ui(dens + i, Sden, i); for (j = 1; j < m && i + j < n; j++) { fmpz_mul(t, S + 0, Ri(j) + i + j - 1); for (k = 1; k <= i + j - 1; k++) fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k); fmpz_set(Qinv + i + j, t); fmpz_mul(dens + i + j, Sden, Rdeni(j)); fmpz_mul_ui(dens + i + j, dens + i + j, i + j); } if (i + 1 < n) { _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, Ri(m), Rdeni(m), n - 1, n - 1); _fmpq_poly_canonicalise(T, Tden, n - 1); fmpz_swap(Tden, Sden); tmp = S; S = T; T = tmp; } } _set_vec(Qinv, den, Qinv, dens, n); _fmpq_poly_canonicalise(Qinv, den, n); fmpz_clear(t); _fmpz_vec_clear(dens, n); _fmpz_vec_clear(R, (n - 1) * m); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); _fmpz_vec_clear(Rden, m); fmpz_clear(Sden); fmpz_clear(Tden); }
void _fmpq_poly_revert_series_lagrange(fmpz * Qinv, fmpz_t den, const fmpz * Q, const fmpz_t Qden, long n) { long i; fmpz *R, *S, *T, *dens, *tmp; fmpz_t Rden, Sden, Tden; if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) { _fmpz_poly_revert_series(Qinv, Q, n); fmpz_one(den); } else if (n <= 2) { fmpz_zero(Qinv); if (n == 2) { fmpz_set(Qinv + 1, Qden); fmpz_set(den, Q + 1); _fmpq_poly_canonicalise(Qinv, den, 2); } } else { dens = _fmpz_vec_init(n); R = _fmpz_vec_init(n - 1); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); fmpz_init(Rden); fmpz_init(Sden); fmpz_init(Tden); fmpz_zero(Qinv); fmpz_one(dens); fmpz_set(Qinv + 1, Qden); fmpz_set(dens + 1, Q + 1); _fmpq_poly_inv_series(R, Rden, Q + 1, Qden, n - 1); _fmpq_poly_canonicalise(R, Rden, n - 1); _fmpz_vec_set(S, R, n - 1); fmpz_set(Sden, Rden); for (i = 2; i < n; i++) { _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, R, Rden, n - 1, n - 1); _fmpq_poly_canonicalise(T, Tden, n - 1); fmpz_set(Qinv + i, T + i - 1); fmpz_mul_ui(dens + i, Tden, i); tmp = S; S = T; T = tmp; fmpz_swap(Sden, Tden); } _set_vec(Qinv, den, Qinv, dens, n); _fmpq_poly_canonicalise(Qinv, den, n); _fmpz_vec_clear(R, n - 1); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); _fmpz_vec_clear(dens, n); fmpz_clear(Rden); fmpz_clear(Sden); fmpz_clear(Tden); } }
int fmpq_poly_check_unique_real_root(const fmpq_poly_t pol, const arb_t a, slong prec) { if (pol->length < 2) return 0; else if (pol->length == 2) { /* linear polynomial */ fmpq_t root; int ans; fmpq_init(root); fmpq_set_fmpz_frac(root, fmpq_poly_numref(pol), fmpq_poly_numref(pol) + 1); fmpq_neg(root, root); ans = arb_contains_fmpq(a, root); fmpq_clear(root); return ans; } else { arb_t b, c; arf_t l, r; fmpz * der; int lsign, rsign; fmpz_poly_t pol2; slong n; /* 1 - cheap test: */ /* - sign(left) * sign(right) = -1 */ /* - no zero of the derivative */ arb_init(b); arb_init(c); arf_init(l); arf_init(r); arb_get_interval_arf(l, r, a, prec); arb_set_arf(b, l); _fmpz_poly_evaluate_arb(c, pol->coeffs, pol->length, b, 2*prec); lsign = arb_sgn2(c); arb_set_arf(b, r); _fmpz_poly_evaluate_arb(c, pol->coeffs, pol->length, b, 2*prec); rsign = arb_sgn2(c); arb_clear(c); if (lsign * rsign == -1) { der = _fmpz_vec_init(pol->length - 1); _fmpz_poly_derivative(der, pol->coeffs, pol->length); _fmpz_poly_evaluate_arb(b, der, pol->length - 1, a, prec); _fmpz_vec_clear(der, pol->length - 1); if (!arb_contains_zero(b)) { arf_clear(l); arf_clear(r); arb_clear(b); return 1; } } else return 0; arb_clear(b); /* 2 - expensive testing */ fmpq_t ql, qr; fmpq_init(ql); fmpq_init(qr); arf_get_fmpq(ql, l); arf_get_fmpq(qr, r); fmpz_poly_init(pol2); fmpz_poly_fit_length(pol2, pol->length); _fmpz_vec_set(pol2->coeffs, pol->coeffs, pol->length); pol2->length = pol->length; _fmpz_poly_scale_0_1_fmpq(pol2->coeffs, pol2->length, ql, qr); n = fmpz_poly_num_real_roots_0_1(pol2); fmpz_poly_clear(pol2); fmpq_clear(ql); fmpq_clear(qr); return (n == 1); } }
int _fmpz_poly_sqrt_classical(fmpz * res, const fmpz * poly, long len) { long i, m; int result; /* the degree must be even */ if (len % 2 == 0) return 0; /* valuation must be even, and then can be reduced to 0 */ while (fmpz_is_zero(poly)) { if (!fmpz_is_zero(poly + 1)) return 0; fmpz_zero(res); poly += 2; len -= 2; res++; } /* check whether a square root exists modulo 2 */ for (i = 1; i < len; i += 2) if (!fmpz_is_even(poly + i)) return 0; /* check endpoints */ if (!fmpz_is_square(poly) || (len > 1 && !fmpz_is_square(poly + len - 1))) return 0; /* square root of leading coefficient */ m = (len + 1) / 2; fmpz_sqrt(res + m - 1, poly + len - 1); result = 1; /* do long divison style 'square root with remainder' from top to bottom */ if (len > 1) { fmpz_t t, u; fmpz * r; fmpz_init(t); fmpz_init(u); r = _fmpz_vec_init(len); _fmpz_vec_set(r, poly, len); fmpz_mul_ui(u, res + m - 1, 2); for (i = 1; i < m; i++) { fmpz_fdiv_qr(res + m - i - 1, t, r + len - i - 1, u); if (!fmpz_is_zero(t)) { result = 0; break; } fmpz_mul_si(t, res + m - i - 1, -2); _fmpz_vec_scalar_addmul_fmpz(r + len - 2*i, res + m - i, i - 1, t); fmpz_submul(r + len - 2*i - 1, res + m - i - 1, res + m - i - 1); } for (i = m; i < len && result; i++) if (!fmpz_is_zero(r + len - 1 - i)) result = 0; _fmpz_vec_clear(r, len); fmpz_clear(t); fmpz_clear(u); } return result; }
static void _qadic_exp_bsplit_series(fmpz *P, fmpz_t Q, fmpz *T, const fmpz *x, slong len, slong lo, slong hi, const fmpz *a, const slong *j, slong lena) { const slong d = j[lena - 1]; if (hi - lo == 1) { _fmpz_vec_set(P, x, len); _fmpz_vec_zero(P + len, 2*d - 1 - len); fmpz_set_si(Q, lo); _fmpz_vec_set(T, P, 2*d - 1); } else if (hi - lo == 2) { _fmpz_poly_sqr(P, x, len); _fmpz_vec_zero(P + (2*len - 1), d - (2*len - 1)); _fmpz_poly_reduce(P, 2*len - 1, a, j, lena); fmpz_set_si(Q, lo); fmpz_mul_si(Q, Q, lo + 1); _fmpz_vec_scalar_mul_si(T, x, len, lo + 1); _fmpz_vec_zero(T + len, d - len); _fmpz_vec_add(T, T, P, d); } else { const slong m = (lo + hi) / 2; fmpz *PR, *TR, *W; fmpz_t QR; PR = _fmpz_vec_init(2*d - 1); TR = _fmpz_vec_init(2*d - 1); W = _fmpz_vec_init(2*d - 1); fmpz_init(QR); _qadic_exp_bsplit_series(P, Q, T, x, len, lo, m, a, j, lena); _qadic_exp_bsplit_series(PR, QR, TR, x, len, m, hi, a, j, lena); _fmpz_poly_mul(W, TR, d, P, d); _fmpz_poly_reduce(W, 2*d - 1, a, j, lena); _fmpz_vec_scalar_mul_fmpz(T, T, d, QR); _fmpz_vec_add(T, T, W, d); _fmpz_poly_mul(W, P, d, PR, d); _fmpz_poly_reduce(W, 2*d - 1, a, j, lena); _fmpz_vec_swap(P, W, d); fmpz_mul(Q, Q, QR); _fmpz_vec_clear(PR, 2*d - 1); _fmpz_vec_clear(TR, 2*d - 1); _fmpz_vec_clear(W, 2*d - 1); fmpz_clear(QR); } }
int main(void) { int i, result; flint_rand_t state; printf("scalar_submul_fmpz...."); fflush(stdout); flint_randinit(state); /* Compare with fmpz_vec_scalar_submul_si */ for (i = 0; i < 10000; i++) { fmpz *a, *b, *c; long len, n; fmpz_t n1; len = n_randint(state, 100); n = (long) n_randbits(state, FLINT_BITS - 1); if (n_randint(state, 2)) n = -n; fmpz_init(n1); fmpz_set_si(n1, n); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); c = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_randtest(b, state, len, 200); _fmpz_vec_set(c, b, len); _fmpz_vec_scalar_submul_fmpz(b, a, len, n1); _fmpz_vec_scalar_submul_si(c, a, len, n); result = (_fmpz_vec_equal(c, b, len)); if (!result) { printf("FAIL:\n"); _fmpz_vec_print(c, len), printf("\n\n"); _fmpz_vec_print(b, len), printf("\n\n"); abort(); } fmpz_clear(n1); _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); _fmpz_vec_clear(c, len); } /* Compute a different way */ for (i = 0; i < 10000; i++) { fmpz *a, *b, *c, *d; long len = n_randint(state, 100); fmpz_t n1; fmpz_init(n1); fmpz_randtest(n1, state, 200); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); c = _fmpz_vec_init(len); d = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_randtest(b, state, len, 200); _fmpz_vec_set(c, b, len); _fmpz_vec_scalar_submul_fmpz(b, a, len, n1); _fmpz_vec_scalar_mul_fmpz(d, a, len, n1); _fmpz_vec_sub(c, c, d, len); result = (_fmpz_vec_equal(c, b, len)); if (!result) { printf("FAIL:\n"); _fmpz_vec_print(c, len), printf("\n\n"); _fmpz_vec_print(b, len), printf("\n\n"); abort(); } fmpz_clear(n1); _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); _fmpz_vec_clear(c, len); _fmpz_vec_clear(d, len); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("scalar_fdiv_q_fmpz...."); fflush(stdout); for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpz *a, *b, *c; fmpz_t n; mpz_t d, e, f, m; slong i; slong len = n_randint(state, 100); fmpz_init(n); fmpz_randtest_not_zero(n, state, 100); if (n_randint(state, 2)) fmpz_neg(n, n); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); c = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_set(b, a, len); _fmpz_vec_scalar_fdiv_q_fmpz(c, a, len, n); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(m); for (i = 0; i < len; i++) { fmpz_get_mpz(m, n); fmpz_get_mpz(d, b + i); mpz_fdiv_q(e, d, m); fmpz_get_mpz(f, c + i); result = (mpz_cmp(f, e) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, m = %Zd, e = %Zd, f = %Zd\n", d, m, e, f); abort(); } } _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); _fmpz_vec_clear(c, len); fmpz_clear(n); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(m); } /* Test aliasing of a and c */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpz *a, *b; fmpz_t n; mpz_t d, e, f, m; slong i; slong len = n_randint(state, 100); fmpz_init(n); fmpz_randtest_not_zero(n, state, 100); if (n_randint(state, 2)) fmpz_neg(n, n); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_set(b, a, len); _fmpz_vec_scalar_fdiv_q_fmpz(a, a, len, n); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(m); for (i = 0; i < len; i++) { fmpz_get_mpz(m, n); fmpz_get_mpz(d, b + i); mpz_fdiv_q(e, d, m); fmpz_get_mpz(f, a + i); result = (mpz_cmp(f, e) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf("d = %Zd, m = %Zd, e = %Zd, f = %Zd\n", d, m, e, f); abort(); } } _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); fmpz_clear(n); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(m); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("scalar_divexact_ui...."); fflush(stdout); /* Check aliasing of a and b */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpz *a, *b; ulong n = n_randtest_not_zero(state); slong len = n_randint(state, 100); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_scalar_mul_ui(a, a, len, n); _fmpz_vec_scalar_divexact_ui(b, a, len, n); _fmpz_vec_scalar_divexact_ui(a, a, len, n); result = (_fmpz_vec_equal(a, b, len)); if (!result) { flint_printf("FAIL:\n"); _fmpz_vec_print(a, len), flint_printf("\n\n"); _fmpz_vec_print(b, len), flint_printf("\n\n"); abort(); } _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); } /* Check that a * n / n == a */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpz *a, *b; ulong n = n_randtest_not_zero(state); slong len = n_randint(state, 100); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_set(b, a, len); _fmpz_vec_scalar_mul_ui(a, a, len, n); _fmpz_vec_scalar_divexact_ui(a, a, len, n); result = (_fmpz_vec_equal(a, b, len)); if (!result) { flint_printf("FAIL:\n"); _fmpz_vec_print(a, len), flint_printf("\n\n"); _fmpz_vec_print(b, len), flint_printf("\n\n"); abort(); } _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }