passagemath-flint 10.6.1rc10__cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
- passagemath_flint-10.6.1rc10.dist-info/RECORD +361 -0
- passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
- passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
- passagemath_flint.libs/libflint-aecb9cc5.so.21.0.0 +0 -0
- passagemath_flint.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
- passagemath_flint.libs/libgfortran-8f1e9814.so.5.0.0 +0 -0
- passagemath_flint.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_flint.libs/libgsl-cda90e79.so.28.0.0 +0 -0
- passagemath_flint.libs/libmpfi-e3c25853.so.0.0.0 +0 -0
- passagemath_flint.libs/libmpfr-82690d50.so.6.2.1 +0 -0
- passagemath_flint.libs/libntl-74e7d9a3.so.44.0.1 +0 -0
- passagemath_flint.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_flint.libs/libquadmath-828275a7.so.0.0.0 +0 -0
- sage/all__sagemath_flint.py +29 -0
- sage/combinat/all__sagemath_flint.py +1 -0
- sage/combinat/posets/all__sagemath_flint.py +1 -0
- sage/combinat/posets/hasse_cython_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython_flint.pyx +194 -0
- sage/data_structures/all__sagemath_flint.py +1 -0
- sage/data_structures/bounded_integer_sequences.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/data_structures/bounded_integer_sequences.pxd +62 -0
- sage/data_structures/bounded_integer_sequences.pyx +1418 -0
- sage/graphs/all__sagemath_flint.py +1 -0
- sage/graphs/chrompoly.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/graphs/matchpoly.pyx +412 -0
- sage/libs/all__sagemath_flint.py +17 -0
- sage/libs/arb/__init__.py +1 -0
- sage/libs/arb/acb.pxd +154 -0
- sage/libs/arb/acb_calc.pxd +9 -0
- sage/libs/arb/acb_elliptic.pxd +25 -0
- sage/libs/arb/acb_hypgeom.pxd +74 -0
- sage/libs/arb/acb_mat.pxd +62 -0
- sage/libs/arb/acb_modular.pxd +17 -0
- sage/libs/arb/acb_poly.pxd +216 -0
- sage/libs/arb/arb.pxd +240 -0
- sage/libs/arb/arb_fmpz_poly.pxd +21 -0
- sage/libs/arb/arb_hypgeom.pxd +83 -0
- sage/libs/arb/arb_wrap.h +34 -0
- sage/libs/arb/arf.pxd +131 -0
- sage/libs/arb/arith.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/arb/arith.pyx +87 -0
- sage/libs/arb/bernoulli.pxd +6 -0
- sage/libs/arb/mag.pxd +77 -0
- sage/libs/arb/types.pxd +37 -0
- sage/libs/flint/__init__.py +1 -0
- sage/libs/flint/acb.pxd +270 -0
- sage/libs/flint/acb_calc.pxd +22 -0
- sage/libs/flint/acb_dft.pxd +51 -0
- sage/libs/flint/acb_dirichlet.pxd +112 -0
- sage/libs/flint/acb_elliptic.pxd +42 -0
- sage/libs/flint/acb_hypgeom.pxd +169 -0
- sage/libs/flint/acb_macros.pxd +9 -0
- sage/libs/flint/acb_mat.pxd +136 -0
- sage/libs/flint/acb_mat_macros.pxd +10 -0
- sage/libs/flint/acb_modular.pxd +62 -0
- sage/libs/flint/acb_poly.pxd +251 -0
- sage/libs/flint/acb_poly_macros.pxd +8 -0
- sage/libs/flint/acb_theta.pxd +124 -0
- sage/libs/flint/acf.pxd +32 -0
- sage/libs/flint/aprcl.pxd +84 -0
- sage/libs/flint/arb.pxd +382 -0
- sage/libs/flint/arb_calc.pxd +31 -0
- sage/libs/flint/arb_fmpz_poly.pxd +34 -0
- sage/libs/flint/arb_fpwrap.pxd +215 -0
- sage/libs/flint/arb_hypgeom.pxd +147 -0
- sage/libs/flint/arb_macros.pxd +9 -0
- sage/libs/flint/arb_mat.pxd +140 -0
- sage/libs/flint/arb_mat_macros.pxd +10 -0
- sage/libs/flint/arb_poly.pxd +237 -0
- sage/libs/flint/arf.pxd +167 -0
- sage/libs/flint/arith.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/arith.pxd +76 -0
- sage/libs/flint/arith.pyx +77 -0
- sage/libs/flint/arith_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/arith_sage.pyx +308 -0
- sage/libs/flint/bernoulli.pxd +28 -0
- sage/libs/flint/bool_mat.pxd +52 -0
- sage/libs/flint/ca.pxd +203 -0
- sage/libs/flint/ca_ext.pxd +34 -0
- sage/libs/flint/ca_field.pxd +32 -0
- sage/libs/flint/ca_mat.pxd +117 -0
- sage/libs/flint/ca_poly.pxd +104 -0
- sage/libs/flint/ca_vec.pxd +46 -0
- sage/libs/flint/calcium.pxd +27 -0
- sage/libs/flint/d_mat.pxd +39 -0
- sage/libs/flint/d_vec.pxd +32 -0
- sage/libs/flint/dirichlet.pxd +57 -0
- sage/libs/flint/dlog.pxd +53 -0
- sage/libs/flint/double_extras.pxd +24 -0
- sage/libs/flint/double_interval.pxd +36 -0
- sage/libs/flint/fexpr.pxd +104 -0
- sage/libs/flint/fexpr_builtin.pxd +20 -0
- sage/libs/flint/fft.pxd +66 -0
- sage/libs/flint/flint.pxd +36 -0
- sage/libs/flint/flint_ntl_wrap.h +35 -0
- sage/libs/flint/flint_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/flint_sage.pyx +163 -0
- sage/libs/flint/flint_wrap.h +190 -0
- sage/libs/flint/fmpq.pxd +137 -0
- sage/libs/flint/fmpq_mat.pxd +105 -0
- sage/libs/flint/fmpq_mat_macros.pxd +10 -0
- sage/libs/flint/fmpq_mpoly.pxd +165 -0
- sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
- sage/libs/flint/fmpq_poly.pxd +241 -0
- sage/libs/flint/fmpq_poly_macros.pxd +9 -0
- sage/libs/flint/fmpq_poly_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpq_poly_sage.pxd +31 -0
- sage/libs/flint/fmpq_poly_sage.pyx +48 -0
- sage/libs/flint/fmpq_vec.pxd +27 -0
- sage/libs/flint/fmpz.pxd +256 -0
- sage/libs/flint/fmpz_extras.pxd +32 -0
- sage/libs/flint/fmpz_factor.pxd +42 -0
- sage/libs/flint/fmpz_factor_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_factor_sage.pxd +4 -0
- sage/libs/flint/fmpz_factor_sage.pyx +29 -0
- sage/libs/flint/fmpz_lll.pxd +49 -0
- sage/libs/flint/fmpz_macros.pxd +8 -0
- sage/libs/flint/fmpz_mat.pxd +184 -0
- sage/libs/flint/fmpz_mat_macros.pxd +10 -0
- sage/libs/flint/fmpz_mod.pxd +46 -0
- sage/libs/flint/fmpz_mod_mat.pxd +71 -0
- sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
- sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fmpz_mod_poly.pxd +249 -0
- sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
- sage/libs/flint/fmpz_mod_vec.pxd +27 -0
- sage/libs/flint/fmpz_mpoly.pxd +224 -0
- sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
- sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
- sage/libs/flint/fmpz_poly.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly.pxd +407 -0
- sage/libs/flint/fmpz_poly.pyx +19 -0
- sage/libs/flint/fmpz_poly_factor.pxd +33 -0
- sage/libs/flint/fmpz_poly_macros.pxd +8 -0
- sage/libs/flint/fmpz_poly_mat.pxd +71 -0
- sage/libs/flint/fmpz_poly_q.pxd +55 -0
- sage/libs/flint/fmpz_poly_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly_sage.pxd +20 -0
- sage/libs/flint/fmpz_poly_sage.pyx +500 -0
- sage/libs/flint/fmpz_vec.pxd +80 -0
- sage/libs/flint/fmpzi.pxd +52 -0
- sage/libs/flint/fq.pxd +97 -0
- sage/libs/flint/fq_default.pxd +84 -0
- sage/libs/flint/fq_default_mat.pxd +70 -0
- sage/libs/flint/fq_default_poly.pxd +97 -0
- sage/libs/flint/fq_default_poly_factor.pxd +39 -0
- sage/libs/flint/fq_embed.pxd +28 -0
- sage/libs/flint/fq_mat.pxd +83 -0
- sage/libs/flint/fq_nmod.pxd +95 -0
- sage/libs/flint/fq_nmod_embed.pxd +28 -0
- sage/libs/flint/fq_nmod_mat.pxd +83 -0
- sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
- sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fq_nmod_poly.pxd +202 -0
- sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
- sage/libs/flint/fq_nmod_vec.pxd +33 -0
- sage/libs/flint/fq_poly.pxd +204 -0
- sage/libs/flint/fq_poly_factor.pxd +47 -0
- sage/libs/flint/fq_vec.pxd +33 -0
- sage/libs/flint/fq_zech.pxd +99 -0
- sage/libs/flint/fq_zech_embed.pxd +28 -0
- sage/libs/flint/fq_zech_mat.pxd +78 -0
- sage/libs/flint/fq_zech_poly.pxd +198 -0
- sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
- sage/libs/flint/fq_zech_vec.pxd +33 -0
- sage/libs/flint/gr.pxd +174 -0
- sage/libs/flint/gr_generic.pxd +215 -0
- sage/libs/flint/gr_mat.pxd +161 -0
- sage/libs/flint/gr_mpoly.pxd +68 -0
- sage/libs/flint/gr_poly.pxd +276 -0
- sage/libs/flint/gr_special.pxd +237 -0
- sage/libs/flint/gr_vec.pxd +120 -0
- sage/libs/flint/hypgeom.pxd +24 -0
- sage/libs/flint/long_extras.pxd +23 -0
- sage/libs/flint/mag.pxd +131 -0
- sage/libs/flint/mag_macros.pxd +8 -0
- sage/libs/flint/mpf_mat.pxd +36 -0
- sage/libs/flint/mpf_vec.pxd +34 -0
- sage/libs/flint/mpfr_mat.pxd +27 -0
- sage/libs/flint/mpfr_vec.pxd +25 -0
- sage/libs/flint/mpn_extras.pxd +41 -0
- sage/libs/flint/mpoly.pxd +72 -0
- sage/libs/flint/nf.pxd +19 -0
- sage/libs/flint/nf_elem.pxd +74 -0
- sage/libs/flint/nmod.pxd +35 -0
- sage/libs/flint/nmod_mat.pxd +104 -0
- sage/libs/flint/nmod_mpoly.pxd +144 -0
- sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/nmod_poly.pxd +339 -0
- sage/libs/flint/nmod_poly_factor.pxd +44 -0
- sage/libs/flint/nmod_poly_linkage.pxi +710 -0
- sage/libs/flint/nmod_poly_mat.pxd +76 -0
- sage/libs/flint/nmod_vec.pxd +40 -0
- sage/libs/flint/ntl_interface.pxd +17 -0
- sage/libs/flint/padic.pxd +93 -0
- sage/libs/flint/padic_mat.pxd +64 -0
- sage/libs/flint/padic_poly.pxd +88 -0
- sage/libs/flint/partitions.pxd +23 -0
- sage/libs/flint/perm.pxd +26 -0
- sage/libs/flint/profiler.pxd +24 -0
- sage/libs/flint/qadic.pxd +77 -0
- sage/libs/flint/qfb.pxd +44 -0
- sage/libs/flint/qqbar.pxd +172 -0
- sage/libs/flint/qsieve.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve.pxd +41 -0
- sage/libs/flint/qsieve.pyx +21 -0
- sage/libs/flint/qsieve_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve_sage.pyx +67 -0
- sage/libs/flint/thread_pool.pxd +25 -0
- sage/libs/flint/types.pxd +2076 -0
- sage/libs/flint/ulong_extras.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras.pxd +141 -0
- sage/libs/flint/ulong_extras.pyx +21 -0
- sage/libs/flint/ulong_extras_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras_sage.pyx +21 -0
- sage/matrix/all__sagemath_flint.py +1 -0
- sage/matrix/change_ring.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_complex_ball_dense.pxd +14 -0
- sage/matrix/matrix_complex_ball_dense.pyx +973 -0
- sage/matrix/matrix_cyclo_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_cyclo_dense.pxd +16 -0
- sage/matrix/matrix_cyclo_dense.pyx +1761 -0
- sage/matrix/matrix_integer_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_dense.pxd +32 -0
- sage/matrix/matrix_integer_dense.pyx +5801 -0
- sage/matrix/matrix_integer_dense_hnf.py +1294 -0
- sage/matrix/matrix_integer_dense_saturation.py +346 -0
- sage/matrix/matrix_integer_sparse.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_sparse.pxd +9 -0
- sage/matrix/matrix_integer_sparse.pyx +1090 -0
- sage/matrix/matrix_rational_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_dense.pxd +23 -0
- sage/matrix/matrix_rational_dense.pyx +2995 -0
- sage/matrix/matrix_rational_sparse.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_sparse.pxd +11 -0
- sage/matrix/matrix_rational_sparse.pyx +789 -0
- sage/matrix/misc_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/misc_flint.pyx +109 -0
- sage/modular/all__sagemath_flint.py +1 -0
- sage/modular/modform/all__sagemath_flint.py +1 -0
- sage/modular/modform/eis_series_cython.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/modform/eis_series_cython.pyx +226 -0
- sage/modular/modsym/all__sagemath_flint.py +1 -0
- sage/modular/modsym/apply.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/modsym/apply.pxd +6 -0
- sage/modular/modsym/apply.pyx +113 -0
- sage/modular/modsym/heilbronn.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/modsym/heilbronn.pyx +966 -0
- sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
- sage/modular/pollack_stevens/dist.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/pollack_stevens/dist.pxd +38 -0
- sage/modular/pollack_stevens/dist.pyx +1439 -0
- sage/quivers/algebra.py +691 -0
- sage/quivers/algebra_elements.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/quivers/algebra_elements.pxd +97 -0
- sage/quivers/algebra_elements.pxi +1324 -0
- sage/quivers/algebra_elements.pyx +1424 -0
- sage/quivers/all.py +1 -0
- sage/quivers/ar_quiver.py +917 -0
- sage/quivers/homspace.py +640 -0
- sage/quivers/morphism.py +1282 -0
- sage/quivers/path_semigroup.py +1155 -0
- sage/quivers/paths.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/quivers/paths.pxd +13 -0
- sage/quivers/paths.pyx +809 -0
- sage/quivers/representation.py +2975 -0
- sage/rings/all__sagemath_flint.py +37 -0
- sage/rings/cif.py +4 -0
- sage/rings/complex_arb.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_arb.pxd +29 -0
- sage/rings/complex_arb.pyx +5176 -0
- sage/rings/complex_interval.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_interval.pxd +30 -0
- sage/rings/complex_interval.pyx +2475 -0
- sage/rings/complex_interval_field.py +711 -0
- sage/rings/convert/all.py +1 -0
- sage/rings/convert/mpfi.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/convert/mpfi.pxd +6 -0
- sage/rings/convert/mpfi.pyx +576 -0
- sage/rings/factorint_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/fraction_field_FpT.pxd +28 -0
- sage/rings/fraction_field_FpT.pyx +2043 -0
- sage/rings/imaginary_unit.py +5 -0
- sage/rings/monomials.py +73 -0
- sage/rings/number_field/S_unit_solver.py +2870 -0
- sage/rings/number_field/all__sagemath_flint.py +7 -0
- sage/rings/number_field/bdd_height.py +664 -0
- sage/rings/number_field/class_group.py +762 -0
- sage/rings/number_field/galois_group.py +1307 -0
- sage/rings/number_field/homset.py +612 -0
- sage/rings/number_field/maps.py +687 -0
- sage/rings/number_field/morphism.py +272 -0
- sage/rings/number_field/number_field.py +12820 -0
- sage/rings/number_field/number_field_element.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element.pxd +59 -0
- sage/rings/number_field/number_field_element.pyx +5735 -0
- sage/rings/number_field/number_field_element_quadratic.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
- sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
- sage/rings/number_field/number_field_ideal_rel.py +925 -0
- sage/rings/number_field/number_field_morphisms.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_morphisms.pyx +781 -0
- sage/rings/number_field/number_field_rel.py +2734 -0
- sage/rings/number_field/order.py +2981 -0
- sage/rings/number_field/order_ideal.py +804 -0
- sage/rings/number_field/selmer_group.py +715 -0
- sage/rings/number_field/small_primes_of_degree_one.py +242 -0
- sage/rings/number_field/splitting_field.py +606 -0
- sage/rings/number_field/structure.py +380 -0
- sage/rings/number_field/unit_group.py +721 -0
- sage/rings/padics/all__sagemath_flint.py +3 -0
- sage/rings/polynomial/all__sagemath_flint.py +1 -0
- sage/rings/polynomial/complex_roots.py +312 -0
- sage/rings/polynomial/evaluation_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/evaluation_flint.pxd +7 -0
- sage/rings/polynomial/evaluation_flint.pyx +68 -0
- sage/rings/polynomial/hilbert.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
- sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
- sage/rings/polynomial/polynomial_number_field.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
- sage/rings/polynomial/polynomial_zmod_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
- sage/rings/polynomial/real_roots.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/real_roots.pxd +81 -0
- sage/rings/polynomial/real_roots.pyx +4704 -0
- sage/rings/polynomial/refine_root.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/refine_root.pyx +142 -0
- sage/rings/polynomial/weil/all.py +4 -0
- sage/rings/polynomial/weil/power_sums.h +46 -0
- sage/rings/polynomial/weil/weil_polynomials.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
- sage/rings/qqbar.py +9025 -0
- sage/rings/real_arb.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/real_arb.pxd +21 -0
- sage/rings/real_arb.pyx +4065 -0
- sage/rings/real_interval_absolute.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/real_mpfi.pyx +5428 -0
- sage/schemes/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
- sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,606 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
# sage.doctest: needs sage.libs.pari
|
3
|
+
"""
|
4
|
+
Splitting fields of polynomials over number fields
|
5
|
+
|
6
|
+
AUTHORS:
|
7
|
+
|
8
|
+
- Jeroen Demeyer (2014-01-02): initial version for :issue:`2217`
|
9
|
+
- Jeroen Demeyer (2014-01-03): added ``abort_degree`` argument, :issue:`15626`
|
10
|
+
"""
|
11
|
+
|
12
|
+
#*****************************************************************************
|
13
|
+
# Copyright (C) 2014 Jeroen Demeyer <jdemeyer@cage.ugent.be>
|
14
|
+
#
|
15
|
+
# This program is free software: you can redistribute it and/or modify
|
16
|
+
# it under the terms of the GNU General Public License as published by
|
17
|
+
# the Free Software Foundation, either version 2 of the License, or
|
18
|
+
# (at your option) any later version.
|
19
|
+
# http://www.gnu.org/licenses/
|
20
|
+
#*****************************************************************************
|
21
|
+
|
22
|
+
from sage.rings.integer import Integer
|
23
|
+
from sage.arith.misc import factorial
|
24
|
+
from sage.rings.number_field.number_field import NumberField
|
25
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
26
|
+
from sage.rings.rational_field import RationalField
|
27
|
+
from sage.libs.pari import pari
|
28
|
+
from cypari2.handle_error import PariError
|
29
|
+
|
30
|
+
|
31
|
+
class SplittingFieldAbort(Exception):
|
32
|
+
"""
|
33
|
+
Special exception class to indicate an early abort of :func:`splitting_field`.
|
34
|
+
|
35
|
+
EXAMPLES::
|
36
|
+
|
37
|
+
sage: from sage.rings.number_field.splitting_field import SplittingFieldAbort
|
38
|
+
sage: raise SplittingFieldAbort(20, 60)
|
39
|
+
Traceback (most recent call last):
|
40
|
+
...
|
41
|
+
SplittingFieldAbort: degree of splitting field is a multiple of 20
|
42
|
+
sage: raise SplittingFieldAbort(12, 12)
|
43
|
+
Traceback (most recent call last):
|
44
|
+
...
|
45
|
+
SplittingFieldAbort: degree of splitting field equals 12
|
46
|
+
"""
|
47
|
+
def __init__(self, div, mult):
|
48
|
+
self.degree_divisor = div
|
49
|
+
self.degree_multiple = mult
|
50
|
+
if div == mult:
|
51
|
+
msg = "degree of splitting field equals %s" % div
|
52
|
+
else:
|
53
|
+
msg = "degree of splitting field is a multiple of %s" % div
|
54
|
+
super().__init__(msg)
|
55
|
+
|
56
|
+
|
57
|
+
class SplittingData:
|
58
|
+
"""
|
59
|
+
A class to store data for internal use in :func:`splitting_field`.
|
60
|
+
It contains two attributes :attr:`pol` (polynomial), :attr:`dm`
|
61
|
+
(degree multiple), where ``pol`` is a PARI polynomial and
|
62
|
+
``dm`` a Sage :class:`Integer`.
|
63
|
+
|
64
|
+
``dm`` is a multiple of the degree of the splitting field of
|
65
|
+
``pol`` over some field `E`. In :func:`splitting_field`, `E` is the
|
66
|
+
field containing the current field `K` and all roots of other
|
67
|
+
polynomials inside the list `L` with ``dm`` less than this ``dm``.
|
68
|
+
"""
|
69
|
+
def __init__(self, _pol, _dm):
|
70
|
+
self.pol = _pol
|
71
|
+
self.dm = Integer(_dm)
|
72
|
+
|
73
|
+
def key(self):
|
74
|
+
"""
|
75
|
+
Return a sorting key. Compare first by degree bound, then by
|
76
|
+
polynomial degree, then by discriminant.
|
77
|
+
|
78
|
+
EXAMPLES::
|
79
|
+
|
80
|
+
sage: from sage.rings.number_field.splitting_field import SplittingData
|
81
|
+
sage: L = []
|
82
|
+
sage: L.append(SplittingData(pari("x^2 + 1"), 1))
|
83
|
+
sage: L.append(SplittingData(pari("x^3 + 1"), 1))
|
84
|
+
sage: L.append(SplittingData(pari("x^2 + 7"), 2))
|
85
|
+
sage: L.append(SplittingData(pari("x^3 + 1"), 2))
|
86
|
+
sage: L.append(SplittingData(pari("x^3 + x^2 + x + 1"), 2))
|
87
|
+
sage: L.sort(key=lambda x: x.key()); L
|
88
|
+
[SplittingData(x^2 + 1, 1), SplittingData(x^3 + 1, 1), SplittingData(x^2 + 7, 2), SplittingData(x^3 + x^2 + x + 1, 2), SplittingData(x^3 + 1, 2)]
|
89
|
+
sage: [x.key() for x in L]
|
90
|
+
[(1, 2, 16), (1, 3, 729), (2, 2, 784), (2, 3, 256), (2, 3, 729)]
|
91
|
+
"""
|
92
|
+
return (self.dm, self.poldegree(), self.pol.poldisc().norm().abs())
|
93
|
+
|
94
|
+
def poldegree(self):
|
95
|
+
"""
|
96
|
+
Return the degree of ``self.pol``.
|
97
|
+
|
98
|
+
EXAMPLES::
|
99
|
+
|
100
|
+
sage: from sage.rings.number_field.splitting_field import SplittingData
|
101
|
+
sage: SplittingData(pari("x^123 + x + 1"), 2).poldegree()
|
102
|
+
123
|
103
|
+
"""
|
104
|
+
return self.pol.poldegree()
|
105
|
+
|
106
|
+
def __repr__(self):
|
107
|
+
"""
|
108
|
+
TESTS::
|
109
|
+
|
110
|
+
sage: from sage.rings.number_field.splitting_field import SplittingData
|
111
|
+
sage: print(SplittingData(pari("polcyclo(24)"), 2))
|
112
|
+
SplittingData(x^8 - x^4 + 1, 2)
|
113
|
+
"""
|
114
|
+
return "SplittingData(%s, %s)" % (self.pol, self.dm)
|
115
|
+
|
116
|
+
def _repr_tuple(self):
|
117
|
+
"""
|
118
|
+
TESTS::
|
119
|
+
|
120
|
+
sage: from sage.rings.number_field.splitting_field import SplittingData
|
121
|
+
sage: SplittingData(pari("polcyclo(24)"), 2)._repr_tuple()
|
122
|
+
(8, 2)
|
123
|
+
"""
|
124
|
+
return (self.poldegree(), self.dm)
|
125
|
+
|
126
|
+
|
127
|
+
def splitting_field(poly, name, map=False, degree_multiple=None, abort_degree=None, simplify=True, simplify_all=False):
|
128
|
+
r"""
|
129
|
+
Compute the splitting field of a given polynomial, defined over a
|
130
|
+
number field.
|
131
|
+
|
132
|
+
INPUT:
|
133
|
+
|
134
|
+
- ``poly`` -- a monic polynomial over a number field
|
135
|
+
|
136
|
+
- ``name`` -- a variable name for the number field
|
137
|
+
|
138
|
+
- ``map`` -- boolean (default: ``False``); also return an embedding of
|
139
|
+
``poly`` into the resulting field. Note that computing this
|
140
|
+
embedding might be expensive.
|
141
|
+
|
142
|
+
- ``degree_multiple`` -- a multiple of the absolute degree of
|
143
|
+
the splitting field. If ``degree_multiple`` equals the actual
|
144
|
+
degree, this can enormously speed up the computation.
|
145
|
+
|
146
|
+
- ``abort_degree`` -- abort by raising a :class:`SplittingFieldAbort`
|
147
|
+
if it can be determined that the absolute degree of the splitting
|
148
|
+
field is strictly larger than ``abort_degree``.
|
149
|
+
|
150
|
+
- ``simplify`` -- boolean (default: ``True``); during the algorithm, try
|
151
|
+
to find a simpler defining polynomial for the intermediate
|
152
|
+
number fields using PARI's ``polredbest()``. This usually speeds
|
153
|
+
up the computation but can also considerably slow it down.
|
154
|
+
Try and see what works best in the given situation.
|
155
|
+
|
156
|
+
- ``simplify_all`` -- boolean (default: ``False``); if ``True``, simplify
|
157
|
+
intermediate fields and also the resulting number field
|
158
|
+
|
159
|
+
OUTPUT:
|
160
|
+
|
161
|
+
If ``map`` is ``False``, the splitting field as an absolute number
|
162
|
+
field. If ``map`` is ``True``, a tuple ``(K, phi)`` where ``phi``
|
163
|
+
is an embedding of the base field in ``K``.
|
164
|
+
|
165
|
+
EXAMPLES::
|
166
|
+
|
167
|
+
sage: R.<x> = PolynomialRing(QQ)
|
168
|
+
sage: K.<a> = (x^3 + 2).splitting_field(); K
|
169
|
+
Number Field in a with defining polynomial
|
170
|
+
x^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1
|
171
|
+
sage: K.<a> = (x^3 - 3*x + 1).splitting_field(); K
|
172
|
+
Number Field in a with defining polynomial x^3 - 3*x + 1
|
173
|
+
|
174
|
+
The ``simplify`` and ``simplify_all`` flags usually yield
|
175
|
+
fields defined by polynomials with smaller coefficients.
|
176
|
+
By default, ``simplify`` is ``True`` and ``simplify_all`` is ``False``.
|
177
|
+
|
178
|
+
::
|
179
|
+
|
180
|
+
sage: (x^4 - x + 1).splitting_field('a', simplify=False)
|
181
|
+
Number Field in a with defining polynomial
|
182
|
+
x^24 - 2780*x^22 + 2*x^21 + 3527512*x^20 - 2876*x^19 - 2701391985*x^18 + 945948*x^17
|
183
|
+
+ 1390511639677*x^16 + 736757420*x^15 - 506816498313560*x^14 - 822702898220*x^13
|
184
|
+
+ 134120588299548463*x^12 + 362240696528256*x^11 - 25964582366880639486*x^10
|
185
|
+
- 91743672243419990*x^9 + 3649429473447308439427*x^8 + 14310332927134072336*x^7
|
186
|
+
- 363192569823568746892571*x^6 - 1353403793640477725898*x^5
|
187
|
+
+ 24293393281774560140427565*x^4 + 70673814899934142357628*x^3
|
188
|
+
- 980621447508959243128437933*x^2 - 1539841440617805445432660*x
|
189
|
+
+ 18065914012013502602456565991
|
190
|
+
sage: (x^4 - x + 1).splitting_field('a', simplify=True)
|
191
|
+
Number Field in a with defining polynomial
|
192
|
+
x^24 + 8*x^23 - 32*x^22 - 310*x^21 + 540*x^20 + 4688*x^19 - 6813*x^18 - 32380*x^17
|
193
|
+
+ 49525*x^16 + 102460*x^15 - 129944*x^14 - 287884*x^13 + 372727*x^12 + 150624*x^11
|
194
|
+
- 110530*x^10 - 566926*x^9 + 1062759*x^8 - 779940*x^7 + 863493*x^6 - 1623578*x^5
|
195
|
+
+ 1759513*x^4 - 955624*x^3 + 459975*x^2 - 141948*x + 53919
|
196
|
+
sage: (x^4 - x + 1).splitting_field('a', simplify_all=True)
|
197
|
+
Number Field in a with defining polynomial x^24 - 3*x^23 + 2*x^22 - x^20 + 4*x^19
|
198
|
+
+ 32*x^18 - 35*x^17 - 92*x^16 + 49*x^15 + 163*x^14 - 15*x^13 - 194*x^12 - 15*x^11
|
199
|
+
+ 163*x^10 + 49*x^9 - 92*x^8 - 35*x^7 + 32*x^6 + 4*x^5 - x^4 + 2*x^2 - 3*x + 1
|
200
|
+
|
201
|
+
Reducible polynomials also work::
|
202
|
+
|
203
|
+
sage: pol = (x^4 - 1)*(x^2 + 1/2)*(x^2 + 1/3)
|
204
|
+
sage: pol.splitting_field('a', simplify_all=True)
|
205
|
+
Number Field in a with defining polynomial x^8 - x^4 + 1
|
206
|
+
|
207
|
+
Relative situation::
|
208
|
+
|
209
|
+
sage: R.<x> = PolynomialRing(QQ)
|
210
|
+
sage: K.<a> = NumberField(x^3 + 2)
|
211
|
+
sage: S.<t> = PolynomialRing(K)
|
212
|
+
sage: L.<b> = (t^2 - a).splitting_field()
|
213
|
+
sage: L
|
214
|
+
Number Field in b with defining polynomial t^6 + 2
|
215
|
+
|
216
|
+
With ``map=True``, we also get the embedding of the base field
|
217
|
+
into the splitting field::
|
218
|
+
|
219
|
+
sage: L.<b>, phi = (t^2 - a).splitting_field(map=True)
|
220
|
+
sage: phi
|
221
|
+
Ring morphism:
|
222
|
+
From: Number Field in a with defining polynomial x^3 + 2
|
223
|
+
To: Number Field in b with defining polynomial t^6 + 2
|
224
|
+
Defn: a |--> b^2
|
225
|
+
sage: (x^4 - x + 1).splitting_field('a', simplify_all=True, map=True)[1]
|
226
|
+
Ring morphism:
|
227
|
+
From: Rational Field
|
228
|
+
To: Number Field in a with defining polynomial
|
229
|
+
x^24 - 3*x^23 + 2*x^22 - x^20 + 4*x^19 + 32*x^18 - 35*x^17 - 92*x^16
|
230
|
+
+ 49*x^15 + 163*x^14 - 15*x^13 - 194*x^12 - 15*x^11 + 163*x^10 + 49*x^9
|
231
|
+
- 92*x^8 - 35*x^7 + 32*x^6 + 4*x^5 - x^4 + 2*x^2 - 3*x + 1
|
232
|
+
Defn: 1 |--> 1
|
233
|
+
|
234
|
+
We can enable verbose messages::
|
235
|
+
|
236
|
+
sage: from sage.misc.verbose import set_verbose
|
237
|
+
sage: set_verbose(2)
|
238
|
+
sage: K.<a> = (x^3 - x + 1).splitting_field()
|
239
|
+
verbose 1 (...: splitting_field.py, splitting_field) Starting field: y
|
240
|
+
verbose 1 (...: splitting_field.py, splitting_field) SplittingData to factor: [(3, 0)]
|
241
|
+
verbose 2 (...: splitting_field.py, splitting_field) Done factoring (time = ...)
|
242
|
+
verbose 1 (...: splitting_field.py, splitting_field) SplittingData to handle: [(2, 2), (3, 3)]
|
243
|
+
verbose 1 (...: splitting_field.py, splitting_field) Bounds for absolute degree: [6, 6]
|
244
|
+
verbose 2 (...: splitting_field.py, splitting_field) Handling polynomial x^2 + 23
|
245
|
+
verbose 1 (...: splitting_field.py, splitting_field) New field before simplifying: x^2 + 23 (time = ...)
|
246
|
+
verbose 1 (...: splitting_field.py, splitting_field) New field: y^2 - y + 6 (time = ...)
|
247
|
+
verbose 2 (...: splitting_field.py, splitting_field) Converted polynomials to new field (time = ...)
|
248
|
+
verbose 1 (...: splitting_field.py, splitting_field) SplittingData to factor: []
|
249
|
+
verbose 2 (...: splitting_field.py, splitting_field) Done factoring (time = ...)
|
250
|
+
verbose 1 (...: splitting_field.py, splitting_field) SplittingData to handle: [(3, 3)]
|
251
|
+
verbose 1 (...: splitting_field.py, splitting_field) Bounds for absolute degree: [6, 6]
|
252
|
+
verbose 2 (...: splitting_field.py, splitting_field) Handling polynomial x^3 - x + 1
|
253
|
+
verbose 1 (...: splitting_field.py, splitting_field) New field: y^6 + 3*y^5 + 19*y^4 + 35*y^3 + 127*y^2 + 73*y + 271 (time = ...)
|
254
|
+
sage: set_verbose(0)
|
255
|
+
|
256
|
+
Try all Galois groups in degree 4. We use a quadratic base field
|
257
|
+
such that ``polgalois()`` cannot be used::
|
258
|
+
|
259
|
+
sage: R.<x> = PolynomialRing(QuadraticField(-11))
|
260
|
+
sage: C2C2pol = x^4 - 10*x^2 + 1
|
261
|
+
sage: C2C2pol.splitting_field('x')
|
262
|
+
Number Field in x with defining polynomial x^8 + 24*x^6 + 608*x^4 + 9792*x^2 + 53824
|
263
|
+
sage: C4pol = x^4 + x^3 + x^2 + x + 1
|
264
|
+
sage: C4pol.splitting_field('x')
|
265
|
+
Number Field in x with defining polynomial
|
266
|
+
x^8 - x^7 - 2*x^6 + 5*x^5 + x^4 + 15*x^3 - 18*x^2 - 27*x + 81
|
267
|
+
sage: D8pol = x^4 - 2
|
268
|
+
sage: D8pol.splitting_field('x')
|
269
|
+
Number Field in x with defining polynomial
|
270
|
+
x^16 + 8*x^15 + 68*x^14 + 336*x^13 + 1514*x^12 + 5080*x^11 + 14912*x^10
|
271
|
+
+ 35048*x^9 + 64959*x^8 + 93416*x^7 + 88216*x^6 + 41608*x^5 - 25586*x^4
|
272
|
+
- 60048*x^3 - 16628*x^2 + 12008*x + 34961
|
273
|
+
sage: A4pol = x^4 - 4*x^3 + 14*x^2 - 28*x + 21
|
274
|
+
sage: A4pol.splitting_field('x')
|
275
|
+
Number Field in x with defining polynomial
|
276
|
+
x^24 - 20*x^23 + 290*x^22 - 3048*x^21 + 26147*x^20 - 186132*x^19 + 1130626*x^18
|
277
|
+
- 5913784*x^17 + 26899345*x^16 - 106792132*x^15 + 371066538*x^14 - 1127792656*x^13
|
278
|
+
+ 2991524876*x^12 - 6888328132*x^11 + 13655960064*x^10 - 23000783036*x^9
|
279
|
+
+ 32244796382*x^8 - 36347834476*x^7 + 30850889884*x^6 - 16707053128*x^5
|
280
|
+
+ 1896946429*x^4 + 4832907884*x^3 - 3038258802*x^2 - 200383596*x + 593179173
|
281
|
+
sage: S4pol = x^4 + x + 1
|
282
|
+
sage: S4pol.splitting_field('x')
|
283
|
+
Number Field in x with defining polynomial x^48 ...
|
284
|
+
|
285
|
+
Some bigger examples::
|
286
|
+
|
287
|
+
sage: R.<x> = PolynomialRing(QQ)
|
288
|
+
sage: pol15 = chebyshev_T(31, x) - 1 # 2^30*(x-1)*minpoly(cos(2*pi/31))^2
|
289
|
+
sage: pol15.splitting_field('a')
|
290
|
+
Number Field in a with defining polynomial
|
291
|
+
x^15 - x^14 - 14*x^13 + 13*x^12 + 78*x^11 - 66*x^10 - 220*x^9 + 165*x^8
|
292
|
+
+ 330*x^7 - 210*x^6 - 252*x^5 + 126*x^4 + 84*x^3 - 28*x^2 - 8*x + 1
|
293
|
+
sage: pol48 = x^6 - 4*x^4 + 12*x^2 - 12
|
294
|
+
sage: pol48.splitting_field('a')
|
295
|
+
Number Field in a with defining polynomial x^48 ...
|
296
|
+
|
297
|
+
If you somehow know the degree of the field in advance, you
|
298
|
+
should add a ``degree_multiple`` argument. This can speed up the
|
299
|
+
computation, in particular for polynomials of degree >= 12 or
|
300
|
+
for relative extensions::
|
301
|
+
|
302
|
+
sage: pol15.splitting_field('a', degree_multiple=15)
|
303
|
+
Number Field in a with defining polynomial
|
304
|
+
x^15 + x^14 - 14*x^13 - 13*x^12 + 78*x^11 + 66*x^10 - 220*x^9 - 165*x^8
|
305
|
+
+ 330*x^7 + 210*x^6 - 252*x^5 - 126*x^4 + 84*x^3 + 28*x^2 - 8*x - 1
|
306
|
+
|
307
|
+
A value for ``degree_multiple`` which isn't actually a
|
308
|
+
multiple of the absolute degree of the splitting field can
|
309
|
+
either result in a wrong answer or the following exception::
|
310
|
+
|
311
|
+
sage: pol48.splitting_field('a', degree_multiple=20)
|
312
|
+
Traceback (most recent call last):
|
313
|
+
...
|
314
|
+
ValueError: inconsistent degree_multiple in splitting_field()
|
315
|
+
|
316
|
+
Compute the Galois closure as the splitting field of the defining polynomial::
|
317
|
+
|
318
|
+
sage: R.<x> = PolynomialRing(QQ)
|
319
|
+
sage: pol48 = x^6 - 4*x^4 + 12*x^2 - 12
|
320
|
+
sage: K.<a> = NumberField(pol48)
|
321
|
+
sage: L.<b> = pol48.change_ring(K).splitting_field()
|
322
|
+
sage: L
|
323
|
+
Number Field in b with defining polynomial x^48 ...
|
324
|
+
|
325
|
+
Try all Galois groups over `\QQ` in degree 5 except for `S_5`
|
326
|
+
(the latter is infeasible with the current implementation)::
|
327
|
+
|
328
|
+
sage: C5pol = x^5 + x^4 - 4*x^3 - 3*x^2 + 3*x + 1
|
329
|
+
sage: C5pol.splitting_field('x')
|
330
|
+
Number Field in x with defining polynomial x^5 + x^4 - 4*x^3 - 3*x^2 + 3*x + 1
|
331
|
+
sage: D10pol = x^5 - x^4 - 5*x^3 + 4*x^2 + 3*x - 1
|
332
|
+
sage: D10pol.splitting_field('x')
|
333
|
+
Number Field in x with defining polynomial
|
334
|
+
x^10 - 28*x^8 + 216*x^6 - 681*x^4 + 902*x^2 - 401
|
335
|
+
sage: AGL_1_5pol = x^5 - 2
|
336
|
+
sage: AGL_1_5pol.splitting_field('x')
|
337
|
+
Number Field in x with defining polynomial
|
338
|
+
x^20 + 10*x^19 + 55*x^18 + 210*x^17 + 595*x^16 + 1300*x^15 + 2250*x^14
|
339
|
+
+ 3130*x^13 + 3585*x^12 + 3500*x^11 + 2965*x^10 + 2250*x^9 + 1625*x^8
|
340
|
+
+ 1150*x^7 + 750*x^6 + 400*x^5 + 275*x^4 + 100*x^3 + 75*x^2 + 25
|
341
|
+
sage: A5pol = x^5 - x^4 + 2*x^2 - 2*x + 2
|
342
|
+
sage: A5pol.splitting_field('x')
|
343
|
+
Number Field in x with defining polynomial x^60 ...
|
344
|
+
|
345
|
+
We can use the ``abort_degree`` option if we don't want to compute
|
346
|
+
fields of too large degree (this can be used to check whether the
|
347
|
+
splitting field has small degree)::
|
348
|
+
|
349
|
+
sage: (x^5 + x + 3).splitting_field('b', abort_degree=119)
|
350
|
+
Traceback (most recent call last):
|
351
|
+
...
|
352
|
+
SplittingFieldAbort: degree of splitting field equals 120
|
353
|
+
sage: (x^10 + x + 3).splitting_field('b', abort_degree=60) # long time (10s on sage.math, 2014)
|
354
|
+
Traceback (most recent call last):
|
355
|
+
...
|
356
|
+
SplittingFieldAbort: degree of splitting field is a multiple of 180
|
357
|
+
|
358
|
+
Use the ``degree_divisor`` attribute to recover the divisor of the
|
359
|
+
degree of the splitting field or ``degree_multiple`` to recover a
|
360
|
+
multiple::
|
361
|
+
|
362
|
+
sage: from sage.rings.number_field.splitting_field import SplittingFieldAbort
|
363
|
+
sage: try: # long time (4s on sage.math, 2014)
|
364
|
+
....: (x^8 + x + 1).splitting_field('b', abort_degree=60, simplify=False)
|
365
|
+
....: except SplittingFieldAbort as e:
|
366
|
+
....: print(e.degree_divisor)
|
367
|
+
....: print(e.degree_multiple)
|
368
|
+
120
|
369
|
+
1440
|
370
|
+
|
371
|
+
TESTS::
|
372
|
+
|
373
|
+
sage: from sage.rings.number_field.splitting_field import splitting_field
|
374
|
+
sage: splitting_field(polygen(QQ), name='x', map=True, simplify_all=True)
|
375
|
+
(Number Field in x with defining polynomial x, Ring morphism:
|
376
|
+
From: Rational Field
|
377
|
+
To: Number Field in x with defining polynomial x
|
378
|
+
Defn: 1 |--> 1)
|
379
|
+
"""
|
380
|
+
from sage.misc.timing import cputime
|
381
|
+
from sage.misc.verbose import verbose
|
382
|
+
|
383
|
+
degree_multiple = Integer(degree_multiple or 0)
|
384
|
+
abort_degree = Integer(abort_degree or 0)
|
385
|
+
|
386
|
+
# Kpol = PARI polynomial in y defining the extension found so far
|
387
|
+
F = poly.base_ring()
|
388
|
+
if isinstance(F, RationalField):
|
389
|
+
Kpol = pari("'y")
|
390
|
+
else:
|
391
|
+
Kpol = F.pari_polynomial("y")
|
392
|
+
# Fgen = the generator of F as element of Q[y]/Kpol
|
393
|
+
# (only needed if map=True)
|
394
|
+
if map:
|
395
|
+
Fgen = F.gen().__pari__()
|
396
|
+
verbose("Starting field: %s" % Kpol)
|
397
|
+
|
398
|
+
# L and Lred are lists of SplittingData.
|
399
|
+
# L contains polynomials which are irreducible over K,
|
400
|
+
# Lred contains polynomials which need to be factored.
|
401
|
+
L = []
|
402
|
+
Lred = [SplittingData(poly._pari_with_name(), degree_multiple)]
|
403
|
+
|
404
|
+
# Main loop, handle polynomials one by one
|
405
|
+
while True:
|
406
|
+
# Absolute degree of current field K
|
407
|
+
absolute_degree = Integer(Kpol.poldegree())
|
408
|
+
|
409
|
+
# Compute minimum relative degree of splitting field
|
410
|
+
rel_degree_divisor = Integer(1)
|
411
|
+
for splitting in L:
|
412
|
+
rel_degree_divisor = rel_degree_divisor.lcm(splitting.poldegree())
|
413
|
+
|
414
|
+
# Check for early aborts
|
415
|
+
abort_rel_degree = abort_degree//absolute_degree
|
416
|
+
if abort_rel_degree and rel_degree_divisor > abort_rel_degree:
|
417
|
+
raise SplittingFieldAbort(absolute_degree * rel_degree_divisor, degree_multiple)
|
418
|
+
|
419
|
+
# First, factor polynomials in Lred and store the result in L
|
420
|
+
verbose("SplittingData to factor: %s" % [s._repr_tuple() for s in Lred])
|
421
|
+
t = cputime()
|
422
|
+
for splitting in Lred:
|
423
|
+
m = splitting.dm.gcd(degree_multiple).gcd(factorial(splitting.poldegree()))
|
424
|
+
if m == 1:
|
425
|
+
continue
|
426
|
+
factors = Kpol.nffactor(splitting.pol)[0]
|
427
|
+
for q in factors:
|
428
|
+
d = q.poldegree()
|
429
|
+
fac = factorial(d)
|
430
|
+
# Multiple of the degree of the splitting field of q,
|
431
|
+
# note that the degree equals fac iff the Galois group is S_n.
|
432
|
+
mq = m.gcd(fac)
|
433
|
+
if mq == 1:
|
434
|
+
continue
|
435
|
+
# Multiple of the degree of the splitting field of q
|
436
|
+
# over the field defined by adding square root of the
|
437
|
+
# discriminant.
|
438
|
+
# If the Galois group is contained in A_n, then mq_alt is
|
439
|
+
# also the degree multiple over the current field K.
|
440
|
+
# Here, we have equality if the Galois group is A_n.
|
441
|
+
mq_alt = mq.gcd(fac//2)
|
442
|
+
|
443
|
+
# If we are over Q, then use PARI's polgalois() to compute
|
444
|
+
# these degrees exactly.
|
445
|
+
if absolute_degree == 1:
|
446
|
+
try:
|
447
|
+
G = q.polgalois()
|
448
|
+
except PariError:
|
449
|
+
pass
|
450
|
+
else:
|
451
|
+
mq = Integer(G[0])
|
452
|
+
mq_alt = mq//2 if (G[1] == -1) else mq
|
453
|
+
|
454
|
+
# In degree 4, use the cubic resolvent to refine the
|
455
|
+
# degree bounds.
|
456
|
+
if d == 4 and mq >= 12: # mq equals 12 or 24
|
457
|
+
# Compute cubic resolvent
|
458
|
+
a0, a1, a2, a3, a4 = (q/q.pollead()).Vecrev()
|
459
|
+
assert a4 == 1
|
460
|
+
cubicpol = pari([4*a0*a2 - a1*a1 - a0*a3*a3, a1*a3 - 4*a0, -a2, 1]).Polrev()
|
461
|
+
cubicfactors = Kpol.nffactor(cubicpol)[0]
|
462
|
+
if len(cubicfactors) == 1: # A4 or S4
|
463
|
+
# After adding a root of the cubic resolvent,
|
464
|
+
# the degree of the extension defined by q
|
465
|
+
# is a factor 3 smaller.
|
466
|
+
L.append(SplittingData(cubicpol, 3))
|
467
|
+
rel_degree_divisor = rel_degree_divisor.lcm(3)
|
468
|
+
mq = mq//3 # 4 or 8
|
469
|
+
mq_alt = 4
|
470
|
+
elif len(cubicfactors) == 2: # C4 or D8
|
471
|
+
# The irreducible degree 2 factor is
|
472
|
+
# equivalent to x^2 - q.poldisc().
|
473
|
+
discpol = cubicfactors[1]
|
474
|
+
L.append(SplittingData(discpol, 2))
|
475
|
+
mq = mq_alt = 4
|
476
|
+
else: # C2 x C2
|
477
|
+
mq = mq_alt = 4
|
478
|
+
|
479
|
+
if mq > mq_alt >= 3:
|
480
|
+
# Add quadratic resolvent x^2 - D to decrease
|
481
|
+
# the degree multiple by a factor 2.
|
482
|
+
discpol = pari([-q.poldisc(), 0, 1]).Polrev()
|
483
|
+
discfactors = Kpol.nffactor(discpol)[0]
|
484
|
+
if len(discfactors) == 1:
|
485
|
+
# Discriminant is not a square
|
486
|
+
L.append(SplittingData(discpol, 2))
|
487
|
+
rel_degree_divisor = rel_degree_divisor.lcm(2)
|
488
|
+
mq = mq_alt
|
489
|
+
|
490
|
+
L.append(SplittingData(q, mq))
|
491
|
+
rel_degree_divisor = rel_degree_divisor.lcm(q.poldegree())
|
492
|
+
if abort_rel_degree and rel_degree_divisor > abort_rel_degree:
|
493
|
+
raise SplittingFieldAbort(absolute_degree * rel_degree_divisor, degree_multiple)
|
494
|
+
verbose("Done factoring", t, level=2)
|
495
|
+
|
496
|
+
if len(L) == 0: # Nothing left to do
|
497
|
+
break
|
498
|
+
|
499
|
+
# Recompute absolute degree multiple
|
500
|
+
new_degree_multiple = absolute_degree
|
501
|
+
for splitting in L:
|
502
|
+
new_degree_multiple *= splitting.dm
|
503
|
+
degree_multiple = new_degree_multiple.gcd(degree_multiple)
|
504
|
+
|
505
|
+
# Absolute degree divisor
|
506
|
+
degree_divisor = rel_degree_divisor * absolute_degree
|
507
|
+
|
508
|
+
# Sort according to degree to handle low degrees first
|
509
|
+
L.sort(key=lambda x: x.key())
|
510
|
+
verbose("SplittingData to handle: %s" % [s._repr_tuple() for s in L])
|
511
|
+
verbose("Bounds for absolute degree: [%s, %s]" % (degree_divisor,degree_multiple))
|
512
|
+
|
513
|
+
# Check consistency
|
514
|
+
if degree_multiple % degree_divisor != 0:
|
515
|
+
raise ValueError("inconsistent degree_multiple in splitting_field()")
|
516
|
+
for splitting in L:
|
517
|
+
# The degree of the splitting field must be a multiple of
|
518
|
+
# the degree of the polynomial. Only do this check for
|
519
|
+
# SplittingData with minimal dm, because the higher dm are
|
520
|
+
# defined as relative degree over the splitting field of
|
521
|
+
# the polynomials with lesser dm.
|
522
|
+
if splitting.dm > L[0].dm:
|
523
|
+
break
|
524
|
+
if splitting.dm % splitting.poldegree() != 0:
|
525
|
+
raise ValueError("inconsistent degree_multiple in splitting_field()")
|
526
|
+
|
527
|
+
# Add a root of f = L[0] to construct the field N = K[x]/f(x)
|
528
|
+
splitting = L[0]
|
529
|
+
f = splitting.pol
|
530
|
+
verbose("Handling polynomial %s" % (f.lift()), level=2)
|
531
|
+
t = cputime()
|
532
|
+
Npol, KtoN, k = Kpol.rnfequation(f, flag=1)
|
533
|
+
|
534
|
+
# Make Npol monic integral primitive, store in Mpol
|
535
|
+
# (after this, we don't need Npol anymore, only Mpol)
|
536
|
+
Mdiv = pari(1)
|
537
|
+
Mpol = Npol
|
538
|
+
while True:
|
539
|
+
denom = Integer(Mpol.pollead())
|
540
|
+
if denom == 1:
|
541
|
+
break
|
542
|
+
denom = pari(denom.factor().radical_value())
|
543
|
+
Mpol = (Mpol*(denom**Mpol.poldegree())).subst("x", pari([0,1/denom]).Polrev("x"))
|
544
|
+
Mpol /= Mpol.content()
|
545
|
+
Mdiv *= denom
|
546
|
+
|
547
|
+
# We are finished for sure if we hit the degree bound
|
548
|
+
finished = (Mpol.poldegree() >= degree_multiple)
|
549
|
+
|
550
|
+
if simplify_all or (simplify and not finished):
|
551
|
+
# Find a simpler defining polynomial Lpol for Mpol
|
552
|
+
verbose("New field before simplifying: %s" % Mpol, t)
|
553
|
+
t = cputime()
|
554
|
+
M = Mpol.polredbest(1)
|
555
|
+
Lpol = M[0].change_variable_name("y")
|
556
|
+
MtoL = M[1].lift().change_variable_name("y").Mod(Lpol)
|
557
|
+
else:
|
558
|
+
# Lpol = Mpol
|
559
|
+
Lpol = Mpol.change_variable_name("y")
|
560
|
+
MtoL = pari("'y")
|
561
|
+
|
562
|
+
NtoL = MtoL/Mdiv
|
563
|
+
KtoL = KtoN.lift().subst("x", NtoL).Mod(Lpol)
|
564
|
+
Kpol = Lpol # New Kpol (for next iteration)
|
565
|
+
verbose("New field: %s" % Kpol, t)
|
566
|
+
if map:
|
567
|
+
t = cputime()
|
568
|
+
Fgen = Fgen.lift().subst("y", KtoL)
|
569
|
+
verbose("Computed generator of F in K", t, level=2)
|
570
|
+
if finished:
|
571
|
+
break
|
572
|
+
|
573
|
+
t = cputime()
|
574
|
+
|
575
|
+
# Convert f and elements of L from K to L and store in L
|
576
|
+
# (if the polynomial is certain to remain irreducible) or Lred.
|
577
|
+
Lold = L[1:]
|
578
|
+
L = []
|
579
|
+
Lred = []
|
580
|
+
|
581
|
+
# First add f divided by the linear factor we obtained,
|
582
|
+
# mg is the new degree multiple.
|
583
|
+
mg = splitting.dm//f.poldegree()
|
584
|
+
if mg > 1:
|
585
|
+
g = [c.subst("y", KtoL).Mod(Lpol) for c in f.Vecrev().lift()]
|
586
|
+
g = pari(g).Polrev()
|
587
|
+
g /= pari([k*KtoL - NtoL, 1]).Polrev() # divide linear factor
|
588
|
+
Lred.append(SplittingData(g, mg))
|
589
|
+
|
590
|
+
for splitting in Lold:
|
591
|
+
g = [c.subst("y", KtoL) for c in splitting.pol.Vecrev().lift()]
|
592
|
+
g = pari(g).Polrev()
|
593
|
+
mg = splitting.dm
|
594
|
+
if Integer(g.poldegree()).gcd(f.poldegree()) == 1: # linearly disjoint fields
|
595
|
+
L.append(SplittingData(g, mg))
|
596
|
+
else:
|
597
|
+
Lred.append(SplittingData(g, mg))
|
598
|
+
verbose("Converted polynomials to new field", t, level=2)
|
599
|
+
|
600
|
+
# Convert Kpol to Sage and construct the absolute number field
|
601
|
+
Kpol = PolynomialRing(RationalField(), name=poly.variable_name())(Kpol/Kpol.pollead())
|
602
|
+
K = NumberField(Kpol, name)
|
603
|
+
if map:
|
604
|
+
return K, F.hom(Fgen, K)
|
605
|
+
else:
|
606
|
+
return K
|