Пример #1
0
void
arb_max(arb_t z, const arb_t x, const arb_t y, slong prec)
{
    arf_t left, right, t, xr, yr;

    if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
    {
        arb_indeterminate(z);
        return;
    }

    arf_init(left);
    arf_init(right);
    arf_init(t);

    arf_init_set_mag_shallow(xr, arb_radref(x));
    arf_init_set_mag_shallow(yr, arb_radref(y));

    arf_sub(left, arb_midref(x), xr, prec, ARF_RND_FLOOR);
    arf_sub(t, arb_midref(y), yr, prec, ARF_RND_FLOOR);
    arf_max(left, left, t);

    arf_add(right, arb_midref(x), xr, prec, ARF_RND_CEIL);
    arf_add(t, arb_midref(y), yr, prec, ARF_RND_CEIL);
    arf_max(right, right, t);

    arb_set_interval_arf(z, left, right, prec);

    arf_clear(left);
    arf_clear(right);
    arf_clear(t);
}
Пример #2
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);
}
Пример #3
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);
    }
}
Пример #4
0
int
_arf_add_eps(arf_t s, const arf_t x, int sgn, long prec, arf_rnd_t rnd)
{
    arf_t t;
    long bits;

    bits = arf_bits(x);

    if (bits == 0)
    {
        printf("_arf_add_eps\n");
        abort();
    }

    bits = FLINT_MAX(bits, prec) + 10;

    arf_init(t);
    arf_set_si(t, sgn);
    arf_mul_2exp_fmpz(t, t, ARF_EXPREF(x));
    arf_mul_2exp_si(t, t, -bits);
    arf_add(s, x, t, prec, rnd);
    arf_clear(t);

    return 1;
}
Пример #5
0
int
arf_add_naive(arf_t z, const arf_t x, const arf_t y, slong prec, arf_rnd_t rnd)
{
    if (rnd == ARF_RND_NEAR)
    {
        arf_add(z, x, y, ARF_PREC_EXACT, ARF_RND_DOWN);
        return arf_set_round(z, z, prec, rnd);
    }
    else
    {
        fmpr_t a, b;
        slong r;

        fmpr_init(a);
        fmpr_init(b);

        arf_get_fmpr(a, x);
        arf_get_fmpr(b, y);

        r = fmpr_add(a, a, b, prec, rnd);
        arf_set_fmpr(z, a);

        fmpr_clear(a);
        fmpr_clear(b);

        return (r == FMPR_RESULT_EXACT) ? 0 : 1;
    }
}
Пример #6
0
int arb_calc_partition(arf_interval_t L, arf_interval_t R,
    arb_calc_func_t func, void * param, const arf_interval_t block, slong prec)
{
    arb_t t, m;
    arf_t u;
    int msign;

    arb_init(t);
    arb_init(m);
    arf_init(u);

    /* Compute the midpoint (TODO: try other points) */
    arf_add(u, &block->a, &block->b, ARF_PREC_EXACT, ARF_RND_DOWN);
    arf_mul_2exp_si(u, u, -1);

    /* Evaluate and get sign at midpoint */
    arb_set_arf(m, u);
    func(t, m, param, 1, prec);
    msign = _arb_sign(t);

    /* L, R = block, split at midpoint */
    arf_set(&L->a, &block->a);
    arf_set(&R->b, &block->b);
    arf_set(&L->b, u);
    arf_set(&R->a, u);

    arb_clear(t);
    arb_clear(m);
    arf_clear(u);

    return msign;
}
Пример #7
0
void arf_twobytwo_diag(arf_t u1, arf_t u2, const arf_t a, const arf_t b, const arf_t d, slong prec) {
    // Compute the orthogonal matrix that diagonalizes
    //
    //    A = [a b]
    //        [b d]
    //
    // This matrix will have the form
    //
    //    U = [cos x , -sin x]
    //        [sin x, cos x]
    //
    // where the diagonal matrix is U^t A U.
    // We set u1 = cos x, u2 = -sin x.

    if(arf_is_zero(b)) {
        arf_set_ui(u1, 1);
        arf_set_ui(u2, 0);
        return;
    }
    arf_t x; arf_init(x);

    arf_mul(u1, b, b, prec, ARF_RND_NEAR);            // u1 = b^2
    arf_sub(u2, a, d, prec, ARF_RND_NEAR);            // u2 = a - d
    arf_mul_2exp_si(u2, u2, -1);                      // u2 = (a - d)/2
    arf_mul(u2, u2, u2, prec, ARF_RND_NEAR);          // u2 = ( (a - d)/2 )^2
    arf_add(u1, u1, u2, prec, ARF_RND_NEAR);          // u1 = b^2 + ( (a-d)/2 )^2
    arf_sqrt(u1, u1, prec, ARF_RND_NEAR);             // u1 = sqrt(above)

    arf_mul_2exp_si(u1, u1, 1);                       // u1 = 2 (sqrt (above) )
    arf_add(u1, u1, d, prec, ARF_RND_NEAR);           // u1 += d
    arf_sub(u1, u1, a, prec, ARF_RND_NEAR);           // u1 -= a
    arf_mul_2exp_si(u1, u1, -1);                      // u1 = (d - a)/2 + sqrt(b^2 + ( (a-d)/2 )^2)

    arf_mul(x, u1, u1, prec, ARF_RND_NEAR);
    arf_addmul(x, b, b, prec, ARF_RND_NEAR);          // x = u1^2 + b^2
    arf_sqrt(x, x, prec, ARF_RND_NEAR);               // x = sqrt(u1^2 + b^2)
    arf_div(u2, u1, x, prec, ARF_RND_NEAR);
    arf_div(u1, b, x, prec, ARF_RND_NEAR);
    arf_neg(u1, u1);

    arf_clear(x);
}
Пример #8
0
int
arf_add_si_naive(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
{
    arf_t t;
    int r;
    arf_init(t);
    arf_set_si(t, y);
    r = arf_add(z, x, t, prec, rnd);
    arf_clear(t);
    return r;
}
Пример #9
0
int
arf_add_fmpz_naive(arf_t z, const arf_t x, const fmpz_t y, long prec, arf_rnd_t rnd)
{
    arf_t t;
    int r;
    arf_init(t);
    arf_set_fmpz(t, y);
    r = arf_add(z, x, t, prec, rnd);
    arf_clear(t);
    return r;
}
Пример #10
0
int
arf_addmul_si_naive(arf_t z, const arf_t x, slong y, slong prec, arf_rnd_t rnd)
{
    arf_t t;
    int inexact;

    arf_init(t);
    arf_mul_si(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN);

    inexact = arf_add(z, z, t, prec, rnd);

    arf_clear(t);

    return inexact;
}
Пример #11
0
static void
arb_supremum(arf_t res, const arb_t x)
{
    if (arf_is_nan(arb_midref(x)))
    {
        arf_nan(res);
    }
    else if (mag_is_inf(arb_radref(x)))
    {
        arf_pos_inf(res);
    }
    else
    {
        arf_set_mag(res, arb_radref(x));
        arf_add(res, res, arb_midref(x), ARF_PREC_EXACT, ARF_RND_CEIL);
    }
}
Пример #12
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);
}
int
acb_calc_integrate_taylor(acb_t res,
    acb_calc_func_t func, void * param,
    const acb_t a, const acb_t b,
    const arf_t inner_radius,
    const arf_t outer_radius,
    long accuracy_goal, long prec)
{
    long num_steps, step, N, bp;
    int result;

    acb_t delta, m, x, y1, y2, sum;
    acb_ptr taylor_poly;
    arf_t err;

    acb_init(delta);
    acb_init(m);
    acb_init(x);
    acb_init(y1);
    acb_init(y2);
    acb_init(sum);
    arf_init(err);

    acb_sub(delta, b, a, prec);

    /* precision used for bounds calculations */
    bp = MAG_BITS;

    /* compute the number of steps */
    {
        arf_t t;
        arf_init(t);
        acb_get_abs_ubound_arf(t, delta, bp);
        arf_div(t, t, inner_radius, bp, ARF_RND_UP);
        arf_mul_2exp_si(t, t, -1);
        num_steps = (long) (arf_get_d(t, ARF_RND_UP) + 1.0);
        /* make sure it's not something absurd */
        num_steps = FLINT_MIN(num_steps, 10 * prec);
        num_steps = FLINT_MAX(num_steps, 1);
        arf_clear(t);
    }

    result = ARB_CALC_SUCCESS;

    acb_zero(sum);

    for (step = 0; step < num_steps; step++)
    {
        /* midpoint of subinterval */
        acb_mul_ui(m, delta, 2 * step + 1, prec);
        acb_div_ui(m, m, 2 * num_steps, prec);
        acb_add(m, m, a, prec);

        if (arb_calc_verbose)
        {
            printf("integration point %ld/%ld: ", 2 * step + 1, 2 * num_steps);
            acb_printd(m, 15); printf("\n");
        }

        /* evaluate at +/- x */
        /* TODO: exactify m, and include error in x? */
        acb_div_ui(x, delta, 2 * num_steps, prec);

        /* compute bounds and number of terms to use */
        {
            arb_t cbound, xbound, rbound;
            arf_t C, D, R, X, T;
            double DD, TT, NN;

            arb_init(cbound);
            arb_init(xbound);
            arb_init(rbound);
            arf_init(C);
            arf_init(D);
            arf_init(R);
            arf_init(X);
            arf_init(T);

            /* R is the outer radius */
            arf_set(R, outer_radius);

            /* X = upper bound for |x| */
            acb_get_abs_ubound_arf(X, x, bp);
            arb_set_arf(xbound, X);

            /* Compute C(m,R). Important subtlety: due to rounding when
               computing m, we will in general be farther than R away from
               the integration path. But since acb_calc_cauchy_bound
               actually integrates over the area traced by a complex
               interval, it will catch any extra singularities (giving
               an infinite bound). */
            arb_set_arf(rbound, outer_radius);
            acb_calc_cauchy_bound(cbound, func, param, m, rbound, 8, bp);
            arf_set_mag(C, arb_radref(cbound));
            arf_add(C, arb_midref(cbound), C, bp, ARF_RND_UP);

            /* Sanity check: we need C < inf and R > X */
            if (arf_is_finite(C) && arf_cmp(R, X) > 0)
            {
                /* Compute upper bound for D = C * R * X / (R - X) */
                arf_mul(D, C, R, bp, ARF_RND_UP);
                arf_mul(D, D, X, bp, ARF_RND_UP);
                arf_sub(T, R, X, bp, ARF_RND_DOWN);
                arf_div(D, D, T, bp, ARF_RND_UP);

                /* Compute upper bound for T = (X / R) */
                arf_div(T, X, R, bp, ARF_RND_UP);

                /* Choose N */
                /* TODO: use arf arithmetic to avoid overflow */
                /* TODO: use relative accuracy (look at |f(m)|?) */
                DD = arf_get_d(D, ARF_RND_UP);
                TT = arf_get_d(T, ARF_RND_UP);
                NN = -(accuracy_goal * 0.69314718055994530942 + log(DD)) / log(TT);
                N = NN + 0.5;
                N = FLINT_MIN(N, 100 * prec);
                N = FLINT_MAX(N, 1);

                /* Tail bound: D / (N + 1) * T^N */
                {
                    mag_t TT;
                    mag_init(TT);
                    arf_get_mag(TT, T);
                    mag_pow_ui(TT, TT, N);
                    arf_set_mag(T, TT);
                    mag_clear(TT);
                }
                arf_mul(D, D, T, bp, ARF_RND_UP);
                arf_div_ui(err, D, N + 1, bp, ARF_RND_UP);
            }
            else
            {
                N = 1;
                arf_pos_inf(err);
                result = ARB_CALC_NO_CONVERGENCE;
            }

            if (arb_calc_verbose)
            {
                printf("N = %ld; bound: ", N); arf_printd(err, 15); printf("\n");
                printf("R: "); arf_printd(R, 15); printf("\n");
                printf("C: "); arf_printd(C, 15); printf("\n");
                printf("X: "); arf_printd(X, 15); printf("\n");
            }

            arb_clear(cbound);
            arb_clear(xbound);
            arb_clear(rbound);
            arf_clear(C);
            arf_clear(D);
            arf_clear(R);
            arf_clear(X);
            arf_clear(T);
        }

        /* evaluate Taylor polynomial */
        taylor_poly = _acb_vec_init(N + 1);
        func(taylor_poly, m, param, N, prec);
        _acb_poly_integral(taylor_poly, taylor_poly, N + 1, prec);
        _acb_poly_evaluate(y2, taylor_poly, N + 1, x, prec);
        acb_neg(x, x);
        _acb_poly_evaluate(y1, taylor_poly, N + 1, x, prec);
        acb_neg(x, x);

        /* add truncation error */
        arb_add_error_arf(acb_realref(y1), err);
        arb_add_error_arf(acb_imagref(y1), err);
        arb_add_error_arf(acb_realref(y2), err);
        arb_add_error_arf(acb_imagref(y2), err);

        acb_add(sum, sum, y2, prec);
        acb_sub(sum, sum, y1, prec);

        if (arb_calc_verbose)
        {
            printf("values:  ");
            acb_printd(y1, 15); printf("  ");
            acb_printd(y2, 15); printf("\n");
        }

        _acb_vec_clear(taylor_poly, N + 1);

        if (result == ARB_CALC_NO_CONVERGENCE)
            break;
    }

    acb_set(res, sum);

    acb_clear(delta);
    acb_clear(m);
    acb_clear(x);
    acb_clear(y1);
    acb_clear(y2);
    acb_clear(sum);
    arf_clear(err);

    return result;
}
Пример #14
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++)
    {
        slong i, len, prec, bits, expbits;
        int res1, res2;
        arf_t s1, s2, s3, err;
        mag_t err_bound;
        arf_struct terms[20];
        arf_rnd_t rnd;

        len = n_randint(state, 20);
        bits = 2 + n_randint(state, 1000);
        prec = 2 + n_randint(state, 1000);
        expbits = n_randint(state, 14);

        arf_init(s1);
        arf_init(s2);
        arf_init(s3);
        arf_init(err);
        mag_init(err_bound);

        for (i = 0; i < len; i++)
        {
            arf_init(terms + i);
            arf_randtest_special(terms + i, state, bits, expbits);
        }

        switch (n_randint(state, 4))
        {
            case 0: rnd = ARF_RND_DOWN; break;
            case 1: rnd = ARF_RND_UP; break;
            case 2: rnd = ARF_RND_FLOOR; break;
            default: rnd = ARF_RND_CEIL; break;
        }

        res1 = arf_sum(s1, terms, len, prec, rnd);

        arf_zero(s2);
        for (i = 0; i < len; i++)
            arf_add(s2, s2, terms + i, ARF_PREC_EXACT, ARF_RND_DOWN);
        res2 = arf_set_round(s3, s2, prec, rnd);

        if (!arf_equal(s1, s3) || res1 != res2)
        {
            flint_printf("FAIL (%wd)\n\n", iter);
            flint_printf("prec = %wd\n\n", prec);
            for (i = 0; i < len; i++)
            {
                flint_printf("terms[%wd] = ", i); arf_print(terms + i); flint_printf("\n\n");
            }
            flint_printf("s1 = "); arf_print(s1); flint_printf("\n\n");
            flint_printf("s2 = "); arf_print(s2); flint_printf("\n\n");
            flint_printf("s3 = "); arf_print(s3); flint_printf("\n\n");
            flint_printf("res1 = %d, res2 = %d\n\n", res1, res2);
            abort();
        }

        arf_sub(err, s1, s2, ARF_PREC_EXACT, ARF_RND_DOWN);
        arf_abs(err, err);

        if (res1)
            arf_mag_set_ulp(err_bound, s1, prec);
        else
            mag_zero(err_bound);

        if (arf_cmpabs_mag(err, err_bound) > 0)
        {
            flint_printf("FAIL (error bound)!\n");
            flint_printf("prec = %wd\n\n", prec);
            for (i = 0; i < len; i++)
            {
                flint_printf("terms[%wd] = ", i); arf_print(terms + i); flint_printf("\n\n");
            }
            flint_printf("s1 = "); arf_print(s1); flint_printf("\n\n");
            flint_printf("s2 = "); arf_print(s2); flint_printf("\n\n");
            flint_printf("s3 = "); arf_print(s3); flint_printf("\n\n");
            flint_printf("error: "); arf_print(err); flint_printf("\n\n");
            flint_printf("error bound: "); mag_print(err_bound); flint_printf("\n\n");
            flint_printf("res1 = %d, res2 = %d\n\n", res1, res2);
            abort();
        }

        arf_clear(s1);
        arf_clear(s2);
        arf_clear(s3);
        arf_clear(err);
        mag_clear(err_bound);

        for (i = 0; i < len; i++)
            arf_clear(terms + i);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #15
0
int
arf_sum(arf_t s, arf_srcptr terms, long len, long prec, arf_rnd_t rnd)
{
    arf_ptr blocks;
    long i, j, used;
    int have_merged, res;

    /* first check if the result is inf or nan */
    {
        int have_pos_inf = 0;
        int have_neg_inf = 0;

        for (i = 0; i < len; i++)
        {
            if (arf_is_pos_inf(terms + i))
            {
                if (have_neg_inf)
                {
                    arf_nan(s);
                    return 0;
                }
                have_pos_inf = 1;
            }
            else if (arf_is_neg_inf(terms + i))
            {
                if (have_pos_inf)
                {
                    arf_nan(s);
                    return 0;
                }
                have_neg_inf = 1;
            }
            else if (arf_is_nan(terms + i))
            {
                arf_nan(s);
                return 0;
            }
        }

        if (have_pos_inf)
        {
            arf_pos_inf(s);
            return 0;
        }

        if (have_neg_inf)
        {
            arf_neg_inf(s);
            return 0;
        }
    }

    blocks = flint_malloc(sizeof(arf_struct) * len);
    for (i = 0; i < len; i++)
        arf_init(blocks + i);

    /* put all terms into blocks */
    used = 0;
    for (i = 0; i < len; i++)
    {
        if (!arf_is_zero(terms + i))
        {
            arf_set(blocks + used, terms + i);
            used++;
        }
    }

    /* merge blocks until all are well separated */
    have_merged = 1;
    while (used >= 2 && have_merged)
    {
        have_merged = 0;

        for (i = 0; i < used && !have_merged; i++)
        {
            for (j = i + 1; j < used && !have_merged; j++)
            {
                if (_arf_are_close(blocks + i, blocks + j, prec))
                {
                    arf_add(blocks + i, blocks + i, blocks + j,
                        ARF_PREC_EXACT, ARF_RND_DOWN);

                    /* remove the merged block */
                    arf_swap(blocks + j, blocks + used - 1);
                    used--;

                    /* remove the updated block if the sum is zero */
                    if (arf_is_zero(blocks + i))
                    {
                        arf_swap(blocks + i, blocks + used - 1);
                        used--;
                    }

                    have_merged = 1;
                }
            }
        }
    }

    if (used == 0)
    {
        arf_zero(s);
        res = 0;
    }
    else if (used == 1)
    {
        res = arf_set_round(s, blocks + 0, prec, rnd);
    }
    else
    {
        /* find the two largest blocks */
        for (i = 1; i < used; i++)
            if (arf_cmpabs(blocks + 0, blocks + i) < 0)
                arf_swap(blocks + 0, blocks + i);

        for (i = 2; i < used; i++)
            if (arf_cmpabs(blocks + 1, blocks + i) < 0)
                arf_swap(blocks + 1, blocks + i);

        res = _arf_add_eps(s, blocks + 0, arf_sgn(blocks + 1), prec, rnd);
    }

    for (i = 0; i < len; i++)
        arf_clear(blocks + i);
    flint_free(blocks);

    return res;
}
Пример #16
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);
    /* _flint_rand_init_gmp(state); */

    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        arf_t x;
        int octant;
        fmpz_t q;
        mp_ptr w;
        arb_t wb, t, u;
        mp_size_t wn;
        slong prec, prec2;
        int success;
        mp_limb_t error;

        prec = 2 + n_randint(state, 10000);
        wn = 1 + n_randint(state, 200);
        prec2 = FLINT_MAX(prec, wn * FLINT_BITS) + 100;

        arf_init(x);
        arb_init(wb);
        arb_init(t);
        arb_init(u);
        fmpz_init(q);
        w = flint_malloc(sizeof(mp_limb_t) * wn);

        arf_randtest(x, state, prec, 14);

        /* this should generate numbers close to multiples of pi/4 */
        if (n_randint(state, 4) == 0)
        {
            arb_const_pi(t, prec);
            arb_mul_2exp_si(t, t, -2);
            fmpz_randtest(q, state, 200);
            arb_mul_fmpz(t, t, q, prec);
            arf_add(x, x, arb_midref(t), prec, ARF_RND_DOWN);
        }

        arf_abs(x, x);

        success = _arb_get_mpn_fixed_mod_pi4(w, q, &octant, &error, x, wn);

        if (success)
        {
            /* could round differently */
            if (fmpz_fdiv_ui(q, 8) != octant)
            {
                flint_printf("bad octant\n");
                abort();
            }

            _arf_set_mpn_fixed(arb_midref(wb), w, wn, wn, 0, FLINT_BITS * wn, ARB_RND);
            mag_set_ui_2exp_si(arb_radref(wb), error, -FLINT_BITS * wn);

            arb_const_pi(u, prec2);
            arb_mul_2exp_si(u, u, -2);
            arb_set(t, wb);
            if (octant % 2 == 1)
                arb_sub(t, u, t, prec2);
            arb_addmul_fmpz(t, u, q, prec2);

            if (!arb_contains_arf(t, x))
            {
                flint_printf("FAIL (containment)\n");
                flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n");
                flint_printf("q = "); fmpz_print(q); flint_printf("\n\n");
                flint_printf("w = "); arb_printd(wb, 50); flint_printf("\n\n");
                flint_printf("t = "); arb_printd(t, 50); flint_printf("\n\n");
                abort();
            }

            arb_const_pi(t, prec2);
            arb_mul_2exp_si(t, t, -2);

            if (arf_sgn(arb_midref(wb)) < 0 ||
                arf_cmp(arb_midref(wb), arb_midref(t)) >= 0)
            {
                flint_printf("FAIL (expected 0 <= w < pi/4)\n");
                flint_printf("x = "); arf_printd(x, 50); flint_printf("\n\n");
                flint_printf("w = "); arb_printd(wb, 50); flint_printf("\n\n");
                abort();
            }
        }

        flint_free(w);
        fmpz_clear(q);
        arf_clear(x);
        arb_clear(wb);
        arb_clear(t);
        arb_clear(u);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #17
