slong fmpr_rsqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd) { slong r; if (fmpr_is_special(x)) { if (fmpr_is_zero(x)) fmpr_pos_inf(y); else if (fmpr_is_pos_inf(x)) fmpr_zero(y); else fmpr_nan(y); return FMPR_RESULT_EXACT; } if (fmpr_sgn(x) < 0) { fmpr_nan(y); return FMPR_RESULT_EXACT; } /* special case: 4^n */ if (fmpz_is_one(fmpr_manref(x)) && fmpz_is_even(fmpr_expref(x))) { r = fmpr_set_round(y, x, prec, rnd); fmpz_tdiv_q_2exp(fmpr_expref(y), fmpr_expref(y), 1); fmpz_neg(fmpr_expref(y), fmpr_expref(y)); return r; } { fmpr_t t; fmpz_t e; fmpr_init(t); fmpz_init(e); fmpz_neg(e, fmpr_expref(x)); if (fmpz_is_odd(e)) fmpz_add_ui(e, e, 1); fmpr_mul_2exp_fmpz(t, x, e); CALL_MPFR_FUNC(r, mpfr_rec_sqrt, y, t, prec, rnd); fmpz_tdiv_q_2exp(e, e, 1); fmpr_mul_2exp_fmpz(y, y, e); fmpr_clear(t); fmpz_clear(e); return r; } }
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 arb_fib_fmpz(arb_t f, const fmpz_t n, slong prec) { arb_t t, u; slong wp, sign, i; if (fmpz_sgn(n) < 0) { fmpz_t m; fmpz_init(m); fmpz_neg(m, n); arb_fib_fmpz(f, m, prec); if (fmpz_is_even(m)) arb_neg(f, f); fmpz_clear(m); return; } if (fmpz_cmp_ui(n, 4) <= 0) { ulong x = fmpz_get_ui(n); arb_set_ui(f, x - (x > 1)); return; } wp = ARF_PREC_ADD(prec, 3 * fmpz_bits(n)); arb_init(u); arb_init(t); arb_set_ui(f, UWORD(1)); arb_set_ui(u, UWORD(1)); sign = -1; for (i = fmpz_flog_ui(n, UWORD(2)) - 1; i > 0; i--) { arb_mul(t, f, f, wp); arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul(f, f, f, wp); arb_mul_2exp_si(f, f, 1); arb_submul_ui(f, t, 3, wp); arb_sub_si(f, f, 2 * sign, wp); arb_mul_ui(u, t, 5, wp); arb_add_si(u, u, 2 * sign, wp); sign = 1; if (fmpz_tstbit(n, i)) { arb_set(t, f); arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul_2exp_si(t, t, 1); arb_add(u, f, t, wp); sign = -1; } } if (fmpz_tstbit(n, 0)) { arb_add(f, f, u, wp); arb_mul_2exp_si(f, f, -1); arb_mul(f, f, u, wp); arb_sub_si(f, f, sign, prec); } else { arb_mul(f, f, u, prec); } arb_clear(u); arb_clear(t); }
int main(void) { int iter; FLINT_TEST_INIT(state); flint_printf("factor...."); fflush(stdout); /* Default algorithm */ for (iter = 0; iter < flint_test_multiplier(); iter++) { int result = 1; TEMPLATE(T, poly_t) pol1, poly, quot, rem, product; TEMPLATE(T, poly_factor_t) res; TEMPLATE(T, ctx_t) ctx; TEMPLATE(T, t) lead; slong length, num, i, j; ulong exp[5], prod1; TEMPLATE(T, ctx_randtest) (ctx, state); TEMPLATE(T, poly_init) (pol1, ctx); TEMPLATE(T, poly_init) (poly, ctx); TEMPLATE(T, poly_init) (quot, ctx); TEMPLATE(T, poly_init) (rem, ctx); TEMPLATE(T, poly_zero) (pol1, ctx); TEMPLATE(T, poly_one) (pol1, ctx); length = n_randint(state, 4) + 2; TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx); exp[0] = n_randint(state, 3) + 1; prod1 = exp[0]; for (i = 0; i < exp[0]; i++) TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); num = n_randint(state, 3) + 1; for (i = 1; i < num; i++) { do { length = n_randint(state, 3) + 2; TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx); TEMPLATE(T, poly_divrem) (quot, rem, pol1, poly, ctx); } while ((poly->length < 2) || (rem->length == 0)); exp[i] = n_randint(state, 3) + 1; prod1 *= exp[i]; for (j = 0; j < exp[i]; j++) TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); } TEMPLATE(T, poly_factor_init) (res, ctx); TEMPLATE(T, init) (lead, ctx); switch (n_randint(state, 4)) { case 0: TEMPLATE(T, poly_factor) (res, lead, pol1, ctx); break; case 1: TEMPLATE(T, poly_factor_with_berlekamp) (res, lead, pol1, ctx); break; case 2: if (fmpz_is_even(TEMPLATE(T, ctx_prime) (ctx))) TEMPLATE(T, poly_factor) (res, lead, pol1, ctx); else TEMPLATE(T, poly_factor_with_cantor_zassenhaus) (res, lead, pol1, ctx); break; case 3: TEMPLATE(T, poly_factor_with_kaltofen_shoup) (res, lead, pol1, ctx); break; } fflush(stdout); result &= (res->num == num); if (!result) { flint_printf("Error: number of factors incorrect, %wd, %wd\n", res->num, num); abort(); } TEMPLATE(T, poly_init) (product, ctx); TEMPLATE(T, poly_one) (product, ctx); for (i = 0; i < res->num; i++) for (j = 0; j < res->exp[i]; j++) TEMPLATE(T, poly_mul) (product, product, res->poly + i, ctx); TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (product, product, lead, ctx); result &= TEMPLATE(T, poly_equal) (pol1, product, ctx); if (!result) { flint_printf ("Error: product of factors does not equal original polynomial\n"); TEMPLATE(T, poly_print_pretty) (pol1, "x", ctx); flint_printf("\n"); TEMPLATE(T, poly_print_pretty) (product, "x", ctx); flint_printf("\n"); abort(); } TEMPLATE(T, poly_clear) (product, ctx); TEMPLATE(T, poly_clear) (quot, ctx); TEMPLATE(T, poly_clear) (rem, ctx); TEMPLATE(T, poly_clear) (pol1, ctx); TEMPLATE(T, poly_clear) (poly, ctx); TEMPLATE(T, poly_factor_clear) (res, ctx); TEMPLATE(T, clear) (lead, ctx); TEMPLATE(T, ctx_clear) (ctx); } /* Test deflation trick */ for (iter = 0; iter < flint_test_multiplier(); iter++) { TEMPLATE(T, poly_t) pol1, poly, quot, rem; TEMPLATE(T, poly_factor_t) res, res2; TEMPLATE(T, ctx_t) ctx; TEMPLATE(T, t) lead; slong length, num, i, j; slong exp[5], prod1; ulong inflation; int found; TEMPLATE(T, ctx_randtest) (ctx, state); TEMPLATE(T, poly_init) (pol1, ctx); TEMPLATE(T, poly_init) (poly, ctx); TEMPLATE(T, poly_init) (quot, ctx); TEMPLATE(T, poly_init) (rem, ctx); TEMPLATE(T, poly_zero) (pol1, ctx); TEMPLATE(T, poly_one) (pol1, ctx); inflation = n_randint(state, 7) + 1; length = n_randint(state, 4) + 2; TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx); TEMPLATE(T, poly_inflate) (poly, poly, inflation, ctx); exp[0] = n_randint(state, 6) + 1; prod1 = exp[0]; for (i = 0; i < exp[0]; i++) TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); num = n_randint(state, 5) + 1; for (i = 1; i < num; i++) { do { length = n_randint(state, 6) + 2; TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx); TEMPLATE(T, poly_divrem) (quot, rem, pol1, poly, ctx); } while ((poly->length < 2) || (rem->length == 0)); exp[i] = n_randint(state, 6) + 1; prod1 *= exp[i]; TEMPLATE(T, poly_inflate) (poly, poly, inflation, ctx); for (j = 0; j < exp[i]; j++) TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); } TEMPLATE(T, poly_factor_init) (res, ctx); TEMPLATE(T, poly_factor_init) (res2, ctx); TEMPLATE(T, init) (lead, ctx); switch (n_randint(state, 4)) { case 0: TEMPLATE(T, poly_factor) (res, lead, pol1, ctx); break; case 1: TEMPLATE(T, poly_factor_with_berlekamp) (res, lead, pol1, ctx); break; case 2: TEMPLATE(T, poly_factor_with_cantor_zassenhaus) (res, lead, pol1, ctx); break; case 3: TEMPLATE(T, poly_factor_with_kaltofen_shoup) (res, lead, pol1, ctx); break; } TEMPLATE(T, poly_factor_cantor_zassenhaus) (res2, pol1, ctx); if (res->num != res2->num) { flint_printf("FAIL: different number of factors found\n"); abort(); } for (i = 0; i < res->num; i++) { found = 0; for (j = 0; j < res2->num; j++) { if (TEMPLATE(T, poly_equal) (res->poly + i, res2->poly + j, ctx) && res->exp[i] == res2->exp[j]) { found = 1; break; } } if (!found) { flint_printf("FAIL: factor not found\n"); abort(); } } TEMPLATE(T, poly_clear) (quot, ctx); TEMPLATE(T, poly_clear) (rem, ctx); TEMPLATE(T, poly_clear) (pol1, ctx); TEMPLATE(T, poly_clear) (poly, ctx); TEMPLATE(T, poly_factor_clear) (res, ctx); TEMPLATE(T, poly_factor_clear) (res2, ctx); TEMPLATE(T, clear) (lead, ctx); TEMPLATE(T, ctx_clear) (ctx); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }