示例#1
0
int main(int argc, char *argv[]) {
  assert(argc>=3);
  const long n = atol(argv[1]);
  const long prec = atol(argv[2]);

  flint_rand_t randstate;
  flint_randinit_seed(randstate, 0x1337, 1);

  mpfr_t sigma;
  mpfr_init2(sigma, prec);
  mpfr_set_d(sigma, _gghlite_sigma(n), MPFR_RNDN);

  fmpz_poly_t g;
  fmpz_poly_init(g);
  fmpz_poly_sample_sigma(g, n, sigma, randstate);

  fmpq_poly_t gq; fmpq_poly_init(gq);
  fmpq_poly_set_fmpz_poly(gq, g);
  fmpq_poly_t g_inv; fmpq_poly_init(g_inv);

  fmpq_poly_t modulus;
  fmpq_poly_init_oz_modulus(modulus, n);

  printf(" n: %4ld, log σ': %7.2f, ",n, log2(_gghlite_sigma(n)));

  uint64_t t = ggh_walltime(0);
  fmpq_poly_invert_mod(g_inv, gq, modulus);
  t = ggh_walltime(t);
  printf("xgcd: %7.3f, ", t/1000000.0);
  fflush(0);

  t = ggh_walltime(0);
  _fmpq_poly_oz_invert_approx(g_inv, gq, n, 160);
  t = ggh_walltime(t);
  printf("%4ld: %7.3f, ", prec, t/1000000.0);
  fflush(0);

  t = ggh_walltime(0);
  fmpq_poly_oz_invert_approx(g_inv, gq, n, 160, 0);
  t = ggh_walltime(t);
  printf("%4lditer: %7.3f, ", prec, t/1000000.0);
  fflush(0);

  t = ggh_walltime(0);
  _fmpq_poly_oz_invert_approx(g_inv, gq, n, 0);
  t = ggh_walltime(t);
  printf("∞: %7.3f.", t/1000000.0);


  printf("\n");

  mpfr_clear(sigma);
  fmpz_poly_clear(g);
  fmpq_poly_clear(gq);
  fmpq_poly_clear(g_inv);
  fmpq_poly_clear(modulus);
  flint_randclear(randstate);
  flint_cleanup();
  return 0;
}
示例#2
0
void renf_randtest(renf_t nf, flint_rand_t state, slong len, slong prec, mp_bitcnt_t bits)
{
    fmpz_poly_t p;
    fmpq_poly_t p2;
    fmpz * c_array;
    slong * k_array;
    slong n_interval, n_exact;
    ulong i;
    arb_t emb;

    /* compute a random irreducible polynomial */
    if (len <= 1)
    {
        fprintf(stderr, "ERROR (renf_randtest): got length < 2\n");
        abort();
    }

    fmpz_poly_init(p);
    do{
        fmpz_poly_randtest_irreducible(p, state, len, bits);
    }while(!fmpz_poly_has_real_root(p));

    /* pick a random real root */
    c_array = _fmpz_vec_init(p->length);
    k_array = malloc((p->length) * sizeof(slong));
    n_interval = 0;

    fmpz_poly_isolate_real_roots(NULL, &n_exact,
            c_array, k_array, &n_interval, p);

    if (n_interval == 0)
    {
        fprintf(stderr, "Runtime error\n");
        abort();
    }

    i = n_randint(state, n_interval);

    /* construct the associated number field */
    arb_init(emb);
    arb_from_interval(emb, c_array+i, k_array[i], fmpz_bits(c_array + i) + FLINT_MAX(k_array[i], 0) + 2);

    fmpq_poly_init(p2);
    fmpq_poly_set_fmpz_poly(p2, p);

    /* NOTE: renf init might not be happy with the ball emb */
    renf_init(nf, p2, emb, prec);

    _fmpz_vec_clear(c_array, p->length);
    free(k_array);
    fmpz_poly_clear(p);
    fmpq_poly_clear(p2);
    arb_clear(emb);
}
示例#3
0
文件: dgsl.c 项目: malb/gghlite-flint
int dgsl_rot_mp_call_plus_fmpz_poly(fmpz_poly_t rop, const dgsl_rot_mp_t *self, const fmpz_poly_t c, gmp_randstate_t state) {
  fmpz_poly_t t;  fmpz_poly_init(t);
  fmpz_poly_set(t, c);
  fmpq_poly_t tq; fmpq_poly_init(tq); // == 0
  fmpq_poly_set_fmpz_poly(tq, t);
  fmpq_poly_neg(tq, tq);
  dgsl_rot_mp_call_recenter_fmpq_poly(rop, self, tq, state);
  fmpz_poly_add(rop, rop, t);
  fmpq_poly_clear(tq);
  fmpz_poly_clear(t);
  return 0;
}
示例#4
0
文件: dgsl.c 项目: malb/gghlite-flint
void _dgsl_rot_mp_sqrt_sigma_2(fmpq_poly_t rop, const fmpz_poly_t g, const mpfr_t sigma,
                              const int r, const long n, const mpfr_prec_t prec, const oz_flag_t flags) {
  fmpq_poly_zero(rop);

  fmpq_t r_q2;
  fmpq_init(r_q2);
  fmpq_set_si(r_q2, r, 1);
  fmpq_mul(r_q2, r_q2, r_q2);
  fmpq_neg(r_q2, r_q2);
  fmpq_poly_set_coeff_fmpq(rop, 0, r_q2);
  fmpq_clear(r_q2);

  fmpq_poly_t g_q; fmpq_poly_init(g_q);
  fmpq_poly_set_fmpz_poly(g_q, g);

  fmpq_poly_t ng; fmpq_poly_init(ng);
  fmpq_poly_oz_invert_approx(ng, g_q, n, prec, flags);

  fmpq_poly_t ngt;
  fmpq_poly_init(ngt);
  fmpq_poly_oz_conjugate(ngt, ng, n);

  fmpq_poly_t nggt;
  fmpq_poly_init(nggt);
  fmpq_poly_oz_mul(nggt, ng, ngt, n);

  /**
     We compute sqrt(g^-T · g^-1) to use it as the starting point for
     convergence on sqrt(σ^2 · g^-T · g^-1 - r^2) below. We can compute the
     former with less precision than the latter
  */

  mpfr_t norm;
  mpfr_init2(norm, prec);
  fmpz_poly_eucl_norm_mpfr(norm, g, MPFR_RNDN);
  double p = mpfr_get_d(norm, MPFR_RNDN);

  /**
     |g^-1| ~= 1/|g|
     |g^-T| ~= |g^-1|
     |g^-1·g^-T| ~= sqrt(n)·|g^-T|·|g^-1|
  */
  fmpq_poly_t sqrt_start; fmpq_poly_init(sqrt_start);
  p = log2(n) + 4*log2(p);
  int fail = -1;
  while (fail) {
    p = 2*p;
    if (fail<0)
      fail = fmpq_poly_oz_sqrt_approx_db(sqrt_start, nggt, n, p, prec/2, flags, NULL);
    else
      fail = fmpq_poly_oz_sqrt_approx_db(sqrt_start, nggt, n, p, prec/2, flags, sqrt_start);
    if(fail)
      fprintf(stderr, "FAILED for precision %7.1f with code (%d), doubling precision.\n", p, fail);
  }

  fmpq_t sigma2;
  fmpq_init(sigma2);
  fmpq_set_mpfr(sigma2, sigma, MPFR_RNDN);
  fmpq_poly_scalar_mul_fmpq(sqrt_start, sqrt_start, sigma2);

  fmpq_mul(sigma2, sigma2, sigma2);
  fmpq_poly_scalar_mul_fmpq(nggt, nggt, sigma2);
  fmpq_clear(sigma2);

  fmpq_poly_add(rop, rop, nggt);

  p = p + 2*log2(mpfr_get_d(sigma, MPFR_RNDN));

  fmpq_poly_oz_sqrt_approx_babylonian(rop, rop, n, p, prec, flags, sqrt_start);

  mpfr_clear(norm);
  fmpq_poly_clear(g_q);
  fmpq_poly_clear(ng);
  fmpq_poly_clear(ngt);
  fmpq_poly_clear(nggt);
  fmpq_poly_clear(sqrt_start);
}
示例#5
0
文件: dgsl.c 项目: malb/gghlite-flint
dgsl_rot_mp_t *dgsl_rot_mp_init(const long n, const fmpz_poly_t B, mpfr_t sigma, fmpq_poly_t c, const dgsl_alg_t algorithm, const oz_flag_t flags) {
  assert(mpfr_cmp_ui(sigma, 0) > 0);

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

  dgsl_alg_t alg = algorithm;

  self->n = n;

  self->prec = mpfr_get_prec(sigma);

  fmpz_poly_init(self->B);
  fmpz_poly_set(self->B, B);
  if(fmpz_poly_length(self->B) > n)
    dgs_die("polynomial is longer than length n");
  else
    fmpz_poly_realloc(self->B, n);


  fmpz_poly_init(self->c_z);
  fmpq_poly_init(self->c);

  mpfr_init2(self->sigma, self->prec);
  mpfr_set(self->sigma, sigma, MPFR_RNDN);

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

  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_t c_;
    mpfr_init2(c_, self->prec);
    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_rot_mp_call_identity;
    mpfr_clear(c_);
    break;
  }
  case DGSL_GPV_INLATTICE: {
    self->D = (dgs_disc_gauss_mp_t**)calloc(n, sizeof(dgs_disc_gauss_mp_t*));

    if (c && !fmpq_poly_is_zero(c)) {
      fmpq_t c_i;
      fmpq_init(c_i);
      for(int i=0; i<n; i++) {
        fmpq_poly_get_coeff_fmpq(c_i, c, i);
        fmpz_poly_set_coeff_fmpz(self->c_z, i, fmpq_numref(c_i));
      }
      fmpq_clear(c_i);
    }
    mpfr_mat_t G;
    mpfr_mat_init(G, n, n, self->prec);
    mpfr_mat_set_fmpz_poly(G, B);
    mpfr_mat_gso(G, MPFR_RNDN);

    mpfr_t sigma_;
    mpfr_init2(sigma_, self->prec);

    mpfr_t norm;
    mpfr_init2(norm, self->prec);

    mpfr_t c_;
    mpfr_init2(c_, self->prec);
    mpfr_set_d(c_, 0.0, MPFR_RNDN);

    for(long i=0; i<n; 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_clear(c_);
    mpfr_mat_clear(G);

    self->call = dgsl_rot_mp_call_gpv_inlattice;
    break;
  }
  case DGSL_INLATTICE: {
    fmpq_poly_init(self->sigma_sqrt);
    long r= 2*ceil(sqrt(log(n)));

    fmpq_poly_t Bq;    fmpq_poly_init(Bq);
    fmpq_poly_set_fmpz_poly(Bq, self->B);
    fmpq_poly_oz_invert_approx(self->B_inv, Bq, n, self->prec, flags);
    fmpq_poly_clear(Bq);

    _dgsl_rot_mp_sqrt_sigma_2(self->sigma_sqrt, self->B, sigma, r, n, self->prec, flags);

    mpfr_init2(self->r_f, self->prec);
    mpfr_set_ui(self->r_f, r, MPFR_RNDN);

    self->call = dgsl_rot_mp_call_inlattice;
    break;
  }
  case DGSL_COSET:
    dgs_die("not implemented");

  default:
    dgs_die("not implemented");
  }


  return self;
}