/* compose by poly2 = a*x^n + c, no aliasing; n >= 1 */ void _arb_poly_compose_axnc(arb_ptr res, arb_srcptr poly1, slong len1, const arb_t c, const arb_t a, slong n, slong prec) { slong i; _arb_vec_set_round(res, poly1, len1, prec); /* shift by c (c = 0 case will be fast) */ _arb_poly_taylor_shift(res, c, len1, prec); /* multiply by powers of a */ if (!arb_is_one(a)) { if (arb_equal_si(a, -1)) { for (i = 1; i < len1; i += 2) arb_neg(res + i, res + i); } else if (len1 == 2) { arb_mul(res + 1, res + 1, a, prec); } else { arb_t t; arb_init(t); arb_set(t, a); for (i = 1; i < len1; i++) { arb_mul(res + i, res + i, t, prec); if (i + 1 < len1) arb_mul(t, t, a, prec); } arb_clear(t); } } /* stretch */ for (i = len1 - 1; i >= 1 && n > 1; i--) { arb_swap(res + i * n, res + i); _arb_vec_zero(res + (i - 1) * n + 1, n - 1); } }
void _arb_poly_taylor_shift_horner(arb_ptr poly, const arb_t c, slong n, slong prec) { slong i, j; if (arb_is_one(c)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) arb_add(poly + j, poly + j, poly + j + 1, prec); } else if (arb_equal_si(c, -1)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) arb_sub(poly + j, poly + j, poly + j + 1, prec); } else if (!arb_is_zero(c)) { for (i = n - 2; i >= 0; i--) for (j = i; j < n - 1; j++) arb_addmul(poly + j, poly + j + 1, c, prec); } }
int main() { slong iter; FLINT_TEST_INIT(state); { ulong k; arb_t a,b; arf_t c,d; fmpq_poly_t p; arb_init(a); arb_init(b); arf_init(c); arf_init(d); /* x+1 */ fmpq_poly_init(p); fmpq_poly_set_coeff_si(p, 0, 1); fmpq_poly_set_coeff_si(p, 1, 1); for (iter = 0; iter < 5000; iter++) { k = n_randint(state, 10000); arb_set_si(a, k); fmpq_poly_evaluate_arb(b, p, a, 30 + n_randint(state, 100)); if (!arb_equal_si(b, k + 1)) { printf("FAIL (fmpq_poly_evaluate_arb):\n"); printf("a = "); arb_print(a); printf("\n"); printf("b = "); arb_print(b); printf("\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); abort(); } arf_set_si(c, k); fmpq_poly_evaluate_arf(d, p, c, 30 + n_randint(state, 100)); if (!arf_equal_si(d, k + 1)) { printf("FAIL (fmpq_poly_evaluate_arf):\n"); printf("c = "); arf_print(c); printf("\n"); printf("d = "); arf_print(d); printf("\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); abort(); } } /* x^2 */ fmpq_poly_zero(p); fmpq_poly_set_coeff_si(p, 2, 1); for (iter = 0; iter < 1000; iter++) { k = n_randint(state, 10000); arb_set_si(a, k); fmpq_poly_evaluate_arb(b, p, a, 30 + n_randint(state, 100)); if (!arb_equal_si(b, k * k)) { printf("Error (test_fmpq_poly_evaluate_arb):\n"); printf("a = "); arb_print(a); printf("\n"); printf("b = "); arb_print(b); printf("\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); abort(); } arf_set_si(c, k); fmpq_poly_evaluate_arf(d, p, c, 30 + n_randint(state, 100)); if (!arf_equal_si(d, k * k)) { printf("Error (test_fmpq_poly_evaluate_arf):\n"); printf("c = "); arf_print(c); printf("\n"); printf("d = "); arf_print(d); printf("\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); abort(); } } fmpq_poly_clear(p); arb_clear(a); arb_clear(b); arf_clear(c); arf_clear(d); } /* check evaluate_arb agains exact evaluate_fmpq */ for (iter = 0; iter < 1000; iter++) { fmpq_poly_t p; fmpq_t x,y; arb_t a,b; fmpq_poly_init(p); fmpq_init(x); fmpq_init(y); arb_init(a); arb_init(b); fmpq_poly_randtest(p, state, 1 + n_randint(state,100), 10); fmpq_randtest(x, state, 10); arb_set_fmpq(a, x, 64); fmpq_poly_evaluate_fmpq(y, p, x); fmpq_poly_evaluate_arb(b, p, a, 60); if (!arb_contains_fmpq(b, y)) { printf("FAIL (y not in b):\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); printf("x = "); fmpq_print(x); printf("\n"); printf("y = "); fmpq_print(y); printf("\n"); printf("a = "); arb_print(a); printf("\n"); printf("b = "); arb_print(b); printf("\n"); abort(); } fmpq_poly_evaluate_arb(a, p, a, 60); if (!arb_equal(a,b)) { printf("FAIL (a not equal b):\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); printf("x = "); fmpq_print(x); printf("\n"); printf("y = "); fmpq_print(y); printf("\n"); printf("a = "); arb_print(a); printf("\n"); printf("b = "); arb_print(b); printf("\n"); abort(); } fmpq_poly_clear(p); fmpq_clear(x); fmpq_clear(y); arb_clear(a); arb_clear(b); } /* test aliasing */ for (iter = 0; iter < 1000; iter++) { fmpq_poly_t p; arb_t a,b; arf_t c,d; fmpq_poly_init(p); arb_init(a); arb_init(b); arf_init(c); arf_init(d); fmpq_poly_randtest(p, state, 1 + n_randint(state,100), 10); arb_randtest(a, state, 60, 10); arb_randtest(b, state, 60, 10); arf_randtest(c, state, 60, 10); arf_randtest(d, state, 60, 10); fmpq_poly_evaluate_arb(b, p, a, 60); fmpq_poly_evaluate_arb(a, p, a, 60); if (!arb_equal(a, b)) { printf("FAIL (a not equal b):\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); printf("a = "); arb_print(a); printf("\n"); printf("b = "); arb_print(b); printf("\n"); abort(); } fmpq_poly_evaluate_arf(d, p, c, 60); fmpq_poly_evaluate_arf(c, p, c, 60); if (!arf_equal(c, d)) { printf("FAIL (c not equal d):\n"); printf("p = "); fmpq_poly_print(p); printf("\n"); printf("c = "); arf_print(c); printf("\n"); printf("d = "); arf_print(d); printf("\n"); } fmpq_poly_clear(p); arb_clear(a); arb_clear(b); arf_clear(c); arf_clear(d); } FLINT_TEST_CLEANUP(state); return 0; }