0
int
arf_addmul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn, zn, tn, alloc;
    mp_srcptr xptr, yptr, zptr;
    mp_ptr tptr, tptr2;
    fmpz_t texp, yexp;
    slong shift;
    int tsgnbit, ysgnbit, inexact;
    ARF_MUL_TMP_DECL

    yn = FLINT_ABS(y->_mp_size);

    if (arf_is_special(x) || yn == 0 || arf_is_special(z))
    {
        if (arf_is_zero(z))
        {
            return arf_mul_mpz(z, x, y, prec, rnd);
        }
        else if (arf_is_finite(x))
        {
            return arf_set_round(z, z, prec, rnd);
        }
        else
        {
            /* todo: speed up */
            arf_t t;
            arf_init(t);
            arf_mul_mpz(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN);
            inexact = arf_add(z, z, t, prec, rnd);
            arf_clear(t);
            return inexact;
        }
    }

    ARF_GET_MPN_READONLY(xptr, xn, x);

    yptr = y->_mp_d;
    ysgnbit = (y->_mp_size < 0);
    *yexp = yn * FLINT_BITS;

    ARF_GET_MPN_READONLY(zptr, zn, z);

    fmpz_init(texp);

    tsgnbit = ARF_SGNBIT(x) ^ ysgnbit;

    alloc = tn = xn + yn;
    ARF_MUL_TMP_ALLOC(tptr2, alloc)
    tptr = tptr2;

    ARF_MPN_MUL(tptr, xptr, xn, yptr, yn);

    shift = (tptr[tn - 1] == 0) * FLINT_BITS;
    tn -= (tptr[tn - 1] == 0);

    _fmpz_add2_fast(texp, ARF_EXPREF(x), yexp, -shift);
    shift = _fmpz_sub_small(ARF_EXPREF(z), texp);

    if (shift >= 0)
        inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z),
            tptr, tn, tsgnbit, shift, prec, rnd);
    else
        inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp,
            zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd);

    ARF_MUL_TMP_FREE(tptr2, alloc)
    fmpz_clear(texp);

    return inexact;
}
Пример #18
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;
}
Пример #19
0
int main()
{
    slong iter, iter2;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        arf_t x, y, z, v;
        slong prec, r1, r2;
        arf_rnd_t rnd;
        fmpz_t t;

        arf_init(x);
        arf_init(y);
        arf_init(z);
        arf_init(v);
        fmpz_init(t);

        for (iter2 = 0; iter2 < 100; iter2++)
        {
            arf_randtest_special(x, state, 2000, 100);
            arf_randtest_special(y, state, 2000, 100);
            prec = 2 + n_randint(state, 2000);

            switch (n_randint(state, 5))
            {
                case 0:  rnd = ARF_RND_DOWN; break;
                case 1:  rnd = ARF_RND_UP; break;
                case 2:  rnd = ARF_RND_FLOOR; break;
                case 3:  rnd = ARF_RND_CEIL; break;
                default: rnd = ARF_RND_NEAR; break;
            }

            rnd = ARF_RND_DOWN;

            if (arf_is_normal(x) && arf_is_normal(y))
            {
                fmpz_sub(t, ARF_EXPREF(x), ARF_EXPREF(y));

                /* if not too far apart, sometimes test exact addition */
                if (fmpz_bits(t) < 10)
                {
                    if (n_randint(state, 10) == 0)
                        prec = ARF_PREC_EXACT;
                }
                else if (rnd == ARF_RND_NEAR)
                { /* large shift not supported in add_naive */
                    rnd = ARF_RND_DOWN;
                }
            }

            switch (n_randint(state, 5))
            {
            case 0:
                r1 = arf_add(z, x, y, prec, rnd);
                r2 = arf_add_naive(v, x, y, prec, rnd);
                if (!arf_equal(z, v) || r1 != r2)
                {
                    flint_printf("FAIL!\n");
                    flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd);
                    flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                    flint_printf("y = "); arf_print(y); flint_printf("\n\n");
                    flint_printf("z = "); arf_print(z); flint_printf("\n\n");
                    flint_printf("v = "); arf_print(v); flint_printf("\n\n");
                    flint_printf("r1 = %wd, r2 = %wd\n", r1, r2);
                    abort();
                }
                break;

            case 1:
                r1 = arf_add(z, x, x, prec, rnd);
                r2 = arf_add_naive(v, x, x, prec, rnd);
                if (!arf_equal(z, v) || r1 != r2)
                {
                    flint_printf("FAIL (aliasing 1)!\n");
                    flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd);
                    flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                    flint_printf("z = "); arf_print(z); flint_printf("\n\n");
                    flint_printf("v = "); arf_print(v); flint_printf("\n\n");
                    flint_printf("r1 = %wd, r2 = %wd\n", r1, r2);
                    abort();
                }
                break;

            case 2:
                r2 = arf_add_naive(v, x, x, prec, rnd);
                r1 = arf_add(x, x, x, prec, rnd);
                if (!arf_equal(v, x) || r1 != r2)
                {
                    flint_printf("FAIL (aliasing 2)!\n");
                    flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd);
                    flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                    flint_printf("z = "); arf_print(z); flint_printf("\n\n");
                    flint_printf("v = "); arf_print(v); flint_printf("\n\n");
                    flint_printf("r1 = %wd, r2 = %wd\n", r1, r2);
                    abort();
                }
                break;

            case 3:
                r2 = arf_add_naive(v, x, y, prec, rnd);
                r1 = arf_add(x, x, y, prec, rnd);
                if (!arf_equal(x, v) || r1 != r2)
                {
                    flint_printf("FAIL (aliasing 3)!\n");
                    flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd);
                    flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                    flint_printf("y = "); arf_print(y); flint_printf("\n\n");
                    flint_printf("v = "); arf_print(v); flint_printf("\n\n");
                    flint_printf("r1 = %wd, r2 = %wd\n", r1, r2);
                    abort();
                }
                break;

            default:
                r2 = arf_add_naive(v, x, y, prec, rnd);
                r1 = arf_add(x, y, x, prec, rnd);
                if (!arf_equal(x, v) || r1 != r2)
                {
                    flint_printf("FAIL (aliasing 4)!\n");
                    flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd);
                    flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                    flint_printf("y = "); arf_print(y); flint_printf("\n\n");
                    flint_printf("v = "); arf_print(v); flint_printf("\n\n");
                    flint_printf("r1 = %wd, r2 = %wd\n", r1, r2);
                    abort();
                }
                break;
            }
        }

        arf_clear(x);
        arf_clear(y);
        arf_clear(z);
        arf_clear(v);
        fmpz_clear(t);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #20
