예제 #1
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);
    }
}
예제 #2
0
static void
fmpz_mul_or_div_2exp(fmpz_t x, fmpz_t y, slong s)
{
    if (s >= 0)
        fmpz_mul_2exp(x, y, s);
    else
        fmpz_fdiv_q_2exp(x, y, -s);
}
예제 #3
0
파일: mul_2exp.c 프로젝트: clear731/lattice
void fmpq_mul_2exp(fmpq_t res, const fmpq_t x, mp_bitcnt_t exp)
{
    if (fmpq_is_zero(x) || exp == 0)
    {
        fmpq_set(res, x);
    }
    else
    {
        mp_bitcnt_t v = fmpz_val2(fmpq_denref(x));

        if (exp <= v)
        {
            fmpz_set(fmpq_numref(res), fmpq_numref(x));
            fmpz_fdiv_q_2exp(fmpq_denref(res), fmpq_denref(x), exp);
        }
        else
        {
            fmpz_mul_2exp(fmpq_numref(res), fmpq_numref(x), exp - v);
            fmpz_fdiv_q_2exp(fmpq_denref(res), fmpq_denref(x), v);
        }
    }
}
예제 #4
0
/* Balanced product of linear factors (x+alpha_i) using
   fixed-point arithmetic with prec bits */
