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); }
void _qadic_exp_balanced(fmpz *rop, const fmpz *x, slong v, slong len, const fmpz *a, const slong *j, slong lena, const fmpz_t p, slong N, const fmpz_t pN) { const slong d = j[lena - 1]; fmpz_t pw; fmpz *r, *s, *t; slong i, w; r = _fmpz_vec_init(d); s = _fmpz_vec_init(2*d - 1); t = _fmpz_vec_init(d); fmpz_init(pw); fmpz_pow_ui(pw, p, v); _fmpz_vec_scalar_mul_fmpz(t, x, len, pw); _fmpz_vec_scalar_mod_fmpz(t, t, len, pN); _fmpz_vec_zero(t + len, d - len); fmpz_set(pw, p); fmpz_one(rop + 0); _fmpz_vec_zero(rop + 1, d - 1); w = 1; while (!_fmpz_vec_is_zero(t, d)) { fmpz_mul(pw, pw, pw); for (i = 0; i < d; i++) { fmpz_fdiv_r(r + i, t + i, pw); fmpz_sub(t + i, t + i, r + i); } if (!_fmpz_vec_is_zero(r, d)) { _qadic_exp_bsplit(r, r, w, d, a, j, lena, p, N); _fmpz_poly_mul(s, rop, d, r, d); _fmpz_poly_reduce(s, 2*d - 1, a, j, lena); _fmpz_vec_scalar_mod_fmpz(rop, s, d, pN); } w *= 2; } _fmpz_vec_clear(r, d); _fmpz_vec_clear(s, 2*d - 1); _fmpz_vec_clear(t, d); fmpz_clear(pw); }
void _fmpz_poly_sqrlow_KS(fmpz * res, const fmpz * poly, long len, long n) { int neg; long bits, limbs, loglen, sign = 0; mp_limb_t *arr_in, *arr_out; FMPZ_VEC_NORM(poly, len); if (len == 0) { _fmpz_vec_zero(res, n); return; } neg = (fmpz_sgn(poly + len - 1) > 0) ? 0 : -1; if (n > 2 * len - 1) { _fmpz_vec_zero(res + 2 * len - 1, n - (2 * len - 1)); n = 2 * len - 1; } bits = _fmpz_vec_max_bits(poly, len); if (bits < 0) { sign = 1; bits = - bits; } loglen = FLINT_BIT_COUNT(len); bits = 2 * bits + loglen + sign; limbs = (bits * len - 1) / FLINT_BITS + 1; arr_in = flint_calloc(limbs, sizeof(mp_limb_t)); arr_out = flint_malloc((2 * limbs) * sizeof(mp_limb_t)); _fmpz_poly_bit_pack(arr_in, poly, len, bits, neg); mpn_sqr(arr_out, arr_in, limbs); if (sign) _fmpz_poly_bit_unpack(res, n, arr_out, bits, 0); else _fmpz_poly_bit_unpack_unsigned(res, n, arr_out, bits); flint_free(arr_in); flint_free(arr_out); }
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); }
/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */ void _fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1, long len1, const fmpz * poly2, long len2) { fmpz *rev1, *rev2, *out, *temp; long length, loglen = 0; if (len1 == 1) { fmpz_mul(res, poly1, poly2); return; } while ((1L << loglen) < len1) loglen++; length = (1L << loglen); rev1 = (fmpz *) flint_calloc(4 * length, sizeof(fmpz *)); rev2 = rev1 + length; out = rev1 + 2 * length; temp = _fmpz_vec_init(2 * length); revbin1(rev1, poly1, len1, loglen); revbin1(rev2, poly2, len2, loglen); _fmpz_poly_mul_kara_recursive(out, rev1, rev2, temp, loglen); _fmpz_vec_zero(res, len1 + len2 - 1); revbin2(res, out, len1 + len2 - 1, loglen + 1); _fmpz_vec_clear(temp, 2 * length); flint_free(rev1); }
int fmpq_poly_set_str(fmpq_poly_t poly, const char * str) { int ans; long len; len = atol(str); if (len < 0) return -1; if (len == 0) { fmpq_poly_zero(poly); return 0; } fmpq_poly_fit_length(poly, len); ans = _fmpq_poly_set_str(poly->coeffs, poly->den, str); if (ans == 0) { _fmpq_poly_set_length(poly, len); _fmpq_poly_normalise(poly); } else { _fmpz_vec_zero(poly->coeffs, len); fmpz_set_ui(poly->den, 1); _fmpq_poly_set_length(poly, 0); } return ans; }
void _fmpq_poly_scalar_mul_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, slong len, ulong c) { fmpz_t gcd; /* GCD( den, c ) */ if (c == 0) { _fmpz_vec_zero(rpoly, len); fmpz_one(rden); return; } fmpz_init(gcd); fmpz_set_ui(gcd, c); fmpz_gcd(gcd, gcd, den); if (*gcd == WORD(1)) { _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c); fmpz_set(rden, den); } else { ulong gcd2 = fmpz_get_ui(gcd); ulong c2 = c / gcd2; _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c2); fmpz_fdiv_q_ui(rden, den, gcd2); } fmpz_clear(gcd); }
void _fmpq_poly_compose_series_horner(fmpz * res, fmpz_t den, const fmpz * poly1, const fmpz_t den1, long len1, const fmpz * poly2, const fmpz_t den2, long len2, long n) { if (fmpz_is_one(den2)) { _fmpz_poly_compose_series(res, poly1, len1, poly2, len2, n); fmpz_set(den, den1); _fmpq_poly_canonicalise(res, den, n); } else if (n == 1) { fmpz_set(res, poly1); fmpz_set(den, den1); _fmpq_poly_canonicalise(res, den, 1); } else { long i = len1 - 1; long lenr; fmpz_t tden; fmpz * t = _fmpz_vec_init(n); fmpz_init(tden); _fmpz_vec_zero(res, n); lenr = len2; _fmpq_poly_scalar_mul_fmpz(res, den, poly2, den2, len2, poly1 + i); _fmpq_poly_scalar_div_fmpz(res, den, res, den, len2, den1); i--; _fmpq_poly_add(res, den, res, den, len2, poly1 + i, den1, 1); _fmpq_poly_canonicalise(res, den, lenr); while (i > 0) { i--; if (lenr + len2 - 1 < n) { _fmpq_poly_mul(t, tden, res, den, lenr, poly2, den2, len2); lenr = lenr + len2 - 1; } else { _fmpq_poly_mullow(t, tden, res, den, lenr, poly2, den2, len2, n); lenr = n; } _fmpq_poly_canonicalise(t, tden, lenr); _fmpq_poly_add(res, den, t, tden, lenr, poly1 + i, den1, 1); } _fmpq_poly_canonicalise(res, den, n); _fmpz_vec_clear(t, n); fmpz_clear(tden); } }
int main(void) { int i, result; flint_rand_t state; printf("is_zero...."); fflush(stdout); flint_randinit(state); /* Check zero vector */ for (i = 0; i < 10000; i++) { fmpz *a; long len = n_randint(state, 100); a = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_zero(a, len); result = (_fmpz_vec_is_zero(a, len)); if (!result) { printf("FAIL1:\n"); _fmpz_vec_print(a, len), printf("\n\n"); abort(); } _fmpz_vec_clear(a, len); } /* Check non-zero vector */ for (i = 0; i < 10000; i++) { fmpz *a; long len = n_randint(state, 100) + 1; a = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); fmpz_set_ui(a + (len - 1), 1UL); result = (!_fmpz_vec_is_zero(a, len)); if (!result) { printf("FAIL2:\n"); _fmpz_vec_print(a, len), printf("\n\n"); abort(); } _fmpz_vec_clear(a, len); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
void _fmpq_poly_invsqrt_series(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long n) { long m; fmpz * t, * u; fmpz_t tden, uden; if (n == 1) { fmpz_one(rpoly); fmpz_one(rden); return; } m = (n + 1) / 2; _fmpq_poly_invsqrt_series(rpoly, rden, poly, den, m); fmpz_init(tden); fmpz_init(uden); t = _fmpz_vec_init(n); u = _fmpz_vec_init(n); _fmpz_vec_zero(rpoly + m, n - m); _fmpq_poly_mul(t, tden, rpoly, rden, m, rpoly, rden, m); if (2*m - 1 < n) fmpz_zero(t + n - 1); _fmpq_poly_mullow(u, uden, t, tden, n, rpoly, rden, n, n); _fmpq_poly_mullow(t, tden, u, uden, n, poly, den, n, n); _fmpz_vec_neg(t + m, t + m, n - m); _fmpz_vec_zero(t, m); fmpz_mul_ui(tden, tden, 2UL); _fmpq_poly_canonicalise(t, tden, n); _fmpq_poly_add(rpoly, rden, rpoly, rden, m, t, tden, n); fmpz_clear(tden); fmpz_clear(uden); _fmpz_vec_clear(t, n); _fmpz_vec_clear(u, n); }
void fmpz_poly_zero_coeffs(fmpz_poly_t poly, long i, long j) { if (i < 0) i = 0; if (j > poly->length) j = poly->length; _fmpz_vec_zero(poly->coeffs, j - i); if (j == poly->length) { _fmpz_poly_set_length(poly, i); _fmpz_poly_normalise(poly); } }
void _qadic_exp(fmpz *rop, const fmpz *op, slong v, slong len, const fmpz *a, const slong *j, slong lena, const fmpz_t p, slong N, const fmpz_t pN) { if (N < (WORD(1) << 13) / (slong) fmpz_bits(p)) { _qadic_exp_rectangular(rop, op, v, len, a, j, lena, p, N, pN); } else { const slong d = j[lena - 1]; _qadic_exp_balanced(rop, op, v, len, a, j, lena, p, N, pN); _fmpz_vec_zero(rop + d, d - 1); } }
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); }
int dgsl_mp_call_identity(fmpz *rop, const dgsl_mp_t *self, gmp_randstate_t state) { assert(rop); assert(self); const long n = fmpz_mat_ncols(self->B); mpz_t tmp_g; mpz_init(tmp_g); _fmpz_vec_zero(rop, n); for(long i=0; i<n; i++) { self->D[0]->call(tmp_g, self->D[0], state); fmpz_set_mpz(rop+i, tmp_g); } mpz_clear(tmp_g); return 0; }
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); } }
static void _qadic_exp_bsplit(fmpz *y, const fmpz *x, slong v, slong len, const fmpz *a, const slong *j, slong lena, const fmpz_t p, slong N) { const slong d = j[lena - 1]; const slong n = _padic_exp_bound(v, N, p); if (n == 1) { fmpz_one(y + 0); _fmpz_vec_zero(y + 1, d - 1); } else { fmpz *P, *T; fmpz_t Q, R; slong f; P = _fmpz_vec_init(2*d - 1); T = _fmpz_vec_init(2*d - 1); fmpz_init(Q); fmpz_init(R); _qadic_exp_bsplit_series(P, Q, T, x, len, 1, n, a, j, lena); fmpz_add(T + 0, T + 0, Q); /* (T,Q) := (T,Q) + 1 */ /* Note exp(x) is a unit so val(T) == val(Q). */ f = fmpz_remove(Q, Q, p); fmpz_pow_ui(R, p, f); _fmpz_vec_scalar_divexact_fmpz(T, T, d, R); _padic_inv(Q, Q, p, N); _fmpz_vec_scalar_mul_fmpz(y, T, d, Q); _fmpz_vec_clear(P, 2*d - 1); _fmpz_vec_clear(T, 2*d - 1); fmpz_clear(Q); fmpz_clear(R); } }
int dgsl_mp_call_inlattice(fmpz *rop, const dgsl_mp_t *self, gmp_randstate_t state) { assert(rop); assert(self); const long m = fmpz_mat_nrows(self->B); const long n = fmpz_mat_ncols(self->B); mpz_t tmp_g; mpz_init(tmp_g); fmpz_t tmp_f; fmpz_init(tmp_f); _fmpz_vec_zero(rop, n); for(long i=0; i<m; i++) { self->D[i]->call(tmp_g, self->D[i], state); fmpz_set_mpz(tmp_f, tmp_g); _fmpz_vec_scalar_addmul_fmpz(rop, self->B->rows[i], n, tmp_f); } _fmpz_vec_add(rop, rop, self->c_z, n); mpz_clear(tmp_g); fmpz_clear(tmp_f); return 0; }
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_ramanujan_tau(fmpz_poly_t res, long n) { long j, k, jv, kv; fmpz_t tmp; fmpz_poly_fit_length(res, n); _fmpz_vec_zero(res->coeffs, n); _fmpz_poly_set_length(res, n); fmpz_init(tmp); for (j = jv = 0; jv < n; jv += ++j) { fmpz_set_ui(tmp, 2*j+1); for (k = kv = 0; jv + kv < n; kv += ++k) { if ((j+k) & 1) fmpz_submul_ui(res->coeffs + jv+kv, tmp, 2*k+1); else fmpz_addmul_ui(res->coeffs + jv+kv, tmp, 2*k+1); } } fmpz_poly_mullow(res, res, res, n-1); fmpz_poly_mullow(res, res, res, n-1); fmpz_poly_shift_left(res, res, 1); fmpz_clear(tmp); }
void _fmpq_poly_exp_series(fmpz * g, fmpz_t gden, const fmpz * h, const fmpz_t hden, long n) { long m; fmpz * t, * u; fmpz_t tden, uden; if (n < 2) { fmpz_one(g); fmpz_one(gden); return; } m = (n + 1) / 2; _fmpq_poly_exp_series(g, gden, h, hden, m); _fmpz_vec_zero(g + m, n - m); t = _fmpz_vec_init(n); u = _fmpz_vec_init(n); fmpz_init(tden); fmpz_init(uden); _fmpq_poly_log_series(t, tden, g, gden, n); _fmpq_poly_sub(t, tden, t, tden, n, h, hden, n); /* TODO: half of product is redundant! */ _fmpq_poly_mullow(u, uden, g, gden, n, t, tden, n, n); _fmpq_poly_sub(g, gden, g, gden, n, u, uden, n); _fmpq_poly_canonicalise(g, gden, n); fmpz_clear(tden); fmpz_clear(uden); _fmpz_vec_clear(t, n); _fmpz_vec_clear(u, n); }
/* Assumes poly1 and poly2 are not length 0. */ void _fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1, long len1, const fmpz * poly2, long len2, long start) { _fmpz_vec_zero(res, start); if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */ { if (start == 0) fmpz_mul(res, poly1, poly2); } else /* Ordinary case */ { long i, m, n; /* Set res[i] = poly1[i]*poly2[0] */ if (start < len1) _fmpz_vec_scalar_mul_fmpz(res + start, poly1 + start, len1 - start, poly2); /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ m = FLINT_MAX(len1 - 1, start); _fmpz_vec_scalar_mul_fmpz(res + m, poly2 + m - len1 + 1, len2 - 1 + len1 - m, poly1 + len1 - 1); /* out[i+j] += in1[i]*in2[j] */ m = FLINT_MAX(start, len2 - 1); for (i = m - len2 + 1; i < len1 - 1; i++) { n = FLINT_MAX(i + 1, start); _fmpz_vec_scalar_addmul_fmpz(res + n, poly2 + n - i, len2 + i - n, poly1 + i); } } }
int dgsl_mp_call_coset(fmpz *rop, const dgsl_mp_t *self, gmp_randstate_t state) { assert(rop); assert(self); const long n = fmpz_mat_ncols(self->B); _fmpz_vec_zero(rop, n); mpfr_t *c = _mpfr_vec_init(n, mpfr_get_prec(self->sigma)); _mpfr_vec_set(c, self->c, n, MPFR_RNDN); mpfr_t c_prime; mpfr_init2(c_prime, mpfr_get_prec(self->sigma)); mpfr_t tmp; mpfr_init2(tmp, mpfr_get_prec(self->sigma)); mpfr_t sigma_prime; mpfr_init2(sigma_prime, mpfr_get_prec(self->sigma)); mpz_t z; mpz_init(z); mpfr_t z_mpfr; mpfr_init2(z_mpfr, mpfr_get_prec(self->sigma)); fmpz_t z_fmpz; fmpz_init(z_fmpz); size_t tau = 3; if (ceil(sqrt(log2((double)n))) > tau) tau = ceil(sqrt(log2((double)n))); mpfr_t *b = _mpfr_vec_init(n, mpfr_get_prec(self->sigma)); const long m = fmpz_mat_nrows(self->B); for(long j=0; j<m; j++) { long i = m-j-1; _mpfr_vec_dot_product(c_prime, c, self->G->rows[i], n, MPFR_RNDN); _mpfr_vec_dot_product(tmp, self->G->rows[i], self->G->rows[i], n, MPFR_RNDN); mpfr_div(c_prime, c_prime, tmp, MPFR_RNDN); mpfr_sqrt(tmp, tmp, MPFR_RNDN); mpfr_div(sigma_prime, self->sigma, tmp, MPFR_RNDN); assert(mpfr_cmp_d(sigma_prime, 0.0) > 0); dgs_disc_gauss_mp_t *D = dgs_disc_gauss_mp_init(sigma_prime, c_prime, tau, DGS_DISC_GAUSS_UNIFORM_ONLINE); D->call(z, D, state); dgs_disc_gauss_mp_clear(D); mpfr_set_z(z_mpfr, z, MPFR_RNDN); mpfr_neg(z_mpfr, z_mpfr, MPFR_RNDN); _mpfr_vec_set_fmpz_vec(b, self->B->rows[i], n, MPFR_RNDN); _mpfr_vec_scalar_addmul_mpfr(c, b, n, z_mpfr, MPFR_RNDN); fmpz_set_mpz(z_fmpz, z); _fmpz_vec_scalar_addmul_fmpz(rop, self->B->rows[i], n, z_fmpz); } fmpz_clear(z_fmpz); mpfr_clear(z_mpfr); mpfr_clear(sigma_prime); mpfr_clear(tmp); mpfr_clear(c_prime); _mpfr_vec_clear(c, n); _mpfr_vec_clear(b, 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); }
/* convert to an fmpz poly with a common exponent and coefficients at most prec bits, also bounding input error plus rounding error */ void _fmprb_poly_get_fmpz_poly_2exp(fmpr_t error, fmpz_t exp, fmpz * coeffs, fmprb_srcptr A, long lenA, long prec) { fmpz_t top_exp, bot_exp; long shift; long i; int rounding; fmpz_init(top_exp); fmpz_init(bot_exp); if (!_fmprb_poly_mid_get_hull(bot_exp, top_exp, A, lenA)) { fmpz_zero(exp); _fmpz_vec_zero(coeffs, lenA); fmpr_zero(error); for (i = 0; i < lenA; i++) { if (fmpr_cmp(fmprb_radref(A + i), error) > 0) fmpr_set(error, fmprb_radref(A + i)); } return; /* no need to clear fmpzs */ } /* only take as much precision as necessary */ shift = _fmpz_sub_small(top_exp, bot_exp); prec = FLINT_MIN(prec, shift); fmpz_sub_ui(exp, top_exp, prec); /* extract integer polynomial */ rounding = 0; for (i = 0; i < lenA; i++) rounding |= fmpr_get_fmpz_fixed_fmpz(coeffs + i, fmprb_midref(A + i), exp); fmpr_zero(error); /* compute maximum of input errors */ for (i = 0; i < lenA; i++) { if (fmpr_cmp(fmprb_radref(A + i), error) > 0) fmpr_set(error, fmprb_radref(A + i)); } /* add rounding error */ if (rounding) { fmpr_t t; fmpr_init(t); fmpz_set_ui(fmpr_manref(t), 1UL); fmpz_set(fmpr_expref(t), exp); fmpr_add(error, error, t, FMPRB_RAD_PREC, FMPR_RND_UP); fmpr_clear(t); } fmpz_clear(top_exp); }
void _padic_poly_sub(fmpz *rop, slong *val, slong N, const fmpz *op1, slong val1, slong len1, slong N1, const fmpz *op2, slong val2, slong len2, slong N2, const padic_ctx_t ctx) { const slong len = FLINT_MAX(len1, len2); *val = FLINT_MIN(val1, val2); if (val1 == val2) { _fmpz_poly_sub(rop, op1, len1, op2, len2); _padic_poly_canonicalise(rop, val, len, ctx->p); } else { fmpz_t x; fmpz_init(x); if (val1 < val2) /* F := p^g (G - p^{h-g} H) */ { fmpz_pow_ui(x, ctx->p, val2 - val1); if (rop == op1) { _fmpz_vec_zero(rop + len1, len2 - len1); _fmpz_vec_scalar_submul_fmpz(rop, op2, len2, x); } else { _fmpz_vec_scalar_mul_fmpz(rop, op2, len2, x); _fmpz_vec_neg(rop, rop, len2); _fmpz_poly_add(rop, op1, len1, rop, len2); } } else /* F := p^h (p^(g-h) G - H) */ { fmpz_pow_ui(x, ctx->p, val1 - val2); if (rop == op2) { _fmpz_vec_neg(rop, op2, len2); _fmpz_vec_zero(rop + len2, len1 - len2); _fmpz_vec_scalar_addmul_fmpz(rop, op1, len1, x); } else { _fmpz_vec_scalar_mul_fmpz(rop, op1, len1, x); _fmpz_poly_sub(rop, rop, len1, op2, len2); } } fmpz_clear(x); } /* Reduce */ if (N - *val > 0) { fmpz_t pow; int alloc; alloc = _padic_ctx_pow_ui(pow, N - *val, ctx); if (N >= N1 && N >= N2) { slong i; for (i = 0; i < len; i++) if (fmpz_sgn(rop + i) < 0) fmpz_add(rop + i, rop + i, pow); } else { _fmpz_vec_scalar_mod_fmpz(rop, rop, len, pow); } if (alloc) fmpz_clear(pow); } else { _fmpz_vec_zero(rop, len); *val = 0; } }
/* Assumes len1 != 0 != len2 */ int _fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, long len1, const fmpz * poly2, long len2) { ulong bits1, bits2, max_bits, pack_bits, bound_bits, bits_G, bits_Q; ulong limbs1, limbs2, limbsg, pack_limbs, qlimbs; ulong log_glen, log_length; long sign1, sign2, glen, qlen; fmpz_t ac, bc, d, gc; fmpz * A, * B, * G, * Q, * t; mp_ptr array1, array2, arrayg, q, temp; int divides; fmpz_init(ac); fmpz_init(bc); fmpz_init(d); /* compute gcd of content of poly1 and poly2 */ _fmpz_poly_content(ac, poly1, len1); _fmpz_poly_content(bc, poly2, len2); fmpz_gcd(d, ac, bc); /* special case, one of the polys is a constant */ if (len2 == 1) /* if len1 == 1 then so does len2 */ { fmpz_set(res, d); fmpz_clear(ac); fmpz_clear(bc); fmpz_clear(d); return 1; } /* divide poly1 and poly2 by their content */ A = _fmpz_vec_init(len1); B = _fmpz_vec_init(len2); _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, ac); _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, bc); fmpz_clear(ac); fmpz_clear(bc); /* special case, one of the polys is length 2 */ if (len2 == 2) /* if len1 == 2 then so does len2 */ { Q = _fmpz_vec_init(len1 - len2 + 1); if (_fmpz_poly_divides(Q, A, len1, B, 2)) { _fmpz_vec_scalar_mul_fmpz(res, B, 2, d); if (fmpz_sgn(res + 1) < 0) _fmpz_vec_neg(res, res, 2); } else { fmpz_set(res, d); fmpz_zero(res + 1); } fmpz_clear(d); _fmpz_vec_clear(A, len1); _fmpz_vec_clear(B, len2); _fmpz_vec_clear(Q, len1 - len2 + 1); return 1; } /* Determine how many bits (pack_bits) to pack into. The bound bound_bits ensures that if G | A and G | B with G primitive then G is the gcd of A and B. The bound is taken from http://arxiv.org/abs/cs/0206032v1 */ bits1 = FLINT_ABS(_fmpz_vec_max_bits(A, len1)); bits2 = FLINT_ABS(_fmpz_vec_max_bits(B, len2)); max_bits = FLINT_MAX(bits1, bits2); bound_bits = FLINT_MIN(bits1, bits2) + 6; pack_bits = FLINT_MAX(bound_bits, max_bits); /* need to pack original polys */ pack_limbs = (pack_bits - 1)/FLINT_BITS + 1; if (pack_bits >= 32) /* pack into multiples of limbs if >= 32 bits */ pack_bits = FLINT_BITS*pack_limbs; /* allocate space to pack into */ limbs1 = (pack_bits*len1 - 1)/FLINT_BITS + 1; limbs2 = (pack_bits*len2 - 1)/FLINT_BITS + 1; array1 = flint_calloc(limbs1, sizeof(mp_limb_t)); array2 = flint_calloc(limbs2, sizeof(mp_limb_t)); arrayg = flint_calloc(limbs2, sizeof(mp_limb_t)); /* pack first poly and normalise */ sign1 = (long) fmpz_sgn(A + len1 - 1); _fmpz_poly_bit_pack(array1, A, len1, pack_bits, sign1); while (array1[limbs1 - 1] == 0) limbs1--; /* pack second poly and normalise */ sign2 = (long) fmpz_sgn(B + len2 - 1); _fmpz_poly_bit_pack(array2, B, len2, pack_bits, sign2); while (array2[limbs2 - 1] == 0) limbs2--; /* compute integer GCD */ limbsg = mpn_gcd_full(arrayg, array1, limbs1, array2, limbs2); /* Make space for unpacked gcd. May have one extra coeff due to 1 0 -x being packed as 0 -1 -x. */ glen = FLINT_MIN((limbsg*FLINT_BITS)/pack_bits + 1, len2); G = _fmpz_vec_init(glen); /* unpack gcd */ _fmpz_poly_bit_unpack(G, glen, arrayg, pack_bits, 0); while (G[glen - 1] == 0) glen--; /* divide by any content */ fmpz_init(gc); _fmpz_poly_content(gc, G, glen); if (!fmpz_is_one(gc)) limbsg = mpn_tdiv_q_fmpz_inplace(arrayg, limbsg, gc); /* make space for quotient and remainder of first poly by gcd */ qlimbs = limbs1 - limbsg + 1; qlen = FLINT_MIN(len1, (qlimbs*FLINT_BITS)/pack_bits + 1); qlimbs = (qlen*pack_bits - 1)/FLINT_BITS + 1; q = flint_calloc(qlimbs, sizeof(mp_limb_t)); temp = flint_malloc(limbsg*sizeof(mp_limb_t)); divides = 0; if (mpn_divides(q, array1, limbs1, arrayg, limbsg, temp)) { /* unpack quotient of first poly by gcd */ Q = _fmpz_vec_init(len1); t = _fmpz_vec_init(len1 + glen); _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0); while (Q[qlen - 1] == 0) qlen--; /* divide by content */ _fmpz_vec_scalar_divexact_fmpz(G, G, glen, gc); /* check if we really need to multiply out to check for exact quotient */ bits_G = FLINT_ABS(_fmpz_vec_max_bits(G, glen)); bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen)); log_glen = FLINT_BIT_COUNT(glen); log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen)); divides = (bits_G + bits_Q + log_length < pack_bits); if (!divides) /* need to multiply out to check exact quotient */ divides = multiplies_out(A, len1, Q, qlen, G, glen, sign1, t); if (divides) /* quotient really was exact */ { mpn_zero(q, qlimbs); if (mpn_divides(q, array2, limbs2, arrayg, limbsg, temp)) { /* unpack quotient of second poly by gcd */ qlimbs = limbs2 - limbsg + 1; qlen = FLINT_MIN(len2, (qlimbs*FLINT_BITS - 1)/pack_bits + 1); _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0); while (Q[qlen - 1] == 0) qlen--; /* check if we really need to multiply out to check for exact quotient */ bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen)); log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen)); divides = (bits_G + bits_Q + log_length < pack_bits); if (!divides) /* we need to multiply out */ divides = multiplies_out(B, len2, Q, qlen, G, glen, sign1, t); } } _fmpz_vec_clear(t, len1 + glen); _fmpz_vec_clear(Q, len1); } flint_free(q); flint_free(temp); flint_free(arrayg); flint_free(array1); flint_free(array2); fmpz_clear(gc); _fmpz_vec_clear(A, len1); _fmpz_vec_clear(B, len2); /* we found the gcd, so multiply by content */ if (divides) { _fmpz_vec_zero(res + glen, len2 - glen); _fmpz_vec_scalar_mul_fmpz(res, G, glen, d); } fmpz_clear(d); _fmpz_vec_clear(G, glen); return divides; }
void _fmpz_poly_mullow_KS(fmpz * res, const fmpz * poly1, long len1, const fmpz * poly2, long len2, long n) { int neg1, neg2; long limbs1, limbs2, loglen; long bits1, bits2, bits; mp_limb_t *arr1, *arr2, *arr3; long sign = 0; FMPZ_VEC_NORM(poly1, len1); FMPZ_VEC_NORM(poly2, len2); if (!len1 | !len2) { _fmpz_vec_zero(res, n); return; } neg1 = (fmpz_sgn(poly1 + len1 - 1) > 0) ? 0 : -1; neg2 = (fmpz_sgn(poly2 + len2 - 1) > 0) ? 0 : -1; if (n > len1 + len2 - 1) { _fmpz_vec_zero(res + len1 + len2 - 1, n - (len1 + len2 - 1)); n = len1 + len2 - 1; } bits1 = _fmpz_vec_max_bits(poly1, len1); if (bits1 < 0) { sign = 1; bits1 = -bits1; } if (poly1 != poly2) { bits2 = _fmpz_vec_max_bits(poly2, len2); if (bits2 < 0) { sign = 1; bits2 = -bits2; } } else bits2 = bits1; loglen = FLINT_BIT_COUNT(FLINT_MIN(len1, len2)); bits = bits1 + bits2 + loglen + sign; limbs1 = (bits * len1 - 1) / FLINT_BITS + 1; limbs2 = (bits * len2 - 1) / FLINT_BITS + 1; if (poly1 == poly2) { arr1 = (mp_ptr) flint_calloc(limbs1, sizeof(mp_limb_t)); arr2 = arr1; _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1); } else { arr1 = (mp_ptr) flint_calloc(limbs1 + limbs2, sizeof(mp_limb_t)); arr2 = arr1 + limbs1; _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1); _fmpz_poly_bit_pack(arr2, poly2, len2, bits, neg2); } arr3 = (mp_ptr) flint_malloc((limbs1 + limbs2) * sizeof(mp_limb_t)); if (limbs1 == limbs2) mpn_mul_n(arr3, arr1, arr2, limbs1); else if (limbs1 > limbs2) mpn_mul(arr3, arr1, limbs1, arr2, limbs2); else mpn_mul(arr3, arr2, limbs2, arr1, limbs1); if (sign) _fmpz_poly_bit_unpack(res, n, arr3, bits, neg1 ^ neg2); else _fmpz_poly_bit_unpack_unsigned(res, n, arr3, bits); flint_free(arr1); flint_free(arr3); }
void _fmpq_poly_inv_series_newton(fmpz * Qinv, fmpz_t Qinvden, const fmpz * Q, const fmpz_t Qden, long n) { if (n == 1) { if (fmpz_sgn(Q) > 0) { fmpz_set(Qinv, Qden); fmpz_set(Qinvden, Q); } else { fmpz_neg(Qinv, Qden); fmpz_neg(Qinvden, Q); } } else { const long alloc = FLINT_MAX(n, 3 * FMPQ_POLY_INV_NEWTON_CUTOFF); long *a, i, m; fmpz *W, *Wden; W = _fmpz_vec_init(alloc + 1); Wden = W + alloc; for (i = 1; (1L << i) < n; i++) ; a = (long *) flint_malloc(i * sizeof(long)); a[i = 0] = n; while (n >= FMPQ_POLY_INV_NEWTON_CUTOFF) a[++i] = (n = (n + 1) / 2); /* Base case */ { fmpz *rev = W + 2 * FMPQ_POLY_INV_NEWTON_CUTOFF; _fmpz_poly_reverse(rev, Q, n, n); _fmpz_vec_zero(W, 2*n - 2); fmpz_one(W + (2*n - 2)); fmpz_one(Wden); _fmpq_poly_div(Qinv, Qinvden, W, Wden, 2*n - 1, rev, Qden, n); _fmpq_poly_canonicalise(Qinv, Qinvden, n); _fmpz_poly_reverse(Qinv, Qinv, n, n); } for (i--; i >= 0; i--) { m = n; n = a[i]; _fmpz_poly_mullow(W, Q, n, Qinv, m, n); fmpz_mul(Wden, Qden, Qinvden); _fmpz_poly_mullow(Qinv + m, Qinv, m, W + m, n - m, n - m); fmpz_mul(Qinvden, Qinvden, Wden); _fmpz_vec_scalar_mul_fmpz(Qinv, Qinv, m, Wden); _fmpz_vec_neg(Qinv + m, Qinv + m, n - m); _fmpq_poly_canonicalise(Qinv, Qinvden, n); } _fmpz_vec_clear(W, alloc + 1); flint_free(a); } }
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); } }