Пример #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);
}
Пример #2
0
static void
arb_sqrt1pm1_tiny(arb_t r, const arb_t z, slong prec)
{
    mag_t b, c;
    arb_t t;

    mag_init(b);
    mag_init(c);
    arb_init(t);

    /* if |z| < 1, then |(sqrt(1+z)-1) - (z/2-z^2/8)| <= |z|^3/(1-|z|)/16 */
    arb_get_mag(b, z);
    mag_one(c);
    mag_sub_lower(c, c, b);
    mag_pow_ui(b, b, 3);
    mag_div(b, b, c);
    mag_mul_2exp_si(b, b, -4);

    arb_mul(t, z, z, prec);
    arb_mul_2exp_si(t, t, -2);
    arb_sub(r, z, t, prec);
    arb_mul_2exp_si(r, r, -1);

    if (mag_is_finite(b))
        arb_add_error_mag(r, b);
    else
        arb_indeterminate(r);

    mag_clear(b);
    mag_clear(c);
    arb_clear(t);
}
Пример #3
0
/* Differential equation for F(a,b,c,y+z):

   (y+z)(y-1+z) F''(z) + ((y+z)(a+b+1) - c) F'(z) + a b F(z) = 0

   Coefficients in the Taylor series are bounded by

       A * binomial(N+k, k) * nu^k

   using the Cauchy-Kovalevskaya majorant method.
   See J. van der Hoeven, "Fast evaluation of holonomic functions near
   and in regular singularities"
*/
static void
bound(mag_t A, mag_t nu, mag_t N,
    const acb_t a, const acb_t b, const acb_t c, const acb_t y,
    const acb_t f0, const acb_t f1)
{
    mag_t M0, M1, t, u;
    acb_t d;

    acb_init(d);
    mag_init(M0);
    mag_init(M1);
    mag_init(t);
    mag_init(u);

    /* nu = max(1/|y-1|, 1/|y|) = 1/min(|y-1|, |y|) */
    acb_get_mag_lower(t, y);
    acb_sub_ui(d, y, 1, MAG_BITS);
    acb_get_mag_lower(u, d);
    mag_min(t, t, u);
    mag_one(u);
    mag_div(nu, u, t);

    /* M0 = 2 nu |ab| */
    acb_get_mag(t, a);
    acb_get_mag(u, b);
    mag_mul(M0, t, u);
    mag_mul(M0, M0, nu);
    mag_mul_2exp_si(M0, M0, 1);

    /* M1 = 2 nu |(a+b+1)y-c| + 2|a+b+1| */
    acb_add(d, a, b, MAG_BITS);
    acb_add_ui(d, d, 1, MAG_BITS);
    acb_get_mag(t, d);
    acb_mul(d, d, y, MAG_BITS);
    acb_sub(d, d, c, MAG_BITS);
    acb_get_mag(u, d);
    mag_mul(u, u, nu);
    mag_add(M1, t, u);
    mag_mul_2exp_si(M1, M1, 1);

    /* N = max(sqrt(2 M0), 2 M1) / nu */
    mag_mul_2exp_si(M0, M0, 1);
    mag_sqrt(M0, M0);
    mag_mul_2exp_si(M1, M1, 1);
    mag_max(N, M0, M1);
    mag_div(N, N, nu);

    /* A = max(|f0|, |f1| / (nu (N+1)) */
    acb_get_mag(t, f0);
    acb_get_mag(u, f1);
    mag_div(u, u, nu);
    mag_div(u, u, N);  /* upper bound for dividing by N+1 */
    mag_max(A, t, u);

    acb_clear(d);
    mag_clear(M0);
    mag_clear(M1);
    mag_clear(t);
    mag_clear(u);
}
Пример #4
0
void
acb_hypgeom_mag_chi(mag_t chi, ulong n)
{
    mag_t p, q;
    ulong k;

    mag_init(p);
    mag_init(q);

    if (n % 2 == 0)
    {
        mag_one(p);
        mag_one(q);
    }
    else
    {
        /* upper bound for pi/2 */
        mag_set_ui_2exp_si(p, 843314857, -28);
        mag_one(q);
    }

    for (k = n; k >= 2; k -= 2)
    {
        mag_mul_ui(p, p, k);
        mag_mul_ui_lower(q, q, k - 1);
    }

    mag_div(chi, p, q);

    mag_clear(p);
    mag_clear(q);
}
Пример #5
0
Файл: log1p.c Проект: isuruf/arb
static void
acb_log1p_tiny(acb_t r, const acb_t z, slong prec)
{
    mag_t b, c;
    acb_t t;
    int real;

    mag_init(b);
    mag_init(c);
    acb_init(t);

    real = acb_is_real(z);

    /* if |z| < 1, then |log(1+z) - [z - z^2/2]| <= |z|^3/(1-|z|) */
    acb_get_mag(b, z);
    mag_one(c);
    mag_sub_lower(c, c, b);
    mag_pow_ui(b, b, 3);
    mag_div(b, b, c);

    acb_mul(t, z, z, prec);
    acb_mul_2exp_si(t, t, -1);
    acb_sub(r, z, t, prec);

    if (real && mag_is_finite(b))
        arb_add_error_mag(acb_realref(r), b);
    else
        acb_add_error_mag(r, b);

    mag_clear(b);
    mag_clear(c);
    acb_clear(t);
}
static void
acb_rising_get_mag2_right(mag_t bound, const arb_t a, const arb_t b, ulong n)
{
    mag_t t, u;
    ulong k;

    mag_init(t);
    mag_init(u);

    arb_get_mag(t, a);
    arb_get_mag(u, b);

    mag_mul(bound, t, t);
    mag_addmul(bound, u, u);
    mag_set(u, bound);
    mag_mul_2exp_si(t, t, 1);

    for (k = 1; k < n; k++)
    {
        mag_add_ui_2exp_si(u, u, 2 * k - 1, 0);
        mag_add(u, u, t);
        mag_mul(bound, bound, u);
    }

    mag_clear(t);
    mag_clear(u);
}
Пример #7
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 500 * arb_test_multiplier(); iter++)
    {
        arb_t a, b;
        mag_t u, v;
        slong aprec, bprec;
        slong abits, bbits;

        aprec = 2 + n_randint(state, 1000);
        bprec = 2 + n_randint(state, 1000);
        abits = 2 + n_randint(state, 100);
        bbits = 2 + n_randint(state, 100);

        arb_init(a);
        arb_init(b);
        mag_init(u);
        mag_init(v);

        arb_randtest(a, state, aprec, abits);
        arb_randtest(b, state, bprec, bbits);

        if (arb_is_nonnegative(a) && arb_is_nonnegative(b))
        {
            acb_dirichlet_backlund_s_bound(u, a);
            acb_dirichlet_backlund_s_bound(v, b);

            if ((arb_lt(a, b) && mag_cmp(u, v) > 0) ||
                (arb_gt(a, b) && mag_cmp(u, v) < 0))
            {
                flint_printf("FAIL: increasing on t >= 0\n\n");
                flint_printf("a = "); arb_print(a); flint_printf("\n\n");
                flint_printf("b = "); arb_print(b); flint_printf("\n\n");
                flint_printf("u = "); mag_print(u); flint_printf("\n\n");
                flint_printf("v = "); mag_print(v); flint_printf("\n\n");
                flint_abort();
            }
        }

        arb_clear(a);
        arb_clear(b);
        mag_clear(u);
        mag_clear(v);
    }

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

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

    flint_randinit(state);

    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        fmpr_t x, y, z;
        mag_t xb, yb;
        slong e;

        fmpr_init(x);
        fmpr_init(y);
        fmpr_init(z);

        mag_init(xb);
        mag_init(yb);

        mag_randtest_special(xb, state, 100);
        e = z_randtest(state);
        mag_get_fmpr(x, xb);

        mag_mul_2exp_si(yb, xb, e);

        fmpr_mul_2exp_si(y, x, e);

        mag_get_fmpr(z, yb);

        MAG_CHECK_BITS(yb)

        if (!fmpr_equal(z, y))
        {
            flint_printf("FAIL\n\n");
            flint_printf("x = "); fmpr_printd(x, 15); flint_printf("\n\n");
            flint_printf("y = "); fmpr_printd(y, 15); flint_printf("\n\n");
            flint_printf("z = "); fmpr_printd(z, 15); flint_printf("\n\n");
            abort();
        }

        fmpr_clear(x);
        fmpr_clear(y);
        fmpr_clear(z);

        mag_clear(xb);
        mag_clear(yb);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #9
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);
}
Пример #10
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        fmpr_t x, y;
        mag_t xb, yb;
        int c1, c2;

        fmpr_init(x);
        fmpr_init(y);

        mag_init(xb);
        mag_init(yb);

        mag_randtest_special(xb, state, 100);
        mag_randtest_special(yb, state, 100);

        mag_get_fmpr(x, xb);
        mag_get_fmpr(y, yb);

        c1 = fmpr_cmp(x, y);
        c2 = mag_cmp(xb, yb);

        if (c1 != c2)
        {
            flint_printf("FAIL\n\n");
            flint_printf("x = "); fmpr_print(x); flint_printf("\n\n");
            flint_printf("y = "); fmpr_print(y); flint_printf("\n\n");
            flint_printf("xb = "); mag_print(xb); flint_printf("\n\n");
            flint_printf("yb = "); mag_print(yb); flint_printf("\n\n");
            abort();
        }

        fmpr_clear(x);
        fmpr_clear(y);

        mag_clear(xb);
        mag_clear(yb);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #11
