void acb_hypgeom_laguerre_l(acb_t res, const acb_t n, const acb_t m, const acb_t z, slong prec) { acb_t t, u, v; if (use_recurrence(n, m, prec)) { acb_hypgeom_laguerre_l_ui_recurrence(res, arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), m, z, prec); return; } /* todo: should be a test of whether n contains any negative integer */ if (acb_contains_int(n) && !arb_is_nonnegative(acb_realref(n))) { acb_indeterminate(res); return; } acb_init(t); acb_init(u); acb_init(v); acb_neg(t, n); acb_add_ui(u, m, 1, prec); acb_hypgeom_m(t, t, u, z, 1, prec); acb_add_ui(u, n, 1, prec); acb_rising(u, u, m, prec); acb_mul(res, t, u, prec); acb_clear(t); acb_clear(u); acb_clear(v); }
void arb_hypgeom_m(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, slong prec) { acb_t t, u, v; acb_init(t); acb_init(u); acb_init(v); arb_set(acb_realref(t), a); arb_set(acb_realref(u), b); arb_set(acb_realref(v), z); acb_hypgeom_m(t, t, u, v, regularized, prec); if (acb_is_finite(t) && acb_is_real(t)) arb_swap(res, acb_realref(t)); else arb_indeterminate(res); acb_clear(t); acb_clear(u); acb_clear(v); }
int main(int argc, char *argv[]) { int function, i, numtests; slong prec, goal; double t, total, logtotal; acb_t a, b, c, z, r, s; acb_init(a); acb_init(b); acb_init(c); acb_init(z); acb_init(r); acb_init(s); /* J(0,pi x) I(0,pi x) K(0,pi x) */ for (function = 0; function < 3; function++) { total = 0.0; logtotal = 0.0; if (function < 2) numtests = 40; else numtests = 30; for (i = 0; i < numtests; i++) { // printf("%2d ", i + 1); fflush(stdout); TIMEIT_START prec = 96; for (;;) { if (function == 0) { acb_set_d_d(a, input_1f1[i][0], input_1f1[i][1]); acb_set_d_d(b, input_1f1[i][2], input_1f1[i][3]); acb_set_d_d(z, input_1f1[i][4], input_1f1[i][5]); acb_hypgeom_m(r, a, b, z, 0, prec); } else if (function == 1) { acb_set_d_d(a, input_1f1[i][0], input_1f1[i][1]); acb_set_d_d(b, input_1f1[i][2], input_1f1[i][3]); acb_set_d_d(z, input_1f1[i][4], input_1f1[i][5]); acb_hypgeom_u(r, a, b, z, prec); } else if (function == 2) { acb_set_d_d(a, input_2f1[i][0], input_2f1[i][1]); acb_set_d_d(b, input_2f1[i][2], input_2f1[i][3]); acb_set_d_d(c, input_2f1[i][4], input_2f1[i][5]); acb_set_d_d(z, input_2f1[i][6], input_2f1[i][7]); acb_hypgeom_2f1(r, a, b, c, z, 0, prec); } else { acb_set_d_d(a, input_2f1[i][0], input_2f1[i][1]); acb_set_d_d(b, input_2f1[i][2], input_2f1[i][3]); acb_set_d_d(c, input_2f1[i][4], input_2f1[i][5]); acb_set_d_d(z, input_2f1[i][6], input_2f1[i][7]); acb_mul_2exp_si(z, z, 1); acb_sub_ui(z, z, 1, prec); acb_neg(z, z); acb_hypgeom_legendre_q(r, a, c, z, 0, prec); } if (function == 3) { if (acb_rel_accuracy_bits(r) >= goal) break; } else { if (arb_can_round_arf(acb_realref(r), goal, ARF_RND_NEAR) && arb_can_round_arf(acb_imagref(r), goal, ARF_RND_NEAR)) break; } prec *= 2; } TIMEIT_STOP_VAL(t) total += t; logtotal += log(t); #if 1 printf("%8g, ", t); #else printf("%8ld %8g ", prec, t); _acb_print(r, 25); printf("\n"); #endif } printf("---------------------------------------------------------------\n"); printf("Mean %g s; geometric mean %g\n", total, exp(logtotal / numtests)); printf("---------------------------------------------------------------\n"); } acb_clear(a); acb_clear(b); acb_clear(c); acb_clear(z); acb_clear(r); acb_clear(s); }