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_clear(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); _arb_vec_clear(w->edge_expectations, edge_count); _arb_vec_clear(w->cc_edge_expectations, edge_count); _arb_mat_vec_clear(w->base_node_vectors, node_count); _arb_mat_vec_clear(w->lhood_edge_vectors, edge_count); _arb_mat_vec_clear(w->lhood_node_vectors, node_count); _arb_mat_vec_clear(w->forward_edge_vectors, edge_count); _arb_mat_vec_clear(w->forward_node_vectors, node_count); }
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 _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_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 nd_accum_clear(nd_accum_t a) { free(a->shape); free(a->strides); _arb_vec_clear(a->data, a->size); }
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_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_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 cross_site_ws_clear(cross_site_ws_t w) { if (w->edge_rates) { _arb_vec_clear(w->edge_rates, w->edge_count); } if (w->equilibrium) { _arb_vec_clear(w->equilibrium, w->state_count); } if (w->rate_divisor) { arb_clear(w->rate_divisor); flint_free(w->rate_divisor); } if (w->rate_matrix) { arb_mat_clear(w->rate_matrix); flint_free(w->rate_matrix); } /* Clear stuff related to the rate mixture. */ if (w->rate_mix_prior) { _arb_vec_clear(w->rate_mix_prior, w->rate_category_count); } if (w->rate_mix_rates) { _arb_vec_clear(w->rate_mix_rates, w->rate_category_count); } if (w->rate_mix_expect) { _arb_vec_clear(w->rate_mix_expect, 1); } /* * Clear arrays of matrices. * The arrays are allowed to be NULL. */ { slong n = w->rate_category_count * w->edge_count; _arb_mat_vec_clear(w->transition_matrices, n); _arb_mat_vec_clear(w->dwell_frechet_matrices, n); _arb_mat_vec_clear(w->trans_frechet_matrices, n); } }
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 _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 _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 _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 _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); } }
void nd_axis_clear(nd_axis_t axis) { free(axis->name); free(axis->selection); free(axis->is_selected); free(axis->request_update); if (axis->agg_weights) { _arb_vec_clear(axis->agg_weights, axis->n); arb_clear(axis->agg_weight_divisor); } axis->n = 0; axis->k = 0; }
/* * 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); } }
/* 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; }
int main() { slong iter; flint_rand_t state; flint_printf("evaluate_vec_fast...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { slong i, n, qbits1, qbits2, rbits1, rbits2, rbits3; fmpq_poly_t F; fmpq * X, * Y; arb_poly_t f; arb_ptr x, y; qbits1 = 2 + n_randint(state, 100); qbits2 = 2 + n_randint(state, 100); rbits1 = 2 + n_randint(state, 200); rbits2 = 2 + n_randint(state, 200); rbits3 = 2 + n_randint(state, 200); n = n_randint(state, 10); fmpq_poly_init(F); X = _fmpq_vec_init(n); Y = _fmpq_vec_init(n); arb_poly_init(f); x = _arb_vec_init(n); y = _arb_vec_init(n); fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); for (i = 0; i < n; i++) fmpq_randtest(X + i, state, qbits2); for (i = 0; i < n; i++) fmpq_poly_evaluate_fmpq(Y + i, F, X + i); arb_poly_set_fmpq_poly(f, F, rbits1); for (i = 0; i < n; i++) arb_set_fmpq(x + i, X + i, rbits2); arb_poly_evaluate_vec_fast(y, f, x, n, rbits3); for (i = 0; i < n; i++) { if (!arb_contains_fmpq(y + i, Y + i)) { flint_printf("FAIL (%wd of %wd)\n\n", i, n); flint_printf("F = "); fmpq_poly_print(F); flint_printf("\n\n"); flint_printf("X = "); fmpq_print(X + i); flint_printf("\n\n"); flint_printf("Y = "); fmpq_print(Y + i); flint_printf("\n\n"); flint_printf("f = "); arb_poly_printd(f, 15); flint_printf("\n\n"); flint_printf("x = "); arb_printd(x + i, 15); flint_printf("\n\n"); flint_printf("y = "); arb_printd(y + i, 15); flint_printf("\n\n"); abort(); } } fmpq_poly_clear(F); _fmpq_vec_clear(X, n); _fmpq_vec_clear(Y, n); arb_poly_clear(f); _arb_vec_clear(x, n); _arb_vec_clear(y, n); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }