Beispiel #1
0
int
fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den,
                            const fmpz_mat_t A, const fmpz_mat_t B)
{
    long i, dim = fmpz_mat_nrows(A);

    if (dim == 0)
    {
        fmpz_one(den);
        return 1;
    }
    else if (dim == 1)
    {
        fmpz_set(den, fmpz_mat_entry(A, 0, 0));

        if (fmpz_is_zero(den))
            return 0;

        if (!fmpz_mat_is_empty(B))
            _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B));
        return 1;
    }
    else if (dim == 2)
    {
        fmpz_t t, u;

        _fmpz_mat_det_cofactor_2x2(den, A->rows);

        if (fmpz_is_zero(den))
            return 0;

        fmpz_init(t);
        fmpz_init(u);

        for (i = 0; i < fmpz_mat_ncols(B); i++)
        {
            fmpz_mul   (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i));
            fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i));
            fmpz_mul   (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i));
            fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i));

            fmpz_swap(fmpz_mat_entry(X, 0, i), t);
            fmpz_swap(fmpz_mat_entry(X, 1, i), u);
        }

        fmpz_clear(t);
        fmpz_clear(u);

        return 1;
    }
    else if (dim == 3)
    {
        return _fmpz_mat_solve_cramer_3x3(X, den, A, B);
    }
    else
    {
        printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented");
        abort();
    }
}
/** Compute the column HNF with transformation matrix H = AU.
 *
 * TODO: Implement directly as in fmpz_mat_hnf_transform().
 */
