int main(void) { int i, result; flint_rand_t state; ulong cflags = 0UL; printf("rem...."); fflush(stdout); flint_randinit(state); /* Check aliasing of r and a */ for (i = 0; i < 2000; i++) { fmpq_poly_t a, b, r; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(r); fmpq_poly_randtest(a, state, n_randint(state, 50), 200); fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); fmpq_poly_rem(r, a, b); fmpq_poly_rem(a, a, b); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(r) ? 0 : 2; result = (fmpq_poly_equal(r, a) && !cflags); if (!result) { printf("FAIL:\n"); printf("r = "), fmpq_poly_debug(r), printf("\n\n"); printf("a = "), fmpq_poly_debug(a), printf("\n\n"); printf("b = "), fmpq_poly_debug(b), printf("\n\n"); printf("cflags = %lu\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(r); } /* Check aliasing of r and b */ for (i = 0; i < 2000; i++) { fmpq_poly_t a, b, r; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(r); fmpq_poly_randtest(a, state, n_randint(state, 50), 200); fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); fmpq_poly_rem(r, a, b); fmpq_poly_rem(b, a, b); cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; cflags |= fmpq_poly_is_canonical(r) ? 0 : 2; result = (fmpq_poly_equal(r, b) && !cflags); if (!result) { printf("FAIL:\n"); printf("r = "), fmpq_poly_debug(r), printf("\n\n"); printf("a = "), fmpq_poly_debug(a), printf("\n\n"); printf("b = "), fmpq_poly_debug(b), printf("\n\n"); printf("cflags = %lu\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(r); } /* Compare with divrem */ for (i = 0; i < 2000; i++) { fmpq_poly_t a, b, q, r, r2; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(q); fmpq_poly_init(r); fmpq_poly_init(r2); fmpq_poly_randtest(a, state, n_randint(state, 50), 200); fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); fmpq_poly_divrem(q, r, a, b); fmpq_poly_rem(r2, a, b); cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; cflags |= fmpq_poly_is_canonical(r2) ? 0 : 2; result = (fmpq_poly_equal(r, r2) && !cflags); if (!result) { printf("FAIL:\n"); printf("a = "), fmpq_poly_debug(a), printf("\n\n"); printf("b = "), fmpq_poly_debug(b), printf("\n\n"); printf("q = "), fmpq_poly_debug(q), printf("\n\n"); printf("r = "), fmpq_poly_debug(r), printf("\n\n"); printf("r2 = "), fmpq_poly_debug(r2), printf("\n\n"); printf("cflags = %lu\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(q); fmpq_poly_clear(r); fmpq_poly_clear(r2); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
int main() { long iter; flint_rand_t state; printf("divrem...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 100000; iter++) { long m, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t A, B, Q, R; arb_poly_t a, b, q, r; qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 200); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 20); n = 1 + n_randint(state, 20); fmpq_poly_init(A); fmpq_poly_init(B); fmpq_poly_init(Q); fmpq_poly_init(R); arb_poly_init(a); arb_poly_init(b); arb_poly_init(q); arb_poly_init(r); fmpq_poly_randtest(A, state, m, qbits1); fmpq_poly_randtest_not_zero(B, state, n, qbits2); fmpq_poly_divrem(Q, R, A, B); arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_divrem(q, r, a, b, rbits3); if (!arb_poly_contains_fmpq_poly(q, Q) || !arb_poly_contains_fmpq_poly(r, R)) { printf("FAIL\n\n"); printf("A = "); fmpq_poly_print(A); printf("\n\n"); printf("B = "); fmpq_poly_print(B); printf("\n\n"); printf("Q = "); fmpq_poly_print(Q); printf("\n\n"); printf("R = "); fmpq_poly_print(R); printf("\n\n"); printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); printf("q = "); arb_poly_printd(q, 15); printf("\n\n"); printf("r = "); arb_poly_printd(r, 15); printf("\n\n"); abort(); } arb_poly_divrem(a, r, a, b, rbits3); if (!arb_poly_equal(a, q)) { printf("FAIL (aliasing q, a)\n\n"); } arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_divrem(b, r, a, b, rbits3); if (!arb_poly_equal(b, q)) { printf("FAIL (aliasing q, b)\n\n"); abort(); } arb_poly_set_fmpq_poly(b, B, rbits2); arb_poly_divrem(q, a, a, b, rbits3); if (!arb_poly_equal(a, r)) { printf("FAIL (aliasing r, a)\n\n"); abort(); } arb_poly_set_fmpq_poly(a, A, rbits1); arb_poly_divrem(q, b, a, b, rbits3); if (!arb_poly_equal(b, r)) { printf("FAIL (aliasing r, b)\n\n"); abort(); } fmpq_poly_clear(A); fmpq_poly_clear(B); fmpq_poly_clear(Q); fmpq_poly_clear(R); arb_poly_clear(a); arb_poly_clear(b); arb_poly_clear(q); arb_poly_clear(r); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void fmpq_poly_divrem(fmpq_poly_t Q, fmpq_poly_t R, const fmpq_poly_t poly1, const fmpq_poly_t poly2) { slong lenA, lenB, lenQ, lenR; if (fmpq_poly_is_zero(poly2)) { flint_printf("Exception (fmpq_poly_divrem). Division by zero.\n"); abort(); } if (Q == R) { flint_printf("Exception (fmpq_poly_divrem). Output arguments aliased.\n"); abort(); } /* Deal with the various other cases of aliasing. */ if (R == poly1 || R == poly2) { if (Q == poly1 || Q == poly2) { fmpq_poly_t tempQ, tempR; fmpq_poly_init(tempQ); fmpq_poly_init(tempR); fmpq_poly_divrem(tempQ, tempR, poly1, poly2); fmpq_poly_swap(Q, tempQ); fmpq_poly_swap(R, tempR); fmpq_poly_clear(tempQ); fmpq_poly_clear(tempR); return; } else { fmpq_poly_t tempR; fmpq_poly_init(tempR); fmpq_poly_divrem(Q, tempR, poly1, poly2); fmpq_poly_swap(R, tempR); fmpq_poly_clear(tempR); return; } } else { if (Q == poly1 || Q == poly2) { fmpq_poly_t tempQ; fmpq_poly_init(tempQ); fmpq_poly_divrem(tempQ, R, poly1, poly2); fmpq_poly_swap(Q, tempQ); fmpq_poly_clear(tempQ); return; } } if (poly1->length < poly2->length) { fmpq_poly_set(R, poly1); fmpq_poly_zero(Q); return; } lenA = poly1->length; lenB = poly2->length; lenQ = lenA - lenB + 1; lenR = lenB - 1; fmpq_poly_fit_length(Q, lenQ); fmpq_poly_fit_length(R, lenA); /* XXX: Need at least that much space */ _fmpq_poly_divrem(Q->coeffs, Q->den, R->coeffs, R->den, poly1->coeffs, poly1->den, poly1->length, poly2->coeffs, poly2->den, poly2->length, NULL); _fmpq_poly_set_length(Q, lenQ); _fmpq_poly_set_length(R, lenR); _fmpq_poly_normalise(R); }