Exemple #1
0
/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */
void
_fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1,
                            slong len1, const fmpz * poly2, slong len2)
{
    if ((len1 == 1) && (len2 == 1)) /* Special case if the length of both inputs is 1 */
    {
        fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        slong i;

        /* Set res[i] = poly1[i]*poly2[0]  */
        _fmpz_vec_scalar_mul_fmpz(res, poly1 + len2 - 1, len1 - len2 + 1,
                                  poly2);

        /* out[i+j] += in1[i]*in2[j] */
        for (i = 0; i < len2 - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res, poly2 + len2 - i - 1,
                                         FLINT_MIN(i + 1, len1 - len2 + 1),
                                         poly1 + i);
        for (; i < len1 - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res + i - len2 + 2, poly2 + 1,
                                         FLINT_MIN(len2 - 1, len1 - i - 1),
                                         poly1 + i);
    }
}
Exemple #2
0
/* Assumes poly1 and poly2 are not length 0. */
void
_fmpz_poly_mul_classical(fmpz * res, const fmpz * poly1,
                         slong len1, const fmpz * poly2, slong len2)
{
    if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */
    {
        fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        slong i;

        /* Set res[i] = poly1[i]*poly2[0] */
        _fmpz_vec_scalar_mul_fmpz(res, poly1, len1, poly2);

        /* Set res[i+len1-1] = in1[len1-1]*in2[i] */
        _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, len2 - 1,
                                  poly1 + len1 - 1);

        /* out[i+j] += in1[i]*in2[j] */
        for (i = 0; i < len1 - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1, len2 - 1,
                                         poly1 + i);
    }
}
Exemple #3
0
/*
   Assumes poly1 and poly2 are not length 0 and 0 < n <= len1 + len2 - 1.
 */
