void acb_hypgeom_bessel_k_0f1_series(acb_poly_t res, const acb_poly_t nu, const acb_poly_t z, slong len, slong prec) { acb_poly_t s, u, A, B; acb_poly_struct b[2]; arb_t c; slong wlen; int singular; acb_poly_init(s); acb_poly_init(u); acb_poly_init(A); acb_poly_init(B); acb_poly_init(b + 0); acb_poly_init(b + 1); arb_init(c); singular = (nu->length == 0) || acb_is_int(nu->coeffs); wlen = len + (singular != 0); /* A = (z/2)^nu, B = 1/A */ acb_poly_scalar_mul_2exp_si(A, z, -1); acb_poly_pow_series(A, A, nu, wlen, prec); acb_poly_inv_series(B, A, wlen, prec); acb_poly_mullow(u, z, z, wlen, prec); acb_poly_scalar_mul_2exp_si(u, u, -2); acb_poly_one(b + 1); acb_poly_add_si(b + 0, nu, 1, prec); acb_hypgeom_pfq_series_direct(s, NULL, 0, b, 2, u, 1, -1, wlen, prec); acb_poly_mullow(A, A, s, wlen, prec); acb_poly_add_si(b + 0, nu, -1, prec); acb_poly_neg(b + 0, b + 0); acb_hypgeom_pfq_series_direct(s, NULL, 0, b, 2, u, 1, -1, wlen, prec); acb_poly_mullow(B, B, s, wlen, prec); acb_poly_sub(A, B, A, prec); acb_poly_scalar_mul_2exp_si(A, A, -1); /* multiply by pi csc(pi nu) */ acb_poly_sin_pi_series(B, nu, wlen, prec); if (singular) { acb_poly_shift_right(A, A, 1); acb_poly_shift_right(B, B, 1); } acb_poly_div_series(res, A, B, len, prec); arb_const_pi(c, prec); _acb_vec_scalar_mul_arb(res->coeffs, res->coeffs, res->length, c, prec); acb_poly_clear(s); acb_poly_clear(u); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(b + 0); acb_poly_clear(b + 1); arb_clear(c); }
int main() { slong iter; flint_rand_t state; flint_printf("hardy_z_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; dirichlet_group_t G; dirichlet_char_t chi; ulong q; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 8); n1 = 1 + n_randint(state, 8); n2 = 1 + n_randint(state, 8); do { q = 1 + n_randint(state, 15); } while (q % 4 == 2); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); do { dirichlet_char_index(chi, G, n_randint(state, G->phi_q)); } while (!dirichlet_char_is_primitive(G, chi)); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_poly_randtest(S, state, m, bits1, 3); acb_dirichlet_hardy_z_series(A, S, G, chi, n1, bits2); acb_poly_set(B, S); /* aliasing */ if (q == 1 && n_randint(state, 2)) acb_poly_neg(B, B); acb_dirichlet_hardy_z_series(B, B, G, chi, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\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"); abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); dirichlet_char_clear(chi); dirichlet_group_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_upper_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t s, t, c; int regularized; regularized = n_randint(state, 3); bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(s); acb_init(t); acb_init(c); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_randtest(s, state, bits1, 3); acb_hypgeom_gamma_upper_series(A, s, S, regularized, n1, bits2); acb_hypgeom_gamma_upper_series(B, s, S, regularized, n2, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL (consistency)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\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_abort(); } /* f(h(x)) = -exp(-h(x)) h(x)^(s-1) */ acb_poly_neg(C, S); acb_poly_exp_series(C, C, n1, bits2); acb_sub_ui(t, s, 1, bits2); acb_poly_pow_acb_series(B, S, t, n1, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_neg(C, C); if (regularized == 0) { /* integral(f(h(x)) h'(x))' = f(h(x)) h'(x) */ acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_truncate(C, n1 - 1); } else if (regularized == 1) { /* (integral(f(h(x)) h'(x)) / c)' = (f(h(x)) h'(x)) / c */ acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_gamma(c, s, bits2); acb_poly_scalar_div(C, C, c, bits2); acb_poly_truncate(C, n1 - 1); } else if (regularized == 2) { /* (h(x)^-s integral(f(h(x)) h'(x)))' = * h(x)^-(s+1) (h(x) f(h(x)) - s integral(f(h(x)) h'(x))) h'(x) */ acb_poly_t D; acb_poly_init(D); acb_poly_derivative(B, S, bits2); acb_poly_mullow(D, C, B, n1, bits2); acb_poly_integral(D, D, bits2); acb_poly_scalar_mul(D, D, s, bits2); acb_poly_mullow(C, C, S, n1, bits2); acb_poly_sub(D, C, D, bits2); acb_add_ui(t, s, 1, bits2); acb_neg(t, t); acb_poly_pow_acb_series(B, S, t, n1, bits2); acb_poly_mullow(C, D, B, n1, bits2); acb_poly_derivative(B, S, bits2); acb_poly_mullow(C, C, B, n1, bits2); acb_poly_truncate(C, n1 - 1); acb_poly_clear(D); } acb_poly_derivative(B, A, bits2); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL (derivative)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\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_abort(); } acb_hypgeom_gamma_upper_series(S, s, S, regularized, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); flint_printf("regularized = %d\n\n", regularized); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\n\n"); flint_printf("A = "); acb_poly_printd(A, 15); flint_printf("\n\n"); flint_abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(s); acb_clear(t); acb_clear(c); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter; flint_rand_t state; flint_printf("erfi_series...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 200 * arb_test_multiplier(); iter++) { slong m, n1, n2, bits1, bits2, bits3; acb_poly_t S, A, B, C; acb_t I; bits1 = 2 + n_randint(state, 200); bits2 = 2 + n_randint(state, 200); bits3 = 2 + n_randint(state, 200); m = 1 + n_randint(state, 10); n1 = 1 + n_randint(state, 10); n2 = 1 + n_randint(state, 10); acb_poly_init(S); acb_poly_init(A); acb_poly_init(B); acb_poly_init(C); acb_init(I); acb_poly_randtest(S, state, m, bits1, 3); acb_poly_randtest(A, state, m, bits1, 3); acb_poly_randtest(B, state, m, bits1, 3); acb_hypgeom_erfi_series(A, S, n1, bits2); acb_onei(I); acb_poly_set_acb(C, I); acb_poly_mul(B, S, C, bits3); acb_hypgeom_erf_series(B, B, n2, bits3); acb_poly_neg(C, C); acb_poly_mul(B, B, C, bits3); acb_poly_set(C, A); acb_poly_truncate(C, FLINT_MIN(n1, n2)); acb_poly_truncate(B, FLINT_MIN(n1, n2)); if (!acb_poly_overlaps(B, C)) { flint_printf("FAIL\n\n"); flint_printf("S = "); acb_poly_printd(S, 15); flint_printf("\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"); abort(); } acb_hypgeom_erfi_series(S, S, n1, bits2); if (!acb_poly_overlaps(A, S)) { flint_printf("FAIL (aliasing)\n\n"); abort(); } acb_poly_clear(S); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(C); acb_clear(I); } 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"); flint_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); }
void acb_hypgeom_u_1f1_series(acb_poly_t res, const acb_poly_t a, const acb_poly_t b, const acb_poly_t z, long len, long prec) { acb_poly_t s, u, A, B; acb_poly_struct aa[3]; arb_t c; long wlen; int singular; acb_poly_init(s); acb_poly_init(u); acb_poly_init(A); acb_poly_init(B); acb_poly_init(aa + 0); acb_poly_init(aa + 1); acb_poly_init(aa + 2); arb_init(c); singular = (b->length == 0) || acb_is_int(b->coeffs); wlen = len + (singular != 0); /* A = rgamma(a-b+1) * 1F~1(a,b,z) */ acb_poly_sub(u, a, b, prec); acb_poly_add_si(u, u, 1, prec); acb_poly_rgamma_series(A, u, wlen, prec); /* todo: handle a = 1 efficiently */ acb_poly_set(aa, a); acb_poly_set(aa + 1, b); acb_poly_one(aa + 2); acb_hypgeom_pfq_series_direct(s, aa, 1, aa + 1, 2, z, 1, -1, wlen, prec); acb_poly_mullow(A, A, s, wlen, prec); /* B = rgamma(a) * 1F~1(a-b+1,2-b,z) * z^(1-b) */ acb_poly_set(aa, u); acb_poly_add_si(aa + 1, b, -2, prec); acb_poly_neg(aa + 1, aa + 1); acb_hypgeom_pfq_series_direct(s, aa, 1, aa + 1, 2, z, 1, -1, wlen, prec); acb_poly_rgamma_series(B, a, wlen, prec); acb_poly_mullow(B, B, s, wlen, prec); acb_poly_add_si(u, b, -1, prec); acb_poly_neg(u, u); acb_poly_pow_series(s, z, u, wlen, prec); acb_poly_mullow(B, B, s, wlen, prec); acb_poly_sub(A, A, B, prec); /* multiply by pi csc(pi b) */ acb_poly_sin_pi_series(B, b, wlen, prec); if (singular) { acb_poly_shift_right(A, A, 1); acb_poly_shift_right(B, B, 1); } acb_poly_div_series(res, A, B, len, prec); arb_const_pi(c, prec); _acb_vec_scalar_mul_arb(res->coeffs, res->coeffs, res->length, c, prec); acb_poly_clear(s); acb_poly_clear(u); acb_poly_clear(A); acb_poly_clear(B); acb_poly_clear(aa + 0); acb_poly_clear(aa + 1); acb_poly_clear(aa + 2); arb_clear(c); }