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); }
static void likelihood_ws_init(likelihood_ws_t w, const model_and_data_t m) { slong node_count = model_and_data_node_count(m); slong edge_count = model_and_data_edge_count(m); slong state_count = model_and_data_state_count(m); w->edge_expectations = _arb_vec_init(edge_count); w->cc_edge_expectations = _arb_vec_init(edge_count); w->base_node_vectors = _arb_mat_vec_init(state_count, 1, node_count); w->lhood_node_vectors = _arb_mat_vec_init(state_count, 1, node_count); w->lhood_edge_vectors = _arb_mat_vec_init(state_count, 1, edge_count); w->forward_node_vectors = _arb_mat_vec_init(state_count, 1, node_count); w->forward_edge_vectors = _arb_mat_vec_init(state_count, 1, edge_count); }
static void _arb_poly_rising_ui_series_bsplit(arb_ptr res, arb_srcptr f, slong flen, ulong a, ulong b, slong trunc, slong prec) { flen = FLINT_MIN(flen, trunc); if (b - a == 1) { arb_add_ui(res, f, a, prec); _arb_vec_set(res + 1, f + 1, flen - 1); } else { arb_ptr L, R; slong len1, len2; slong m = a + (b - a) / 2; len1 = poly_pow_length(flen, m - a, trunc); len2 = poly_pow_length(flen, b - m, trunc); L = _arb_vec_init(len1 + len2); R = L + len1; _arb_poly_rising_ui_series_bsplit(L, f, flen, a, m, trunc, prec); _arb_poly_rising_ui_series_bsplit(R, f, flen, m, b, trunc, prec); _arb_poly_mullow(res, L, len1, R, len2, FLINT_MIN(trunc, len1 + len2 - 1), prec); _arb_vec_clear(L, len1 + len2); } }
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 _acb_poly_zeta_cpx_series(acb_ptr z, const acb_t s, const acb_t a, int deflate, long d, long prec) { ulong M, N; long i; arf_t bound; arb_ptr vb; if (d < 1) return; if (!acb_is_finite(s) || !acb_is_finite(a)) { _acb_vec_indeterminate(z, d); return; } arf_init(bound); vb = _arb_vec_init(d); _acb_poly_zeta_em_choose_param(bound, &N, &M, s, a, FLINT_MIN(d, 2), prec, MAG_BITS); _acb_poly_zeta_em_bound(vb, s, a, N, M, d, MAG_BITS); _acb_poly_zeta_em_sum(z, s, a, deflate, N, M, d, prec); for (i = 0; i < d; i++) { arb_get_abs_ubound_arf(bound, vb + i, MAG_BITS); arb_add_error_arf(acb_realref(z + i), bound); arb_add_error_arf(acb_imagref(z + i), bound); } arf_clear(bound); _arb_vec_clear(vb, d); }
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_div(arb_ptr Q, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) { slong lenQ, lenB2; arb_ptr Arev, Brev; lenQ = lenA - lenB + 1; Arev = _arb_vec_init(2 * lenQ); Brev = Arev + lenQ; _arb_poly_reverse(Arev, A + (lenA - lenQ), lenQ, lenQ); if (lenB >= lenQ) { _arb_poly_reverse(Brev, B + (lenB - lenQ), lenQ, lenQ); lenB2 = lenQ; } else { _arb_poly_reverse(Brev, B, lenB, lenB); lenB2 = lenB; } _arb_poly_div_series(Q, Arev, lenQ, Brev, lenB2, lenQ, prec); _arb_poly_reverse(Q, Q, lenQ, lenQ); _arb_vec_clear(Arev, 2 * lenQ); }
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); }
static void _cross_site_ws_init_edge_rates(cross_site_ws_t w, const model_and_data_t m) { slong i, idx; double tmpd; w->edge_rates = _arb_vec_init(w->edge_count); /* * Define the map from csr edge index to edge rate. * The edge rate is represented in arbitrary precision. */ if (!m->edge_map) { fprintf(stderr, "internal error: edge map is uninitialized\n"); abort(); } if (!m->edge_map->order) { fprintf(stderr, "internal error: edge map order is uninitialized\n"); abort(); } if (!m->edge_rate_coefficients) { fprintf(stderr, "internal error: edge rate coeffs unavailable\n"); abort(); } for (i = 0; i < w->edge_count; i++) { idx = m->edge_map->order[i]; tmpd = m->edge_rate_coefficients[i]; arb_set_d(w->edge_rates + idx, tmpd); } }
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_poly_rem(arb_ptr R, arb_srcptr A, slong lenA, arb_srcptr B, slong lenB, slong prec) { const slong lenQ = lenA - lenB + 1; arb_ptr Q = _arb_vec_init(lenQ); _arb_poly_divrem(Q, R, A, lenA, B, lenB, prec); _arb_vec_clear(Q, lenQ); }
void _arb_poly_sinh_cosh_series_exponential(arb_ptr s, arb_ptr c, const arb_srcptr h, slong hlen, slong len, slong prec) { arb_ptr t, u, v; arb_t s0, c0; hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_sinh_cosh(s, c, h, prec); _arb_vec_zero(s + 1, len - 1); _arb_vec_zero(c + 1, len - 1); return; } arb_init(s0); arb_init(c0); t = _arb_vec_init(3 * len); u = t + len; v = u + len; arb_sinh_cosh(s0, c0, h, prec); _arb_vec_set(t + 1, h + 1, hlen - 1); _arb_poly_exp_series(t, t, len, len, prec); /* todo: part of the inverse could be avoided since exp computes it internally to half the length */ _arb_poly_inv_series(u, t, len, len, prec); /* hyperbolic sine */ _arb_vec_sub(s, t, u, len, prec); _arb_vec_scalar_mul_2exp_si(s, s, len, -1); /* hyperbolic cosine */ _arb_vec_add(c, t, u, len, prec); _arb_vec_scalar_mul_2exp_si(c, c, len, -1); /* sinh(h0 + h1) = cosh(h0) sinh(h1) + sinh(h0) cosh(h1) cosh(h0 + h1) = cosh(h0) cosh(h1) + sinh(h0) sinh(h1) */ if (!arb_is_zero(s0)) { _arb_vec_scalar_mul(t, s, len, c0, prec); _arb_vec_scalar_mul(u, c, len, s0, prec); _arb_vec_scalar_mul(v, s, len, s0, prec); _arb_vec_add(s, t, u, len, prec); _arb_vec_scalar_mul(t, c, len, c0, prec); _arb_vec_add(c, t, v, len, prec); } _arb_vec_clear(t, 3 * len); arb_clear(s0); arb_clear(c0); }
void _acb_poly_zeta_em_bound1(mag_t bound, const acb_t s, const acb_t a, slong N, slong M, slong len, slong wp) { arb_ptr vec = _arb_vec_init(len); _acb_poly_zeta_em_bound(vec, s, a, N, M, len, wp); _arb_vec_get_mag(bound, vec, len); _arb_vec_clear(vec, len); }
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); }
void _acb_poly_zeta_cpx_series(acb_ptr z, const acb_t s, const acb_t a, int deflate, slong d, slong prec) { ulong M, N; slong i; mag_t bound; arb_ptr vb; int is_real, const_is_real; if (d < 1) return; if (!acb_is_finite(s) || !acb_is_finite(a)) { _acb_vec_indeterminate(z, d); return; } is_real = const_is_real = 0; if (acb_is_real(s) && acb_is_real(a)) { if (arb_is_positive(acb_realref(a))) { is_real = const_is_real = 1; } else if (arb_is_int(acb_realref(a)) && arb_is_int(acb_realref(s)) && arb_is_nonpositive(acb_realref(s))) { const_is_real = 1; } } mag_init(bound); vb = _arb_vec_init(d); _acb_poly_zeta_em_choose_param(bound, &N, &M, s, a, FLINT_MIN(d, 2), prec, MAG_BITS); _acb_poly_zeta_em_bound(vb, s, a, N, M, d, MAG_BITS); _acb_poly_zeta_em_sum(z, s, a, deflate, N, M, d, prec); for (i = 0; i < d; i++) { arb_get_mag(bound, vb + i); arb_add_error_mag(acb_realref(z + i), bound); if (!is_real && !(i == 0 && const_is_real)) arb_add_error_mag(acb_imagref(z + i), bound); } mag_clear(bound); _arb_vec_clear(vb, d); }
void cross_site_ws_init(cross_site_ws_t w, const model_and_data_t m) { cross_site_ws_pre_init(w); w->rate_category_count = model_and_data_rate_category_count(m); w->node_count = model_and_data_node_count(m); w->edge_count = model_and_data_edge_count(m); w->state_count = model_and_data_state_count(m); /* rate mixture workspace */ w->rate_mix_prior = _arb_vec_init(w->rate_category_count); w->rate_mix_rates = _arb_vec_init(w->rate_category_count); w->rate_mix_expect = _arb_vec_init(1); /* initialize edge rates */ _cross_site_ws_init_edge_rates(w, m); /* alloc equilibrium if necessary */ if (model_and_data_uses_equilibrium(m)) { w->equilibrium = _arb_vec_init(w->state_count); } /* alloc the rate matrix */ w->rate_matrix = flint_malloc(sizeof(arb_mat_struct)); arb_mat_init(w->rate_matrix, w->state_count, w->state_count); /* alloc the rate divisor */ w->rate_divisor = flint_malloc(sizeof(arb_struct)); arb_init(w->rate_divisor); /* allocate transition matrices */ { slong n = w->rate_category_count * w->edge_count; slong k = w->state_count; w->transition_matrices = _arb_mat_vec_init(k, k, n); } }
void _arb_poly_asin_series(arb_ptr g, arb_srcptr h, slong hlen, slong n, slong prec) { arb_t c; arb_init(c); arb_asin(c, h, prec); hlen = FLINT_MIN(hlen, n); if (hlen == 1) { _arb_vec_zero(g + 1, n - 1); } else { arb_ptr t, u; slong ulen; t = _arb_vec_init(n); u = _arb_vec_init(n); /* asin(h(x)) = integral(h'(x)/sqrt(1-h(x)^2)) */ ulen = FLINT_MIN(n, 2 * hlen - 1); _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); arb_sub_ui(u, u, 1, prec); _arb_vec_neg(u, u, ulen); _arb_poly_rsqrt_series(t, u, ulen, n, prec); _arb_poly_derivative(u, h, hlen, prec); _arb_poly_mullow(g, t, n, u, hlen - 1, n, prec); _arb_poly_integral(g, g, n, prec); _arb_vec_clear(t, n); _arb_vec_clear(u, n); } arb_swap(g, c); arb_clear(c); }
void _arb_poly_cot_pi_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); if (hlen == 1) { arb_cot_pi(g, h, prec); _arb_vec_zero(g + 1, len - 1); } else { arb_ptr t, u; t = _arb_vec_init(len); u = _arb_vec_init(len); _arb_poly_sin_cos_pi_series(t, u, h, hlen, len, prec); _arb_poly_div_series(g, u, len, t, len, len, prec); _arb_vec_clear(t, len); _arb_vec_clear(u, len); } }
void nd_axis_init(nd_axis_t axis, const char *name, int total_count, column_reduction_t r, int component_axis_count, struct nd_component_axis *component_axes, slong prec) { int i, idx; /* set compound axis hack data */ axis->component_axis_count = component_axis_count; axis->component_axes = component_axes; /* set the name */ axis->name = malloc(strlen(name) + 1); strcpy(axis->name, name); /* set the counts */ axis->n = total_count; axis->k = r->selection_len; /* allocate some bookkeeping vectors */ axis->selection = calloc(axis->k, sizeof(int)); axis->is_selected = calloc(axis->n, sizeof(int)); axis->request_update = calloc(axis->n, sizeof(int)); /* initialize the bookkeeping vectors */ for (i = 0; i < axis->k; i++) { idx = r->selection[i]; axis->selection[i] = idx; axis->is_selected[idx] = 1; axis->request_update[idx] = 1; } /* initialize the arbitrary precision weight arrays */ if (r->agg_mode == AGG_NONE) { axis->agg_weights = NULL; } else { axis->agg_weights = _arb_vec_init(axis->n); arb_init(axis->agg_weight_divisor); } /* initialize weight values */ nd_axis_update_precision(axis, r, prec); }
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); } }
/* * The rate matrix, equilibrium, and rate mixture rate expectation * have already been updated. */ static void _update_rate_divisor(cross_site_ws_t w, const model_and_data_t m, slong prec) { if (m->use_equilibrium_rate_divisor) { arb_struct *row_sums; row_sums = _arb_vec_init(w->state_count); _arb_mat_row_sums(row_sums, w->rate_matrix, prec); _arb_vec_dot(w->rate_divisor, row_sums, w->equilibrium, w->state_count, prec); _arb_vec_clear(row_sums, w->state_count); arb_mul(w->rate_divisor, w->rate_divisor, w->rate_mix_expect, prec); } else { arb_set(w->rate_divisor, m->rate_divisor); } }
void nd_accum_init(nd_accum_t a, nd_axis_struct *axes, int ndim) { int i; int stride; nd_axis_struct *axis; a->ndim = ndim; a->axes = axes; /* determine the nd array shape, accounting for aggregation along axes */ a->shape = malloc(a->ndim * sizeof(int)); for (i = 0; i < ndim; i++) { axis = a->axes + i; if (axis->agg_weights) { a->shape[i] = 1; } else { a->shape[i] = axis->n; } } /* determine the nd array size, accounting for aggregation along axes */ a->size = 1; for (i = 0; i < a->ndim; i++) { a->size *= a->shape[i]; } /* determine the nd array strides, accounting for aggregation along axes */ stride = 1; a->strides = malloc(a->ndim * sizeof(int)); for (i = ndim-1; i >= 0; i--) { a->strides[i] = stride; stride *= a->shape[i]; } /* allocate the data array */ a->data = _arb_vec_init(a->size); }
/* sin((pi/2)x) */ static int sin_pi2_x(arb_ptr out, const arb_t inp, void * params, slong order, slong prec) { arb_ptr x; x = _arb_vec_init(2); arb_set(x, inp); arb_one(x + 1); arb_const_pi(out, prec); arb_mul_2exp_si(out, out, -1); _arb_vec_scalar_mul(x, x, 2, out, prec); _arb_poly_sin_series(out, x, order, order, prec); _arb_vec_clear(x, 2); return 0; }
void _arb_poly_sinh_cosh_series_basecase(arb_ptr s, arb_ptr c, arb_srcptr h, slong hlen, slong n, slong prec) { slong j, k, alen = FLINT_MIN(n, hlen); arb_ptr a; arb_t t, u; arb_sinh_cosh(s, c, h, prec); if (hlen == 1) { _arb_vec_zero(s + 1, n - 1); _arb_vec_zero(c + 1, n - 1); return; } arb_init(t); arb_init(u); a = _arb_vec_init(alen); for (k = 1; k < alen; k++) arb_mul_ui(a + k, h + k, k, prec); for (k = 1; k < n; k++) { arb_zero(t); arb_zero(u); for (j = 1; j < FLINT_MIN(k + 1, hlen); j++) { arb_addmul(t, a + j, s + k - j, prec); arb_addmul(u, a + j, c + k - j, prec); } arb_div_ui(c + k, t, k, prec); arb_div_ui(s + k, u, k, prec); } arb_clear(t); arb_clear(u); _arb_vec_clear(a, alen); }
int sin_1x(arb_ptr out, const arb_t inp, void * params, long order, long prec) { arb_ptr x; int xlen = FLINT_MIN(2, order); x = _arb_vec_init(xlen); arb_set(x, inp); if (xlen > 1) arb_one(x + 1); _arb_poly_inv_series(out, x, xlen, order, prec); _arb_poly_sin_series(out, out, order, order, prec); _arb_vec_clear(x, xlen); eval_count++; return 0; }
void _arb_poly_div_series(arb_ptr Q, arb_srcptr A, long Alen, arb_srcptr B, long Blen, long n, long prec) { Alen = FLINT_MIN(Alen, n); Blen = FLINT_MIN(Blen, n); if (Blen == 1) { _arb_vec_scalar_div(Q, A, Alen, B, prec); _arb_vec_zero(Q + Alen, n - Alen); } else { arb_ptr Binv; Binv = _arb_vec_init(n); _arb_poly_inv_series(Binv, B, Blen, n, prec); _arb_poly_mullow(Q, Binv, n, A, Alen, n, prec); _arb_vec_clear(Binv, n); } }
void _arb_poly_inv_series(arb_ptr Qinv, arb_srcptr Q, slong Qlen, slong len, slong prec) { arb_inv(Qinv, Q, prec); if (Qlen == 1) { _arb_vec_zero(Qinv + 1, len - 1); } else if (len == 2) { arb_div(Qinv + 1, Qinv, Q, prec); arb_mul(Qinv + 1, Qinv + 1, Q + 1, prec); arb_neg(Qinv + 1, Qinv + 1); } else { slong Qnlen, Wlen, W2len; arb_ptr W; W = _arb_vec_init(len); NEWTON_INIT(1, len) NEWTON_LOOP(m, n) Qnlen = FLINT_MIN(Qlen, n); Wlen = FLINT_MIN(Qnlen + m - 1, n); W2len = Wlen - m; MULLOW(W, Q, Qnlen, Qinv, m, Wlen, prec); MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m, prec); _arb_vec_neg(Qinv + m, Qinv + m, n - m); NEWTON_END_LOOP NEWTON_END _arb_vec_clear(W, len); } }
void _arb_poly_sqrt_series(arb_ptr g, arb_srcptr h, slong hlen, slong len, slong prec) { hlen = FLINT_MIN(hlen, len); while (hlen > 0 && arb_is_zero(h + hlen - 1)) hlen--; 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 if (_arb_vec_is_zero(h + 1, hlen - 2)) { arb_t t; arb_init(t); arf_set_si_2exp_si(arb_midref(t), 1, -1); _arb_poly_binomial_pow_arb_series(g, h, hlen, t, len, prec); arb_clear(t); } 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); } }
int main() { long iter; flint_rand_t state; printf("interpolate_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000; iter++) { long i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t P; arb_poly_t R, S; fmpq_t t, u; arb_ptr xs, ys; fmpq_poly_init(P); arb_poly_init(R); arb_poly_init(S); fmpq_init(t); fmpq_init(u); qbits1 = 2 + n_randint(state, 200); qbits2 = 2 + n_randint(state, 5); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); n = P->length; xs = _arb_vec_init(n); ys = _arb_vec_init(n); arb_poly_set_fmpq_poly(R, P, rbits1); if (n > 0) { fmpq_randtest(t, state, qbits2); arb_set_fmpq(xs, t, rbits2); for (i = 1; i < n; i++) { fmpq_randtest_not_zero(u, state, qbits2); fmpq_abs(u, u); fmpq_add(t, t, u); arb_set_fmpq(xs + i, t, rbits2); } } for (i = 0; i < n; i++) arb_poly_evaluate(ys + i, R, xs + i, rbits2); arb_poly_interpolate_fast(S, xs, ys, n, rbits3); if (!arb_poly_contains_fmpq_poly(S, P)) { printf("FAIL:\n"); printf("P = "); fmpq_poly_print(P); printf("\n\n"); printf("R = "); arb_poly_printd(R, 15); printf("\n\n"); printf("S = "); arb_poly_printd(S, 15); printf("\n\n"); abort(); } fmpq_poly_clear(P); arb_poly_clear(R); arb_poly_clear(S); fmpq_clear(t); fmpq_clear(u); _arb_vec_clear(xs, n); _arb_vec_clear(ys, n); } flint_randclear(state); flint_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
int _acb_poly_validate_real_roots(acb_srcptr roots, acb_srcptr poly, long len, long prec) { long i, deg, num_real; arb_ptr real; int result; deg = len - 1; num_real = 0; result = 1; if (deg <= 1) return 1; real = _arb_vec_init(deg); /* pick out the candidate real roots */ for (i = 0; i < deg; i++) { if (arb_contains_zero(acb_imagref(roots + i))) { arb_set(real + num_real, acb_realref(roots + i)); num_real++; } } /* number of real roots must be even if the polynomial is even, and odd if the polynomial is odd (unless there are repeated roots... in which case the input is invalid) */ if ((num_real % 2) != (deg % 2)) { result = 0; } else if (num_real > 0) { int sign_neg_inf, sign_pos_inf, prev_sign; acb_t t; acb_init(t); /* by assumption that the roots are real and isolated, the lead coefficient really must be known to be either positive or negative */ sign_pos_inf = arb_is_positive(acb_realref(poly + deg)) ? 1 : -1; sign_neg_inf = (deg % 2) ? -sign_pos_inf : sign_pos_inf; /* now we check that there's a sign change between each root */ _arb_vec_sort_mid(real, num_real); prev_sign = sign_neg_inf; for (i = 0; i < num_real - 1; i++) { /* set t to the midpoint between the midpoints */ arb_zero(acb_imagref(t)); arf_add(arb_midref(acb_realref(t)), arb_midref(real + i), arb_midref(real + i + 1), prec, ARF_RND_DOWN); arf_mul_2exp_si(arb_midref(acb_realref(t)), arb_midref(acb_realref(t)), -1); mag_zero(arb_radref(acb_realref(t))); /* check that this point really is between both intervals (one interval could be much wider than the other */ if (arb_lt(real + i, acb_realref(t)) && arb_lt(acb_realref(t), real + i + 1)) { /* check sign change */ _acb_poly_evaluate(t, poly, len, t, prec); if (prev_sign == 1) result = arb_is_negative(acb_realref(t)); else result = arb_is_positive(acb_realref(t)); if (!result) break; prev_sign = -prev_sign; } else { result = 0; break; } } acb_clear(t); } _arb_vec_clear(real, deg); return result; }