static void _fmpz_mod_mat_det(fmpz_t rop, const fmpz *M, slong n, const fmpz_t pN) { fmpz *F; fmpz *a; fmpz *A; fmpz_t s; slong t, i, j, p, k; F = _fmpz_vec_init(n); a = _fmpz_vec_init((n-1) * n); A = _fmpz_vec_init(n); fmpz_init(s); fmpz_neg(F + 0, M + 0*n + 0); for (t = 1; t < n; t++) { for (i = 0; i <= t; i++) fmpz_set(a + 0*n + i, M + i*n + t); fmpz_set(A + 0, M + t*n + t); for (p = 1; p < t; p++) { for (i = 0; i <= t; i++) { fmpz_zero(s); for (j = 0; j <= t; j++) fmpz_addmul(s, M + i*n + j, a + (p-1)*n + j); fmpz_mod(a + p*n + i, s, pN); } fmpz_set(A + p, a + p*n + t); } fmpz_zero(s); for (j = 0; j <= t; j++) fmpz_addmul(s, M + t*n + j, a + (t-1)*n + j); fmpz_mod(A + t, s, pN); for (p = 0; p <= t; p++) { fmpz_sub(F + p, F + p, A + p); for (k = 0; k < p; k++) fmpz_submul(F + p, A + k, F + (p-k-1)); fmpz_mod(F + p, F + p, pN); } } /* Now [F{n-1}, F{n-2}, ..., F{0}, 1] is the characteristic polynomial of the matrix M. */ if (n % WORD(2) == 0) { fmpz_set(rop, F + (n-1)); } else { fmpz_neg(rop, F + (n-1)); fmpz_mod(rop, rop, pN); } _fmpz_vec_clear(F, n); _fmpz_vec_clear(a, (n-1)*n); _fmpz_vec_clear(A, n); fmpz_clear(s); }
int main() { fmpz * num1; fmpz * den1; fmpz_t num2; fmpz_t den2; long n, N; printf("bernoulli_number...."); fflush(stdout); N = 4000; num1 = _fmpz_vec_init(N); den1 = _fmpz_vec_init(N); fmpz_init(num2); fmpz_init(den2); _bernoulli_number_vec_multi_mod(num1, den1, N); for (n = 0; n < N; n++) { _bernoulli_number(num2, den2, n); if (!fmpz_equal(num1 + n, num2)) { printf("FAIL: n = %ld, numerator\n", n); printf("vec: "); fmpz_print(num1 + n); printf("\n"); printf("single: "); fmpz_print(num2); printf("\n"); abort(); } if (!fmpz_equal(den1 + n, den2)) { printf("FAIL: n = %ld, denominator\n", n); printf("vec: "); fmpz_print(den1 + n); printf("\n"); printf("single: "); fmpz_print(den2); printf("\n"); abort(); } } /* Check non underscore versions */ do { long N = 100; fmpq * x; fmpq_t t; fmpq_init(t); x = flint_malloc(sizeof(fmpq) * N); for (n = 0; n < N; n++) fmpq_init(x + n); bernoulli_number_vec(x, N); for (n = 0; n < N; n++) { bernoulli_number(t, n); if (!fmpq_equal(x + n, t)) { printf("FAIL!: n = %ld\n", n); abort(); } } for (n = 0; n < N; n++) fmpq_clear(x + n); flint_free(x); fmpq_clear(t); } while (0); _fmpz_vec_clear(num1, N); _fmpz_vec_clear(den1, N); fmpz_clear(num2); fmpz_clear(den2); mpfr_free_cache(); _fmpz_cleanup(); printf("PASS\n"); return 0; }
int main(void) { int i, result; flint_rand_t state; printf("scalar_mul_2exp...."); fflush(stdout); flint_randinit(state); /* Check aliasing of a and b */ for (i = 0; i < 10000; i++) { fmpz *a, *b; long len = n_randint(state, 100); ulong exp = n_randint(state, 200); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_scalar_mul_2exp(b, a, len, exp); _fmpz_vec_scalar_mul_2exp(a, a, len, exp); result = (_fmpz_vec_equal(a, b, len)); if (!result) { printf("FAIL:\n"); printf("exp = %lu\n", exp); _fmpz_vec_print(a, len), printf("\n\n"); _fmpz_vec_print(b, len), printf("\n\n"); abort(); } _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); } /* Check aliasing of (a*2^e1)*2^e2 equals a*2^(e1+e2) */ for (i = 0; i < 10000; i++) { fmpz *a, *b; long len = n_randint(state, 100); ulong e1 = n_randint(state, 200); ulong e2 = n_randint(state, 200); a = _fmpz_vec_init(len); b = _fmpz_vec_init(len); _fmpz_vec_randtest(a, state, len, 200); _fmpz_vec_scalar_mul_2exp(b, a, len, e1); _fmpz_vec_scalar_mul_2exp(b, b, len, e2); _fmpz_vec_scalar_mul_2exp(a, a, len, e1 + e2); result = (_fmpz_vec_equal(a, b, len)); if (!result) { printf("FAIL:\n"); printf("e1 = %lu, e2 = %lu\n", e1, e2); _fmpz_vec_print(a, len), printf("\n\n"); _fmpz_vec_print(b, len), printf("\n\n"); abort(); } _fmpz_vec_clear(a, len); _fmpz_vec_clear(b, len); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
int main() { long iter; flint_rand_t state; printf("rising2_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000; iter++) { arb_t a, u, v, u2, v2; fmpz *f; arb_ptr g; ulong n; long i, prec; arb_init(a); arb_init(u); arb_init(v); arb_init(u2); arb_init(v2); arb_randtest(a, state, 1 + n_randint(state, 4000), 10); arb_randtest(u, state, 1 + n_randint(state, 4000), 10); arb_randtest(v, state, 1 + n_randint(state, 4000), 10); n = n_randint(state, 120); f = _fmpz_vec_init(n + 1); g = _arb_vec_init(n + 1); prec = 2 + n_randint(state, 4000); arb_rising2_ui(u, v, a, n, prec); arith_stirling_number_1u_vec(f, n, n + 1); for (i = 0; i <= n; i++) arb_set_fmpz(g + i, f + i); _arb_poly_evaluate(u2, g, n + 1, a, prec); _arb_poly_derivative(g, g, n + 1, prec); _arb_poly_evaluate(v2, g, n, a, prec); if (!arb_overlaps(u, u2) || !arb_overlaps(v, v2)) { printf("FAIL: overlap\n\n"); printf("n = %lu\n", n); printf("a = "); arb_printd(a, 15); printf("\n\n"); printf("u = "); arb_printd(u, 15); printf("\n\n"); printf("u2 = "); arb_printd(u2, 15); printf("\n\n"); printf("v = "); arb_printd(v, 15); printf("\n\n"); printf("v2 = "); arb_printd(v2, 15); printf("\n\n"); abort(); } arb_set(u2, a); arb_rising2_ui(u2, v, u2, n, prec); if (!arb_equal(u2, u)) { printf("FAIL: aliasing 1\n\n"); printf("a = "); arb_printd(a, 15); printf("\n\n"); printf("u = "); arb_printd(u, 15); printf("\n\n"); printf("u2 = "); arb_printd(u2, 15); printf("\n\n"); printf("n = %lu\n", n); abort(); } arb_set(v2, a); arb_rising2_ui(u, v2, v2, n, prec); if (!arb_equal(v2, v)) { printf("FAIL: aliasing 2\n\n"); printf("a = "); arb_printd(a, 15); printf("\n\n"); printf("v = "); arb_printd(v, 15); printf("\n\n"); printf("v2 = "); arb_printd(v2, 15); printf("\n\n"); printf("n = %lu\n", n); abort(); } arb_clear(a); arb_clear(u); arb_clear(v); arb_clear(u2); arb_clear(v2); _fmpz_vec_clear(f, n + 1); _arb_vec_clear(g, n + 1); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
static void __fmpz_poly_divrem_divconquer(fmpz * Q, fmpz * R, const fmpz * A, long lenA, const fmpz * B, long lenB) { if (lenA < 2 * lenB - 1) { /* Convert unbalanced division into a 2 n1 - 1 by n1 division */ const long n1 = lenA - lenB + 1; const long n2 = lenB - n1; const fmpz * p1 = A + n2; const fmpz * d1 = B + n2; const fmpz * d2 = B; fmpz * W = _fmpz_vec_init((2 * n1 - 1) + lenB - 1); fmpz * d1q1 = R + n2; fmpz * d2q1 = W + (2 * n1 - 1); _fmpz_poly_divrem_divconquer_recursive(Q, d1q1, W, p1, d1, n1); /* Compute d2q1 = Q d2, of length lenB - 1 */ if (n1 >= n2) _fmpz_poly_mul(d2q1, Q, n1, d2, n2); else _fmpz_poly_mul(d2q1, d2, n2, Q, n1); /* Compute BQ = d1q1 * x^n1 + d2q1, of length lenB - 1; then compute R = A - BQ */ _fmpz_vec_swap(R, d2q1, n2); _fmpz_vec_add(R + n2, R + n2, d2q1 + n2, n1 - 1); _fmpz_vec_sub(R, A, R, lenA); _fmpz_vec_clear(W, (2 * n1 - 1) + lenB - 1); } else if (lenA > 2 * lenB - 1) { /* We shift A right until it is of length 2 lenB - 1, call this p1 */ const long shift = lenA - 2 * lenB + 1; const fmpz * p1 = A + shift; fmpz * q1 = Q + shift; fmpz * q2 = Q; fmpz * W = R + lenA; fmpz * d1q1 = W + (2 * lenB - 1); /* XXX: In this case, we expect R to be of length lenA + 2 * (2 * lenB - 1) and A to be modifiable */ /* Set q1 to p1 div B, a 2 lenB - 1 by lenB division, so q1 ends up being of length lenB; set d1q1 = d1 * q1 of length 2 lenB - 1 */ _fmpz_poly_divrem_divconquer_recursive(q1, d1q1, W, p1, B, lenB); /* We have dq1 = d1 * q1 * x^shift, of length lenA Compute R = A - dq1; the first lenB coeffs represent remainder terms (zero if division is exact), leaving lenA - lenB significant terms which we use in the division */ _fmpz_vec_sub((fmpz *) A + shift, A + shift, d1q1, lenB - 1); /* Compute q2 = trunc(R) div B; it is a smaller division than the original since len(trunc(R)) = lenA - lenB */ __fmpz_poly_divrem_divconquer(q2, R, A, lenA - lenB, B, lenB); _fmpz_vec_sub(R + lenA - lenB, A + lenA - lenB, d1q1 + lenB - 1, lenB); /* We have Q = q1 * x^shift + q2; Q has length lenB + shift; note q2 has length shift since the above division is lenA - lenB by lenB We've also written the remainder in place */ } else /* lenA = 2 * lenB - 1 */ { fmpz * W = _fmpz_vec_init(lenA); _fmpz_poly_divrem_divconquer_recursive(Q, R, W, A, B, lenB); _fmpz_vec_sub(R, A, R, lenA); _fmpz_vec_clear(W, lenA); } }
void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) { if (fmpz_equal_ui(p, 2)) { fmpz_one(rop); } else if (N == 1) { fmpz_mod(rop, op, p); } else { slong *a, i, n; fmpz *pow, *u; fmpz_t s, t; fmpz_t inv; fmpz_t pm1; a = _padic_lifts_exps(&n, N); pow = _fmpz_vec_init(2 * n); u = pow + n; _padic_lifts_pows(pow, a, n, p); fmpz_init(s); fmpz_init(t); fmpz_init(inv); fmpz_init(pm1); fmpz_sub_ui(pm1, p, 1); /* Compute reduced units for (p-1) */ { fmpz_mod(u + 0, pm1, pow + 0); } for (i = 1; i < n; i++) { fmpz_mod(u + i, u + (i - 1), pow + i); } /* Run Newton iteration */ i = n - 1; { fmpz_mod(rop, op, pow + i); fmpz_set(inv, pm1); } for (i--; i >= 0; i--) { /* Lift rop */ fmpz_powm(s, rop, p, pow + i); fmpz_sub(s, s, rop); fmpz_mul(t, s, inv); fmpz_sub(rop, rop, t); fmpz_mod(rop, rop, pow + i); /* Lift inv */ if (i > 0) { fmpz_mul(s, inv, inv); fmpz_mul(t, u + i, s); fmpz_mul_2exp(inv, inv, 1); fmpz_sub(inv, inv, t); fmpz_mod(inv, inv, pow + i); } } fmpz_clear(s); fmpz_clear(t); fmpz_clear(inv); fmpz_clear(pm1); _fmpz_vec_clear(pow, 2 * n); flint_free(a); } }
void acb_rising2_ui_rs(acb_t u, acb_t v, const acb_t x, ulong n, ulong m, long prec) { if (n == 0) { acb_zero(v); acb_one(u); } else if (n == 1) { acb_set(u, x); acb_one(v); } else { long wp; ulong i, j, a, b; acb_ptr xs; acb_t S, T, U, V; fmpz *A, *B; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); if (m == 0) { ulong m1, m2; m1 = 0.6 * pow(wp, 0.4); m2 = n_sqrt(n); m = FLINT_MIN(m1, m2); } m = FLINT_MAX(m, 1); xs = _acb_vec_init(m + 1); A = _fmpz_vec_init(2 * m + 1); B = A + (m + 1); acb_init(S); acb_init(T); acb_init(U); acb_init(V); _acb_vec_set_powers(xs, x, m + 1, wp); for (i = 0; i < n; i += m) { a = i; b = FLINT_MIN(n, a + m); if (a == 0 || b != a + m) { _gamma_rf_bsplit(A, a, b); } else { fmpz tt = m; _fmpz_poly_taylor_shift(A, &tt, m + 1); } _fmpz_poly_derivative(B, A, b - a + 1); acb_set_fmpz(S, A); for (j = 1; j <= b - a; j++) acb_addmul_fmpz(S, xs + j, A + j, wp); acb_set_fmpz(T, B); for (j = 1; j < b - a; j++) acb_addmul_fmpz(T, xs + j, B + j, wp); if (i == 0) { acb_set(U, S); acb_set(V, T); } else { acb_mul(V, V, S, wp); acb_addmul(V, U, T, wp); acb_mul(U, U, S, wp); } } acb_set(u, U); acb_set(v, V); _acb_vec_clear(xs, m + 1); _fmpz_vec_clear(A, 2 * m + 1); acb_clear(S); acb_clear(T); acb_clear(U); acb_clear(V); } }
void fmpz_mod_poly_radix(fmpz_mod_poly_struct **B, const fmpz_mod_poly_t F, const fmpz_mod_poly_radix_t D) { const long lenF = F->length; const long degF = F->length - 1; const long degR = D->degR; const long N = degF / degR; if (N == 0) { fmpz_mod_poly_set(B[0], F); } else { const long k = FLINT_BIT_COUNT(N); /* k := ceil{log{N+1}} */ const long lenG = (1L << k) * degR; /* Padded size */ const long t = (lenG - 1) / degR - N; /* Extra {degR}-blocks */ fmpz *G; /* Padded copy of F */ fmpz *T; /* Additional B[i] */ fmpz **C; /* Enlarged version of B */ fmpz *W; /* Temporary space */ long i; if (lenF < lenG) { G = flint_malloc(lenG * sizeof(fmpz)); for (i = 0; i < lenF; i++) G[i] = F->coeffs[i]; mpn_zero((mp_ptr) G + lenF, lenG - lenF); T = t ? _fmpz_vec_init(t * degR) : NULL; } else /* lenF == lenG */ { G = F->coeffs; T = NULL; } C = flint_malloc((N + 1 + t) * sizeof(fmpz *)); for (i = 0; i <= N; i++) { fmpz_mod_poly_fit_length(B[i], degR); C[i] = B[i]->coeffs; } for (i = 0; i < t; i++) { C[N + 1 + i] = T + i * degR; } W = _fmpz_vec_init(lenG); _fmpz_mod_poly_radix(C, G, D->Rpow, D->Rinv, degR, 0, k-1, W, &(F->p)); _fmpz_vec_clear(W, lenG); for (i = 0; i <= N; i++) { _fmpz_mod_poly_set_length(B[i], degR); _fmpz_mod_poly_normalise(B[i]); } flint_free(C); if (lenF < lenG) { flint_free(G); } if (t) { _fmpz_vec_clear(T, t * degR); } } }
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; }
void acb_rising_ui_rs(acb_t y, const acb_t x, ulong n, ulong m, slong prec) { acb_ptr xs; acb_t t, u, v; ulong i, k, rem; fmpz_t c, h; fmpz *s, *d; slong wp; if (n == 0) { acb_one(y); return; } if (n == 1) { acb_set_round(y, x, prec); return; } wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); acb_init(t); acb_init(u); acb_init(v); fmpz_init(c); fmpz_init(h); if (m == 0) { ulong m1, m2; m1 = 0.2 * pow(2.0 * wp, 0.4); m2 = n_sqrt(n); m = FLINT_MIN(m1, m2); } m = FLINT_MIN(m, n); m = FLINT_MAX(m, 1); xs = _acb_vec_init(m + 1); d = _fmpz_vec_init(m * m); s = _fmpz_vec_init(m + 1); _acb_vec_set_powers(xs, x, m + 1, wp); rising_difference_polynomial(s, d, m); /* tail */ rem = m; while (rem + m <= n) rem += m; acb_one(y); for (k = rem; k < n; k++) { acb_add_ui(t, xs + 1, k, wp); acb_mul(y, y, t, wp); } /* initial rising factorial */ acb_zero(t); for (i = 1; i <= m; i++) acb_addmul_fmpz(t, xs + i, s + i, wp); acb_mul(y, y, t, wp); /* the leading coefficient is always the same */ acb_mul_fmpz(xs + m - 1, xs + m - 1, d + m - 1 + 0, wp); for (k = 0; k + 2 * m <= n; k += m) { for (i = 0; i < m - 1; i++) { fmpz_set_ui(h, k); _fmpz_poly_evaluate_horner_fmpz(c, d + i * m, m - i, h); if (i == 0) acb_add_fmpz(t, t, c, wp); else acb_addmul_fmpz(t, xs + i, c, wp); } acb_add(t, t, xs + m - 1, wp); acb_mul(y, y, t, wp); } acb_set_round(y, y, prec); acb_clear(t); acb_clear(u); acb_clear(v); _acb_vec_clear(xs, m + 1); _fmpz_vec_clear(d, m * m); _fmpz_vec_clear(s, m + 1); fmpz_clear(c); fmpz_clear(h); }
void bernoulli_rev_init(bernoulli_rev_t iter, ulong nmax) { long j; fmpz_t t; arb_t x; arf_t u; int round1, round2; long wp; nmax -= (nmax % 2); iter->n = nmax; iter->alloc = 0; if (nmax < BERNOULLI_REV_MIN) return; iter->prec = wp = bernoulli_global_prec(nmax); iter->max_power = bernoulli_zeta_terms(nmax, iter->prec); iter->alloc = iter->max_power + 1; iter->powers = _fmpz_vec_init(iter->alloc); fmpz_init(iter->pow_error); arb_init(iter->prefactor); arb_init(iter->two_pi_squared); arb_init(x); fmpz_init(t); arf_init(u); /* precompute powers */ for (j = 3; j <= iter->max_power; j += 2) { arb_ui_pow_ui(x, j, nmax, bernoulli_power_prec(j, nmax, wp)); arb_inv(x, x, bernoulli_power_prec(j, nmax, wp)); round1 = arf_get_fmpz_fixed_si(t, arb_midref(x), -wp); fmpz_set(iter->powers + j, t); /* error: the radius, plus two roundings */ arf_set_mag(u, arb_radref(x)); round2 = arf_get_fmpz_fixed_si(t, u, -wp); fmpz_add_ui(t, t, (round1 != 0) + (round2 != 0)); if (fmpz_cmp(iter->pow_error, t) < 0) fmpz_set(iter->pow_error, t); } /* precompute (2pi)^2 and 2*(n!)/(2pi)^n */ arb_fac_ui(iter->prefactor, nmax, wp); arb_mul_2exp_si(iter->prefactor, iter->prefactor, 1); arb_const_pi(x, wp); arb_mul_2exp_si(x, x, 1); arb_mul(iter->two_pi_squared, x, x, wp); arb_pow_ui(x, iter->two_pi_squared, nmax / 2, wp); arb_div(iter->prefactor, iter->prefactor, x, wp); fmpz_clear(t); arb_clear(x); arf_clear(u); }
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); } }
void _fmpq_poly_resultant(fmpz_t rnum, fmpz_t rden, const fmpz *poly1, const fmpz_t den1, long len1, const fmpz *poly2, const fmpz_t den2, long len2) { if (len2 == 1) { if (len1 == 1) { fmpz_one(rnum); fmpz_one(rden); } else if (len1 == 2) { fmpz_set(rnum, poly2); fmpz_set(rden, den2); } else { fmpz_pow_ui(rnum, poly2, len1 - 1); if (fmpz_is_one(den2)) { fmpz_one(rden); } else { fmpz_pow_ui(rden, den2, len1 - 1); } } } else /* len1 >= len2 >= 2 */ { fmpz_t c1, c2; fmpz *prim1, *prim2, *g; long lenG = len2; fmpz_init(c1); fmpz_init(c2); _fmpz_vec_content(c1, poly1, len1); _fmpz_vec_content(c2, poly2, len2); prim1 = _fmpz_vec_init(len1); prim2 = _fmpz_vec_init(len2); g = _fmpz_vec_init(len2); _fmpz_vec_scalar_divexact_fmpz(prim1, poly1, len1, c1); _fmpz_vec_scalar_divexact_fmpz(prim2, poly2, len2, c2); _fmpz_poly_gcd(g, prim1, len1, prim2, len2); FMPZ_VEC_NORM(g, lenG); if (lenG > 1) { fmpz_zero(rnum); fmpz_one(rden); } else /* prim1, prim2 are coprime */ { fmpz_t t; fmpz_init(t); _fmpz_poly_resultant(rnum, prim1, len1, prim2, len2); if (!fmpz_is_one(c1)) { fmpz_pow_ui(t, c1, len2 - 1); fmpz_mul(rnum, rnum, t); } if (!fmpz_is_one(c2)) { fmpz_pow_ui(t, c2, len1 - 1); fmpz_mul(rnum, rnum, t); } if (fmpz_is_one(den1)) { if (fmpz_is_one(den2)) fmpz_one(rden); else fmpz_pow_ui(rden, den2, len1 - 1); } else { if (fmpz_is_one(den2)) fmpz_pow_ui(rden, den1, len2 - 1); else { fmpz_pow_ui(rden, den1, len2 - 1); fmpz_pow_ui(t, den2, len1 - 1); fmpz_mul(rden, rden, t); } } _fmpq_canonicalise(rnum, rden); fmpz_clear(t); } fmpz_clear(c1); fmpz_clear(c2); _fmpz_vec_clear(prim1, len1); _fmpz_vec_clear(prim2, len2); _fmpz_vec_clear(g, len2); } }
#include <stdlib.h> #include <mpir.h> #include "flint.h" #include "fmpz.h" #include "fmpz_vec.h" #include "fmpz_poly.h" #include "fmpz_mod_poly.h" void _fmpz_mod_poly_pow(fmpz *res, const fmpz *poly, long len, ulong e, const fmpz_t p) { ulong bit = ~((~0UL) >> 1); long rlen; long alloc = (long) e * (len - 1) + 1; fmpz *v = _fmpz_vec_init(alloc); fmpz *R, *S, *T; /* Set bits to the bitmask with a 1 one place lower than the msb of e */ while ((bit & e) == 0UL) bit >>= 1; bit >>= 1; /* Trial run without any polynomial arithmetic to determine the parity of the number of swaps; then set R and S accordingly */
int fmpq_mat_inv(fmpq_mat_t B, const fmpq_mat_t A) { long n = A->r; if (n == 0) { return 1; } else if (n == 1) { if (fmpq_is_zero(fmpq_mat_entry(A, 0, 0))) return 0; fmpq_inv(fmpq_mat_entry(B, 0, 0), fmpq_mat_entry(A, 0, 0)); return 1; } else if (n == 2) { fmpq_t d; int success; fmpq_init(d); fmpq_mul(d, fmpq_mat_entry(A, 0, 0), fmpq_mat_entry(A, 1, 1)); fmpq_submul(d, fmpq_mat_entry(A, 0, 1), fmpq_mat_entry(A, 1, 0)); success = !fmpq_is_zero(d); if (success) { fmpq_t t00, t01, t10, t11; fmpq_inv(d, d); fmpq_init(t00); fmpq_init(t01); fmpq_init(t10); fmpq_init(t11); fmpq_mul(t00, fmpq_mat_entry(A, 1, 1), d); fmpq_mul(t01, fmpq_mat_entry(A, 0, 1), d); fmpq_mul(t10, fmpq_mat_entry(A, 1, 0), d); fmpq_mul(t11, fmpq_mat_entry(A, 0, 0), d); fmpq_set(fmpq_mat_entry(B, 0, 0), t00); fmpq_neg(fmpq_mat_entry(B, 0, 1), t01); fmpq_neg(fmpq_mat_entry(B, 1, 0), t10); fmpq_set(fmpq_mat_entry(B, 1, 1), t11); fmpq_clear(t00); fmpq_clear(t01); fmpq_clear(t10); fmpq_clear(t11); } fmpq_clear(d); return success; } else { fmpz_mat_t Aclear, Bclear, I; fmpz * den; long i; int success; fmpz_mat_init(Aclear, n, n); fmpz_mat_init(Bclear, n, n); fmpz_mat_init(I, n, n); den = _fmpz_vec_init(n); fmpq_mat_get_fmpz_mat_rowwise(Aclear, den, A); for (i = 0; i < n; i++) fmpz_set(fmpz_mat_entry(I, i, i), den + i); success = fmpz_mat_solve(Bclear, den, Aclear, I); if (success) fmpq_mat_set_fmpz_mat_div_fmpz(B, Bclear, den); fmpz_mat_clear(Aclear); fmpz_mat_clear(Bclear); fmpz_mat_clear(I); _fmpz_vec_clear(den, A->r); return success; } }
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); }
/* 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 diagfrob(padic_mat_t F, const fmpz *a, long n, long d, long N, const padic_ctx_t ctx, const int verbose) { const fmpz *P = ctx->p; const long p = fmpz_get_si(P); const long delta = diagfrob_delta(n, P); const long N2 = N - n + 2 * (padic_val_fac_ui(n - 1, P) + n + delta); const long M = (p * p * (N2 + n_clog(N2 + 3, p) + 4) + (p - 2)) / (p - 1) - 1; mon_t *B; long *iB, lenB, lo, hi; long i, j, k, *u, *v; long **C, *lenC; fmpz *dinv, **mu; clock_t t0 = 0, t1 = 0; double t; gmc_basis_sets(&B, &iB, &lenB, &lo, &hi, n, d); if (verbose) { printf("Frobenius on the diagonal fibre\n"); printf("N = %ld\n", N); printf("N2 = %ld\n", N2); printf("M = %ld\n", M); } if (verbose) { printf("Basis for H_{dR}^%ld(U)\n", n); gmc_basis_print(B, iB, lenB, n, d); printf("\n"); } C = malloc((n + 1) * sizeof(long *)); C[0] = malloc((n + 1) * lenB * sizeof(long)); for (i = 1; i <= n; i++) { C[i] = C[i-1] + lenB; } lenC = malloc((n + 1) * sizeof(long)); for (i = 0; i <= n; i++) { _congruence_class(C[i], &lenC[i], i, B, lenB, n, d, p); } dinv = _fmpz_vec_init(M/p + 1); mu = malloc((n + 1) * sizeof(fmpz *)); for (i = 0; i <= n; i++) { mu[i] = _fmpz_vec_init(((M + 1 + p - 1) / p) * lenC[i]); } u = malloc((n + 1) * sizeof(long)); v = malloc((n + 1) * sizeof(long)); if (verbose) { printf("Sequence d^{-r}\n"); t0 = clock(); } precompute_dinv(dinv, M, d, p, N2); if (verbose) { t1 = clock(); t = (double) (t1 - t0) / CLOCKS_PER_SEC; printf("T = %f\n", t); } if (verbose) { printf("Sequence mu_{m}\n"); t0 = clock(); } precompute_muex(mu, M, (const long **) C, lenC, a, n, p, N2); /* XXX */ if (verbose) { t1 = clock(); t = (double) (t1 - t0) / CLOCKS_PER_SEC; printf("T = %f\n", t); } if (verbose) { printf("Matrix F\n"); t0 = clock(); } for (i = 0; i < lenB; i++) for (j = 0; j < lenB; j++) { for (k = 0; k <= n; k++) { u[k] = mon_get_exp(B[i], k); v[k] = mon_get_exp(B[j], k); if ((p * (u[k] + 1) - (v[k] + 1)) % d != 0) { break; } } if (k <= n) { fmpz_zero(padic_mat_entry(F, i, j)); } else { long o; entry(padic_mat_entry(F, i, j), &o, u, v, a, dinv, (const fmpz **) mu, M, (const long **) C, lenC, n, d, p, N, N2); if (o != - delta) { fmpz_t w; fmpz_init(w); fmpz_pow_ui(w, P, o + delta); fmpz_mul(padic_mat_entry(F, i, j), padic_mat_entry(F, i, j), w); fmpz_clear(w); } } } padic_mat_val(F) = - delta; _padic_mat_canonicalise(F, ctx); if (verbose) { t1 = clock(); t = (double) (t1 - t0) / CLOCKS_PER_SEC; printf("T = %f\n", t); } _fmpz_vec_clear(dinv, M/p + 1); for (i = 0; i <= n; i++) { _fmpz_vec_clear(mu[i], ((M + 1 + p - 1) / p) * lenC[i]); } free(mu); free(C[0]); free(C); free(lenC); free(u); free(v); free(B); free(iB); }
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; }
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); }
void fmpz_poly_pseudo_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R, ulong * d, const fmpz_poly_t A, const fmpz_poly_t B) { long lenq, lenr; fmpz *q, *r; if (B->length == 0) { printf("Exception: division by zero in fmpz_poly_pseudo_divrem_basecase\n"); abort(); } if (Q == R) { printf("Exception: output arguments Q and R may not be aliased\n"); abort(); } if (A->length < B->length) { fmpz_poly_zero(Q); fmpz_poly_set(R, A); *d = 0; return; } lenq = A->length - B->length + 1; lenr = A->length; if (Q == A || Q == B) q = _fmpz_vec_init(lenq); else { fmpz_poly_fit_length(Q, lenq); q = Q->coeffs; } if (R == B) r = _fmpz_vec_init(lenr); else { fmpz_poly_fit_length(R, lenr); r = R->coeffs; } _fmpz_poly_pseudo_divrem_basecase(q, r, d, A->coeffs, A->length, B->coeffs, B->length); for (lenr = B->length - 2; (lenr >= 0) && !r[lenr]; lenr--) ; lenr++; if (Q == A || Q == B) { _fmpz_vec_clear(Q->coeffs, Q->alloc); Q->coeffs = q; Q->alloc = lenq; Q->length = lenq; } else _fmpz_poly_set_length(Q, lenq); if (R == B) { _fmpz_vec_clear(R->coeffs, R->alloc); R->coeffs = r; R->alloc = A->length; R->length = lenr; } else _fmpz_poly_set_length(R, lenr); }
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)); } } } }
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; }
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; }