static void
balanced_product(fmpz * c, fmpz * alpha, slong len, slong prec)
{
    if (len == 1)
    {
        fmpz_one(c + 1);
        fmpz_mul_2exp(c + 1, c + 1, prec);
        fmpz_set(c, alpha);
    }
    else if (len == 2)
    {
        fmpz_mul(c, alpha, alpha + 1);
        fmpz_fdiv_q_2exp(c, c, prec);
        fmpz_add(c + 1, alpha, alpha + 1);
        fmpz_one(c + 2);
        fmpz_mul_2exp(c + 2, c + 2, prec);
    }
    else
    {
        fmpz *L, *R;
        slong i, m;

        m = len / 2;
        L = _fmpz_vec_init(len + 2);
        R = L + m + 1;

        balanced_product(L, alpha, m, prec);
        balanced_product(R, alpha + m, len - m, prec);
        _fmpz_poly_mul(c, R, len - m + 1, L, m + 1);

        for (i = 0; i < len + 1; i++)
            fmpz_fdiv_q_2exp(c + i, c + i, prec);

        _fmpz_vec_clear(L, len + 2);
    }
}
예제 #5
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);
}
예제 #6
0
파일: randajtai.c 프로젝트: goens/flint2
void
fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha)
{
    long r, c, i, j, d;
    fmpz_t tmp;

    r = mat->r;
    c = mat->c;
    d = r;

    if (c != r)
    {
        printf("Exception: fmpz_mat_ajtai called on an ill-formed matrix\n");
        abort();
    }

    fmpz_init(tmp);

    for (i = 0; i < d; i++)
    {
        mp_bitcnt_t bits = (mp_bitcnt_t) pow((double) (2 * d - i), alpha);

        fmpz_one(tmp);
        fmpz_mul_2exp(tmp, tmp, bits);
        fmpz_sub_ui(tmp, tmp, 1);
        fmpz_randm(mat->rows[i] + i, state, tmp);
        fmpz_add_ui(mat->rows[i] + i, mat->rows[i] + i, 2);
        fmpz_fdiv_q_2exp(mat->rows[i] + i, mat->rows[i] + i, 1);

        for (j = i + 1; j <= d; j++)
        {
            fmpz_randm(mat->rows[j] + i, state, tmp);
            if (n_randint(state, 2))
                fmpz_neg(mat->rows[j] + i, mat->rows[j] + i);
            fmpz_zero(mat->rows[i] + j);
        }
    }

    fmpz_clear(tmp);
}
예제 #7
0
void
fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha)
{
    const slong c = mat->c, r = mat->r, d = r;

    slong i, j;
    fmpz_t tmp;

    if (c != r)
    {
        flint_printf("Exception (fmpz_mat_ajtai): Non-square matrix.\n");
        abort();
    }

    fmpz_init(tmp);

    for (i = 0; i < d; i++)
    {
        mp_bitcnt_t bits = (mp_bitcnt_t) pow((double) (2 * d - i), alpha);

        fmpz_one(tmp);
        fmpz_mul_2exp(tmp, tmp, bits);
        fmpz_sub_ui(tmp, tmp, 1);
        fmpz_randm(mat->rows[i] + i, state, tmp);
        fmpz_add_ui(mat->rows[i] + i, mat->rows[i] + i, 2);
        fmpz_fdiv_q_2exp(mat->rows[i] + i, mat->rows[i] + i, 1);

        for (j = i + 1; j <= d; j++)
        {
            fmpz_randm(mat->rows[j] + i, state, tmp);
            if (n_randint(state, 2))
                fmpz_neg(mat->rows[j] + i, mat->rows[j] + i);
            fmpz_zero(mat->rows[i] + j);
        }
    }

    fmpz_clear(tmp);
}
예제 #8
0
void
test0(slong b)
 {
  fmpz_t M; fmpz_init_set_ui(M,1);
  fmpz_mul_2exp(M,M,(ulong)b);
  test1_ui(b,M,0);
  test1_ui(b,M,1);
  test1_ui(b,M,(mp_limb_t)-1);
  test1(b,M,M);                      // M
  fmpz_t n; fmpz_init_set(n,M);
  fmpz_add_ui(n,M,1);
  test1(b,M,n);                      // M+1
  fmpz_sub_ui(n,M,1);
  test1(b,M,n);                      // M-1
  slong i;
  fmpz_t m; fmpz_init(m);
  fmpz_t Mhalf; fmpz_init(Mhalf);
  fmpz_fdiv_q_2exp(Mhalf,M,1);
  for(i=100;i--;)
   {
    fmpz_randm(m,rst,n);                      // m = random(M-1)
    test1(b,M,m);
    fmpz_add(m,m,Mhalf);                     // m+M/2
    test1(b,M,m);
   }
  fmpz_mul_2exp(m,M,1);
  test1(b,M,m);                      // M<<1
  fmpz_mul_2exp(m,m,1);
  test1(b,M,m);                      // M<<2
  fmpz_mul_2exp(m,m,1);
  test1(b,M,m);                      // M<<3
  fmpz_mul(m,m,M);
  test1(b,M,m);                      // M*(M<<3)
  fmpz_clear(Mhalf);
  fmpz_clear(m);
  fmpz_clear(n);
  fmpz_clear(M);
 }