0
Файл: mul.c Проект: isuruf/arb
static void
_acb_mul_slow(acb_t z, const acb_t x, const acb_t y, slong prec)
{
    int inexact;

    mag_t am, bm, cm, dm, er, fr;

    mag_init_set_arf(am, arb_midref(a));
    mag_init_set_arf(bm, arb_midref(b));
    mag_init_set_arf(cm, arb_midref(c));
    mag_init_set_arf(dm, arb_midref(d));

    mag_init(er);
    mag_init(fr);

    mag_addmul(er, am, cr);
    mag_addmul(er, bm, dr);
    mag_addmul(er, cm, ar);
    mag_addmul(er, dm, br);
    mag_addmul(er, ar, cr);
    mag_addmul(er, br, dr);

    mag_addmul(fr, am, dr);
    mag_addmul(fr, bm, cr);
    mag_addmul(fr, cm, br);
    mag_addmul(fr, dm, ar);
    mag_addmul(fr, br, cr);
    mag_addmul(fr, ar, dr);

    inexact = arf_complex_mul(arb_midref(e), arb_midref(f),
                    arb_midref(a), arb_midref(b),
                    arb_midref(c), arb_midref(d), prec, ARB_RND);

    if (inexact & 1)
        arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec);
    else
        mag_swap(arb_radref(e), er);

    if (inexact & 2)
        arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec);
    else
        mag_swap(arb_radref(f), fr);

    mag_clear(am);
    mag_clear(bm);
    mag_clear(cm);
    mag_clear(dm);

    mag_clear(er);
    mag_clear(fr);
}
Пример #12
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);
}
Пример #13
0
void
_arb_sinc_derivative_bound(mag_t d, const arb_t x)
{
    /* |f'(x)| < min(arb_get_mag(x), 1) / 2 */
    mag_t r, one;
    mag_init(r);
    mag_init(one);
    arb_get_mag(r, x);
    mag_one(one);
    mag_min(d, r, one);
    mag_mul_2exp_si(d, d, -1);
    mag_clear(r);
    mag_clear(one);
}
Пример #14
0
void
arb_root_ui_algebraic(arb_t res, const arb_t x, ulong k, slong prec)
{
    mag_t r, msubr, m1k, t;

    if (arb_is_exact(x))
    {
        arb_root_arf(res, arb_midref(x), k, prec);
        return;
    }

    if (!arb_is_nonnegative(x))
    {
        arb_indeterminate(res);
        return;
    }

    mag_init(r);
    mag_init(msubr);
    mag_init(m1k);
    mag_init(t);

    /* x = [m-r, m+r] */
    mag_set(r, arb_radref(x));
    /* m - r */
    arb_get_mag_lower(msubr, x);

    /* m^(1/k) */
    arb_root_arf(res, arb_midref(x), k, prec);

    /* bound for m^(1/k) */
    arb_get_mag(m1k, res);

    /* C = min(1, log(1+r/(m-r))/k) */
    mag_div(t, r, msubr);
    mag_log1p(t, t);
    mag_div_ui(t, t, k);
    if (mag_cmp_2exp_si(t, 0) > 0)
        mag_one(t);

    /* C m^(1/k) */
    mag_mul(t, m1k, t);
    mag_add(arb_radref(res), arb_radref(res), t);

    mag_clear(r);
    mag_clear(msubr);
    mag_clear(m1k);
    mag_clear(t);
}
Пример #15
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;
}
Пример #16
0
void
acb_get_mag(mag_t u, const acb_t z)
{
    if (arb_is_zero(acb_imagref(z)))
    {
        arb_get_mag(u, acb_realref(z));
    }
    else if (arb_is_zero(acb_realref(z)))
    {
        arb_get_mag(u, acb_imagref(z));
    }
    else
    {
        mag_t v;
        mag_init(v);

        arb_get_mag(u, acb_realref(z));
        arb_get_mag(v, acb_imagref(z));

        mag_mul(u, u, u);
        mag_addmul(u, v, v);
        mag_sqrt(u, u);

        mag_clear(v);
    }
}
Пример #17
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);
    }
}
Пример #18
0
void
acb_dirichlet_theta_arb(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t t, slong prec)
{
    slong len;
    ulong order;
    arb_t xt;
    mag_t e;

    len = acb_dirichlet_theta_length(G->q, t, prec);

    arb_init(xt);
    _acb_dirichlet_theta_argument_at_arb(xt, G->q, t, prec);

    mag_init(e);
    mag_tail_kexpk2_arb(e, xt, len);

    arb_neg(xt, xt);
    arb_exp(xt, xt, prec);

    /* TODO: tune this limit */
    order = dirichlet_order_char(G, chi);
    if (order < 30)
        _acb_dirichlet_theta_arb_smallorder(res, G, chi, xt, len, prec);
    else
        _acb_dirichlet_theta_arb_naive(res, G, chi, xt, len, prec);

    arb_add_error_mag(acb_realref(res), e);
    arb_add_error_mag(acb_imagref(res), e);

    mag_clear(e);

    acb_mul_2exp_si(res, res, 1);
    arb_clear(xt);
}
Пример #19
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);
    }
}
Пример #20
0
/* bound (1 + 1/m)^n, m > 0, n >= 0 */
void
mag_binpow_uiui(mag_t b, ulong m, ulong n)
{
    mag_t t;

    if (m == 0)
    {
        mag_inf(b);
        return;
    }

    mag_init(t);

    /* bound by exp(n/m) <= 1 + (n/m) + (n/m)^2 */
    if (m > n)
    {
        mag_set_ui(t, n);   /* x = n/m */
        mag_div_ui(t, t, m);

        mag_mul(b, t, t);   /* x^2 */
        mag_add(b, b, t);   /* x */
        mag_one(t);
        mag_add(b, b, t);   /* 1 */
    }
    else
    {
        mag_one(b);
        mag_div_ui(b, b, m);
        mag_one(t);
        mag_add(t, t, b);
        mag_pow_ui(b, t, n);
    }

    mag_clear(t);
}
Пример #21
0
static void
acb_hypgeom_mag_Cn(mag_t Cn, int R, const mag_t nu, const mag_t sigma, ulong n)
{
    if (R == 1)
    {
        mag_one(Cn);
    }
    else
    {
        acb_hypgeom_mag_chi(Cn, n);

        if (R == 3)
        {
            mag_t tmp;
            mag_init(tmp);
            mag_mul(tmp, nu, nu);
            mag_mul(tmp, tmp, sigma);
            if (n != 1)
                mag_mul_ui(tmp, tmp, n);
            mag_add(Cn, Cn, tmp);
            mag_pow_ui(tmp, nu, n);
            mag_mul(Cn, Cn, tmp);
            mag_clear(tmp);
        }
    }
}
Пример #22
0
void
acb_sinc_pi(acb_t res, const acb_t x, slong prec)
{
    mag_t m;
    acb_t t;

    if (acb_is_zero(x))
    {
        acb_one(res);
        return;
    }

    mag_init(m);
    acb_init(t);

    acb_get_mag_lower(m, x);

    if (mag_cmp_2exp_si(m, -1) > 0)
    {
        acb_const_pi(t, prec + 4);
        acb_mul(t, t, x, prec + 4);
        acb_sin_pi(res, x, prec + 4);
        acb_div(res, res, t, prec);
    }
    else
    {
        acb_const_pi(t, prec + 4);
        acb_mul(t, t, x, prec + 4);
        acb_sinc(res, t, prec);
    }

    mag_clear(m);
    acb_clear(t);
}
Пример #23
0
/* assumes no aliasing of w and p */
void
acb_lambertw_branchpoint_series(acb_t w, const acb_t t, int bound, slong prec)
{
    slong i;
    static const int coeffs[] = {-130636800,130636800,-43545600,19958400,
        -10402560,5813640,-3394560,2042589,-1256320};

    acb_zero(w);

    for (i = 8; i >= 0; i--)
    {
        acb_mul(w, w, t, prec);
        acb_add_si(w, w, coeffs[i], prec);
    }

    acb_div_si(w, w, -coeffs[0], prec);

    if (bound)
    {
        mag_t err;
        mag_init(err);
        acb_get_mag(err, t);
        mag_geom_series(err, err, 9);

        if (acb_is_real(t))
            arb_add_error_mag(acb_realref(w), err);
        else
            acb_add_error_mag(w, err);
        mag_clear(err);
    }
}
Пример #24
0
void
arb_div(arb_t z, const arb_t x, const arb_t y, long prec)
{
    mag_t zr, xm, ym, yl, yw;
    int inexact;

    if (arb_is_exact(y))
    {
        arb_div_arf(z, x, arb_midref(y), prec);
    }
    else if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
    {
        arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND);
        mag_inf(arb_radref(z));
    }
    else
    {
        mag_init_set_arf(xm, arb_midref(x));
        mag_init_set_arf(ym, arb_midref(y));
        mag_init(zr);
        mag_init(yl);
        mag_init(yw);

        /* (|x|*yrad + |y|*xrad)/(y*(|y|-yrad)) */
        mag_mul(zr, xm, arb_radref(y));
        mag_addmul(zr, ym, arb_radref(x));
        arb_get_mag_lower(yw, y);

        arf_get_mag_lower(yl, arb_midref(y));
        mag_mul_lower(yl, yl, yw);

        mag_div(zr, zr, yl);

        inexact = arf_div(arb_midref(z), arb_midref(x), arb_midref(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(xm);
        mag_clear(ym);
        mag_clear(zr);
        mag_clear(yl);
        mag_clear(yw);
    }
}
Пример #25
0
int main() {

#define ni 5
    slong n, i, f;
    double b[ni][2] = { { 0, 1}, {-1, 1}, {0, 10}, {-20, 3}, {0, 3.14} };
    const slong prec = 40;
#define nf 5
    arb_func_t func[nf] = { (arb_func_t)&f_1x2, (arb_func_t)&f_pol, (arb_func_t)&f_thsh, (arb_func_t)&f_thsh_shift, (arb_func_t)&f_aj };
#if VERBOSE
    char * fn[nf] = { "1/(1+x^2)", "1/p(x)", "th(sh(x))", "th(sh(x+.7I))" , "1/y" };
#endif
    params_t p[nf];
    
    arf_t tmin, tmax;
    mag_t max;

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

    p[1].len = 3;
    p[1].z = _acb_vec_init(3);
    acb_set_d_d(p[1].z + 0, 2, 1);
    acb_set_d_d(p[1].z + 1, 2, .1);
    acb_set_d_d(p[1].z + 2, 1, .1);

    p[4] = p[1];

    arf_init(tmin);
    arf_init(tmax);
    mag_init(max);

    for (i = 0; i < ni; i++)
    {
        arf_set_d(tmin, b[i][0]);
        arf_set_d(tmax, b[i][1]);

        for (f = 0; f < nf; f++)
        { 
            for (n = 5; n < 100; n *= 2)
            {
                slong count;
                count = mag_func_arf(max, func[f], (void *)&p[f], tmin, tmax, n, prec);
#if VERBOSE
                flint_printf("\nmax %s on [%lf, %lf] <= ",fn[f],b[i][0],b[i][1]);
                mag_printd(max,8);
                flint_printf(" [asked %ld, did %ld]", n, count);
#endif
            }
        }

    }

    mag_clear(max);
    arf_clear(tmin);
    arf_clear(tmax);

    printf("PASS\n");
    return 0;
}
Пример #26
0
void
mag_add_ui(mag_t y, const mag_t x, ulong k)
{
    mag_t t;
    mag_init(t); /* no need to free */
    mag_set_ui(t, k);
    mag_add(y, x, t);
}
Пример #27
0
void
mag_add_ui_lower(mag_t res, const mag_t x, ulong k)
{
    mag_t t;
    mag_init(t);
    mag_set_ui_lower(t, k);  /* no need to free */
    mag_add_lower(res, x, t);
}
Пример #28
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        fmpr_t a, b, c;
        mag_t m;
        double x;

        fmpr_init(a);
        fmpr_init(b);
        fmpr_init(c);
        mag_init(m);

        x = d_randtest2(state);
        x = ldexp(x, 100 - n_randint(state, 200));

        if (n_randint(state, 100) == 0)
            x = 0.0;

        fmpr_set_d(a, x);
        mag_set_d(m, x);

        mag_get_fmpr(b, m);

        fmpr_set(c, a);
        fmpr_mul_ui(c, c, 1025, MAG_BITS, FMPR_RND_UP);
        fmpr_mul_2exp_si(c, c, -10);

        MAG_CHECK_BITS(m)

        if (!(fmpr_cmpabs(a, b) <= 0 && fmpr_cmpabs(b, c) <= 0))
        {
            flint_printf("FAIL\n\n");
            flint_printf("a = "); fmpr_print(a); flint_printf("\n\n");
            flint_printf("b = "); fmpr_print(b); flint_printf("\n\n");
            flint_printf("c = "); fmpr_print(c); flint_printf("\n\n");
            abort();
        }

        fmpr_clear(a);
        fmpr_clear(b);
        fmpr_clear(c);
        mag_clear(m);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #29
0
void
fmprb_hypgeom_infsum(fmprb_t P, fmprb_t Q, hypgeom_t hyp, long target_prec, long prec)
{
    mag_t err, z;
    long n;

    mag_init(err);
    mag_init(z);

    mag_set_fmpz(z, hyp->P->coeffs + hyp->P->length - 1);
    mag_div_fmpz(z, z, hyp->Q->coeffs + hyp->Q->length - 1);

    if (!hyp->have_precomputed)
    {
        hypgeom_precompute(hyp);
        hyp->have_precomputed = 1;
    }

    n = hypgeom_bound(err, hyp->r, hyp->boundC, hyp->boundD,
        hyp->boundK, hyp->MK, z, target_prec);

    fmprb_hypgeom_sum(P, Q, hyp, n, prec);

    if (fmpr_sgn(fmprb_midref(Q)) < 0)
    {
        fmprb_neg(P, P);
        fmprb_neg(Q, Q);
    }

    /* We have p/q = s + err i.e. (p + q*err)/q = s */
    {
        fmpr_t u, v;
        fmpr_init(u);
        fmpr_init(v);
        mag_get_fmpr(v, err);
        fmpr_add(u, fmprb_midref(Q), fmprb_radref(Q), FMPRB_RAD_PREC, FMPR_RND_UP);
        fmpr_mul(u, u, v, FMPRB_RAD_PREC, FMPR_RND_UP);
        fmprb_add_error_fmpr(P, u);
        fmpr_clear(u);
        fmpr_clear(v);
    }

    mag_clear(z);
    mag_clear(err);
}
Пример #30
0
void
acb_dirichlet_zeta_rs(acb_t res, const acb_t s, slong K, slong prec)
{
    if (acb_is_exact(s))
    {
        acb_dirichlet_zeta_rs_mid(res, s, K, prec);
    }
    else
    {
        acb_t t;
        mag_t rad, err, err2;
        slong acc;

        acc = acb_rel_accuracy_bits(s);
        acc = FLINT_MAX(acc, 0);
        acc = FLINT_MIN(acc, prec);
        prec = FLINT_MIN(prec, acc + 20);

        acb_init(t);
        mag_init(rad);
        mag_init(err);
        mag_init(err2);

        /* rad = rad(s) */
        mag_hypot(rad, arb_radref(acb_realref(s)), arb_radref(acb_imagref(s)));

        /* bound |zeta'(s)| */
        acb_dirichlet_zeta_deriv_bound(err, err2, s);

        /* error <= |zeta'(s)| * rad(s) */
        mag_mul(err, err, rad);

        /* evaluate at midpoint */
        acb_get_mid(t, s);
        acb_dirichlet_zeta_rs_mid(res, t, K, prec);

        acb_add_error_mag(res, err);

        acb_clear(t);
        mag_clear(rad);
        mag_clear(err);
        mag_clear(err2);
    }
}