void
_fmpz_poly_mullow_classical(fmpz * res, const fmpz * poly1, long len1, 
                                        const fmpz * poly2, long len2, long n)
{
    if ((len1 == 1 && len2 == 1) || n == 1) /* Special case if the length of output is 1 */
    {
        fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        long i;

        /* Set res[i] = poly1[i]*poly2[0] */
        _fmpz_vec_scalar_mul_fmpz(res, poly1, FLINT_MIN(len1, n), poly2);

        /* Set res[i+len1-1] = in1[len1-1]*in2[i] */
        if (n > len1)
            _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, n - len1,
                                      poly1 + len1 - 1);

        /* out[i+j] += in1[i]*in2[j] */
        for (i = 0; i < FLINT_MIN(len1, n) - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1,
                                         FLINT_MIN(len2, n - i) - 1, 
                                         poly1 + i);
    }
}
Exemple #4
0
int dgsl_mp_call_inlattice(fmpz *rop,  const dgsl_mp_t *self, gmp_randstate_t state) {
  assert(rop); assert(self);

  const long m = fmpz_mat_nrows(self->B);
  const long n = fmpz_mat_ncols(self->B);
  mpz_t  tmp_g; mpz_init(tmp_g);
  fmpz_t tmp_f; fmpz_init(tmp_f);

  _fmpz_vec_zero(rop, n);

  for(long i=0; i<m; i++) {
    self->D[i]->call(tmp_g, self->D[i], state);
    fmpz_set_mpz(tmp_f, tmp_g);
    _fmpz_vec_scalar_addmul_fmpz(rop, self->B->rows[i], n, tmp_f);
  }
  _fmpz_vec_add(rop, rop, self->c_z, n);

  mpz_clear(tmp_g);
  fmpz_clear(tmp_f);

  return 0;
}
Exemple #5
0
/* Assumes len > 0. */
void _fmpz_poly_sqr_classical(fmpz *rop, const fmpz *op, long len)
{
    if (len == 1)  /* Special case */
    {
        fmpz_mul(rop, op, op);
    }
    else   /* Ordinary case */
    {
        long i;

        _fmpz_vec_scalar_mul_fmpz(rop, op, len, op);

        _fmpz_vec_scalar_mul_fmpz(rop + len, op + 1, len - 1, op + len - 1);

        for (i = 1; i < len - 1; i++)
            _fmpz_vec_scalar_addmul_fmpz(rop + i + 1, op + 1, i - 1, op + i);

        for (i = 1; i < 2 * len - 2; i++)
            fmpz_mul_ui(rop + i, rop + i, 2);

        for (i = 1; i < len - 1; i++)
            fmpz_addmul(rop + 2 * i, op + i, op + i);
    }
}
Exemple #6
0
/* Assumes poly1 and poly2 are not length 0. */
void
_fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1,
                             long len1, const fmpz * poly2, long len2,
                             long start)
{
    _fmpz_vec_zero(res, start);

    if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */
    {
        if (start == 0)
            fmpz_mul(res, poly1, poly2);
    }
    else                        /* Ordinary case */
    {
        long i, m, n;

        /* Set res[i] = poly1[i]*poly2[0] */
        if (start < len1)
            _fmpz_vec_scalar_mul_fmpz(res + start, poly1 + start, len1 - start,
                                      poly2);

        /* Set res[i+len1-1] = in1[len1-1]*in2[i] */
        m = FLINT_MAX(len1 - 1, start);
        _fmpz_vec_scalar_mul_fmpz(res + m, poly2 + m - len1 + 1,
                                  len2 - 1 + len1 - m, poly1 + len1 - 1);

        /* out[i+j] += in1[i]*in2[j] */
        m = FLINT_MAX(start, len2 - 1);
        for (i = m - len2 + 1; i < len1 - 1; i++)
        {
            n = FLINT_MAX(i + 1, start);
            _fmpz_vec_scalar_addmul_fmpz(res + n, poly2 + n - i, len2 + i - n,
                                         poly1 + i);
        }
    }
}
Exemple #7
0
int dgsl_mp_call_coset(fmpz *rop, const dgsl_mp_t *self, gmp_randstate_t state) {
  assert(rop); assert(self);

  const long n = fmpz_mat_ncols(self->B);
  _fmpz_vec_zero(rop, n);

  mpfr_t *c = _mpfr_vec_init(n, mpfr_get_prec(self->sigma));
  _mpfr_vec_set(c, self->c, n, MPFR_RNDN);

  mpfr_t c_prime;
  mpfr_init2(c_prime, mpfr_get_prec(self->sigma));

  mpfr_t tmp;
  mpfr_init2(tmp, mpfr_get_prec(self->sigma));

  mpfr_t sigma_prime;
  mpfr_init2(sigma_prime, mpfr_get_prec(self->sigma));

  mpz_t z;
  mpz_init(z);

  mpfr_t z_mpfr;
  mpfr_init2(z_mpfr, mpfr_get_prec(self->sigma));

  fmpz_t z_fmpz;
  fmpz_init(z_fmpz);

  size_t tau = 3;
  if (ceil(sqrt(log2((double)n))) > tau)
    tau = ceil(sqrt(log2((double)n)));

  mpfr_t *b = _mpfr_vec_init(n, mpfr_get_prec(self->sigma));

  const long m = fmpz_mat_nrows(self->B);
  for(long j=0; j<m; j++) {
    long i = m-j-1;
    _mpfr_vec_dot_product(c_prime, c,                self->G->rows[i], n, MPFR_RNDN);
    _mpfr_vec_dot_product(tmp,     self->G->rows[i], self->G->rows[i], n, MPFR_RNDN);
    mpfr_div(c_prime, c_prime, tmp, MPFR_RNDN);

    mpfr_sqrt(tmp, tmp, MPFR_RNDN);
    mpfr_div(sigma_prime, self->sigma, tmp, MPFR_RNDN);

    assert(mpfr_cmp_d(sigma_prime, 0.0) > 0);
    dgs_disc_gauss_mp_t *D = dgs_disc_gauss_mp_init(sigma_prime, c_prime, tau, DGS_DISC_GAUSS_UNIFORM_ONLINE);
    D->call(z, D, state);
    dgs_disc_gauss_mp_clear(D);

    mpfr_set_z(z_mpfr, z, MPFR_RNDN);
    mpfr_neg(z_mpfr, z_mpfr, MPFR_RNDN);
    _mpfr_vec_set_fmpz_vec(b, self->B->rows[i], n, MPFR_RNDN);
    _mpfr_vec_scalar_addmul_mpfr(c, b, n, z_mpfr, MPFR_RNDN);

    fmpz_set_mpz(z_fmpz, z);
    _fmpz_vec_scalar_addmul_fmpz(rop, self->B->rows[i], n, z_fmpz);
  }

  fmpz_clear(z_fmpz);
  mpfr_clear(z_mpfr);
  mpfr_clear(sigma_prime);
  mpfr_clear(tmp);
  mpfr_clear(c_prime);
  _mpfr_vec_clear(c, n);
  _mpfr_vec_clear(b, n);
  return 0;
}
Exemple #8
0
void _padic_poly_sub(fmpz *rop, slong *val, slong N, 
                     const fmpz *op1, slong val1, slong len1, slong N1, 
                     const fmpz *op2, slong val2, slong len2, slong N2, 
                     const padic_ctx_t ctx)
{
    const slong len = FLINT_MAX(len1, len2);

    *val = FLINT_MIN(val1, val2);

    if (val1 == val2)
    {
        _fmpz_poly_sub(rop, op1, len1, op2, len2);
        _padic_poly_canonicalise(rop, val, len, ctx->p);
    }
    else
    {
        fmpz_t x;

        fmpz_init(x);
        if (val1 < val2)  /* F := p^g (G - p^{h-g} H) */
        {
            fmpz_pow_ui(x, ctx->p, val2 - val1);

            if (rop == op1)
            {
                _fmpz_vec_zero(rop + len1, len2 - len1);
                _fmpz_vec_scalar_submul_fmpz(rop, op2, len2, x);
            }
            else
            {
                _fmpz_vec_scalar_mul_fmpz(rop, op2, len2, x);
                _fmpz_vec_neg(rop, rop, len2);
                _fmpz_poly_add(rop, op1, len1, rop, len2);
            }
        }
        else  /* F := p^h (p^(g-h) G - H) */
        {
            fmpz_pow_ui(x, ctx->p, val1 - val2);

            if (rop == op2)
            {
                _fmpz_vec_neg(rop, op2, len2);
                _fmpz_vec_zero(rop + len2, len1 - len2);
                _fmpz_vec_scalar_addmul_fmpz(rop, op1, len1, x);
            }
            else
            {
                _fmpz_vec_scalar_mul_fmpz(rop, op1, len1, x);
                _fmpz_poly_sub(rop, rop, len1, op2, len2);
            }
        }
        fmpz_clear(x);
    }

    /* Reduce */
    if (N - *val > 0)
    {
        fmpz_t pow;
        int alloc;

        alloc = _padic_ctx_pow_ui(pow, N - *val, ctx);

        if (N >= N1 && N >= N2)
        {
            slong i;
            for (i = 0; i < len; i++)
                if (fmpz_sgn(rop + i) < 0)
                    fmpz_add(rop + i, rop + i, pow);
        }
        else
        {
            _fmpz_vec_scalar_mod_fmpz(rop, rop, len, pow);
        }

        if (alloc)
            fmpz_clear(pow);
    }
    else
    {
        _fmpz_vec_zero(rop, len);
        *val = 0;
    }
}
Exemple #9
0
void
_fmpq_poly_interpolate_fmpz_vec(fmpz * poly, fmpz_t den,
                                    const fmpz * xs, const fmpz * ys, long n)
{
    fmpz *P, *Q, *w;
    fmpz_t t;

    long i, j;

    /* Constant */
    if (n == 1)
    {
        fmpz_set(poly, ys);
        fmpz_one(den);
        return;
    }

    /* Linear */
    if (n == 2)
    {
        fmpz_sub(den, xs, xs + 1);
        fmpz_sub(poly + 1, ys, ys + 1);
        fmpz_mul(poly, xs, ys + 1);
        fmpz_submul(poly, xs + 1, ys);
        return;
    }

    fmpz_init(t);

    P = _fmpz_vec_init(n + 1);
    Q = _fmpz_vec_init(n);
    w = _fmpz_vec_init(n);

    /* P = (x-x[0])*(x-x[1])*...*(x-x[n-1]) */
    _fmpz_poly_product_roots_fmpz_vec(P, xs, n);

    /* Weights */
    for (i = 0; i < n; i++)
    {
        fmpz_one(w + i);
        for (j = 0; j < n; j++)
        {
            if (i != j)
            {
                fmpz_sub(t, xs + i, xs + j);
                fmpz_mul(w + i, w + i, t);
            }
        }
    }

    _fmpz_vec_zero(poly, n);
    _fmpz_vec_lcm(den, w, n);

    for (i = 0; i < n; i++)
    {
        /* Q = P / (x - x[i]) */
        _fmpz_poly_div_root(Q, P, n + 1, xs + i);

        /* result += Q * weight(i) */
        fmpz_divexact(t, den, w + i);
        fmpz_mul(t, t, ys + i);
        _fmpz_vec_scalar_addmul_fmpz(poly, Q, n, t);
    }

    _fmpz_vec_clear(P, n + 1);
    _fmpz_vec_clear(Q, n);
    _fmpz_vec_clear(w, n);
    fmpz_clear(t);
}
Exemple #10
0
int
_fmpz_poly_sqrt_classical(fmpz * res, const fmpz * poly, long len)
{
    long i, m;
    int result;

    /* the degree must be even */
    if (len % 2 == 0)
        return 0;

    /* valuation must be even, and then can be reduced to 0 */
    while (fmpz_is_zero(poly))
    {
        if (!fmpz_is_zero(poly + 1))
            return 0;

        fmpz_zero(res);
        poly += 2;
        len -= 2;
        res++;
    }

    /* check whether a square root exists modulo 2 */
    for (i = 1; i < len; i += 2)
        if (!fmpz_is_even(poly + i))
            return 0;

    /* check endpoints */
    if (!fmpz_is_square(poly) || (len > 1 && !fmpz_is_square(poly + len - 1)))
        return 0;

    /* square root of leading coefficient */
    m = (len + 1) / 2;
    fmpz_sqrt(res + m - 1, poly + len - 1);
    result = 1;

    /* do long divison style 'square root with remainder' from top to bottom */
    if (len > 1)
    {
        fmpz_t t, u;
        fmpz * r;

        fmpz_init(t);
        fmpz_init(u);
        r = _fmpz_vec_init(len);
        _fmpz_vec_set(r, poly, len);
        fmpz_mul_ui(u, res + m - 1, 2);

        for (i = 1; i < m; i++)
        {
            fmpz_fdiv_qr(res + m - i - 1, t, r + len - i - 1, u);
            if (!fmpz_is_zero(t))
            {
                result = 0;
                break;
            }

            fmpz_mul_si(t, res + m - i - 1, -2);
            _fmpz_vec_scalar_addmul_fmpz(r + len - 2*i, res + m - i, i - 1, t);
            fmpz_submul(r + len - 2*i - 1, res + m - i - 1, res + m - i - 1);
        }

        for (i = m; i < len && result; i++)
            if (!fmpz_is_zero(r + len - 1 - i))
                result = 0;

        _fmpz_vec_clear(r, len);
        fmpz_clear(t);
        fmpz_clear(u);
    }

    return result;
}