void fmpq_poly_scalar_div_mpq(fmpq_poly_t rop, const fmpq_poly_t op, const mpq_t c) { fmpz_t r, s; if (mpq_sgn(c) == 0) { printf("Exception: division by zero in fmpq_poly_scalar_div_mpq\n"); abort(); } if (fmpq_poly_is_zero(op)) { fmpq_poly_zero(rop); return; } fmpq_poly_fit_length(rop, op->length); _fmpq_poly_set_length(rop, op->length); fmpz_init(r); fmpz_init(s); fmpz_set_mpz(r, mpq_numref(c)); fmpz_set_mpz(s, mpq_denref(c)); _fmpq_poly_scalar_div_mpq(rop->coeffs, rop->den, op->coeffs, op->den, op->length, r, s); fmpz_clear(r); fmpz_clear(s); }
void dgsl_rot_mp_clear(dgsl_rot_mp_t *self) { if (!self) return; fmpz_poly_clear(self->c_z); fmpq_poly_clear(self->c); if (!fmpz_poly_is_zero(self->B)) fmpz_poly_clear(self->B); if (!fmpq_poly_is_zero(self->B_inv)) fmpq_poly_clear(self->B_inv); if(self->call == dgsl_rot_mp_call_identity) { if(self->D) { dgs_disc_gauss_mp_clear(self->D[0]); free(self->D); } } if(self->call == dgsl_rot_mp_call_gpv_inlattice) { } if(self->call == dgsl_rot_mp_call_inlattice) { mpfr_clear(self->r_f); fmpq_poly_clear(self->sigma_sqrt); } mpfr_clear(self->sigma); free(self); }
void fmpq_poly_scalar_mul_fmpz(fmpq_poly_t rop, const fmpq_poly_t op, const fmpz_t c) { if (fmpz_is_zero(c) || fmpq_poly_is_zero(op)) { fmpq_poly_zero(rop); return; } fmpq_poly_fit_length(rop, op->length); _fmpq_poly_set_length(rop, op->length); _fmpq_poly_scalar_mul_fmpz(rop->coeffs, rop->den, op->coeffs, op->den, op->length, c); }
void fmpq_poly_scalar_mul_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c) { if (c == 0 || fmpq_poly_is_zero(op)) { fmpq_poly_zero(rop); return; } fmpq_poly_fit_length(rop, op->length); _fmpq_poly_set_length(rop, op->length); _fmpq_poly_scalar_mul_ui(rop->coeffs, rop->den, op->coeffs, op->den, op->length, c); }
void fmpq_poly_scalar_div_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c) { if (c == 0UL) { printf("Exception: division by zero in fmpq_poly_scalar_div_ui\n"); abort(); } if (fmpq_poly_is_zero(op)) { fmpq_poly_zero(rop); return; } fmpq_poly_fit_length(rop, op->length); _fmpq_poly_set_length(rop, op->length); _fmpq_poly_scalar_div_ui(rop->coeffs, rop->den, op->coeffs, op->den, op->length, c); }
void fmpq_poly_div(fmpq_poly_t Q, const fmpq_poly_t poly1, const fmpq_poly_t poly2) { long lenA, lenB, lenQ; if (fmpq_poly_is_zero(poly2)) { printf("Exception: division by zero in fmpq_poly_div\n"); abort(); } if (poly1->length < poly2->length) { fmpq_poly_zero(Q); return; } /* Deal with aliasing */ if (Q == poly1 || Q == poly2) { fmpq_poly_t tempQ; fmpq_poly_init(tempQ); fmpq_poly_div(tempQ, poly1, poly2); fmpq_poly_swap(Q, tempQ); fmpq_poly_clear(tempQ); return; } lenA = poly1->length; lenB = poly2->length; lenQ = lenA - lenB + 1; fmpq_poly_fit_length(Q, lenQ); _fmpq_poly_div(Q->coeffs, Q->den, poly1->coeffs, poly1->den, poly1->length, poly2->coeffs, poly2->den, poly2->length); _fmpq_poly_set_length(Q, lenQ); }
void fmpq_poly_scalar_div_fmpq(fmpq_poly_t rop, const fmpq_poly_t op, const fmpq_t c) { if (fmpq_is_zero(c)) { flint_printf("Exception (fmpq_poly_scalar_div_fmpq). Division by zero.\n"); abort(); } if (fmpq_poly_is_zero(op)) { fmpq_poly_zero(rop); } else { fmpq_poly_fit_length(rop, op->length); _fmpq_poly_set_length(rop, op->length); _fmpq_poly_scalar_div_fmpq(rop->coeffs, rop->den, op->coeffs, op->den, op->length, fmpq_numref(c), fmpq_denref(c)); } }
int main(void) { int cflags = 0, i, result; flint_rand_t state; printf("lcm...."); fflush(stdout); flint_randinit(state); /* Check aliasing of a and c */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_lcm(c, a, b); fmpq_poly_lcm(a, a, b); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(a, c) && !cflags); if (!result) { printf("FAIL:\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); } /* Check aliasing of b and c */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_lcm(c, a, b); fmpq_poly_lcm(b, a, b); cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(b, c) && !cflags); if (!result) { printf("FAIL:\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); } /* Generic case when a, b are most likely co-prime ***********************/ /* Verify commutativity and that c is monic */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_lcm(c, a, b); fmpq_poly_lcm(a, b, a); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(a, c) && !cflags && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); if (!result) { printf("FAIL:\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); } /* Verify that LCM(a, b) GCD(a, b) == a b */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, lcm, gcd; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(lcm); fmpq_poly_init(gcd); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_lcm(lcm, a, b); fmpq_poly_gcd(gcd, a, b); fmpq_poly_mul(lcm, lcm, gcd); fmpq_poly_mul(a, a, b); fmpq_poly_make_monic(a, a); result = fmpq_poly_equal(lcm, a); if (!result) { printf("FAIL:\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(lcm), printf("\n\n"); fmpq_poly_debug(gcd), printf("\n\n"); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(lcm); fmpq_poly_clear(gcd); } /* Case when a, b are not co-prime ***************************************/ /* Verify commutativity and that c is monic */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c, t; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_init(t); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_randtest(t, state, n_randint(state, 50), 20); fmpq_poly_mul(a, a, t); fmpq_poly_mul(b, b, t); fmpq_poly_lcm(c, a, b); fmpq_poly_lcm(a, b, a); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(a, c) && !cflags && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); if (!result) { printf("FAIL:\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); fmpq_poly_clear(t); } /* Verify that LCM(a, b) GCD(a, b) == a b */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, lcm, gcd, t; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(lcm); fmpq_poly_init(gcd); fmpq_poly_init(t); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_randtest(t, state, n_randint(state, 50), 20); fmpq_poly_mul(a, a, t); fmpq_poly_mul(b, b, t); fmpq_poly_lcm(lcm, a, b); fmpq_poly_gcd(gcd, a, b); fmpq_poly_mul(lcm, lcm, gcd); fmpq_poly_mul(a, a, b); fmpq_poly_make_monic(a, a); result = fmpq_poly_equal(lcm, a); if (!result) { printf("FAIL:\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(lcm), printf("\n\n"); fmpq_poly_debug(gcd), printf("\n\n"); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(lcm); fmpq_poly_clear(gcd); fmpq_poly_clear(t); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
dgsl_rot_mp_t *dgsl_rot_mp_init(const long n, const fmpz_poly_t B, mpfr_t sigma, fmpq_poly_t c, const dgsl_alg_t algorithm, const oz_flag_t flags) { assert(mpfr_cmp_ui(sigma, 0) > 0); dgsl_rot_mp_t *self = (dgsl_rot_mp_t*)calloc(1, sizeof(dgsl_rot_mp_t)); if(!self) dgs_die("out of memory"); dgsl_alg_t alg = algorithm; self->n = n; self->prec = mpfr_get_prec(sigma); fmpz_poly_init(self->B); fmpz_poly_set(self->B, B); if(fmpz_poly_length(self->B) > n) dgs_die("polynomial is longer than length n"); else fmpz_poly_realloc(self->B, n); fmpz_poly_init(self->c_z); fmpq_poly_init(self->c); mpfr_init2(self->sigma, self->prec); mpfr_set(self->sigma, sigma, MPFR_RNDN); if (alg == DGSL_DETECT) { if (fmpz_poly_is_one(self->B) && (c && fmpq_poly_is_zero(c))) { alg = DGSL_IDENTITY; } else if (c && fmpq_poly_is_zero(c)) alg = DGSL_INLATTICE; else alg = DGSL_COSET; //TODO: we could test for lattice membership here } size_t tau = 3; if (2*ceil(sqrt(log2((double)n))) > tau) tau = 2*ceil(sqrt(log2((double)n))); switch(alg) { case DGSL_IDENTITY: { self->D = (dgs_disc_gauss_mp_t**)calloc(1, sizeof(dgs_disc_gauss_mp_t*)); mpfr_t c_; mpfr_init2(c_, self->prec); mpfr_set_d(c_, 0.0, MPFR_RNDN); self->D[0] = dgs_disc_gauss_mp_init(self->sigma, c_, tau, DGS_DISC_GAUSS_DEFAULT); self->call = dgsl_rot_mp_call_identity; mpfr_clear(c_); break; } case DGSL_GPV_INLATTICE: { self->D = (dgs_disc_gauss_mp_t**)calloc(n, sizeof(dgs_disc_gauss_mp_t*)); if (c && !fmpq_poly_is_zero(c)) { fmpq_t c_i; fmpq_init(c_i); for(int i=0; i<n; i++) { fmpq_poly_get_coeff_fmpq(c_i, c, i); fmpz_poly_set_coeff_fmpz(self->c_z, i, fmpq_numref(c_i)); } fmpq_clear(c_i); } mpfr_mat_t G; mpfr_mat_init(G, n, n, self->prec); mpfr_mat_set_fmpz_poly(G, B); mpfr_mat_gso(G, MPFR_RNDN); mpfr_t sigma_; mpfr_init2(sigma_, self->prec); mpfr_t norm; mpfr_init2(norm, self->prec); mpfr_t c_; mpfr_init2(c_, self->prec); mpfr_set_d(c_, 0.0, MPFR_RNDN); for(long i=0; i<n; i++) { _mpfr_vec_2norm(norm, G->rows[i], n, MPFR_RNDN); assert(mpfr_cmp_d(norm, 0.0) > 0); mpfr_div(sigma_, self->sigma, norm, MPFR_RNDN); assert(mpfr_cmp_d(sigma_, 0.0) > 0); self->D[i] = dgs_disc_gauss_mp_init(sigma_, c_, tau, DGS_DISC_GAUSS_DEFAULT); } mpfr_clear(sigma_); mpfr_clear(norm); mpfr_clear(c_); mpfr_mat_clear(G); self->call = dgsl_rot_mp_call_gpv_inlattice; break; } case DGSL_INLATTICE: { fmpq_poly_init(self->sigma_sqrt); long r= 2*ceil(sqrt(log(n))); fmpq_poly_t Bq; fmpq_poly_init(Bq); fmpq_poly_set_fmpz_poly(Bq, self->B); fmpq_poly_oz_invert_approx(self->B_inv, Bq, n, self->prec, flags); fmpq_poly_clear(Bq); _dgsl_rot_mp_sqrt_sigma_2(self->sigma_sqrt, self->B, sigma, r, n, self->prec, flags); mpfr_init2(self->r_f, self->prec); mpfr_set_ui(self->r_f, r, MPFR_RNDN); self->call = dgsl_rot_mp_call_inlattice; break; } case DGSL_COSET: dgs_die("not implemented"); default: dgs_die("not implemented"); } return self; }
int main(void) { int i, result; ulong cflags = UWORD(0); FLINT_TEST_INIT(state); flint_printf("derivative...."); fflush(stdout); /* Check aliasing */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpq_poly_t a, b; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_randtest(a, state, n_randint(state, 100), 200); fmpq_poly_derivative(b, a); fmpq_poly_derivative(a, a); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; result = (fmpq_poly_equal(a, b) && !cflags); if (!result) { flint_printf("FAIL:\n"); fmpq_poly_debug(a), flint_printf("\n\n"); fmpq_poly_debug(b), flint_printf("\n\n"); flint_printf("cflags = %wu\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); } /* Check constants have derivative zero */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpq_poly_t a, b; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_randtest(a, state, n_randint(state, 2), 200); fmpq_poly_derivative(b, a); cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; result = fmpq_poly_is_zero(b) && !cflags; if (!result) { flint_printf("FAIL:\n"); fmpq_poly_debug(a), flint_printf("\n\n"); fmpq_poly_debug(b), flint_printf("\n\n"); flint_printf("cflags = %wu\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); } /* Check (f g)' = f' g + f g' */ for (i = 0; i < 1000 * flint_test_multiplier(); i++) { fmpq_poly_t a, b, c, d, lhs, rhs; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_init(d); fmpq_poly_init(lhs); fmpq_poly_init(rhs); fmpq_poly_randtest(a, state, n_randint(state, 100), 200); fmpq_poly_randtest(b, state, n_randint(state, 100), 200); fmpq_poly_mul(lhs, a, b); fmpq_poly_derivative(lhs, lhs); fmpq_poly_derivative(c, a); fmpq_poly_derivative(d, b); fmpq_poly_mul(c, c, b); fmpq_poly_mul(d, a, d); fmpq_poly_add(rhs, c, d); cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; result = fmpq_poly_equal(lhs, rhs) && !cflags; if (!result) { flint_printf("FAIL:\n"); fmpq_poly_debug(a), flint_printf("\n\n"); fmpq_poly_debug(b), flint_printf("\n\n"); flint_printf("cflags = %wu\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); fmpq_poly_clear(d); fmpq_poly_clear(lhs); fmpq_poly_clear(rhs); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
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); }
int main(void) { int cflags = 0, i, result; flint_rand_t state; printf("gcd...."); fflush(stdout); flint_randinit(state); /* Check aliasing of a and c */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_gcd(c, a, b); fmpq_poly_gcd(a, a, b); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(a, c) && !cflags); if (!result) { printf("FAIL (aliasing a, c):\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); } /* Check aliasing of b and c */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_gcd(c, a, b); fmpq_poly_gcd(b, a, b); cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(b, c) && !cflags); if (!result) { printf("FAIL (aliasing b, c):\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); } /* Generic case when a, b are most likely co-prime ***********************/ /* Verify commutativity and that c is monic */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_gcd(c, a, b); fmpq_poly_gcd(a, b, a); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(a, c) && !cflags && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); if (!result) { printf("FAIL (commutativity #1):\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); } /* Verify that GCD(a, b) divides a, b */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c, r1, r2; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_init(r1); fmpq_poly_init(r2); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_gcd(c, a, b); if (!fmpq_poly_is_zero(c)) { fmpq_poly_rem(r1, a, c); fmpq_poly_rem(r2, b, c); } result = fmpq_poly_is_zero(r1) && fmpq_poly_is_zero(r2); if (!result) { printf("FAIL (division #1):\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); fmpq_poly_clear(r1); fmpq_poly_clear(r2); } /* Case when a, b are not co-prime ***************************************/ /* Verify commutativity and that c is monic */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c, t; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_init(t); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_randtest(t, state, n_randint(state, 50), 20); fmpq_poly_mul(a, a, t); fmpq_poly_mul(b, b, t); fmpq_poly_gcd(c, a, b); fmpq_poly_gcd(a, b, a); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; result = (fmpq_poly_equal(a, c) && !cflags && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); if (!result) { printf("FAIL (commutativity #2):\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); fmpq_poly_clear(t); } /* Verify that GCD(a, b) divides a, b */ for (i = 0; i < 1000; i++) { fmpq_poly_t a, b, c, r1, r2, t; fmpq_poly_init(a); fmpq_poly_init(b); fmpq_poly_init(c); fmpq_poly_init(r1); fmpq_poly_init(r2); fmpq_poly_init(t); fmpq_poly_randtest(a, state, n_randint(state, 100), 100); fmpq_poly_randtest(b, state, n_randint(state, 100), 100); fmpq_poly_randtest(t, state, n_randint(state, 50), 20); fmpq_poly_mul(a, a, t); fmpq_poly_mul(b, b, t); fmpq_poly_gcd(c, a, b); if (!fmpq_poly_is_zero(c)) { fmpq_poly_rem(r1, a, c); fmpq_poly_rem(r2, b, c); } result = fmpq_poly_is_zero(r1) && fmpq_poly_is_zero(r2); if (!result) { printf("FAIL (division #2):\n"); fmpq_poly_debug(a), printf("\n\n"); fmpq_poly_debug(b), printf("\n\n"); fmpq_poly_debug(c), printf("\n\n"); printf("cflags = %d\n\n", cflags); abort(); } fmpq_poly_clear(a); fmpq_poly_clear(b); fmpq_poly_clear(c); fmpq_poly_clear(r1); fmpq_poly_clear(r2); fmpq_poly_clear(t); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }