void acb_digamma(acb_t y, const acb_t x, long prec) { int reflect; long r, n, wp; acb_t t, u, v; wp = prec + FLINT_BIT_COUNT(prec); acb_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 1, wp); acb_init(t); acb_init(u); acb_init(v); /* psi(x) = psi((1-x)+r) - h(1-x,r) - pi*cot(pi*x) */ if (reflect) { acb_sub_ui(t, x, 1, wp); acb_neg(t, t); acb_cot_pi(v, x, wp); arb_const_pi(acb_realref(u), wp); acb_mul_arb(v, v, acb_realref(u), wp); acb_rising2_ui(y, u, t, r, wp); acb_div(u, u, y, wp); acb_add(v, v, u, wp); acb_add_ui(t, t, r, wp); acb_gamma_stirling_eval(u, t, n, 1, wp); acb_sub(y, u, v, wp); } else { acb_add_ui(t, x, r, wp); acb_gamma_stirling_eval(u, t, n, 1, wp); acb_rising2_ui(y, t, x, r, wp); acb_div(t, t, y, wp); acb_sub(y, u, t, prec); } acb_clear(t); acb_clear(u); acb_clear(v); }
int main() { slong iter; flint_rand_t state; flint_printf("rising2_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000; iter++) { acb_t a, u, v, u2, v2; fmpz *f; acb_ptr g; ulong n; slong i, prec; acb_init(a); acb_init(u); acb_init(v); acb_init(u2); acb_init(v2); acb_randtest(a, state, 1 + n_randint(state, 4000), 10); acb_randtest(u, state, 1 + n_randint(state, 4000), 10); acb_randtest(v, state, 1 + n_randint(state, 4000), 10); n = n_randint(state, 120); f = _fmpz_vec_init(n + 1); g = _acb_vec_init(n + 1); prec = 2 + n_randint(state, 4000); acb_rising2_ui(u, v, a, n, prec); arith_stirling_number_1u_vec(f, n, n + 1); for (i = 0; i <= n; i++) acb_set_fmpz(g + i, f + i); _acb_poly_evaluate(u2, g, n + 1, a, prec); _acb_poly_derivative(g, g, n + 1, prec); _acb_poly_evaluate(v2, g, n, a, prec); if (!acb_overlaps(u, u2) || !acb_overlaps(v, v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n", n); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); acb_printd(u2, 15); flint_printf("\n\n"); flint_printf("v = "); acb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); acb_printd(v2, 15); flint_printf("\n\n"); abort(); } acb_set(u2, a); acb_rising2_ui(u2, v, u2, n, prec); if (!acb_equal(u2, u)) { flint_printf("FAIL: aliasing 1\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); acb_printd(u2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); abort(); } acb_set(v2, a); acb_rising2_ui(u, v2, v2, n, prec); if (!acb_equal(v2, v)) { flint_printf("FAIL: aliasing 2\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("v = "); acb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); acb_printd(v2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); abort(); } acb_clear(a); acb_clear(u); acb_clear(v); acb_clear(u2); acb_clear(v2); _fmpz_vec_clear(f, n + 1); _acb_vec_clear(g, n + 1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }