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); }
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); }
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)); } } } }
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); }
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); }
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; }