void _acb_poly_interpolation_weights(acb_ptr w, acb_ptr * tree, slong len, slong prec) { acb_ptr tmp; slong i, n, height; if (len == 0) return; if (len == 1) { acb_one(w); return; } tmp = _acb_vec_init(len + 1); height = FLINT_CLOG2(len); n = WORD(1) << (height - 1); _acb_poly_mul_monic(tmp, tree[height-1], n + 1, tree[height-1] + (n + 1), (len - n + 1), prec); _acb_poly_derivative(tmp, tmp, len + 1, prec); _acb_poly_evaluate_vec_fast_precomp(w, tmp, len, tree, len, prec); for (i = 0; i < len; i++) acb_inv(w + i, w + i, prec); _acb_vec_clear(tmp, len + 1); }
void _acb_poly_atan_series(acb_ptr g, acb_srcptr h, slong hlen, slong n, slong prec) { acb_t c; acb_init(c); acb_atan(c, h, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _acb_vec_zero(g + 1, n - 1); } else { acb_ptr t, u; slong ulen; t = _acb_vec_init(n); u = _acb_vec_init(n); /* atan(h(x)) = integral(h'(x)/(1+h(x)^2)) */ ulen = FLINT_MIN(n, 2 * hlen - 1); _acb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); acb_add_ui(u, u, 1, prec); _acb_poly_derivative(t, h, hlen, prec); _acb_poly_div_series(g, t, hlen - 1, u, ulen, n, prec); _acb_poly_integral(g, g, n, prec); _acb_vec_clear(t, n); _acb_vec_clear(u, n); } acb_swap(g, c); acb_clear(c); }
int main() { slong iter; flint_rand_t state; flint_printf("rising2_ui...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000; iter++) { acb_t a, u, v, u2, v2; fmpz *f; acb_ptr g; ulong n; slong i, prec; acb_init(a); acb_init(u); acb_init(v); acb_init(u2); acb_init(v2); acb_randtest(a, state, 1 + n_randint(state, 4000), 10); acb_randtest(u, state, 1 + n_randint(state, 4000), 10); acb_randtest(v, state, 1 + n_randint(state, 4000), 10); n = n_randint(state, 120); f = _fmpz_vec_init(n + 1); g = _acb_vec_init(n + 1); prec = 2 + n_randint(state, 4000); acb_rising2_ui(u, v, a, n, prec); arith_stirling_number_1u_vec(f, n, n + 1); for (i = 0; i <= n; i++) acb_set_fmpz(g + i, f + i); _acb_poly_evaluate(u2, g, n + 1, a, prec); _acb_poly_derivative(g, g, n + 1, prec); _acb_poly_evaluate(v2, g, n, a, prec); if (!acb_overlaps(u, u2) || !acb_overlaps(v, v2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("n = %wu\n", n); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); acb_printd(u2, 15); flint_printf("\n\n"); flint_printf("v = "); acb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); acb_printd(v2, 15); flint_printf("\n\n"); abort(); } acb_set(u2, a); acb_rising2_ui(u2, v, u2, n, prec); if (!acb_equal(u2, u)) { flint_printf("FAIL: aliasing 1\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("u = "); acb_printd(u, 15); flint_printf("\n\n"); flint_printf("u2 = "); acb_printd(u2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); abort(); } acb_set(v2, a); acb_rising2_ui(u, v2, v2, n, prec); if (!acb_equal(v2, v)) { flint_printf("FAIL: aliasing 2\n\n"); flint_printf("a = "); acb_printd(a, 15); flint_printf("\n\n"); flint_printf("v = "); acb_printd(v, 15); flint_printf("\n\n"); flint_printf("v2 = "); acb_printd(v2, 15); flint_printf("\n\n"); flint_printf("n = %wu\n", n); abort(); } acb_clear(a); acb_clear(u); acb_clear(v); acb_clear(u2); acb_clear(v2); _fmpz_vec_clear(f, n + 1); _acb_vec_clear(g, n + 1); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
slong _acb_poly_validate_roots(acb_ptr roots, acb_srcptr poly, slong len, slong prec) { slong i, j, deg; slong isolated, nonisolated, total_isolated; acb_ptr deriv; acb_ptr tmp; int *overlap; deg = len - 1; deriv = _acb_vec_init(deg); overlap = flint_calloc(deg, sizeof(int)); tmp = flint_malloc(sizeof(acb_struct) * deg); _acb_poly_derivative(deriv, poly, len, prec); /* compute an inclusion interval for each point */ for (i = 0; i < deg; i++) { _acb_poly_root_inclusion(roots + i, roots + i, poly, deriv, len, prec); } /* find which points do not overlap with any other points */ for (i = 0; i < deg; i++) { for (j = i + 1; j < deg; j++) { if (acb_overlaps(roots + i, roots + j)) { overlap[i] = overlap[j] = 1; } } } /* count and move all isolated roots to the front of the array */ total_isolated = 0; for (i = 0; i < deg; i++) total_isolated += (overlap[i] == 0); for (i = 0; i < deg; i++) tmp[i] = roots[i]; isolated = 0; nonisolated = 0; for (i = 0; i < deg; i++) { if (overlap[i] == 0) { roots[isolated] = tmp[i]; isolated++; } else { roots[total_isolated + nonisolated] = tmp[i]; nonisolated++; } } _acb_vec_clear(deriv, deg); flint_free(tmp); flint_free(overlap); return isolated; }
int main() { long iter; flint_rand_t state; printf("elliptic_p_zpx...."); fflush(stdout); flint_randinit(state); /* Test differential equation */ for (iter = 0; iter < 5000; iter++) { acb_t tau, z; acb_ptr g, wp, wp3, wpd, wpd2; long prec, len, i; len = 1 + n_randint(state, 15); prec = 2 + n_randint(state, 1000); acb_init(tau); acb_init(z); g = _acb_vec_init(2); wp = _acb_vec_init(len + 1); wp3 = _acb_vec_init(len); wpd = _acb_vec_init(len); wpd2 = _acb_vec_init(len); acb_randtest(tau, state, prec, 10); acb_randtest(z, state, prec, 10); acb_modular_elliptic_p_zpx(wp, z, tau, len + 1, prec); acb_modular_eisenstein(g, tau, 2, prec); acb_mul_ui(g, g, 60, prec); acb_mul_ui(g + 1, g + 1, 140, prec); _acb_poly_derivative(wpd, wp, len + 1, prec); _acb_poly_mullow(wpd2, wpd, len, wpd, len, len, prec); _acb_poly_pow_ui_trunc_binexp(wp3, wp, len, 3, len, prec); _acb_vec_scalar_mul_ui(wp3, wp3, len, 4, prec); _acb_vec_scalar_submul(wp3, wp, len, g, prec); acb_sub(wp3, wp3, g + 1, prec); for (i = 0; i < len; i++) { if (!acb_overlaps(wpd2 + i, wp3 + i)) { printf("FAIL (overlap)\n"); printf("i = %ld len = %ld prec = %ld\n\n", i, len, prec); printf("z = "); acb_printd(z, 15); printf("\n\n"); printf("tau = "); acb_printd(tau, 15); printf("\n\n"); printf("wp = "); acb_printd(wp + i, 15); printf("\n\n"); printf("wpd = "); acb_printd(wpd + i, 15); printf("\n\n"); printf("wp3 = "); acb_printd(wp3 + i, 15); printf("\n\n"); abort(); } } acb_clear(tau); acb_clear(z); _acb_vec_clear(g, 2); _acb_vec_clear(wp, len + 1); _acb_vec_clear(wp3, len); _acb_vec_clear(wpd, len); _acb_vec_clear(wpd2, len); } /* Consistency test */ for (iter = 0; iter < 5000; iter++) { acb_t tau, z; acb_ptr wp1, wp2; long prec1, prec2, len1, len2, i; len1 = n_randint(state, 15); len2 = n_randint(state, 15); prec1 = 2 + n_randint(state, 1000); prec2 = 2 + n_randint(state, 1000); acb_init(tau); acb_init(z); wp1 = _acb_vec_init(len1); wp2 = _acb_vec_init(len2); acb_randtest(tau, state, prec1, 10); acb_randtest(z, state, prec1, 10); acb_modular_elliptic_p_zpx(wp1, z, tau, len1, prec1); acb_modular_elliptic_p_zpx(wp2, z, tau, len2, prec2); for (i = 0; i < FLINT_MIN(len1, len2); i++) { if (!acb_overlaps(wp1 + i, wp2 + i)) { printf("FAIL (overlap)\n"); printf("i = %ld len1 = %ld len2 = %ld\n\n", i, len1, len2); printf("tau = "); acb_printd(tau, 15); printf("\n\n"); printf("z = "); acb_printd(z, 15); printf("\n\n"); printf("wp1 = "); acb_printd(wp1 + i, 15); printf("\n\n"); printf("wp2 = "); acb_printd(wp2 + i, 15); printf("\n\n"); abort(); } } acb_clear(tau); acb_clear(z); _acb_vec_clear(wp1, len1); _acb_vec_clear(wp2, len2); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void _acb_poly_digamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec) { int reflect; slong i, r, n, rflen, wp; acb_t zr; acb_ptr t, u, v; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { acb_digamma(res, h, prec); if (acb_is_finite(res)) _acb_vec_zero(res + 1, len - 1); else _acb_vec_indeterminate(res + 1, len - 1); return; } /* use real code for real input */ if (_acb_vec_is_real(h, hlen)) { arb_ptr tmp = _arb_vec_init(len); for (i = 0; i < hlen; i++) arb_set(tmp + i, acb_realref(h + i)); _arb_poly_digamma_series(tmp, tmp, hlen, len, prec); for (i = 0; i < len; i++) acb_set_arb(res + i, tmp + i); _arb_vec_clear(tmp, len); return; } wp = prec + FLINT_BIT_COUNT(prec); t = _acb_vec_init(len + 1); u = _acb_vec_init(len + 1); v = _acb_vec_init(len + 1); acb_init(zr); /* use Stirling series */ acb_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 1, wp); /* psi(x) = psi((1-x)+r) - h(1-x,r) - pi*cot(pi*x) */ if (reflect) { if (r != 0) /* otherwise t = 0 */ { acb_sub_ui(v, h, 1, wp); acb_neg(v, v); acb_one(v + 1); rflen = FLINT_MIN(len + 1, r + 1); _acb_poly_rising_ui_series(u, v, 2, r, rflen, wp); _acb_poly_derivative(v, u, rflen, wp); _acb_poly_div_series(t, v, rflen - 1, u, rflen, len, wp); for (i = 1; i < len; i += 2) acb_neg(t + i, t + i); } acb_sub_ui(zr, h, r + 1, wp); acb_neg(zr, zr); _acb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); for (i = 1; i < len; i += 2) acb_neg(u + i, u + i); _acb_vec_sub(u, u, t, len, wp); acb_set(t, h); acb_one(t + 1); _acb_poly_cot_pi_series(t, t, 2, len, wp); acb_const_pi(v, wp); _acb_vec_scalar_mul(t, t, len, v, wp); _acb_vec_sub(u, u, t, len, wp); } else { if (r == 0) { acb_add_ui(zr, h, r, wp); _acb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); } else { acb_set(v, h); acb_one(v + 1); rflen = FLINT_MIN(len + 1, r + 1); _acb_poly_rising_ui_series(u, v, 2, r, rflen, wp); _acb_poly_derivative(v, u, rflen, wp); _acb_poly_div_series(t, v, rflen - 1, u, rflen, len, wp); acb_add_ui(zr, h, r, wp); _acb_poly_gamma_stirling_eval2(u, zr, n, len + 1, 1, wp); _acb_vec_sub(u, u, t, len, wp); } } /* compose with nonconstant part */ acb_zero(t); _acb_vec_set(t + 1, h + 1, hlen - 1); _acb_poly_compose_series(res, u, len, t, hlen, len, prec); acb_clear(zr); _acb_vec_clear(t, len + 1); _acb_vec_clear(u, len + 1); _acb_vec_clear(v, len + 1); }