passagemath-flint 10.6.1rc10__cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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 +360 -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-3701249d.so.21.0.0 +0 -0
- passagemath_flint.libs/libgf2x-fbd36f80.so.3.0.0 +0 -0
- passagemath_flint.libs/libgfortran-8a9a71bc.so.5.0.0 +0 -0
- passagemath_flint.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_flint.libs/libgsl-e3525837.so.28.0.0 +0 -0
- passagemath_flint.libs/libmpfi-ad12a86d.so.0.0.0 +0 -0
- passagemath_flint.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
- passagemath_flint.libs/libntl-1004113e.so.44.0.1 +0 -0
- passagemath_flint.libs/libopenblasp-r0-4c5b64b1.3.29.so +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-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-313-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-313-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-313-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-313-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-313-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-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-aarch64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-313-aarch64-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-aarch64-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,602 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
r"""
|
3
|
+
Compute Hilbert series of monomial ideals
|
4
|
+
|
5
|
+
This implementation was provided at :issue:`26243` and is supposed to be a way
|
6
|
+
out when Singular fails with an int overflow, which will regularly be the case
|
7
|
+
in any example with more than 34 variables.
|
8
|
+
"""
|
9
|
+
#*****************************************************************************
|
10
|
+
#
|
11
|
+
# Tools to compute Hilbert Poincaré series of monomial ideals
|
12
|
+
#
|
13
|
+
# Copyright (C) 2018 Simon A. King <simon.king@uni-jena.de>
|
14
|
+
#
|
15
|
+
# This program is free software: you can redistribute it and/or modify
|
16
|
+
# it under the terms of the GNU General Public License as published by
|
17
|
+
# the Free Software Foundation, either version 2 of the License, or
|
18
|
+
# (at your option) any later version.
|
19
|
+
# http://www.gnu.org/licenses/
|
20
|
+
#
|
21
|
+
#*****************************************************************************
|
22
|
+
|
23
|
+
import sage.interfaces.abc
|
24
|
+
|
25
|
+
from sage.rings.polynomial.polydict cimport ETuple
|
26
|
+
from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint
|
27
|
+
|
28
|
+
from cysignals.memory cimport sig_malloc
|
29
|
+
from cpython.list cimport PyList_GET_ITEM
|
30
|
+
|
31
|
+
# A boilerplate class to implement a binary tree
|
32
|
+
# with some additional information
|
33
|
+
|
34
|
+
from sage.libs.flint.fmpz_poly cimport *
|
35
|
+
from sage.libs.flint.types cimport fmpz_poly_t
|
36
|
+
|
37
|
+
cdef class Node:
|
38
|
+
"""
|
39
|
+
A node of a binary tree
|
40
|
+
|
41
|
+
It has slots for data that allow to recursively compute
|
42
|
+
the first Hilbert series of a monomial ideal.
|
43
|
+
"""
|
44
|
+
cdef Node Back, Left, Right
|
45
|
+
cdef list Id
|
46
|
+
cdef fmpz_poly_t LMult
|
47
|
+
cdef fmpz_poly_t RMult
|
48
|
+
cdef fmpz_poly_t LeftFHS
|
49
|
+
|
50
|
+
def __cinit__(self):
|
51
|
+
fmpz_poly_init(self.LMult)
|
52
|
+
fmpz_poly_init(self.RMult)
|
53
|
+
fmpz_poly_init(self.LeftFHS)
|
54
|
+
|
55
|
+
def __dealloc__(self):
|
56
|
+
fmpz_poly_clear(self.LMult)
|
57
|
+
fmpz_poly_clear(self.RMult)
|
58
|
+
fmpz_poly_clear(self.LeftFHS)
|
59
|
+
|
60
|
+
cdef inline size_t median(list v) noexcept:
|
61
|
+
"""
|
62
|
+
Specialized version of :func:`from sage.stats.basic_stats.median`.
|
63
|
+
"""
|
64
|
+
cdef list values = sorted(v)
|
65
|
+
cdef size_t nvals = len(values)
|
66
|
+
if nvals % 2 == 1:
|
67
|
+
return values[(nvals+1)//2 - 1]
|
68
|
+
else:
|
69
|
+
lower = values[(nvals+1)//2 - 1]
|
70
|
+
upper = values[nvals // 2]
|
71
|
+
return (lower + upper) // 2
|
72
|
+
|
73
|
+
###
|
74
|
+
# cdef functions related with lists of monomials
|
75
|
+
###
|
76
|
+
|
77
|
+
cdef inline bint indivisible_in_list(ETuple m, list L, size_t i) noexcept:
|
78
|
+
"""
|
79
|
+
Return if ``m`` divisible by any monomial in ``L[:i]``.
|
80
|
+
"""
|
81
|
+
cdef size_t j
|
82
|
+
for j in range(i):
|
83
|
+
if (<ETuple>PyList_GET_ITEM(L,j)).divides(m):
|
84
|
+
return False
|
85
|
+
return True
|
86
|
+
|
87
|
+
cdef inline list interred(list L):
|
88
|
+
"""
|
89
|
+
Return interreduction of a list of monomials.
|
90
|
+
|
91
|
+
.. NOTE::
|
92
|
+
|
93
|
+
The given list will be sorted in-place.
|
94
|
+
|
95
|
+
INPUT:
|
96
|
+
|
97
|
+
- ``L`` -- list of :class:`~sage.rings.polynomial.polydict.ETuple`
|
98
|
+
|
99
|
+
OUTPUT:
|
100
|
+
|
101
|
+
The interreduced list, where we interprete each ETuple as
|
102
|
+
a monomial in a multivariate ring.
|
103
|
+
"""
|
104
|
+
# First, we sort L ascendingly by total unweighted degree.
|
105
|
+
# Afterwards, no monomial in L is divisible by a monomial
|
106
|
+
# that appears later in L.
|
107
|
+
if not L:
|
108
|
+
return []
|
109
|
+
L.sort(key=ETuple._unweighted_degree)
|
110
|
+
cdef size_t i
|
111
|
+
cdef ETuple m
|
112
|
+
cdef list result = [<ETuple> PyList_GET_ITEM(L, 0)]
|
113
|
+
for i in range(1, len(L)):
|
114
|
+
m = <ETuple> PyList_GET_ITEM(L, i)
|
115
|
+
if indivisible_in_list(m, L, i):
|
116
|
+
result.append(m)
|
117
|
+
return result
|
118
|
+
|
119
|
+
cdef list quotient(list L, ETuple m):
|
120
|
+
"""
|
121
|
+
Return the quotient of the ideal represented by ``L`` and the
|
122
|
+
monomial represented by ``m``.
|
123
|
+
"""
|
124
|
+
cdef list result = L[:len(L)] # creates a copy
|
125
|
+
cdef size_t i
|
126
|
+
for i in range(len(L)):
|
127
|
+
result.append((<ETuple>PyList_GET_ITEM(L,i)).divide_by_gcd(m))
|
128
|
+
return interred(result)
|
129
|
+
|
130
|
+
cdef list quotient_by_var(list L, size_t index):
|
131
|
+
"""
|
132
|
+
Return the quotient of the ideal represented by ``L`` and the
|
133
|
+
variable number ``index``.
|
134
|
+
"""
|
135
|
+
cdef list result = L[:len(L)] # creates a copy
|
136
|
+
cdef size_t i
|
137
|
+
for i in range(len(L)):
|
138
|
+
if (<ETuple> PyList_GET_ITEM(L, i)).get_exp(index):
|
139
|
+
result.append((<ETuple> PyList_GET_ITEM(L, i)).divide_by_var(index))
|
140
|
+
return interred(result)
|
141
|
+
|
142
|
+
cdef ETuple sum_from_list(list L, size_t s, size_t l):
|
143
|
+
"""
|
144
|
+
Compute the vector sum of the ETuples in ``L[s:s+l]`` in a balanced way.
|
145
|
+
"""
|
146
|
+
if l == 1:
|
147
|
+
return <ETuple>PyList_GET_ITEM(L,s)
|
148
|
+
if l == 2:
|
149
|
+
return (<ETuple>PyList_GET_ITEM(L,s)).eadd(<ETuple>PyList_GET_ITEM(L,s+1))
|
150
|
+
cdef size_t l2 = l // 2
|
151
|
+
cdef ETuple m1, m2
|
152
|
+
m1 = sum_from_list(L, s, l2)
|
153
|
+
m2 = sum_from_list(L, s+l2, l-l2)
|
154
|
+
return m1.eadd(m2)
|
155
|
+
|
156
|
+
cdef bint HilbertBaseCase(Polynomial_integer_dense_flint fhs, Node D, tuple w) noexcept:
|
157
|
+
"""
|
158
|
+
Try to compute the first Hilbert series of ``D.Id``, or return
|
159
|
+
``NotImplemented``.
|
160
|
+
|
161
|
+
The third parameter ``w`` is a tuple of integers, the degree weights
|
162
|
+
to be used.
|
163
|
+
|
164
|
+
``fhs`` is supposed to be zero. In some base cases, ``fhs`` will be
|
165
|
+
changed to the value of the Hilbert series and ``True`` is returned.
|
166
|
+
Otherwiese, ``False`` is returned.
|
167
|
+
"""
|
168
|
+
cdef size_t i, j, exp
|
169
|
+
# First, the easiest cases:
|
170
|
+
if not D.Id: # The zero ideal
|
171
|
+
fmpz_poly_set_coeff_si(fhs._poly, 0, 1) # = PR(1)
|
172
|
+
return True
|
173
|
+
cdef ETuple m = <ETuple>PyList_GET_ITEM(D.Id, len(D.Id)-1)
|
174
|
+
if m._nonzero == 0: # The one ideal
|
175
|
+
return True
|
176
|
+
|
177
|
+
# Second, another reasy case: D.Id is generated by variables.
|
178
|
+
# D.Id is sorted ascendingly. Hence, if the last generator is a single
|
179
|
+
# variable, then ALL are.
|
180
|
+
cdef fmpz_poly_t poly_tmp
|
181
|
+
if m._nonzero == 1 and m._data[1] == 1:
|
182
|
+
fmpz_poly_init(poly_tmp)
|
183
|
+
fmpz_poly_set_coeff_si(poly_tmp, 0, 1)
|
184
|
+
fmpz_poly_set_coeff_si(fhs._poly, 0, 1) # = PR(1)
|
185
|
+
if w is None:
|
186
|
+
for i in range(len(D.Id)):
|
187
|
+
exp = (<ETuple>PyList_GET_ITEM(D.Id, i)).unweighted_degree()
|
188
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
189
|
+
fmpz_poly_mul(fhs._poly, fhs._poly, poly_tmp)
|
190
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
191
|
+
else:
|
192
|
+
for i in range(len(D.Id)):
|
193
|
+
exp = (<ETuple>PyList_GET_ITEM(D.Id, i)).weighted_degree(w)
|
194
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
195
|
+
fmpz_poly_mul(fhs._poly, fhs._poly, poly_tmp)
|
196
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
197
|
+
fmpz_poly_clear(poly_tmp)
|
198
|
+
return True # PR.prod([(1-t**degree(m,w)) for m in D.Id])
|
199
|
+
|
200
|
+
# Thirdly, we test for proper powers of single variables.
|
201
|
+
cdef bint easy = True
|
202
|
+
for i in range(len(D.Id)):
|
203
|
+
m = <ETuple>PyList_GET_ITEM(D.Id, i) # will be used later when we are breaking
|
204
|
+
if m._nonzero > 1: # i.e., the generator contains more than a single var
|
205
|
+
easy = False
|
206
|
+
break
|
207
|
+
if easy:
|
208
|
+
# The ideal is generated by some powers of single variables, i.e., it splits.
|
209
|
+
fmpz_poly_init(poly_tmp)
|
210
|
+
fmpz_poly_set_coeff_si(poly_tmp, 0, 1)
|
211
|
+
fmpz_poly_set_coeff_si(fhs._poly, 0, 1) # = PR(1)
|
212
|
+
if w is None:
|
213
|
+
for i in range(len(D.Id)):
|
214
|
+
exp = (<ETuple>PyList_GET_ITEM(D.Id, i)).unweighted_degree()
|
215
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
216
|
+
fmpz_poly_mul(fhs._poly, fhs._poly, poly_tmp)
|
217
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
218
|
+
else:
|
219
|
+
for i in range(len(D.Id)):
|
220
|
+
exp = (<ETuple>PyList_GET_ITEM(D.Id, i)).weighted_degree(w)
|
221
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
222
|
+
fmpz_poly_mul(fhs._poly, fhs._poly, poly_tmp)
|
223
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
224
|
+
fmpz_poly_clear(poly_tmp)
|
225
|
+
return True # PR.prod([(1-t**degree(m,w)) for m in D.Id])
|
226
|
+
|
227
|
+
easy = True
|
228
|
+
cdef ETuple m2
|
229
|
+
for j in range(i+1, len(D.Id)):
|
230
|
+
if (<ETuple>PyList_GET_ITEM(D.Id,j))._nonzero > 1:
|
231
|
+
# i.e., another generator contains more than a single var
|
232
|
+
easy = False
|
233
|
+
break
|
234
|
+
cdef fmpz_poly_t FirstSummand, SecondSummand
|
235
|
+
if easy:
|
236
|
+
# The ideal only has a single non-simple power, in position i.
|
237
|
+
# We have preserved that monomial, it is called m.
|
238
|
+
fmpz_poly_init(poly_tmp)
|
239
|
+
fmpz_poly_init(FirstSummand)
|
240
|
+
fmpz_poly_init(SecondSummand)
|
241
|
+
fmpz_poly_set_coeff_si(poly_tmp, 0, 1)
|
242
|
+
fmpz_poly_set_coeff_si(FirstSummand, 0, 1)
|
243
|
+
if w is None:
|
244
|
+
fmpz_poly_set_coeff_si(SecondSummand, m.unweighted_degree(), -1)
|
245
|
+
# Since the ideal is interreduced and all other monomials are
|
246
|
+
# simple powers, we have the following formula:
|
247
|
+
#~ return prod([(1-t**degree(m2,w)) for m2 in D.Id if m2 is not m])
|
248
|
+
#~ - t**degree(m,w)*prod((1-t**quotient_degree(m2,m,w)) for m2 in D.Id if m is not m2)
|
249
|
+
for j in range(len(D.Id)):
|
250
|
+
if i != j:
|
251
|
+
m2 = <ETuple>PyList_GET_ITEM(D.Id,j)
|
252
|
+
exp = m2.unweighted_degree()
|
253
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
254
|
+
fmpz_poly_mul(FirstSummand, FirstSummand, poly_tmp)
|
255
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
256
|
+
exp = m2.unweighted_quotient_degree(m)
|
257
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
258
|
+
fmpz_poly_mul(SecondSummand, SecondSummand, poly_tmp)
|
259
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
260
|
+
else:
|
261
|
+
fmpz_poly_set_coeff_si(SecondSummand, m.weighted_degree(w), -1)
|
262
|
+
# Since the ideal is interreduced and all other monomials are
|
263
|
+
# simple powers, we have the following formula:
|
264
|
+
#~ return prod([(1-t**degree(m2,w)) for m2 in D.Id if m2 is not m])
|
265
|
+
#~ - t**degree(m,w)*prod((1-t**quotient_degree(m2,m,w)) for m2 in D.Id if m is not m2)
|
266
|
+
for j in range(len(D.Id)):
|
267
|
+
if i != j:
|
268
|
+
m2 = <ETuple>PyList_GET_ITEM(D.Id,j)
|
269
|
+
exp = m2.weighted_degree(w)
|
270
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
271
|
+
fmpz_poly_mul(FirstSummand, FirstSummand, poly_tmp)
|
272
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
273
|
+
exp = m2.weighted_quotient_degree(m,w)
|
274
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, -1)
|
275
|
+
fmpz_poly_mul(SecondSummand, SecondSummand, poly_tmp)
|
276
|
+
fmpz_poly_set_coeff_si(poly_tmp, exp, 0)
|
277
|
+
fmpz_poly_clear(poly_tmp)
|
278
|
+
fmpz_poly_add(fhs._poly, fhs._poly, FirstSummand)
|
279
|
+
fmpz_poly_add(fhs._poly, fhs._poly, SecondSummand)
|
280
|
+
fmpz_poly_clear(FirstSummand)
|
281
|
+
fmpz_poly_clear(SecondSummand)
|
282
|
+
return True
|
283
|
+
# We are in a truly difficult case and give up for now...
|
284
|
+
return False
|
285
|
+
|
286
|
+
cdef make_children(Node D, tuple w):
|
287
|
+
"""
|
288
|
+
Create child nodes in ``D`` that allow to compute the first Hilbert
|
289
|
+
series of ``D.Id``.
|
290
|
+
|
291
|
+
Basically, the first Hilbert series of ``D.Id`` will be
|
292
|
+
``D.LMult`` times the first Hilbert series of ``D.Left.Id``,
|
293
|
+
possibly plus ``D.RMult`` times the first Hilbert series of ``D.Right.Id``
|
294
|
+
if ``D.Right`` is not ``None``.
|
295
|
+
"""
|
296
|
+
cdef size_t j, m
|
297
|
+
cdef int i
|
298
|
+
# Determine the variable that appears most often in the monomials.
|
299
|
+
# If "most often" means "only once", then instead we choose a variable that is
|
300
|
+
# guaranteed to appear in a composed monomial.
|
301
|
+
# We will raise it to a reasonably high power that still guarantees that
|
302
|
+
# many monomials will be divisible by it.
|
303
|
+
cdef ETuple all_exponents = sum_from_list(D.Id, 0, len(D.Id))
|
304
|
+
m = 0
|
305
|
+
cdef list max_exponents = []
|
306
|
+
for i in range(0, 2*all_exponents._nonzero, 2):
|
307
|
+
j = all_exponents._data[i+1]
|
308
|
+
if j > m:
|
309
|
+
max_exponents = [all_exponents._data[i]]
|
310
|
+
m = j
|
311
|
+
elif j == m:
|
312
|
+
max_exponents.append(all_exponents._data[i])
|
313
|
+
cdef size_t e # will be the exponent, if the monomial used for cutting is power of a variable
|
314
|
+
cdef ETuple cut
|
315
|
+
cdef list Id2
|
316
|
+
cdef size_t cut_deg
|
317
|
+
# Cases:
|
318
|
+
# - m==1, which means that all variables occur at most once.
|
319
|
+
# => we cut by a variable that appears in a decomposable generator
|
320
|
+
# - max_exponents = [j]
|
321
|
+
# => cut = var(j)**e, where e is the median of all j-exponents
|
322
|
+
# - max_exponents = [j1,...,jk]
|
323
|
+
# => cut = prod([var(j1),...,var(jk)]) or something of that type.
|
324
|
+
if m == 1:
|
325
|
+
# D.Id is sorted, which means that the last generator is decomposable
|
326
|
+
all_exponents = <ETuple> PyList_GET_ITEM(D.Id, len(D.Id)-1)
|
327
|
+
j = all_exponents._data[2*all_exponents._nonzero-2]
|
328
|
+
cut = all_exponents._new()
|
329
|
+
cut._nonzero = 1
|
330
|
+
cut._data = <int*> sig_malloc(sizeof(int)*2)
|
331
|
+
cut._data[0] = j
|
332
|
+
cut._data[1] = 1
|
333
|
+
if w is None:
|
334
|
+
cut_deg = cut.unweighted_degree()
|
335
|
+
else:
|
336
|
+
cut_deg = cut.weighted_degree(w)
|
337
|
+
# var(j) *only* appears in D.Id[-1]. Hence, D.Id+var(j) will be a split case,
|
338
|
+
# with var(j) and D.Id[:-1]. So, we do the splitting right now.
|
339
|
+
# Only the last generator contains var(j). Hence, D.Id/var(j) is obtained
|
340
|
+
# from D.Id by adding the quotient of its last generator divided by var(j),
|
341
|
+
# of course followed by interreduction.
|
342
|
+
#~ D.LMult = 1 - t**degree(cut,w)
|
343
|
+
fmpz_poly_set_coeff_si(D.LMult, 0, 1)
|
344
|
+
fmpz_poly_set_coeff_si(D.LMult, cut_deg, -1)
|
345
|
+
D.Left = Node.__new__(Node)
|
346
|
+
D.Left.Id = D.Id[:len(D.Id)-1]
|
347
|
+
D.Left.Back = D
|
348
|
+
Id2 = D.Id[:len(D.Id)-1]
|
349
|
+
Id2.append(all_exponents.divide_by_var(j))
|
350
|
+
D.Right = Node.__new__(Node)
|
351
|
+
D.Right.Id = interred(Id2)
|
352
|
+
D.Right.Back = D
|
353
|
+
#~ D.RMult = 1 - D.LMult
|
354
|
+
fmpz_poly_set_coeff_si(D.RMult, cut_deg, 1)
|
355
|
+
else:
|
356
|
+
j = max_exponents[0]
|
357
|
+
e = median([(<ETuple> mon).get_exp(j) for mon in D.Id if (<ETuple> mon).get_exp(j)])
|
358
|
+
cut = all_exponents._new()
|
359
|
+
cut._nonzero = 1
|
360
|
+
cut._data = <int*> sig_malloc(sizeof(int)*2)
|
361
|
+
cut._data[0] = j
|
362
|
+
cut._data[1] = e
|
363
|
+
if w is None:
|
364
|
+
cut_deg = cut.unweighted_degree()
|
365
|
+
else:
|
366
|
+
cut_deg = cut.weighted_degree(w)
|
367
|
+
try:
|
368
|
+
i = D.Id.index(cut)
|
369
|
+
except ValueError:
|
370
|
+
i = -1
|
371
|
+
if i >= 0:
|
372
|
+
# var(j)**e is a generator. Hence, e is the maximal exponent of
|
373
|
+
# var(j) in D.Id, by D.Id being interreduced. But it also is the
|
374
|
+
# truncated median, hence, there cannot be smaller exponents
|
375
|
+
# (for otherwise the median would be strictly smaller than the
|
376
|
+
# maximum). Conclusion: var(j) only appears in the generator var(j)**e
|
377
|
+
# -- we have a split case.
|
378
|
+
Id2 = D.Id[:len(D.Id)]
|
379
|
+
Id2.pop(i)
|
380
|
+
#~ D.LMult = 1-t**degree(cut,w)
|
381
|
+
fmpz_poly_set_coeff_si(D.LMult, 0, 1)
|
382
|
+
fmpz_poly_set_coeff_si(D.LMult, cut_deg, -1)
|
383
|
+
D.Left = Node.__new__(Node)
|
384
|
+
D.Left.Id = Id2
|
385
|
+
D.Left.Back = D
|
386
|
+
D.Right = None
|
387
|
+
else:
|
388
|
+
cut = all_exponents._new()
|
389
|
+
cut._nonzero = 1
|
390
|
+
cut._data = <int*> sig_malloc(sizeof(int)*2)
|
391
|
+
cut._data[0] = j
|
392
|
+
cut._data[1] = e
|
393
|
+
if e > 1:
|
394
|
+
# D.LMult = 1
|
395
|
+
fmpz_poly_set_coeff_si(D.LMult, 0, 1)
|
396
|
+
Id2 = D.Id[:len(D.Id)]
|
397
|
+
Id2.append(cut)
|
398
|
+
D.Left = Node.__new__(Node)
|
399
|
+
D.Left.Id = interred(Id2)
|
400
|
+
D.Left.Back = D
|
401
|
+
D.Right = Node.__new__(Node)
|
402
|
+
D.Right.Id = quotient(D.Id,cut)
|
403
|
+
D.Right.Back = D
|
404
|
+
else:
|
405
|
+
# m > 1, therefore var(j) cannot be a generator (D.Id is interreduced).
|
406
|
+
# D.Id+var(j) will be a split case. So, we do the splitting right now.
|
407
|
+
#~ D.LMult = 1-t**(1 if w is None else w[j])
|
408
|
+
fmpz_poly_set_coeff_si(D.LMult, 0, 1)
|
409
|
+
fmpz_poly_set_coeff_si(D.LMult, (1 if w is None else w[j]), -1)
|
410
|
+
D.Left = Node.__new__(Node)
|
411
|
+
D.Left.Id = [(<ETuple> mon) for mon in D.Id if (<ETuple> mon).get_exp(j) == 0]
|
412
|
+
D.Left.Back = D
|
413
|
+
D.Right = Node.__new__(Node)
|
414
|
+
D.Right.Id = quotient_by_var(D.Id, j)
|
415
|
+
D.Right.Back = D
|
416
|
+
#~ D.RMult = t**(e if w is None else e*w[j])
|
417
|
+
fmpz_poly_set_coeff_si(D.RMult, (e if w is None else e * w[j]), 1)
|
418
|
+
#else:
|
419
|
+
# It may be a good idea to form the product of some of the most
|
420
|
+
# frequent variables. But this isn't implemented yet. TODO?
|
421
|
+
|
422
|
+
|
423
|
+
def first_hilbert_series(I, grading=None, return_grading=False):
|
424
|
+
"""
|
425
|
+
Return the first Hilbert series of the given monomial ideal.
|
426
|
+
|
427
|
+
INPUT:
|
428
|
+
|
429
|
+
- ``I`` -- a monomial ideal (possibly defined in singular)
|
430
|
+
- ``grading`` -- (optional) a list or tuple of integers used as
|
431
|
+
degree weights
|
432
|
+
- ``return_grading`` -- boolean (default: ``False``); whether to return the
|
433
|
+
grading
|
434
|
+
|
435
|
+
OUTPUT:
|
436
|
+
|
437
|
+
A univariate polynomial, namely the first Hilbert function of ``I``, and
|
438
|
+
if ``return_grading==True`` also the grading used to compute the series.
|
439
|
+
|
440
|
+
EXAMPLES::
|
441
|
+
|
442
|
+
sage: from sage.rings.polynomial.hilbert import first_hilbert_series
|
443
|
+
|
444
|
+
sage: # needs sage.libs.singular
|
445
|
+
sage: R = singular.ring(0,'(x,y,z)','dp')
|
446
|
+
sage: I = singular.ideal(['x^2','y^2','z^2'])
|
447
|
+
sage: first_hilbert_series(I)
|
448
|
+
-t^6 + 3*t^4 - 3*t^2 + 1
|
449
|
+
sage: first_hilbert_series(I, return_grading=True)
|
450
|
+
(-t^6 + 3*t^4 - 3*t^2 + 1, (1, 1, 1))
|
451
|
+
sage: first_hilbert_series(I, grading=(1,2,3))
|
452
|
+
-t^12 + t^10 + t^8 - t^4 - t^2 + 1
|
453
|
+
|
454
|
+
TESTS:
|
455
|
+
|
456
|
+
We test against some corner cases::
|
457
|
+
|
458
|
+
sage: R.<x,y,z> = PolynomialRing(QQ)
|
459
|
+
sage: I = 0*R
|
460
|
+
sage: first_hilbert_series(I)
|
461
|
+
1
|
462
|
+
sage: first_hilbert_series(singular(I)) # needs sage.libs.singular
|
463
|
+
1
|
464
|
+
sage: I = 1*R
|
465
|
+
sage: first_hilbert_series(I)
|
466
|
+
0
|
467
|
+
sage: first_hilbert_series(singular(I)) # needs sage.libs.singular
|
468
|
+
0
|
469
|
+
"""
|
470
|
+
from sage.rings.integer_ring import ZZ
|
471
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
472
|
+
PR = PolynomialRing(ZZ, 't')
|
473
|
+
cdef Node AN
|
474
|
+
# The "active node". If a recursive computation is needed, it will be equipped
|
475
|
+
# with a 'Left' and a 'Right' child node, and some 'Multipliers'. Later, the first Hilbert
|
476
|
+
# series of the left child node will be stored in 'LeftFHS', and together with
|
477
|
+
# the first Hilbert series of the right child node and the multiplier yields
|
478
|
+
# the first Hilbert series of 'Id'.
|
479
|
+
cdef tuple w
|
480
|
+
cdef Polynomial_integer_dense_flint fhs = Polynomial_integer_dense_flint.__new__(Polynomial_integer_dense_flint)
|
481
|
+
fhs._parent = PR
|
482
|
+
fhs._is_gen = 0
|
483
|
+
if isinstance(I, sage.interfaces.abc.SingularElement):
|
484
|
+
S = I._check_valid()
|
485
|
+
# First, we need to deal with quotient rings, which also covers the case
|
486
|
+
# of graded commutative rings that arise as cohomology rings in odd characteristic.
|
487
|
+
# We replace everything by a commutative version of the quotient ring.
|
488
|
+
br = S('basering')
|
489
|
+
if S.eval('isQuotientRing(basering)')=='1':
|
490
|
+
L = S('ringlist(basering)')
|
491
|
+
R = S('ring(list(%s[1..3],ideal(0)))' % L.name())
|
492
|
+
R.set_ring()
|
493
|
+
I = S('fetch(%s,%s)+ideal(%s)' % (br.name(), I.name(), br.name()))
|
494
|
+
|
495
|
+
I = [ETuple([int(x) for x in S.eval('string(leadexp({}[{}]))'.format(I.name(), i)).split(',')])
|
496
|
+
for i in range(1,int(S.eval('size({})'.format(I.name())))+1)]
|
497
|
+
br.set_ring()
|
498
|
+
if grading is None:
|
499
|
+
w = tuple(int(S.eval('deg(var({}))'.format(i))) for i in range(1,int(S.eval('nvars(basering)'))+1))
|
500
|
+
else:
|
501
|
+
w = tuple(grading)
|
502
|
+
else:
|
503
|
+
try:
|
504
|
+
I = [bla.exponents()[0] for bla in I if bla]
|
505
|
+
except TypeError:
|
506
|
+
I = [bla.exponents()[0] for bla in I.gens() if bla]
|
507
|
+
if grading is not None:
|
508
|
+
w = tuple(grading)
|
509
|
+
else:
|
510
|
+
w = None
|
511
|
+
|
512
|
+
AN = Node.__new__(Node)
|
513
|
+
AN.Id = interred(I)
|
514
|
+
AN.Back = None
|
515
|
+
|
516
|
+
# Invariant of this function:
|
517
|
+
# At each point, got_result will be false, or got_result is true and fhs
|
518
|
+
# is the first Hilbert series of AN.
|
519
|
+
cdef bint got_result = HilbertBaseCase(fhs, AN, w)
|
520
|
+
while True:
|
521
|
+
if not got_result:
|
522
|
+
make_children(AN, w)
|
523
|
+
AN = AN.Left
|
524
|
+
got_result = HilbertBaseCase(fhs, AN, w)
|
525
|
+
else:
|
526
|
+
if AN.Back is None: # We are back on top, i.e., fhs is the First Hilber Series of I
|
527
|
+
if return_grading:
|
528
|
+
return fhs, w
|
529
|
+
else:
|
530
|
+
return fhs
|
531
|
+
if AN is AN.Back.Left: # We store fhs and proceed to the sibling
|
532
|
+
# ... unless there is no sibling
|
533
|
+
if AN.Back.Right is None:
|
534
|
+
AN = AN.Back
|
535
|
+
#~ fhs *= AN.LMult
|
536
|
+
fmpz_poly_mul(fhs._poly, fhs._poly, AN.LMult)
|
537
|
+
got_result = True
|
538
|
+
else:
|
539
|
+
fmpz_poly_set(AN.Back.LeftFHS, fhs._poly)
|
540
|
+
fmpz_poly_set_si(fhs._poly, 0)
|
541
|
+
AN = AN.Back.Right
|
542
|
+
AN.Back.Left = None
|
543
|
+
got_result = HilbertBaseCase(fhs, AN, w)
|
544
|
+
else: # FHS of the left sibling is stored, of the right sibling is known.
|
545
|
+
AN = AN.Back
|
546
|
+
AN.Right = None
|
547
|
+
#~ fhs = AN.LMult*AN.LeftFHS + AN.RMult*fhs
|
548
|
+
fmpz_poly_mul(AN.LMult, AN.LMult, AN.LeftFHS)
|
549
|
+
fmpz_poly_mul(AN.RMult, AN.RMult, fhs._poly)
|
550
|
+
fmpz_poly_add(fhs._poly, AN.LMult, AN.RMult)
|
551
|
+
got_result = True
|
552
|
+
|
553
|
+
|
554
|
+
def hilbert_poincare_series(I, grading=None):
|
555
|
+
r"""
|
556
|
+
Return the Hilbert Poincaré series of the given monomial ideal.
|
557
|
+
|
558
|
+
INPUT:
|
559
|
+
|
560
|
+
- ``I`` -- a monomial ideal (possibly defined in Singular)
|
561
|
+
- ``grading`` -- (optional) a tuple of degree weights
|
562
|
+
|
563
|
+
EXAMPLES::
|
564
|
+
|
565
|
+
sage: # needs sage.libs.singular
|
566
|
+
sage: from sage.rings.polynomial.hilbert import hilbert_poincare_series
|
567
|
+
sage: R = PolynomialRing(QQ,'x',9)
|
568
|
+
sage: I = [m.lm()
|
569
|
+
....: for m in ((matrix(R, 3, R.gens())^2).list() * R).groebner_basis()] * R
|
570
|
+
sage: hilbert_poincare_series(I)
|
571
|
+
(t^7 - 3*t^6 + 2*t^5 + 2*t^4 - 2*t^3 + 6*t^2 + 5*t + 1)/(t^4 - 4*t^3 + 6*t^2 - 4*t + 1)
|
572
|
+
sage: hilbert_poincare_series((R * R.gens())^2, grading=range(1,10))
|
573
|
+
t^9 + t^8 + t^7 + t^6 + t^5 + t^4 + t^3 + t^2 + t + 1
|
574
|
+
|
575
|
+
The following example is taken from :issue:`20145`::
|
576
|
+
|
577
|
+
sage: # needs sage.libs.singular
|
578
|
+
sage: n=4; m=11; P = PolynomialRing(QQ, n*m, "x"); x = P.gens(); M = Matrix(n, x)
|
579
|
+
sage: from sage.rings.polynomial.hilbert import first_hilbert_series
|
580
|
+
sage: I = P.ideal(M.minors(2))
|
581
|
+
sage: J = P * [m.lm() for m in I.groebner_basis()]
|
582
|
+
sage: hilbert_poincare_series(J).numerator()
|
583
|
+
120*t^3 + 135*t^2 + 30*t + 1
|
584
|
+
sage: hilbert_poincare_series(J).denominator().factor()
|
585
|
+
(t - 1)^14
|
586
|
+
"""
|
587
|
+
cdef Polynomial_integer_dense_flint HP
|
588
|
+
HP, grading = first_hilbert_series(I, grading=grading, return_grading=True)
|
589
|
+
PR = HP._parent
|
590
|
+
|
591
|
+
# If grading was None, but the ideal lives in Singular, then grading is now
|
592
|
+
# the degree vector of Singular's basering.
|
593
|
+
# Otherwise, it may still be None.
|
594
|
+
if grading is None:
|
595
|
+
if HP.leading_coefficient() >= 0:
|
596
|
+
return HP / ((1-PR.gen())**I.ring().ngens())
|
597
|
+
return (-HP) / (-((1-PR.gen())**I.ring().ngens()))
|
598
|
+
else:
|
599
|
+
t = PR.gen()
|
600
|
+
if HP.leading_coefficient() >= 0:
|
601
|
+
return HP / PR.prod([(1-t**d) for d in grading])
|
602
|
+
return (-HP) / (-PR.prod([(1-t**d) for d in grading]))
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
from sage.libs.flint.acb_poly cimport *
|
3
|
+
from sage.rings.polynomial.polynomial_element cimport Polynomial
|
4
|
+
|
5
|
+
cdef class Polynomial_complex_arb(Polynomial):
|
6
|
+
cdef acb_poly_struct[1] _poly # https://github.com/cython/cython/issues/1984
|
7
|
+
cdef Polynomial_complex_arb _new(self)
|