std::vector<mpz_class> renf_elem_class::num_vector() const noexcept { mpz_class x; std::vector<mpz_class> res; if (nf == nullptr) { fmpz_get_mpz(x.__get_mp(), fmpq_numref(b)); res.push_back(x); } else { fmpq_poly_t f; fmpq_poly_init(f); nf_elem_get_fmpq_poly(f, a->elem, nf->renf_t()->nf); for (size_t i = 0; i < fmpq_poly_length(f); i++) { fmpz_get_mpz(x.__get_mp(), fmpq_poly_numref(f) + i); res.push_back(x); } size_t deg = fmpq_poly_degree(nf->renf_t()->nf->pol); for (size_t i = fmpq_poly_length(f); i < deg; i++) res.push_back(mpz_class(0)); fmpq_poly_clear(f); } return res; }
int main(int argc, char* argv[]) { int i, j, k; int levels[argc-1]; fmpq_poly_t Pn, Ep; long deg; char *strf; acb_ptr nodes; acb_ptr weights; int solvable; int validate_extension, validate_weights; int valid; int comp_nodes, comp_weights; int target_prec; int nrprintdigits; int loglevel; if(argc <= 1) { printf("Compute a nested generalized Kronrod extension of a Gauss rule\n"); printf("Syntax: kes [-ve] [-vw] [-cn] [-cw] [-dc D] [-dp D] [-l L] n p1 p2 ... pk\n"); printf("Options:\n"); printf(" -ve Validate the polynomial extension by nodes\n"); printf(" -vw Validate the polynomial extension by weights\n"); printf(" -cn Compute the nodes\n"); printf(" -cw Compute the weights\n"); printf(" -dc Compute nodes and weights up to this number of decimal digits\n"); printf(" -dp Print this number of decimal digits\n"); printf(" -l Set the log level\n"); return EXIT_FAILURE; } target_prec = 53; nrprintdigits = 20; loglevel = 8; comp_nodes = 0; comp_weights = 0; validate_extension = 0; validate_weights = 0; k = 0; for(i = 1; i < argc; i++) { if (!strcmp(argv[i], "-ve")) { validate_extension = 1; } else if (!strcmp(argv[i], "-vw")) { validate_weights = 1; } else if (!strcmp(argv[i], "-cn")) { comp_nodes = 1; } else if (!strcmp(argv[i], "-cw")) { comp_weights = 1; } else if (!strcmp(argv[i], "-dc")) { /* 'digits' is in base 10 and log(10)/log(2) = 3.32193 */ target_prec = 3.32193 * atoi(argv[i+1]); i++; } else if (!strcmp(argv[i], "-dp")) { nrprintdigits = atoi(argv[i+1]); i++; } else if (!strcmp(argv[i], "-l")) { loglevel = atoi(argv[i+1]); i++; } else { levels[k] = atoi(argv[i]); k++; } } /* Compute extension */ fmpq_poly_init(Pn); polynomial(Pn, levels[0]); printf("Starting with polynomial:\n"); strf = fmpq_poly_get_str_pretty(Pn, "t"); flint_printf("P : %s\n", strf); printf("Extension levels are:"); for(i = 0; i < k; i++) { printf(" %i", levels[i]); } printf("\n"); fmpq_poly_init(Ep); solvable = find_multi_extension(Ep, Pn, k, levels, validate_extension, loglevel); fmpq_poly_mul(Pn, Pn, Ep); fmpq_poly_canonicalise(Pn); if(solvable) { if(! fmpq_poly_is_squarefree(Pn)) { printf("=====> FINAL POLYNOMIAL NOT SQF <====="); } if(loglevel >= 2) { printf("-------------------------------------------------\n"); printf("Ending with final polynomial:\n"); strf = fmpq_poly_get_str_pretty(Pn, "t"); flint_printf("P : %s\n", strf); } deg = fmpq_poly_degree(Pn); nodes = _acb_vec_init(deg); weights = _acb_vec_init(deg); if(comp_weights || validate_weights) { compute_nodes_and_weights(nodes, weights, Pn, target_prec, loglevel); } else if(comp_nodes) { compute_nodes(nodes, Pn, target_prec, loglevel); } valid = 1; if(validate_weights) { valid = validate_extension_by_weights(weights, deg, target_prec, loglevel); } if(! valid) { printf("**************************************\n"); printf("*** EXTENSION WITH INVALID WEIGHTS ***\n"); printf("**************************************\n"); } /* Print roots and weights */ if((validate_weights && valid) || ! validate_weights) { if(comp_nodes) { printf("-------------------------------------------------\n"); printf("The nodes are:\n"); for(j = 0; j < deg; j++) { printf("| "); acb_printd(nodes + j, nrprintdigits); printf("\n"); } } if(comp_weights) { printf("-------------------------------------------------\n"); printf("The weights are:\n"); for(j = 0; j < deg; j++) { printf("| "); acb_printd(weights + j, nrprintdigits); printf("\n"); } } } _acb_vec_clear(nodes, deg); _acb_vec_clear(weights, deg); } flint_free(strf); fmpq_poly_clear(Pn); fmpq_poly_clear(Ep); return EXIT_SUCCESS; }
void nf_elem_rep_mat_fmpz_mat_den(fmpz_mat_t res, fmpz_t den, const nf_elem_t a, const nf_t nf) { if (nf->flag & NF_LINEAR) { fmpz_set(fmpz_mat_entry(res, 0, 0), LNF_ELEM_NUMREF(a)); fmpz_set(den, LNF_ELEM_DENREF(a)); } else if (nf->flag & NF_QUADRATIC) { nf_elem_t t; const fmpz * const anum = QNF_ELEM_NUMREF(a); const fmpz * const aden = QNF_ELEM_DENREF(a); fmpz * const tnum = QNF_ELEM_NUMREF(t); fmpz * const tden = QNF_ELEM_DENREF(t); nf_elem_init(t, nf); nf_elem_mul_gen(t, a, nf); if (fmpz_equal(tden, aden)) { fmpz_set(fmpz_mat_entry(res, 0, 0), anum); fmpz_set(fmpz_mat_entry(res, 0, 1), anum + 1); fmpz_set(fmpz_mat_entry(res, 1, 0), tnum); fmpz_set(fmpz_mat_entry(res, 1, 1), tnum + 1); fmpz_set(den, tden); } else { fmpz_lcm(den, tden, aden); fmpz_divexact(fmpz_mat_entry(res, 0, 0), den, aden); fmpz_mul(fmpz_mat_entry(res, 0, 1), anum + 1, fmpz_mat_entry(res, 0, 0)); fmpz_mul(fmpz_mat_entry(res, 0, 0), anum, fmpz_mat_entry(res, 0, 0)); fmpz_divexact(fmpz_mat_entry(res, 1, 0), den, tden); fmpz_mul(fmpz_mat_entry(res, 1, 1), tnum + 1, fmpz_mat_entry(res, 1, 0)); fmpz_mul(fmpz_mat_entry(res, 1, 0), tnum, fmpz_mat_entry(res, 1, 0)); } nf_elem_clear(t, nf); } else { slong i, j; nf_elem_t t; slong d = fmpq_poly_degree(nf->pol); nf_elem_init(t, nf); nf_elem_set(t, a, nf); if (NF_ELEM(a)->length == 0) { fmpz_mat_zero(res); fmpz_one(den); } else if (NF_ELEM(a)->length == 1) { fmpz_mat_zero(res); for (i = 0; i <= d - 1; i++) { fmpz_set(fmpz_mat_entry(res, i, i), fmpq_poly_numref(NF_ELEM(a))); } fmpz_set(den, fmpq_poly_denref(NF_ELEM(a))); } else { /* Special case if defining polynomial is monic and integral and the element also has trivial denominator */ if (nf->flag & NF_MONIC && fmpz_is_one(fmpq_poly_denref(nf->pol)) && fmpz_is_one(fmpq_poly_denref(NF_ELEM(a)))) { fmpz_one(den); for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, 0, i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, 0, i)); for (j = 1; j <= d - NF_ELEM(a)->length; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i < j; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, j, j + i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = j + NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); } for (j = d - NF_ELEM(a)->length + 1; j <= d - 1; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i <= d - 1; i++) fmpz_set(fmpz_mat_entry(res, j, i), fmpq_poly_numref(NF_ELEM(t)) + i); } } else { /* Now the general case. For 0 <= j < d - 2 we store the * denominator for row j at res[d - 1, j]. At the end we * divide the lcm of all of them by the corresponding * denominator of the row to get the correct multiplier for * row. */ for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, 0, i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, 0, i)); fmpz_set(fmpz_mat_entry(res, d - 1, 0), fmpq_poly_denref(NF_ELEM(a))); for (j = 1; j <= d - NF_ELEM(a)->length; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i < j; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); for (i = 0; i <= NF_ELEM(a)->length - 1; i++) fmpz_set(fmpz_mat_entry(res, j, j + i), fmpq_poly_numref(NF_ELEM(a)) + i); for (i = j + NF_ELEM(a)->length; i <= d - 1; i++) fmpz_zero(fmpz_mat_entry(res, j, i)); fmpz_set(fmpz_mat_entry(res, d - 1, j), fmpq_poly_denref(NF_ELEM(a))); } for (j = d - NF_ELEM(a)->length + 1; j <= d - 2; j++) { nf_elem_mul_gen(t, t, nf); for (i = 0; i <= d - 1; i++) fmpz_set(fmpz_mat_entry(res, j, i), fmpq_poly_numref(NF_ELEM(t)) + i); fmpz_set(fmpz_mat_entry(res, d - 1, j), fmpq_poly_denref(NF_ELEM(t))); } nf_elem_mul_gen(t, t, nf); /* Now compute the correct denominator */ fmpz_set(fmpz_mat_entry(res, d - 1, d - 1), fmpq_poly_denref(NF_ELEM(t))); fmpz_set(den, fmpq_poly_denref(NF_ELEM(t))); for (j = 0; j <= d - 2; j++) fmpz_lcm(den, den, fmpz_mat_entry(res, d - 1, j)); for (j = 0; j <= d - 2; j++) { if (!fmpz_equal(den, fmpz_mat_entry(res, d - 1, j))) { fmpz_divexact(fmpz_mat_entry(res, d - 1, j), den, fmpz_mat_entry(res, d - 1, j)); for (i = 0; i <= d - 1; i++) fmpz_mul(fmpz_mat_entry(res, j, i), fmpz_mat_entry(res, j, i), fmpz_mat_entry(res, d - 1, j)); } } if (fmpz_equal(den, fmpz_mat_entry(res, d - 1, d - 1))) { for (i = 0; i < d; i++) fmpz_set(fmpz_mat_entry(res, d - 1, i), fmpq_poly_numref(NF_ELEM(t)) + i); } else { fmpz_divexact(fmpz_mat_entry(res, d - 1, d - 1), den, fmpq_poly_denref(NF_ELEM(t))); for (i = 0; i < d; i++) fmpz_mul(fmpz_mat_entry(res, d - 1, i), fmpq_poly_numref(NF_ELEM(t)) + i, fmpz_mat_entry(res, d - 1, d - 1)); } } } nf_elem_clear(t, nf); } }