passagemath-flint 10.6.1rc10__cp313-cp313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-313-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-313-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-313-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-313-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-313-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-313-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-313-x86_64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-313-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-313-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,925 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
# sage.doctest: needs sage.rings.number_field
|
3
|
+
r"""
|
4
|
+
Ideals of relative number fields
|
5
|
+
|
6
|
+
EXAMPLES::
|
7
|
+
|
8
|
+
sage: x = polygen(ZZ, 'x')
|
9
|
+
sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2])
|
10
|
+
sage: A = K.absolute_field('z')
|
11
|
+
sage: I = A.factor(7)[0][0]
|
12
|
+
sage: from_A, to_A = A.structure()
|
13
|
+
sage: G = [from_A(z) for z in I.gens()]; G
|
14
|
+
[7, -2*b*a - 1]
|
15
|
+
sage: K.fractional_ideal(G)
|
16
|
+
Fractional ideal ((-1/2*b + 2)*a - 1/2*b - 2)
|
17
|
+
sage: K.fractional_ideal(G).absolute_norm().factor()
|
18
|
+
7^2
|
19
|
+
|
20
|
+
AUTHORS:
|
21
|
+
|
22
|
+
- Steven Sivek (2005-05-16)
|
23
|
+
- William Stein (2007-09-06)
|
24
|
+
- Nick Alexander (2009-01)
|
25
|
+
"""
|
26
|
+
|
27
|
+
#*****************************************************************************
|
28
|
+
# Copyright (C) 2007 William Stein <wstein@gmail.com>
|
29
|
+
#
|
30
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
31
|
+
# as published by the Free Software Foundation; either version 2 of
|
32
|
+
# the License, or (at your option) any later version.
|
33
|
+
# http://www.gnu.org/licenses/
|
34
|
+
#*****************************************************************************
|
35
|
+
|
36
|
+
|
37
|
+
from .number_field_ideal import NumberFieldFractionalIdeal
|
38
|
+
from sage.structure.factorization import Factorization
|
39
|
+
from sage.structure.proof.proof import get_flag
|
40
|
+
from sage.structure.richcmp import richcmp
|
41
|
+
|
42
|
+
import sage.rings.rational_field as rational_field
|
43
|
+
import sage.rings.integer_ring as integer_ring
|
44
|
+
QQ = rational_field.RationalField()
|
45
|
+
ZZ = integer_ring.IntegerRing()
|
46
|
+
|
47
|
+
|
48
|
+
class NumberFieldFractionalIdeal_rel(NumberFieldFractionalIdeal):
|
49
|
+
"""
|
50
|
+
An ideal of a relative number field.
|
51
|
+
|
52
|
+
EXAMPLES::
|
53
|
+
|
54
|
+
sage: x = polygen(ZZ, 'x')
|
55
|
+
sage: K.<a> = NumberField([x^2 + 1, x^2 + 2]); K
|
56
|
+
Number Field in a0 with defining polynomial x^2 + 1 over its base field
|
57
|
+
sage: i = K.ideal(38); i
|
58
|
+
Fractional ideal (38)
|
59
|
+
|
60
|
+
sage: K.<a0, a1> = NumberField([x^2 + 1, x^2 + 2]); K
|
61
|
+
Number Field in a0 with defining polynomial x^2 + 1 over its base field
|
62
|
+
sage: i = K.ideal([a0+1]); i # random
|
63
|
+
Fractional ideal (-a1*a0)
|
64
|
+
sage: (g, ) = i.gens_reduced(); g # random
|
65
|
+
-a1*a0
|
66
|
+
sage: (g / (a0 + 1)).is_integral()
|
67
|
+
True
|
68
|
+
sage: ((a0 + 1) / g).is_integral()
|
69
|
+
True
|
70
|
+
|
71
|
+
TESTS:
|
72
|
+
|
73
|
+
One test fails, because ideals aren't fully integrated into the
|
74
|
+
categories framework yet::
|
75
|
+
|
76
|
+
sage: TestSuite(i).run()
|
77
|
+
Failure in _test_category:
|
78
|
+
...
|
79
|
+
The following tests failed: _test_category
|
80
|
+
"""
|
81
|
+
def _richcmp_(self, other, op):
|
82
|
+
"""
|
83
|
+
Compare an ideal of a relative number field to something else.
|
84
|
+
|
85
|
+
EXAMPLES::
|
86
|
+
|
87
|
+
sage: x = polygen(ZZ, 'x')
|
88
|
+
sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7])
|
89
|
+
sage: I = K.ideal(2, (a + 2*b + 3)/2)
|
90
|
+
sage: J = K.ideal(2, a - b)
|
91
|
+
sage: I == J
|
92
|
+
False
|
93
|
+
"""
|
94
|
+
if not isinstance(other, NumberFieldFractionalIdeal):
|
95
|
+
return NotImplemented
|
96
|
+
return richcmp(self.pari_hnf().sage(), other.pari_hnf().sage(), op)
|
97
|
+
|
98
|
+
def _contains_(self, x):
|
99
|
+
"""
|
100
|
+
Return ``True`` if `x` is an element of this ideal.
|
101
|
+
|
102
|
+
This function is called (indirectly) when the ``in`` operator is used.
|
103
|
+
|
104
|
+
EXAMPLES::
|
105
|
+
|
106
|
+
sage: x = polygen(ZZ, 'x')
|
107
|
+
sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7])
|
108
|
+
sage: I = K.ideal(2, (a + 2*b + 3)/2)
|
109
|
+
sage: [z in I for z in [a, b, 2, a + b]] # indirect doctest
|
110
|
+
[False, False, True, True]
|
111
|
+
"""
|
112
|
+
abs_ideal = self.absolute_ideal()
|
113
|
+
to_abs = abs_ideal.number_field().structure()[1]
|
114
|
+
return to_abs(x) in abs_ideal
|
115
|
+
|
116
|
+
def pari_rhnf(self):
|
117
|
+
"""
|
118
|
+
Return PARI's representation of this relative ideal in Hermite
|
119
|
+
normal form.
|
120
|
+
|
121
|
+
EXAMPLES::
|
122
|
+
|
123
|
+
sage: x = polygen(ZZ, 'x')
|
124
|
+
sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7])
|
125
|
+
sage: I = K.ideal(2, (a + 2*b + 3)/2)
|
126
|
+
sage: I.pari_rhnf()
|
127
|
+
[[1, -2; 0, 1], [[2, 1; 0, 1], 1/2]]
|
128
|
+
"""
|
129
|
+
try:
|
130
|
+
return self.__pari_rhnf
|
131
|
+
except AttributeError:
|
132
|
+
nfzk = self.number_field().pari_nf().nf_subst('x').nf_get_zk()
|
133
|
+
rnf = self.number_field().pari_rnf()
|
134
|
+
L_hnf = self.absolute_ideal().pari_hnf()
|
135
|
+
self.__pari_rhnf = rnf.rnfidealabstorel(nfzk * L_hnf)
|
136
|
+
return self.__pari_rhnf
|
137
|
+
|
138
|
+
def absolute_ideal(self, names='a'):
|
139
|
+
r"""
|
140
|
+
If this is an ideal in the extension `L/K`, return the ideal with
|
141
|
+
the same generators in the absolute field `L/\QQ`.
|
142
|
+
|
143
|
+
INPUT:
|
144
|
+
|
145
|
+
- ``names`` -- (optional) string; name of generator of the absolute
|
146
|
+
field
|
147
|
+
|
148
|
+
EXAMPLES::
|
149
|
+
|
150
|
+
sage: x = ZZ['x'].0
|
151
|
+
sage: K.<b> = NumberField(x^2 - 2)
|
152
|
+
sage: L.<c> = K.extension(x^2 - b)
|
153
|
+
sage: F.<m> = L.absolute_field()
|
154
|
+
|
155
|
+
An example of an inert ideal::
|
156
|
+
|
157
|
+
sage: P = F.factor(13)[0][0]; P
|
158
|
+
Fractional ideal (13)
|
159
|
+
sage: J = L.ideal(13)
|
160
|
+
sage: J.absolute_ideal()
|
161
|
+
Fractional ideal (13)
|
162
|
+
|
163
|
+
Now a non-trivial ideal in `L` that is principal in the
|
164
|
+
subfield `K`. Since the optional ``names`` argument is not
|
165
|
+
passed, the generators of the absolute ideal `J` are returned
|
166
|
+
in terms of the default field generator `a`. This does not agree
|
167
|
+
with the generator `m` of the absolute field `F` defined above::
|
168
|
+
|
169
|
+
sage: J = L.ideal(b); J
|
170
|
+
Fractional ideal (b)
|
171
|
+
sage: J.absolute_ideal()
|
172
|
+
Fractional ideal (a^2)
|
173
|
+
sage: J.relative_norm()
|
174
|
+
Fractional ideal (2)
|
175
|
+
sage: J.absolute_norm()
|
176
|
+
4
|
177
|
+
sage: J.absolute_ideal().norm()
|
178
|
+
4
|
179
|
+
|
180
|
+
Now pass `m` as the name for the generator of the absolute field::
|
181
|
+
|
182
|
+
sage: J.absolute_ideal('m')
|
183
|
+
Fractional ideal (m^2)
|
184
|
+
|
185
|
+
Now an ideal not generated by an element of `K`::
|
186
|
+
|
187
|
+
sage: J = L.ideal(c); J
|
188
|
+
Fractional ideal (c)
|
189
|
+
sage: J.absolute_ideal()
|
190
|
+
Fractional ideal (a)
|
191
|
+
sage: J.absolute_norm()
|
192
|
+
2
|
193
|
+
sage: J.ideal_below()
|
194
|
+
Fractional ideal (-b)
|
195
|
+
sage: J.ideal_below().norm()
|
196
|
+
2
|
197
|
+
"""
|
198
|
+
try:
|
199
|
+
return self.__absolute_ideal[names]
|
200
|
+
except KeyError:
|
201
|
+
pass
|
202
|
+
except AttributeError:
|
203
|
+
self.__absolute_ideal = {}
|
204
|
+
L = self.number_field().absolute_field(names)
|
205
|
+
genlist = [L(x.polynomial() ) for x in self.gens() ]
|
206
|
+
M = L.ideal(genlist)
|
207
|
+
self.__absolute_ideal[names] = M
|
208
|
+
return M
|
209
|
+
|
210
|
+
def _from_absolute_ideal(self, id):
|
211
|
+
r"""
|
212
|
+
Convert the absolute ideal ``id`` to a relative number field ideal.
|
213
|
+
|
214
|
+
WARNING: This is an internal helper function.
|
215
|
+
|
216
|
+
TESTS::
|
217
|
+
|
218
|
+
sage: x = polygen(ZZ, 'x')
|
219
|
+
sage: L.<a, b> = QQ.extension([x^2 + 71, x^3 + 2*x + 1])
|
220
|
+
sage: (2*a + b).norm()
|
221
|
+
22584817
|
222
|
+
sage: J = L.ideal(2*a + b)
|
223
|
+
sage: 2*a + b in J
|
224
|
+
True
|
225
|
+
sage: J.absolute_norm()
|
226
|
+
22584817
|
227
|
+
sage: Labs.<c> = L.absolute_field(); Labs # random (polynomial not unique)
|
228
|
+
Number Field in c with defining polynomial x^6 + 217*x^4 - 2*x^3 + 15127*x^2 + 422*x + 338032
|
229
|
+
sage: Jabs = J.absolute_ideal(names='c')
|
230
|
+
sage: Jabs == Labs.ideal(22584817, -1473/812911*c^5 + 8695/4877466*c^4 - 1308209/4877466*c^3 + 117415/443406*c^2 - 22963264/2438733*c - 13721081784272/2438733)
|
231
|
+
True
|
232
|
+
sage: Jabs.norm()
|
233
|
+
22584817
|
234
|
+
sage: J._from_absolute_ideal(Jabs) == J
|
235
|
+
True
|
236
|
+
"""
|
237
|
+
f, _ = id.number_field().structure()
|
238
|
+
return self.number_field().ideal([f(_) for _ in id.gens()])
|
239
|
+
|
240
|
+
def free_module(self):
|
241
|
+
r"""
|
242
|
+
Return this ideal as a `\ZZ`-submodule of the `\QQ`-vector
|
243
|
+
space corresponding to the ambient number field.
|
244
|
+
|
245
|
+
EXAMPLES::
|
246
|
+
|
247
|
+
sage: x = polygen(ZZ, 'x')
|
248
|
+
sage: K.<a, b> = NumberField([x^3 - x + 1, x^2 + 23])
|
249
|
+
sage: I = K.ideal(a*b - 1)
|
250
|
+
sage: I.free_module()
|
251
|
+
Free module of degree 6 and rank 6 over Integer Ring
|
252
|
+
User basis matrix:
|
253
|
+
...
|
254
|
+
sage: I.free_module().is_submodule(K.maximal_order().free_module())
|
255
|
+
True
|
256
|
+
"""
|
257
|
+
return self.absolute_ideal().free_module()
|
258
|
+
|
259
|
+
def gens_reduced(self):
|
260
|
+
r"""
|
261
|
+
Return a small set of generators for this ideal. This will always
|
262
|
+
return a single generator if one exists (i.e. if the ideal is
|
263
|
+
principal), and otherwise two generators.
|
264
|
+
|
265
|
+
EXAMPLES::
|
266
|
+
|
267
|
+
sage: x = polygen(ZZ, 'x')
|
268
|
+
sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2])
|
269
|
+
sage: I = K.ideal((a + 1)*b/2 + 1)
|
270
|
+
sage: I.gens_reduced()
|
271
|
+
(1/2*b*a + 1/2*b + 1,)
|
272
|
+
|
273
|
+
TESTS:
|
274
|
+
|
275
|
+
Number fields defined by non-monic and non-integral
|
276
|
+
polynomials are supported (:issue:`252`)::
|
277
|
+
|
278
|
+
sage: K.<a> = NumberField(2*x^2 - 1/3)
|
279
|
+
sage: L.<b> = K.extension(5*x^2 + 1)
|
280
|
+
sage: P = L.primes_above(2)[0]
|
281
|
+
sage: P.gens_reduced()
|
282
|
+
(2, -15*a*b - 3*a + 1)
|
283
|
+
"""
|
284
|
+
try:
|
285
|
+
# Compute the single generator, if it exists
|
286
|
+
self.is_principal()
|
287
|
+
return self.__reduced_generators
|
288
|
+
except AttributeError:
|
289
|
+
L = self.number_field()
|
290
|
+
gens = L.pari_rnf().rnfidealtwoelt(self.pari_rhnf())
|
291
|
+
gens = [L(x, check=False) for x in gens]
|
292
|
+
|
293
|
+
# PARI always returns two elements, even if only one is needed!
|
294
|
+
if gens[1] in L.ideal(gens[0]):
|
295
|
+
gens = gens[:1]
|
296
|
+
elif gens[0] in L.ideal(gens[1]):
|
297
|
+
gens = gens[1:]
|
298
|
+
self.__reduced_generators = tuple(gens)
|
299
|
+
return self.__reduced_generators
|
300
|
+
|
301
|
+
def __invert__(self):
|
302
|
+
"""
|
303
|
+
Return the multiplicative inverse of ``self``. Call with ``~self``.
|
304
|
+
|
305
|
+
EXAMPLES::
|
306
|
+
|
307
|
+
sage: x = polygen(ZZ, 'x')
|
308
|
+
sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2])
|
309
|
+
sage: I = K.fractional_ideal(4)
|
310
|
+
sage: I^(-1)
|
311
|
+
Fractional ideal (1/4)
|
312
|
+
sage: I * I^(-1)
|
313
|
+
Fractional ideal (1)
|
314
|
+
"""
|
315
|
+
if self.is_zero():
|
316
|
+
raise ZeroDivisionError
|
317
|
+
return self._from_absolute_ideal(~self.absolute_ideal())
|
318
|
+
|
319
|
+
def is_principal(self, proof=None):
|
320
|
+
"""
|
321
|
+
Return ``True`` if this ideal is principal. If so, set
|
322
|
+
``self.__reduced_generators``, with length one.
|
323
|
+
|
324
|
+
EXAMPLES::
|
325
|
+
|
326
|
+
sage: x = polygen(ZZ, 'x')
|
327
|
+
sage: K.<a, b> = NumberField([x^2 - 23, x^2 + 1])
|
328
|
+
sage: I = K.ideal([7, (-1/2*b - 3/2)*a + 3/2*b + 9/2])
|
329
|
+
sage: I.is_principal()
|
330
|
+
True
|
331
|
+
sage: I # random
|
332
|
+
Fractional ideal ((1/2*b + 1/2)*a - 3/2*b - 3/2)
|
333
|
+
"""
|
334
|
+
proof = get_flag(proof, "number_field")
|
335
|
+
try:
|
336
|
+
return self.__is_principal
|
337
|
+
except AttributeError:
|
338
|
+
self.__is_principal = self.absolute_ideal().is_principal(proof=proof)
|
339
|
+
if self.__is_principal:
|
340
|
+
abs_ideal = self.absolute_ideal()
|
341
|
+
from_abs = abs_ideal.number_field().structure()[0]
|
342
|
+
g = from_abs(abs_ideal.gens_reduced()[0])
|
343
|
+
self.__reduced_generators = tuple([g])
|
344
|
+
return self.__is_principal
|
345
|
+
|
346
|
+
def is_zero(self):
|
347
|
+
r"""
|
348
|
+
Return ``True`` if this is the zero ideal.
|
349
|
+
|
350
|
+
EXAMPLES::
|
351
|
+
|
352
|
+
sage: x = polygen(ZZ, 'x')
|
353
|
+
sage: K.<a, b> = NumberField([x^2 + 3, x^3 + 4])
|
354
|
+
sage: K.ideal(17).is_zero()
|
355
|
+
False
|
356
|
+
sage: K.ideal(0).is_zero()
|
357
|
+
True
|
358
|
+
"""
|
359
|
+
zero = self.number_field().pari_rnf().rnfidealhnf(0)
|
360
|
+
return self.pari_rhnf() == zero
|
361
|
+
|
362
|
+
def absolute_norm(self):
|
363
|
+
"""
|
364
|
+
Compute the absolute norm of this fractional ideal in a relative number
|
365
|
+
field, returning a positive integer.
|
366
|
+
|
367
|
+
EXAMPLES::
|
368
|
+
|
369
|
+
sage: x = polygen(ZZ, 'x')
|
370
|
+
sage: L.<a, b, c> = QQ.extension([x^2 - 23, x^2 - 5, x^2 - 7])
|
371
|
+
sage: I = L.ideal(a + b)
|
372
|
+
sage: I.absolute_norm()
|
373
|
+
104976
|
374
|
+
sage: I.relative_norm().relative_norm().relative_norm()
|
375
|
+
104976
|
376
|
+
"""
|
377
|
+
return self.absolute_ideal().norm()
|
378
|
+
|
379
|
+
def relative_norm(self):
|
380
|
+
"""
|
381
|
+
Compute the relative norm of this fractional ideal in a relative number
|
382
|
+
field, returning an ideal in the base field.
|
383
|
+
|
384
|
+
EXAMPLES::
|
385
|
+
|
386
|
+
sage: R.<x> = QQ[]
|
387
|
+
sage: K.<a> = NumberField(x^2 + 6)
|
388
|
+
sage: L.<b> = K.extension(K['x'].gen()^4 + a)
|
389
|
+
sage: N = L.ideal(b).relative_norm(); N
|
390
|
+
Fractional ideal (-a)
|
391
|
+
sage: N.parent()
|
392
|
+
Monoid of ideals of Number Field in a with defining polynomial x^2 + 6
|
393
|
+
sage: N.ring()
|
394
|
+
Number Field in a with defining polynomial x^2 + 6
|
395
|
+
sage: PQ.<X> = QQ[]
|
396
|
+
sage: F.<a, b> = NumberField([X^2 - 2, X^2 - 3])
|
397
|
+
sage: PF.<Y> = F[]
|
398
|
+
sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
|
399
|
+
sage: K.ideal(1).relative_norm()
|
400
|
+
Fractional ideal (1)
|
401
|
+
sage: K.ideal(13).relative_norm().relative_norm()
|
402
|
+
Fractional ideal (28561)
|
403
|
+
sage: K.ideal(13).relative_norm().relative_norm().relative_norm()
|
404
|
+
815730721
|
405
|
+
sage: K.ideal(13).absolute_norm()
|
406
|
+
815730721
|
407
|
+
|
408
|
+
Number fields defined by non-monic and non-integral
|
409
|
+
polynomials are supported (:issue:`252`)::
|
410
|
+
|
411
|
+
sage: K.<a> = NumberField(2*x^2 - 1/3)
|
412
|
+
sage: L.<b> = K.extension(5*x^2 + 1)
|
413
|
+
sage: P = L.primes_above(2)[0]
|
414
|
+
sage: P.relative_norm()
|
415
|
+
Fractional ideal (6*a + 2)
|
416
|
+
"""
|
417
|
+
L = self.number_field()
|
418
|
+
K = L.base_field()
|
419
|
+
K_abs = K.absolute_field('a')
|
420
|
+
to_K = K_abs.structure()[0]
|
421
|
+
hnf = L.pari_rnf().rnfidealnormrel(self.pari_rhnf())
|
422
|
+
return K.ideal([to_K(K_abs(x, check=False)) for x in K.pari_zk() * hnf])
|
423
|
+
|
424
|
+
def norm(self):
|
425
|
+
"""
|
426
|
+
The norm of a fractional ideal in a relative number field is deliberately
|
427
|
+
unimplemented, so that a user cannot mistake the absolute norm
|
428
|
+
for the relative norm, or vice versa.
|
429
|
+
|
430
|
+
EXAMPLES::
|
431
|
+
|
432
|
+
sage: x = polygen(ZZ, 'x')
|
433
|
+
sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2])
|
434
|
+
sage: K.ideal(2).norm()
|
435
|
+
Traceback (most recent call last):
|
436
|
+
...
|
437
|
+
NotImplementedError: For a fractional ideal in a relative number field
|
438
|
+
you must use relative_norm or absolute_norm as appropriate
|
439
|
+
"""
|
440
|
+
raise NotImplementedError("For a fractional ideal in a relative number field you must use relative_norm or absolute_norm as appropriate")
|
441
|
+
|
442
|
+
def ideal_below(self):
|
443
|
+
r"""
|
444
|
+
Compute the ideal of `K` below this ideal of `L`.
|
445
|
+
|
446
|
+
EXAMPLES::
|
447
|
+
|
448
|
+
sage: R.<x> = QQ[]
|
449
|
+
sage: K.<a> = NumberField(x^2 + 6)
|
450
|
+
sage: L.<b> = K.extension(K['x'].gen()^4 + a)
|
451
|
+
sage: N = L.ideal(b)
|
452
|
+
sage: M = N.ideal_below(); M == K.ideal([-a])
|
453
|
+
True
|
454
|
+
sage: Np = L.ideal([L(t) for t in M.gens()])
|
455
|
+
sage: Np.ideal_below() == M
|
456
|
+
True
|
457
|
+
sage: M.parent()
|
458
|
+
Monoid of ideals of Number Field in a with defining polynomial x^2 + 6
|
459
|
+
sage: M.ring()
|
460
|
+
Number Field in a with defining polynomial x^2 + 6
|
461
|
+
sage: M.ring() is K
|
462
|
+
True
|
463
|
+
|
464
|
+
This example concerns an inert ideal::
|
465
|
+
|
466
|
+
sage: K = NumberField(x^4 + 6*x^2 + 24, 'a')
|
467
|
+
sage: K.factor(7)
|
468
|
+
Fractional ideal (7)
|
469
|
+
sage: K0, K0_into_K, _ = K.subfields(2)[0]
|
470
|
+
sage: K0
|
471
|
+
Number Field in a0 with defining polynomial x^2 - 6*x + 24
|
472
|
+
sage: L = K.relativize(K0_into_K, 'c'); L
|
473
|
+
Number Field in c with defining polynomial x^2 + a0 over its base field
|
474
|
+
sage: L.base_field() is K0
|
475
|
+
True
|
476
|
+
sage: L.ideal(7)
|
477
|
+
Fractional ideal (7)
|
478
|
+
sage: L.ideal(7).ideal_below()
|
479
|
+
Fractional ideal (7)
|
480
|
+
sage: L.ideal(7).ideal_below().number_field() is K0
|
481
|
+
True
|
482
|
+
|
483
|
+
This example concerns an ideal that splits in the quadratic field but
|
484
|
+
each factor ideal remains inert in the extension::
|
485
|
+
|
486
|
+
sage: len(K.factor(19))
|
487
|
+
2
|
488
|
+
sage: K0 = L.base_field(); a0 = K0.gen()
|
489
|
+
sage: len(K0.factor(19))
|
490
|
+
2
|
491
|
+
sage: w1 = -a0 + 1; P1 = K0.ideal([w1])
|
492
|
+
sage: P1.norm().factor(), P1.is_prime()
|
493
|
+
(19, True)
|
494
|
+
sage: L_into_K, K_into_L = L.structure()
|
495
|
+
sage: L.ideal(K_into_L(K0_into_K(w1))).ideal_below() == P1
|
496
|
+
True
|
497
|
+
|
498
|
+
The choice of embedding of quadratic field into quartic field matters::
|
499
|
+
|
500
|
+
sage: rho, tau = K0.embeddings(K)
|
501
|
+
sage: L1 = K.relativize(rho, 'b')
|
502
|
+
sage: L2 = K.relativize(tau, 'b')
|
503
|
+
sage: L1_into_K, K_into_L1 = L1.structure()
|
504
|
+
sage: L2_into_K, K_into_L2 = L2.structure()
|
505
|
+
sage: a = K.gen()
|
506
|
+
sage: P = K.ideal([a^2 + 5])
|
507
|
+
sage: K_into_L1(P).ideal_below() == K0.ideal([-a0 + 1])
|
508
|
+
True
|
509
|
+
sage: K_into_L2(P).ideal_below() == K0.ideal([-a0 + 5])
|
510
|
+
True
|
511
|
+
sage: K0.ideal([-a0 + 1]) == K0.ideal([-a0 + 5])
|
512
|
+
False
|
513
|
+
|
514
|
+
It works when the base field is itself a relative number field::
|
515
|
+
|
516
|
+
sage: PQ.<X> = QQ[]
|
517
|
+
sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3])
|
518
|
+
sage: PF.<Y> = F[]
|
519
|
+
sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
|
520
|
+
sage: I = K.ideal(3, c)
|
521
|
+
sage: J = I.ideal_below()
|
522
|
+
sage: J == K.ideal(b)
|
523
|
+
True
|
524
|
+
sage: J.number_field() == F
|
525
|
+
True
|
526
|
+
|
527
|
+
Number fields defined by non-monic and non-integral
|
528
|
+
polynomials are supported (:issue:`252`)::
|
529
|
+
|
530
|
+
sage: K.<a> = NumberField(2*x^2 - 1/3)
|
531
|
+
sage: L.<b> = K.extension(5*x^2 + 1)
|
532
|
+
sage: P = L.primes_above(2)[0]
|
533
|
+
sage: P.ideal_below()
|
534
|
+
Fractional ideal (6*a + 2)
|
535
|
+
"""
|
536
|
+
L = self.number_field()
|
537
|
+
K = L.base_field()
|
538
|
+
K_abs = K.absolute_field('a')
|
539
|
+
to_K = K_abs.structure()[0]
|
540
|
+
hnf = L.pari_rnf().rnfidealdown(self.pari_rhnf())
|
541
|
+
return K.ideal([to_K(K_abs(x, check=False)) for x in K.pari_zk() * hnf])
|
542
|
+
|
543
|
+
def factor(self):
|
544
|
+
"""
|
545
|
+
Factor the ideal by factoring the corresponding ideal
|
546
|
+
in the absolute number field.
|
547
|
+
|
548
|
+
EXAMPLES::
|
549
|
+
|
550
|
+
sage: x = polygen(ZZ, 'x')
|
551
|
+
sage: K.<a, b> = QQ.extension([x^2 + 11, x^2 - 5])
|
552
|
+
sage: K.factor(5)
|
553
|
+
(Fractional ideal (5, (1/4*b - 1/4)*a + 1/4*b + 3/4))^2 * (Fractional ideal (5, (1/4*b - 1/4)*a + 1/4*b + 7/4))^2
|
554
|
+
sage: K.ideal(5).factor()
|
555
|
+
(Fractional ideal (5, (1/4*b - 1/4)*a + 1/4*b + 3/4))^2 * (Fractional ideal (5, (1/4*b - 1/4)*a + 1/4*b + 7/4))^2
|
556
|
+
sage: K.ideal(5).prime_factors()
|
557
|
+
[Fractional ideal (5, (1/4*b - 1/4)*a + 1/4*b + 3/4),
|
558
|
+
Fractional ideal (5, (1/4*b - 1/4)*a + 1/4*b + 7/4)]
|
559
|
+
|
560
|
+
sage: PQ.<X> = QQ[]
|
561
|
+
sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3])
|
562
|
+
sage: PF.<Y> = F[]
|
563
|
+
sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
|
564
|
+
sage: I = K.ideal(c)
|
565
|
+
sage: P = K.ideal((b*a - b - 1)*c/2 + a - 1)
|
566
|
+
sage: Q = K.ideal((b*a - b - 1)*c/2)
|
567
|
+
sage: list(I.factor()) == [(P, 2), (Q, 1)]
|
568
|
+
True
|
569
|
+
sage: I == P^2*Q
|
570
|
+
True
|
571
|
+
sage: [p.is_prime() for p in [P, Q]]
|
572
|
+
[True, True]
|
573
|
+
"""
|
574
|
+
F = self.number_field()
|
575
|
+
abs_ideal = self.absolute_ideal()
|
576
|
+
to_F = abs_ideal.number_field().structure()[0]
|
577
|
+
factor_list = [(F.ideal([to_F(_) for _ in p.gens()]), e) for p, e in abs_ideal.factor()]
|
578
|
+
# sorting and simplification will already have been done
|
579
|
+
return Factorization(factor_list, sort=False, simplify=False)
|
580
|
+
|
581
|
+
def integral_basis(self):
|
582
|
+
r"""
|
583
|
+
Return a basis for ``self`` as a `\ZZ`-module.
|
584
|
+
|
585
|
+
EXAMPLES::
|
586
|
+
|
587
|
+
sage: x = polygen(ZZ, 'x')
|
588
|
+
sage: K.<a,b> = NumberField([x^2 + 1, x^2 - 3])
|
589
|
+
sage: I = K.ideal(17*b - 3*a)
|
590
|
+
sage: x = I.integral_basis(); x # random
|
591
|
+
[438, -b*a + 309, 219*a - 219*b, 156*a - 154*b]
|
592
|
+
|
593
|
+
The exact results are somewhat unpredictable, hence the ``# random``
|
594
|
+
flag, but we can test that they are indeed a basis::
|
595
|
+
|
596
|
+
sage: V, _, phi = K.absolute_vector_space()
|
597
|
+
sage: V.span([phi(u) for u in x], ZZ) == I.free_module()
|
598
|
+
True
|
599
|
+
"""
|
600
|
+
J = self.absolute_ideal()
|
601
|
+
iso = J.number_field().structure()[0]
|
602
|
+
return [iso(x) for x in J.integral_basis()]
|
603
|
+
|
604
|
+
def integral_split(self):
|
605
|
+
r"""
|
606
|
+
Return a tuple `(I, d)`, where `I` is an integral ideal, and `d` is the
|
607
|
+
smallest positive integer such that this ideal is equal to `I/d`.
|
608
|
+
|
609
|
+
EXAMPLES::
|
610
|
+
|
611
|
+
sage: x = polygen(ZZ, 'x')
|
612
|
+
sage: K.<a, b> = NumberFieldTower([x^2 - 23, x^2 + 1])
|
613
|
+
sage: I = K.ideal([a + b/3])
|
614
|
+
sage: J, d = I.integral_split()
|
615
|
+
sage: J.is_integral()
|
616
|
+
True
|
617
|
+
sage: J == d*I
|
618
|
+
True
|
619
|
+
"""
|
620
|
+
d = self.absolute_ideal().integral_split()[1]
|
621
|
+
return (d*self, d)
|
622
|
+
|
623
|
+
def is_prime(self):
|
624
|
+
"""
|
625
|
+
Return ``True`` if this ideal of a relative number field is prime.
|
626
|
+
|
627
|
+
EXAMPLES::
|
628
|
+
|
629
|
+
sage: x = polygen(ZZ, 'x')
|
630
|
+
sage: K.<a, b> = NumberField([x^2 - 17, x^3 - 2])
|
631
|
+
sage: K.ideal(a + b).is_prime()
|
632
|
+
True
|
633
|
+
sage: K.ideal(13).is_prime()
|
634
|
+
False
|
635
|
+
"""
|
636
|
+
try:
|
637
|
+
return self._pari_prime is not None
|
638
|
+
except AttributeError:
|
639
|
+
abs_ideal = self.absolute_ideal()
|
640
|
+
abs_ideal.is_prime()
|
641
|
+
self._pari_prime = abs_ideal._pari_prime
|
642
|
+
return self._pari_prime is not None
|
643
|
+
|
644
|
+
def is_integral(self):
|
645
|
+
"""
|
646
|
+
Return ``True`` if this ideal is integral.
|
647
|
+
|
648
|
+
EXAMPLES::
|
649
|
+
|
650
|
+
sage: x = polygen(ZZ, 'x')
|
651
|
+
sage: K.<a, b> = QQ.extension([x^2 + 11, x^2 - 5])
|
652
|
+
sage: I = K.ideal(7).prime_factors()[0]
|
653
|
+
sage: I.is_integral()
|
654
|
+
True
|
655
|
+
sage: (I/2).is_integral()
|
656
|
+
False
|
657
|
+
"""
|
658
|
+
return self.absolute_ideal().is_integral()
|
659
|
+
|
660
|
+
def absolute_ramification_index(self):
|
661
|
+
"""
|
662
|
+
Return the absolute ramification index of this fractional ideal,
|
663
|
+
assuming it is prime. Otherwise, raise a :exc:`ValueError`.
|
664
|
+
|
665
|
+
The absolute ramification index is the power of this prime
|
666
|
+
appearing in the factorization of the rational prime that
|
667
|
+
this prime lies over.
|
668
|
+
|
669
|
+
Use :meth:`relative_ramification_index` to obtain the power of this
|
670
|
+
prime occurring in the factorization of the prime ideal
|
671
|
+
of the base field that this prime lies over.
|
672
|
+
|
673
|
+
EXAMPLES::
|
674
|
+
|
675
|
+
sage: PQ.<X> = QQ[]
|
676
|
+
sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3])
|
677
|
+
sage: PF.<Y> = F[]
|
678
|
+
sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
|
679
|
+
sage: I = K.ideal(3, c)
|
680
|
+
sage: I.absolute_ramification_index()
|
681
|
+
4
|
682
|
+
sage: I.smallest_integer()
|
683
|
+
3
|
684
|
+
sage: K.ideal(3) == I^4
|
685
|
+
True
|
686
|
+
"""
|
687
|
+
if self.is_prime():
|
688
|
+
return self.absolute_ideal().ramification_index()
|
689
|
+
raise ValueError("the fractional ideal (= %s) is not prime" % self)
|
690
|
+
|
691
|
+
def relative_ramification_index(self):
|
692
|
+
"""
|
693
|
+
Return the relative ramification index of this fractional ideal,
|
694
|
+
assuming it is prime. Otherwise, raise a :exc:`ValueError`.
|
695
|
+
|
696
|
+
The relative ramification index is the power of this prime
|
697
|
+
appearing in the factorization of the prime ideal of the
|
698
|
+
base field that this prime lies over.
|
699
|
+
|
700
|
+
Use :meth:`absolute_ramification_index` to obtain the power of this
|
701
|
+
prime occurring in the factorization of the rational prime
|
702
|
+
that this prime lies over.
|
703
|
+
|
704
|
+
EXAMPLES::
|
705
|
+
|
706
|
+
sage: PQ.<X> = QQ[]
|
707
|
+
sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3])
|
708
|
+
sage: PF.<Y> = F[]
|
709
|
+
sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
|
710
|
+
sage: I = K.ideal(3, c)
|
711
|
+
sage: I.relative_ramification_index()
|
712
|
+
2
|
713
|
+
sage: I.ideal_below() # random sign
|
714
|
+
Fractional ideal (b)
|
715
|
+
sage: I.ideal_below() == K.ideal(b)
|
716
|
+
True
|
717
|
+
sage: K.ideal(b) == I^2
|
718
|
+
True
|
719
|
+
"""
|
720
|
+
if self.is_prime():
|
721
|
+
abs_index = self.absolute_ramification_index()
|
722
|
+
base_ideal = self.ideal_below()
|
723
|
+
return ZZ(abs_index/base_ideal.absolute_ramification_index())
|
724
|
+
raise ValueError("the fractional ideal (= %s) is not prime" % self)
|
725
|
+
|
726
|
+
def ramification_index(self):
|
727
|
+
r"""
|
728
|
+
For ideals in relative number fields, :meth:`ramification_index`
|
729
|
+
is deliberately not implemented in order to avoid ambiguity.
|
730
|
+
Either :meth:`~relative_ramification_index` or
|
731
|
+
:meth:`~absolute_ramification_index` should be used instead.
|
732
|
+
|
733
|
+
EXAMPLES::
|
734
|
+
|
735
|
+
sage: x = polygen(ZZ, 'x')
|
736
|
+
sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2])
|
737
|
+
sage: K.ideal(2).ramification_index()
|
738
|
+
Traceback (most recent call last):
|
739
|
+
...
|
740
|
+
NotImplementedError: For an ideal in a relative number field you must use
|
741
|
+
relative_ramification_index or absolute_ramification_index as appropriate
|
742
|
+
"""
|
743
|
+
raise NotImplementedError("For an ideal in a relative number field you must use relative_ramification_index or absolute_ramification_index as appropriate")
|
744
|
+
|
745
|
+
def residue_class_degree(self):
|
746
|
+
r"""
|
747
|
+
Return the residue class degree of this prime.
|
748
|
+
|
749
|
+
EXAMPLES::
|
750
|
+
|
751
|
+
sage: PQ.<X> = QQ[]
|
752
|
+
sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3])
|
753
|
+
sage: PF.<Y> = F[]
|
754
|
+
sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b)
|
755
|
+
sage: [I.residue_class_degree() for I in K.ideal(c).prime_factors()]
|
756
|
+
[1, 2]
|
757
|
+
"""
|
758
|
+
if self.is_prime():
|
759
|
+
return self.absolute_ideal().residue_class_degree()
|
760
|
+
raise ValueError("the ideal (= %s) is not prime" % self)
|
761
|
+
|
762
|
+
def residues(self):
|
763
|
+
"""
|
764
|
+
Return a iterator through a complete list of residues modulo this
|
765
|
+
integral ideal.
|
766
|
+
|
767
|
+
An error is raised if this fractional ideal is not integral.
|
768
|
+
|
769
|
+
EXAMPLES::
|
770
|
+
|
771
|
+
sage: x = polygen(ZZ, 'x')
|
772
|
+
sage: K.<a, w> = NumberFieldTower([x^2 - 3, x^2 + x + 1])
|
773
|
+
sage: I = K.ideal(6, -w*a - w + 4)
|
774
|
+
sage: list(I.residues())[:5]
|
775
|
+
[(25/3*w - 1/3)*a + 22*w + 1,
|
776
|
+
(16/3*w - 1/3)*a + 13*w,
|
777
|
+
(7/3*w - 1/3)*a + 4*w - 1,
|
778
|
+
(-2/3*w - 1/3)*a - 5*w - 2,
|
779
|
+
(-11/3*w - 1/3)*a - 14*w - 3]
|
780
|
+
"""
|
781
|
+
abs_ideal = self.absolute_ideal()
|
782
|
+
from_abs = abs_ideal.number_field().structure()[0]
|
783
|
+
from sage.misc.mrange import xmrange_iter
|
784
|
+
abs_residues = abs_ideal.residues()
|
785
|
+
return xmrange_iter(abs_residues.iter_list, lambda c: from_abs(abs_residues.typ(c)))
|
786
|
+
|
787
|
+
def element_1_mod(self, other):
|
788
|
+
r"""
|
789
|
+
Return an element `r` in this ideal such that `1-r` is in ``other``.
|
790
|
+
|
791
|
+
An error is raised if either ideal is not integral of if they
|
792
|
+
are not coprime.
|
793
|
+
|
794
|
+
INPUT:
|
795
|
+
|
796
|
+
- ``other`` -- another ideal of the same field, or generators of an
|
797
|
+
ideal
|
798
|
+
|
799
|
+
OUTPUT:
|
800
|
+
|
801
|
+
an element `r` of the ideal ``self`` such that `1-r` is in the ideal
|
802
|
+
``other``.
|
803
|
+
|
804
|
+
EXAMPLES::
|
805
|
+
|
806
|
+
sage: x = polygen(ZZ, 'x')
|
807
|
+
sage: K.<a, b> = NumberFieldTower([x^2 - 23, x^2 + 1])
|
808
|
+
sage: I = Ideal(2, (a - 3*b + 2)/2)
|
809
|
+
sage: J = K.ideal(a)
|
810
|
+
sage: z = I.element_1_mod(J)
|
811
|
+
sage: z in I
|
812
|
+
True
|
813
|
+
sage: 1 - z in J
|
814
|
+
True
|
815
|
+
"""
|
816
|
+
# Catch invalid inputs by making sure that we can make an ideal out of other.
|
817
|
+
K = self.number_field()
|
818
|
+
if not self.is_integral():
|
819
|
+
raise TypeError("%s is not an integral ideal" % self)
|
820
|
+
|
821
|
+
other = K.ideal(other)
|
822
|
+
if not other.is_integral():
|
823
|
+
raise TypeError("%s is not an integral ideal" % other)
|
824
|
+
|
825
|
+
if not self.is_coprime(other):
|
826
|
+
raise TypeError("%s and %s are not coprime ideals" % (self, other))
|
827
|
+
|
828
|
+
to_K = K.absolute_field('a').structure()[0]
|
829
|
+
return to_K(self.absolute_ideal().element_1_mod(other.absolute_ideal()))
|
830
|
+
|
831
|
+
def smallest_integer(self):
|
832
|
+
r"""
|
833
|
+
Return the smallest nonnegative integer in `I \cap \ZZ`, where `I` is
|
834
|
+
this ideal. If `I = 0`, returns `0`.
|
835
|
+
|
836
|
+
EXAMPLES::
|
837
|
+
|
838
|
+
sage: x = polygen(ZZ, 'x')
|
839
|
+
sage: K.<a, b> = NumberFieldTower([x^2 - 23, x^2 + 1])
|
840
|
+
sage: I = K.ideal([a + b])
|
841
|
+
sage: I.smallest_integer()
|
842
|
+
12
|
843
|
+
sage: [m for m in range(13) if m in I]
|
844
|
+
[0, 12]
|
845
|
+
"""
|
846
|
+
return self.absolute_ideal().smallest_integer()
|
847
|
+
|
848
|
+
def valuation(self, p):
|
849
|
+
r"""
|
850
|
+
Return the valuation of this fractional ideal at `\mathfrak{p}`.
|
851
|
+
|
852
|
+
INPUT:
|
853
|
+
|
854
|
+
- ``p`` -- a prime ideal `\mathfrak{p}` of this relative number field
|
855
|
+
|
856
|
+
OUTPUT:
|
857
|
+
|
858
|
+
(integer) The valuation of this fractional ideal at the prime
|
859
|
+
`\mathfrak{p}`. If `\mathfrak{p}` is not prime, raise a
|
860
|
+
:exc:`ValueError`.
|
861
|
+
|
862
|
+
EXAMPLES::
|
863
|
+
|
864
|
+
sage: x = polygen(ZZ, 'x')
|
865
|
+
sage: K.<a, b> = NumberField([x^2 - 17, x^3 - 2])
|
866
|
+
sage: A = K.ideal(a + b)
|
867
|
+
sage: A.is_prime()
|
868
|
+
True
|
869
|
+
sage: (A*K.ideal(3)).valuation(A)
|
870
|
+
1
|
871
|
+
sage: K.ideal(25).valuation(5)
|
872
|
+
Traceback (most recent call last):
|
873
|
+
...
|
874
|
+
ValueError: p (= Fractional ideal (5)) must be a prime
|
875
|
+
"""
|
876
|
+
if p == 0:
|
877
|
+
raise ValueError("p (= %s) must be nonzero" % p)
|
878
|
+
if not isinstance(p, NumberFieldFractionalIdeal):
|
879
|
+
p = self.number_field().ideal(p)
|
880
|
+
if not p.is_prime():
|
881
|
+
raise ValueError("p (= %s) must be a prime" % p)
|
882
|
+
if p.ring() != self.number_field():
|
883
|
+
raise ValueError("p (= %s) must be an ideal in %s" % self.number_field())
|
884
|
+
return self.absolute_ideal().valuation(p.absolute_ideal())
|
885
|
+
|
886
|
+
|
887
|
+
def is_NumberFieldFractionalIdeal_rel(x):
|
888
|
+
"""
|
889
|
+
Return ``True`` if `x` is a fractional ideal of a relative number field.
|
890
|
+
|
891
|
+
EXAMPLES::
|
892
|
+
|
893
|
+
sage: from sage.rings.number_field.number_field_ideal_rel import is_NumberFieldFractionalIdeal_rel
|
894
|
+
sage: from sage.rings.number_field.number_field_ideal import is_NumberFieldFractionalIdeal
|
895
|
+
sage: is_NumberFieldFractionalIdeal_rel(2/3)
|
896
|
+
doctest:warning...
|
897
|
+
DeprecationWarning: The function is_NumberFieldFractionalIdeal_rel is deprecated;
|
898
|
+
use 'isinstance(..., NumberFieldFractionalIdeal_rel' instead.
|
899
|
+
See https://github.com/sagemath/sage/issues/38124 for details.
|
900
|
+
False
|
901
|
+
sage: is_NumberFieldFractionalIdeal_rel(ideal(5))
|
902
|
+
False
|
903
|
+
sage: x = polygen(ZZ, 'x')
|
904
|
+
sage: k.<a> = NumberField(x^2 + 2)
|
905
|
+
sage: I = k.ideal([a + 1]); I
|
906
|
+
Fractional ideal (a + 1)
|
907
|
+
sage: is_NumberFieldFractionalIdeal_rel(I)
|
908
|
+
False
|
909
|
+
sage: R.<x> = QQ[]
|
910
|
+
sage: K.<a> = NumberField(x^2 + 6)
|
911
|
+
sage: L.<b> = K.extension(K['x'].gen()^4 + a)
|
912
|
+
sage: I = L.ideal(b); I
|
913
|
+
Fractional ideal (6, b)
|
914
|
+
sage: is_NumberFieldFractionalIdeal_rel(I)
|
915
|
+
True
|
916
|
+
sage: N = I.relative_norm(); N
|
917
|
+
Fractional ideal (-a)
|
918
|
+
sage: is_NumberFieldFractionalIdeal_rel(N)
|
919
|
+
False
|
920
|
+
"""
|
921
|
+
from sage.misc.superseded import deprecation
|
922
|
+
deprecation(38124,
|
923
|
+
"The function is_NumberFieldFractionalIdeal_rel is deprecated; "
|
924
|
+
"use 'isinstance(..., NumberFieldFractionalIdeal_rel' instead.")
|
925
|
+
return isinstance(x, NumberFieldFractionalIdeal_rel)
|