0
int main()
{
    long iter;
    flint_rand_t state;

    printf("add_error....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        arb_t a, b, c;
        arf_t m, r;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        arf_init(m);
        arf_init(r);

        arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10);
        arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10);
        arb_randtest_special(c, state, 1 + n_randint(state, 2000), 10);
        arf_randtest_special(m, state, 1 + n_randint(state, 2000), 10);
        arf_randtest_special(r, state, 1 + n_randint(state, 2000), 10);

        /* c = a plus error bounds */
        arb_set(c, a);
        arf_set(arb_midref(b), m);
        arf_get_mag(arb_radref(b), r);
        arb_add_error(c, b);

        /* b = a + random point */
        arb_set(b, a);

        if (n_randint(state, 2))
            arf_add(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN);
        else
            arf_sub(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN);

        if (n_randint(state, 2))
            arf_add(arb_midref(b), arb_midref(b), r, ARF_PREC_EXACT, ARF_RND_DOWN);
        else
            arf_sub(arb_midref(b), arb_midref(b), r, ARF_PREC_EXACT, ARF_RND_DOWN);

        /* should this be done differently? */
        if (arf_is_nan(arb_midref(b)))
            arf_zero(arb_midref(b));

        if (!arb_contains(c, b))
        {
            printf("FAIL (arb_add_error)\n\n");
            printf("a = "); arb_printn(a, 50, 0); printf("\n\n");
            printf("b = "); arb_printn(b, 50, 0); printf("\n\n");
            printf("c = "); arb_printn(c, 50, 0); printf("\n\n");
            abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        arf_clear(m);
        arf_clear(r);
    }

    for (iter = 0; iter < 10000; iter++)
    {
        arb_t a, b, c;
        arf_t m;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        arf_init(m);

        arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10);
        arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10);
        arb_randtest_special(c, state, 1 + n_randint(state, 2000), 10);
        arf_randtest_special(m, state, 1 + n_randint(state, 2000), 10);

        /* c = a plus error bounds */
        arb_set(c, a);
        arb_add_error_arf(c, m);

        /* b = a + random point */
        arb_set(b, a);

        if (n_randint(state, 2))
            arf_add(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN);
        else
            arf_sub(arb_midref(b), arb_midref(b), m, ARF_PREC_EXACT, ARF_RND_DOWN);

        /* should this be done differently? */
        if (arf_is_nan(arb_midref(b)))
            arf_zero(arb_midref(b));

        if (!arb_contains(c, b))
        {
            printf("FAIL (arb_add_error_arf)\n\n");
            printf("a = "); arb_printn(a, 50, 0); printf("\n\n");
            printf("b = "); arb_printn(b, 50, 0); printf("\n\n");
            printf("c = "); arb_printn(c, 50, 0); printf("\n\n");
            abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        arf_clear(m);
    }

    for (iter = 0; iter < 10000; iter++)
    {
        arb_t a, b, c;
        arf_t t;
        mag_t r;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        mag_init(r);
        arf_init(t);

        arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10);
        arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10);
        mag_randtest(r, state, 10);

        /* c = a plus error bounds */
        arb_set(c, a);
        arb_add_error_mag(c, r);

        /* b = a + random point */
        arb_set(b, a);
        arf_set_mag(t, r);
        if (n_randint(state, 2))
            arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN);
        else
            arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN);

        /* should this be done differently? */
        if (arf_is_nan(arb_midref(b)))
            arf_zero(arb_midref(b));

        if (!arb_contains(c, b))
        {
            printf("FAIL (arb_add_error_mag)\n\n");
            printf("a = "); arb_printn(a, 50, 0); printf("\n\n");
            printf("b = "); arb_printn(b, 50, 0); printf("\n\n");
            printf("c = "); arb_printn(c, 50, 0); printf("\n\n");
            abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        mag_clear(r);
        arf_clear(t);
    }

    for (iter = 0; iter < 10000; iter++)
    {
        arb_t a, b, c;
        arf_t t;
        long e;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        arf_init(t);

        arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10);
        arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10);
        e = n_randint(state, 10) - 10;

        /* c = a plus error bounds */
        arb_set(c, a);
        arb_add_error_2exp_si(c, e);

        /* b = a + random point */
        arb_set(b, a);
        arf_one(t);
        arf_mul_2exp_si(t, t, e);
        if (n_randint(state, 2))
            arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN);
        else
            arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN);

        /* should this be done differently? */
        if (arf_is_nan(arb_midref(b)))
            arf_zero(arb_midref(b));

        if (!arb_contains(c, b))
        {
            printf("FAIL (arb_add_error_2exp_si)\n\n");
            printf("a = "); arb_printn(a, 50, 0); printf("\n\n");
            printf("b = "); arb_printn(b, 50, 0); printf("\n\n");
            printf("c = "); arb_printn(c, 50, 0); printf("\n\n");
            abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        arf_clear(t);
    }

    for (iter = 0; iter < 10000; iter++)
    {
        arb_t a, b, c;
        arf_t t;
        fmpz_t e;

        arb_init(a);
        arb_init(b);
        arb_init(c);
        arf_init(t);
        fmpz_init(e);

        arb_randtest_special(a, state, 1 + n_randint(state, 2000), 10);
        arb_randtest_special(b, state, 1 + n_randint(state, 2000), 10);
        fmpz_randtest(e, state, 10);

        /* c = a plus error bounds */
        arb_set(c, a);
        arb_add_error_2exp_fmpz(c, e);

        /* b = a + random point */
        arb_set(b, a);
        arf_one(t);
        arf_mul_2exp_fmpz(t, t, e);
        if (n_randint(state, 2))
            arf_add(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN);
        else
            arf_sub(arb_midref(b), arb_midref(b), t, ARF_PREC_EXACT, ARF_RND_DOWN);

        /* should this be done differently? */
        if (arf_is_nan(arb_midref(b)))
            arf_zero(arb_midref(b));

        if (!arb_contains(c, b))
        {
            printf("FAIL (arb_add_error_2exp_fmpz)\n\n");
            printf("a = "); arb_printn(a, 50, 0); printf("\n\n");
            printf("b = "); arb_printn(b, 50, 0); printf("\n\n");
            printf("c = "); arb_printn(c, 50, 0); printf("\n\n");
            abort();
        }

        arb_clear(a);
        arb_clear(b);
        arb_clear(c);
        arf_clear(t);
        fmpz_clear(e);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #21
0
int
arf_addmul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn, zn, tn, alloc;
    mp_srcptr xptr, yptr, zptr;
    mp_ptr tptr, tptr2;
    fmpz_t texp;
    slong shift;
    int tsgnbit, inexact;
    ARF_MUL_TMP_DECL

    if (arf_is_special(x) || arf_is_special(y) || arf_is_special(z))
    {
        if (arf_is_zero(z))
        {
            return arf_mul(z, x, y, prec, rnd);
        }
        else if (arf_is_finite(x) && arf_is_finite(y))
        {
            return arf_set_round(z, z, prec, rnd);
        }
        else
        {
            /* todo: speed up */
            arf_t t;
            arf_init(t);
            arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN);
            inexact = arf_add(z, z, t, prec, rnd);
            arf_clear(t);
            return inexact;
        }
    }

    tsgnbit = ARF_SGNBIT(x) ^ ARF_SGNBIT(y);
    ARF_GET_MPN_READONLY(xptr, xn, x);
    ARF_GET_MPN_READONLY(yptr, yn, y);
    ARF_GET_MPN_READONLY(zptr, zn, z);

    fmpz_init(texp);

    _fmpz_add2_fast(texp, ARF_EXPREF(x), ARF_EXPREF(y), 0);
    shift = _fmpz_sub_small(ARF_EXPREF(z), texp);

    alloc = tn = xn + yn;
    ARF_MUL_TMP_ALLOC(tptr2, alloc)
    tptr = tptr2;

    ARF_MPN_MUL(tptr, xptr, xn, yptr, yn);

    tn -= (tptr[0] == 0);
    tptr += (tptr[0] == 0);

    if (shift >= 0)
        inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z),
            tptr, tn, tsgnbit, shift, prec, rnd);
    else
        inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp,
            zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd);

    ARF_MUL_TMP_FREE(tptr2, alloc)
    fmpz_clear(texp);

    return inexact;
}