passagemath-flint 10.6.1rc10__cp312-cp312-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-312-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-312-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-312-x86_64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-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-312-x86_64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-312-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-312-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-312-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-312-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-312-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-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-312-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-312-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-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-312-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-312-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-312-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-312-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-312-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-312-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-312-x86_64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-312-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-312-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,804 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
# sage.doctest: needs sage.libs.pari
|
3
|
+
r"""
|
4
|
+
Ideals of (Not Necessarily Maximal) Orders in Number Fields
|
5
|
+
|
6
|
+
This module implements (integral) ideals of orders in number fields.
|
7
|
+
|
8
|
+
.. NOTE::
|
9
|
+
|
10
|
+
Currently, Sage only offers very limited functionality for
|
11
|
+
ideals of non-maximal orders (compared to the maximal case).
|
12
|
+
This should hopefully change in the future.
|
13
|
+
|
14
|
+
EXAMPLES::
|
15
|
+
|
16
|
+
sage: O = QuadraticField(-1).order(5*i)
|
17
|
+
sage: I = O.ideal([13, 5*i-1]); I
|
18
|
+
Ideal (60*a + 1, 65*a) of Order of conductor 5 generated by 5*a
|
19
|
+
in Number Field in a with defining polynomial x^2 + 1 with a = 1*I
|
20
|
+
|
21
|
+
An ideal of an order in a relative number field::
|
22
|
+
|
23
|
+
sage: x = polygen(ZZ, 'x')
|
24
|
+
sage: K.<a,b> = NumberField([x^2 + 1, x^2 - 3])
|
25
|
+
sage: O = K.order([3*a,2*b])
|
26
|
+
sage: I = O.ideal((-6*b + 6)*a + 6*b + 18); I
|
27
|
+
Ideal ((-60*b + 180)*a + 72, (-54*b + 174)*a - 6*b + 54, (-72*b + 288)*a + 72, 1872*a)
|
28
|
+
of Relative Order generated by [3*a - 2*b, -6*b*a + 6, 3*a]
|
29
|
+
in Number Field in a with defining polynomial x^2 + 1 over its base field
|
30
|
+
|
31
|
+
Perhaps the most useful functionality at this time is mapping ideals
|
32
|
+
of *quadratic* orders to corresponding binary quadratic forms::
|
33
|
+
|
34
|
+
sage: K.<t> = QuadraticField(-21463)
|
35
|
+
sage: O = K.order(t)
|
36
|
+
sage: I = O.ideal([123457, t + 45259]); I
|
37
|
+
Ideal (23058*t + 1, 123457*t) of Order of conductor 26 generated by t
|
38
|
+
in Number Field in t with defining polynomial x^2 + 21463 with t = 146.5025597046004?*I
|
39
|
+
sage: I.quadratic_form()
|
40
|
+
123457*x^2 - 90518*x*y + 16592*y^2
|
41
|
+
|
42
|
+
.. TODO::
|
43
|
+
|
44
|
+
Generalize more functionality (such as primality testing and
|
45
|
+
factoring) from
|
46
|
+
:class:`~sage.rings.number_field.number_field_ideal.NumberFieldFractionalIdeal`
|
47
|
+
to ideals of not necessarily maximal orders.
|
48
|
+
|
49
|
+
AUTHORS:
|
50
|
+
|
51
|
+
- Lorenz Panny (2022)
|
52
|
+
"""
|
53
|
+
|
54
|
+
# ****************************************************************************
|
55
|
+
# Copyright (C) 2022 Lorenz Panny
|
56
|
+
#
|
57
|
+
# This program is free software: you can redistribute it and/or modify
|
58
|
+
# it under the terms of the GNU General Public License as published by
|
59
|
+
# the Free Software Foundation, either version 2 of the License, or
|
60
|
+
# (at your option) any later version.
|
61
|
+
# https://www.gnu.org/licenses/
|
62
|
+
# ****************************************************************************
|
63
|
+
|
64
|
+
from sage.structure.richcmp import richcmp
|
65
|
+
from sage.structure.sequence import Sequence
|
66
|
+
from sage.rings.integer_ring import ZZ
|
67
|
+
from sage.rings.rational_field import QQ
|
68
|
+
from sage.modules.free_module_element import vector
|
69
|
+
from sage.rings.polynomial.polynomial_ring import polygens
|
70
|
+
from sage.rings.ideal import Ideal_generic
|
71
|
+
|
72
|
+
import sage.rings.number_field.order
|
73
|
+
|
74
|
+
# TODO I*u works when u lies in I.ring().number_field(), but u*I doesn't
|
75
|
+
|
76
|
+
|
77
|
+
def NumberFieldOrderIdeal(O, *args, **kwds):
|
78
|
+
r"""
|
79
|
+
Construct either a :class:`NumberFieldOrderIdeal_generic`
|
80
|
+
or a :class:`NumberFieldOrderIdeal_quadratic` from the
|
81
|
+
given arguments.
|
82
|
+
|
83
|
+
EXAMPLES::
|
84
|
+
|
85
|
+
sage: from sage.rings.number_field.order_ideal import NumberFieldOrderIdeal
|
86
|
+
sage: R.<x> = QQ[]
|
87
|
+
sage: K.<t> = NumberField(x^3 - 40)
|
88
|
+
sage: O = K.order(t)
|
89
|
+
sage: I = NumberFieldOrderIdeal(O, [13, t-1]); I
|
90
|
+
Ideal (12*t^2 + 1, 12*t^2 + t, 13*t^2) of Order generated by t
|
91
|
+
in Number Field in t with defining polynomial x^3 - 40
|
92
|
+
sage: K.absolute_degree()
|
93
|
+
3
|
94
|
+
sage: type(I)
|
95
|
+
<class 'sage.rings.number_field.order_ideal.NumberFieldOrderIdeal_generic'>
|
96
|
+
|
97
|
+
::
|
98
|
+
|
99
|
+
sage: L.<u> = QuadraticField(-3)
|
100
|
+
sage: J = NumberFieldOrderIdeal(L.maximal_order(), [(u+5)/2])
|
101
|
+
sage: L.absolute_degree()
|
102
|
+
2
|
103
|
+
sage: type(J)
|
104
|
+
<class 'sage.rings.number_field.order_ideal.NumberFieldOrderIdeal_quadratic'>
|
105
|
+
"""
|
106
|
+
if O.absolute_degree() == 2:
|
107
|
+
cls = NumberFieldOrderIdeal_quadratic
|
108
|
+
else:
|
109
|
+
cls = NumberFieldOrderIdeal_generic
|
110
|
+
return cls(O, *args, **kwds)
|
111
|
+
|
112
|
+
|
113
|
+
class NumberFieldOrderIdeal_generic(Ideal_generic):
|
114
|
+
r"""
|
115
|
+
An ideal of a not necessarily maximal order in a number field.
|
116
|
+
"""
|
117
|
+
def __init__(self, O, gens, *, coerce=True):
|
118
|
+
r"""
|
119
|
+
Ideals of not necessarily maximal orders.
|
120
|
+
|
121
|
+
The preferred way to construct objects of this class is via
|
122
|
+
the :meth:`~sage.rings.number_field.order.Order.ideal` method.
|
123
|
+
|
124
|
+
EXAMPLES::
|
125
|
+
|
126
|
+
sage: R.<x> = QQ[]
|
127
|
+
sage: K.<t> = NumberField(x^3 - 40)
|
128
|
+
sage: O = K.order(t)
|
129
|
+
sage: I = O.ideal([13, t-1]); I
|
130
|
+
Ideal (12*t^2 + 1, 12*t^2 + t, 13*t^2) of Order generated by t
|
131
|
+
in Number Field in t with defining polynomial x^3 - 40
|
132
|
+
sage: I.norm()
|
133
|
+
13
|
134
|
+
"""
|
135
|
+
if not isinstance(O, sage.rings.number_field.order.Order):
|
136
|
+
raise TypeError('not a number-field order')
|
137
|
+
|
138
|
+
if not isinstance(gens, (list, tuple)):
|
139
|
+
gens = [gens]
|
140
|
+
|
141
|
+
if coerce:
|
142
|
+
gens = Sequence(gens, O)
|
143
|
+
|
144
|
+
_, from_V, to_V = O.number_field().absolute_vector_space()
|
145
|
+
span = [to_V(a*g) for a in O.basis() for g in gens]
|
146
|
+
self._module = O.free_module().submodule(span)
|
147
|
+
basis = [O(from_V(v)) for v in self._module.basis()]
|
148
|
+
|
149
|
+
super().__init__(O, basis, coerce=False)
|
150
|
+
|
151
|
+
def __hash__(self):
|
152
|
+
r"""
|
153
|
+
Return a hash value for this ideal.
|
154
|
+
|
155
|
+
EXAMPLES::
|
156
|
+
|
157
|
+
sage: hash(QuadraticField(-1).order(5*i).ideal(7)) # random
|
158
|
+
42
|
159
|
+
"""
|
160
|
+
return hash((NumberFieldOrderIdeal_generic, self.ring(), self._module))
|
161
|
+
|
162
|
+
def _richcmp_(self, other, op):
|
163
|
+
r"""
|
164
|
+
Implement comparison of ideals of number-field orders.
|
165
|
+
|
166
|
+
EXAMPLES::
|
167
|
+
|
168
|
+
sage: K.<t> = QuadraticField(-123)
|
169
|
+
sage: g, = K.ring_of_integers().ring_generators()
|
170
|
+
sage: O = K.order(567*g)
|
171
|
+
sage: I = O.ideal([191, 567*t-27]); I
|
172
|
+
Ideal (56133/2*t + 1/2, 108297*t) of Order of conductor 567 generated by 567/2*t + 1/2
|
173
|
+
in Number Field in t with defining polynomial x^2 + 123 with t = 11.09053650640942?*I
|
174
|
+
sage: I == I
|
175
|
+
True
|
176
|
+
sage: I != I
|
177
|
+
False
|
178
|
+
sage: I == I^2
|
179
|
+
False
|
180
|
+
"""
|
181
|
+
if not isinstance(other, NumberFieldOrderIdeal_generic):
|
182
|
+
return NotImplemented
|
183
|
+
if self.ring() != other.ring():
|
184
|
+
return NotImplemented
|
185
|
+
return richcmp(self._module, other._module, op)
|
186
|
+
|
187
|
+
def _contains_(self, x):
|
188
|
+
r"""
|
189
|
+
Test whether this ideal contains a given element.
|
190
|
+
|
191
|
+
EXAMPLES::
|
192
|
+
|
193
|
+
sage: K.<t> = QuadraticField(-123)
|
194
|
+
sage: g, = K.ring_of_integers().ring_generators()
|
195
|
+
sage: O = K.order(567*g)
|
196
|
+
sage: I = O.ideal([191, 567*t-27]); I
|
197
|
+
Ideal (56133/2*t + 1/2, 108297*t) of Order of conductor 567 generated by 567/2*t + 1/2
|
198
|
+
in Number Field in t with defining polynomial x^2 + 123 with t = 11.09053650640942?*I
|
199
|
+
sage: 0 in I
|
200
|
+
True
|
201
|
+
sage: -191 in I
|
202
|
+
True
|
203
|
+
sage: 1 in I
|
204
|
+
False
|
205
|
+
sage: 567*t in I
|
206
|
+
False
|
207
|
+
sage: t-91 in I
|
208
|
+
False
|
209
|
+
sage: t-91 in K.maximal_order().ideal(I.gens(), future=1)
|
210
|
+
True
|
211
|
+
"""
|
212
|
+
x = self.ring()(x)
|
213
|
+
return vector(QQ, x.list()) in self._module
|
214
|
+
|
215
|
+
def free_module(self):
|
216
|
+
r"""
|
217
|
+
Return the free `\ZZ`-module corresponding to this ideal
|
218
|
+
as a submodule of the vector space associated to the ambient
|
219
|
+
number field.
|
220
|
+
|
221
|
+
EXAMPLES::
|
222
|
+
|
223
|
+
sage: K.<t> = QuadraticField(-123)
|
224
|
+
sage: g, = K.ring_of_integers().ring_generators()
|
225
|
+
sage: O = K.order(567*g)
|
226
|
+
sage: I = O.ideal([191, 567*t-27]); I
|
227
|
+
Ideal (56133/2*t + 1/2, 108297*t) of Order of conductor 567 generated by 567/2*t + 1/2
|
228
|
+
in Number Field in t with defining polynomial x^2 + 123 with t = 11.09053650640942?*I
|
229
|
+
sage: I.free_module()
|
230
|
+
Free module of degree 2 and rank 2 over Integer Ring
|
231
|
+
Echelon basis matrix:
|
232
|
+
[ 1/2 56133/2]
|
233
|
+
[ 0 108297]
|
234
|
+
sage: I.free_module().is_submodule(O.free_module())
|
235
|
+
True
|
236
|
+
|
237
|
+
.. SEEALSO::
|
238
|
+
|
239
|
+
- :meth:`sage.rings.number_field.number_field.NumberField_absolute.absolute_vector_space`
|
240
|
+
- :meth:`sage.rings.number_field.order.Order.free_module`
|
241
|
+
- :meth:`sage.rings.number_field.number_field_ideal.NumberFieldIdeal.free_module`
|
242
|
+
"""
|
243
|
+
return self._module
|
244
|
+
|
245
|
+
def norm(self):
|
246
|
+
r"""
|
247
|
+
Return the norm of this ideal.
|
248
|
+
|
249
|
+
The norm is defined as the index (as an abelian group)
|
250
|
+
of the ideal in its order.
|
251
|
+
|
252
|
+
EXAMPLES::
|
253
|
+
|
254
|
+
sage: K.<t> = QuadraticField(-123)
|
255
|
+
sage: g, = K.ring_of_integers().ring_generators()
|
256
|
+
sage: O = K.order(567*g)
|
257
|
+
sage: I = O.ideal([191, 567*t-27])
|
258
|
+
sage: I.norm()
|
259
|
+
191
|
260
|
+
sage: (O.free_module() / I.free_module()).cardinality()
|
261
|
+
191
|
262
|
+
"""
|
263
|
+
return self.free_module().index_in(self.ring().free_module())
|
264
|
+
|
265
|
+
|
266
|
+
def _positive_sqrt(R, D):
|
267
|
+
r"""
|
268
|
+
Return the "positive" square root of `D` in `R`, which must be
|
269
|
+
a quadratic field or an order in a quadratic field.
|
270
|
+
|
271
|
+
EXAMPLES::
|
272
|
+
|
273
|
+
sage: from sage.rings.number_field.order_ideal import _positive_sqrt
|
274
|
+
sage: K = QuadraticField(-77)
|
275
|
+
sage: _positive_sqrt(K, 0)
|
276
|
+
0
|
277
|
+
sage: _positive_sqrt(K, -77)
|
278
|
+
a
|
279
|
+
sage: x = polygen(ZZ)
|
280
|
+
sage: O.<t> = EquationOrder(x^2 - x - 1)
|
281
|
+
sage: _positive_sqrt(O, O.number_field().discriminant())
|
282
|
+
2*t - 1
|
283
|
+
"""
|
284
|
+
if D.is_zero():
|
285
|
+
return R.zero()
|
286
|
+
sqrtD, = (s for s in R(D).sqrt(all=True) if s.real() > 0 or s.imag() > 0)
|
287
|
+
return sqrtD
|
288
|
+
|
289
|
+
|
290
|
+
def _gens_from_bqf(O, Q):
|
291
|
+
r"""
|
292
|
+
Helper function to compute generators of the ideal associated to
|
293
|
+
the given binary quadratic form.
|
294
|
+
|
295
|
+
The resulting map induces a left-inverse of
|
296
|
+
:meth:`NumberFieldOrderIdeal_quadratic.quadratic_form`
|
297
|
+
on equivalence classes.
|
298
|
+
|
299
|
+
REFERENCES:
|
300
|
+
|
301
|
+
The correspondence itself is classical.
|
302
|
+
Implemented after [Coh1993]_, §5.2.
|
303
|
+
|
304
|
+
EXAMPLES::
|
305
|
+
|
306
|
+
sage: K.<a> = QuadraticField(-18511)
|
307
|
+
sage: O = K.order([83/2*a+1/2,83*a])
|
308
|
+
sage: I = O.ideal([7868666196280491149/2*a + 107/2, 12934030292704639127*a])
|
309
|
+
sage: F = I.quadratic_form(); F
|
310
|
+
16673990859269835983*x^2 - 19847240181321592929*x*y + 5906098697962163510*y^2
|
311
|
+
sage: J = O.ideal(F); J
|
312
|
+
Ideal (7868666196280491149/2*a + 107/2, 12934030292704639127*a)
|
313
|
+
of Order of conductor 83 generated by 83/2*a + 1/2
|
314
|
+
in Number Field in a with defining polynomial x^2 + 18511 with a = 136.0551358824797?*I
|
315
|
+
sage: G = J.quadratic_form(); G
|
316
|
+
16673990859269835983*x^2 - 19847240181321592929*x*y + 5906098697962163510*y^2
|
317
|
+
sage: u = -479159/2*a + 665/2
|
318
|
+
sage: J *= u; J
|
319
|
+
Ideal (19274211614964208316630114412627/2*a + 43763/2, 33600036954602803764386186323012*a)
|
320
|
+
of Order of conductor 83 generated by 83/2*a + 1/2
|
321
|
+
in Number Field in a with defining polynomial x^2 + 18511 with a = 136.0551358824797?*I
|
322
|
+
sage: H = J.quadratic_form()
|
323
|
+
sage: H.is_equivalent(F)
|
324
|
+
True
|
325
|
+
|
326
|
+
TESTS:
|
327
|
+
|
328
|
+
Randomized testing::
|
329
|
+
|
330
|
+
sage: from sage.rings.number_field.order_ideal import _random_for_testing
|
331
|
+
sage: O, random_ideal = _random_for_testing()
|
332
|
+
sage: I = random_ideal()
|
333
|
+
sage: F = I.quadratic_form()
|
334
|
+
sage: M = matrix.random_unimodular(MatrixSpace(ZZ,2))
|
335
|
+
sage: assert M.det() == 1
|
336
|
+
sage: G = F.matrix_action_left(M)
|
337
|
+
sage: G.discriminant() == F.discriminant()
|
338
|
+
True
|
339
|
+
sage: J = O.ideal(G, future=1)
|
340
|
+
sage: J.quadratic_form().is_equivalent(G)
|
341
|
+
True
|
342
|
+
"""
|
343
|
+
D = O.discriminant()
|
344
|
+
if Q.discriminant() != O.discriminant():
|
345
|
+
raise ValueError('order and form must have the same discriminant')
|
346
|
+
a, b, c = Q
|
347
|
+
sqrtD = _positive_sqrt(O.number_field(), D)
|
348
|
+
g = (- b + sqrtD) / 2
|
349
|
+
t = sqrtD if a < 0 else 1
|
350
|
+
return a*t, g*t
|
351
|
+
|
352
|
+
|
353
|
+
class NumberFieldOrderIdeal_quadratic(NumberFieldOrderIdeal_generic):
|
354
|
+
r"""
|
355
|
+
An ideal of a not necessarily maximal order in a *quadratic* number field.
|
356
|
+
"""
|
357
|
+
def __init__(self, O, gens, *, coerce=True):
|
358
|
+
r"""
|
359
|
+
Ideals of *quadratic* orders are implemented by a specialized
|
360
|
+
class because they have some extra features not present in
|
361
|
+
general number fields.
|
362
|
+
|
363
|
+
The preferred way to construct objects of this class is via
|
364
|
+
the :meth:`~sage.rings.number_field.order.Order.ideal` method
|
365
|
+
(or the ``O*a`` convenience syntax).
|
366
|
+
|
367
|
+
EXAMPLES::
|
368
|
+
|
369
|
+
sage: K.<t> = QuadraticField(-100)
|
370
|
+
sage: O = K.order(t)
|
371
|
+
sage: type(O.ideal(7))
|
372
|
+
<class 'sage.rings.number_field.order_ideal.NumberFieldOrderIdeal_quadratic'>
|
373
|
+
sage: O*7 == O.ideal(7)
|
374
|
+
True
|
375
|
+
"""
|
376
|
+
from sage.quadratic_forms.binary_qf import BinaryQF
|
377
|
+
if isinstance(gens, BinaryQF):
|
378
|
+
gens = _gens_from_bqf(O, gens)
|
379
|
+
coerce = False
|
380
|
+
super().__init__(O, gens, coerce=coerce)
|
381
|
+
|
382
|
+
def conjugate(self):
|
383
|
+
r"""
|
384
|
+
Return the conjugate of this ideal, defined by conjugating
|
385
|
+
the generators.
|
386
|
+
|
387
|
+
EXAMPLES::
|
388
|
+
|
389
|
+
sage: K.<t> = QuadraticField(-123)
|
390
|
+
sage: g, = K.ring_of_integers().ring_generators()
|
391
|
+
sage: O = K.order(567*g)
|
392
|
+
sage: I = O.ideal([191, 567*t-27])
|
393
|
+
sage: I.norm()
|
394
|
+
191
|
395
|
+
sage: I.norm() in I.conjugate() * I
|
396
|
+
True
|
397
|
+
sage: I.conjugate() * I == I.norm() * O
|
398
|
+
True
|
399
|
+
"""
|
400
|
+
conj_gens = [g.conjugate() for g in self.gens()]
|
401
|
+
return NumberFieldOrderIdeal(self.ring(), conj_gens)
|
402
|
+
|
403
|
+
def gens_two(self) -> tuple:
|
404
|
+
r"""
|
405
|
+
Express this ideal using exactly two generators, the first of
|
406
|
+
which is a generator for the intersection of the ideal with `\ZZ`.
|
407
|
+
|
408
|
+
EXAMPLES::
|
409
|
+
|
410
|
+
sage: K.<t> = QuadraticField(-100)
|
411
|
+
sage: O = K.order(t)
|
412
|
+
sage: I = O.ideal([123, 131-t, 21+23*t])
|
413
|
+
sage: I.gens_two()
|
414
|
+
(41, t - 8)
|
415
|
+
sage: I == O.ideal(I.gens_two())
|
416
|
+
True
|
417
|
+
|
418
|
+
The second generator is zero if and only if the ideal is
|
419
|
+
generated by an integer::
|
420
|
+
|
421
|
+
sage: J = O.ideal([-33*t, 11*t-6589])
|
422
|
+
sage: J.gens_two()
|
423
|
+
(11, 0)
|
424
|
+
sage: J == O.ideal(11)
|
425
|
+
True
|
426
|
+
|
427
|
+
.. WARNING::
|
428
|
+
|
429
|
+
The returned generators do *not* necessarily
|
430
|
+
form a `\ZZ`-basis of the ideal.
|
431
|
+
|
432
|
+
TESTS:
|
433
|
+
|
434
|
+
Random testing::
|
435
|
+
|
436
|
+
sage: from sage.rings.number_field.order_ideal import _random_for_testing
|
437
|
+
sage: O, random_ideal = _random_for_testing()
|
438
|
+
sage: I = random_ideal()
|
439
|
+
sage: gs2 = I.gens_two()
|
440
|
+
sage: len(gs2)
|
441
|
+
2
|
442
|
+
sage: all(g in O for g in gs2)
|
443
|
+
True
|
444
|
+
sage: O.ideal(gs2, future=1) == I
|
445
|
+
True
|
446
|
+
"""
|
447
|
+
O = self.ring()
|
448
|
+
if self.is_zero():
|
449
|
+
return (O.zero(),)*2
|
450
|
+
M = self._module & (ZZ**2).submodule([(1,0)])
|
451
|
+
(N,_), = M.gens()
|
452
|
+
NOgens = [N*g for g in O.free_module().basis()]
|
453
|
+
Q = self._module / self._module.submodule(NOgens)
|
454
|
+
if Q.invariants():
|
455
|
+
assert len(Q.invariants()) == 1
|
456
|
+
_, from_V, _ = O.number_field().absolute_vector_space()
|
457
|
+
alpha, = (from_V(g.lift()) for g in Q.gens())
|
458
|
+
else:
|
459
|
+
alpha = 0
|
460
|
+
return tuple(map(O, (N, alpha)))
|
461
|
+
|
462
|
+
def is_principal(self):
|
463
|
+
r"""
|
464
|
+
Determine whether or not this ideal is principal.
|
465
|
+
|
466
|
+
.. SEEALSO::
|
467
|
+
|
468
|
+
To find a generator, use :meth:`gens_reduced`.
|
469
|
+
|
470
|
+
EXAMPLES:
|
471
|
+
|
472
|
+
sage: K.<a> = QuadraticField(-163)
|
473
|
+
sage: O = K.order(7*a)
|
474
|
+
sage: O.class_number()
|
475
|
+
24
|
476
|
+
sage: order = lambda v: next(e for e in range(1,99) if (v^e).is_principal())
|
477
|
+
sage: I = O.ideal([47, 7*a-35])
|
478
|
+
sage: order(I)
|
479
|
+
24
|
480
|
+
sage: J = O.ideal([71, 7*a-65])
|
481
|
+
sage: order(J)
|
482
|
+
12
|
483
|
+
sage: next(e for e in range(99) if (I^e * J.conjugate()).is_principal())
|
484
|
+
10
|
485
|
+
sage: (I^10 * J.conjugate()).is_principal()
|
486
|
+
True
|
487
|
+
|
488
|
+
::
|
489
|
+
|
490
|
+
sage: K.<a> = QuadraticField(229)
|
491
|
+
sage: O = K.order(7*a)
|
492
|
+
sage: I = O.ideal([3, 7*a-2])
|
493
|
+
sage: J = O.ideal([5, 7*a-4])
|
494
|
+
sage: (I * J.conjugate()).is_principal()
|
495
|
+
True
|
496
|
+
sage: el = 104 + 7*a
|
497
|
+
sage: el.norm()
|
498
|
+
-405
|
499
|
+
sage: (I * (J * el).conjugate()).is_principal()
|
500
|
+
True
|
501
|
+
"""
|
502
|
+
if self.is_zero():
|
503
|
+
return True
|
504
|
+
f = self.quadratic_form()
|
505
|
+
sol = f.solve_integer(1)
|
506
|
+
if sol is None:
|
507
|
+
sol = f.solve_integer(-1)
|
508
|
+
return sol is not None
|
509
|
+
|
510
|
+
def gens_reduced(self) -> tuple:
|
511
|
+
r"""
|
512
|
+
Express this ideal in terms of at most two generators,
|
513
|
+
and one if possible (i.e., if the ideal is principal).
|
514
|
+
|
515
|
+
EXAMPLES::
|
516
|
+
|
517
|
+
sage: x = polygen(QQ)
|
518
|
+
sage: K.<a> = NumberField(x^2 + 11*x + 5)
|
519
|
+
sage: O = K.order(7*a)
|
520
|
+
sage: I = O.ideal([31915, -71145879*a - 32195694])
|
521
|
+
sage: I.gens_reduced()
|
522
|
+
(-63*a + 17,)
|
523
|
+
|
524
|
+
ALGORITHM:
|
525
|
+
|
526
|
+
Compute a reduction of the :meth:`quadratic_form` to see
|
527
|
+
if it represents `1`, then use the transformation matrix
|
528
|
+
to find an element in the ideal whose norm equals the
|
529
|
+
norm of the ideal.
|
530
|
+
|
531
|
+
TESTS::
|
532
|
+
|
533
|
+
sage: from sage.rings.number_field.order_ideal import _random_for_testing
|
534
|
+
sage: O, random_ideal = _random_for_testing()
|
535
|
+
sage: I = random_ideal()
|
536
|
+
sage: gs = I.gens_reduced()
|
537
|
+
sage: len(gs) in (1,2)
|
538
|
+
True
|
539
|
+
sage: all(g in O for g in gs)
|
540
|
+
True
|
541
|
+
sage: (len(gs) == 1) == I.is_principal()
|
542
|
+
True
|
543
|
+
sage: O.ideal(gs, future=1) == I
|
544
|
+
True
|
545
|
+
"""
|
546
|
+
if self.is_zero():
|
547
|
+
return (self.ring().zero(),)
|
548
|
+
f, bas = self.quadratic_form(basis=True)
|
549
|
+
sol = f.solve_integer(1)
|
550
|
+
if sol is None:
|
551
|
+
sol = f.solve_integer(-1)
|
552
|
+
if sol is None:
|
553
|
+
return self.gens_two()
|
554
|
+
gen = sum(c * g for c, g in zip(sol, bas))
|
555
|
+
assert NumberFieldOrderIdeal(self.ring(), gen) == self
|
556
|
+
return (gen,)
|
557
|
+
|
558
|
+
def is_equivalent(self, other, narrow=False):
|
559
|
+
r"""
|
560
|
+
Determine whether this ideal is equivalent to another ideal
|
561
|
+
in the same order.
|
562
|
+
|
563
|
+
If ``narrow`` is ``True``, test narrow equivalence instead.
|
564
|
+
|
565
|
+
(Two ideals are equivalent if they differ by multiplication
|
566
|
+
by a nonzero element. They are narrowly equivalent if they
|
567
|
+
differ by multiplication by an element of positive norm.)
|
568
|
+
|
569
|
+
EXAMPLES::
|
570
|
+
|
571
|
+
sage: K.<a> = QuadraticField(-163)
|
572
|
+
sage: O = K.order(7*a)
|
573
|
+
sage: I = O.ideal([47, 7*a-35])
|
574
|
+
sage: J = O.ideal([71, 7*a-65])
|
575
|
+
sage: I.is_equivalent(J)
|
576
|
+
False
|
577
|
+
sage: (I^10).is_equivalent(J)
|
578
|
+
True
|
579
|
+
|
580
|
+
::
|
581
|
+
|
582
|
+
sage: K.<a> = QuadraticField(229)
|
583
|
+
sage: O = K.order(7*a)
|
584
|
+
sage: O.class_number()
|
585
|
+
3
|
586
|
+
sage: I = O.ideal([3, 7*a-2])
|
587
|
+
sage: J = O.ideal([5, 7*a-4])
|
588
|
+
sage: I.is_equivalent(J)
|
589
|
+
True
|
590
|
+
|
591
|
+
::
|
592
|
+
|
593
|
+
sage: K.<a> = QuadraticField(273)
|
594
|
+
sage: O = K.order(11*a)
|
595
|
+
sage: O.class_number()
|
596
|
+
20
|
597
|
+
sage: I = O.ideal([17, 11*a-11])
|
598
|
+
sage: J = O.ideal([19, 11*a-12])
|
599
|
+
sage: I.is_equivalent(J)
|
600
|
+
False
|
601
|
+
sage: (I^3).is_equivalent(J)
|
602
|
+
False
|
603
|
+
sage: (I^6).is_equivalent(J^2)
|
604
|
+
True
|
605
|
+
sage: el = 177 + 11*a
|
606
|
+
sage: el.norm()
|
607
|
+
-1704
|
608
|
+
sage: (I^6).is_equivalent(J^2, narrow=True)
|
609
|
+
True
|
610
|
+
sage: (I^6).is_equivalent(J^2*el, narrow=True)
|
611
|
+
False
|
612
|
+
"""
|
613
|
+
if self.ring() != other.ring():
|
614
|
+
raise ValueError('ideals must lie in the same order')
|
615
|
+
if self.is_zero():
|
616
|
+
return other.is_zero()
|
617
|
+
if other.is_zero():
|
618
|
+
return False
|
619
|
+
gs = (self * other.conjugate()).gens_reduced()
|
620
|
+
assert len(gs) in (1,2)
|
621
|
+
if len(gs) > 1:
|
622
|
+
return False
|
623
|
+
elif narrow:
|
624
|
+
return gs[0].norm() > 0
|
625
|
+
return True
|
626
|
+
|
627
|
+
def quadratic_form(self, *, basis=False):
|
628
|
+
r"""
|
629
|
+
Return the binary quadratic form associated to this ideal.
|
630
|
+
|
631
|
+
This map induces an injective homomorphism from the narrow
|
632
|
+
class group on ideals to the class group on quadratic forms.
|
633
|
+
|
634
|
+
If ``basis`` is set to ``True`` (default: ``False``), the
|
635
|
+
method additionally returns a `\ZZ`-basis `(a,b)` of this
|
636
|
+
ideal `I` such that `f(x,y)` equals
|
637
|
+
`\mathrm{norm}(xa+yb) / \mathrm{norm}(I)`,
|
638
|
+
where `f` is the returned quadratic form.
|
639
|
+
|
640
|
+
.. NOTE::
|
641
|
+
|
642
|
+
The narrow class group is the group of invertible ideals
|
643
|
+
modulo the principal ideals generated by an element of
|
644
|
+
positive norm.
|
645
|
+
|
646
|
+
- For *imaginary* quadratic orders, the narrow class group
|
647
|
+
is identical to the class group.
|
648
|
+
|
649
|
+
- For *real* quadratic orders, identifying the classes of
|
650
|
+
`f(x,y)` and `-f(y,x)` recovers a correspondence with the
|
651
|
+
standard class group.
|
652
|
+
|
653
|
+
REFERENCES:
|
654
|
+
|
655
|
+
The correspondence itself is classical.
|
656
|
+
Implemented after [Coh1993]_, §5.2.
|
657
|
+
|
658
|
+
.. SEEALSO::
|
659
|
+
|
660
|
+
:meth:`sage.rings.number_field.number_field_ideal.NumberFieldFractionalIdeal.quadratic_form`
|
661
|
+
|
662
|
+
EXAMPLES::
|
663
|
+
|
664
|
+
sage: K.<t> = QuadraticField(-419)
|
665
|
+
sage: O = K.order(t)
|
666
|
+
sage: O.discriminant().factor()
|
667
|
+
-1 * 2^2 * 419
|
668
|
+
sage: I = O.ideal([t-1, 105]); I
|
669
|
+
Ideal (104*t + 1, 105*t) of Order of conductor 2 generated by t
|
670
|
+
in Number Field in t with defining polynomial x^2 + 419 with t = 20.46948949045873?*I
|
671
|
+
sage: f = I.quadratic_form(); f
|
672
|
+
105*x^2 - 208*x*y + 107*y^2
|
673
|
+
sage: f.discriminant().factor()
|
674
|
+
-1 * 2^2 * 419
|
675
|
+
sage: power(f,3).reduced_form()
|
676
|
+
x^2 + 419*y^2
|
677
|
+
|
678
|
+
::
|
679
|
+
|
680
|
+
sage: u = 23*t - 45
|
681
|
+
sage: J = I*u
|
682
|
+
sage: g = J.quadratic_form(); g
|
683
|
+
23485980*x^2 - 22795498*x*y + 5531329*y^2
|
684
|
+
sage: f.is_equivalent(g)
|
685
|
+
True
|
686
|
+
|
687
|
+
The inverse operation (modulo equivalence) can be computed by
|
688
|
+
passing a :class:`~sage.quadratic_forms.binary_qf.BinaryQF`
|
689
|
+
to ``O.ideal()``::
|
690
|
+
|
691
|
+
sage: II = O.ideal(f); II
|
692
|
+
Ideal (104*t + 1, 105*t) of Order of conductor 2 generated by t
|
693
|
+
in Number Field in t with defining polynomial x^2 + 419 with t = 20.46948949045873?*I
|
694
|
+
sage: II.quadratic_form().is_equivalent(f)
|
695
|
+
True
|
696
|
+
|
697
|
+
TESTS:
|
698
|
+
|
699
|
+
Randomized testing (principal ideals generated by an element
|
700
|
+
of positive norm map to the principal form)::
|
701
|
+
|
702
|
+
sage: from sage.rings.number_field.order_ideal import _random_for_testing
|
703
|
+
sage: O, _ = _random_for_testing()
|
704
|
+
sage: D = O.discriminant()
|
705
|
+
sage: gen = (O.random_element() for _ in iter(int,1))
|
706
|
+
sage: g = next(el for el in gen if el.norm() > 0)
|
707
|
+
sage: I = O.ideal(g, future=1)
|
708
|
+
sage: F = I.quadratic_form()
|
709
|
+
sage: F.is_equivalent(BinaryQF.principal(D))
|
710
|
+
True
|
711
|
+
|
712
|
+
Randomized testing (mapping is a homomorphism)::
|
713
|
+
|
714
|
+
sage: from sage.rings.number_field.order_ideal import _random_for_testing
|
715
|
+
sage: O, random_ideal = _random_for_testing()
|
716
|
+
sage: I = random_ideal()
|
717
|
+
sage: J = random_ideal()
|
718
|
+
sage: F = I.quadratic_form()
|
719
|
+
sage: G = J.quadratic_form()
|
720
|
+
sage: # Once future=1 is the default, the following line can be K = I * J
|
721
|
+
sage: K = O.ideal([g*h for g in I.gens() for h in J.gens()], future=1)
|
722
|
+
sage: H = K.quadratic_form()
|
723
|
+
sage: F.discriminant() == G.discriminant() == H.discriminant() == O.discriminant()
|
724
|
+
True
|
725
|
+
sage: H.is_equivalent(F*G)
|
726
|
+
True
|
727
|
+
|
728
|
+
Constructing an ideal from a form is indeed a one-sided inverse::
|
729
|
+
|
730
|
+
sage: II = O.ideal(F, future=1)
|
731
|
+
sage: II.quadratic_form().is_equivalent(F)
|
732
|
+
True
|
733
|
+
"""
|
734
|
+
if self.is_zero():
|
735
|
+
if basis:
|
736
|
+
return BinaryQF(0), (self.ring().zero(),)*2
|
737
|
+
return BinaryQF(0)
|
738
|
+
|
739
|
+
O = self.ring()
|
740
|
+
sqrtD = _positive_sqrt(O.number_field(), O.discriminant())
|
741
|
+
|
742
|
+
# find a "good" ZZ-basis of the ideal
|
743
|
+
M = self._module.basis_matrix()[:,::-1]
|
744
|
+
M = M.row_space(ZZ).basis_matrix()[:,::-1]
|
745
|
+
beta, alpha = map(O, M.rows())
|
746
|
+
assert alpha in QQ
|
747
|
+
if QQ(alpha * (beta - beta.galois_conjugate()) / sqrtD) < 0:
|
748
|
+
alpha = -alpha
|
749
|
+
|
750
|
+
# compute the (reduced) norm form of the ideal
|
751
|
+
A,B = (g.matrix() for g in (alpha, beta))
|
752
|
+
x,y = polygens(QQ, 'x,y')
|
753
|
+
Q = (x*A - y*B).determinant() / self.norm()
|
754
|
+
Q = Q.change_ring(ZZ)
|
755
|
+
|
756
|
+
from sage.quadratic_forms.binary_qf import BinaryQF
|
757
|
+
Q = BinaryQF(Q)
|
758
|
+
assert Q.discriminant() == O.discriminant()
|
759
|
+
return (Q, (alpha, -beta)) if basis else Q
|
760
|
+
|
761
|
+
|
762
|
+
def _random_for_testing():
|
763
|
+
r"""
|
764
|
+
A small helper function to produce somewhat random examples
|
765
|
+
of ideals of (not necessarily maximal) quadratic orders.
|
766
|
+
|
767
|
+
Used in doctests.
|
768
|
+
|
769
|
+
EXAMPLES::
|
770
|
+
|
771
|
+
sage: from sage.rings.number_field.order_ideal import _random_for_testing
|
772
|
+
sage: O, random_ideal = _random_for_testing()
|
773
|
+
sage: random_ideal().ring() is O
|
774
|
+
True
|
775
|
+
"""
|
776
|
+
from sage.misc.prandom import choice, randrange
|
777
|
+
from sage.rings.number_field.number_field import QuadraticField
|
778
|
+
from sage.arith.misc import primes
|
779
|
+
from sage.rings.finite_rings.integer_mod_ring import Zmod
|
780
|
+
while True:
|
781
|
+
d = ZZ(choice((-1, +1)) * randrange(1, 10**5))
|
782
|
+
if not d.is_square():
|
783
|
+
break
|
784
|
+
K,t = QuadraticField(d).objgen()
|
785
|
+
g, = K.ring_of_integers().ring_generators()
|
786
|
+
|
787
|
+
f = randrange(1, 100)
|
788
|
+
O = K.order(f*g)
|
789
|
+
assert O.discriminant() == f**2 * K.discriminant()
|
790
|
+
|
791
|
+
poly = (f*g).minpoly()
|
792
|
+
base = []
|
793
|
+
for l in primes(1000):
|
794
|
+
vs = poly.roots(ring=Zmod(l), multiplicities=False)
|
795
|
+
base += [NumberFieldOrderIdeal(O, [l, f*g-ZZ(v)]) for v in vs]
|
796
|
+
|
797
|
+
def random_ideal():
|
798
|
+
I = NumberFieldOrderIdeal(O, [1])
|
799
|
+
for _ in range(randrange(20)):
|
800
|
+
J = choice(base)
|
801
|
+
I = NumberFieldOrderIdeal(O, [x*y for x in I.gens() for y in J.gens()])
|
802
|
+
return I
|
803
|
+
|
804
|
+
return O, random_ideal
|