Beispiel #1
0
void
arb_mat_bound_inf_norm(mag_t b, const arb_mat_t A)
{
    slong i, j, r, c;

    mag_t s, t;

    r = arb_mat_nrows(A);
    c = arb_mat_ncols(A);

    mag_zero(b);

    if (r == 0 || c == 0)
        return;

    mag_init(s);
    mag_init(t);

    for (i = 0; i < r; i++)
    {
        mag_zero(s);

        for (j = 0; j < c; j++)
        {
            arb_get_mag(t, arb_mat_entry(A, i, j));
            mag_add(s, s, t);
        }

        mag_max(b, b, s);
    }

    mag_clear(s);
    mag_clear(t);
}
Beispiel #2
0
void
acb_hypgeom_erf_propagated_error(mag_t re, mag_t im, const acb_t z)
{
    mag_t x, y;

    mag_init(x);
    mag_init(y);

    /* |exp(-(x+y)^2)| = exp(y^2-x^2) */
    arb_get_mag(y, acb_imagref(z));
    mag_mul(y, y, y);

    arb_get_mag_lower(x, acb_realref(z));
    mag_mul_lower(x, x, x);

    if (mag_cmp(y, x) >= 0)
    {
        mag_sub(re, y, x);
        mag_exp(re, re);
    }
    else
    {
        mag_sub_lower(re, x, y);
        mag_expinv(re, re);
    }

    /* Radius. */
    mag_hypot(x, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z)));
    mag_mul(re, re, x);

    /* 2/sqrt(pi) < 289/256 */
    mag_mul_ui(re, re, 289);
    mag_mul_2exp_si(re, re, -8);

    if (arb_is_zero(acb_imagref(z)))
    {
        /* todo: could bound magnitude even for complex numbers */
        mag_set_ui(y, 2);
        mag_min(re, re, y);

        mag_zero(im);
    }
    else if (arb_is_zero(acb_realref(z)))
    {
        mag_swap(im, re);
        mag_zero(re);
    }
    else
    {
        mag_set(im, re);
    }

    mag_clear(x);
    mag_clear(y);
}
/* note: the tmp variable t should have zero radius */
static void
acb_approx_div(acb_t z, const acb_t x, const acb_t y, acb_t t, slong prec)
{
    arf_set(arb_midref(acb_realref(t)), arb_midref(acb_realref(y)));
    arf_set(arb_midref(acb_imagref(t)), arb_midref(acb_imagref(y)));

    acb_inv(t, t, prec);

    mag_zero(arb_radref(acb_realref(t)));
    mag_zero(arb_radref(acb_imagref(t)));

    acb_approx_mul(z, x, t, prec);
}
Beispiel #4
0
/* assumes no aliasing */
slong
acb_lambertw_initial(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, slong prec)
{
    /* Handle z very close to 0 on the principal branch. */
    if (fmpz_is_zero(k) && 
            (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -20) <= 0 &&
             arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -20) <= 0))
    {
        acb_set(res, z);
        acb_submul(res, res, res, prec);
        return 40;  /* could be tightened... */
    }

    /* For moderate input not close to the branch point, compute a double
       approximation as the initial value. */
    if (fmpz_is_zero(k) &&
        arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 400) < 0 &&
        arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 400) < 0 &&
          (arf_cmp_d(arb_midref(acb_realref(z)), -0.37) < 0 ||
           arf_cmp_d(arb_midref(acb_realref(z)), -0.36) > 0 ||
           arf_cmpabs_d(arb_midref(acb_imagref(z)), 0.01) > 0))
    {
        acb_lambertw_principal_d(res, z);
        return 48;
    }

    /* Check if we are close to the branch point at -1/e. */
    if ((fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z)))
                         || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z))))
        && ((arf_cmpabs_2exp_si(arb_midref(acb_realref(ez1)), -2) <= 0 &&
             arf_cmpabs_2exp_si(arb_midref(acb_imagref(ez1)), -2) <= 0)))
    {
        acb_t t;
        acb_init(t);
        acb_mul_2exp_si(t, ez1, 1);
        mag_zero(arb_radref(acb_realref(t)));
        mag_zero(arb_radref(acb_imagref(t)));
        acb_mul_ui(t, t, 3, prec);
        acb_sqrt(t, t, prec);
        if (!fmpz_is_zero(k))
            acb_neg(t, t);
        acb_lambertw_branchpoint_series(res, t, 0, prec);
        acb_clear(t);
        return 1;  /* todo: estimate */
    }

    acb_lambertw_initial_asymp(res, z, k, prec);
    return 1;  /* todo: estimate */
}
Beispiel #5
0
void
mag_exp_tail(mag_t z, const mag_t x, ulong N)
{
    if (N == 0 || mag_is_inf(x))
    {
        mag_exp(z, x);
    }
    else if (mag_is_zero(x))
    {
        mag_zero(z);
    }
    else
    {
        mag_t t;
        mag_init(t);
        mag_set_ui_2exp_si(t, N, -1);

        /* bound by geometric series when N >= 2*x  <=> N/2 >= x */
        if (mag_cmp(t, x) >= 0)
        {
            /* 2 c^N / N! */
            mag_pow_ui(t, x, N);
            mag_rfac_ui(z, N);
            mag_mul(z, z, t);
            mag_mul_2exp_si(z, z, 1);
        }
        else
        {
            mag_exp(z, x);
        }

        mag_clear(t);
    }
}
Beispiel #6
0
static __inline__ void
arb_nonnegative_part(arb_t z, const arb_t x, long prec)
{
    if (arb_contains_negative(x))
    {
        arf_t t;
        arf_init(t);

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

        if (arf_sgn(arb_midref(z)) <= 0)
        {
            mag_zero(arb_radref(z));
        }
        else
        {
            arf_mul_2exp_si(arb_midref(z), arb_midref(z), -1);
            arf_get_mag(arb_radref(z), arb_midref(z));

            /* XXX: needed since arf_get_mag is inexact */
            arf_set_mag(arb_midref(z), arb_radref(z));
        }

        arf_clear(t);
    }
    else
    {
        arb_set(z, x);
    }
}
Beispiel #7
0
void
arb_set_interval_arf(arb_t x, const arf_t a, const arf_t b, slong prec)
{
    arf_t t;
    int inexact;

    if (arf_is_inf(a) && arf_equal(a, b))
    {
        /* [-inf, -inf] or [+inf, +inf] */
        arf_set(arb_midref(x), a);
        mag_zero(arb_radref(x));
        return;
    }

    arf_init(t);
    arf_sub(t, b, a, MAG_BITS, ARF_RND_UP);

    if (arf_sgn(t) < 0)
    {
        flint_printf("exception: arb_set_interval_arf: endpoints not ordered\n");
        abort();
    }

    arf_get_mag(arb_radref(x), t);

    inexact = arf_add(arb_midref(x), a, b, prec, ARB_RND);
    if (inexact)
        arf_mag_add_ulp(arb_radref(x), arb_radref(x), arb_midref(x), prec);

    arb_mul_2exp_si(x, x, -1);

    arf_clear(t);
}
Beispiel #8
0
void
mag_geom_series(mag_t res, const mag_t x, ulong n)
{
    if (mag_is_zero(x))
    {
        if (n == 0)
            mag_one(res);
        else
            mag_zero(res);
    }
    else if (mag_is_inf(x))
    {
        mag_inf(res);
    }
    else
    {
        mag_t t;
        mag_init(t);
        mag_one(t);
        mag_sub_lower(t, t, x);

        if (mag_is_zero(t))
        {
            mag_inf(res);
        }
        else
        {
            mag_pow_ui(res, x, n);
            mag_div(res, res, t);
        }

        mag_clear(t);
    }
}
Beispiel #9
0
static void
arb_root_arf(arb_t z, const arf_t x, ulong k, slong prec)
{
    int inexact = arf_root(arb_midref(z), x, k, prec, ARB_RND);

    if (inexact)
        arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec);
    else
        mag_zero(arb_radref(z));
}
Beispiel #10
0
void
acb_lambertw_cleared_cut(acb_t res, const acb_t z, const fmpz_t k, int flags, slong prec)
{
    acb_t ez1;
    acb_init(ez1);

    /* compute e*z + 1 */
    arb_const_e(acb_realref(ez1), prec);
    acb_mul(ez1, ez1, z, prec);
    acb_add_ui(ez1, ez1, 1, prec);

    if (acb_is_exact(z))
    {
        acb_lambertw_main(res, z, ez1, k, flags, prec);
    }
    else
    {
        acb_t zz;
        mag_t err, rad;

        mag_init(err);
        mag_init(rad);
        acb_init(zz);

        acb_lambertw_bound_deriv(err, z, ez1, k);
        mag_hypot(rad, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z)));
        mag_mul(err, err, rad);

        acb_set(zz, z);
        mag_zero(arb_radref(acb_realref(zz)));
        mag_zero(arb_radref(acb_imagref(zz)));  /* todo: recompute ez1? */

        acb_lambertw_main(res, zz, ez1, k, flags, prec);
        acb_add_error_mag(res, err);

        mag_clear(err);
        mag_clear(rad);
        acb_clear(zz);
    }

    acb_clear(ez1);
}
Beispiel #11
0
void
_arb_poly_majorant(arb_ptr res, arb_srcptr vec, slong len, slong prec)
{
    slong i;

    for (i = 0; i < len; i++)
    {
        arb_get_abs_ubound_arf(arb_midref(res + i), vec + i, prec);
        mag_zero(arb_radref(res + i));
    }
}
void
_acb_poly_reciprocal_majorant(arb_ptr res, acb_srcptr vec, long len, long prec)
{
    long i;

    for (i = 0; i < len; i++)
    {
        if (i == 0)
        {
            acb_get_abs_lbound_arf(arb_midref(res + i), vec + i, prec);
            mag_zero(arb_radref(res + i));
        }
        else
        {
            acb_get_abs_ubound_arf(arb_midref(res + i), vec + i, prec);
            arf_neg(arb_midref(res + i), arb_midref(res + i));
            mag_zero(arb_radref(res + i));
        }
    }
}
Beispiel #13
0
void
arb_set_round_fmpz(arb_t y, const fmpz_t x, slong prec)
{
    int inexact;
    inexact = arf_set_round_fmpz(arb_midref(y), x, prec, ARB_RND);

    if (inexact)
        arf_mag_set_ulp(arb_radref(y), arb_midref(y), prec);
    else
        mag_zero(arb_radref(y));
}
Beispiel #14
0
void
arb_fmpz_div_fmpz(arb_t z, const fmpz_t x, const fmpz_t y, long prec)
{
    int inexact;

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

    if (inexact)
        arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec);
    else
        mag_zero(arb_radref(z));
}
Beispiel #15
0
static void
_arb_arf_div_rounded_den(arb_t res, const arf_t x, const arf_t y, int yinexact, slong prec)
{
    int inexact = arf_div(arb_midref(res), x, y, prec, ARB_RND);

    if (yinexact && !arf_is_special(arb_midref(res)))
        arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec - 1);
    else if (inexact)
        arf_mag_set_ulp(arb_radref(res), arb_midref(res), prec);
    else
        mag_zero(arb_radref(res));
}
Beispiel #16
0
void
arb_sinc(arb_t z, const arb_t x, slong prec)
{
    mag_t c, r;
    mag_init(c);
    mag_init(r);
    mag_set_ui_2exp_si(c, 5, -1);
    arb_get_mag_lower(r, x);
    if (mag_cmp(c, r) < 0)
    {
        /* x is not near the origin */
        _arb_sinc_direct(z, x, prec);
    }
    else if (mag_cmp_2exp_si(arb_radref(x), 1) < 0)
    {
        /* determine error magnitude using the derivative bound */
        if (arb_is_exact(x))
        {
            mag_zero(c);
        }
        else
        {
            _arb_sinc_derivative_bound(r, x);
            mag_mul(c, arb_radref(x), r);
        }

        /* evaluate sinc at the midpoint of x */
        if (arf_is_zero(arb_midref(x)))
        {
            arb_one(z);
        }
        else
        {
            arb_get_mid_arb(z, x);
            _arb_sinc_direct(z, z, prec);
        }

        /* add the error */
        mag_add(arb_radref(z), arb_radref(z), c);
    }
    else
    {
        /* x has a large radius and includes points near the origin */
        arf_zero(arb_midref(z));
        mag_one(arb_radref(z));
    }

    mag_clear(c);
    mag_clear(r);
}
Beispiel #17
0
void
mag_expinv(mag_t res, const mag_t x)
{
    if (mag_is_zero(x))
    {
        mag_one(res);
    }
    else if (mag_is_inf(x))
    {
        mag_zero(res);
    }
    else if (fmpz_sgn(MAG_EXPREF(x)) <= 0)
    {
        mag_one(res);
    }
    else if (fmpz_cmp_ui(MAG_EXPREF(x), 2 * MAG_BITS) > 0)
    {
        fmpz_t t;
        fmpz_init(t);

        /* If x > 2^60, exp(-x) < 2^(-2^60 / log(2))  */
        /* -1/log(2) < -369/256 */
        fmpz_set_si(t, -369);
        fmpz_mul_2exp(t, t, 2 * MAG_BITS - 8);

        mag_one(res);
        mag_mul_2exp_fmpz(res, res, t);

        fmpz_clear(t);
    }
    else
    {
        fmpz_t t;
        slong e = MAG_EXP(x);

        fmpz_init(t);
        fmpz_set_ui(t, MAG_MAN(x));

        if (e >= MAG_BITS)
            fmpz_mul_2exp(t, t, e - MAG_BITS);
        else
            fmpz_tdiv_q_2exp(t, t, MAG_BITS - e);

        /* upper bound for 1/e */
        mag_set_ui_2exp_si(res, 395007543, -30);

        mag_pow_fmpz(res, res, t);
        fmpz_clear(t);
    }
}
Beispiel #18
0
int arb_calc_newton_step(arb_t xnew, arb_calc_func_t func,
    void * param, const arb_t x, const arb_t conv_region,
    const arf_t conv_factor, slong prec)
{
    mag_t err, v;
    arb_t t;
    arb_struct u[2];
    int result;

    mag_init(err);
    mag_init(v);
    arb_init(t);
    arb_init(u + 0);
    arb_init(u + 1);

    mag_mul(err, arb_radref(x), arb_radref(x));
    arf_get_mag(v, conv_factor);
    mag_mul(err, err, v);

    arf_set(arb_midref(t), arb_midref(x));
    mag_zero(arb_radref(t));

    func(u, t, param, 2, prec);

    arb_div(u, u, u + 1, prec);
    arb_sub(u, t, u, prec);

    mag_add(arb_radref(u), arb_radref(u), err);

    if (arb_contains(conv_region, u) &&
        (mag_cmp(arb_radref(u), arb_radref(x)) < 0))
    {
        arb_swap(xnew, u);
        result = ARB_CALC_SUCCESS;
    }
    else
    {
        arb_set(xnew, x);
        result = ARB_CALC_NO_CONVERGENCE;
    }

    arb_clear(t);
    arb_clear(u);
    arb_clear(u + 1);
    mag_clear(err);
    mag_clear(v);

    return result;
}
Beispiel #19
0
void
_acb_poly_roots_initial_values(acb_ptr roots, slong deg, slong prec)
{
    slong i;

    fmpq_t q;
    fmpq_init(q);

    fmpq_set_si(q, 4, 10);
    arb_set_fmpq(acb_realref(roots + 0), q, prec);
    mag_zero(arb_radref(acb_realref(roots + 0)));

    fmpq_set_si(q, 9, 10);
    arb_set_fmpq(acb_imagref(roots + 0), q, prec);
    mag_zero(arb_radref(acb_imagref(roots + 0)));
    fmpq_clear(q);

    for (i = 1; i < deg; i++)
    {
        acb_mul(roots + i, roots + i - 1, roots + 0, prec);
        mag_zero(arb_radref(acb_realref(roots + i)));
        mag_zero(arb_radref(acb_imagref(roots + i)));
    }
}
Beispiel #20
0
int
_arb_poly_newton_step(arb_t xnew, arb_srcptr poly, long len,
    const arb_t x,
    const arb_t convergence_interval,
    const arf_t convergence_factor, long prec)
{
    arf_t err;
    arb_t t, u, v;
    int result;

    arf_init(err);
    arb_init(t);
    arb_init(u);
    arb_init(v);

    arf_set_mag(err, arb_radref(x));
    arf_mul(err, err, err, MAG_BITS, ARF_RND_UP);
    arf_mul(err, err, convergence_factor, MAG_BITS, ARF_RND_UP);

    arf_set(arb_midref(t), arb_midref(x));
    mag_zero(arb_radref(t));

    _arb_poly_evaluate2(u, v, poly, len, t, prec);

    arb_div(u, u, v, prec);
    arb_sub(u, t, u, prec);

    arb_add_error_arf(u, err);

    if (arb_contains(convergence_interval, u) &&
        (mag_cmp(arb_radref(u), arb_radref(x)) < 0))
    {
        arb_swap(xnew, u);
        result = 1;
    }
    else
    {
        arb_set(xnew, x);
        result = 0;
    }

    arb_clear(t);
    arb_clear(u);
    arb_clear(v);
    arf_clear(err);

    return result;
}
void
mag_log_ui(mag_t t, ulong n)
{
    if (n <= 1)
    {
        if (n == 1)
            mag_zero(t);
        else
            mag_inf(t);
    }
    else
    {
        mag_set_ui(t, n-1);
        mag_log1p(t, t);
    }
}
Beispiel #22
0
/* check accuracy compared to reference algorithm */
void arb_exp_simple(arb_t res, const arb_t x, slong prec)
{
    mag_t t, u;

    mag_init_set(t, arb_radref(x));
    mag_init(u);

    arf_set(arb_midref(res), arb_midref(x));
    mag_zero(arb_radref(res));
    arb_exp(res, x, prec);

    mag_expm1(t, t);
    arb_get_mag(u, res);
    mag_addmul(arb_radref(res), t, u);

    mag_clear(t);
    mag_clear(u);
}
Beispiel #23
0
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);
    }
}
Beispiel #24
0
void
mag_set_d_lower(mag_t z, double c)
{
    if (c < 0.0)
        c = -c;

    if (c == 0.0 || (c != c))
    {
        mag_zero(z);
    }
    else if (c == D_INF)
    {
        mag_inf(z);
    }
    else
    {
        _fmpz_demote(MAG_EXPREF(z));
        MAG_SET_D_2EXP_LOWER(MAG_MAN(z), MAG_EXP(z), c, 0);
    }
}
Beispiel #25
0
static void
bound_rfac(arb_ptr F, const acb_t s, ulong n, slong len, slong wp)
{
    if (len == 1)
    {
        acb_rising_ui_get_mag(arb_radref(F), s, n);
        arf_set_mag(arb_midref(F), arb_radref(F));
        mag_zero(arb_radref(F + 0));
    }
    else
    {
        arb_struct sx[2];
        arb_init(sx + 0);
        arb_init(sx + 1);
        acb_abs(sx + 0, s, wp);
        arb_one(sx + 1);
        _arb_vec_zero(F, len);
        _arb_poly_rising_ui_series(F, sx, 2, n, len, wp);
        arb_clear(sx + 0);
        arb_clear(sx + 1);
    }
}
Beispiel #26
0
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;
}
Beispiel #27
0
/* derivatives: |8/sqrt(pi) sin(2z^2)|, |8/sqrt(pi) cos(2z^2)| <= 5 exp(4|xy|) */
void
acb_hypgeom_fresnel_erf_error(acb_t res1, acb_t res2, const acb_t z, slong prec)
{
    mag_t re;
    mag_t im;
    acb_t zmid;

    mag_init(re);
    mag_init(im);
    acb_init(zmid);

    if (arf_cmpabs_ui(arb_midref(acb_realref(z)), 1000) < 0 &&
        arf_cmpabs_ui(arb_midref(acb_imagref(z)), 1000) < 0)
    {
        arb_get_mag(re, acb_realref(z));
        arb_get_mag(im, acb_imagref(z));
        mag_mul(re, re, im);
        mag_mul_2exp_si(re, re, 2);
        mag_exp(re, re);
        mag_mul_ui(re, re, 5);
    }
    else
    {
        arb_t t;
        arb_init(t);
        arb_mul(t, acb_realref(z), acb_imagref(z), prec);
        arb_abs(t, t);
        arb_mul_2exp_si(t, t, 2);
        arb_exp(t, t, prec);
        arb_get_mag(re, t);
        mag_mul_ui(re, re, 5);
        arb_clear(t);
    }

    mag_hypot(im, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z)));
    mag_mul(re, re, im);

    if (arb_is_zero(acb_imagref(z)))
    {
        mag_set_ui(im, 8);  /* For real x, |S(x)| < 4, |C(x)| < 4. */
        mag_min(re, re, im);
        mag_zero(im);
    }
    else if (arb_is_zero(acb_realref(z)))
    {
        mag_set_ui(im, 8);
        mag_min(im, re, im);
        mag_zero(re);
    }
    else
    {
        mag_set(im, re);
    }

    arf_set(arb_midref(acb_realref(zmid)), arb_midref(acb_realref(z)));
    arf_set(arb_midref(acb_imagref(zmid)), arb_midref(acb_imagref(z)));

    acb_hypgeom_fresnel_erf(res1, res2, zmid, prec);

    if (res1 != NULL)
    {
        arb_add_error_mag(acb_realref(res1), re);
        arb_add_error_mag(acb_imagref(res1), im);
    }

    if (res2 != NULL)
    {
        arb_add_error_mag(acb_realref(res2), re);
        arb_add_error_mag(acb_imagref(res2), im);
    }

    mag_clear(re);
    mag_clear(im);
    acb_clear(zmid);
}
Beispiel #28
0
int main()
{
    slong iter;
    flint_rand_t state;

    flint_printf("atan_arf_bb....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 5000; iter++)
    {
        arb_t x, y, z;
        slong prec, prec2;

        arb_init(x);
        arb_init(y);
        arb_init(z);

        prec = 2 + n_randint(state, 8000);

        arb_randtest(x, state, 1 + n_randint(state, 8000), 3);
        mag_zero(arb_radref(x));

        if (n_randint(state, 2))
            arb_mul_2exp_si(x, x, 1 + n_randint(state, 40));
        else
            arb_mul_2exp_si(x, x, -n_randint(state, 1.5 * prec));

        if (!arf_is_special(arb_midref(x)))
            prec2 = prec + 100 + 2 * (-ARF_EXP(arb_midref(x)));
        else
            prec2 = prec + 100;

        arb_atan_arf_via_mpfr(y, arb_midref(x), prec2);
        arb_atan_arf_bb(z, arb_midref(x), prec);

        if (!arb_contains(z, y))
        {
            flint_printf("FAIL: containment\n\n");
            flint_printf("prec = %wd\n\n", prec);
            flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n");
            flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n");
            flint_printf("z = "); arb_printd(z, 50); flint_printf("\n\n");
            abort();
        }

        if (arb_rel_accuracy_bits(z) < prec - 2)
        {
            flint_printf("FAIL: poor accuracy\n\n");
            flint_printf("prec = %wd,  acc = %wd\n\n", prec, arb_rel_accuracy_bits(z));
            flint_printf("x = "); arb_printd(x, 50); flint_printf("\n\n");
            flint_printf("y = "); arb_printd(y, 50); flint_printf("\n\n");
            flint_printf("z = "); arb_printd(z, 50); flint_printf("\n\n");
            abort();
        }

        arb_atan_arf_bb(x, arb_midref(x), prec);

        if (!arb_overlaps(x, z))
        {
            flint_printf("FAIL: aliasing\n\n");
            abort();
        }

        arb_clear(x);
        arb_clear(y);
        arb_clear(z);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Beispiel #29
0
void arb_set_exact(arb_t x) {
    mag_zero(arb_radref(x));
}
Beispiel #30
0
int main()
{
    slong iter;
    flint_rand_t state;

    flint_printf("approx_dot....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        arb_ptr x, y;
        arb_t s1, s2, z;
        slong i, len, prec, xbits, ybits, ebits;
        int initial, subtract, revx, revy;

        if (n_randint(state, 100) == 0)
            len = n_randint(state, 100);
        else if (n_randint(state, 10) == 0)
            len = n_randint(state, 10);
        else
            len = n_randint(state, 3);

        if (n_randint(state, 10) != 0 || len > 10)
        {
            prec = 2 + n_randint(state, 500);
            xbits = 2 + n_randint(state, 500);
            ybits = 2 + n_randint(state, 500);
        }
        else
        {
            prec = 2 + n_randint(state, 4000);
            xbits = 2 + n_randint(state, 4000);
            ybits = 2 + n_randint(state, 4000);
        }

        if (n_randint(state, 100) == 0)
            ebits = 2 + n_randint(state, 100);
        else
            ebits = 2 + n_randint(state, 10);

        initial = n_randint(state, 2);
        subtract = n_randint(state, 2);
        revx = n_randint(state, 2);
        revy = n_randint(state, 2);

        x = _arb_vec_init(len);
        y = _arb_vec_init(len);
        arb_init(s1);
        arb_init(s2);
        arb_init(z);

        switch (n_randint(state, 3))
        {
            case 0:
                for (i = 0; i < len; i++)
                {
                    arb_randtest(x + i, state, xbits, ebits);
                    arb_randtest(y + i, state, ybits, ebits);
                }
                break;

            /* Test with cancellation */
            case 1:
                for (i = 0; i < len; i++)
                {
                    if (i <= len / 2)
                    {
                        arb_randtest(x + i, state, xbits, ebits);
                        arb_randtest(y + i, state, ybits, ebits);
                    }
                    else
                    {
                        arb_neg(x + i, x + len - i - 1);
                        arb_set(y + i, y + len - i - 1);
                    }
                }
                break;

            default:
                for (i = 0; i < len; i++)
                {
                    if (i <= len / 2)
                    {
                        arb_randtest(x + i, state, xbits, ebits);
                        arb_randtest(y + i, state, ybits, ebits);
                    }
                    else
                    {
                        arb_neg_round(x + i, x + len - i - 1, 2 + n_randint(state, 500));
                        arb_set_round(y + i, y + len - i - 1, 2 + n_randint(state, 500));
                    }
                }
                break;
        }

        arb_randtest(s1, state, 200, 100);
        arb_randtest(s2, state, 200, 100);
        arb_randtest(z, state, xbits, ebits);

        arb_approx_dot(s1, initial ? z : NULL, subtract,
            revx ? (x + len - 1) : x, revx ? -1 : 1,
            revy ? (y + len - 1) : y, revy ? -1 : 1,
            len, prec);
        mag_zero(arb_radref(s1));

        /* With the fast algorithm, we expect identical results when
           reversing the vectors. */
        if (ebits <= 12)
        {
            arb_approx_dot(s2, initial ? z : NULL, subtract,
                !revx ? (x + len - 1) : x, !revx ? -1 : 1,
                !revy ? (y + len - 1) : y, !revy ? -1 : 1,
                len, prec);
            mag_zero(arb_radref(s2));

            if (!arb_equal(s1, s2))
            {
                flint_printf("FAIL (reversal)\n\n");
                flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits);

                if (initial)
                {
                    flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z));
                }

                for (i = 0; i < len; i++)
                {
                    flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i));
                    flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i));
                }
                flint_printf("\n\n");
                flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n");
                flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n");
                flint_abort();
            }
        }

        /* Verify that radii are ignored */
        for (i = 0; i < len; i++)
        {
            arb_get_mid_arb(x + i, x + i);
            arb_get_mid_arb(y + i, y + i);
        }
        arb_get_mid_arb(z, z);

        arb_approx_dot(s2, initial ? z : NULL, subtract,
            revx ? (x + len - 1) : x, revx ? -1 : 1,
            revy ? (y + len - 1) : y, revy ? -1 : 1,
            len, prec);
        mag_zero(arb_radref(s2));

        if (!arb_equal(s1, s2))
        {
            flint_printf("FAIL (radii)\n\n");
            flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits);

            if (initial)
            {
                flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z));
            }

            for (i = 0; i < len; i++)
            {
                flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i));
                flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i));
            }
            flint_printf("\n\n");
            flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n");
            flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n");
            flint_abort();
        }

        /* Compare with arb_dot */
        arb_approx_dot(s2, initial ? z : NULL, subtract,
            revx ? (x + len - 1) : x, revx ? -1 : 1,
            revy ? (y + len - 1) : y, revy ? -1 : 1,
            len, prec);

        {
            mag_t err, xx, yy;

            mag_init(err);
            mag_init(xx);
            mag_init(yy);

            if (initial)
                arb_get_mag(err, z);

            for (i = 0; i < len; i++)
            {
                arb_get_mag(xx, revx ? x + len - 1 - i : x + i);
                arb_get_mag(yy, revx ? y + len - 1 - i : y + i);
                mag_addmul(err, xx, yy);
            }

            mag_mul_2exp_si(err, err, -prec + 2);
            arb_add_error_mag(s2, err);

            if (!arb_contains(s2, s1))
            {
                flint_printf("FAIL (inclusion)\n\n");
                flint_printf("iter = %wd, len = %wd, prec = %wd, ebits = %wd\n\n", iter, len, prec, ebits);

                if (initial)
                {
                    flint_printf("z = ", i); arb_printn(z, 100, ARB_STR_MORE); flint_printf(" (%wd)\n\n", arb_bits(z));
                }

                for (i = 0; i < len; i++)
                {
                    flint_printf("x[%wd] = ", i); arb_printn(x + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(x + i));
                    flint_printf("y[%wd] = ", i); arb_printn(y + i, 100, ARB_STR_MORE); flint_printf(" (%wd)\n", arb_bits(y + i));
                }
                flint_printf("\n\n");
                flint_printf("s1 = "); arb_printn(s1, 100, ARB_STR_MORE); flint_printf("\n\n");
                flint_printf("s2 = "); arb_printn(s2, 100, ARB_STR_MORE); flint_printf("\n\n");
                flint_abort();
            }

            mag_clear(err);
            mag_clear(xx);
            mag_clear(yy);
        }

        arb_clear(s1);
        arb_clear(s2);
        arb_clear(z);
        _arb_vec_clear(x, len);
        _arb_vec_clear(y, len);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}