void _arb_poly_sinh_cosh_series(arb_ptr s, arb_ptr c, const arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sinh_cosh(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_set(t, h + 1); arb_sinh_cosh(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_mul(c + 1, s, t, prec); arb_clear(t); } else if (hlen < 60 || n < 120) _arb_poly_sinh_cosh_series_basecase(s, c, h, hlen, n, prec); else _arb_poly_sinh_cosh_series_exponential(s, c, h, hlen, n, prec); }
void _arb_poly_sin_cos_pi_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin_cos_pi(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_const_pi(t, prec); arb_mul(t, t, h + 1, prec); arb_sin_cos_pi(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_neg(t, t); arb_mul(c + 1, s, t, prec); arb_clear(t); } else if (hlen < TANGENT_CUTOFF) _arb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 1); else _arb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 1); }
void _arb_poly_div_root(arb_ptr Q, arb_t R, arb_srcptr A, slong len, const arb_t c, slong prec) { arb_t r, t; slong i; if (len < 2) { arb_zero(R); return; } arb_init(r); arb_init(t); arb_set(t, A + len - 2); arb_set(Q + len - 2, A + len - 1); arb_set(r, Q + len - 2); /* TODO: avoid the extra assignments (but still support aliasing) */ for (i = len - 2; i > 0; i--) { arb_mul(r, r, c, prec); arb_add(r, r, t, prec); arb_set(t, A + i - 1); arb_set(Q + i - 1, r); } arb_mul(r, r, c, prec); arb_add(R, r, t, prec); }
static void _newton_to_monomial(arb_ptr ys, arb_srcptr xs, long n, long prec) { arb_t t, u; long i, j; arb_init(t); arb_init(u); for (i = n - 2; i >= 0; i--) { arb_set(t, ys + i); arb_set(ys + i, ys + i + 1); for (j = i + 1; j < n - 1; j++) { arb_mul(u, ys + j, xs + i, prec); arb_sub(ys + j, ys + j + 1, u, prec); } arb_mul(u, ys + n - 1, xs + i, prec); arb_sub(ys + n - 1, t, u, prec); } _arb_poly_reverse(ys, ys, n, n); arb_clear(t); arb_clear(u); }
void _arb_poly_evaluate_rectangular(arb_t y, arb_srcptr poly, long len, const arb_t x, long prec) { long i, j, m, r; arb_ptr xs; arb_t s, t, c; if (len < 3) { if (len == 0) { arb_zero(y); } else if (len == 1) { arb_set_round(y, poly + 0, prec); } else if (len == 2) { arb_mul(y, x, poly + 1, prec); arb_add(y, y, poly + 0, prec); } return; } m = n_sqrt(len) + 1; r = (len + m - 1) / m; xs = _arb_vec_init(m + 1); arb_init(s); arb_init(t); arb_init(c); _arb_vec_set_powers(xs, x, m + 1, prec); arb_set(y, poly + (r - 1) * m); for (j = 1; (r - 1) * m + j < len; j++) arb_addmul(y, xs + j, poly + (r - 1) * m + j, prec); for (i = r - 2; i >= 0; i--) { arb_set(s, poly + i * m); for (j = 1; j < m; j++) arb_addmul(s, xs + j, poly + i * m + j, prec); arb_mul(y, y, xs + m, prec); arb_add(y, y, s, prec); } _arb_vec_clear(xs, m + 1); arb_clear(s); arb_clear(t); arb_clear(c); }
/* Bound for scaled Bessel function: 2/(2 pi x)^(1/2) Bound for tail of integral: 2 N (k / (pi N))^(k / 2) / (k - 2). */ void scaled_bessel_tail_bound(arb_t b, ulong k, const arb_t N, slong prec) { arb_const_pi(b, prec); arb_mul(b, b, N, prec); arb_ui_div(b, k, b, prec); arb_sqrt(b, b, prec); arb_pow_ui(b, b, k, prec); arb_mul(b, b, N, prec); arb_mul_ui(b, b, 2, prec); arb_div_ui(b, b, k - 2, prec); }
static void bound_I(arb_ptr I, const arb_t A, const arb_t B, const arb_t C, slong len, slong wp) { slong k; arb_t D, Dk, L, T, Bm1; arb_init(D); arb_init(Dk); arb_init(Bm1); arb_init(T); arb_init(L); arb_sub_ui(Bm1, B, 1, wp); arb_one(L); /* T = 1 / (A^Bm1 * Bm1) */ arb_inv(T, A, wp); arb_pow(T, T, Bm1, wp); arb_div(T, T, Bm1, wp); if (len > 1) { arb_log(D, A, wp); arb_add(D, D, C, wp); arb_mul(D, D, Bm1, wp); arb_set(Dk, D); } for (k = 0; k < len; k++) { if (k > 0) { arb_mul_ui(L, L, k, wp); arb_add(L, L, Dk, wp); arb_mul(Dk, Dk, D, wp); } arb_mul(I + k, L, T, wp); arb_div(T, T, Bm1, wp); } arb_clear(D); arb_clear(Dk); arb_clear(Bm1); arb_clear(T); arb_clear(L); }
void _arb_poly_tan_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_tan(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_t t; arb_init(t); arb_tan(g, h, prec); arb_mul(t, g, g, prec); arb_add_ui(t, t, 1, prec); arb_mul(g + 1, t, h + 1, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t, u; t = _arb_vec_init(2 * len); u = t + len; NEWTON_INIT(TAN_NEWTON_CUTOFF, len) NEWTON_BASECASE(n) _arb_poly_sin_cos_series_basecase(t, u, h, hlen, n, prec, 0); _arb_poly_div_series(g, t, n, u, n, n, prec); NEWTON_END_BASECASE NEWTON_LOOP(m, n) _arb_poly_mullow(u, g, m, g, m, n, prec); arb_add_ui(u, u, 1, prec); _arb_poly_atan_series(t, g, m, n, prec); _arb_poly_sub(t + m, h + m, FLINT_MAX(0, hlen - m), t + m, n - m, prec); _arb_poly_mullow(g + m, u, n, t + m, n - m, n - m, prec); NEWTON_END_LOOP NEWTON_END _arb_vec_clear(t, 2 * len); } }
int f_pol(arb_t max, const arb_t t, params_t * p, slong prec) { slong k; acb_t z; arb_t tmp; acb_init(z); arb_init(tmp); arb_one(max); for (k = 0; k < p->len; k++) { acb_sub_arb(z, p->z + k, t, prec); acb_abs(tmp, z, prec); if (arb_contains_zero(tmp)) return 0; arb_mul(max, max, tmp, prec); } arb_inv(max, max, prec); arb_clear(tmp); acb_clear(z); return 1; }
void _arb_poly_sqrt_series(arb_ptr g, arb_srcptr h, long hlen, long len, long prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_sqrt(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else if (len == 2) { arb_sqrt(g, h, prec); arb_div(g + 1, h + 1, h, prec); arb_mul(g + 1, g + 1, g, prec); arb_mul_2exp_si(g + 1, g + 1, -1); } else { arb_ptr t; t = _arb_vec_init(len); _arb_poly_rsqrt_series(t, h, hlen, len, prec); _arb_poly_mullow(g, t, len, h, hlen, len, prec); _arb_vec_clear(t, len); } }
void _arb_poly_sinh_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sinh(g, h, prec); _arb_vec_zero(g + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_sinh_cosh(g, t, h, prec); arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ arb_clear(t); } else { arb_ptr t = _arb_vec_init(n); _arb_poly_sinh_cosh_series(g, t, h, hlen, n, prec); _arb_vec_clear(t, n); } }
void _arb_poly_log1p_series(arb_ptr res, arb_srcptr f, slong flen, slong n, slong prec) { arb_t a; flen = FLINT_MIN(flen, n); arb_init(a); arb_log1p(a, f, prec); if (flen == 1) { _arb_vec_zero(res + 1, n - 1); } else if (n == 2) { arb_add_ui(res, f + 0, 1, prec); arb_div(res + 1, f + 1, res + 0, prec); } else if (_arb_vec_is_zero(f + 1, flen - 2)) /* f = a + bx^d */ { slong i, j, d = flen - 1; arb_add_ui(res, f + 0, 1, prec); for (i = 1, j = d; j < n; j += d, i++) { if (i == 1) arb_div(res + j, f + d, res, prec); else arb_mul(res + j, res + j - d, res + d, prec); _arb_vec_zero(res + j - d + 1, flen - 2); } _arb_vec_zero(res + j - d + 1, n - (j - d + 1)); for (i = 2, j = 2 * d; j < n; j += d, i++) arb_div_si(res + j, res + j, i % 2 ? i : -i, prec); } else { arb_ptr f_diff, f_inv; slong alloc; alloc = n + flen; f_inv = _arb_vec_init(alloc); f_diff = f_inv + n; arb_add_ui(f_diff, f, 1, prec); _arb_vec_set(f_diff + 1, f + 1, flen - 1); _arb_poly_inv_series(f_inv, f_diff, flen, n, prec); _arb_poly_derivative(f_diff, f, flen, prec); _arb_poly_mullow(res, f_inv, n - 1, f_diff, flen - 1, n - 1, prec); _arb_poly_integral(res, res, n, prec); _arb_vec_clear(f_inv, alloc); } arb_swap(res, a); arb_clear(a); }
void _arb_poly_product_roots(arb_ptr poly, arb_srcptr xs, slong n, slong prec) { if (n == 0) { arb_one(poly); } else if (n == 1) { arb_neg(poly, xs); arb_one(poly + 1); } else if (n == 2) { arb_mul(poly, xs + 0, xs + 1, prec); arb_add(poly + 1, xs + 0, xs + 1, prec); arb_neg(poly + 1, poly + 1); arb_one(poly + 2); } else { const slong m = (n + 1) / 2; arb_ptr tmp; tmp = _arb_vec_init(n + 2); _arb_poly_product_roots(tmp, xs, m, prec); _arb_poly_product_roots(tmp + m + 1, xs + m, n - m, prec); _arb_poly_mul_monic(poly, tmp, m + 1, tmp + m + 1, n - m + 1, prec); _arb_vec_clear(tmp, n + 2); } }
void arb_sech(arb_t res, const arb_t x, slong prec) { if (arf_cmpabs_2exp_si(arb_midref(x), 0) > 0) { arb_t t; arb_init(t); if (arf_sgn(arb_midref(x)) > 0) { arb_neg(t, x); arb_exp(t, t, prec + 4); } else { arb_exp(t, x, prec + 4); } arb_mul(res, t, t, prec + 4); arb_add_ui(res, res, 1, prec + 4); arb_div(res, t, res, prec); arb_mul_2exp_si(res, res, 1); arb_clear(t); } else { arb_cosh(res, x, prec + 4); arb_inv(res, res, prec); } }
static void arb_sqrt1pm1_tiny(arb_t r, const arb_t z, slong prec) { mag_t b, c; arb_t t; mag_init(b); mag_init(c); arb_init(t); /* if |z| < 1, then |(sqrt(1+z)-1) - (z/2-z^2/8)| <= |z|^3/(1-|z|)/16 */ arb_get_mag(b, z); mag_one(c); mag_sub_lower(c, c, b); mag_pow_ui(b, b, 3); mag_div(b, b, c); mag_mul_2exp_si(b, b, -4); arb_mul(t, z, z, prec); arb_mul_2exp_si(t, t, -2); arb_sub(r, z, t, prec); arb_mul_2exp_si(r, r, -1); if (mag_is_finite(b)) arb_add_error_mag(r, b); else arb_indeterminate(r); mag_clear(b); mag_clear(c); arb_clear(t); }
void _arb_poly_revert_series_lagrange_fast(arb_ptr Qinv, arb_srcptr Q, long Qlen, long n, long prec) { long i, j, k, m; arb_ptr R, S, T, tmp; arb_t t; if (n <= 2) { if (n >= 1) arb_zero(Qinv); if (n == 2) arb_inv(Qinv + 1, Q + 1, prec); return; } m = n_sqrt(n); arb_init(t); R = _arb_vec_init((n - 1) * m); S = _arb_vec_init(n - 1); T = _arb_vec_init(n - 1); arb_zero(Qinv); arb_inv(Qinv + 1, Q + 1, prec); _arb_poly_inv_series(Ri(1), Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); for (i = 2; i <= m; i++) _arb_poly_mullow(Ri(i), Ri((i + 1) / 2), n - 1, Ri(i / 2), n - 1, n - 1, prec); for (i = 2; i < m; i++) arb_div_ui(Qinv + i, Ri(i) + i - 1, i, prec); _arb_vec_set(S, Ri(m), n - 1); for (i = m; i < n; i += m) { arb_div_ui(Qinv + i, S + i - 1, i, prec); for (j = 1; j < m && i + j < n; j++) { arb_mul(t, S + 0, Ri(j) + i + j - 1, prec); for (k = 1; k <= i + j - 1; k++) arb_addmul(t, S + k, Ri(j) + i + j - 1 - k, prec); arb_div_ui(Qinv + i + j, t, i + j, prec); } if (i + 1 < n) { _arb_poly_mullow(T, S, n - 1, Ri(m), n - 1, n - 1, prec); tmp = S; S = T; T = tmp; } } arb_clear(t); _arb_vec_clear(R, (n - 1) * m); _arb_vec_clear(S, n - 1); _arb_vec_clear(T, n - 1); }
/* compose by poly2 = a*x^n + c, no aliasing; n >= 1 */ void _arb_poly_compose_axnc(arb_ptr res, arb_srcptr poly1, slong len1, const arb_t c, const arb_t a, slong n, slong prec) { slong i; _arb_vec_set_round(res, poly1, len1, prec); /* shift by c (c = 0 case will be fast) */ _arb_poly_taylor_shift(res, c, len1, prec); /* multiply by powers of a */ if (!arb_is_one(a)) { if (arb_equal_si(a, -1)) { for (i = 1; i < len1; i += 2) arb_neg(res + i, res + i); } else if (len1 == 2) { arb_mul(res + 1, res + 1, a, prec); } else { arb_t t; arb_init(t); arb_set(t, a); for (i = 1; i < len1; i++) { arb_mul(res + i, res + i, t, prec); if (i + 1 < len1) arb_mul(t, t, a, prec); } arb_clear(t); } } /* stretch */ for (i = len1 - 1; i >= 1 && n > 1; i--) { arb_swap(res + i * n, res + i); _arb_vec_zero(res + (i - 1) * n + 1, n - 1); } }
int f_1x2(arb_t max, const arb_t t, params_t * p, slong prec) { arb_mul(max, t, t, prec); arb_add_si(max, max, 1, prec); arb_inv(max, max, prec); return 1; }
static void _update_aggregated_state_frechet_matrices( cross_site_ws_t csw, model_and_data_t m, nd_axis_struct *edge_axis, nd_axis_struct *trans_axis, const int *first_idx, const int *second_idx, slong prec) { arb_mat_t P, L, Q; arb_t rate; slong first_state, second_state; slong cat, trans_idx; slong state_count = model_and_data_state_count(m); slong edge_count = model_and_data_edge_count(m); slong rate_category_count = model_and_data_rate_category_count(m); arb_init(rate); arb_mat_init(P, state_count, state_count); arb_mat_init(L, state_count, state_count); arb_mat_init(Q, state_count, state_count); /* set entries of L to the requested transition weights */ for (trans_idx = 0; trans_idx < trans_axis->n; trans_idx++) { first_state = first_idx[trans_idx]; second_state = second_idx[trans_idx]; arb_add(arb_mat_entry(L, first_state, second_state), arb_mat_entry(L, first_state, second_state), trans_axis->agg_weights + trans_idx, prec); } /* multiply entries of L by the rate matrix entries */ arb_mat_mul_entrywise(L, L, csw->rate_matrix, prec); /* divide L by the global weight divisor */ arb_mat_scalar_div_arb(L, L, trans_axis->agg_weight_divisor, prec); for (cat = 0; cat < rate_category_count; cat++) { slong edge; const arb_struct * cat_rate = csw->rate_mix_rates + cat; for (edge = 0; edge < edge_count; edge++) { slong idx = m->edge_map->order[edge]; const arb_struct * edge_rate = csw->edge_rates + idx; arb_mat_struct *fmat; if (!edge_axis->request_update[edge]) continue; fmat = cross_site_ws_trans_frechet_matrix(csw, cat, idx); arb_mul(rate, edge_rate, cat_rate, prec); arb_mat_scalar_mul_arb(Q, csw->rate_matrix, rate, prec); _arb_mat_exp_frechet(P, fmat, Q, L, prec); } } arb_clear(rate); arb_mat_clear(P); arb_mat_clear(L); arb_mat_clear(Q); }
void nd_accum_accumulate(nd_accum_t a, int *coords, arb_struct *value, slong prec) { int axis_idx; int offset, coord, stride; nd_axis_struct *axis; arb_struct *p; arb_t x; arb_init(x); arb_set(x, value); offset = 0; for (axis_idx = 0; axis_idx < a->ndim; axis_idx++) { axis = a->axes + axis_idx; coord = coords[axis_idx]; stride = a->strides[axis_idx]; /* flint_printf("debug:\n"); flint_printf("ndim=%wd axis=%d coord=%d\n", a->ndim, axis_idx, coord); flint_printf("strides:\n"); { int j; for (j = 0; j < a->ndim; j++) { flint_printf("%d : %d\n", j, a->strides[j]); } } */ if (axis->agg_weights) { arb_mul(x, x, axis->agg_weights + coord, prec); /* todo: delay this division */ arb_div(x, x, axis->agg_weight_divisor, prec); } else { offset += coord * stride; } } if (offset < 0) { fprintf(stderr, "internal error: negative offset\n"); abort(); } if (offset >= a->size) { fprintf(stderr, "internal error: offset=%d >= size=%d\n", offset, a->size); abort(); } p = a->data + offset; arb_add(p, p, x, prec); arb_clear(x); }
void arb_zeta_ui_borwein_bsplit(arb_t x, ulong s, slong prec) { zeta_bsplit_t sum; mag_t err; slong wp, n; /* zeta(0) = -1/2 */ if (s == 0) { arb_set_si(x, -1); arb_mul_2exp_si(x, x, -1); return; } if (s == 1) { flint_printf("zeta_ui_borwein_bsplit: zeta(1)"); abort(); } n = prec / ERROR_B + 2; wp = prec + 30; zeta_bsplit_init(sum); zeta_bsplit(sum, 0, n + 1, n, s, 0, wp); /* A/Q3 - B/Q3 / (C/Q1) = (A*C - B*Q1) / (Q3*C) */ arb_mul(sum->A, sum->A, sum->C, wp); arb_mul(sum->B, sum->B, sum->Q1, wp); arb_sub(sum->A, sum->A, sum->B, wp); arb_mul(sum->Q3, sum->Q3, sum->C, wp); arb_div(sum->C, sum->A, sum->Q3, wp); mag_init(err); mag_borwein_error(err, n); mag_add(arb_radref(sum->C), arb_radref(sum->C), err); mag_clear(err); /* convert from eta(s) to zeta(s) */ arb_div_2expm1_ui(x, sum->C, s - 1, wp); arb_mul_2exp_si(x, x, s - 1); zeta_bsplit_clear(sum); }
void arb_submul_naive(arb_t z, const arb_t x, const arb_t y, slong prec) { arb_t t; arb_init(t); arb_mul(t, x, y, ARF_PREC_EXACT); arb_sub(z, z, t, prec); arb_clear(t); }
int main() { slong iter; flint_rand_t state; flint_printf("sin_cos_pi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++) { arb_t a, b, c, d, e; slong prec = 2 + n_randint(state, 200); arb_init(a); arb_init(b); arb_init(c); arb_init(d); arb_init(e); arb_randtest(a, state, 1 + n_randint(state, 200), 10); arb_randtest(b, state, 1 + n_randint(state, 200), 10); arb_randtest(c, state, 1 + n_randint(state, 200), 10); arb_randtest(d, state, 1 + n_randint(state, 200), 10); arb_randtest(e, state, 1 + n_randint(state, 200), 10); arb_const_pi(b, prec); arb_mul(b, b, a, prec); arb_sin_cos(b, d, b, prec); arb_sin_cos_pi(c, e, a, prec); if (!arb_overlaps(b, c) || !arb_overlaps(d, e)) { flint_printf("FAIL: overlap\n\n"); flint_printf("a = "); arb_print(a); flint_printf("\n\n"); flint_printf("b = "); arb_print(b); flint_printf("\n\n"); flint_printf("c = "); arb_print(c); flint_printf("\n\n"); flint_printf("d = "); arb_print(d); flint_printf("\n\n"); flint_printf("e = "); arb_print(e); flint_printf("\n\n"); flint_abort(); } arb_clear(a); arb_clear(b); arb_clear(c); arb_clear(d); arb_clear(e); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
void acb_tan_pi(acb_t r, const acb_t z, slong prec) { if (arb_is_zero(acb_imagref(z))) { arb_tan_pi(acb_realref(r), acb_realref(z), prec); arb_zero(acb_imagref(r)); } else if (arb_is_zero(acb_realref(z))) { arb_t t; arb_init(t); arb_const_pi(t, prec + 4); arb_mul(t, acb_imagref(z), t, prec + 4); arb_tanh(acb_imagref(r), t, prec); arb_zero(acb_realref(r)); arb_clear(t); } else { acb_t t; acb_init(t); if (arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 0) < 0) { acb_sin_cos_pi(r, t, z, prec + 4); acb_div(r, r, t, prec); } else { acb_mul_2exp_si(t, z, 1); if (arf_sgn(arb_midref(acb_imagref(z))) > 0) { acb_exp_pi_i(t, t, prec + 4); acb_add_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_div_onei(r, r); } else { acb_neg(t, t); acb_exp_pi_i(t, t, prec + 4); acb_add_ui(r, t, 1, prec + 4); acb_div(r, t, r, prec + 4); acb_mul_2exp_si(r, r, 1); acb_sub_ui(r, r, 1, prec); acb_mul_onei(r, r); } } acb_clear(t); } }
void acb_dirichlet_vec_mellin_arb(acb_ptr res, const dirichlet_group_t G, const dirichlet_char_t chi, slong len, const arb_t t, slong n, slong prec) { slong k; arb_t tk, xt, stk, st; acb_ptr a; mag_t e; a = _acb_vec_init(len); acb_dirichlet_chi_vec(a, G, chi, len, prec); if (dirichlet_parity_char(G, chi)) { for (k = 2; k < len; k++) acb_mul_si(a + k, a + k, k, prec); } arb_init(tk); arb_init(xt); arb_init(st); arb_init(stk); mag_init(e); arb_sqrt(st, t, prec); arb_one(tk); arb_one(stk); for (k = 0; k < n; k++) { _acb_dirichlet_theta_argument_at_arb(xt, G->q, tk, prec); mag_tail_kexpk2_arb(e, xt, len); arb_neg(xt, xt); arb_exp(xt, xt, prec); /* TODO: reduce len */ acb_dirichlet_qseries_arb(res + k, a, xt, len, prec); acb_add_error_mag(res + k, e); acb_mul_arb(res + k, res + k, stk, prec); arb_mul(tk, tk, t, prec); arb_mul(stk, stk, st, prec); } mag_clear(e); arb_clear(xt); arb_clear(tk); arb_clear(stk); arb_clear(st); _acb_vec_clear(a, len); }
/* series of c^(d+x) */ static __inline__ void _arb_poly_pow_cpx(arb_ptr res, const arb_t c, const arb_t d, long trunc, long prec) { long i; arb_t logc; arb_init(logc); arb_log(logc, c, prec); arb_mul(res + 0, logc, d, prec); arb_exp(res + 0, res + 0, prec); for (i = 1; i < trunc; i++) { arb_mul(res + i, res + i - 1, logc, prec); arb_div_ui(res + i, res + i, i, prec); } arb_clear(logc); }
void arb_twobytwo_diag(arb_t u1, arb_t u2, const arb_t a, const arb_t b, const arb_t d, slong prec) { // Compute the orthogonal matrix that diagonalizes // // A = [a b] // [b d] // // This matrix will have the form // // U = [cos x , -sin x] // [sin x, cos x] // // where the diagonal matrix is U^t A U. // We set u1 = cos x, u2 = -sin x. if(arb_contains_zero(b)) { // this is not quite right (doesn't set error intervals) arb_set_ui(u1, 1); arb_set_ui(u2, 0); return; } arb_t x; arb_init(x); arb_mul(u1, b, b, prec); // u1 = b^2 arb_sub(u2, a, d, prec); // u2 = a - d arb_mul_2exp_si(u2, u2, -1); // u2 = (a - d)/2 arb_mul(u2, u2, u2, prec); // u2 = ( (a - d)/2 )^2 arb_add(u1, u1, u2, prec); // u1 = b^2 + ( (a-d)/2 )^2 arb_sqrt(u1, u1, prec); // u1 = sqrt(above) arb_mul_2exp_si(u1, u1, 1); // u1 = 2 (sqrt (above) ) arb_add(u1, u1, d, prec); // u1 += d arb_sub(u1, u1, a, prec); // u1 -= a arb_mul_2exp_si(u1, u1, -1); // u1 = (d - a)/2 + sqrt(b^2 + ( (a-d)/2 )^2) arb_mul(x, u1, u1, prec); arb_addmul(x, b, b, prec); // x = u1^2 + b^2 arb_sqrt(x, x, prec); // x = sqrt(u1^2 + b^2) arb_div(u2, u1, x, prec); arb_div(u1, b, x, prec); arb_neg(u1, u1); arb_clear(x); }
void _arb_poly_compose_series(arb_ptr res, arb_srcptr poly1, slong len1, arb_srcptr poly2, slong len2, slong n, slong prec) { if (len2 == 1) { arb_set_round(res, poly1, prec); _arb_vec_zero(res + 1, n - 1); } else if (_arb_vec_is_zero(poly2 + 1, len2 - 2)) /* poly2 is a monomial */ { slong i, j; arb_t t; arb_init(t); arb_set(t, poly2 + len2 - 1); arb_set_round(res, poly1, prec); for (i = 1, j = len2 - 1; i < len1 && j < n; i++, j += len2 - 1) { arb_mul(res + j, poly1 + i, t, prec); if (i + 1 < len1 && j + len2 - 1 < n) arb_mul(t, t, poly2 + len2 - 1, prec); } if (len2 != 2) for (i = 1; i < n; i++) if (i % (len2 - 1) != 0) arb_zero(res + i); arb_clear(t); } else if (len1 < 6 || n < 6) { _arb_poly_compose_series_horner(res, poly1, len1, poly2, len2, n, prec); } else { _arb_poly_compose_series_brent_kung(res, poly1, len1, poly2, len2, n, prec); } }
void _arb_poly_sin_cos_series(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { hlen = FLINT_MIN(hlen, n); if (hlen == 1) { arb_sin_cos(s, c, h, prec); _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); } else if (n == 2) { arb_t t; arb_init(t); arb_set(t, h + 1); arb_sin_cos(s, c, h, prec); arb_mul(s + 1, c, t, prec); arb_neg(t, t); arb_mul(c + 1, s, t, prec); arb_clear(t); } else { slong cutoff; if (prec <= 128) { cutoff = 1400; } else { cutoff = 100000 / pow(log(prec), 3); cutoff = FLINT_MIN(cutoff, 700); } if (hlen < cutoff) _arb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec, 0); else _arb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec, 0); } }
void arb_agm(arb_t z, const arb_t x, const arb_t y, long prec) { arb_t t, u, v, w; if (arb_contains_negative(x) || arb_contains_negative(y)) { arb_indeterminate(z); return; } if (arb_is_zero(x) || arb_is_zero(y)) { arb_zero(z); return; } arb_init(t); arb_init(u); arb_init(v); arb_init(w); arb_set(t, x); arb_set(u, y); while (!arb_overlaps(t, u) && !arb_contains_nonpositive(t) && !arb_contains_nonpositive(u)) { arb_add(v, t, u, prec); arb_mul_2exp_si(v, v, -1); arb_mul(w, t, u, prec); arb_sqrt(w, w, prec); arb_swap(v, t); arb_swap(w, u); } if (!arb_is_finite(t) || !arb_is_finite(u)) { arb_indeterminate(z); } else { arb_union(z, t, u, prec); } arb_clear(t); arb_clear(u); arb_clear(v); arb_clear(w); }