예제 #9
0
void
_arith_cos_minpoly(fmpz * coeffs, slong d, ulong n)
{
    slong i, j;
    fmpz * alpha;
    fmpz_t half;
    mpfr_t t, u;
    mp_bitcnt_t prec;
    slong exp;

    if (n <= MAX_32BIT)
    {
        for (i = 0; i <= d; i++)
            fmpz_set_si(coeffs + i, lookup_table[n - 1][i]);
        return;
    }

    /* Direct formula for odd primes > 3 */
    if (n_is_prime(n))
    {
        slong s = (n - 1) / 2;

        switch (s % 4)
        {
            case 0:
                fmpz_set_si(coeffs, WORD(1));
                fmpz_set_si(coeffs + 1, -s);
                break;
            case 1:
                fmpz_set_si(coeffs, WORD(1));
                fmpz_set_si(coeffs + 1, s + 1);
                break;
            case 2:
                fmpz_set_si(coeffs, WORD(-1));
                fmpz_set_si(coeffs + 1, s);
                break;
            case 3:
                fmpz_set_si(coeffs, WORD(-1));
                fmpz_set_si(coeffs + 1, -s - 1);
                break;
        }

        for (i = 2; i <= s; i++)
        {
            slong b = (s - i) % 2;
            fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, s+i-b, s+2-b-i);
            fmpz_divexact2_uiui(coeffs + i, coeffs + i, i, i-1);
            fmpz_neg(coeffs + i, coeffs + i);
        }

        return;
    }

    prec = magnitude_bound(d) + 5 + FLINT_BIT_COUNT(d);

    alpha = _fmpz_vec_init(d);
    fmpz_init(half);
    mpfr_init2(t, prec);
    mpfr_init2(u, prec);

    fmpz_one(half);
    fmpz_mul_2exp(half, half, prec - 1);
    mpfr_const_pi(t, prec);
    mpfr_div_ui(t, t, n, MPFR_RNDN);

    for (i = j = 0; j < d; i++)
    {
        if (n_gcd(n, i) == 1)
        {
            mpfr_mul_ui(u, t, 2 * i, MPFR_RNDN);
            mpfr_cos(u, u, MPFR_RNDN);
            mpfr_neg(u, u, MPFR_RNDN);
            exp = mpfr_get_z_2exp(_fmpz_promote(alpha + j), u);
            _fmpz_demote_val(alpha + j);
            fmpz_mul_or_div_2exp(alpha + j, alpha + j, exp + prec);
            j++;
        }
    }

    balanced_product(coeffs, alpha, d, prec);

    /* Scale and round */
    for (i = 0; i < d + 1; i++)
    {
        slong r = d;
        if ((n & (n - 1)) == 0)
            r--;
        fmpz_mul_2exp(coeffs + i, coeffs + i, r);
        fmpz_add(coeffs + i, coeffs + i, half);
        fmpz_fdiv_q_2exp(coeffs + i, coeffs + i, prec);
    }

    fmpz_clear(half);
    mpfr_clear(t);
    mpfr_clear(u);
    _fmpz_vec_clear(alpha, d);
}
예제 #10
0
int
arb_get_unique_fmpz(fmpz_t z, const arb_t x)
{
    if (!arb_is_finite(x))
    {
        return 0;
    }
    else if (arb_is_exact(x))
    {
        /* x = b*2^e, e >= 0 */
        if (arf_is_int(arb_midref(x)))
        {
            /* arf_get_fmpz aborts on overflow */
            arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN);
            return 1;
        }
        else
        {
            return 0;
        }
    }
    /* if the radius is >= 1, there are at least two integers */
    else if (mag_cmp_2exp_si(arb_radref(x), 0) >= 0)
    {
        return 0;
    }
    /* there are 0 or 1 integers if the radius is < 1 */
    else
    {
        fmpz_t a, b, exp;
        int res;

        /* if the midpoint is exactly an integer, it is what we want */
        if (arf_is_int(arb_midref(x)))
        {
            /* arf_get_fmpz aborts on overflow */
            arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN);
            return 1;
        }

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

        /* if the radius is tiny, it can't be an integer */
        arf_bot(a, arb_midref(x));

        if (fmpz_cmp(a, MAG_EXPREF(arb_radref(x))) > 0)
        {
            res = 0;
        }
        else
        {
            arb_get_interval_fmpz_2exp(a, b, exp, x);

            if (COEFF_IS_MPZ(*exp))
            {
                flint_printf("arb_get_unique_fmpz: input too large\n");
                abort();
            }

            if (*exp >= 0)
            {
                res = fmpz_equal(a, b);

                if (res)
                {
                    fmpz_mul_2exp(a, a, *exp);
                    fmpz_mul_2exp(b, b, *exp);
                }
            }
            else
            {
                fmpz_cdiv_q_2exp(a, a, -(*exp));
                fmpz_fdiv_q_2exp(b, b, -(*exp));
                res = fmpz_equal(a, b);
            }

            if (res)
                fmpz_set(z, a);
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(exp);

        return res;
    }
}