Exemple #1
0
void
acb_poly_sqrt_series(acb_poly_t g, const acb_poly_t h, slong n, slong prec)
{
    if (n == 0)
    {
        acb_poly_zero(g);
        return;
    }

    if (g == h)
    {
        acb_poly_t t;
        acb_poly_init(t);
        acb_poly_sqrt_series(t, h, n, prec);
        acb_poly_swap(g, t);
        acb_poly_clear(t);
        return;
    }

    acb_poly_fit_length(g, n);
    if (h->length == 0)
        _acb_vec_indeterminate(g->coeffs, n);
    else
        _acb_poly_sqrt_series(g->coeffs, h->coeffs, h->length, n, prec);
    _acb_poly_set_length(g, n);
    _acb_poly_normalise(g);
}
Exemple #2
0
void
acb_poly_inv_series(acb_poly_t Qinv, const acb_poly_t Q, slong n, slong prec)
{
    if (n == 0)
    {
        acb_poly_zero(Qinv);
        return;
    }

    if (Q->length == 0)
    {
        acb_poly_fit_length(Qinv, n);
        _acb_vec_indeterminate(Qinv->coeffs, n);
        _acb_poly_set_length(Qinv, n);
        return;
    }

    if (Qinv == Q)
    {
        acb_poly_t t;
        acb_poly_init(t);
        acb_poly_inv_series(t, Q, n, prec);
        acb_poly_swap(Qinv, t);
        acb_poly_clear(t);
        return;
    }

    acb_poly_fit_length(Qinv, n);
    _acb_poly_inv_series(Qinv->coeffs, Q->coeffs, Q->length, n, prec);
    _acb_poly_set_length(Qinv, n);
    _acb_poly_normalise(Qinv);
}
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);
}
Exemple #4
0
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);
}
Exemple #5
0
void
acb_poly_lgamma_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec)
{
    acb_poly_fit_length(res, n);

    if (f->length == 0 || n == 0)
        _acb_vec_indeterminate(res->coeffs, n);
    else
        _acb_poly_lgamma_series(res->coeffs, f->coeffs, f->length, n, prec);

    _acb_poly_set_length(res, n);
    _acb_poly_normalise(res);
}
Exemple #6
0
void
_acb_poly_lgamma_series(acb_ptr res, acb_srcptr h, slong hlen, slong len, slong prec)
{
    int reflect;
    slong i, r, n, wp;
    acb_t zr;
    acb_ptr t, u;

    hlen = FLINT_MIN(hlen, len);

    if (hlen == 1)
    {
        acb_lgamma(res, h, prec);
        if (acb_is_finite(res))
            _acb_vec_zero(res + 1, len - 1);
        else
            _acb_vec_indeterminate(res + 1, len - 1);
        return;
    }

    if (len == 2)
    {
        acb_t v;
        acb_init(v);
        acb_set(v, h + 1);
        acb_digamma(res + 1, h, prec);
        acb_lgamma(res, h, prec);
        acb_mul(res + 1, res + 1, v, prec);
        acb_clear(v);
        return;
    }

    /* use real code for real input and output */
    if (_acb_vec_is_real(h, hlen) && arb_is_positive(acb_realref(h)))
    {
        arb_ptr tmp = _arb_vec_init(len);
        for (i = 0; i < hlen; i++)
            arb_set(tmp + i, acb_realref(h + i));
        _arb_poly_lgamma_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);
    u = _acb_vec_init(len);
    acb_init(zr);

    /* use Stirling series */
    acb_gamma_stirling_choose_param(&reflect, &r, &n, h, 1, 0, wp);

    if (reflect)
    {
        /* log gamma(h+x) = log rf(1-(h+x), r) - log gamma(1-(h+x)+r) - log sin(pi (h+x)) + log(pi) */
        if (r != 0) /* otherwise t = 0 */
        {
            acb_sub_ui(u, h, 1, wp);
            acb_neg(u, u);
            _log_rising_ui_series(t, u, r, len, wp);
            for (i = 1; i < len; i += 2)
                acb_neg(t + i, t + i);
        }

        acb_sub_ui(u, h, 1, wp);
        acb_neg(u, u);
        acb_add_ui(zr, u, r, wp);
        _acb_poly_gamma_stirling_eval(u, zr, n, len, wp);
        for (i = 1; i < len; i += 2)
            acb_neg(u + i, u + i);

        _acb_vec_sub(t, t, u, len, wp);

        /* log(sin) is unstable with large imaginary parts;
           cot_pi is implemented in a numerically stable way */
        acb_set(u, h);
        acb_one(u + 1);
        _acb_poly_cot_pi_series(u, u, 2, len - 1, wp);
        _acb_poly_integral(u, u, len, wp);
        acb_const_pi(u, wp);
        _acb_vec_scalar_mul(u + 1, u + 1, len - 1, u, wp);
        acb_log_sin_pi(u, h, wp);

        _acb_vec_sub(u, t, u, len, wp);

        acb_const_pi(t, wp); /* todo: constant for log pi */
        acb_log(t, t, wp);
        acb_add(u, u, t, wp);
    }
    else
    {
        /* log gamma(x) = log gamma(x+r) - log rf(x,r) */

        acb_add_ui(zr, h, r, wp);
        _acb_poly_gamma_stirling_eval(u, zr, n, len, wp);

        if (r != 0)
        {
            _log_rising_ui_series(t, h, r, len, 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);
    _acb_vec_clear(u, len);
}
Exemple #7
0
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);
}
int
acb_mat_eig_simple_rump(acb_ptr E, acb_mat_t L, acb_mat_t R,
    const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec)
{
    slong i, j, n;
    acb_mat_t X, R2;
    int result;

    n = acb_mat_nrows(A);

    if (n == 0)
        return 1;

    if (n == 1)
    {
        acb_set_round(E, acb_mat_entry(A, 0, 0), prec);
        if (L != NULL)
            acb_one(acb_mat_entry(L, 0, 0));
        if (R != NULL)
            acb_one(acb_mat_entry(R, 0, 0));
        return 1;
    }

    acb_mat_init(X, n, 1);
    acb_mat_init(R2, n, n);

    result = 1;

    for (i = 0; i < n && result; i++)
    {
        for (j = 0; j < n; j++)
            acb_set(acb_mat_entry(X, j, 0), acb_mat_entry(R_approx, j, i));

        acb_mat_eig_enclosure_rump(E + i, NULL, X, A, E_approx + i, X, prec);

        if (!acb_is_finite(E + i))
            result = 0;

        for (j = 0; j < i; j++)
            if (acb_overlaps(E + i, E + j))
                result = 0;

        for (j = 0; j < n; j++)
            acb_set(acb_mat_entry(R2, j, i), acb_mat_entry(X, j, 0));
    }

    if (R != NULL)
    {
        if (result)
            acb_mat_set(R, R2);
        else
            acb_mat_indeterminate(R);
    }

    if (L != NULL)
    {
        if (!result || !acb_mat_inv(L, R, prec))
            acb_mat_indeterminate(L);
    }

    if (!result)
        _acb_vec_indeterminate(E, n);

    acb_mat_clear(X);
    acb_mat_clear(R2);

    return result;
}