int main() { slong iter; flint_rand_t state; flint_printf("div...."); fflush(stdout); flint_randinit(state); /* test aliasing of c and a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_div(c, a, b, prec); acb_div(a, a, b, prec); if (!acb_equal(a, c)) { flint_printf("FAIL: aliasing c, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing of c and b */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_div(c, a, b, prec); acb_div(b, a, b, prec); if (!acb_equal(b, c)) { flint_printf("FAIL: aliasing c, b\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test aliasing a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_div(c, a, a, prec); acb_div(d, a, b, prec); if (!acb_overlaps(c, d)) { flint_printf("FAIL: aliasing a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("d = "); acb_print(d); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); } /* test aliasing a, a, a */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec; acb_init(a); acb_init(b); acb_init(c); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); prec = 2 + n_randint(state, 200); acb_set(b, a); acb_div(c, a, b, prec); acb_div(a, a, a, prec); if (!acb_overlaps(a, c)) { flint_printf("FAIL: aliasing a, a, a\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } /* test (a+b)/c = a/c + b/c */ for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++) { acb_t a, b, c, d, e, f; acb_init(a); acb_init(b); acb_init(c); acb_init(d); acb_init(e); acb_init(f); acb_randtest(a, state, 1 + n_randint(state, 200), 10); acb_randtest(b, state, 1 + n_randint(state, 200), 10); acb_randtest(c, state, 1 + n_randint(state, 200), 10); acb_add(d, a, b, 2 + n_randint(state, 200)); acb_div(e, d, c, 2 + n_randint(state, 200)); acb_div(d, a, c, 2 + n_randint(state, 200)); acb_div(f, b, c, 2 + n_randint(state, 200)); acb_add(f, d, f, 2 + n_randint(state, 200)); if (!acb_overlaps(e, f)) { flint_printf("FAIL: (a+b)/c = a/c + b/c\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); flint_printf("e = "); acb_print(e); flint_printf("\n\n"); flint_printf("f = "); acb_print(f); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(d); acb_clear(e); acb_clear(f); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void fmpz_poly_complex_roots_squarefree(const fmpz_poly_t poly, slong initial_prec, slong target_prec, slong print_digits) { slong i, j, prec, deg, deg_deflated, isolated, maxiter, deflation; acb_poly_t cpoly, cpoly_deflated; fmpz_poly_t poly_deflated; acb_ptr roots, roots_deflated; int removed_zero; if (fmpz_poly_degree(poly) < 1) return; fmpz_poly_init(poly_deflated); acb_poly_init(cpoly); acb_poly_init(cpoly_deflated); /* try to write poly as poly_deflated(x^deflation), possibly multiplied by x */ removed_zero = fmpz_is_zero(poly->coeffs); if (removed_zero) fmpz_poly_shift_right(poly_deflated, poly, 1); else fmpz_poly_set(poly_deflated, poly); deflation = fmpz_poly_deflation(poly_deflated); fmpz_poly_deflate(poly_deflated, poly_deflated, deflation); deg = fmpz_poly_degree(poly); deg_deflated = fmpz_poly_degree(poly_deflated); flint_printf("searching for %wd roots, %wd deflated\n", deg, deg_deflated); roots = _acb_vec_init(deg); roots_deflated = _acb_vec_init(deg_deflated); for (prec = initial_prec; ; prec *= 2) { acb_poly_set_fmpz_poly(cpoly_deflated, poly_deflated, prec); maxiter = FLINT_MIN(FLINT_MAX(deg_deflated, 32), prec); TIMEIT_ONCE_START flint_printf("prec=%wd: ", prec); isolated = acb_poly_find_roots(roots_deflated, cpoly_deflated, prec == initial_prec ? NULL : roots_deflated, maxiter, prec); flint_printf("%wd isolated roots | ", isolated); TIMEIT_ONCE_STOP if (isolated == deg_deflated) { if (!check_accuracy(roots_deflated, deg_deflated, target_prec)) continue; if (deflation == 1) { _acb_vec_set(roots, roots_deflated, deg_deflated); } else /* compute all nth roots */ { acb_t w, w2; acb_init(w); acb_init(w2); acb_unit_root(w, deflation, prec); acb_unit_root(w2, 2 * deflation, prec); for (i = 0; i < deg_deflated; i++) { if (arf_sgn(arb_midref(acb_realref(roots_deflated + i))) > 0) { acb_root_ui(roots + i * deflation, roots_deflated + i, deflation, prec); } else { acb_neg(roots + i * deflation, roots_deflated + i); acb_root_ui(roots + i * deflation, roots + i * deflation, deflation, prec); acb_mul(roots + i * deflation, roots + i * deflation, w2, prec); } for (j = 1; j < deflation; j++) { acb_mul(roots + i * deflation + j, roots + i * deflation + j - 1, w, prec); } } acb_clear(w); acb_clear(w2); } /* by assumption that poly is squarefree, must be just one */ if (removed_zero) acb_zero(roots + deg_deflated * deflation); if (!check_accuracy(roots, deg, target_prec)) continue; acb_poly_set_fmpz_poly(cpoly, poly, prec); if (!acb_poly_validate_real_roots(roots, cpoly, prec)) continue; for (i = 0; i < deg; i++) { if (arb_contains_zero(acb_imagref(roots + i))) arb_zero(acb_imagref(roots + i)); } flint_printf("done!\n"); break; } } if (print_digits != 0) { _acb_vec_sort_pretty(roots, deg); for (i = 0; i < deg; i++) { acb_printn(roots + i, print_digits, 0); flint_printf("\n"); } } fmpz_poly_clear(poly_deflated); acb_poly_clear(cpoly); acb_poly_clear(cpoly_deflated); _acb_vec_clear(roots, deg); _acb_vec_clear(roots_deflated, deg_deflated); }
int main() { slong iter; flint_rand_t state; flint_printf("u_asymp...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { acb_t a, b, a2, b2, z, U1, U2, t, u, M1, M2, am; acb_struct bm[2]; ulong n1, n2; slong prec0, prec1, prec2; acb_init(a); acb_init(b); acb_init(a2); acb_init(b2); acb_init(z); acb_init(U1); acb_init(U2); acb_init(t); acb_init(u); acb_init(M1); acb_init(M2); acb_init(am); acb_init(bm); acb_init(bm + 1); if (n_randint(state, 4) == 0) { n1 = n_randint(state, 200); n2 = n_randint(state, 200); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); } else { n1 = n_randint(state, 40); n2 = n_randint(state, 40); prec0 = 2 + n_randint(state, 300); prec1 = 2 + n_randint(state, 300); prec2 = 2 + n_randint(state, 300); } acb_randtest_param(a, state, prec0, 1 + n_randint(state, 20)); if (n_randint(state, 4) == 0) acb_add_ui(b, a, n_randint(state, 10), prec0); else acb_randtest_param(b, state, prec0, 1 + n_randint(state, 20)); acb_randtest(z, state, prec0, 1 + n_randint(state, 20)); /* Test Kummer's transformation */ acb_sub(a2, a, b, prec0); acb_add_ui(a2, a2, 1, prec0); acb_sub_ui(b2, b, 2, prec0); acb_neg(b2, b2); acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1); acb_hypgeom_u_asymp(U2, a2, b2, z, n2, prec2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (Kummer transformation)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); abort(); } /* Check contiguous relation (b-a-1)U(a,b-1,z) + z U(a,b+1,z) + (1-b-z) U(a,b,z) = 0 */ acb_one(t); acb_sub(t, t, b, prec0); acb_sub(t, t, z, prec0); acb_mul(u, U1, t, prec1); acb_add_ui(b2, b, 1, prec0); acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2); acb_addmul(u, U2, z, prec1); acb_sub_ui(b2, b, 1, prec0); acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2); acb_sub(t, b, a, prec0); acb_sub_ui(t, t, 1, prec0); acb_mul(t, t, U2, prec0); acb_add(t, t, u, prec0); if (!acb_contains_zero(t)) { flint_printf("FAIL (contiguous relation)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("t = "); acb_printd(t, 100); flint_printf("\n"); abort(); } /* Test U(a,b,z) = gamma(1-b)/gamma(a-b+1) M(a,b,z) + gamma(b-1)/gamma(a) z^(1-b) M(a-b+1,2-b,z) */ acb_set(am, a); acb_set(bm, b); acb_one(bm + 1); acb_hypgeom_pfq_direct(M1, am, 1, bm, 2, z, n2, prec2); acb_sub(am, a, b, prec2); acb_add_ui(am, am, 1, prec2); acb_sub_ui(bm, b, 2, prec2); acb_neg(bm, bm); acb_one(bm + 1); acb_hypgeom_pfq_direct(M2, am, 1, bm, 2, z, n2, prec2); acb_sub(am, a, b, prec2); acb_add_ui(am, am, 1, prec2); acb_rgamma(am, am, prec2); acb_mul(M1, M1, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_neg(am, am); acb_gamma(am, am, prec2); acb_mul(M1, M1, am, prec2); acb_rgamma(am, a, prec2); acb_mul(M2, M2, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_gamma(am, am, prec2); acb_mul(M2, M2, am, prec2); acb_sub_ui(am, b, 1, prec2); acb_neg(am, am); acb_pow(am, z, am, prec2); acb_mul(M2, M2, am, prec2); acb_add(U2, M1, M2, prec2); acb_pow(am, z, a, prec2); acb_mul(U2, U2, am, prec2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (U in terms of M)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); abort(); } /* Test special value: b = a+1 */ acb_add_ui(b, a, 1, prec0); acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1); acb_one(U2); if (!acb_overlaps(U1, U2)) { flint_printf("FAIL (special value)\n"); flint_printf("iter = %wd\n", iter); flint_printf("a = "); acb_printd(a, 50); flint_printf("\n"); flint_printf("b = "); acb_printd(b, 50); flint_printf("\n"); flint_printf("z = "); acb_printd(z, 50); flint_printf("\n"); flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2); flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n"); flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(a2); acb_clear(b2); acb_clear(z); acb_clear(U1); acb_clear(U2); acb_clear(t); acb_clear(u); acb_clear(M1); acb_clear(M2); acb_clear(am); acb_clear(bm); acb_clear(bm + 1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_hypgeom_2f1_transform_nolimit(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec) { acb_t ba, ca, cb, cab, ac1, bc1, ab1, ba1, w, t, u, v, s; if (acb_contains_zero(z) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (arb_contains_si(acb_realref(z), 1) && arb_contains_zero(acb_imagref(z))) { acb_indeterminate(res); return; } if (!regularized) { acb_init(t); acb_gamma(t, c, prec); acb_hypgeom_2f1_transform_nolimit(res, a, b, c, z, 1, which, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } acb_init(ba); acb_init(ca); acb_init(cb); acb_init(cab); acb_init(ac1); acb_init(bc1); acb_init(ab1); acb_init(ba1); acb_init(w); acb_init(t); acb_init(u); acb_init(v); acb_init(s); acb_add_si(s, z, -1, prec); /* s = 1 - z */ acb_neg(s, s); acb_sub(ba, b, a, prec); /* ba = b - a */ acb_sub(ca, c, a, prec); /* ca = c - a */ acb_sub(cb, c, b, prec); /* cb = c - b */ acb_sub(cab, ca, b, prec); /* cab = c - a - b */ acb_add_si(ac1, ca, -1, prec); acb_neg(ac1, ac1); /* ac1 = a - c + 1 */ acb_add_si(bc1, cb, -1, prec); acb_neg(bc1, bc1); /* bc1 = b - c + 1 */ acb_add_si(ab1, ba, -1, prec); acb_neg(ab1, ab1); /* ab1 = a - b + 1 */ acb_add_si(ba1, ba, 1, prec); /* ba1 = b - a + 1 */ /* t = left term, u = right term (DLMF 15.8.1 - 15.8.5) */ if (which == 2) { acb_inv(w, z, prec); /* w = 1/z */ acb_hypgeom_2f1_direct(t, a, ac1, ab1, w, 1, prec); acb_hypgeom_2f1_direct(u, b, bc1, ba1, w, 1, prec); } else if (which == 3) { acb_inv(w, s, prec); /* w = 1/(1-z) */ acb_hypgeom_2f1_direct(t, a, cb, ab1, w, 1, prec); acb_hypgeom_2f1_direct(u, b, ca, ba1, w, 1, prec); } else if (which == 4) { acb_set(w, s); /* w = 1-z */ acb_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_direct(t, a, b, v, w, 1, prec); acb_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_hypgeom_2f1_direct(u, ca, cb, v, w, 1, prec); } else if (which == 5) { acb_inv(w, z, prec); /* w = 1-1/z */ acb_neg(w, w); acb_add_si(w, w, 1, prec); acb_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_direct(t, a, ac1, v, w, 1, prec); acb_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_add_si(u, a, -1, prec); /* u = 1-a */ acb_neg(u, u); acb_hypgeom_2f1_direct(u, ca, u, v, w, 1, prec); } else { flint_printf("invalid transformation!\n"); abort(); } /* gamma factors */ acb_rgamma(v, a, prec); acb_mul(u, u, v, prec); acb_rgamma(v, ca, prec); acb_mul(t, t, v, prec); acb_rgamma(v, b, prec); if (which == 2 || which == 3) acb_mul(t, t, v, prec); else acb_mul(u, u, v, prec); acb_rgamma(v, cb, prec); if (which == 2 || which == 3) acb_mul(u, u, v, prec); else acb_mul(t, t, v, prec); if (which == 2 || which == 3) { if (which == 2) acb_neg(s, z); /* -z, otherwise 1-z since before */ acb_neg(v, a); acb_pow(v, s, v, prec); acb_mul(t, t, v, prec); acb_neg(v, b); acb_pow(v, s, v, prec); acb_mul(u, u, v, prec); } else { acb_pow(v, s, cab, prec); acb_mul(u, u, v, prec); if (which == 5) { acb_neg(v, a); acb_pow(v, z, v, prec); acb_mul(t, t, v, prec); acb_neg(v, ca); acb_pow(v, z, v, prec); acb_mul(u, u, v, prec); } } acb_sub(t, t, u, prec); if (which == 2 || which == 3) acb_sin_pi(v, ba, prec); else acb_sin_pi(v, cab, prec); acb_div(t, t, v, prec); acb_const_pi(v, prec); acb_mul(t, t, v, prec); acb_set(res, t); acb_clear(ba); acb_clear(ca); acb_clear(cb); acb_clear(cab); acb_clear(ac1); acb_clear(bc1); acb_clear(ab1); acb_clear(ba1); acb_clear(w); acb_clear(t); acb_clear(u); acb_clear(v); acb_clear(s); }
void acb_hypgeom_2f1_transform(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec) { if (which == 1) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); acb_sub_ui(t, z, 1, prec); /* t = z-1 */ acb_div(u, z, t, prec); /* u = z/(z-1) */ acb_neg(t, t); acb_neg(v, a); acb_pow(t, t, v, prec); /* t = (1-z)^-a */ acb_sub(v, c, b, prec); /* v = c-b */ /* We cannot use regularized=1 directly, since if c is a nonnegative integer, the transformation formula reads (lhs) * 0 = (rhs) * 0. */ acb_hypgeom_2f1_direct(u, a, v, c, u, 1, prec); if (!regularized) { acb_gamma(v, c, prec); acb_mul(u, u, v, prec); } acb_mul(res, u, t, prec); acb_clear(t); acb_clear(u); acb_clear(v); } else { acb_t d; acb_init(d); if (which == 2 || which == 3) { acb_sub(d, b, a, prec); } else { acb_sub(d, c, a, prec); acb_sub(d, d, b, prec); } if (acb_is_int(d)) acb_hypgeom_2f1_transform_limit(res, a, b, c, z, regularized, which, prec); else acb_hypgeom_2f1_transform_nolimit(res, a, b, c, z, regularized, which, prec); acb_clear(d); } if (!acb_is_finite(res)) acb_indeterminate(res); }
int main() { long iter; flint_rand_t state; flint_printf("0f1...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000; iter++) { acb_t a, z, w1, w2; long prec1, prec2; int regularized, ebits; acb_init(a); acb_init(z); acb_init(w1); acb_init(w2); prec1 = 2 + n_randint(state, 700); prec2 = 2 + n_randint(state, 700); if (n_randint(state, 5) == 0) ebits = 100; else ebits = 10; acb_randtest_param(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest_param(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits)); regularized = n_randint(state, 2); switch (n_randint(state, 3)) { case 0: acb_hypgeom_0f1_asymp(w1, a, z, regularized, prec1); break; case 1: acb_hypgeom_0f1_direct(w1, a, z, regularized, prec1); break; default: acb_hypgeom_0f1(w1, a, z, regularized, prec1); } switch (n_randint(state, 3)) { case 0: acb_hypgeom_0f1_asymp(w2, a, z, regularized, prec2); break; case 1: acb_hypgeom_0f1_direct(w2, a, z, regularized, prec2); break; default: acb_hypgeom_0f1(w2, a, z, regularized, prec2); } if (!acb_overlaps(w1, w2)) { flint_printf("FAIL: consistency\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(z); acb_clear(w1); acb_clear(w2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { long iter; flint_rand_t state; printf("lgamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { acb_t a, b, c; long prec1, prec2; prec1 = 2 + n_randint(state, 500); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_lgamma(b, a, prec1); if (n_randint(state, 4) == 0) { acb_randtest(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10)); acb_add(a, a, c, prec1); acb_sub(a, a, c, prec1); } acb_lgamma(c, a, prec2); if (!acb_overlaps(b, c)) { printf("FAIL: overlap\n\n"); printf("a = "); acb_print(a); printf("\n\n"); printf("b = "); acb_print(b); printf("\n\n"); printf("c = "); acb_print(c); printf("\n\n"); abort(); } /* check lgamma(z+1) = lgamma(z) + log(z) */ acb_log(c, a, prec1); acb_add(b, b, c, prec1); acb_add_ui(c, a, 1, prec1); acb_lgamma(c, c, prec1); if (!acb_overlaps(b, c)) { printf("FAIL: functional equation\n\n"); printf("a = "); acb_print(a); printf("\n\n"); printf("b = "); acb_print(b); printf("\n\n"); printf("c = "); acb_print(c); printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
/* note: z should be exact here */ void acb_lambertw_main(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { acb_t w, t, oldw, ew; mag_t err; slong i, wp, accuracy, ebits, kbits, mbits, wp_initial, extraprec; int have_ew; acb_init(t); acb_init(w); acb_init(oldw); acb_init(ew); mag_init(err); /* We need higher precision for large k, large exponents, or very close to the branch point at -1/e. todo: we should be recomputing ez1 to higher precision when close... */ acb_get_mag(err, z); if (fmpz_is_zero(k) && mag_cmp_2exp_si(err, 0) < 0) ebits = 0; else ebits = fmpz_bits(MAG_EXPREF(err)); if (fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z))) || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z)))) { acb_get_mag(err, ez1); mbits = -MAG_EXP(err); mbits = FLINT_MAX(mbits, 0); mbits = FLINT_MIN(mbits, prec); } else { mbits = 0; } kbits = fmpz_bits(k); extraprec = FLINT_MAX(ebits, kbits); extraprec = FLINT_MAX(extraprec, mbits); wp = wp_initial = 40 + extraprec; accuracy = acb_lambertw_initial(w, z, ez1, k, wp_initial); mag_zero(arb_radref(acb_realref(w))); mag_zero(arb_radref(acb_imagref(w))); /* We should be able to compute e^w for the final certification during the Halley iteration. */ have_ew = 0; for (i = 0; i < 5 + FLINT_BIT_COUNT(prec + extraprec); i++) { /* todo: should we restart? */ if (!acb_is_finite(w)) break; wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10); wp = FLINT_MAX(wp, 40); wp += extraprec; acb_set(oldw, w); acb_lambertw_halley_step(t, ew, z, w, wp); /* estimate the error (conservatively) */ acb_sub(w, w, t, wp); acb_get_mag(err, w); acb_set(w, t); acb_add_error_mag(t, err); accuracy = acb_rel_accuracy_bits(t); if (accuracy > 2 * extraprec) accuracy *= 2.9; /* less conservatively */ accuracy = FLINT_MIN(accuracy, wp); accuracy = FLINT_MAX(accuracy, 0); if (accuracy > prec + extraprec) { /* e^w = e^oldw * e^(w-oldw) */ acb_sub(t, w, oldw, wp); acb_exp(t, t, wp); acb_mul(ew, ew, t, wp); have_ew = 1; break; } mag_zero(arb_radref(acb_realref(w))); mag_zero(arb_radref(acb_imagref(w))); } wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10); wp = FLINT_MAX(wp, 40); wp += extraprec; if (acb_lambertw_check_branch(w, k, wp)) { acb_t u, r, eu1; mag_t err, rad; acb_init(u); acb_init(r); acb_init(eu1); mag_init(err); mag_init(rad); if (have_ew) acb_set(t, ew); else acb_exp(t, w, wp); /* t = w e^w */ acb_mul(t, t, w, wp); acb_sub(r, t, z, wp); /* Bound W' on the straight line path between t and z */ acb_union(u, t, z, wp); arb_const_e(acb_realref(eu1), wp); arb_zero(acb_imagref(eu1)); acb_mul(eu1, eu1, u, wp); acb_add_ui(eu1, eu1, 1, wp); if (acb_lambertw_branch_crossing(u, eu1, k)) { mag_inf(err); } else { acb_lambertw_bound_deriv(err, u, eu1, k); acb_get_mag(rad, r); mag_mul(err, err, rad); } acb_add_error_mag(w, err); acb_set(res, w); acb_clear(u); acb_clear(r); acb_clear(eu1); mag_clear(err); mag_clear(rad); } else { acb_indeterminate(res); } acb_clear(t); acb_clear(w); acb_clear(oldw); acb_clear(ew); mag_clear(err); }
void _acb_lambertw(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec) { slong goal, ebits, ebits2, ls, lt; const fmpz * expo; /* Estimated accuracy goal. */ /* todo: account for exponent bits and bits in k. */ goal = acb_rel_accuracy_bits(z); goal = FLINT_MAX(goal, 10); goal = FLINT_MIN(goal, prec); /* Handle tiny z directly. For k >= 2, |c_k| <= 4^k / 16. */ if (fmpz_is_zero(k) && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -goal / 2) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -goal / 2) < 0) { mag_t err; mag_init(err); acb_get_mag(err, z); mag_mul_2exp_si(err, err, 2); acb_set(res, z); acb_submul(res, res, res, prec); mag_geom_series(err, err, 3); mag_mul_2exp_si(err, err, -4); acb_add_error_mag(res, err); mag_clear(err); return; } if (arf_cmpabs(arb_midref(acb_realref(z)), arb_midref(acb_imagref(z))) >= 0) expo = ARF_EXPREF(arb_midref(acb_realref(z))); else expo = ARF_EXPREF(arb_midref(acb_imagref(z))); ebits = fmpz_bits(expo); /* ebits ~= log2(|log(z) + 2 pi i k|) */ /* ebits2 ~= log2(log(log(z))) */ ebits = FLINT_MAX(ebits, fmpz_bits(k)); ebits = FLINT_MAX(ebits, 1) - 1; ebits2 = FLINT_BIT_COUNT(ebits); ebits2 = FLINT_MAX(ebits2, 1) - 1; /* We gain accuracy from the exponent when W ~ log - log log */ if (fmpz_sgn(expo) > 0 || (fmpz_sgn(expo) < 0 && !fmpz_is_zero(k))) { goal += ebits - ebits2; goal = FLINT_MAX(goal, 10); goal = FLINT_MIN(goal, prec); /* The asymptotic series with truncation L, M gives us about t - max(2+lt+L*(2+ls), M*(2+lt)) bits of accuracy where ls = -ebits, lt = ebits2 - ebits. */ ls = 2 - ebits; lt = 2 + ebits2 - ebits; if (ebits - FLINT_MAX(lt + 1*ls, 1*lt) > goal) { acb_lambertw_asymp(res, z, k, 1, 1, goal); acb_set_round(res, res, prec); return; } else if (ebits - FLINT_MAX(lt + 3*ls, 5*lt) > goal) { acb_lambertw_asymp(res, z, k, 3, 5, goal); acb_set_round(res, res, prec); return; } } /* Extremely close to the branch point at -1/e, use the series expansion directly. */ if (acb_lambertw_try_near_branch_point(res, z, ez1, k, flags, goal)) { acb_set_round(res, res, prec); return; } /* compute union of both sides */ if (acb_lambertw_branch_crossing(z, ez1, k)) { acb_t za, zb, eza1, ezb1; fmpz_t kk; acb_init(za); acb_init(zb); acb_init(eza1); acb_init(ezb1); fmpz_init(kk); fmpz_neg(kk, k); acb_set(za, z); acb_conj(zb, z); arb_nonnegative_part(acb_imagref(za), acb_imagref(za)); arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb)); acb_set(eza1, ez1); acb_conj(ezb1, ez1); arb_nonnegative_part(acb_imagref(eza1), acb_imagref(eza1)); arb_nonnegative_part(acb_imagref(ezb1), acb_imagref(ezb1)); /* Check series expansion again, because now there is no crossing. */ if (!acb_lambertw_try_near_branch_point(res, za, eza1, k, flags, goal)) acb_lambertw_cleared_cut_fix_small(za, za, eza1, k, flags, goal); if (!acb_lambertw_try_near_branch_point(res, zb, ezb1, kk, flags, goal)) acb_lambertw_cleared_cut_fix_small(zb, zb, ezb1, kk, flags, goal); acb_conj(zb, zb); acb_union(res, za, zb, prec); acb_clear(za); acb_clear(zb); acb_clear(eza1); acb_clear(ezb1); fmpz_clear(kk); } else { acb_lambertw_cleared_cut_fix_small(res, z, ez1, k, flags, goal); acb_set_round(res, res, prec); } }
void acb_hypgeom_legendre_q(acb_t res, const acb_t n, const acb_t m, const acb_t z, int type, slong prec) { if (type == 0) { /* http://functions.wolfram.com/07.11.26.0033.01 */ /* todo: simplify the gamma quotients and the sqrt pi factor... */ acb_t a, b, c, z2, mn, nm, t, u; acb_init(a); acb_init(b); acb_init(c); acb_init(z2); acb_init(mn); acb_init(nm); acb_init(t); acb_init(u); acb_add(mn, m, n, prec); /* mn = m + n */ acb_sub(nm, n, m, prec); /* nm = n - m */ acb_mul(z2, z, z, prec); /* z2 = z^2 */ /* t = 2F1((1-m-n)/2, (n-m)/2+1, 3/2, z^2) */ acb_sub_ui(a, mn, 1, prec); acb_neg(a, a); acb_mul_2exp_si(a, a, -1); acb_mul_2exp_si(b, nm, -1); acb_add_ui(b, b, 1, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_hypgeom_2f1(t, a, b, c, z2, 0, prec); /* u = 2F1(-(m+n)/2, (n-m+1)/2, 1/2, z^2) */ acb_neg(a, mn); acb_mul_2exp_si(a, a, -1); acb_add_ui(b, nm, 1, prec); acb_mul_2exp_si(b, b, -1); acb_one(c); acb_mul_2exp_si(c, c, -1); acb_hypgeom_2f1(u, a, b, c, z2, 0, prec); /* a = cospi((m+n)/2) gamma((m+n)/2+1) rgamma((n-m+1)/2) z */ /* b = sinpi((m+n)/2) gamma((m+n+1)/2) rgamma((n-m)/2+1) / 2 */ acb_mul_2exp_si(a, mn, -1); acb_sin_cos_pi(b, a, a, prec); acb_mul_2exp_si(c, mn, -1); acb_add_ui(c, c, 1, prec); acb_gamma(c, c, prec); acb_mul(a, a, c, prec); acb_add_ui(c, nm, 1, prec); acb_mul_2exp_si(c, c, -1); acb_rgamma(c, c, prec); acb_mul(a, a, c, prec); acb_mul(a, a, z, prec); acb_add_ui(c, mn, 1, prec); acb_mul_2exp_si(c, c, -1); acb_gamma(c, c, prec); acb_mul(b, b, c, prec); acb_mul_2exp_si(c, nm, -1); acb_add_ui(c, c, 1, prec); acb_rgamma(c, c, prec); acb_mul(b, b, c, prec); acb_mul_2exp_si(b, b, -1); /* at - bu */ acb_mul(t, t, a, prec); acb_mul(u, u, b, prec); acb_sub(t, t, u, prec); /* prefactor sqrt(pi) 2^m (1-z^2)^(-m/2) */ if (!acb_is_zero(m)) { acb_sub_ui(u, z2, 1, prec); acb_neg(u, u); acb_neg(c, m); acb_mul_2exp_si(c, c, -1); acb_pow(u, u, c, prec); acb_set_ui(c, 2); acb_pow(c, c, m, prec); acb_mul(u, u, c, prec); acb_mul(t, t, u, prec); } arb_const_sqrt_pi(acb_realref(u), prec); acb_mul_arb(t, t, acb_realref(u), prec); acb_set(res, t); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z2); acb_clear(mn); acb_clear(nm); acb_clear(t); acb_clear(u); } else if (type == 1) { if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -2) < 0 && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -2) < 0) || !_acb_hypgeom_legendre_q_single_valid(z)) { _acb_hypgeom_legendre_q_double(res, n, m, z, prec); } else { _acb_hypgeom_legendre_q_single(res, n, m, z, prec); } } else { flint_printf("unsupported 'type' %d for legendre q\n", type); abort(); } }
void _acb_hypgeom_legendre_q_double(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); if (acb_is_int(m)) { acb_sub_ui(t, z, 1, prec); acb_mul_2exp_si(u, m, -1); acb_pow(v, t, u, prec); acb_neg(t, t); acb_neg(u, u); acb_pow(t, t, u, prec); acb_mul(t, t, v, prec); acb_hypgeom_legendre_q(u, n, m, z, 0, prec); acb_mul(t, t, u, prec); acb_mul_2exp_si(u, m, -1); if (!acb_is_int(u)) acb_neg(t, t); acb_sub_ui(u, z, 1, prec); acb_sqrt(u, u, prec); acb_sub_ui(v, z, 1, prec); acb_neg(v, v); acb_rsqrt(v, v, prec); acb_mul(u, u, v, prec); acb_hypgeom_legendre_p(v, n, m, z, 1, prec); acb_mul(u, u, v, prec); acb_const_pi(v, prec); acb_mul(u, u, v, prec); acb_mul_2exp_si(u, u, -1); acb_sub(res, t, u, prec); } else { acb_sub(t, n, m, prec); acb_add_ui(t, t, 1, prec); acb_mul_2exp_si(u, m, 1); acb_rising(t, t, u, prec); acb_neg(u, m); acb_hypgeom_legendre_p(u, n, u, z, 1, prec); acb_mul(t, t, u, prec); acb_hypgeom_legendre_p(u, n, m, z, 1, prec); acb_sub(t, u, t, prec); acb_exp_pi_i(u, m, prec); acb_mul(t, t, u, prec); acb_sin_pi(u, m, prec); acb_div(t, t, u, prec); acb_const_pi(u, prec); acb_mul(t, t, u, prec); acb_mul_2exp_si(t, t, -1); acb_set(res, t); } acb_clear(t); acb_clear(u); acb_clear(v); }
void _acb_hypgeom_legendre_q_single(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t a, b, c, z2, t, u; acb_init(a); acb_init(b); acb_init(c); acb_init(z2); acb_init(t); acb_init(u); /* invalid in (-1,0) */ if (!_acb_hypgeom_legendre_q_single_valid(z)) { acb_indeterminate(res); return; } acb_pow_si(z2, z, -2, prec); /* z2 = 1/z^2 */ /* t = 2F1r((m+n+1)/2, (m+n)/2+1, n+3/2, 1/z^2) */ acb_add(b, m, n, prec); acb_add_ui(a, b, 1, prec); acb_mul_2exp_si(a, a, -1); acb_mul_2exp_si(b, b, -1); acb_add_ui(b, b, 1, prec); acb_set_ui(c, 3); acb_mul_2exp_si(c, c, -1); acb_add(c, c, n, prec); acb_hypgeom_2f1(t, a, b, c, z2, 1, prec); /* prefactor sqrt(pi) 2^-n (z+1)^(m/2) (z-1)^(m/2) exp(i pi m) */ /* (1/2) gamma(m+n+1) z^(-m-n-1) */ if (!acb_is_zero(m)) { acb_add_ui(z2, z, 1, prec); acb_mul_2exp_si(c, m, -1); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_sub_ui(z2, z, 1, prec); acb_mul_2exp_si(c, m, -1); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_exp_pi_i(z2, m, prec); acb_mul(t, t, z2, prec); } acb_set_ui(z2, 2); acb_neg(c, n); acb_pow(z2, z2, c, prec); acb_mul(t, t, z2, prec); acb_add(c, m, n, prec); acb_add_ui(c, c, 1, prec); acb_gamma(z2, c, prec); acb_mul(t, t, z2, prec); acb_neg(c, c); acb_pow(z2, z, c, prec); acb_mul(t, t, z2, prec); acb_mul_2exp_si(t, t, -1); arb_const_sqrt_pi(acb_realref(u), prec); acb_mul_arb(t, t, acb_realref(u), prec); acb_set(res, t); acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z2); acb_clear(t); acb_clear(u); }
int main() { slong iter; flint_rand_t state; flint_printf("find_roots...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_poly_t A; acb_poly_t B; acb_poly_t C; acb_t t; acb_ptr roots; slong i, deg, isolated; slong prec = 10 + n_randint(state, 400); acb_init(t); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); do { acb_poly_randtest(A, state, 2 + n_randint(state, 15), prec, 5); } while (A->length == 0); deg = A->length - 1; roots = _acb_vec_init(deg); isolated = acb_poly_find_roots(roots, A, NULL, 0, prec); if (isolated == deg) { acb_poly_fit_length(B, 1); acb_set(B->coeffs, A->coeffs + deg); _acb_poly_set_length(B, 1); for (i = 0; i < deg; i++) { acb_poly_fit_length(C, 2); acb_one(C->coeffs + 1); acb_neg(C->coeffs + 0, roots + i); _acb_poly_set_length(C, 2); acb_poly_mul(B, B, C, prec); } if (!acb_poly_contains(B, A)) { flint_printf("FAIL: product does not equal polynomial\n"); acb_poly_printd(A, 15); flint_printf("\n\n"); acb_poly_printd(B, 15); flint_printf("\n\n"); flint_abort(); } } for (i = 0; i < isolated; i++) { acb_poly_evaluate(t, A, roots + i, prec); if (!acb_contains_zero(t)) { flint_printf("FAIL: poly(root) does not contain zero\n"); acb_poly_printd(A, 15); flint_printf("\n\n"); acb_printd(roots + i, 15); flint_printf("\n\n"); acb_printd(t, 15); flint_printf("\n\n"); flint_abort(); } } _acb_vec_clear(roots, deg); acb_clear(t); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("elliptic_p...."); fflush(stdout); flint_randinit(state); /* check test values */ for (iter = 0; iter < 100; iter++) { slong i; acb_t z, tau, p1, p2; acb_init(z); acb_init(tau); acb_init(p1); acb_init(p2); for (i = 0; i < NUM_TESTS; i++) { acb_set_dddd(z, testdata[i][0], 0.0, testdata[i][1], 0.0); acb_set_dddd(tau, testdata[i][2], 0.0, testdata[i][3], 0.0); acb_set_dddd(p2, testdata[i][4], EPS, testdata[i][5], EPS); acb_modular_elliptic_p(p1, z, tau, 2 + n_randint(state, 1000)); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (test value)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); abort(); } } acb_clear(z); acb_clear(tau); acb_clear(p1); acb_clear(p2); } /* Test periods */ for (iter = 0; iter < 2000; iter++) { acb_t tau, z1, z2, p1, p2; slong m, n, e0, prec0, prec1, prec2; acb_init(tau); acb_init(z1); acb_init(z2); acb_init(p1); acb_init(p2); e0 = 1 + n_randint(state, 10); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest(tau, state, prec0, e0); if (arf_sgn(arb_midref(acb_imagref(tau))) < 0) acb_neg(tau, tau); acb_randtest(z1, state, prec0, e0); acb_randtest(p1, state, prec0, e0); acb_randtest(p2, state, prec0, e0); /* z2 = z1 + m + n*tau */ m = n_randint(state, 10); n = n_randint(state, 10); acb_add_ui(z2, z1, m, prec0); acb_addmul_ui(z2, tau, n, prec0); acb_modular_elliptic_p(p1, z1, tau, prec1); acb_modular_elliptic_p(p2, z2, tau, prec2); if (!acb_overlaps(p1, p2)) { flint_printf("FAIL (overlap)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n"); abort(); } acb_modular_elliptic_p(z1, z1, tau, prec1); if (!acb_overlaps(z1, p1)) { flint_printf("FAIL (aliasing)\n"); flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n"); flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n"); flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n"); abort(); } acb_clear(tau); acb_clear(z1); acb_clear(z2); acb_clear(p1); acb_clear(p2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { long iter; flint_rand_t state; printf("delta...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { acb_t tau, z1, z2; long e0, prec0, prec1, prec2; acb_init(tau); acb_init(z1); acb_init(z2); e0 = 1 + n_randint(state, 10); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_randtest(tau, state, prec0, e0); acb_randtest(z1, state, prec0, e0); acb_randtest(z2, state, prec0, e0); /* compare with eta */ acb_modular_delta(z1, tau, prec1); acb_modular_eta(z2, tau, prec2); acb_pow_ui(z2, z2, 24, prec2); if (!acb_overlaps(z1, z2)) { printf("FAIL (overlap)\n"); printf("tau = "); acb_printd(tau, 15); printf("\n\n"); printf("z1 = "); acb_printd(z1, 15); printf("\n\n"); printf("z2 = "); acb_printd(z2, 15); printf("\n\n"); abort(); } acb_modular_delta(tau, tau, prec1); if (!acb_overlaps(z1, tau)) { printf("FAIL (aliasing)\n"); printf("tau = "); acb_printd(tau, 15); printf("\n\n"); printf("z1 = "); acb_printd(z1, 15); printf("\n\n"); printf("z2 = "); acb_printd(z2, 15); printf("\n\n"); abort(); } acb_clear(tau); acb_clear(z1); acb_clear(z2); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void acb_lambertw_middle(acb_t res, const acb_t z, slong prec) { fmpz_t k; if (acb_contains_zero(z)) { acb_indeterminate(res); return; } fmpz_init(k); fmpz_set_si(k, -1); if (arb_is_positive(acb_imagref(z))) { acb_lambertw(res, z, k, 0, prec); } else if (arb_is_negative(acb_imagref(z))) { acb_conj(res, z); acb_lambertw(res, res, k, 0, prec); acb_conj(res, res); } else if (arb_is_negative(acb_realref(z))) { if (arb_is_nonnegative(acb_imagref(z))) { acb_lambertw(res, z, k, 0, prec); } else if (arb_is_negative(acb_imagref(z))) { acb_conj(res, z); acb_lambertw(res, res, k, 0, prec); acb_conj(res, res); } else { acb_t za, zb; acb_init(za); acb_init(zb); acb_set(za, z); acb_conj(zb, z); arb_nonnegative_part(acb_imagref(za), acb_imagref(za)); arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb)); acb_lambertw(za, za, k, 0, prec); acb_lambertw(zb, zb, k, 0, prec); acb_conj(zb, zb); acb_union(res, za, zb, prec); acb_clear(za); acb_clear(zb); } } else /* re is positive */ { if (arb_is_positive(acb_imagref(z))) { acb_lambertw(res, z, k, 0, prec); } else if (arb_is_nonpositive(acb_imagref(z))) { acb_conj(res, z); acb_lambertw(res, res, k, 0, prec); acb_conj(res, res); } else { acb_t za, zb; acb_init(za); acb_init(zb); acb_set(za, z); acb_conj(zb, z); arb_nonnegative_part(acb_imagref(za), acb_imagref(za)); arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb)); acb_lambertw(za, za, k, 0, prec); acb_lambertw(zb, zb, k, 0, prec); acb_conj(zb, zb); acb_union(res, za, zb, prec); acb_clear(za); acb_clear(zb); } } fmpz_clear(k); }
int main() { long iter; flint_rand_t state; printf("det...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { fmpq_mat_t Q; fmpq_t Qdet; acb_mat_t A; acb_t Adet, imagunit; long n, qbits, prec; int imaginary; n = n_randint(state, 8); qbits = 1 + n_randint(state, 100); prec = 2 + n_randint(state, 200); imaginary = n_randint(state, 2); fmpq_mat_init(Q, n, n); fmpq_init(Qdet); acb_mat_init(A, n, n); acb_init(Adet); acb_init(imagunit); fmpq_mat_randtest(Q, state, qbits); fmpq_mat_det(Qdet, Q); acb_mat_set_fmpq_mat(A, Q, prec); if (imaginary) { acb_onei(imagunit); acb_mat_scalar_mul_acb(A, A, imagunit, prec); } acb_mat_det(Adet, A, prec); if (imaginary) { acb_onei(imagunit); acb_inv(imagunit, imagunit, prec); acb_pow_ui(imagunit, imagunit, n, prec); acb_mul(Adet, Adet, imagunit, prec); } if (!acb_contains_fmpq(Adet, Qdet)) { printf("FAIL (containment, iter = %ld)\n", iter); printf("n = %ld, prec = %ld\n", n, prec); printf("\n"); printf("Q = \n"); fmpq_mat_print(Q); printf("\n\n"); printf("Qdet = \n"); fmpq_print(Qdet); printf("\n\n"); printf("A = \n"); acb_mat_printd(A, 15); printf("\n\n"); printf("Adet = \n"); acb_printd(Adet, 15); printf("\n\n"); printf("Adet = \n"); acb_print(Adet); printf("\n\n"); abort(); } fmpq_mat_clear(Q); fmpq_clear(Qdet); acb_mat_clear(A); acb_clear(Adet); acb_clear(imagunit); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
static void bsplit(acb_t A1, acb_t B1, acb_t C1, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong aa, slong bb, slong prec, int invz) { if (bb - aa == 1) { slong i; if (p == 0) { if (invz) acb_one(A1); else acb_set(A1, z); } else { acb_add_ui(A1, a, aa, prec); for (i = 1; i < p; i++) { acb_add_ui(B1, a + i, aa, prec); acb_mul(A1, A1, B1, prec); } if (!invz) acb_mul(A1, A1, z, prec); } if (q == 0) { if (invz) acb_set(C1, z); else acb_one(C1); } else { acb_add_ui(C1, b, aa, prec); for (i = 1; i < q; i++) { acb_add_ui(B1, b + i, aa, prec); acb_mul(C1, C1, B1, prec); } if (invz) acb_mul(C1, C1, z, prec); } /* acb_set(B1, C1); but we skip this */ } else { slong m; acb_t A2, B2, C2; acb_init(A2); acb_init(B2); acb_init(C2); m = aa + (bb - aa) / 2; bsplit(A1, B1, C1, a, p, b, q, z, aa, m, prec, invz); bsplit(A2, B2, C2, a, p, b, q, z, m, bb, prec, invz); if (bb - m == 1) /* B2 = C2 */ { if (m - aa == 1) acb_add(B2, A1, C1, prec); else acb_add(B2, A1, B1, prec); acb_mul(B1, B2, C2, prec); } else { if (m - aa == 1) acb_mul(B1, C1, C2, prec); else acb_mul(B1, B1, C2, prec); acb_addmul(B1, A1, B2, prec); } acb_mul(A1, A1, A2, prec); acb_mul(C1, C1, C2, prec); acb_clear(A2); acb_clear(B2); acb_clear(C2); } }
int main() { slong iter; flint_rand_t state; flint_printf("hardy_z...."); fflush(stdout); flint_randinit(state); /* test self-consistency */ for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t s, s2; dirichlet_group_t G; dirichlet_char_t chi; acb_ptr vec1, vec2; slong len1, len2; slong prec1, prec2; ulong q, k; slong i; len1 = n_randint(state, 6); len2 = n_randint(state, 6); prec1 = 2 + n_randint(state, 100); prec2 = 2 + n_randint(state, 100); do { q = 1 + n_randint(state, 30); } while (q % 4 == 2); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); do { k = n_randint(state, n_euler_phi(q)); dirichlet_char_index(chi, G, k); } while (dirichlet_conductor_char(G, chi) != q); acb_init(s); acb_init(s2); vec1 = _acb_vec_init(len1); vec2 = _acb_vec_init(len2); acb_randtest(s, state, 2 + n_randint(state, 200), 2); acb_randtest(s2, state, 2 + n_randint(state, 200), 2); acb_sub(s2, s2, s2, 200); acb_add(s2, s, s2, 200); acb_dirichlet_hardy_z(vec1, s, G, chi, len1, prec1); acb_dirichlet_hardy_z(vec2, s2, G, chi, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(vec1 + i, vec2 + i)) { flint_printf("FAIL: overlap\n\n"); flint_printf("iter = %wd q = %wu k = %wu i = %wd\n\n", iter, q, k, i); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); acb_printn(vec1 + i, 50, 0); flint_printf("\n\n"); flint_printf("r2 = "); acb_printn(vec2 + i, 50, 0); flint_printf("\n\n"); flint_abort(); } } if (arb_contains_zero(acb_imagref(s))) { for (i = 0; i < len1; i++) { if (!arb_contains_zero(acb_imagref(vec1 + i))) { flint_printf("FAIL: real 1\n\n"); flint_printf("iter = %wd q = %wu k = %wu i = %wd\n\n", iter, q, k, i); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); acb_printn(vec1 + i, 50, 0); flint_printf("\n\n"); flint_abort(); } } } if (arb_contains_zero(acb_imagref(s2))) { for (i = 0; i < len2; i++) { if (!arb_contains_zero(acb_imagref(vec2 + i))) { flint_printf("FAIL: real 1\n\n"); flint_printf("iter = %wd q = %wu k = %wu i = %wd\n\n", iter, q, k, i); flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n"); flint_printf("r1 = "); acb_printn(vec2 + i, 50, 0); flint_printf("\n\n"); flint_abort(); } } } dirichlet_char_clear(chi); dirichlet_group_clear(G); acb_clear(s); acb_clear(s2); _acb_vec_clear(vec1, len1); _acb_vec_clear(vec2, len2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_modular_elliptic_k_cpx(acb_ptr w, const acb_t m, slong len, slong prec) { acb_t t, u, msub1m, m2sub1; slong k, n; if (len < 1) return; if (len == 1) { acb_modular_elliptic_k(w, m, prec); return; } if (acb_is_zero(m)) { acb_const_pi(w, prec); acb_mul_2exp_si(w, w, -1); for (k = 1; k < len; k++) { acb_mul_ui(w + k, w + k - 1, (2 * k - 1) * (2 * k - 1), prec); acb_div_ui(w + k, w + k, 4 * k * k, prec); } return; } acb_init(t); acb_init(u); acb_init(msub1m); acb_init(m2sub1); acb_sub_ui(msub1m, m, 1, prec); acb_neg(t, msub1m); acb_sqrt(t, t, prec); acb_mul(msub1m, msub1m, m, prec); acb_mul_2exp_si(m2sub1, m, 1); acb_sub_ui(m2sub1, m2sub1, 1, prec); acb_agm1_cpx(w, t, 2, prec); /* pi M'(t) / (4 t M(t)^2) */ acb_mul(u, w, w, prec); acb_mul(t, t, u, prec); acb_div(w + 1, w + 1, t, prec); acb_const_pi(u, prec); acb_mul(w + 1, w + 1, u, prec); acb_mul_2exp_si(w + 1, w + 1, -2); /* pi / (2 M(t)) */ acb_const_pi(u, prec); acb_div(w, u, w, prec); acb_mul_2exp_si(w, w, -1); acb_inv(t, msub1m, prec); for (k = 2; k < len; k++) { n = k - 2; acb_mul_ui(w + k, w + n, (2 * n + 1) * (2 * n + 1), prec); acb_mul(u, w + n + 1, m2sub1, prec); acb_addmul_ui(w + k, u, (n + 1) * (n + 1) * 4, prec); acb_mul(w + k, w + k, t, prec); acb_div_ui(w + k, w + k, 4 * (n + 1) * (n + 2), prec); acb_neg(w + k, w + k); } acb_clear(t); acb_clear(u); acb_clear(msub1m); acb_clear(m2sub1); }
int _acb_poly_validate_real_roots(acb_srcptr roots, acb_srcptr poly, slong len, slong prec) { slong i, deg, num_real; arb_ptr real; int result; deg = len - 1; num_real = 0; result = 1; if (deg <= 1) return 1; real = _arb_vec_init(deg); /* pick out the candidate real roots */ for (i = 0; i < deg; i++) { if (arb_contains_zero(acb_imagref(roots + i))) { arb_set(real + num_real, acb_realref(roots + i)); num_real++; } } /* number of real roots must be even if the polynomial is even, and odd if the polynomial is odd (unless there are repeated roots... in which case the input is invalid) */ if ((num_real % 2) != (deg % 2)) { result = 0; } else if (num_real > 0) { int sign_neg_inf, sign_pos_inf, prev_sign; acb_t t; acb_init(t); /* by assumption that the roots are real and isolated, the lead coefficient really must be known to be either positive or negative */ sign_pos_inf = arb_is_positive(acb_realref(poly + deg)) ? 1 : -1; sign_neg_inf = (deg % 2) ? -sign_pos_inf : sign_pos_inf; /* now we check that there's a sign change between each root */ _arb_vec_sort_mid(real, num_real); prev_sign = sign_neg_inf; for (i = 0; i < num_real - 1; i++) { /* set t to the midpoint between the midpoints */ arb_zero(acb_imagref(t)); arf_add(arb_midref(acb_realref(t)), arb_midref(real + i), arb_midref(real + i + 1), prec, ARF_RND_DOWN); arf_mul_2exp_si(arb_midref(acb_realref(t)), arb_midref(acb_realref(t)), -1); mag_zero(arb_radref(acb_realref(t))); /* check that this point really is between both intervals (one interval could be much wider than the other */ if (arb_lt(real + i, acb_realref(t)) && arb_lt(acb_realref(t), real + i + 1)) { /* check sign change */ _acb_poly_evaluate(t, poly, len, t, prec); if (prev_sign == 1) result = arb_is_negative(acb_realref(t)); else result = arb_is_positive(acb_realref(t)); if (!result) break; prev_sign = -prev_sign; } else { result = 0; break; } } acb_clear(t); } _arb_vec_clear(real, deg); return result; }
int main() { slong iter; flint_rand_t state; flint_printf("lgamma_series...."); fflush(stdout); flint_randinit(state); /* special accuracy test case */ { acb_poly_t a; acb_t c; acb_init(c); acb_poly_init(a); arb_set_str(acb_realref(c), "-20.25", 53); arb_set_str(acb_imagref(c), "1e1000", 53); acb_poly_set_coeff_acb(a, 0, c); acb_poly_set_coeff_si(a, 1, 1); acb_poly_lgamma_series(a, a, 3, 53); if (acb_rel_accuracy_bits(a->coeffs) < 40 || acb_rel_accuracy_bits(a->coeffs + 1) < 40 || acb_rel_accuracy_bits(a->coeffs + 2) < 40) { flint_printf("FAIL: accuracy (reflection formula)\n\n"); acb_poly_printd(a, 15); flint_printf("\n\n"); abort(); } acb_poly_clear(a); acb_clear(c); } for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { slong m, n1, n2, rbits1, rbits2, rbits3; acb_poly_t a, b, c, d; rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 30); n1 = 1 + n_randint(state, 30); n2 = 1 + n_randint(state, 30); acb_poly_init(a); acb_poly_init(b); acb_poly_init(c); acb_poly_init(d); acb_poly_randtest(a, state, m, rbits1, 10); acb_poly_randtest(b, state, m, rbits1, 10); acb_poly_randtest(c, state, m, rbits1, 10); acb_poly_lgamma_series(b, a, n1, rbits2); acb_poly_lgamma_series(c, a, n2, rbits3); acb_poly_set(d, b); acb_poly_truncate(d, FLINT_MIN(n1, n2)); acb_poly_truncate(c, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL\n\n"); flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); abort(); } /* check loggamma(a) + log(a) = loggamma(a+1) */ acb_poly_log_series(c, a, n1, rbits2); acb_poly_add(c, b, c, rbits2); acb_poly_set(d, a); acb_add_ui(d->coeffs, d->coeffs, 1, rbits2); acb_poly_lgamma_series(d, d, n1, rbits2); if (!acb_poly_overlaps(c, d)) { flint_printf("FAIL (functional equation)\n\n"); flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n"); flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n"); flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n"); flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n"); abort(); } acb_poly_lgamma_series(a, a, n1, rbits2); if (!acb_poly_overlaps(a, b)) { flint_printf("FAIL (aliasing)\n\n"); abort(); } acb_poly_clear(a); acb_poly_clear(b); acb_poly_clear(c); acb_poly_clear(d); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void _acb_hypgeom_2f1_transform_limit(acb_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t c, const acb_poly_t z, int which, slong prec) { acb_poly_t ba, ca, cb, cab, ac1, bc1, ab1, ba1, w, t, u, v, s; acb_t tt; acb_poly_init(ba); acb_poly_init(ca); acb_poly_init(cb); acb_poly_init(cab); acb_poly_init(ac1); acb_poly_init(bc1); acb_poly_init(ab1); acb_poly_init(ba1); acb_poly_init(w); acb_poly_init(t); acb_poly_init(u); acb_poly_init(v); acb_poly_init(s); acb_init(tt); acb_poly_add_si(s, z, -1, prec); /* s = 1 - z */ acb_poly_neg(s, s); acb_poly_sub(ba, b, a, prec); /* ba = b - a */ acb_poly_sub(ca, c, a, prec); /* ca = c - a */ acb_poly_sub(cb, c, b, prec); /* cb = c - b */ acb_poly_sub(cab, ca, b, prec); /* cab = c - a - b */ acb_poly_add_si(ac1, ca, -1, prec); acb_poly_neg(ac1, ac1); /* ac1 = a - c + 1 */ acb_poly_add_si(bc1, cb, -1, prec); acb_poly_neg(bc1, bc1); /* bc1 = b - c + 1 */ acb_poly_add_si(ab1, ba, -1, prec); acb_poly_neg(ab1, ab1); /* ab1 = a - b + 1 */ acb_poly_add_si(ba1, ba, 1, prec); /* ba1 = b - a + 1 */ /* t = left term, u = right term (DLMF 15.8.1 - 15.8.5) */ if (which == 2) { acb_poly_inv_series(w, z, 2, prec); /* w = 1/z */ acb_hypgeom_2f1_series_direct(t, a, ac1, ab1, w, 1, 2, prec); acb_hypgeom_2f1_series_direct(u, b, bc1, ba1, w, 1, 2, prec); } else if (which == 3) { acb_poly_inv_series(w, s, 2, prec); /* w = 1/(1-z) */ acb_hypgeom_2f1_series_direct(t, a, cb, ab1, w, 1, 2, prec); acb_hypgeom_2f1_series_direct(u, b, ca, ba1, w, 1, 2, prec); } else if (which == 4) { acb_poly_set(w, s); /* w = 1-z */ acb_poly_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_series_direct(t, a, b, v, w, 1, 2, prec); acb_poly_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_hypgeom_2f1_series_direct(u, ca, cb, v, w, 1, 2, prec); } else if (which == 5) { acb_poly_inv_series(w, z, 2, prec); /* w = 1-1/z */ acb_poly_neg(w, w); acb_poly_add_si(w, w, 1, prec); acb_poly_add(v, ac1, b, prec); /* v = a+b-c+1 */ acb_hypgeom_2f1_series_direct(t, a, ac1, v, w, 1, 2, prec); acb_poly_add_si(v, cab, 1, prec); /* v = c-a-b+1 */ acb_poly_add_si(u, a, -1, prec); /* u = 1-a */ acb_poly_neg(u, u); acb_hypgeom_2f1_series_direct(u, ca, u, v, w, 1, 2, prec); } else { flint_printf("invalid transformation!\n"); abort(); } /* gamma factors */ acb_poly_rgamma_series(v, a, 2, prec); acb_poly_mullow(u, u, v, 2, prec); acb_poly_rgamma_series(v, ca, 2, prec); acb_poly_mullow(t, t, v, 2, prec); acb_poly_rgamma_series(v, b, 2, prec); if (which == 2 || which == 3) acb_poly_mullow(t, t, v, 2, prec); else acb_poly_mullow(u, u, v, 2, prec); acb_poly_rgamma_series(v, cb, 2, prec); if (which == 2 || which == 3) acb_poly_mullow(u, u, v, 2, prec); else acb_poly_mullow(t, t, v, 2, prec); if (which == 2 || which == 3) { if (which == 2) acb_poly_neg(s, z); /* -z, otherwise 1-z since before */ acb_poly_neg(v, a); acb_poly_pow_series(v, s, v, 2, prec); acb_poly_mullow(t, t, v, 2, prec); acb_poly_neg(v, b); acb_poly_pow_series(v, s, v, 2, prec); acb_poly_mullow(u, u, v, 2, prec); } else { acb_poly_pow_series(v, s, cab, 2, prec); acb_poly_mullow(u, u, v, 2, prec); if (which == 5) { acb_poly_neg(v, a); acb_poly_pow_series(v, z, v, 2, prec); acb_poly_mullow(t, t, v, 2, prec); acb_poly_neg(v, ca); acb_poly_pow_series(v, z, v, 2, prec); acb_poly_mullow(u, u, v, 2, prec); } } acb_poly_sub(t, t, u, prec); if (which == 2 || which == 3) acb_poly_sin_pi_series(v, ba, 2, prec); else acb_poly_sin_pi_series(v, cab, 2, prec); acb_poly_get_coeff_acb(tt, t, 1); acb_poly_get_coeff_acb(res, v, 1); acb_div(res, tt, res, prec); acb_const_pi(tt, prec); acb_mul(res, res, tt, prec); acb_poly_clear(ba); acb_poly_clear(ca); acb_poly_clear(cb); acb_poly_clear(cab); acb_poly_clear(ac1); acb_poly_clear(bc1); acb_poly_clear(ab1); acb_poly_clear(ba1); acb_poly_clear(w); acb_poly_clear(t); acb_poly_clear(u); acb_poly_clear(v); acb_poly_clear(s); acb_clear(tt); }
int main() { slong iter; flint_rand_t state; flint_printf("digamma...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++) { acb_t a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(a); acb_init(b); acb_init(c); arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 3); arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 3); acb_digamma(b, a, prec1); acb_digamma(c, a, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); abort(); } acb_set(c, a); acb_digamma(c, c, prec2); if (!acb_overlaps(b, c)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); abort(); } /* check digamma(z+1) = digamma(z) + 1/z */ acb_inv(c, a, prec1); acb_add(b, b, c, prec1); acb_add_ui(c, a, 1, prec1); acb_digamma(c, c, prec1); if (!acb_overlaps(b, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); abort(); } acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_elliptic_p_jet(acb_ptr r, const acb_t z, const acb_t tau, slong len, slong prec) { acb_t t01, t02, t03, t04; acb_ptr tz1, tz2, tz3, tz4; acb_t t; int real; slong k; if (len < 1) return; if (len == 1) { acb_elliptic_p(r, z, tau, prec); return; } real = acb_is_real(z) && arb_is_int_2exp_si(acb_realref(tau), -1) && arb_is_positive(acb_imagref(tau)); acb_init(t); acb_init(t01); acb_init(t02); acb_init(t03); acb_init(t04); tz1 = _acb_vec_init(len); tz2 = _acb_vec_init(len); tz3 = _acb_vec_init(len); tz4 = _acb_vec_init(len); acb_modular_theta_jet(tz1, tz2, tz3, tz4, z, tau, len, prec); /* [theta_4(z) / theta_1(z)]^2 */ _acb_poly_div_series(tz2, tz4, len, tz1, len, len, prec); _acb_poly_mullow(tz1, tz2, len, tz2, len, len, prec); acb_zero(t); acb_modular_theta(t01, t02, t03, t04, t, tau, prec); /* [theta_2(0) * theta_3(0)] ^2 */ acb_mul(t, t02, t03, prec); acb_mul(t, t, t, prec); _acb_vec_scalar_mul(tz1, tz1, len, t, prec); /* - [theta_2(0)^4 + theta_3(0)^4] / 3 */ acb_pow_ui(t02, t02, 4, prec); acb_pow_ui(t03, t03, 4, prec); acb_add(t, t02, t03, prec); acb_div_ui(t, t, 3, prec); acb_sub(tz1, tz1, t, prec); /* times pi^2 */ acb_const_pi(t, prec); acb_mul(t, t, t, prec); _acb_vec_scalar_mul(r, tz1, len, t, prec); if (real) { for (k = 0; k < len; k++) arb_zero(acb_imagref(r + k)); } acb_clear(t); acb_clear(t01); acb_clear(t02); acb_clear(t03); acb_clear(t04); _acb_vec_clear(tz1, len); _acb_vec_clear(tz2, len); _acb_vec_clear(tz3, len); _acb_vec_clear(tz4, len); }
int main() { slong iter; flint_rand_t state; flint_printf("exp...."); fflush(stdout); flint_randinit(state); /* check exp(A)*exp(c*A) = exp((1+c)*A) */ for (iter = 0; iter < 500 * arb_test_multiplier(); iter++) { acb_mat_t A, E, F, EF, G; fmpq_mat_t Q; acb_t c, d; slong n, qbits, prec; n = n_randint(state, 5); qbits = 2 + n_randint(state, 300); prec = 2 + n_randint(state, 300); acb_init(c); acb_init(d); fmpq_mat_init(Q, n, n); acb_mat_init(A, n, n); acb_mat_init(E, n, n); acb_mat_init(F, n, n); acb_mat_init(EF, n, n); acb_mat_init(G, n, n); _fmpq_mat_randtest_for_exp(Q, state, qbits); acb_mat_set_fmpq_mat(A, Q, prec); acb_mat_exp(E, A, prec); acb_randtest(c, state, prec, 10); acb_mat_scalar_mul_acb(F, A, c, prec); acb_mat_exp(F, F, prec); acb_add_ui(d, c, 1, prec); acb_mat_scalar_mul_acb(G, A, d, prec); acb_mat_exp(G, G, prec); acb_mat_mul(EF, E, F, prec); if (!acb_mat_overlaps(EF, G)) { flint_printf("FAIL\n\n"); flint_printf("n = %wd, prec = %wd\n", n, prec); flint_printf("c = \n"); acb_printd(c, 15); flint_printf("\n\n"); flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n"); flint_printf("E = \n"); acb_mat_printd(E, 15); flint_printf("\n\n"); flint_printf("F = \n"); acb_mat_printd(F, 15); flint_printf("\n\n"); flint_printf("E*F = \n"); acb_mat_printd(EF, 15); flint_printf("\n\n"); flint_printf("G = \n"); acb_mat_printd(G, 15); flint_printf("\n\n"); flint_abort(); } acb_clear(c); acb_clear(d); fmpq_mat_clear(Q); acb_mat_clear(A); acb_mat_clear(E); acb_mat_clear(F); acb_mat_clear(EF); acb_mat_clear(G); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("gamma_lower...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++) { acb_t a0, a1, b, z, w0, w1, t, u, enz; slong prec0, prec1; int regularized; acb_init(a0); acb_init(a1); acb_init(b); acb_init(z); acb_init(w0); acb_init(w1); acb_init(t); acb_init(u); acb_init(enz); regularized = n_randint(state, 3); prec0 = 2 + n_randint(state, 1000); prec1 = 2 + n_randint(state, 1000); acb_randtest_param(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100)); acb_add_ui(a1, a0, 1, prec0); acb_hypgeom_gamma_lower(w0, a0, z, regularized, prec0); acb_hypgeom_gamma_lower(w1, a1, z, regularized, prec1); acb_neg(enz, z); acb_exp(enz, enz, prec0); /* recurrence relations */ if (regularized == 2) { /* gamma^{*}(a,z) - exp(-z)/Gamma(a+1) - z gamma^{*}(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E4 */ acb_set(t, w0); acb_rgamma(u, a1, prec0); acb_submul(t, enz, u, prec0); acb_submul(t, z, w1, prec0); } else if (regularized == 1) { /* P(a,z) - exp(-z) z^a / Gamma(a+1) - P(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E5 */ acb_pow(u, z, a0, prec0); acb_rgamma(b, a1, prec0); acb_mul(u, u, b, prec0); acb_sub(t, w0, w1, prec0); acb_submul(t, enz, u, prec0); } else { /* a gamma(a,z) - exp(-z) z^a - gamma(a+1,z) = 0 */ /* http://dlmf.nist.gov/8.8.E1 */ acb_pow(u, z, a0, prec0); acb_mul(t, a0, w0, prec0); acb_submul(t, enz, u, prec0); acb_sub(t, t, w1, prec0); } if (!acb_contains_zero(t)) { flint_printf("FAIL: recurrence relation\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); abort(); } /* identities relating lower and upper incomplete gamma functions */ if (regularized == 0 || regularized == 1) { acb_t u0; acb_init(u0); acb_hypgeom_gamma_upper(u0, a0, z, regularized, prec0); acb_zero(t); if (regularized == 1) { /* P(s,z) + Q(s,z) - 1 = 0 */ /* http://dlmf.nist.gov/8.2.E5 */ acb_add(t, w0, u0, prec0); acb_sub_ui(t, t, 1, prec0); } else { /* gamma(s,z) + Gamma(s,z) - Gamma(s) = 0 */ /* excludes non-positive integer values of s */ /* http://dlmf.nist.gov/8.2.E3 */ if (!acb_is_int(a0) || arb_is_positive(acb_realref(a0))) { acb_gamma(b, a0, prec0); acb_add(t, w0, u0, prec0); acb_sub(t, t, b, prec0); } } if (!acb_contains_zero(t)) { flint_printf("FAIL: lower plus upper\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n"); flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n"); flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n"); flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n"); flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n"); abort(); } acb_clear(u0); } acb_clear(a0); acb_clear(a1); acb_clear(b); acb_clear(z); acb_clear(w0); acb_clear(w1); acb_clear(t); acb_clear(u); acb_clear(enz); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { long iter; flint_rand_t state; printf("root_bound_fujiwara...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { acb_poly_t a; acb_ptr roots; acb_t t; mag_t mag1, mag2; long i, deg, prec; prec = 10 + n_randint(state, 400); deg = n_randint(state, 10); acb_init(t); acb_poly_init(a); mag_init(mag1); mag_init(mag2); roots = _acb_vec_init(deg); for (i = 0; i < deg; i++) acb_randtest(roots + i, state, prec, 1 + n_randint(state, 20)); acb_poly_product_roots(a, roots, deg, prec); acb_randtest(t, state, prec, 1 + n_randint(state, 20)); _acb_vec_scalar_mul(a->coeffs, a->coeffs, a->length, t, prec); acb_poly_root_bound_fujiwara(mag1, a); for (i = 0; i < deg; i++) { acb_get_mag(mag2, roots + i); /* acb_get_mag gives an upper bound which due to rounding could be larger than mag1, so we pick a slightly smaller number */ mag_mul_ui(mag2, mag2, 10000); mag_div_ui(mag2, mag2, 10001); if (mag_cmp(mag2, mag1) > 0) { printf("FAIL\n"); printf("a = "); acb_poly_printd(a, 15); printf("\n\n"); printf("root = "); acb_printd(roots + i, 15); printf("\n\n"); printf("mag1 = "); mag_printd(mag1, 10); printf("\n\n"); printf("mag2 = "); mag_printd(mag2, 10); printf("\n\n"); abort(); } } _acb_vec_clear(roots, deg); acb_clear(t); acb_poly_clear(a); mag_clear(mag1); mag_clear(mag2); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void acb_hypgeom_2f1_transform_limit(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int regularized, int which, slong prec) { acb_poly_t aa, bb, cc, zz; acb_t t; if (acb_contains_zero(z) || !acb_is_finite(z)) { acb_indeterminate(res); return; } if (arb_contains_si(acb_realref(z), 1) && arb_contains_zero(acb_imagref(z))) { acb_indeterminate(res); return; } if (!regularized) { acb_init(t); acb_gamma(t, c, prec); acb_hypgeom_2f1_transform_limit(res, a, b, c, z, 1, which, prec); acb_mul(res, res, t, prec); acb_clear(t); return; } acb_poly_init(aa); acb_poly_init(bb); acb_poly_init(cc); acb_poly_init(zz); acb_init(t); acb_poly_set_acb(aa, a); acb_poly_set_acb(bb, b); acb_poly_set_acb(cc, c); acb_poly_set_acb(zz, z); if (which == 2 || which == 3) { acb_sub(t, b, a, prec); acb_poly_set_coeff_si(aa, 1, 1); /* prefer b-a nonnegative (either is correct) to avoid expensive operations in the hypergeometric series */ if (arb_is_nonnegative(acb_realref(t))) _acb_hypgeom_2f1_transform_limit(res, aa, bb, cc, zz, which, prec); else _acb_hypgeom_2f1_transform_limit(res, bb, aa, cc, zz, which, prec); } else { acb_poly_set_coeff_si(aa, 1, 1); _acb_hypgeom_2f1_transform_limit(res, aa, bb, cc, zz, which, prec); } acb_poly_clear(aa); acb_poly_clear(bb); acb_poly_clear(cc); acb_poly_clear(zz); acb_clear(t); }
int main() { slong iter; flint_rand_t state; flint_printf("sin_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { acb_t x, y, a, b, c; slong prec1, prec2; prec1 = 2 + n_randint(state, 1000); prec2 = prec1 + 30; acb_init(x); acb_init(y); acb_init(a); acb_init(b); acb_init(c); acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100)); acb_sin_pi(a, x, prec1); acb_sin_pi(b, x, prec2); /* check consistency */ if (!acb_overlaps(a, b)) { flint_printf("FAIL: overlap\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("b = "); acb_print(b); flint_printf("\n\n"); abort(); } /* compare with cos */ arb_const_pi(acb_realref(c), prec1); acb_mul_arb(y, x, acb_realref(c), prec1); acb_sin(c, y, prec1); if (!acb_overlaps(a, c)) { flint_printf("FAIL: functional equation\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); flint_printf("y = "); acb_print(y); flint_printf("\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("c = "); acb_print(c); flint_printf("\n\n"); abort(); } acb_sin_pi(x, x, prec1); if (!acb_overlaps(a, x)) { flint_printf("FAIL: aliasing\n\n"); flint_printf("a = "); acb_print(a); flint_printf("\n\n"); flint_printf("x = "); acb_print(x); flint_printf("\n\n"); abort(); } acb_clear(x); acb_clear(y); acb_clear(a); acb_clear(b); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }