Esempio n. 1
0
void fmpq_poly_set_coeff_mpq(fmpq_poly_t poly, slong n, const mpq_t x)
{
    fmpq_t f;

    fmpq_init_set_readonly(f, x);
    fmpq_poly_set_coeff_fmpq(poly, n, f);
    fmpq_clear_readonly(f);
}
Esempio n. 2
0
void test_field1(flint_rand_t state)
{
    /* tests in QQ[sqrt(5)] */
    int iter;

    fmpq_t k;
    fmpq_poly_t p;
    arb_t emb;
    renf_t nf;
    renf_elem_t a;

    fmpq_poly_init(p);
    fmpq_poly_set_coeff_si(p, 2, 1);
    fmpq_poly_set_coeff_si(p, 1, -1);
    fmpq_poly_set_coeff_si(p, 0, -1);

    arb_init(emb);
    arb_set_d(emb, 1.61803398874989);
    arb_add_error_2exp_si(emb, -20);
    renf_init(nf, p, emb, 20 + n_randint(state, 20));
    arb_clear(emb);

    renf_elem_init(a, nf);
    fmpq_init(k);

    /* (1+sqrt(5))/2 vs Fibonacci */
    fmpq_poly_zero(p);
    fmpq_poly_set_coeff_si(p, 1, -1);
    for (iter = 1; iter < 50; iter++)
    {
        fprintf(stderr, "start iter = %d\n", iter);
        fflush(stderr);
        fmpz_fib_ui(fmpq_numref(k), iter+1);
        fmpz_fib_ui(fmpq_denref(k), iter);
        fmpq_poly_set_coeff_fmpq(p, 0, k);
        renf_elem_set_fmpq_poly(a, p, nf);
        check_ceil(a, nf, 1 - iter % 2, "sqrt(5)");
        fprintf(stderr, "end\n");
        fflush(stderr);
    }

    renf_elem_clear(a, nf);
    renf_clear(nf);
    fmpq_clear(k);
    fmpq_poly_clear(p);
}
Esempio n. 3
0
void gmde_convert_soln_fmpq(mat_t A, const ctx_t ctxA, 
                            const fmpq_mat_struct *C, long N)
{
    long i, j, k;

    assert(N > 0);
    assert(A->m == C->r && A->n == C->c);

    for (i = 0; i < A->m; i++)
        for (j = 0; j < A->n; j++)
        {
            ctxA->zero(ctxA, mat_entry(A, i, j, ctxA));

            for (k = N - 1; k >= 0; k--)
            {
                if (!fmpq_is_zero(fmpq_mat_entry(C + k, i, j)))
                {
                    fmpq_poly_set_coeff_fmpq(
                        (fmpq_poly_struct *) mat_entry(A, i, j, ctxA), 
                        k, fmpq_mat_entry(C + k, i, j));
                }
            }
        }
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
void test_field2(flint_rand_t state)
{
    /* test in QQ[3^(1/4)] */
    renf_t nf;
    renf_elem_t a;
    fmpq_t d, k;
    fmpq_poly_t p;

    fmpq_init(d);
    fmpq_poly_init(p);

    fmpq_set_si(d, 3, 1);
    renf_init_nth_root_fmpq(nf, d, 4, 10 + n_randint(state, 10));

    fmpq_clear(d);

    fmpq_init(k);
    renf_elem_init(a, nf);

    /* test rationals */

    /* --> 3^(1/4)  */
    fmpq_poly_set_coeff_si(p, 1, 1);
    renf_elem_set_fmpq_poly(a, p, nf);

    check_ceil(a, nf, 2, "3^(1/4)");

    /* --> 3^(1/4) - p_34 / q_34 */
    /*     ceil = 1              */
    fmpz_set_str(fmpq_numref(k), "3871793620206447926", 10);
    fmpz_set_str(fmpq_denref(k), "2941926960111028069", 10);
    fmpq_neg(k, k);
    fmpq_poly_set_coeff_fmpq(p, 0, k);
    renf_elem_set_fmpq_poly(a, p, nf);

    check_ceil(a, nf, 1, "3^(1/4)");

    /* --> 3^(1/4) - p_35 / q_35 */
    /*     ceil = 0              */
    fmpz_set_str(fmpq_numref(k), "4393442218385055959", 10);
    fmpz_set_str(fmpq_denref(k), "3338294180377262795", 10);
    fmpq_neg(k, k);
    fmpq_poly_set_coeff_fmpq(p, 0, k);
    renf_elem_set_fmpq_poly(a, p, nf);

    check_ceil(a, nf, 0, "3^(1/4)");

    /* --> 3^(1/4) - p_200 / q_200 */
    fmpz_set_str(fmpq_numref(k), "51566086581654990699052199424489069476470199719930170996263916596162993841059250500042162091", 10);
    fmpz_set_str(fmpq_denref(k), "39181752754141206003124111890355840072199542360218864430892618765033598468868752146602163065", 10);
    fmpq_neg(k, k);
    fmpq_poly_set_coeff_fmpq(p, 0, k);
    renf_elem_set_fmpq_poly(a, p, nf);

    check_ceil(a, nf, 1, "3^(1/4)");

    /* --> 3^(1/4) - p_201 / q_201 */
    fmpz_set_str(fmpq_numref(k), "80796322887694335717970676356641716096406222234122724217891106756946083353628876437327250032", 10);
    fmpz_set_str(fmpq_denref(k), "61391929399498685496270115285641595325756438975454257165479021482386018841773493669624721869", 10);
    fmpq_neg(k, k);
    fmpq_poly_set_coeff_fmpq(p, 0, k);
    renf_elem_set_fmpq_poly(a, p, nf);

    check_ceil(a, nf, 0, "3^(1/4)");

    /* */
    fmpz_set_str(fmpq_numref(k), "13231942875843754343234", 10);
    fmpz_set_str(fmpq_denref(k), "14321431341231112121", 10);
    fmpq_poly_set_coeff_fmpq(p, 3, k);
    fmpz_set_str(fmpq_numref(k), "148589873455543948591", 10);
    fmpz_set_str(fmpq_denref(k), "12332111221111", 10);
    fmpq_neg(k, k);
    fmpq_poly_set_coeff_fmpq(p, 2, k);
    fmpz_set_str(fmpq_numref(k), "1233321469998711012392391", 10);
    fmpz_set_str(fmpq_denref(k), "11814121556810191", 10);
    fmpq_poly_set_coeff_fmpq(p, 1, k);
    fmpz_set_str(fmpq_numref(k), "1249152314425433983202991363672458443993964487436329478959287771807457205881969983777233465754608376177969464841", 10);
    fmpz_set_str(fmpq_denref(k), "10720278662399817731713810382544982753044312944075797382817281426908463944866446042500978893159281330135", 10);
    fmpq_neg(k, k);
    fmpq_poly_set_coeff_fmpq(p, 0, k);
    renf_elem_set_fmpq_poly(a, p, nf);

    check_ceil(a, nf, 231, "3^(1/4)");

    renf_elem_clear(a, nf);
    renf_clear(nf);
    fmpq_clear(k);
    fmpq_poly_clear(p);
}
Esempio n. 6
0
int fmpq_poly_oz_sqrt_approx_pade(fmpq_poly_t f_sqrt, const fmpq_poly_t f, const long n, const int p, const mpfr_prec_t prec, const mpfr_prec_t bound, oz_flag_t flags, const fmpq_poly_t init) {
  fmpq_poly_t y;       fmpq_poly_init(y);
  fmpq_poly_t y_next;  fmpq_poly_init(y_next);
  fmpq_poly_t z;       fmpq_poly_init(z);
  fmpq_poly_t z_next;  fmpq_poly_init(z_next);

  mpfr_t norm;      mpfr_init2(norm, prec);
  mpfr_t prev_norm; mpfr_init2(prev_norm, prec);
  mpfr_t log_f;     mpfr_init2(log_f, prec);

  if (init) {
    // z = y/x
    fmpq_poly_set(y, init);
    _fmpq_poly_oz_invert_approx(z, f, n, prec);
    fmpq_poly_oz_mul(z, z, y, n);
  } else {
    fmpq_poly_set(y, f);
    fmpq_poly_set_coeff_si(z, 0, 1);
  }

  fmpq_t *xi = (fmpq_t*)calloc(p, sizeof(fmpq_t));
  fmpq_t *a2 = (fmpq_t*)calloc(p, sizeof(fmpq_t));
  fmpq_t *c  = (fmpq_t*)calloc(p, sizeof(fmpq_t));
  fmpq_poly_t *t_ = (fmpq_poly_t*)calloc(p, sizeof(fmpq_poly_t));
  fmpq_poly_t *s_ = (fmpq_poly_t*)calloc(p, sizeof(fmpq_poly_t));

  mpfr_t pi;  mpfr_init2(pi, 4*prec);
  mpfr_const_pi(pi, MPFR_RNDN);

#pragma omp parallel for
  for(int i=0; i<p; i++) {
    mpfr_t xi_r; mpfr_init2(xi_r, 4*prec);
    mpfr_t a2_r; mpfr_init2(a2_r, 4*prec);

    /*  ζ_i = 1/2 * (1 + cos( (2·i -1)·π/(2·p) )) */
    mpfr_set_si(xi_r, 2*i+1, MPFR_RNDN);
    mpfr_mul(xi_r, xi_r, pi, MPFR_RNDN);
    mpfr_div_si(xi_r, xi_r, 2*p, MPFR_RNDN);
    mpfr_cos(xi_r, xi_r, MPFR_RNDN);
    mpfr_add_si(xi_r, xi_r, 1, MPFR_RNDN);
    mpfr_div_si(xi_r, xi_r, 2, MPFR_RNDN);

    /* α_i^2 = 1/ζ_i -1 */
    mpfr_set_si(a2_r, 1, MPFR_RNDN);
    mpfr_div(a2_r, a2_r, xi_r, MPFR_RNDN);
    mpfr_sub_si(a2_r, a2_r, 1, MPFR_RNDN);

    fmpq_init(xi[i]);
    fmpq_init(a2[i]);
    fmpq_set_mpfr(xi[i], xi_r, MPFR_RNDN);
    fmpq_set_mpfr(a2[i], a2_r, MPFR_RNDN);

    fmpq_init(c[i]);
    fmpq_poly_init(t_[i]);
    fmpq_poly_init(s_[i]);

    mpfr_clear(xi_r);
    mpfr_clear(a2_r);
  }

  mpfr_clear(pi);

  uint64_t t = oz_walltime(0);

  int r = 0;
  int cont = 1;
  for(long  k=0; cont; k++) {
    if (k == 0 || mpfr_cmp_ui(prev_norm, 1) > 0)
      _fmpq_poly_oz_sqrt_approx_scale(y, z, n, prec);

    /*   T = sum([1/xi[i] * ~(Z*Y + a2[i]) for i in range(p)]) */
#pragma omp parallel for
  for(int i=0; i<p; i++) {
    fmpq_poly_oz_mul(t_[i], z, y, n);
    fmpq_poly_get_coeff_fmpq(c[i], t_[i], 0);
    fmpq_add(c[i], c[i], a2[i]);
    fmpq_poly_set_coeff_fmpq(t_[i], 0, c[i]);
    fmpq_poly_scalar_mul_fmpq(t_[i], t_[i], xi[i]);
    _fmpq_poly_oz_invert_approx(s_[i], t_[i], n, prec);
  }

  for(int i=1; i<p; i++)
    fmpq_poly_add(s_[0],   s_[0], s_[i]);

#pragma omp parallel sections
    {
#pragma omp section
      {
        fmpq_poly_oz_mul(y_next, y, s_[0], n);
        fmpq_poly_scalar_div_si(y_next, y_next, p);
        fmpq_poly_set(y, y_next);
      }
#pragma omp section
      {
        fmpq_poly_oz_mul(z_next, z, s_[0], n);
        fmpq_poly_scalar_div_si(z_next, z_next, p);
        fmpq_poly_set(z, z_next);
      }
    }
    cont = !_fmpq_poly_oz_sqrt_approx_break(norm, y, f, n, bound, prec);

    if(flags & OZ_VERBOSE) {
      mpfr_log2(log_f, norm, MPFR_RNDN);
      mpfr_fprintf(stderr, "Computing sqrt(Σ)::  k: %4d,  Δ=|sqrt(Σ)^2-Σ|: %7.2Rf", k, log_f);
      fprintf(stderr, " <? %4ld, ", -bound);
      fprintf(stderr, "t: %8.2fs\n", oz_seconds(oz_walltime(t)));
      fflush(0);
    }

    if (cont) {
      if (k>0 && mpfr_cmp_ui_2exp(norm, 1, bound) >= 0) {
        /* something went really wrong */
        r = -1;
        break;
      }
      if (k>0 && mpfr_cmp(norm, prev_norm) >= 0) {
        /*  we don't converge any more */
        r = 1;
        break;
      }
      mpfr_set(prev_norm, norm, MPFR_RNDN);
    }
  }

  for(int i=0; i<p; i++) {
    fmpq_clear(xi[i]);
    fmpq_clear(a2[i]);
    fmpq_clear(c[i]);
    fmpq_poly_clear(t_[i]);
    fmpq_poly_clear(s_[i]);
  }
  free(xi);
  free(a2);
  free(c);
  free(t_);
  free(s_);

  mpfr_clear(log_f);
  fmpq_poly_set(f_sqrt, y);
  mpfr_clear(norm);
  mpfr_clear(prev_norm);
  fmpq_poly_clear(y_next);
  fmpq_poly_clear(y);
  fmpq_poly_clear(z_next);
  fmpq_poly_clear(z);
  return r;
}