void _acb_poly_evaluate_rectangular(acb_t y, acb_srcptr poly, slong len, const acb_t x, slong prec) { slong i, j, m, r; acb_ptr xs; acb_t s, t, c; if (len < 3) { if (len == 0) { acb_zero(y); } else if (len == 1) { acb_set_round(y, poly + 0, prec); } else if (len == 2) { acb_mul(y, x, poly + 1, prec); acb_add(y, y, poly + 0, prec); } return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _acb_vec_init(m + 1); acb_init(s); acb_init(t); acb_init(c); _acb_vec_set_powers(xs, x, m + 1, prec); acb_set(y, poly + (r - 1) * m); for (j = 1; (r - 1) * m + j < len; j++) acb_addmul(y, xs + j, poly + (r - 1) * m + j, prec); for (i = r - 2; i >= 0; i--) { acb_set(s, poly + i * m); for (j = 1; j < m; j++) acb_addmul(s, xs + j, poly + i * m + j, prec); acb_mul(y, y, xs + m, prec); acb_add(y, y, s, prec); } _acb_vec_clear(xs, m + 1); acb_clear(s); acb_clear(t); acb_clear(c); }
void acb_hypgeom_pfq_sum_rs(acb_t res, acb_t term, acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec) { acb_ptr zpow; acb_t s, t, u; slong i, j, k, m; mag_t B, C; if (n == 0) { acb_zero(res); acb_one(term); return; } if (n < 0) abort(); m = n_sqrt(n); m = FLINT_MIN(m, 150); mag_init(B); mag_init(C); acb_init(s); acb_init(t); acb_init(u); zpow = _acb_vec_init(m + 1); _acb_vec_set_powers(zpow, z, m + 1, prec); mag_one(B); for (k = n; k >= 0; k--) { j = k % m; if (k < n) acb_add(s, s, zpow + j, prec); if (k > 0) { if (p > 0) { acb_add_ui(u, a, k - 1, prec); for (i = 1; i < p; i++) { acb_add_ui(t, a + i, k - 1, prec); acb_mul(u, u, t, prec); } if (k < n) acb_mul(s, s, u, prec); acb_get_mag(C, u); mag_mul(B, B, C); } if (q > 0) { acb_add_ui(u, b, k - 1, prec); for (i = 1; i < q; i++) { acb_add_ui(t, b + i, k - 1, prec); acb_mul(u, u, t, prec); } if (k < n) acb_div(s, s, u, prec); acb_get_mag_lower(C, u); mag_div(B, B, C); } if (j == 0 && k < n) { acb_mul(s, s, zpow + m, prec); } } } acb_get_mag(C, z); mag_pow_ui(C, C, n); mag_mul(B, B, C); acb_zero(term); if (_acb_vec_is_real(a, p) && _acb_vec_is_real(b, q) && acb_is_real(z)) arb_add_error_mag(acb_realref(term), B); else acb_add_error_mag(term, B); acb_set(res, s); mag_clear(B); mag_clear(C); acb_clear(s); acb_clear(t); acb_clear(u); _acb_vec_clear(zpow, m + 1); }
void acb_rising2_ui_rs(acb_t u, acb_t v, const acb_t x, ulong n, ulong m, long prec) { if (n == 0) { acb_zero(v); acb_one(u); } else if (n == 1) { acb_set(u, x); acb_one(v); } else { long wp; ulong i, j, a, b; acb_ptr xs; acb_t S, T, U, V; fmpz *A, *B; wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); if (m == 0) { ulong m1, m2; m1 = 0.6 * pow(wp, 0.4); m2 = n_sqrt(n); m = FLINT_MIN(m1, m2); } m = FLINT_MAX(m, 1); xs = _acb_vec_init(m + 1); A = _fmpz_vec_init(2 * m + 1); B = A + (m + 1); acb_init(S); acb_init(T); acb_init(U); acb_init(V); _acb_vec_set_powers(xs, x, m + 1, wp); for (i = 0; i < n; i += m) { a = i; b = FLINT_MIN(n, a + m); if (a == 0 || b != a + m) { _gamma_rf_bsplit(A, a, b); } else { fmpz tt = m; _fmpz_poly_taylor_shift(A, &tt, m + 1); } _fmpz_poly_derivative(B, A, b - a + 1); acb_set_fmpz(S, A); for (j = 1; j <= b - a; j++) acb_addmul_fmpz(S, xs + j, A + j, wp); acb_set_fmpz(T, B); for (j = 1; j < b - a; j++) acb_addmul_fmpz(T, xs + j, B + j, wp); if (i == 0) { acb_set(U, S); acb_set(V, T); } else { acb_mul(V, V, S, wp); acb_addmul(V, U, T, wp); acb_mul(U, U, S, wp); } } acb_set(u, U); acb_set(v, V); _acb_vec_clear(xs, m + 1); _fmpz_vec_clear(A, 2 * m + 1); acb_clear(S); acb_clear(T); acb_clear(U); acb_clear(V); } }
void acb_rising_ui_rs(acb_t y, const acb_t x, ulong n, ulong m, slong prec) { acb_ptr xs; acb_t t, u, v; ulong i, k, rem; fmpz_t c, h; fmpz *s, *d; slong wp; if (n == 0) { acb_one(y); return; } if (n == 1) { acb_set_round(y, x, prec); return; } wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n)); acb_init(t); acb_init(u); acb_init(v); fmpz_init(c); fmpz_init(h); if (m == 0) { ulong m1, m2; m1 = 0.2 * pow(2.0 * wp, 0.4); m2 = n_sqrt(n); m = FLINT_MIN(m1, m2); } m = FLINT_MIN(m, n); m = FLINT_MAX(m, 1); xs = _acb_vec_init(m + 1); d = _fmpz_vec_init(m * m); s = _fmpz_vec_init(m + 1); _acb_vec_set_powers(xs, x, m + 1, wp); rising_difference_polynomial(s, d, m); /* tail */ rem = m; while (rem + m <= n) rem += m; acb_one(y); for (k = rem; k < n; k++) { acb_add_ui(t, xs + 1, k, wp); acb_mul(y, y, t, wp); } /* initial rising factorial */ acb_zero(t); for (i = 1; i <= m; i++) acb_addmul_fmpz(t, xs + i, s + i, wp); acb_mul(y, y, t, wp); /* the leading coefficient is always the same */ acb_mul_fmpz(xs + m - 1, xs + m - 1, d + m - 1 + 0, wp); for (k = 0; k + 2 * m <= n; k += m) { for (i = 0; i < m - 1; i++) { fmpz_set_ui(h, k); _fmpz_poly_evaluate_horner_fmpz(c, d + i * m, m - i, h); if (i == 0) acb_add_fmpz(t, t, c, wp); else acb_addmul_fmpz(t, xs + i, c, wp); } acb_add(t, t, xs + m - 1, wp); acb_mul(y, y, t, wp); } acb_set_round(y, y, prec); acb_clear(t); acb_clear(u); acb_clear(v); _acb_vec_clear(xs, m + 1); _fmpz_vec_clear(d, m * m); _fmpz_vec_clear(s, m + 1); fmpz_clear(c); fmpz_clear(h); }