void acb_cot(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_cot(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_coth(acb_imagref(r), acb_imagref(z), prec); arb_neg(acb_imagref(r), acb_imagref(r)); arb_zero(acb_realref(r)); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos(r, t, z, prec + 4); acb_div(r, t, r, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_mul_onei(t, t); acb_exp(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_mul_onei(r, r); } else { acb_div_onei(t, t); acb_exp(t, t, prec + 4); acb_sub_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_div_onei(r, r); } } acb_clear(t); } }
int main() { slong iter; flint_rand_t state; flint_printf("coth...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { arb_t x, y, a, b, c, d; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; arb_init(x); arb_init(y); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_randtest_precise(x, state, 1 + n_randint(state, 1000), 100); arb_randtest_precise(y, state, 1 + n_randint(state, 1000), 100); arb_coth(a, x, prec1); arb_coth(b, x, prec2); /* check consistency */ if (!arb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); abort(); } /* check coth(x+y) = (1 + coth(x) coth(y)) / (coth(x) + coth(y)) */ arb_add(b, x, y, prec1); arb_coth(b, b, prec1); arb_coth(c, y, prec1); arb_add(d, a, c, prec1); arb_mul(c, a, c, prec1); arb_add_ui(c, c, 1, prec1); arb_div(d, c, d, prec1); if (!arb_overlaps(b, d)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); flint_printf("y = "); arb_print(y); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); abort(); } arb_coth(x, x, prec1); if (!arb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("x = "); arb_print(x); flint_printf("\n\n"); abort(); } arb_clear(x); arb_clear(y); arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }