Ejemplo n.º 1
0
Archivo: div.c Proyecto: bluescarni/arb
void
arb_div_arf(arb_t z, const arb_t x, const arf_t y, long prec)
{
    mag_t zr, ym;
    int inexact;

    if (arf_is_zero(y))
    {
        arb_zero_pm_inf(z);
    }
    else if (arb_is_exact(x))
    {
        inexact = arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND);

        if (inexact)
            arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec);
        else
            mag_zero(arb_radref(z));
    }
    else if (mag_is_inf(arb_radref(x)))
    {
        arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND);
        mag_inf(arb_radref(z));
    }
    else
    {
        mag_init(ym);
        mag_init(zr);

        arf_get_mag_lower(ym, y);
        mag_div(zr, arb_radref(x), ym);

        inexact = arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND);

        if (inexact)
            arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec);
        else
            mag_swap(arb_radref(z), zr);

        mag_clear(ym);
        mag_clear(zr);
    }
}
Ejemplo n.º 2
0
void
arb_sqrtpos(arb_t z, const arb_t x, long prec)
{
    if (!arb_is_finite(x))
    {
        if (mag_is_zero(arb_radref(x)) && arf_is_pos_inf(arb_midref(x)))
            arb_pos_inf(z);
        else
            arb_zero_pm_inf(z);
    }
    else if (arb_contains_nonpositive(x))
    {
        arf_t t;

        arf_init(t);

        arf_set_mag(t, arb_radref(x));
        arf_add(t, arb_midref(x), t, MAG_BITS, ARF_RND_CEIL);

        if (arf_sgn(t) <= 0)
        {
            arb_zero(z);
        }
        else
        {
            arf_sqrt(t, t, MAG_BITS, ARF_RND_CEIL);
            arf_mul_2exp_si(t, t, -1);
            arf_set(arb_midref(z), t);
            arf_get_mag(arb_radref(z), t);
        }

        arf_clear(t);
    }
    else
    {
        arb_sqrt(z, x, prec);
    }

    arb_nonnegative_part(z, z, prec);
}
Ejemplo n.º 3
0
void
acb_calc_cauchy_bound(arb_t bound, acb_calc_func_t func, void * param,
                      const acb_t x, const arb_t radius, slong maxdepth, slong prec)
{
    slong i, n, depth, wp;

    arb_t pi, theta, v, s1, c1, s2, c2, st, ct;
    acb_t t, u;
    arb_t b;

    arb_init(pi);
    arb_init(theta);
    arb_init(v);

    arb_init(s1);
    arb_init(c1);
    arb_init(s2);
    arb_init(c2);
    arb_init(st);
    arb_init(ct);

    acb_init(t);
    acb_init(u);
    arb_init(b);

    wp = prec + 20;

    arb_const_pi(pi, wp);
    arb_zero_pm_inf(b);

    for (depth = 0, n = 16; depth < maxdepth; n *= 2, depth++)
    {
        arb_zero(b);

        /* theta = 2 pi / n */
        arb_div_ui(theta, pi, n, wp);
        arb_mul_2exp_si(theta, theta, 1);

        /* sine and cosine of i*theta and (i+1)*theta */
        arb_zero(s1);
        arb_one(c1);
        arb_sin_cos(st, ct, theta, wp);
        arb_set(s2, st);
        arb_set(c2, ct);

        for (i = 0; i < n; i++)
        {
            /* sine and cosine of 2 pi ([i,i+1]/n) */

            /* since we use power of two subdivision points, the
               sine and cosine are monotone on each subinterval */
            arb_union(acb_realref(t), c1, c2, wp);
            arb_union(acb_imagref(t), s1, s2, wp);
            acb_mul_arb(t, t, radius, wp);
            acb_add(t, t, x, prec);

            /* next angle */
            arb_mul(v, c2, ct, wp);
            arb_mul(c1, s2, st, wp);
            arb_sub(c1, v, c1, wp);
            arb_mul(v, c2, st, wp);
            arb_mul(s1, s2, ct, wp);
            arb_add(s1, v, s1, wp);
            arb_swap(c1, c2);
            arb_swap(s1, s2);

            func(u, t, param, 1, prec);
            acb_abs(v, u, prec);
            arb_add(b, b, v, prec);
        }

        arb_div_ui(b, b, n, prec);

        if (arb_is_positive(b))
            break;
    }

    arb_set(bound, b);

    arb_clear(pi);
    arb_clear(theta);
    arb_clear(v);

    acb_clear(t);
    acb_clear(u);
    arb_clear(b);

    arb_clear(s1);
    arb_clear(c1);
    arb_clear(s2);
    arb_clear(c2);
    arb_clear(st);
    arb_clear(ct);
}
Ejemplo n.º 4
0
slong
_acb_poly_find_roots(acb_ptr roots,
    acb_srcptr poly,
    acb_srcptr initial, slong len, slong maxiter, slong prec)
{
    slong iter, i, deg;
    slong rootmag, max_rootmag, correction, max_correction;

    deg = len - 1;

    if (deg == 0)
    {
        return 0;
    }
    else if (acb_contains_zero(poly + len - 1))
    {
        /* if the leading coefficient contains zero, roots can be anywhere */
        for (i = 0; i < deg; i++)
        {
            arb_zero_pm_inf(acb_realref(roots + i));
            arb_zero_pm_inf(acb_imagref(roots + i));
        }
        return 0;
    }
    else if (deg == 1)
    {
        acb_inv(roots + 0, poly + 1, prec);
        acb_mul(roots + 0, roots + 0, poly + 0, prec);
        acb_neg(roots + 0, roots + 0);
        return 1;
    }

    if (initial == NULL)
        _acb_poly_roots_initial_values(roots, deg, prec);
    else
        _acb_vec_set(roots, initial, deg);

    if (maxiter == 0)
        maxiter = 2 * deg + n_sqrt(prec);

    for (iter = 0; iter < maxiter; iter++)
    {
        max_rootmag = -ARF_PREC_EXACT;
        for (i = 0; i < deg; i++)
        {
            rootmag = _acb_get_mid_mag(roots + i);
            max_rootmag = FLINT_MAX(rootmag, max_rootmag);
        }

        _acb_poly_refine_roots_durand_kerner(roots, poly, len, prec);

        max_correction = -ARF_PREC_EXACT;
        for (i = 0; i < deg; i++)
        {
            correction = _acb_get_rad_mag(roots + i);
            max_correction = FLINT_MAX(correction, max_correction);
        }

        /* estimate the correction relative to the whole set of roots */
        max_correction -= max_rootmag;

        /* flint_printf("ITER %wd MAX CORRECTION: %wd\n", iter, max_correction); */

        if (max_correction < -prec / 2)
            maxiter = FLINT_MIN(maxiter, iter + 2);
        else if (max_correction < -prec / 3)
            maxiter = FLINT_MIN(maxiter, iter + 3);
        else if (max_correction < -prec / 4)
            maxiter = FLINT_MIN(maxiter, iter + 4);
    }

    return _acb_poly_validate_roots(roots, poly, len, prec);
}