Ejemplo n.º 1
0
Archivo: sum.c Proyecto: bluescarni/arb
int _arf_are_close(const arf_t x, const arf_t y, long prec)
{
    fmpz_t xb, yb;
    fmpz_t delta;
    int result;

    fmpz_init(xb);
    fmpz_init(yb);
    fmpz_init(delta);

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

    if (fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y)) >= 0)
        fmpz_sub(delta, xb, ARF_EXPREF(y));
    else
        fmpz_sub(delta, yb, ARF_EXPREF(x));

    fmpz_sub_ui(delta, delta, 64);
    result = (fmpz_cmp_ui(delta, prec) < 0);

    fmpz_clear(xb);
    fmpz_clear(yb);
    fmpz_clear(delta);

    return result;
}
Ejemplo n.º 2
0
void 
test_1(fmpz_t n)
 {
  mpfr_t q0; mpfr_init(q0); 
  mpfr_t q1; mpfr_init(q1);
  fmpz_t m; fmpz_init(m);
  int c;
  
  fmpz_get_mpfr(     q0, n   , MPFR_RNDA );
  fmpz_get_mpfr_3arg(q1, n[0], MPFR_RNDA );
  assert( mpfr_equal_p( q0, q1 ) );
  fmpz_set_mpfr(m, q0, MPFR_RNDA);
  if( fmpz_cmp_ui( n, WORD(0) ) >= 0 )
   {
    if( fmpz_cmp(n,m) > 0 )
     {
      flint_printf("RNDA test failed, n="); fmpz_print(n);
      flint_printf(", m="); fmpz_print(m); flint_printf("\n");
      assert(0);
     }
    fmpz_sub(m, m, n);
    IF_MORE_THAN_2;
   }
  else 
   {
    if( fmpz_cmp(n,m) < 0 )
     {
      flint_printf("RNDA test failed, n="); fmpz_print(n);
      flint_printf(", m="); fmpz_print(m); flint_printf("\n");
      assert(0);
     }
    fmpz_sub(m, n, m);
    IF_MORE_THAN_2;
   }
   
  fmpz_get_mpfr( q0, n, MPFR_RNDZ );
  fmpz_set_mpfr( m, q0, MPFR_RNDZ );
  c=fmpz_cmp_si( n, WORD(0) );
  if(c==0)
   assert(0 == fmpz_cmp_si(m,WORD(0)));
  else
   {
    if(c<0)
     {
      fmpz_neg(n, n);
      fmpz_neg(m, m);
     }
    assert( fmpz_cmp(n,m) >= 0 );
    if(c)
     assert( fmpz_cmp_si(m,WORD(0)) >= 0 );
    fmpz_sub(m, n, m);
    IF_MORE_THAN_2_AGAIN;
   }
  
  fmpz_clear(m);
  mpfr_clear(q1);
  mpfr_clear(q0);
 }
