コード例 #1
0
ファイル: evaluate_rectangular.c プロジェクト: certik/arb
void
_fmprb_poly_evaluate_rectangular(fmprb_t y, fmprb_srcptr poly,
    long len, const fmprb_t x, long prec)
{
    long i, j, m, r;
    fmprb_ptr xs;
    fmprb_t s, t, c;

    if (len < 3)
    {
        if (len == 0)
        {
            fmprb_zero(y);
        }
        else if (len == 1)
        {
            fmprb_set_round(y, poly + 0, prec);
        }
        else if (len == 2)
        {
            fmprb_mul(y, x, poly + 1, prec);
            fmprb_add(y, y, poly + 0, prec);
        }
        return;
    }

    m = n_sqrt(len) + 1;
    r = (len + m - 1) / m;

    xs = _fmprb_vec_init(m + 1);
    fmprb_init(s);
    fmprb_init(t);
    fmprb_init(c);

    _fmprb_vec_set_powers(xs, x, m + 1, prec);

    fmprb_set(y, poly + (r - 1) * m);
    for (j = 1; (r - 1) * m + j < len; j++)
        fmprb_addmul(y, xs + j, poly + (r - 1) * m + j, prec);

    for (i = r - 2; i >= 0; i--)
    {
        fmprb_set(s, poly + i * m);
        for (j = 1; j < m; j++)
            fmprb_addmul(s, xs + j, poly + i * m + j, prec);

        fmprb_mul(y, y, xs + m, prec);
        fmprb_add(y, y, s, prec);
    }

    _fmprb_vec_clear(xs, m + 1);
    fmprb_clear(s);
    fmprb_clear(t);
    fmprb_clear(c);
}
コード例 #2
0
ファイル: agm.c プロジェクト: bluescarni/arb
void
fmprb_agm(fmprb_t z, const fmprb_t x, const fmprb_t y, long prec)
{
    fmprb_t t, u, v, w;

    if (fmprb_contains_negative(x) || fmprb_contains_negative(y))
    {
        fmprb_indeterminate(z);
        return;
    }

    if (fmprb_is_zero(x) || fmprb_is_zero(y))
    {
        fmprb_zero(z);
        return;
    }

    fmprb_init(t);
    fmprb_init(u);
    fmprb_init(v);
    fmprb_init(w);

    fmprb_set(t, x);
    fmprb_set(u, y);

    while (!fmprb_overlaps(t, u) &&
            !fmprb_contains_nonpositive(t) &&
            !fmprb_contains_nonpositive(u))
    {
        fmprb_add(v, t, u, prec);
        fmprb_mul_2exp_si(v, v, -1);

        fmprb_mul(w, t, u, prec);
        fmprb_sqrt(w, w, prec);

        fmprb_swap(v, t);
        fmprb_swap(w, u);
    }

    if (!fmprb_is_finite(t) || !fmprb_is_finite(u))
    {
        fmprb_indeterminate(z);
    }
    else
    {
        fmprb_union(z, t, u, prec);
    }

    fmprb_clear(t);
    fmprb_clear(u);
    fmprb_clear(v);
    fmprb_clear(w);
}
コード例 #3
0
ファイル: lu.c プロジェクト: certik/arb
int
fmprb_mat_lu(long * P, fmprb_mat_t LU, const fmprb_mat_t A, long prec)
{
    fmprb_t d, e;
    fmprb_ptr * a;
    long i, j, m, n, r, row, col;
    int result;

    m = fmprb_mat_nrows(A);
    n = fmprb_mat_ncols(A);

    result = 1;

    if (m == 0 || n == 0)
        return result;

    fmprb_mat_set(LU, A);

    a = LU->rows;

    row = col = 0;
    for (i = 0; i < m; i++)
        P[i] = i;

    fmprb_init(d);
    fmprb_init(e);

    while (row < m && col < n)
    {
        r = fmprb_mat_find_pivot_partial(LU, row, m, col);

        if (r == -1)
        {
            result = 0;
            break;
        }
        else if (r != row)
            fmprb_mat_swap_rows(LU, P, row, r);

        fmprb_set(d, a[row] + col);

        for (j = row + 1; j < m; j++)
        {
            fmprb_div(e, a[j] + col, d, prec);
            fmprb_neg(e, e);
            _fmprb_vec_scalar_addmul(a[j] + col,
                a[row] + col, n - col, e, prec);
            fmprb_zero(a[j] + col);
            fmprb_neg(a[j] + row, e);
        }

        row++;
        col++;
    }

    fmprb_clear(d);
    fmprb_clear(e);

    return result;
}
コード例 #4
0
ファイル: det.c プロジェクト: certik/arb
void
fmprb_mat_det(fmprb_t det, const fmprb_mat_t A, long prec)
{
    long n = fmprb_mat_nrows(A);

    if (n == 0)
    {
        fmprb_one(det);
    }
    else if (n == 1)
    {
        fmprb_set(det, fmprb_mat_entry(A, 0, 0));
    }
    else if (n == 2)
    {
        fmprb_mul(det, fmprb_mat_entry(A, 0, 0), fmprb_mat_entry(A, 1, 1), prec);
        fmprb_submul(det, fmprb_mat_entry(A, 0, 1), fmprb_mat_entry(A, 1, 0), prec);
    }
    else
    {
        fmprb_mat_t T;
        fmprb_mat_init(T, fmprb_mat_nrows(A), fmprb_mat_ncols(A));
        fmprb_mat_set(T, A);
        fmprb_mat_det_inplace(det, T, prec);
        fmprb_mat_clear(T);
    }
}
コード例 #5
0
ファイル: zeta.c プロジェクト: certik/arb
void
fmprb_zeta(fmprb_t y, const fmprb_t s, long prec)
{
    fmpcb_t t;
    fmpcb_init(t);
    fmpcb_set_fmprb(t, s),
    fmpcb_zeta(t, t, prec);
    fmprb_set(y, fmpcb_realref(t));
    fmpcb_clear(t);
}
コード例 #6
0
ファイル: real_roots.c プロジェクト: certik/arb
int
sin_x(fmprb_ptr out, const fmprb_t inp, void * params, long order, long prec)
{
    int xlen = FLINT_MIN(2, order);

    fmprb_set(out, inp);
    if (xlen > 1)
        fmprb_one(out + 1);

    _fmprb_poly_sin_series(out, out, xlen, order, prec);

    eval_count++;
    return 0;
}
コード例 #7
0
ファイル: series_em_bound.c プロジェクト: certik/arb
void
bound_I(fmprb_ptr I, const fmprb_t A, const fmprb_t B, const fmprb_t C, long len, long wp)
{
    long k;

    fmprb_t D, Dk, L, T, Bm1;

    fmprb_init(D);
    fmprb_init(Dk);
    fmprb_init(Bm1);
    fmprb_init(T);
    fmprb_init(L);

    fmprb_sub_ui(Bm1, B, 1, wp);
    fmprb_one(L);

    /* T = 1 / (A^Bm1 * Bm1) */
    fmprb_inv(T, A, wp);
    fmprb_pow(T, T, Bm1, wp);
    fmprb_div(T, T, Bm1, wp);

    if (len > 1)
    {
        fmprb_log(D, A, wp);
        fmprb_add(D, D, C, wp);
        fmprb_mul(D, D, Bm1, wp);
        fmprb_set(Dk, D);
    }

    for (k = 0; k < len; k++)
    {
        if (k > 0)
        {
            fmprb_mul_ui(L, L, k, wp);
            fmprb_add(L, L, Dk, wp);
            fmprb_mul(Dk, Dk, D, wp);
        }

        fmprb_mul(I + k, L, T, wp);
        fmprb_div(T, T, Bm1, wp);
    }

    fmprb_clear(D);
    fmprb_clear(Dk);
    fmprb_clear(Bm1);
    fmprb_clear(T);
    fmprb_clear(L);
}
コード例 #8
0
void
gamma_rising_fmprb_ui_bsplit_eight(fmprb_t y, const fmprb_t x, ulong n, long prec)
{
    if (n == 0)
    {
        fmprb_one(y);
    }
    else if (n == 1)
    {
        fmprb_set_round(y, x, prec);
    }
    else
    {
        ulong k, a;
        long wp;
        fmprb_t t, u;

        wp = FMPR_PREC_ADD(prec, FLINT_BIT_COUNT(n));

        fmprb_init(t);
        fmprb_init(u);

        if (n >= 8)
        {
            bsplit(t, x, 0, (n / 8) * 8, wp);
            a = (n / 8) * 8;
        }
        else
        {
            fmprb_set(t, x);
            a = 1;
        }

        for (k = a; k < n; k++)
        {
            fmprb_add_ui(u, x, k, wp);
            fmprb_mul(t, t, u, wp);
        }

        fmprb_set_round(y, t, prec);

        fmprb_clear(t);
        fmprb_clear(u);
    }
}
コード例 #9
0
ファイル: real_roots.c プロジェクト: certik/arb
int
z_function(fmprb_ptr out, const fmprb_t inp, void * params, long order, long prec)
{
    fmprb_struct x[2];

    fmprb_init(x);
    fmprb_init(x + 1);

    fmprb_set(x, inp);
    fmprb_one(x + 1);

    _fmprb_poly_riemann_siegel_z_series(out, x, FLINT_MIN(2, order), order, prec);

    fmprb_clear(x);
    fmprb_clear(x + 1);

    eval_count++;
    return 0;
}
コード例 #10
0
ファイル: real_roots.c プロジェクト: certik/arb
int
sin_1x(fmprb_ptr out, const fmprb_t inp, void * params, long order, long prec)
{
    fmprb_ptr x;
    int xlen = FLINT_MIN(2, order);

    x = _fmprb_vec_init(xlen);

    fmprb_set(x, inp);
    if (xlen > 1)
        fmprb_one(x + 1);

    _fmprb_poly_inv_series(out, x, xlen, order, prec);
    _fmprb_poly_sin_series(out, out, order, order, prec);

    _fmprb_vec_clear(x, xlen);

    eval_count++;
    return 0;
}
コード例 #11
0
ファイル: shift_left.c プロジェクト: certik/arb
void
_fmprb_poly_shift_left(fmprb_ptr res, fmprb_srcptr poly, long len, long n)
{
    long i;

    /* Copy in reverse to avoid writing over unshifted coefficients */
    if (res != poly)
    {
        for (i = len; i--; )
            fmprb_set(res + n + i, poly + i);
    }
    else
    {
        for (i = len; i--; )
            fmprb_swap(res + n + i, res + i);
    }

    for (i = 0; i < n; i++)
        fmprb_zero(res + i);
}
コード例 #12
0
ファイル: sqrtpos.c プロジェクト: isuruf/arb
static __inline__ void
fmprb_nonnegative_part(fmprb_t z, const fmprb_t x, slong prec)
{
    if (fmprb_contains_negative(x))
    {
        fmpr_add(fmprb_midref(z), fmprb_midref(x), fmprb_radref(x), prec, FMPR_RND_CEIL);

        if (fmpr_sgn(fmprb_midref(z)) <= 0)
        {
            fmpr_zero(fmprb_radref(z));
        }
        else
        {
            fmpr_mul_2exp_si(fmprb_midref(z), fmprb_midref(z), -1);
            fmpr_set(fmprb_midref(z), fmprb_radref(z));
        }
    }
    else
    {
        fmprb_set(z, x);
    }
}
コード例 #13
0
void
_fmprb_poly_riemann_siegel_theta_series(fmprb_ptr res,
    fmprb_srcptr h, long hlen, long len, long prec)
{
    fmpcb_ptr s;
    fmprb_t u;
    long i;

    hlen = FLINT_MIN(hlen, len);

    s = _fmpcb_vec_init(len);

    fmprb_init(u);

    /* s = 1/4 + (1/2) i h */
    for (i = 0; i < hlen; i++)
        fmprb_mul_2exp_si(fmpcb_imagref(s + i), h + i, -1);

    fmprb_one(u);
    fmprb_mul_2exp_si(u, u, -2);
    fmprb_add(fmpcb_realref(s), fmpcb_realref(s), u, prec);

    /* log gamma */
    _fmpcb_poly_lgamma_series(s, s, hlen, len, prec);

    /* imaginary part */
    for (i = 0; i < len; i++)
        fmprb_set(res + i, fmpcb_imagref(s + i));

    /* subtract log(pi)/2 * h */
    fmprb_const_pi(u, prec);
    fmprb_log(u, u, prec);
    fmprb_mul_2exp_si(u, u, -1);
    fmprb_neg(u, u);
    _fmprb_vec_scalar_addmul(res, h, hlen, u, prec);

    _fmpcb_vec_clear(s, len);
    fmprb_clear(u);
}
コード例 #14
0
ファイル: evaluate_horner.c プロジェクト: certik/arb
void
_fmprb_poly_evaluate_horner(fmprb_t y, fmprb_srcptr f, long len,
                           const fmprb_t x, long prec)
{
    if (len == 0)
    {
        fmprb_zero(y);
    }
    else if (len == 1 || fmprb_is_zero(x))
    {
        fmprb_set_round(y, f, prec);
    }
    else if (len == 2)
    {
        fmprb_mul(y, x, f + 1, prec);
        fmprb_add(y, y, f + 0, prec);
    }
    else
    {
        long i = len - 1;
        fmprb_t t, u;

        fmprb_init(t);
        fmprb_init(u);
        fmprb_set(u, f + i);

        for (i = len - 2; i >= 0; i--)
        {
            fmprb_mul(t, u, x, prec);
            fmprb_add(u, f + i, t, prec);
        }

        fmprb_swap(y, u);

        fmprb_clear(t);
        fmprb_clear(u);
    }
}
コード例 #15
0
ファイル: ui_borwein_bsplit.c プロジェクト: certik/arb
static __inline__ void
zeta_coeff_k(zeta_bsplit_t S, long k, long n, long s)
{
    fmprb_set_si(S->D, 2 * (n + k));
    fmprb_mul_si(S->D, S->D, n - k, FMPR_PREC_EXACT);
    fmprb_set_si(S->Q1, k + 1);
    fmprb_mul_si(S->Q1, S->Q1, 2*k + 1, FMPR_PREC_EXACT);

    if (k == 0)
    {
        fmprb_zero(S->A);
        fmprb_one(S->Q2);
    }
    else
    {
        fmprb_set_si(S->A, k % 2 ? 1 : -1);
        fmprb_mul(S->A, S->A, S->Q1, FMPR_PREC_EXACT);
        fmprb_ui_pow_ui(S->Q2, k, s, FMPR_PREC_EXACT);
    }

    fmprb_mul(S->Q3, S->Q1, S->Q2, FMPR_PREC_EXACT);
    fmprb_zero(S->B);
    fmprb_set(S->C, S->Q1);
}
コード例 #16
0
ファイル: t-digamma.c プロジェクト: certik/arb
int main()
{
    long iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 3000; iter++)
    {
        fmprb_t a, b, c;
        long prec1, prec2;

        prec1 = 2 + n_randint(state, 1000);
        prec2 = prec1 + 30;

        fmprb_init(a);
        fmprb_init(b);
        fmprb_init(c);

        fmprb_randtest_precise(a, state, 1 + n_randint(state, 1000), 10);

        fmprb_digamma(b, a, prec1);
        fmprb_digamma(c, a, prec2);

        if (!fmprb_overlaps(b, c))
        {
            printf("FAIL: overlap\n\n");
            printf("a = "); fmprb_print(a); printf("\n\n");
            printf("b = "); fmprb_print(b); printf("\n\n");
            printf("c = "); fmprb_print(c); printf("\n\n");
            abort();
        }

        fmprb_set(c, a);
        fmprb_digamma(c, c, prec2);
        if (!fmprb_overlaps(b, c))
        {
            printf("FAIL: aliasing\n\n");
            printf("a = "); fmprb_print(a); printf("\n\n");
            printf("b = "); fmprb_print(b); printf("\n\n");
            printf("c = "); fmprb_print(c); printf("\n\n");
            abort();
        }

        /* check digamma(z+1) = digamma(z) + 1/z */
        fmprb_inv(c, a, prec1);
        fmprb_add(b, b, c, prec1);
        fmprb_add_ui(c, a, 1, prec1);
        fmprb_digamma(c, c, prec1);

        if (!fmprb_overlaps(b, c))
        {
            printf("FAIL: functional equation\n\n");
            printf("a = "); fmprb_print(a); printf("\n\n");
            printf("b = "); fmprb_print(b); printf("\n\n");
            printf("c = "); fmprb_print(c); printf("\n\n");
            abort();
        }

        fmprb_clear(a);
        fmprb_clear(b);
        fmprb_clear(c);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
コード例 #17
0
ファイル: compose_divconquer.c プロジェクト: certik/arb
void
_fmprb_poly_compose_divconquer(fmprb_ptr res, fmprb_srcptr poly1, long len1,
                                          fmprb_srcptr poly2, long len2, long prec)
{
    long i, j, k, n;
    long *hlen, alloc, powlen;
    fmprb_ptr v, pow, temp;
    fmprb_ptr * h;

    if (len1 == 1)
    {
        fmprb_set(res, poly1);
        return;
    }
    if (len2 == 1)
    {
        _fmprb_poly_evaluate(res, poly1, len1, poly2, prec);
        return;
    }
    if (len1 == 2)
    {
        _fmprb_poly_compose_horner(res, poly1, len1, poly2, len2, prec);
        return;
    }

    /* Initialisation */
    
    hlen = (long *) flint_malloc(((len1 + 1) / 2) * sizeof(long));
    
    for (k = 1; (2 << k) < len1; k++) ;
    
    hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1;
    for (i = k - 1; i > 0; i--)
    {
        long hi = (len1 + (1 << i) - 1) / (1 << i);
        for (n = (hi + 1) / 2; n < hi; n++)
            hlen[n] = ((1 << i) - 1) * (len2 - 1) + 1;
    }
    powlen = (1 << k) * (len2 - 1) + 1;
    
    alloc = 0;
    for (i = 0; i < (len1 + 1) / 2; i++)
        alloc += hlen[i];

    v = _fmprb_vec_init(alloc + 2 * powlen);
    h = (fmprb_ptr *) flint_malloc(((len1 + 1) / 2) * sizeof(fmprb_ptr));
    h[0] = v;
    for (i = 0; i < (len1 - 1) / 2; i++)
    {
        h[i + 1] = h[i] + hlen[i];
        hlen[i] = 0;
    }
    hlen[(len1 - 1) / 2] = 0;
    pow = v + alloc;
    temp = pow + powlen;
    
    /* Let's start the actual work */
    
    for (i = 0, j = 0; i < len1 / 2; i++, j += 2)
    {
        if (!fmprb_is_zero(poly1 + j + 1))
        {
            _fmprb_vec_scalar_mul(h[i], poly2, len2, poly1 + j + 1, prec);
            fmprb_add(h[i], h[i], poly1 + j, prec);
            hlen[i] = len2;
        }
        else if (!fmprb_is_zero(poly1 + j))
        {
            fmprb_set(h[i], poly1 + j);
            hlen[i] = 1;
        }
    }
    if ((len1 & 1L))
    {
        if (!fmprb_is_zero(poly1 + j))
        {
            fmprb_set(h[i], poly1 + j);
            hlen[i] = 1;
        }
    }
    
    _fmprb_poly_mul(pow, poly2, len2, poly2, len2, prec);
    powlen = 2 * len2 - 1;
    
    for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2)
    {
        if (hlen[1] > 0)
        {
            long templen = powlen + hlen[1] - 1;
            _fmprb_poly_mul(temp, pow, powlen, h[1], hlen[1], prec);
            _fmprb_poly_add(h[0], temp, templen, h[0], hlen[0], prec);
            hlen[0] = FLINT_MAX(hlen[0], templen);
        }
        
        for (i = 1; i < n / 2; i++)
        {
            if (hlen[2*i + 1] > 0)
            {
                _fmprb_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1], prec);
                hlen[i] = hlen[2*i + 1] + powlen - 1;
            } else
                hlen[i] = 0;
            _fmprb_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i], prec);
            hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]);
        }
        if ((n & 1L))
        {
            _fmprb_vec_set(h[i], h[2*i], hlen[2*i]);
            hlen[i] = hlen[2*i];
        }
        
        _fmprb_poly_mul(temp, pow, powlen, pow, powlen, prec);
        powlen += powlen - 1;
        {
            fmprb_ptr t = pow;
            pow = temp;
            temp = t;
        }
    }

    _fmprb_poly_mul(res, pow, powlen, h[1], hlen[1], prec);
    _fmprb_vec_add(res, res, h[0], hlen[0], prec);
    
    _fmprb_vec_clear(v, alloc + 2 * powlen);
    flint_free(h);
    flint_free(hlen);
}
コード例 #18
0
ファイル: zeta_series.c プロジェクト: jwbober/arb
void
_fmprb_poly_zeta_series(fmprb_ptr res, fmprb_srcptr h, long hlen, const fmprb_t a, int deflate, long len, long prec)
{
    long i;
    fmpcb_t cs, ca;
    fmpcb_ptr z;
    fmprb_ptr t, u;

    if (fmprb_contains_nonpositive(a))
    {
        _fmprb_vec_indeterminate(res, len);
        return;
    }

    hlen = FLINT_MIN(hlen, len);

    z = _fmpcb_vec_init(len);
    t = _fmprb_vec_init(len);
    u = _fmprb_vec_init(len);
    fmpcb_init(cs);
    fmpcb_init(ca);

    /* use reflection formula */
    if (fmpr_sgn(fmprb_midref(h)) < 0 && fmprb_is_one(a))
    {
        /* zeta(s) = (2*pi)**s * sin(pi*s/2) / pi * gamma(1-s) * zeta(1-s) */
        fmprb_t pi;
        fmprb_ptr f, s1, s2, s3, s4;

        fmprb_init(pi);
        f = _fmprb_vec_init(2);
        s1 = _fmprb_vec_init(len);
        s2 = _fmprb_vec_init(len);
        s3 = _fmprb_vec_init(len);
        s4 = _fmprb_vec_init(len);

        fmprb_const_pi(pi, prec);

        /* s1 = (2*pi)**s */
        fmprb_mul_2exp_si(pi, pi, 1);
        _fmprb_poly_pow_cpx(s1, pi, h, len, prec);
        fmprb_mul_2exp_si(pi, pi, -1);

        /* s2 = sin(pi*s/2) / pi */
        fmprb_mul_2exp_si(pi, pi, -1);
        fmprb_mul(f, pi, h, prec);
        fmprb_set(f + 1, pi);
        fmprb_mul_2exp_si(pi, pi, 1);
        _fmprb_poly_sin_series(s2, f, 2, len, prec);
        _fmprb_vec_scalar_div(s2, s2, len, pi, prec);

        /* s3 = gamma(1-s) */
        fmprb_sub_ui(f, h, 1, prec);
        fmprb_neg(f, f);
        fmprb_set_si(f + 1, -1);
        _fmprb_poly_gamma_series(s3, f, 2, len, prec);

        /* s4 = zeta(1-s) */
        fmprb_sub_ui(f, h, 1, prec);
        fmprb_neg(f, f);
        fmpcb_set_fmprb(cs, f);
        fmpcb_one(ca);
        zeta_series(z, cs, ca, 0, len, prec);
        for (i = 0; i < len; i++)
            fmprb_set(s4 + i, fmpcb_realref(z + i));
        for (i = 1; i < len; i += 2)
            fmprb_neg(s4 + i, s4 + i);

        _fmprb_poly_mullow(u, s1, len, s2, len, len, prec);
        _fmprb_poly_mullow(s1, s3, len, s4, len, len, prec);
        _fmprb_poly_mullow(t, u, len, s1, len, len, prec);

        /* add 1/(1-(s+t)) = 1/(1-s) + t/(1-s)^2 + ... */
        if (deflate)
        {
            fmprb_sub_ui(u, h, 1, prec);
            fmprb_neg(u, u);
            fmprb_ui_div(u, 1, u, prec);
            for (i = 1; i < len; i++)
                fmprb_mul(u + i, u + i - 1, u, prec);
            _fmprb_vec_add(t, t, u, len, prec);
        }

        fmprb_clear(pi);
        _fmprb_vec_clear(f, 2);
        _fmprb_vec_clear(s1, len);
        _fmprb_vec_clear(s2, len);
        _fmprb_vec_clear(s3, len);
        _fmprb_vec_clear(s4, len);
    }
    else
    {
        fmpcb_set_fmprb(cs, h);
        fmpcb_set_fmprb(ca, a);
        zeta_series(z, cs, ca, deflate, len, prec);
        for (i = 0; i < len; i++)
            fmprb_set(t + i, fmpcb_realref(z + i));
    }

    /* compose with nonconstant part */
    fmprb_zero(u);
    _fmprb_vec_set(u + 1, h + 1, hlen - 1);
    _fmprb_poly_compose_series(res, t, len, u, hlen, len, prec);

    _fmpcb_vec_clear(z, len);
    _fmprb_vec_clear(t, len);
    _fmprb_vec_clear(u, len);
    fmpcb_init(cs);
    fmpcb_init(ca);
}
コード例 #19
0
ファイル: cauchy_bound.c プロジェクト: certik/arb
void
fmpcb_calc_cauchy_bound(fmprb_t bound, fmpcb_calc_func_t func, void * param,
    const fmpcb_t x, const fmprb_t radius, long maxdepth, long prec)
{
    long i, n, depth, wp;

    fmprb_t pi, theta, v, s1, c1, s2, c2, st, ct;
    fmpcb_t t, u;
    fmprb_t b;

    fmprb_init(pi);
    fmprb_init(theta);
    fmprb_init(v);

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

    fmpcb_init(t);
    fmpcb_init(u);
    fmprb_init(b);

    wp = prec + 20;

    fmprb_const_pi(pi, wp);
    fmprb_zero_pm_inf(b);

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

        /* theta = 2 pi / n */
        fmprb_div_ui(theta, pi, n, wp);
        fmprb_mul_2exp_si(theta, theta, 1);

        /* sine and cosine of i*theta and (i+1)*theta */
        fmprb_zero(s1);
        fmprb_one(c1);
        fmprb_sin_cos(st, ct, theta, wp);
        fmprb_set(s2, st);
        fmprb_set(c2, ct);

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

            /* since we use power of two subdivision points, the
               sine and cosine are monotone on each subinterval */
            fmprb_union(fmpcb_realref(t), c1, c2, wp);
            fmprb_union(fmpcb_imagref(t), s1, s2, wp);
            fmpcb_mul_fmprb(t, t, radius, wp);
            fmpcb_add(t, t, x, prec);

            /* next angle */
            fmprb_mul(v, c2, ct, wp);
            fmprb_mul(c1, s2, st, wp);
            fmprb_sub(c1, v, c1, wp);
            fmprb_mul(v, c2, st, wp);
            fmprb_mul(s1, s2, ct, wp);
            fmprb_add(s1, v, s1, wp);
            fmprb_swap(c1, c2);
            fmprb_swap(s1, s2);

            func(u, t, param, 1, prec);
            fmpcb_abs(v, u, prec);
            fmprb_add(b, b, v, prec);
        }

        fmprb_div_ui(b, b, n, prec);

        if (fmprb_is_exact(b) || fmpr_cmp(fmprb_radref(b), fmprb_midref(b)) < 0)
            break;
    }

    fmprb_set(bound, b);

    fmprb_clear(pi);
    fmprb_clear(theta);
    fmprb_clear(v);

    fmpcb_clear(t);
    fmpcb_clear(u);
    fmprb_clear(b);

    fmprb_clear(s1);
    fmprb_clear(c1);
    fmprb_clear(s2);
    fmprb_clear(c2);
    fmprb_clear(st);
    fmprb_clear(ct);
}
コード例 #20
0
ファイル: evaluate_vec_fast.c プロジェクト: certik/arb
void
_fmprb_poly_evaluate_vec_fast_precomp(fmprb_ptr vs, fmprb_srcptr poly,
    long plen, fmprb_ptr * tree, long len, long prec)
{
    long height, i, j, pow, left;
    long tree_height;
    long tlen;
    fmprb_ptr t, u, swap, pa, pb, pc;

    /* avoid worrying about some degenerate cases */
    if (len < 2 || plen < 2)
    {
        if (len == 1)
        {
            fmprb_t tmp;
            fmprb_init(tmp);
            fmprb_neg(tmp, tree[0] + 0);
            _fmprb_poly_evaluate(vs + 0, poly, plen, tmp, prec);
            fmprb_clear(tmp);
        }
        else if (len != 0 && plen == 0)
        {
            _fmprb_vec_zero(vs, len);
        }
        else if (len != 0 && plen == 1)
        {
            for (i = 0; i < len; i++)
                fmprb_set(vs + i, poly + 0);
        }
        return;
    }

    t = _fmprb_vec_init(len);
    u = _fmprb_vec_init(len);

    left = len;

    /* Initial reduction. We allow the polynomial to be larger
        or smaller than the number of points. */
    height = FLINT_BIT_COUNT(plen - 1) - 1;
    tree_height = FLINT_CLOG2(len);
    while (height >= tree_height)
        height--;
    pow = 1L << height;

    for (i = j = 0; i < len; i += pow, j += (pow + 1))
    {
        tlen = ((i + pow) <= len) ? pow : len % pow;
        _fmprb_poly_rem(t + i, poly, plen, tree[height] + j, tlen + 1, prec);
    }

    for (i = height - 1; i >= 0; i--)
    {
        pow = 1L << i;
        left = len;
        pa = tree[i];
        pb = t;
        pc = u;

        while (left >= 2 * pow)
        {
            _fmprb_poly_rem_2(pc, pb, 2 * pow, pa, pow + 1, prec);
            _fmprb_poly_rem_2(pc + pow, pb, 2 * pow, pa + pow + 1, pow + 1, prec);

            pa += 2 * pow + 2;
            pb += 2 * pow;
            pc += 2 * pow;
            left -= 2 * pow;
        }

        if (left > pow)
        {
            _fmprb_poly_rem(pc, pb, left, pa, pow + 1, prec);
            _fmprb_poly_rem(pc + pow, pb, left, pa + pow + 1, left - pow + 1, prec);
        }
        else if (left > 0)
            _fmprb_vec_set(pc, pb, left);

        swap = t;
        t = u;
        u = swap;
    }

    _fmprb_vec_set(vs, t, len);
    _fmprb_vec_clear(t, len);
    _fmprb_vec_clear(u, len);
}
コード例 #21
0
ファイル: gamma.c プロジェクト: jwbober/arb
static void
_fmprb_gamma(fmprb_t y, const fmprb_t x, long prec, int inverse)
{
    int reflect;
    long r, n, wp;
    fmprb_t t, u, v;

    if (fmprb_is_exact(x))
    {
        const fmpr_struct * mid = fmprb_midref(x);

        if (fmpr_is_special(mid))
        {
            if (!inverse && fmpr_is_pos_inf(mid))
            {
                fmprb_set(y, x);
            }
            else if (fmpr_is_nan(mid) || fmpr_is_neg_inf(mid) || !inverse)
            {
                fmpr_nan(fmprb_midref(y));
                fmpr_pos_inf(fmprb_radref(y));
            }
            else
            {
                fmprb_zero(y);
            }
            return;
        }
        else
        {
            const fmpz exp = *fmpr_expref(mid);
            const fmpz man = *fmpr_manref(mid);

            /* fast gamma(n), gamma(n/2) or gamma(n/4) */
            if (!COEFF_IS_MPZ(exp) && (exp >= -2) &&
                ((double) fmpz_bits(&man) + exp < prec))
            {
                fmpq_t a;
                fmpq_init(a);
                fmpr_get_fmpq(a, mid);
                fmprb_gamma_fmpq(y, a, prec + 2 * inverse);
                if (inverse)
                    fmprb_ui_div(y, 1, y, prec);
                fmpq_clear(a);
                return;
            }
        }
    }

    wp = prec + FLINT_BIT_COUNT(prec);

    gamma_stirling_choose_param_fmprb(&reflect, &r, &n, x, 1, 0, wp);

    fmprb_init(t);
    fmprb_init(u);
    fmprb_init(v);

    if (reflect)
    {
        /* gamma(x) = (rf(1-x, r) * pi) / (gamma(1-x+r) sin(pi x)) */
        fmprb_sub_ui(t, x, 1, wp);
        fmprb_neg(t, t);
        gamma_rising_fmprb_ui_bsplit(u, t, r, wp);
        fmprb_const_pi(v, wp);
        fmprb_mul(u, u, v, wp);
        fmprb_add_ui(t, t, r, wp);
        gamma_stirling_eval_fmprb(v, t, n, 0, wp);
        fmprb_exp(v, v, wp);
        fmprb_sin_pi(t, x, wp);
        fmprb_mul(v, v, t, wp);
    }
    else
    {
        /* gamma(x) = gamma(x+r) / rf(x,r) */
        fmprb_add_ui(t, x, r, wp);
        gamma_stirling_eval_fmprb(u, t, n, 0, wp);
        fmprb_exp(u, u, prec);
        gamma_rising_fmprb_ui_bsplit(v, x, r, wp);
    }

    if (inverse)
        fmprb_div(y, v, u, prec);
    else
        fmprb_div(y, u, v, prec);

    fmprb_clear(t);
    fmprb_clear(u);
    fmprb_clear(v);
}
コード例 #22
0
ファイル: rgamma_series.c プロジェクト: certik/arb
void
_fmprb_poly_rgamma_series(fmprb_ptr res, fmprb_srcptr h, long hlen, long len, long prec)
{
    int reflect;
    long i, rflen, r, n, wp;
    fmprb_ptr t, u, v;
    fmprb_struct f[2];

    hlen = FLINT_MIN(hlen, len);
    wp = prec + FLINT_BIT_COUNT(prec);

    t = _fmprb_vec_init(len);
    u = _fmprb_vec_init(len);
    v = _fmprb_vec_init(len);
    fmprb_init(f);
    fmprb_init(f + 1);

    /* use zeta values at small integers */
    if (fmprb_is_int(h) && (fmpr_cmpabs_ui(fmprb_midref(h), prec / 2) < 0))
    {
        r = fmpr_get_si(fmprb_midref(h), FMPR_RND_DOWN);

        gamma_lgamma_series_at_one(u, len, wp);

        _fmprb_vec_neg(u, u, len);
        _fmprb_poly_exp_series(t, u, len, len, wp);

        if (r == 1)
        {
            _fmprb_vec_swap(v, t, len);
        }
        else if (r <= 0)
        {
            fmprb_set(f, h);
            fmprb_one(f + 1);
            rflen = FLINT_MIN(len, 2 - r);
            _fmprb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), 1 - r, rflen, wp);
            _fmprb_poly_mullow(v, t, len, u, rflen, len, wp);
        }
        else
        {
            fmprb_one(f);
            fmprb_one(f + 1);
            rflen = FLINT_MIN(len, r);
            _fmprb_poly_rising_ui_series(v, f, FLINT_MIN(2, len), r - 1, rflen, wp);

            /* TODO: use div_series? */
            _fmprb_poly_inv_series(u, v, rflen, len, wp);
            _fmprb_poly_mullow(v, t, len, u, len, len, wp);
        }
    }
    else
    {
        /* otherwise use Stirling series */
        gamma_stirling_choose_param_fmprb(&reflect, &r, &n, h, 1, 0, wp);

        /* rgamma(h) = (gamma(1-h+r) sin(pi h)) / (rf(1-h, r) * pi), h = h0 + t*/
        if (reflect)
        {
            /* u = gamma(r+1-h) */
            fmprb_sub_ui(f, h, r + 1, wp);
            fmprb_neg(f, f);
            gamma_stirling_eval_fmprb_series(t, f, n, len, wp);
            _fmprb_poly_exp_series(u, t, len, len, wp);
            for (i = 1; i < len; i += 2)
                fmprb_neg(u + i, u + i);

            /* v = sin(pi x) */
            fmprb_const_pi(f + 1, wp);
            fmprb_mul(f, h, f + 1, wp);
            _fmprb_poly_sin_series(v, f, 2, len, wp);

            _fmprb_poly_mullow(t, u, len, v, len, len, wp);

            /* rf(1-h,r) * pi */
            if (r == 0)
            {
                fmprb_const_pi(u, wp);
                _fmprb_vec_scalar_div(v, t, len, u, wp);
            }
            else
            {
                fmprb_sub_ui(f, h, 1, wp);
                fmprb_neg(f, f);
                fmprb_set_si(f + 1, -1);
                rflen = FLINT_MIN(len, r + 1);
                _fmprb_poly_rising_ui_series(v, f, FLINT_MIN(2, len), r, rflen, wp);
                fmprb_const_pi(u, wp);
                _fmprb_vec_scalar_mul(v, v, rflen, u, wp);

                /* divide by rising factorial */
                /* TODO: might better to use div_series, when it has a good basecase */
                _fmprb_poly_inv_series(u, v, rflen, len, wp);
                _fmprb_poly_mullow(v, t, len, u, len, len, wp);
            }
        }
        else
        {
            /* rgamma(h) = rgamma(h+r) rf(h,r) */
            if (r == 0)
            {
                fmprb_add_ui(f, h, r, wp);
                gamma_stirling_eval_fmprb_series(t, f, n, len, wp);
                _fmprb_vec_neg(t, t, len);
                _fmprb_poly_exp_series(v, t, len, len, wp);
            }
            else
            {
                fmprb_set(f, h);
                fmprb_one(f + 1);
                rflen = FLINT_MIN(len, r + 1);
                _fmprb_poly_rising_ui_series(t, f, FLINT_MIN(2, len), r, rflen, wp);

                fmprb_add_ui(f, h, r, wp);
                gamma_stirling_eval_fmprb_series(v, f, n, len, wp);
                _fmprb_vec_neg(v, v, len);
                _fmprb_poly_exp_series(u, v, len, len, wp);

                _fmprb_poly_mullow(v, u, len, t, rflen, len, wp);
            }
        }
    }

    /* compose with nonconstant part */
    fmprb_zero(t);
    _fmprb_vec_set(t + 1, h + 1, hlen - 1);
    _fmprb_poly_compose_series(res, v, len, t, hlen, len, prec);

    fmprb_clear(f);
    fmprb_clear(f + 1);
    _fmprb_vec_clear(t, len);
    _fmprb_vec_clear(u, len);
    _fmprb_vec_clear(v, len);
}