void fmpz_mat_hnf_col_transform(fmpz_mat_t H, fmpz_mat_t U, \
        const fmpz_mat_t A)
{
    fmpz_mat_t tA, H_, U_;

    /* Compute row HNF for tA: H_ = U_*tA. */
    fmpz_mat_init(tA, fmpz_mat_ncols(A), fmpz_mat_nrows(A));
    fmpz_mat_transpose(tA, A);
    fmpz_mat_init(H_, fmpz_mat_nrows(tA), fmpz_mat_ncols(tA));
    fmpz_mat_init(U_, fmpz_mat_nrows(tA), fmpz_mat_nrows(tA));

    /* Argh!  Pernet-Stein algorithm can fail (with low probability.)  Why
     * doesn't fmpz_mat_hnf_transform() check this?!  Alex has this fixed, so
     * soon this should no longer be needed. */
    do {
        fmpz_mat_hnf_transform(H_, U_, tA);
    } while (!fmpz_mat_is_in_hnf(H_));

    fmpz_mat_clear(tA);

    /* Transpose H_, U_: H = A*U is column HNF. */
    fmpz_mat_transpose(H, H_);
    fmpz_mat_transpose(U, U_);
    fmpz_mat_clear(H_);
    fmpz_mat_clear(U_);
};
Beispiel #3
0
void dgsl_mp_clear(dgsl_mp_t *self) {
  if (!self)
    return;
  _fmpz_vec_clear(self->c_z, fmpz_mat_ncols(self->B));
  _mpfr_vec_clear(self->c,   fmpz_mat_ncols(self->B));

  if (!fmpz_mat_is_empty(self->B)) {
    fmpz_mat_clear(self->B);
  }

  if (!mpfr_mat_is_empty(self->G)) {
    mpfr_mat_clear(self->G);
  }
  if(self->call == dgsl_mp_call_identity) {
    if(self->D) {
      dgs_disc_gauss_mp_clear(self->D[0]);
      free(self->D);
    }
  }
  mpfr_clear(self->sigma);
  free(self);
}
Beispiel #4
0
int dgsl_mp_call_identity(fmpz *rop,  const dgsl_mp_t *self, gmp_randstate_t state) {
  assert(rop); assert(self);

  const long n = fmpz_mat_ncols(self->B);
  mpz_t  tmp_g;  mpz_init(tmp_g);

  _fmpz_vec_zero(rop, n);

  for(long i=0; i<n; i++) {
    self->D[0]->call(tmp_g, self->D[0], state);
    fmpz_set_mpz(rop+i, tmp_g);
  }

  mpz_clear(tmp_g);

  return 0;
}
Beispiel #5
0
void
fmpz_mat_set_perm(fmpz_mat_t X, const long * perm, const fmpz_mat_t B)
{
    if (X == B)
    {
        /* Not implemented */
        abort();
    }
    else
    {
        long i, j;

        if (perm == NULL)
            abort();

        for (i = 0; i < fmpz_mat_nrows(B); i++)
            for (j = 0; j < fmpz_mat_ncols(B); j++)
                fmpz_set(fmpz_mat_entry(X, i, j),
                         fmpz_mat_entry(B, perm[i], j));
    }
}
Beispiel #6
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;
}
Beispiel #7
0
void
fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat,
    nmod_mat_t * const residues, long nres,
    fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign)
{
    long i, j, k;
    mp_ptr r;

    r = _nmod_vec_init(nres);

    for (i = 0; i < fmpz_mat_nrows(mat); i++)
    {
        for (j = 0; j < fmpz_mat_ncols(mat); j++)
        {
            for (k = 0; k < nres; k++)
                r[k] = nmod_mat_entry(residues[k], i, j);
            fmpz_multi_CRT_ui(fmpz_mat_entry(mat, i, j), r, comb, temp, sign);
        }
    }

    _nmod_vec_clear(r);
}
Beispiel #8
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;
}
Beispiel #9
0
dgsl_mp_t *dgsl_mp_init(const fmpz_mat_t B, mpfr_t sigma,
                      mpfr_t *c, const dgsl_alg_t algorithm) {
  assert(mpfr_cmp_ui(sigma, 0) > 0);

  dgsl_mp_t *self = (dgsl_mp_t*)calloc(1, sizeof(dgsl_mp_t));
  if(!self) dgs_die("out of memory");

  dgsl_alg_t alg = algorithm;

  long m = fmpz_mat_nrows(B);
  long n = fmpz_mat_ncols(B);

  const mpfr_prec_t prec = mpfr_get_prec(sigma);

  fmpz_mat_init_set(self->B, B);
  self->c_z = _fmpz_vec_init(n);
  self->c   = _mpfr_vec_init(n, prec);
  mpfr_init2(self->sigma, prec);
  mpfr_set(self->sigma, sigma, MPFR_RNDN);

  if (alg == DGSL_DETECT) {
    if (fmpz_mat_is_one(self->B)) {
      alg = DGSL_IDENTITY;
    } else if (_mpfr_vec_is_zero(c, n))
      alg = DGSL_INLATTICE;
    else
      alg = DGSL_COSET; //TODO: we could test for lattice membership here
  }

  mpfr_t c_;
  mpfr_init2(c_, prec);

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

  switch(alg) {
  case DGSL_IDENTITY:
    self->D = (dgs_disc_gauss_mp_t**)calloc(1, sizeof(dgs_disc_gauss_mp_t*));
    mpfr_set_d(c_, 0.0, MPFR_RNDN);
    self->D[0] = dgs_disc_gauss_mp_init(self->sigma, c_, tau, DGS_DISC_GAUSS_DEFAULT);

    self->call = dgsl_mp_call_identity;
    break;

  case DGSL_INLATTICE:
    self->D = (dgs_disc_gauss_mp_t**)calloc(m, sizeof(dgs_disc_gauss_mp_t*));

    if (c)
      _fmpz_vec_set_mpfr_vec(self->c_z, c, n);

    mpfr_mat_t G;
    mpfr_mat_init(G, m, n, prec);
    mpfr_mat_set_fmpz_mat(G, B);

    mpfr_mat_gso(G, MPFR_RNDN);

    mpfr_t sigma_;
    mpfr_init2(sigma_, prec);

    mpfr_t norm;
    mpfr_init2(norm, prec);

    mpfr_set_d(c_, 0.0, MPFR_RNDN);

    for(long i=0; i<m; i++) {
      _mpfr_vec_2norm(norm, G->rows[i], n, MPFR_RNDN);
      assert(mpfr_cmp_d(norm, 0.0) > 0);
      mpfr_div(sigma_, self->sigma, norm, MPFR_RNDN);
      assert(mpfr_cmp_d(sigma_, 0.0) > 0);
      self->D[i] = dgs_disc_gauss_mp_init(sigma_, c_, tau, DGS_DISC_GAUSS_DEFAULT);
    }

    mpfr_clear(sigma_);
    mpfr_clear(norm);
    mpfr_mat_clear(G);

    self->call = dgsl_mp_call_inlattice;
    break;

  case DGSL_COSET:
    mpfr_mat_init(self->G, m, n, prec);
    mpfr_mat_set_fmpz_mat(self->G, B);
    mpfr_mat_gso(self->G, MPFR_RNDN);

    self->call = dgsl_mp_call_coset;
    break;
  default:
    dgs_die("not implemented");
  }

  mpfr_clear(c_);

  return self;
}
Beispiel #10
0
int
_fmpz_mat_solve_cramer_3x3(fmpz_mat_t X, fmpz_t den,
    const fmpz_mat_t A, const fmpz_mat_t B)
{
    fmpz_t t15, t16, t17;
    int success;

    fmpz_init(t15);
    fmpz_init(t16);
    fmpz_init(t17);

    fmpz_mul(t17, AA(1,0), AA(2,1));
    fmpz_submul(t17, AA(1,1), AA(2,0));

    fmpz_mul(t16, AA(1,2), AA(2,0));
    fmpz_submul(t16, AA(1,0), AA(2,2));

    fmpz_mul(t15, AA(1,1), AA(2,2));
    fmpz_submul(t15, AA(1,2), AA(2,1));

    fmpz_mul   (den, t15, AA(0,0));
    fmpz_addmul(den, t16, AA(0,1));
    fmpz_addmul(den, t17, AA(0,2));

    success = !fmpz_is_zero(den);

    if (success)
    {
        fmpz_t t12, t13, t14, x0, x1, x2;
        long i, n = fmpz_mat_ncols(B);

        fmpz_init(t12);
        fmpz_init(t13);
        fmpz_init(t14);
        fmpz_init(x0);
        fmpz_init(x1);
        fmpz_init(x2);

        for (i = 0; i < n; i++)
        {
            fmpz_mul(t14, AA(2,0), BB(1,i));
            fmpz_submul(t14, AA(1,0), BB(2,i));

            fmpz_mul(t13, AA(2,1), BB(1,i));
            fmpz_submul(t13, AA(1,1), BB(2,i));

            fmpz_mul(t12, AA(2,2), BB(1,i));
            fmpz_submul(t12, AA(1,2), BB(2,i));

            fmpz_mul   (x0, t15, BB(0,i));
            fmpz_addmul(x0, t13, AA(0,2));
            fmpz_submul(x0, t12, AA(0,1));

            fmpz_mul   (x1, t16, BB(0,i));
            fmpz_addmul(x1, t12, AA(0,0));
            fmpz_submul(x1, t14, AA(0,2));

            fmpz_mul   (x2, t17, BB(0,i));
            fmpz_addmul(x2, t14, AA(0,1));
            fmpz_submul(x2, t13, AA(0,0));

            fmpz_swap(XX(0,i), x0);
            fmpz_swap(XX(1,i), x1);
            fmpz_swap(XX(2,i), x2);
        }

        fmpz_clear(t12);
        fmpz_clear(t13);
        fmpz_clear(t14);
        fmpz_clear(x0);
        fmpz_clear(x1);
        fmpz_clear(x2);
    }

    fmpz_clear(t15);
    fmpz_clear(t16);
    fmpz_clear(t17);

    return success;
}
Beispiel #11
0
 size_t numColumns() const { return fmpz_mat_ncols(mArray); }