Ejemplo n.º 3
0
void
elem_sub(elem_ptr res, elem_srcptr op1, elem_srcptr op2, const ring_t ring)
{
    switch (ring->type)
    {
        case TYPE_FMPZ:
            fmpz_sub(res, op1, op2);
            break;

        case TYPE_LIMB:
            *((mp_ptr) res) = *((mp_srcptr) op1) - *((mp_srcptr) op2);
            break;

        case TYPE_POLY:
            elem_poly_sub(res, op1, op2, ring);
            break;

        case TYPE_MOD:
            {
                switch (RING_PARENT(ring)->type)
                {
                    case TYPE_LIMB:
                        *((mp_ptr) res) = n_submod(*((mp_srcptr) op1), *((mp_srcptr) op2), ring->nmod.n);
                        break;

                    case TYPE_FMPZ:
                        fmpz_sub(res, op1, op2);
                        if (fmpz_sgn(res) < 0)
                            fmpz_add(res, res, RING_MODULUS(ring));
                        break;

                    default:
                        NOT_IMPLEMENTED("sub (mod)", ring);
                }
            }
            break;

        case TYPE_FRAC:
            elem_frac_sub(res, op1, op2, ring);
            break;

        case TYPE_COMPLEX:
            elem_sub(REALPART(res, ring), REALPART(op1, ring), REALPART(op2, ring), ring->parent);
            elem_sub(IMAGPART(res, ring), IMAGPART(op1, ring), IMAGPART(op2, ring), ring->parent);
            break;

        default:
            NOT_IMPLEMENTED("sub", ring);
    }
}
Ejemplo n.º 4
0
Archivo: fmpz.c Proyecto: hperl/flint
void __fmpz_multi_CRT_sign(fmpz_t output, fmpz_t input, fmpz_comb_t comb)
{
   unsigned long n = comb->n;
   if (n == 0L) 
   {
      if (input[0] == 0L) 
	   {
	      fmpz_set_ui(output, 0L);
	      return;
	   }

	   unsigned long p = comb->primes[0];
	   if ((p - input[1]) < input[1]) fmpz_set_si(output, (long) (input[1] - p));
	   else fmpz_set_ui(output, input[1]);
	   return;
   }

   fmpz_t temp = fmpz_init(fmpz_size(comb->comb[n-1][0]) + 1);
   
   fmpz_sub(temp, input, comb->comb[comb->n - 1][0]);

   if (fmpz_cmpabs(temp, input) <= 0L) fmpz_set(output, temp);
   else fmpz_set(output, input);

   fmpz_clear(temp);
   return;
}
Ejemplo n.º 5
0
void
fmpr_divappr_abs_ubound(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec)
{
    if (fmpr_is_special(x) || fmpr_is_special(y) || fmpz_is_pm1(fmpr_manref(y)))
    {
        fmpr_div(z, x, y, prec, FMPR_RND_UP);
        fmpr_abs(z, z);
    }
    else
    {
        fmpz_t t, u;
        slong xbits, ybits, tbits, ubits, shift;

        xbits = fmpz_bits(fmpr_manref(x));
        ybits = fmpz_bits(fmpr_manref(y));

        fmpz_init(t);
        fmpz_init(u);

        ubits = FLINT_MIN(ybits, prec);
        tbits = prec + ubits + 1;

        /* upper bound for |x|, shifted */
        if (xbits <= tbits)
        {
            fmpz_mul_2exp(t, fmpr_manref(x), tbits - xbits);
            fmpz_abs(t, t);
        }
        else if (fmpz_sgn(fmpr_manref(x)) > 0)
        {
            fmpz_cdiv_q_2exp(t, fmpr_manref(x), xbits - tbits);
        }
        else
        {
            fmpz_fdiv_q_2exp(t, fmpr_manref(x), xbits - tbits);
            fmpz_neg(t, t);
        }

        /* lower bound for |y|, shifted */
        if (ybits <= ubits)
            fmpz_mul_2exp(u, fmpr_manref(y), ubits - ybits);
        else
            fmpz_tdiv_q_2exp(u, fmpr_manref(y), ybits - ubits);
        fmpz_abs(u, u);

        fmpz_cdiv_q(fmpr_manref(z), t, u);

        shift = (ubits - ybits) - (tbits - xbits);
        fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y));
        if (shift >= 0)
            fmpz_add_ui(fmpr_expref(z), fmpr_expref(z), shift);
        else
            fmpz_sub_ui(fmpr_expref(z), fmpr_expref(z), -shift);

        _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, FMPR_RND_UP);

        fmpz_clear(t);
        fmpz_clear(u);
    }
}
Ejemplo n.º 6
0
void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, 
                                  const fmpz_t a, const fmpz_t p)
{
    if (len == 0)
    {
        fmpz_zero(res);
    }
    else if (len == 1 || fmpz_is_zero(a))
    {
        fmpz_set(res, poly);
    }
    else
    {
        slong i = len - 1;
        fmpz_t t;

        fmpz_init(t);
        fmpz_set(res, poly + i);
        for (i = len - 2; i >= 0; i--)
        {
            fmpz_mul(t, res, a);
            fmpz_mod(t, t, p);
            fmpz_add(res, poly + i, t);
        }
        fmpz_clear(t);

        if (fmpz_cmpabs(res, p) >= 0)
            fmpz_sub(res, res, p);
    }
}
Ejemplo n.º 7
0
void
fmpz_mat_solve_fflu_precomp(fmpz_mat_t X,
                    const long * perm,
                    const fmpz_mat_t FFLU, const fmpz_mat_t B)
{
    fmpz_t T;
    long i, j, k, m, n;

    n = X->r;
    m = X->c;

    fmpz_init(T);
    fmpz_mat_set_perm(X, perm, B);

    for (k = 0; k < m; k++)
    {
        /* Fraction-free forward substitution */
        for (i = 0; i < n - 1; i++)
        {
            for (j = i + 1; j < n; j++)
            {
                fmpz_mul(XX(j, k), XX(j, k), LU(i, i));
                fmpz_mul(T, LU(j, i), XX(i, k));
                fmpz_sub(XX(j, k), XX(j, k), T);
                if (i > 0)
                    fmpz_divexact(XX(j, k), XX(j, k), LU(i-1, i-1));
            }
        }

        /* Fraction-free back substitution */
        for (i = n - 2; i >= 0; i--)
        {
            fmpz_mul(XX(i, k), XX(i, k), LU(n-1, n-1));
            for (j = i + 1; j < n; j++)
            {
                fmpz_mul(T, XX(j, k), LU(i, j));
                fmpz_sub(XX(i, k), XX(i, k), T);
            }
            fmpz_divexact(XX(i, k), XX(i, k), LU(i, i));
        }
    }

    fmpz_clear(T);
}
Ejemplo n.º 8
0
void
_fmpz_vec_scalar_addmul_si_2exp(fmpz * vec1, const fmpz * vec2, slong len2,
                                slong c, ulong exp)
{
    slong i;
    fmpz_t temp;

    if (c == 0)
        return;                 /* nothing to add */

    if (exp == 0)               /* just do addmul */
    {
        _fmpz_vec_scalar_addmul_si(vec1, vec2, len2, c);
        return;
    }

    fmpz_init(temp);

    if (c == 1)                 /* scalar is 1, just add c * 2^exp times c */
    {
        for (i = 0; i < len2; i++)
        {
            fmpz_mul_2exp(temp, vec2 + i, exp);
            fmpz_add(vec1 + i, vec1 + i, temp);
        }
    }
    else if (c == -1)           /* scalar is -1, subtract c * 2^exp */
    {
        for (i = 0; i < len2; i++)
        {
            fmpz_mul_2exp(temp, vec2 + i, exp);
            fmpz_sub(vec1 + i, vec1 + i, temp);
        }
    }
    else                        /* generic case */
    {
        if (c > 0)
        {
            for (i = 0; i < len2; i++)
            {
                fmpz_mul_2exp(temp, vec2 + i, exp);
                fmpz_addmul_ui(vec1 + i, temp, c);
            }
        }
        else
        {
            for (i = 0; i < len2; i++)
            {
                fmpz_mul_2exp(temp, vec2 + i, exp);
                fmpz_submul_ui(vec1 + i, temp, -c);
            }
        }
    }

    fmpz_clear(temp);
}
Ejemplo n.º 9
0
void
_fmprb_get_rand_fmpq(fmpz_t num, fmpz_t den, flint_rand_t state,
    const fmpz_t den_mult, const fmprb_t x)
{
    fmpz_t a, b, exp;

    fmpz_init(a);
    fmpz_init(b);
    fmpz_init(exp);

    fmprb_get_interval_fmpz_2exp(a, b, exp, x);

    if (COEFF_IS_MPZ(*exp))
    {
        printf("exception: fmprb_get_rand_fmpq: too large exponent\n");
        abort();
    }

    if (*exp >= 0)
    {
        fmpz_mul_2exp(a, a, *exp);
        fmpz_mul_2exp(b, b, *exp);
    }

    /* generate random integer in [a*den, b*den] */
    fmpz_mul(a, a, den_mult);
    fmpz_mul(b, b, den_mult);
    fmpz_add_ui(b, b, 1UL);
    fmpz_sub(b, b, a);

    /* return one endpoint with high probability (used for stress
       testing rounding) */
    if (n_randint(state, 6) == 0)
    {
        if (n_randint(state, 2))
            fmpz_zero(num);
        else
            fmpz_sub_ui(num, b, 1UL);
    }
    else
    {
        fmpz_randtest_mod(num, state, b);
    }

    fmpz_add(num, num, a);

    fmpz_set(den, den_mult);

    if (*exp < 0)
        fmpz_mul_2exp(den, den, -(*exp));

    fmpz_clear(a);
    fmpz_clear(b);
    fmpz_clear(exp);
}
Ejemplo n.º 10
0
void qsieve_ll_compute_C(qs_t qs_inf)
{
   mp_limb_t A = qs_inf->A;
   mp_limb_t B = qs_inf->B;
   
   if ((mp_limb_signed_t) B < 0L) B = -B;
   fmpz_set_ui(qs_inf->C, B);
   fmpz_mul_ui(qs_inf->C, qs_inf->C, B);
   fmpz_sub(qs_inf->C, qs_inf->C, qs_inf->kn);
   fmpz_divexact_ui(qs_inf->C, qs_inf->C, A);
} 
Ejemplo n.º 11
0
void 
_padic_log_balanced(fmpz_t z, const fmpz_t y, long v, const fmpz_t p, long N)
{
    fmpz_t pv, pN, r, t, u;
    long val;
    padic_inv_t S;

    fmpz_init(pv);
    fmpz_init(pN);
    fmpz_init(r);
    fmpz_init(t);
    fmpz_init(u);
    _padic_inv_precompute(S, p, N);

    fmpz_set(t, y);
    fmpz_set(pv, p);
    fmpz_pow_ui(pN, p, N);
    fmpz_zero(z);
    val = 1;

    /*
        TODO:  Abort earlier if larger than $p^N$, possible
        with variable precision?
     */
    while (!fmpz_is_zero(t))
    {
        fmpz_mul(pv, pv, pv);
        fmpz_fdiv_qr(t, r, t, pv);

        if (!fmpz_is_zero(t))
        {
            fmpz_mul(t, t, pv);
            fmpz_add_ui(u, r, 1);
            _padic_inv_precomp(u, u, S);
            fmpz_mul(t, t, u);
            fmpz_mod(t, t, pN);
        }

        if (!fmpz_is_zero(r))
        {
            fmpz_neg(r, r);
            _padic_log_bsplit(r, r, val, p, N);
            fmpz_sub(z, z, r);
        }
        val *= 2;
    }

    fmpz_clear(pv);
    fmpz_clear(pN);
    fmpz_clear(r);
    fmpz_clear(t);
    fmpz_clear(u);
    _padic_inv_clear(S);
}
Ejemplo n.º 12
0
void _qadic_exp_balanced(fmpz *rop, const fmpz *x, slong v, slong len, 
                         const fmpz *a, const slong *j, slong lena, 
                         const fmpz_t p, slong N, const fmpz_t pN)
{
    const slong d = j[lena - 1];

    fmpz_t pw;
    fmpz *r, *s, *t;
    slong i, w;

    r = _fmpz_vec_init(d);
    s = _fmpz_vec_init(2*d - 1);
    t = _fmpz_vec_init(d);
    fmpz_init(pw);

    fmpz_pow_ui(pw, p, v);
    _fmpz_vec_scalar_mul_fmpz(t, x, len, pw);
    _fmpz_vec_scalar_mod_fmpz(t, t, len, pN);
    _fmpz_vec_zero(t + len, d - len);

    fmpz_set(pw, p);
    fmpz_one(rop + 0);
    _fmpz_vec_zero(rop + 1, d - 1);
    w = 1;

    while (!_fmpz_vec_is_zero(t, d))
    {
        fmpz_mul(pw, pw, pw);

        for (i = 0; i < d; i++)
        {
            fmpz_fdiv_r(r + i, t + i, pw);
            fmpz_sub(t + i, t + i, r + i);
        }

        if (!_fmpz_vec_is_zero(r, d))
        {
            _qadic_exp_bsplit(r, r, w, d, a, j, lena, p, N);
            _fmpz_poly_mul(s, rop, d, r, d);
            _fmpz_poly_reduce(s, 2*d - 1, a, j, lena);
            _fmpz_vec_scalar_mod_fmpz(rop, s, d, pN);
        }

        w *= 2;
    }

    _fmpz_vec_clear(r, d);
    _fmpz_vec_clear(s, 2*d - 1);
    _fmpz_vec_clear(t, d);
    fmpz_clear(pw);
}
Ejemplo n.º 13
0
void
_arb_poly_get_scale(fmpz_t scale, arb_srcptr x, slong xlen,
                    arb_srcptr y, slong ylen)
{
    slong xa, xb, ya, yb, den;

    fmpz_zero(scale);

    /* ignore zeros (and infs/nans!); find the first and last
       finite nonzero entries to determine the scale */
    xa = 0;
    xb = xlen - 1;
    while (xa < xlen && arf_is_special(arb_midref(x + xa))) xa++;
    while (xb > xa && arf_is_special(arb_midref(x + xb))) xb--;

    ya = 0;
    yb = ylen - 1;
    while (ya < ylen && arf_is_special(arb_midref(y + ya))) ya++;
    while (yb > ya && arf_is_special(arb_midref(y + yb))) yb--;

    /* compute average of exponent differences, weighted by the lengths */
    if (xa <= xb && ya <= yb && (xa < xb || ya < yb))
    {
        fmpz_add(scale, scale, ARF_EXPREF(arb_midref(x + xb)));
        fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(x + xa)));
        fmpz_add(scale, scale, ARF_EXPREF(arb_midref(y + yb)));
        fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(y + ya)));

        den = (xb - xa) + (yb - ya);

        /* scale = floor(scale / den + 1/2) = floor((2 scale + den) / (2 den)) */
        fmpz_mul_2exp(scale, scale, 1);
        fmpz_add_ui(scale, scale, den);
        fmpz_fdiv_q_ui(scale, scale, 2 * den);
    }
}
Ejemplo n.º 14
0
void
_fmpz_poly_sub(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2,
               slong len2)
{
    slong i, min = FLINT_MIN(len1, len2);

    for (i = 0; i < min; i++)   /* subtract up to the length of the shorter poly */
        fmpz_sub(res + i, poly1 + i, poly2 + i);

    if (poly1 != res)           /* copy any remaining coefficients from poly1 */
        for (i = min; i < len1; i++)
            fmpz_set(res + i, poly1 + i);

    /* careful, it is *always* necessary to negate coeffs from poly2, even if this is already res */
    for (i = min; i < len2; i++)
        fmpz_neg(res + i, poly2 + i);
}
Ejemplo n.º 15
0
void arith_stirling_number_1_vec_next(fmpz * row,
    const fmpz * prev, slong n, slong klen)
{
    slong k;

    if (klen > n) fmpz_one(row + n);
    if (n != 0 && klen != 0) fmpz_zero(row);

    for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--)
    {
        fmpz_mul_ui(row + k, prev + k, n - UWORD(1));
        fmpz_sub(row + k, prev + k - 1, row + k);
    }

    for (k = n + 1; k < klen; k++)
        fmpz_zero(row + k);
}
Ejemplo n.º 16
0
slong
_fmpz_sub_small_large(const fmpz_t x, const fmpz_t y)
{
    fmpz_t t;
    fmpz_init(t);
    fmpz_sub(t, x, y);
    if (!COEFF_IS_MPZ(*t))
    {
        /* no need to free t */
        return *t;
    }
    else
    {
        int sign = fmpz_sgn(t);
        fmpz_clear(t);
        return (sign > 0) ? WORD_MAX : -WORD_MAX;
    }
}
Ejemplo n.º 17
0
void
fmpz_randtest_mod(fmpz_t f, flint_rand_t state, const fmpz_t m)
{
    fmpz_t t;

    fmpz_init(t);
    fmpz_randtest_unsigned(t, state, fmpz_bits(m) + 2);
    fmpz_mod(t, t, m);

    if (n_randlimb(state) & UWORD(1))
    {
        fmpz_sub(t, m, t);
        fmpz_sub_ui(t, t, UWORD(1));
    }

    fmpz_set(f, t);
    fmpz_clear(t);
}
Ejemplo n.º 18
0
void
mag_root(mag_t y, const mag_t x, ulong n)
{
    if (n == 0)
    {
        mag_inf(y);
    }
    else if (n == 1 || mag_is_special(x))
    {
        mag_set(y, x);
    }
    else if (n == 2)
    {
        mag_sqrt(y, x);
    }
    else if (n == 4)
    {
        mag_sqrt(y, x);
        mag_sqrt(y, y);
    }
    else
    {
        fmpz_t e, f;

        fmpz_init_set_ui(e, MAG_BITS);
        fmpz_init(f);

        /* We evaluate exp(log(1+2^(kn)x)/n) 2^-k where k is chosen
           so that 2^(kn) x ~= 2^30. TODO: this rewriting is probably
           unnecessary with the new exp/log functions. */
        fmpz_sub(e, e, MAG_EXPREF(x));
        fmpz_cdiv_q_ui(e, e, n);
        fmpz_mul_ui(f, e, n);
        mag_mul_2exp_fmpz(y, x, f);
        mag_log1p(y, y);
        mag_div_ui(y, y, n);
        mag_exp(y, y);
        fmpz_neg(e, e);
        mag_mul_2exp_fmpz(y, y, e);

        fmpz_clear(e);
        fmpz_clear(f);
    }
}
Ejemplo n.º 19
0
void _fmpz_vec_scalar_smod_fmpz(fmpz *res, const fmpz *vec, slong len, const fmpz_t p)
{
    slong i;
    fmpz_t pdiv2;

    fmpz_init(pdiv2);
    fmpz_fdiv_q_2exp(pdiv2, p, 1);

    for (i = 0; i < len; i++)
    {
        fmpz_mod(res + i, vec + i, p);

        if (fmpz_cmp(res + i, pdiv2) > 0)
        {
            fmpz_sub(res + i, res + i, p);
        }
    }

    fmpz_clear(pdiv2);
}
Ejemplo n.º 20
0
static void alpha(fmpz_t rop, const long *u, const long *v, 
    const fmpz *a, const fmpz *dinv, const fmpz **mu, long M, const long **C, const long *lenC, 
    long n, long d, long p, long N)
{
    const long ku = diagfrob_k(u, n, d);

    long i;
    fmpz_t f, g, P, PN;

    fmpz_init(f);
    fmpz_init(g);
    fmpz_init_set_ui(P, p);
    fmpz_init(PN);
    fmpz_pow_ui(PN, P, N);

    fmpz_pow_ui(rop, P, ku);
    fmpz_mod(rop, rop, PN);

    for (i = 0; i <= n; i++)
    {
        long e = (p * (u[i] + 1) - (v[i] + 1)) / d;

        fmpz_powm_ui(f, a + i, e, PN);
        dsum(g, dinv, mu[i], M, C[i], lenC[i], a + i, u[i], v[i], n, d, p, N);
        fmpz_mul(rop, rop, f);
        fmpz_mul(rop, rop, g);
        fmpz_mod(rop, rop, PN);
    }

    if (ku % 2 != 0 && !fmpz_is_zero(rop))
    {
        fmpz_sub(rop, PN, rop);
    }

    fmpz_clear(f);
    fmpz_clear(g);
    fmpz_clear(P);
    fmpz_clear(PN);
}
Ejemplo n.º 21
0
void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, long len1, 
                                              const fmpz *poly2, long len2, 
                                              const fmpz_t p)
{
    if (len1 == 1 || len2 == 0)
    {
        fmpz_set(res, poly1);
    }
    else
    {
        const long alloc = (len1 - 1) * (len2 - 1) + 1;
        long i = len1 - 1, lenr = len2;
        fmpz * t = _fmpz_vec_init(alloc);
        
        /*
           Perform the first two steps as one, 
             "res = a(m) * poly2 + a(m-1)".
         */
        {
            _fmpz_mod_poly_scalar_mul_fmpz(res, poly2, len2, poly1 + i, p);
            i--;
            fmpz_add(res, res, poly1 + i);
            if (fmpz_cmpabs(res, p) >= 0)
                fmpz_sub(res, res, p);
        }
        while (i > 0)
        {
            i--;
            _fmpz_mod_poly_mul(t, res, lenr, poly2, len2, p);
            lenr += len2 - 1;
            _fmpz_mod_poly_add(res, t, lenr, poly1 + i, 1, p);
        }

        _fmpz_vec_clear(t, alloc);
    }
}
Ejemplo n.º 22
0
void
_qseive(const mp_limb_t n, const mp_limb_t B)
{
    nmod_sparse_mat_t M;
    mp_limb_t quad, *quads, *xs, x, i = 0, j, piB = n_prime_pi(B);
    const mp_limb_t * ps = n_primes_arr_readonly(piB + 2);
    const double * pinvs = n_prime_inverses_arr_readonly(piB + 2);
    mzd_t *K;

    /* init */
    quads = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *));
    xs = (mp_limb_t *)malloc((piB + 1)*sizeof(mp_limb_t *));
    K = mzd_init(piB + 1, 1);
    nmod_sparse_mat_init(M, piB + 1, piB + 1, 2);

    printf("init done\n");
    printf("using %ld primes\n", piB);
    /* seive */

    for (x = n_sqrt(n), i = 0; i <= piB; x++)
    {
        quad = x*x - n;
        if (quad == 0)
            continue;
        for (j = 0; j < piB; j++)
            n_remove2_precomp(&quad, ps[j], pinvs[j]);
        if (quad == 1) /* was B-smooth */
        {
            quads[i] = x*x - n;
            quad = x*x - n;
            for (j = 0; j < piB; j++)
            {
                if (n_remove2_precomp(&quad, ps[j], pinvs[j]) % 2)
                    _nmod_sparse_mat_set_entry(M, j, i, M->row_supports[j], 1);
            }
            xs[i] = x;
            i++;
        }
    }
    printf("data collection done\n");

    n_cleanup_primes();

    _bw(K, M, 1, 2, 7, 7);

    printf("procesing complete\n");
    mzd_print(K);

    int done = 0;
    for (j = 0; !done; j++)
    {
        fmpz_t a, b, diff, N;
        fmpz_init_set_ui(a, 1);
        fmpz_init_set_ui(b, 1);
        fmpz_init_set_ui(N, n);
        fmpz_init(diff);
        for (i = 0; i < piB; i++)
        {
            if (mzd_read_bit(K, i, j))
            {
                fmpz_mul_ui(a, a, xs[i]);
                fmpz_mul_ui(b, b, quads[i]);
            }
        }
        assert(fmpz_is_square(b));
        fmpz_sqrt(b, b);
        if (fmpz_mod_ui(a, a, n) != fmpz_mod_ui(b, b, n) && fmpz_mod_ui(a, a, n) != n - fmpz_mod_ui(b, b, n))
        {
            done = 1;

            fmpz_print(a);
            printf("\n");
            fmpz_print(b);
            printf("\n");
            fmpz_sub(diff, a, b);
            fmpz_gcd(a, diff, N);
            fmpz_divexact(b, N, a);
            fmpz_print(a);
            printf("\n");
            fmpz_print(b);
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(N);
        fmpz_clear(diff);
    }
    /* cleanup */
    free(quads);
    free(xs);

    mzd_free(K);

    nmod_sparse_mat_clear(M);

    return;
}
Ejemplo n.º 23
0
static __inline__ void
_mag_vec_get_fmpz_2exp_blocks(fmpz * coeffs,
                              double * dblcoeffs, fmpz * exps, slong * blocks, const fmpz_t scale,
                              arb_srcptr x, mag_srcptr xm, slong len)
{
    fmpz_t top, bot, t, b, v, block_top, block_bot;
    slong i, j, s, block, bits, maxheight;
    int in_zero;
    mag_srcptr cur;

    fmpz_init(top);
    fmpz_init(bot);
    fmpz_init(t);
    fmpz_init(b);
    fmpz_init(v);
    fmpz_init(block_top);
    fmpz_init(block_bot);

    blocks[0] = 0;
    block = 0;
    in_zero = 1;

    maxheight = ALPHA * MAG_BITS + BETA;
    if (maxheight > DOUBLE_BLOCK_MAX_HEIGHT)
        abort();

    for (i = 0; i < len; i++)
    {
        cur = (x == NULL) ? (xm + i) : arb_radref(x + i);

        /* Skip (must be zero, since we assume there are no Infs/NaNs). */
        if (mag_is_special(cur))
            continue;

        /* Bottom and top exponent of current number */
        bits = MAG_BITS;
        fmpz_set(top, MAG_EXPREF(cur));
        fmpz_submul_ui(top, scale, i);
        fmpz_sub_ui(bot, top, bits);

        /* Extend current block. */
        if (in_zero)
        {
            fmpz_swap(block_top, top);
            fmpz_swap(block_bot, bot);
        }
        else
        {
            fmpz_max(t, top, block_top);
            fmpz_min(b, bot, block_bot);
            fmpz_sub(v, t, b);

            /* extend current block */
            if (fmpz_cmp_ui(v, maxheight) < 0)
            {
                fmpz_swap(block_top, t);
                fmpz_swap(block_bot, b);
            }
            else  /* start new block */
            {
                /* write exponent for previous block */
                fmpz_set(exps + block, block_bot);

                block++;
                blocks[block] = i;

                fmpz_swap(block_top, top);
                fmpz_swap(block_bot, bot);
            }
        }

        in_zero = 0;
    }

    /* write exponent for last block */
    fmpz_set(exps + block, block_bot);

    /* end marker */
    blocks[block + 1] = len;

    /* write the block data */
    for (i = 0; blocks[i] != len; i++)
    {
        for (j = blocks[i]; j < blocks[i + 1]; j++)
        {
            cur = (x == NULL) ? (xm + j) : arb_radref(x + j);

            if (mag_is_special(cur))
            {
                fmpz_zero(coeffs + j);
                dblcoeffs[j] = 0.0;
            }
            else
            {
                mp_limb_t man;
                double c;

                man = MAG_MAN(cur);

                /* TODO: only write and use doubles when block is short? */

                /* Divide by 2^(scale * j) */
                fmpz_mul_ui(t, scale, j);
                fmpz_sub(t, MAG_EXPREF(cur), t);

                fmpz_sub_ui(t, t, MAG_BITS); /* bottom exponent */
                s = _fmpz_sub_small(t, exps + i);

                if (s < 0) abort(); /* Bug catcher */

                fmpz_set_ui(coeffs + j, man);
                fmpz_mul_2exp(coeffs + j, coeffs + j, s);
                c = man;
                c = ldexp(c, s - DOUBLE_BLOCK_SHIFT);
                if (c < 1e-150 || c > 1e150) /* Bug catcher */
                    abort();
                dblcoeffs[j] = c;
            }
        }
    }

    fmpz_clear(top);
    fmpz_clear(bot);
    fmpz_clear(t);
    fmpz_clear(b);
    fmpz_clear(v);
    fmpz_clear(block_top);
    fmpz_clear(block_bot);
}
Ejemplo n.º 24
0
void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N)
{
    if (fmpz_equal_ui(p, 2))
    {
        fmpz_one(rop);
    }
    else if (N == 1)
    {
        fmpz_mod(rop, op, p);
    }
    else
    {
        slong *a, i, n;
        fmpz *pow, *u;
        fmpz_t s, t;
        fmpz_t inv;
        fmpz_t pm1;

        a = _padic_lifts_exps(&n, N);

        pow = _fmpz_vec_init(2 * n);
        u   = pow + n;

        _padic_lifts_pows(pow, a, n, p);

        fmpz_init(s);
        fmpz_init(t);
        fmpz_init(inv);
        fmpz_init(pm1);

        fmpz_sub_ui(pm1, p, 1);

        /* Compute reduced units for (p-1) */
        {
            fmpz_mod(u + 0, pm1, pow + 0);
        }
        for (i = 1; i < n; i++)
        {
            fmpz_mod(u + i, u + (i - 1), pow + i);
        }

        /* Run Newton iteration */
        i = n - 1;
        {
            fmpz_mod(rop, op, pow + i);

            fmpz_set(inv, pm1);
        }
        for (i--; i >= 0; i--)
        {
            /* Lift rop */
            fmpz_powm(s, rop, p, pow + i);
            fmpz_sub(s, s, rop);
            fmpz_mul(t, s, inv);
            fmpz_sub(rop, rop, t);
            fmpz_mod(rop, rop, pow + i);

            /* Lift inv */
            if (i > 0)
            {
                fmpz_mul(s, inv, inv);
                fmpz_mul(t, u + i, s);
                fmpz_mul_2exp(inv, inv, 1);
                fmpz_sub(inv, inv, t);
                fmpz_mod(inv, inv, pow + i);
            }
        }

        fmpz_clear(s);
        fmpz_clear(t);
        fmpz_clear(inv);
        fmpz_clear(pm1);
        _fmpz_vec_clear(pow, 2 * n);
        flint_free(a);
    }
}
Ejemplo n.º 25
0
static __inline__ void
_arb_vec_get_fmpz_2exp_blocks(fmpz * coeffs, fmpz * exps,
                              slong * blocks, const fmpz_t scale, arb_srcptr x, slong len, slong prec)
{
    fmpz_t top, bot, t, b, v, block_top, block_bot;
    slong i, j, s, block, bits, maxheight;
    int in_zero;

    fmpz_init(top);
    fmpz_init(bot);
    fmpz_init(t);
    fmpz_init(b);
    fmpz_init(v);
    fmpz_init(block_top);
    fmpz_init(block_bot);

    blocks[0] = 0;
    block = 0;
    in_zero = 1;

    if (prec == ARF_PREC_EXACT)
        maxheight = ARF_PREC_EXACT;
    else
        maxheight = ALPHA * prec + BETA;

    for (i = 0; i < len; i++)
    {
        bits = arf_bits(arb_midref(x + i));

        /* Skip (must be zero, since we assume there are no Infs/NaNs). */
        if (bits == 0)
            continue;

        /* Bottom and top exponent of current number */
        fmpz_set(top, ARF_EXPREF(arb_midref(x + i)));
        fmpz_submul_ui(top, scale, i);
        fmpz_sub_ui(bot, top, bits);

        /* Extend current block. */
        if (in_zero)
        {
            fmpz_swap(block_top, top);
            fmpz_swap(block_bot, bot);
        }
        else
        {
            fmpz_max(t, top, block_top);
            fmpz_min(b, bot, block_bot);
            fmpz_sub(v, t, b);

            /* extend current block */
            if (fmpz_cmp_ui(v, maxheight) < 0)
            {
                fmpz_swap(block_top, t);
                fmpz_swap(block_bot, b);
            }
            else  /* start new block */
            {
                /* write exponent for previous block */
                fmpz_set(exps + block, block_bot);

                block++;
                blocks[block] = i;

                fmpz_swap(block_top, top);
                fmpz_swap(block_bot, bot);
            }
        }

        in_zero = 0;
    }

    /* write exponent for last block */
    fmpz_set(exps + block, block_bot);

    /* end marker */
    blocks[block + 1] = len;

    /* write the block data */
    for (i = 0; blocks[i] != len; i++)
    {
        for (j = blocks[i]; j < blocks[i + 1]; j++)
        {
            if (arf_is_special(arb_midref(x + j)))
            {
                fmpz_zero(coeffs + j);
            }
            else
            {
                /* TODO: make this a single operation */
                arf_get_fmpz_2exp(coeffs + j, bot, arb_midref(x + j));

                fmpz_mul_ui(t, scale, j);
                fmpz_sub(t, bot, t);
                s = _fmpz_sub_small(t, exps + i);
                if (s < 0) abort(); /* Bug catcher */
                fmpz_mul_2exp(coeffs + j, coeffs + j, s);
            }
        }
    }

    fmpz_clear(top);
    fmpz_clear(bot);
    fmpz_clear(t);
    fmpz_clear(b);
    fmpz_clear(v);
    fmpz_clear(block_top);
    fmpz_clear(block_bot);
}
Ejemplo n.º 26
0
Archivo: fmpz.c Proyecto: hperl/flint
void fmpz_multi_CRT_ui(fmpz_t output, unsigned long * residues, fmpz_comb_t comb, fmpz_t ** comb_temp)
{
   ulong i, j, k;

   ulong n = comb->n;
   ulong num;
   ulong log_res;
	mp_limb_t * ptr;
	ulong size;
   ulong num_primes = comb->num_primes;

   if (num_primes == 1) // the output is less than a single prime, so just output the result
   {
	   unsigned long p = comb->primes[0];
	   if ((p - residues[0]) < residues[0]) fmpz_set_si(output, (long) (residues[0] - p));
	   else fmpz_set_ui(output, residues[0]);
	   return;
	}

	// first layer of reconstruction
	num = (1L<<n);
   mp_limb_t temps[3];
   mp_limb_t temp2s[3];
   for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++)
   {
      fmpz_set_ui(temps, residues[i]);
      fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1]));
      fmpz_sub_ui_inplace(temp2s, residues[i + 1]);
      temp2s[0] = -temp2s[0];
      fmpz_mul(temps, temp2s, comb->res[0][j]);
      fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1]));
      fmpz_mul_ui(temps, temp2s, comb->primes[i]); 
      fmpz_add_ui(comb_temp[0][j], temps, residues[i]);
   }
   if (i < num_primes) fmpz_set_ui(comb_temp[0][j], residues[i]);
   
   // compute other layers of reconstruction
	fmpz_t temp = (fmpz_t) flint_heap_alloc(2*num + 1); 
   fmpz_t temp2 = (fmpz_t) flint_heap_alloc(2*num + 1); 
   num /= 2;
   log_res = 1;
   while (log_res < n)
   {
      for (i = 0, j = 0; i < num; i += 2, j++)
      {
         if (fmpz_is_one(comb->comb[log_res-1][i+1]))
		   {
		      if (!fmpz_is_one(comb->comb[log_res-1][i])) fmpz_set(comb_temp[log_res][j], comb_temp[log_res-1][i]);
		   } else
		   {
			   fmpz_mod(temp2, comb_temp[log_res-1][i], comb->comb[log_res-1][i+1]);
            fmpz_sub(temp, temp2, comb_temp[log_res-1][i+1]);
            temp[0] = -temp[0];
            fmpz_mul(temp2, temp, comb->res[log_res][j]);
            fmpz_mod(temp, temp2, comb->comb[log_res-1][i+1]);
            fmpz_mul(temp2, temp, comb->comb[log_res-1][i]);
            fmpz_add(comb_temp[log_res][j], temp2, comb_temp[log_res-1][i]);
		   }
      }     
      log_res++;
      num /= 2; 
   }

   // write out the output
	__fmpz_multi_CRT_sign(comb_temp[log_res - 1][0], comb_temp[log_res - 1][0], comb);
	fmpz_set(output, comb_temp[log_res - 1][0]);

   flint_heap_free(temp2); //temp2
   flint_heap_free(temp); //temp 
}
Ejemplo n.º 27
0
void
_arb_bell_sum_taylor(arb_t res, const fmpz_t n,
        const fmpz_t a, const fmpz_t b, const fmpz_t mmag, long tol)
{
    fmpz_t m, r, R, tmp;
    mag_t B, C, D, bound;
    arb_t t, u;
    long wp, k, N;

    if (_fmpz_sub_small(b, a) < 5)
    {
        arb_bell_sum_bsplit(res, n, a, b, mmag, tol);
        return;
    }

    fmpz_init(m);
    fmpz_init(r);
    fmpz_init(R);
    fmpz_init(tmp);

    /* r = max(m - a, b - m) */
    /* m = a + (b - a) / 2 */
    fmpz_sub(r, b, a);
    fmpz_cdiv_q_2exp(r, r, 1);
    fmpz_add(m, a, r);

    fmpz_mul_2exp(R, r, RADIUS_BITS);

    mag_init(B);
    mag_init(C);
    mag_init(D);
    mag_init(bound);

    arb_init(t);
    arb_init(u);

    if (fmpz_cmp(R, m) >= 0)
    {
        mag_inf(C);
        mag_inf(D);
    }
    else
    {
        /* C = exp(R * |F'(m)| + (1/2) R^2 * (n/(m-R)^2 + 1/(m-R))) */
        /* C = exp(R * (|F'(m)| + (1/2) R * (n/(m-R) + 1)/(m-R))) */
        /* D = (1/2) R * (n/(m-R) + 1)/(m-R) */
        fmpz_sub(tmp, m, R);
        mag_set_fmpz(D, n);
        mag_div_fmpz(D, D, tmp);
        mag_one(C);
        mag_add(D, D, C);
        mag_div_fmpz(D, D, tmp);
        mag_mul_fmpz(D, D, R);
        mag_mul_2exp_si(D, D, -1);

        /* C = |F'(m)| */
        wp = 20 + 1.05 * fmpz_bits(n);
        arb_set_fmpz(t, n);
        arb_div_fmpz(t, t, m, wp);
        fmpz_add_ui(tmp, m, 1);
        arb_set_fmpz(u, tmp);
        arb_digamma(u, u, wp);
        arb_sub(t, t, u, wp);
        arb_get_mag(C, t);

        /* C = exp(R * (C + D)) */
        mag_add(C, C, D);
        mag_mul_fmpz(C, C, R);
        mag_exp(C, C);
    }

    if (mag_cmp_2exp_si(C, tol / 4 + 2) > 0)
    {
        _arb_bell_sum_taylor(res, n, a, m, mmag, tol);
        _arb_bell_sum_taylor(t, n, m, b, mmag, tol);
        arb_add(res, res, t, 2 * tol);
    }
    else
    {
        arb_ptr mx, ser1, ser2, ser3;

        /* D = T(m) */
        wp = 20 + 1.05 * fmpz_bits(n);
        arb_set_fmpz(t, m);
        arb_pow_fmpz(t, t, n, wp);
        fmpz_add_ui(tmp, m, 1);
        arb_gamma_fmpz(u, tmp, wp);
        arb_div(t, t, u, wp);
        arb_get_mag(D, t);

        /* error bound: (b-a) * C * D * B^N / (1 - B), B = r/R */
        /*              ((b-a) * C * D * 2) * 2^(-N*RADIUS_BITS) */

        /* ((b-a) * C * D * 2) */
        mag_mul(bound, C, D);
        mag_mul_2exp_si(bound, bound, 1);
        fmpz_sub(tmp, b, a);
        mag_mul_fmpz(bound, bound, tmp);

        /* N = (tol + log2((b-a)*C*D*2) - mmag) / RADIUS_BITS */
        if (mmag == NULL)
        {
            /* estimate D ~= 2^mmag */
            fmpz_add_ui(tmp, MAG_EXPREF(C), tol);
            fmpz_cdiv_q_ui(tmp, tmp, RADIUS_BITS);
        }
        else
        {
            fmpz_sub(tmp, MAG_EXPREF(bound), mmag);
            fmpz_add_ui(tmp, tmp, tol);
            fmpz_cdiv_q_ui(tmp, tmp, RADIUS_BITS);
        }

        if (fmpz_cmp_ui(tmp, 5 * tol / 4) > 0)
            N = 5 * tol / 4;
        else if (fmpz_cmp_ui(tmp, 2) < 0)
            N = 2;
        else
            N = fmpz_get_ui(tmp);

        /* multiply by 2^(-N*RADIUS_BITS) */
        mag_mul_2exp_si(bound, bound, -N * RADIUS_BITS);

        mx = _arb_vec_init(2);
        ser1 = _arb_vec_init(N);
        ser2 = _arb_vec_init(N);
        ser3 = _arb_vec_init(N);

        /* estimate (this should work for moderate n and tol) */
        wp = 1.1 * tol + 1.05 * fmpz_bits(n) + 5;

        /* increase precision until convergence */
        while (1)
        {
            /* (m+x)^n / gamma(m+1+x) */
            arb_set_fmpz(mx, m);
            arb_one(mx + 1);
            _arb_poly_log_series(ser1, mx, 2, N, wp);
            for (k = 0; k < N; k++)
                arb_mul_fmpz(ser1 + k, ser1 + k, n, wp);
            arb_add_ui(mx, mx, 1, wp);
            _arb_poly_lgamma_series(ser2, mx, 2, N, wp);
            _arb_vec_sub(ser1, ser1, ser2, N, wp);
            _arb_poly_exp_series(ser3, ser1, N, N, wp);

            /* t = a - m, u = b - m */
            arb_set_fmpz(t, a);
            arb_sub_fmpz(t, t, m, wp);
            arb_set_fmpz(u, b);
            arb_sub_fmpz(u, u, m, wp);
            arb_power_sum_vec(ser1, t, u, N, wp);

            arb_zero(res);
            for (k = 0; k < N; k++)
                arb_addmul(res, ser3 + k, ser1 + k, wp);

            if (mmag != NULL)
            {
                if (_fmpz_sub_small(MAG_EXPREF(arb_radref(res)), mmag) <= -tol)
                    break;
            }
            else
            {
                if (arb_rel_accuracy_bits(res) >= tol)
                    break;
            }

            wp = 2 * wp;
        }

        /* add the series truncation bound */
        arb_add_error_mag(res, bound);

        _arb_vec_clear(mx, 2);
        _arb_vec_clear(ser1, N);
        _arb_vec_clear(ser2, N);
        _arb_vec_clear(ser3, N);
    }

    mag_clear(B);
    mag_clear(C);
    mag_clear(D);
    mag_clear(bound);
    arb_clear(t);
    arb_clear(u);

    fmpz_clear(m);
    fmpz_clear(r);
    fmpz_clear(R);
    fmpz_clear(tmp);
}
Ejemplo n.º 28
0
Archivo: fmpz.c Proyecto: hperl/flint
void fmpz_mod(fmpz_t res, const fmpz_t a, const fmpz_t b) 
{
   long a0 = a[0];
   long b0 = b[0];
   unsigned long sizea = FLINT_ABS(a0);
   unsigned long sizeb = b0;
   while ((!a[sizea]) && (sizea)) sizea--;
   while ((!b[sizeb]) && (sizeb)) sizeb--;
      

   mp_limb_t mslimb;
   fmpz_t temp, temp2;
      
   if (sizeb == 0)
   {
      printf("Error: division by zero!\n");
      abort();          
   } else if (sizea < sizeb) 
   {
      if ((long) a0 < 0L) 
      {
         temp = (fmpz_t) flint_stack_alloc(sizeb + 2);
         fmpz_add(temp, a, b);
         fmpz_set(res, temp);
         flint_stack_release();  
      } else fmpz_set(res, a);
      return;
   } else if ((sizea == sizeb) && (fmpz_cmpabs(a, b) < 0L))
   {
      if (fmpz_sgn(a) < 0) fmpz_add(res, a, b);
      else fmpz_set(res, a);
	  return;
   } else
   {
      if (fmpz_is_one(b)) 
	  {
	     fmpz_set_ui(res, 0L); 
		 return;
	  }
	  temp = (fmpz_t) flint_stack_alloc(sizea - sizeb + 1);
      temp2 = (fmpz_t) flint_stack_alloc(sizeb + 2);
      mpn_tdiv_qr(temp, temp2+1, 0, a+1, sizea, b+1, sizeb);
      temp2[0] = sizeb;
      NORM(temp2);
      if (a0 < 0L)
      {
         unsigned long i = 0; 
         for (; i < sizeb; i++)
         {
            if (temp2[i+1]) break;
         }
         if (i < sizeb)
         {
            fmpz_sub(temp2, b, temp2);
         } 
         fmpz_set(res, temp2);
      } else fmpz_set(res, temp2);
      flint_stack_release();  
      flint_stack_release();  
   }
}     
Ejemplo n.º 29
0
char * _padic_get_str(char * str, const padic_t op, const padic_ctx_t ctx)
{
    const fmpz * u = padic_unit(op);
    const long v   = padic_val(op);

    if (fmpz_is_zero(u))
    {
        if (!str)
        {
            str = flint_malloc(2);
        }
        str[0] = '0';
        str[1] = '\0';
        return str;
    }

    if (ctx->mode == PADIC_TERSE)
    {
        if (v == 0)
        {
            str = fmpz_get_str(str, 10, u);
        }
        else if (v > 0)
        {
            fmpz_t t;

            fmpz_init(t);
            fmpz_pow_ui(t, ctx->p, v);
            fmpz_mul(t, t, u);
            str = fmpz_get_str(str, 10, t);
            fmpz_clear(t);
        }
        else  /* v < 0 */
        {
            fmpz_t t;

            fmpz_init(t);
            fmpz_pow_ui(t, ctx->p, -v);
            str = _fmpq_get_str(str, 10, u, t);
            fmpz_clear(t);
        }
    }
    else if (ctx->mode == PADIC_SERIES)
    {
        char *s;
        fmpz_t x;
        fmpz_t d;
        long j, N;

        if (fmpz_sgn(u) < 0)
        {
            printf("ERROR (_padic_get_str).  u < 0 in SERIES mode.\n");
            abort();
        }

        N = fmpz_clog(u, ctx->p) + v;

        if (!str)
        {
            long b = (N - v) * (2 * fmpz_sizeinbase(ctx->p, 10) 
                     + z_sizeinbase(FLINT_MAX(FLINT_ABS(v), FLINT_ABS(N)), 10) 
                     + 5) + 1;

            str = flint_malloc(b);
            if (!str)
            {
                printf("ERROR (_padic_get_str).  Memory allocation failed.\n");
                abort();
            }
        }

        s = str;

        fmpz_init(d);
        fmpz_init(x);

        fmpz_set(x, u);

        /* Unroll first step */
        j = 0;
        {
            fmpz_mod(d, x, ctx->p);       /* d = u mod p^{j+1} */
            fmpz_sub(x, x, d);            /* x = x - d */
            fmpz_divexact(x, x, ctx->p);  /* x = x / p */

            if (!fmpz_is_zero(d))
            {
                if (j + v != 0)
                {
                    fmpz_get_str(s, 10, d);
                    while (*++s != '\0') ;
                    *s++ = '*';
                    fmpz_get_str(s, 10, ctx->p);
                    while (*++s != '\0') ;
                    *s++ = '^';
                    sprintf(s, "%ld", j + v);
                    while (*++s != '\0') ;
                }
                else
                {
                    fmpz_get_str(s, 10, d);
                    while (*++s != '\0') ;
                }
            }

            j++;
        }

        for ( ; !fmpz_is_zero(x); j++)
        {
            fmpz_mod(d, x, ctx->p);       /* d = u mod p^{j+1} */
            fmpz_sub(x, x, d);            /* x = x - d */
            fmpz_divexact(x, x, ctx->p);  /* x = x / p */

            if (!fmpz_is_zero(d))
            {
                if (j + v != 0)
                {
                    *s++ = ' ';
                    *s++ = '+';
                    *s++ = ' ';
                    fmpz_get_str(s, 10, d);
                    while (*++s != '\0') ;
                    *s++ = '*';
                    fmpz_get_str(s, 10, ctx->p);
                    while (*++s != '\0') ;
                    *s++ = '^';
                    sprintf(s, "%ld", j + v);
                    while (*++s != '\0') ;
                }
                else
                {
                    *s++ = ' ';
                    *s++ = '+';
                    *s++ = ' ';
                    fmpz_get_str(s, 10, d);
                    while (*++s != '\0') ;
                }
            }
        }
        
        fmpz_clear(x);
        fmpz_clear(d);
    }
    else  /* ctx->mode == PADIC_VAL_UNIT */
    {
        if (!str)
        {
            long b = fmpz_sizeinbase(u, 10) + fmpz_sizeinbase(ctx->p, 10) 
                   + z_sizeinbase(v, 10) + 4;

            str = flint_malloc(b);
            if (!str)
            {
                printf("ERROR (_padic_get_str).  Memory allocation failed.\n");
                abort();
            }
        }

        if (v == 0)
        {
            str = fmpz_get_str(str, 10, u);
        }
        else if (v == 1)
        {
            char *s = str;

            fmpz_get_str(s, 10, u);
            while (*++s != '\0') ;
            *s++ = '*';
            fmpz_get_str(s, 10, ctx->p);
        }
        else
        {
            char *s = str;

            fmpz_get_str(s, 10, u);
            while (*++s != '\0') ;
            *s++ = '*';
            fmpz_get_str(s, 10, ctx->p);
            while (*++s != '\0') ;
            *s++ = '^';
            sprintf(s, "%ld", v);
        }
    }

    return str;
}
Ejemplo n.º 30
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    {
        arf_t x, y, z;

        arf_init(x);
        arf_init(y);
        arf_init(z);

        for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
        {
            slong bits1, bits2;
            int ret1, ret2;
            mpfr_t g1, g2;
            fmpz_t e;
            arf_rnd_t rnd;

            bits1 = 1 + n_randint(state, 1000);
            bits2 = 2 + n_randint(state, 1000);

            if (n_randint(state, 100) == 0)
                bits2 = ARF_PREC_EXACT;

            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;
            }

            fmpz_init(e);
            mpfr_init2(g1, FLINT_MAX(2, bits1));
            mpfr_init2(g2, FLINT_MIN(bits2, 10000));

            if (n_randint(state, 100) == 0)
            {
                arf_clear(x); arf_clear(y); arf_clear(z);
                arf_init(x); arf_init(y); arf_init(z);
            }

            /* dirty output variables */
            if (n_randint(state, 2))
            {
                arf_randtest_special(y, state, 1 + n_randint(state, 1000),
                    1 + n_randint(state, 100));
                arf_randtest_special(z, state, 1 + n_randint(state, 1000),
                    1 + n_randint(state, 100));
            }

            arf_randtest_special(x, state, bits1, 1 + n_randint(state, 10));
            arf_get_mpfr(g1, x, MPFR_RNDD); /* exact */

            /* test large exponents */
            if (n_randint(state, 4) == 0)
                fmpz_randtest(e, state, 1 + n_randint(state, 100));

            if (!arf_is_special(x))
                fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e);

            ret1 = arf_set_round(y, x, bits2, rnd);
            ret2 = mpfr_set(g2, g1, arf_rnd_to_mpfr(rnd));
            arf_set_mpfr(z, g2);

            if (!arf_is_special(y))
                fmpz_sub(ARF_EXPREF(y), ARF_EXPREF(y), e);

            if (!arf_equal(y, z) || ((ret1 == ARF_RESULT_EXACT) != (ret2 == 0)))
            {
                flint_printf("FAIL\n\n");
                flint_printf("bits1: %wd\n", bits1);
                flint_printf("bits2: %wd\n", bits2);
                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("ret1 = %d, ret2 = %d\n\n", ret1, ret2);
                flint_abort();
            }

            if (!arf_is_special(x))
                fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e);

            ret1 = arf_set_round(y, x, bits2, rnd);
            arf_set(z, x);
            ret2 = arf_set_round(z, z, bits2, rnd);

            if (!arf_equal(y, z) || ret1 != ret2)
            {
                flint_printf("FAIL (aliasing)\n\n");
                flint_printf("bits1: %wd\n", bits1);
                flint_printf("bits2: %wd\n", bits2);
                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("ret1 = %d, ret2 = %d\n\n", ret1, ret2);
                flint_abort();
            }

            mpfr_clear(g1);
            mpfr_clear(g2);
            fmpz_clear(e);
        }

        arf_clear(x);
        arf_clear(y);
        arf_clear(z);
    }

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