passagemath-flint 10.6.1rc10__cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
- passagemath_flint-10.6.1rc10.dist-info/RECORD +361 -0
- passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
- passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
- passagemath_flint.libs/libflint-aecb9cc5.so.21.0.0 +0 -0
- passagemath_flint.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
- passagemath_flint.libs/libgfortran-8f1e9814.so.5.0.0 +0 -0
- passagemath_flint.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_flint.libs/libgsl-cda90e79.so.28.0.0 +0 -0
- passagemath_flint.libs/libmpfi-e3c25853.so.0.0.0 +0 -0
- passagemath_flint.libs/libmpfr-82690d50.so.6.2.1 +0 -0
- passagemath_flint.libs/libntl-74e7d9a3.so.44.0.1 +0 -0
- passagemath_flint.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_flint.libs/libquadmath-828275a7.so.0.0.0 +0 -0
- sage/all__sagemath_flint.py +29 -0
- sage/combinat/all__sagemath_flint.py +1 -0
- sage/combinat/posets/all__sagemath_flint.py +1 -0
- sage/combinat/posets/hasse_cython_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython_flint.pyx +194 -0
- sage/data_structures/all__sagemath_flint.py +1 -0
- sage/data_structures/bounded_integer_sequences.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/data_structures/bounded_integer_sequences.pxd +62 -0
- sage/data_structures/bounded_integer_sequences.pyx +1418 -0
- sage/graphs/all__sagemath_flint.py +1 -0
- sage/graphs/chrompoly.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/graphs/matchpoly.pyx +412 -0
- sage/libs/all__sagemath_flint.py +17 -0
- sage/libs/arb/__init__.py +1 -0
- sage/libs/arb/acb.pxd +154 -0
- sage/libs/arb/acb_calc.pxd +9 -0
- sage/libs/arb/acb_elliptic.pxd +25 -0
- sage/libs/arb/acb_hypgeom.pxd +74 -0
- sage/libs/arb/acb_mat.pxd +62 -0
- sage/libs/arb/acb_modular.pxd +17 -0
- sage/libs/arb/acb_poly.pxd +216 -0
- sage/libs/arb/arb.pxd +240 -0
- sage/libs/arb/arb_fmpz_poly.pxd +21 -0
- sage/libs/arb/arb_hypgeom.pxd +83 -0
- sage/libs/arb/arb_wrap.h +34 -0
- sage/libs/arb/arf.pxd +131 -0
- sage/libs/arb/arith.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/arb/arith.pyx +87 -0
- sage/libs/arb/bernoulli.pxd +6 -0
- sage/libs/arb/mag.pxd +77 -0
- sage/libs/arb/types.pxd +37 -0
- sage/libs/flint/__init__.py +1 -0
- sage/libs/flint/acb.pxd +270 -0
- sage/libs/flint/acb_calc.pxd +22 -0
- sage/libs/flint/acb_dft.pxd +51 -0
- sage/libs/flint/acb_dirichlet.pxd +112 -0
- sage/libs/flint/acb_elliptic.pxd +42 -0
- sage/libs/flint/acb_hypgeom.pxd +169 -0
- sage/libs/flint/acb_macros.pxd +9 -0
- sage/libs/flint/acb_mat.pxd +136 -0
- sage/libs/flint/acb_mat_macros.pxd +10 -0
- sage/libs/flint/acb_modular.pxd +62 -0
- sage/libs/flint/acb_poly.pxd +251 -0
- sage/libs/flint/acb_poly_macros.pxd +8 -0
- sage/libs/flint/acb_theta.pxd +124 -0
- sage/libs/flint/acf.pxd +32 -0
- sage/libs/flint/aprcl.pxd +84 -0
- sage/libs/flint/arb.pxd +382 -0
- sage/libs/flint/arb_calc.pxd +31 -0
- sage/libs/flint/arb_fmpz_poly.pxd +34 -0
- sage/libs/flint/arb_fpwrap.pxd +215 -0
- sage/libs/flint/arb_hypgeom.pxd +147 -0
- sage/libs/flint/arb_macros.pxd +9 -0
- sage/libs/flint/arb_mat.pxd +140 -0
- sage/libs/flint/arb_mat_macros.pxd +10 -0
- sage/libs/flint/arb_poly.pxd +237 -0
- sage/libs/flint/arf.pxd +167 -0
- sage/libs/flint/arith.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/arith.pxd +76 -0
- sage/libs/flint/arith.pyx +77 -0
- sage/libs/flint/arith_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/arith_sage.pyx +308 -0
- sage/libs/flint/bernoulli.pxd +28 -0
- sage/libs/flint/bool_mat.pxd +52 -0
- sage/libs/flint/ca.pxd +203 -0
- sage/libs/flint/ca_ext.pxd +34 -0
- sage/libs/flint/ca_field.pxd +32 -0
- sage/libs/flint/ca_mat.pxd +117 -0
- sage/libs/flint/ca_poly.pxd +104 -0
- sage/libs/flint/ca_vec.pxd +46 -0
- sage/libs/flint/calcium.pxd +27 -0
- sage/libs/flint/d_mat.pxd +39 -0
- sage/libs/flint/d_vec.pxd +32 -0
- sage/libs/flint/dirichlet.pxd +57 -0
- sage/libs/flint/dlog.pxd +53 -0
- sage/libs/flint/double_extras.pxd +24 -0
- sage/libs/flint/double_interval.pxd +36 -0
- sage/libs/flint/fexpr.pxd +104 -0
- sage/libs/flint/fexpr_builtin.pxd +20 -0
- sage/libs/flint/fft.pxd +66 -0
- sage/libs/flint/flint.pxd +36 -0
- sage/libs/flint/flint_ntl_wrap.h +35 -0
- sage/libs/flint/flint_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/flint_sage.pyx +163 -0
- sage/libs/flint/flint_wrap.h +190 -0
- sage/libs/flint/fmpq.pxd +137 -0
- sage/libs/flint/fmpq_mat.pxd +105 -0
- sage/libs/flint/fmpq_mat_macros.pxd +10 -0
- sage/libs/flint/fmpq_mpoly.pxd +165 -0
- sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
- sage/libs/flint/fmpq_poly.pxd +241 -0
- sage/libs/flint/fmpq_poly_macros.pxd +9 -0
- sage/libs/flint/fmpq_poly_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpq_poly_sage.pxd +31 -0
- sage/libs/flint/fmpq_poly_sage.pyx +48 -0
- sage/libs/flint/fmpq_vec.pxd +27 -0
- sage/libs/flint/fmpz.pxd +256 -0
- sage/libs/flint/fmpz_extras.pxd +32 -0
- sage/libs/flint/fmpz_factor.pxd +42 -0
- sage/libs/flint/fmpz_factor_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_factor_sage.pxd +4 -0
- sage/libs/flint/fmpz_factor_sage.pyx +29 -0
- sage/libs/flint/fmpz_lll.pxd +49 -0
- sage/libs/flint/fmpz_macros.pxd +8 -0
- sage/libs/flint/fmpz_mat.pxd +184 -0
- sage/libs/flint/fmpz_mat_macros.pxd +10 -0
- sage/libs/flint/fmpz_mod.pxd +46 -0
- sage/libs/flint/fmpz_mod_mat.pxd +71 -0
- sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
- sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fmpz_mod_poly.pxd +249 -0
- sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
- sage/libs/flint/fmpz_mod_vec.pxd +27 -0
- sage/libs/flint/fmpz_mpoly.pxd +224 -0
- sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
- sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
- sage/libs/flint/fmpz_poly.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly.pxd +407 -0
- sage/libs/flint/fmpz_poly.pyx +19 -0
- sage/libs/flint/fmpz_poly_factor.pxd +33 -0
- sage/libs/flint/fmpz_poly_macros.pxd +8 -0
- sage/libs/flint/fmpz_poly_mat.pxd +71 -0
- sage/libs/flint/fmpz_poly_q.pxd +55 -0
- sage/libs/flint/fmpz_poly_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly_sage.pxd +20 -0
- sage/libs/flint/fmpz_poly_sage.pyx +500 -0
- sage/libs/flint/fmpz_vec.pxd +80 -0
- sage/libs/flint/fmpzi.pxd +52 -0
- sage/libs/flint/fq.pxd +97 -0
- sage/libs/flint/fq_default.pxd +84 -0
- sage/libs/flint/fq_default_mat.pxd +70 -0
- sage/libs/flint/fq_default_poly.pxd +97 -0
- sage/libs/flint/fq_default_poly_factor.pxd +39 -0
- sage/libs/flint/fq_embed.pxd +28 -0
- sage/libs/flint/fq_mat.pxd +83 -0
- sage/libs/flint/fq_nmod.pxd +95 -0
- sage/libs/flint/fq_nmod_embed.pxd +28 -0
- sage/libs/flint/fq_nmod_mat.pxd +83 -0
- sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
- sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fq_nmod_poly.pxd +202 -0
- sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
- sage/libs/flint/fq_nmod_vec.pxd +33 -0
- sage/libs/flint/fq_poly.pxd +204 -0
- sage/libs/flint/fq_poly_factor.pxd +47 -0
- sage/libs/flint/fq_vec.pxd +33 -0
- sage/libs/flint/fq_zech.pxd +99 -0
- sage/libs/flint/fq_zech_embed.pxd +28 -0
- sage/libs/flint/fq_zech_mat.pxd +78 -0
- sage/libs/flint/fq_zech_poly.pxd +198 -0
- sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
- sage/libs/flint/fq_zech_vec.pxd +33 -0
- sage/libs/flint/gr.pxd +174 -0
- sage/libs/flint/gr_generic.pxd +215 -0
- sage/libs/flint/gr_mat.pxd +161 -0
- sage/libs/flint/gr_mpoly.pxd +68 -0
- sage/libs/flint/gr_poly.pxd +276 -0
- sage/libs/flint/gr_special.pxd +237 -0
- sage/libs/flint/gr_vec.pxd +120 -0
- sage/libs/flint/hypgeom.pxd +24 -0
- sage/libs/flint/long_extras.pxd +23 -0
- sage/libs/flint/mag.pxd +131 -0
- sage/libs/flint/mag_macros.pxd +8 -0
- sage/libs/flint/mpf_mat.pxd +36 -0
- sage/libs/flint/mpf_vec.pxd +34 -0
- sage/libs/flint/mpfr_mat.pxd +27 -0
- sage/libs/flint/mpfr_vec.pxd +25 -0
- sage/libs/flint/mpn_extras.pxd +41 -0
- sage/libs/flint/mpoly.pxd +72 -0
- sage/libs/flint/nf.pxd +19 -0
- sage/libs/flint/nf_elem.pxd +74 -0
- sage/libs/flint/nmod.pxd +35 -0
- sage/libs/flint/nmod_mat.pxd +104 -0
- sage/libs/flint/nmod_mpoly.pxd +144 -0
- sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/nmod_poly.pxd +339 -0
- sage/libs/flint/nmod_poly_factor.pxd +44 -0
- sage/libs/flint/nmod_poly_linkage.pxi +710 -0
- sage/libs/flint/nmod_poly_mat.pxd +76 -0
- sage/libs/flint/nmod_vec.pxd +40 -0
- sage/libs/flint/ntl_interface.pxd +17 -0
- sage/libs/flint/padic.pxd +93 -0
- sage/libs/flint/padic_mat.pxd +64 -0
- sage/libs/flint/padic_poly.pxd +88 -0
- sage/libs/flint/partitions.pxd +23 -0
- sage/libs/flint/perm.pxd +26 -0
- sage/libs/flint/profiler.pxd +24 -0
- sage/libs/flint/qadic.pxd +77 -0
- sage/libs/flint/qfb.pxd +44 -0
- sage/libs/flint/qqbar.pxd +172 -0
- sage/libs/flint/qsieve.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve.pxd +41 -0
- sage/libs/flint/qsieve.pyx +21 -0
- sage/libs/flint/qsieve_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve_sage.pyx +67 -0
- sage/libs/flint/thread_pool.pxd +25 -0
- sage/libs/flint/types.pxd +2076 -0
- sage/libs/flint/ulong_extras.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras.pxd +141 -0
- sage/libs/flint/ulong_extras.pyx +21 -0
- sage/libs/flint/ulong_extras_sage.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras_sage.pyx +21 -0
- sage/matrix/all__sagemath_flint.py +1 -0
- sage/matrix/change_ring.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_complex_ball_dense.pxd +14 -0
- sage/matrix/matrix_complex_ball_dense.pyx +973 -0
- sage/matrix/matrix_cyclo_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_cyclo_dense.pxd +16 -0
- sage/matrix/matrix_cyclo_dense.pyx +1761 -0
- sage/matrix/matrix_integer_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_dense.pxd +32 -0
- sage/matrix/matrix_integer_dense.pyx +5801 -0
- sage/matrix/matrix_integer_dense_hnf.py +1294 -0
- sage/matrix/matrix_integer_dense_saturation.py +346 -0
- sage/matrix/matrix_integer_sparse.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_sparse.pxd +9 -0
- sage/matrix/matrix_integer_sparse.pyx +1090 -0
- sage/matrix/matrix_rational_dense.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_dense.pxd +23 -0
- sage/matrix/matrix_rational_dense.pyx +2995 -0
- sage/matrix/matrix_rational_sparse.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_sparse.pxd +11 -0
- sage/matrix/matrix_rational_sparse.pyx +789 -0
- sage/matrix/misc_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/matrix/misc_flint.pyx +109 -0
- sage/modular/all__sagemath_flint.py +1 -0
- sage/modular/modform/all__sagemath_flint.py +1 -0
- sage/modular/modform/eis_series_cython.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/modform/eis_series_cython.pyx +226 -0
- sage/modular/modsym/all__sagemath_flint.py +1 -0
- sage/modular/modsym/apply.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/modsym/apply.pxd +6 -0
- sage/modular/modsym/apply.pyx +113 -0
- sage/modular/modsym/heilbronn.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/modsym/heilbronn.pyx +966 -0
- sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
- sage/modular/pollack_stevens/dist.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/modular/pollack_stevens/dist.pxd +38 -0
- sage/modular/pollack_stevens/dist.pyx +1439 -0
- sage/quivers/algebra.py +691 -0
- sage/quivers/algebra_elements.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/quivers/algebra_elements.pxd +97 -0
- sage/quivers/algebra_elements.pxi +1324 -0
- sage/quivers/algebra_elements.pyx +1424 -0
- sage/quivers/all.py +1 -0
- sage/quivers/ar_quiver.py +917 -0
- sage/quivers/homspace.py +640 -0
- sage/quivers/morphism.py +1282 -0
- sage/quivers/path_semigroup.py +1155 -0
- sage/quivers/paths.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/quivers/paths.pxd +13 -0
- sage/quivers/paths.pyx +809 -0
- sage/quivers/representation.py +2975 -0
- sage/rings/all__sagemath_flint.py +37 -0
- sage/rings/cif.py +4 -0
- sage/rings/complex_arb.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_arb.pxd +29 -0
- sage/rings/complex_arb.pyx +5176 -0
- sage/rings/complex_interval.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_interval.pxd +30 -0
- sage/rings/complex_interval.pyx +2475 -0
- sage/rings/complex_interval_field.py +711 -0
- sage/rings/convert/all.py +1 -0
- sage/rings/convert/mpfi.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/convert/mpfi.pxd +6 -0
- sage/rings/convert/mpfi.pyx +576 -0
- sage/rings/factorint_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/fraction_field_FpT.pxd +28 -0
- sage/rings/fraction_field_FpT.pyx +2043 -0
- sage/rings/imaginary_unit.py +5 -0
- sage/rings/monomials.py +73 -0
- sage/rings/number_field/S_unit_solver.py +2870 -0
- sage/rings/number_field/all__sagemath_flint.py +7 -0
- sage/rings/number_field/bdd_height.py +664 -0
- sage/rings/number_field/class_group.py +762 -0
- sage/rings/number_field/galois_group.py +1307 -0
- sage/rings/number_field/homset.py +612 -0
- sage/rings/number_field/maps.py +687 -0
- sage/rings/number_field/morphism.py +272 -0
- sage/rings/number_field/number_field.py +12820 -0
- sage/rings/number_field/number_field_element.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element.pxd +59 -0
- sage/rings/number_field/number_field_element.pyx +5735 -0
- sage/rings/number_field/number_field_element_quadratic.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
- sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
- sage/rings/number_field/number_field_ideal_rel.py +925 -0
- sage/rings/number_field/number_field_morphisms.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_morphisms.pyx +781 -0
- sage/rings/number_field/number_field_rel.py +2734 -0
- sage/rings/number_field/order.py +2981 -0
- sage/rings/number_field/order_ideal.py +804 -0
- sage/rings/number_field/selmer_group.py +715 -0
- sage/rings/number_field/small_primes_of_degree_one.py +242 -0
- sage/rings/number_field/splitting_field.py +606 -0
- sage/rings/number_field/structure.py +380 -0
- sage/rings/number_field/unit_group.py +721 -0
- sage/rings/padics/all__sagemath_flint.py +3 -0
- sage/rings/polynomial/all__sagemath_flint.py +1 -0
- sage/rings/polynomial/complex_roots.py +312 -0
- sage/rings/polynomial/evaluation_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/evaluation_flint.pxd +7 -0
- sage/rings/polynomial/evaluation_flint.pyx +68 -0
- sage/rings/polynomial/hilbert.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
- sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
- sage/rings/polynomial/polynomial_number_field.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
- sage/rings/polynomial/polynomial_zmod_flint.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
- sage/rings/polynomial/real_roots.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/real_roots.pxd +81 -0
- sage/rings/polynomial/real_roots.pyx +4704 -0
- sage/rings/polynomial/refine_root.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/refine_root.pyx +142 -0
- sage/rings/polynomial/weil/all.py +4 -0
- sage/rings/polynomial/weil/power_sums.h +46 -0
- sage/rings/polynomial/weil/weil_polynomials.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
- sage/rings/qqbar.py +9025 -0
- sage/rings/real_arb.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/real_arb.pxd +21 -0
- sage/rings/real_arb.pyx +4065 -0
- sage/rings/real_interval_absolute.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/rings/real_mpfi.pyx +5428 -0
- sage/schemes/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.cpython-311-x86_64-linux-gnu.so +0 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
- sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,1418 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
r"""
|
3
|
+
Sequences of bounded integers
|
4
|
+
|
5
|
+
This module provides :class:`BoundedIntegerSequence`, which implements
|
6
|
+
sequences of bounded integers and is for many (but not all) operations faster
|
7
|
+
than representing the same sequence as a Python :class:`tuple`.
|
8
|
+
|
9
|
+
The underlying data structure is similar to :class:`~sage.misc.bitset.Bitset`,
|
10
|
+
which means that certain operations are implemented by using fast shift
|
11
|
+
operations from MPIR. The following boilerplate functions can be
|
12
|
+
cimported in Cython modules:
|
13
|
+
|
14
|
+
- ``cdef bint biseq_init(biseq_t R, mp_size_t l, mp_size_t itemsize) except -1``
|
15
|
+
|
16
|
+
Allocate memory for a bounded integer sequence of length ``l`` with
|
17
|
+
items fitting in ``itemsize`` bits.
|
18
|
+
|
19
|
+
- ``cdef inline void biseq_dealloc(biseq_t S)``
|
20
|
+
|
21
|
+
Deallocate the memory used by ``S``.
|
22
|
+
|
23
|
+
- ``cdef bint biseq_init_copy(biseq_t R, biseq_t S)``
|
24
|
+
|
25
|
+
Initialize ``R`` as a copy of ``S``.
|
26
|
+
|
27
|
+
- ``cdef tuple biseq_pickle(biseq_t S)``
|
28
|
+
|
29
|
+
Return a triple ``(bitset_data, itembitsize, length)`` defining ``S``.
|
30
|
+
|
31
|
+
- ``cdef bint biseq_unpickle(biseq_t R, tuple bitset_data, mp_bitcnt_t itembitsize, mp_size_t length) except -1``
|
32
|
+
|
33
|
+
Initialise ``R`` from data returned by ``biseq_pickle``.
|
34
|
+
|
35
|
+
- ``cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1``
|
36
|
+
|
37
|
+
Convert a list to a bounded integer sequence, which must not be allocated.
|
38
|
+
|
39
|
+
- ``cdef inline Py_hash_t biseq_hash(biseq_t S)``
|
40
|
+
|
41
|
+
Hash value for ``S``.
|
42
|
+
|
43
|
+
- ``cdef inline bint biseq_richcmp(biseq_t S1, biseq_t S2, int op)``
|
44
|
+
|
45
|
+
Comparison of ``S1`` and ``S2``. This takes into account the bound, the
|
46
|
+
length, and the list of items of the two sequences.
|
47
|
+
|
48
|
+
- ``cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1``
|
49
|
+
|
50
|
+
Concatenate ``S1`` and ``S2`` and write the result to ``R``. Does not test
|
51
|
+
whether the sequences have the same bound!
|
52
|
+
|
53
|
+
- ``cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2)``
|
54
|
+
|
55
|
+
Is ``S1=S2+something``? Does not check whether the sequences have the same
|
56
|
+
bound!
|
57
|
+
|
58
|
+
- ``cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2``
|
59
|
+
|
60
|
+
Return the position in ``S1`` of ``S2`` as a subsequence of
|
61
|
+
``S1[start:]``, or ``-1`` if ``S2`` is not a subsequence. Does not check
|
62
|
+
whether the sequences have the same bound!
|
63
|
+
|
64
|
+
- ``cdef mp_size_t biseq_starswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) except -2:``
|
65
|
+
|
66
|
+
Return the smallest number ``i`` such that the bounded integer sequence
|
67
|
+
``S1`` starts with the sequence ``S2[i:]``, where ``start <= i <
|
68
|
+
S1.length``, or return ``-1`` if no such ``i`` exists.
|
69
|
+
|
70
|
+
- ``cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2``
|
71
|
+
|
72
|
+
Return the position in ``S`` of the item in ``S[start:]``, or ``-1`` if
|
73
|
+
``S[start:]`` does not contain the item.
|
74
|
+
|
75
|
+
- ``cdef size_t biseq_getitem(biseq_t S, mp_size_t index)``
|
76
|
+
|
77
|
+
Return ``S[index]``, without checking margins.
|
78
|
+
|
79
|
+
- ``cdef size_t biseq_getitem_py(biseq_t S, mp_size_t index)``
|
80
|
+
|
81
|
+
Return ``S[index]`` as Python ``int``, without checking margins.
|
82
|
+
|
83
|
+
- ``cdef biseq_inititem(biseq_t S, mp_size_t index, size_t item)``
|
84
|
+
|
85
|
+
Set ``S[index] = item``, without checking margins and assuming that ``S[index]``
|
86
|
+
has previously been zero.
|
87
|
+
|
88
|
+
- ``cdef inline void biseq_clearitem(biseq_t S, mp_size_t index)``
|
89
|
+
|
90
|
+
Set ``S[index] = 0``, without checking margins.
|
91
|
+
|
92
|
+
- ``cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, mp_size_t step) except -1``
|
93
|
+
|
94
|
+
Initialise ``R`` with ``S[start:stop:step]``.
|
95
|
+
|
96
|
+
AUTHORS:
|
97
|
+
|
98
|
+
- Simon King, Jeroen Demeyer (2014-10): initial version (:issue:`15820`)
|
99
|
+
"""
|
100
|
+
# ****************************************************************************
|
101
|
+
# Copyright (C) 2014 Simon King <simon.king@uni-jena.de>
|
102
|
+
# Copyright (C) 2014 Jeroen Demeyer <jdemeyer@cage.ugennt.be>
|
103
|
+
#
|
104
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
105
|
+
# as published by the Free Software Foundation; either version 2 of
|
106
|
+
# the License, or (at your option) any later version.
|
107
|
+
# https://www.gnu.org/licenses/
|
108
|
+
# ****************************************************************************
|
109
|
+
|
110
|
+
from cysignals.signals cimport sig_check, sig_on, sig_off
|
111
|
+
from sage.data_structures.bitset_base cimport *
|
112
|
+
|
113
|
+
from cpython.long cimport PyLong_FromSize_t
|
114
|
+
from cpython.slice cimport PySlice_GetIndicesEx
|
115
|
+
from sage.libs.flint.flint cimport FLINT_BIT_COUNT as BIT_COUNT
|
116
|
+
from sage.structure.richcmp cimport richcmp_not_equal, rich_to_bool
|
117
|
+
|
118
|
+
cimport cython
|
119
|
+
|
120
|
+
###################
|
121
|
+
# Boilerplate
|
122
|
+
# cdef functions
|
123
|
+
###################
|
124
|
+
|
125
|
+
#
|
126
|
+
# (De)allocation, copying
|
127
|
+
#
|
128
|
+
|
129
|
+
|
130
|
+
@cython.overflowcheck
|
131
|
+
cdef bint biseq_init(biseq_t R, mp_size_t l, mp_bitcnt_t itemsize) except -1:
|
132
|
+
"""
|
133
|
+
Allocate memory for a bounded integer sequence of length ``l`` with
|
134
|
+
items fitting in ``itemsize`` bits.
|
135
|
+
"""
|
136
|
+
cdef mp_bitcnt_t totalbitsize
|
137
|
+
if l:
|
138
|
+
totalbitsize = l * itemsize
|
139
|
+
else:
|
140
|
+
totalbitsize = 1
|
141
|
+
bitset_init(R.data, totalbitsize)
|
142
|
+
R.length = l
|
143
|
+
R.itembitsize = itemsize
|
144
|
+
R.mask_item = limb_lower_bits_up(itemsize)
|
145
|
+
|
146
|
+
cdef inline void biseq_dealloc(biseq_t S) noexcept:
|
147
|
+
"""
|
148
|
+
Deallocate the memory used by ``S``.
|
149
|
+
"""
|
150
|
+
bitset_free(S.data)
|
151
|
+
|
152
|
+
cdef bint biseq_init_copy(biseq_t R, biseq_t S) except -1:
|
153
|
+
"""
|
154
|
+
Initialize ``R`` as a copy of ``S``.
|
155
|
+
"""
|
156
|
+
biseq_init(R, S.length, S.itembitsize)
|
157
|
+
sig_on()
|
158
|
+
bitset_copy(R.data, S.data)
|
159
|
+
sig_off()
|
160
|
+
|
161
|
+
#
|
162
|
+
# Pickling
|
163
|
+
#
|
164
|
+
|
165
|
+
cdef tuple biseq_pickle(biseq_t S):
|
166
|
+
return (bitset_pickle(S.data), S.itembitsize, S.length)
|
167
|
+
|
168
|
+
cdef bint biseq_unpickle(biseq_t R, tuple bitset_data, mp_bitcnt_t itembitsize, mp_size_t length) except -1:
|
169
|
+
biseq_init(R, length, itembitsize)
|
170
|
+
sig_on()
|
171
|
+
bitset_unpickle(R.data, bitset_data)
|
172
|
+
sig_off()
|
173
|
+
return 1
|
174
|
+
|
175
|
+
#
|
176
|
+
# Conversion
|
177
|
+
#
|
178
|
+
|
179
|
+
cdef bint biseq_init_list(biseq_t R, list data, size_t bound) except -1:
|
180
|
+
"""
|
181
|
+
Convert a list into a bounded integer sequence and write the result
|
182
|
+
into ``R``, which must not be initialised.
|
183
|
+
|
184
|
+
INPUT:
|
185
|
+
|
186
|
+
- ``data`` -- list of integers
|
187
|
+
|
188
|
+
- ``bound`` -- a number which is the maximal value of an item
|
189
|
+
"""
|
190
|
+
cdef mp_size_t index = 0
|
191
|
+
cdef size_t item_c
|
192
|
+
|
193
|
+
biseq_init(R, len(data), BIT_COUNT(bound|<size_t>1))
|
194
|
+
|
195
|
+
for item in data:
|
196
|
+
sig_check()
|
197
|
+
item_c = item
|
198
|
+
if item_c > bound:
|
199
|
+
raise OverflowError("list item {!r} larger than {}".format(item, bound))
|
200
|
+
biseq_inititem(R, index, item_c)
|
201
|
+
index += 1
|
202
|
+
|
203
|
+
cdef inline Py_hash_t biseq_hash(biseq_t S) noexcept:
|
204
|
+
return S.itembitsize*(<Py_hash_t>1073807360)+bitset_hash(S.data)
|
205
|
+
|
206
|
+
cdef inline bint biseq_richcmp(biseq_t S1, biseq_t S2, int op) noexcept:
|
207
|
+
if S1.itembitsize != S2.itembitsize:
|
208
|
+
return richcmp_not_equal(S1.itembitsize, S2.itembitsize, op)
|
209
|
+
if S1.length != S2.length:
|
210
|
+
return richcmp_not_equal(S1.length, S2.length, op)
|
211
|
+
return rich_to_bool(op, bitset_cmp(S1.data, S2.data))
|
212
|
+
|
213
|
+
#
|
214
|
+
# Arithmetics
|
215
|
+
#
|
216
|
+
|
217
|
+
cdef bint biseq_init_concat(biseq_t R, biseq_t S1, biseq_t S2) except -1:
|
218
|
+
"""
|
219
|
+
Concatenate two bounded integer sequences ``S1`` and ``S2``.
|
220
|
+
|
221
|
+
ASSUMPTION:
|
222
|
+
|
223
|
+
- The two sequences must have equivalent bounds, i.e., the items on the
|
224
|
+
sequences must fit into the same number of bits.
|
225
|
+
|
226
|
+
OUTPUT:
|
227
|
+
|
228
|
+
The result is written into ``R``, which must not be initialised
|
229
|
+
"""
|
230
|
+
biseq_init(R, S1.length + S2.length, S1.itembitsize)
|
231
|
+
sig_on()
|
232
|
+
bitset_lshift(R.data, S2.data, S1.length * S1.itembitsize)
|
233
|
+
bitset_or(R.data, R.data, S1.data)
|
234
|
+
sig_off()
|
235
|
+
|
236
|
+
|
237
|
+
cdef inline bint biseq_startswith(biseq_t S1, biseq_t S2) except -1:
|
238
|
+
"""
|
239
|
+
Test if bounded integer sequence ``S1`` starts with bounded integer
|
240
|
+
sequence ``S2``.
|
241
|
+
|
242
|
+
ASSUMPTION:
|
243
|
+
|
244
|
+
- The two sequences must have equivalent bounds, i.e., the items on the
|
245
|
+
sequences must fit into the same number of bits. This condition is not
|
246
|
+
tested.
|
247
|
+
"""
|
248
|
+
if S2.length > S1.length:
|
249
|
+
return False
|
250
|
+
if S2.length == 0:
|
251
|
+
return True
|
252
|
+
sig_on()
|
253
|
+
ret = mpn_equal_bits(S1.data.bits, S2.data.bits, S2.data.size)
|
254
|
+
sig_off()
|
255
|
+
return ret
|
256
|
+
|
257
|
+
|
258
|
+
cdef mp_size_t biseq_index(biseq_t S, size_t item, mp_size_t start) except -2:
|
259
|
+
"""
|
260
|
+
Return the position in ``S`` of an item in ``S[start:]``, or -1 if
|
261
|
+
``S[start:]`` does not contain the item.
|
262
|
+
"""
|
263
|
+
cdef mp_size_t index
|
264
|
+
sig_on()
|
265
|
+
for index from start <= index < S.length:
|
266
|
+
if biseq_getitem(S, index) == item:
|
267
|
+
sig_off()
|
268
|
+
return index
|
269
|
+
sig_off()
|
270
|
+
return -1
|
271
|
+
|
272
|
+
|
273
|
+
cdef inline size_t biseq_getitem(biseq_t S, mp_size_t index) noexcept:
|
274
|
+
"""
|
275
|
+
Get item ``S[index]``, without checking margins.
|
276
|
+
"""
|
277
|
+
cdef mp_bitcnt_t limb_index, bit_index
|
278
|
+
bit_index = (<mp_bitcnt_t>index) * S.itembitsize
|
279
|
+
limb_index = bit_index // GMP_LIMB_BITS
|
280
|
+
bit_index %= GMP_LIMB_BITS
|
281
|
+
|
282
|
+
cdef mp_limb_t out
|
283
|
+
out = (S.data.bits[limb_index]) >> bit_index
|
284
|
+
if bit_index + S.itembitsize > GMP_LIMB_BITS:
|
285
|
+
# Our item is stored using 2 limbs, add the part from the upper limb
|
286
|
+
out |= (S.data.bits[limb_index+1]) << (GMP_LIMB_BITS - bit_index)
|
287
|
+
return out & S.mask_item
|
288
|
+
|
289
|
+
cdef biseq_getitem_py(biseq_t S, mp_size_t index):
|
290
|
+
"""
|
291
|
+
Get item ``S[index]`` as a Python ``int``, without
|
292
|
+
checking margins.
|
293
|
+
"""
|
294
|
+
cdef size_t out = biseq_getitem(S, index)
|
295
|
+
return PyLong_FromSize_t(out)
|
296
|
+
|
297
|
+
cdef inline void biseq_inititem(biseq_t S, mp_size_t index, size_t item) noexcept:
|
298
|
+
"""
|
299
|
+
Set ``S[index] = item``, without checking margins.
|
300
|
+
|
301
|
+
Note that it is assumed that ``S[index] == 0`` before the assignment.
|
302
|
+
"""
|
303
|
+
cdef mp_bitcnt_t limb_index, bit_index
|
304
|
+
bit_index = (<mp_bitcnt_t>index) * S.itembitsize
|
305
|
+
limb_index = bit_index // GMP_LIMB_BITS
|
306
|
+
bit_index %= GMP_LIMB_BITS
|
307
|
+
|
308
|
+
S.data.bits[limb_index] |= (item << bit_index)
|
309
|
+
# Have some bits been shifted out of bound?
|
310
|
+
if bit_index + S.itembitsize > GMP_LIMB_BITS:
|
311
|
+
# Our item is stored using 2 limbs, add the part from the upper limb
|
312
|
+
S.data.bits[limb_index+1] |= (item >> (GMP_LIMB_BITS - bit_index))
|
313
|
+
|
314
|
+
cdef inline void biseq_clearitem(biseq_t S, mp_size_t index) noexcept:
|
315
|
+
"""
|
316
|
+
Set ``S[index] = 0``, without checking margins.
|
317
|
+
|
318
|
+
In contrast to ``biseq_inititem``, the previous content of ``S[index]``
|
319
|
+
will be erased.
|
320
|
+
"""
|
321
|
+
cdef mp_bitcnt_t limb_index, bit_index
|
322
|
+
bit_index = (<mp_bitcnt_t>index) * S.itembitsize
|
323
|
+
limb_index = bit_index // GMP_LIMB_BITS
|
324
|
+
bit_index %= GMP_LIMB_BITS
|
325
|
+
|
326
|
+
S.data.bits[limb_index] &= ~(S.mask_item << bit_index)
|
327
|
+
# Have some bits been shifted out of bound?
|
328
|
+
if bit_index + S.itembitsize > GMP_LIMB_BITS:
|
329
|
+
# Our item is stored using 2 limbs, add the part from the upper limb
|
330
|
+
S.data.bits[limb_index+1] &= ~(S.mask_item >> (GMP_LIMB_BITS - bit_index))
|
331
|
+
|
332
|
+
cdef bint biseq_init_slice(biseq_t R, biseq_t S, mp_size_t start, mp_size_t stop, mp_size_t step) except -1:
|
333
|
+
"""
|
334
|
+
Create the slice ``S[start:stop:step]`` as bounded integer sequence
|
335
|
+
and write the result to ``R``, which must not be initialised.
|
336
|
+
"""
|
337
|
+
cdef mp_size_t length = 0
|
338
|
+
if step > 0:
|
339
|
+
if stop > start:
|
340
|
+
length = ((stop-start-1)//step)+1
|
341
|
+
else:
|
342
|
+
if stop < start:
|
343
|
+
length = ((stop-start+1)//step)+1
|
344
|
+
biseq_init(R, length, S.itembitsize)
|
345
|
+
|
346
|
+
if not length:
|
347
|
+
return 0
|
348
|
+
|
349
|
+
if step == 1:
|
350
|
+
# Slicing essentially boils down to a shift operation.
|
351
|
+
sig_on()
|
352
|
+
bitset_rshift(R.data, S.data, start*S.itembitsize)
|
353
|
+
sig_off()
|
354
|
+
return 0
|
355
|
+
|
356
|
+
# In the general case, we move item by item.
|
357
|
+
cdef mp_size_t src_index = start
|
358
|
+
cdef mp_size_t tgt_index
|
359
|
+
sig_on()
|
360
|
+
for tgt_index in range(length):
|
361
|
+
biseq_inititem(R, tgt_index, biseq_getitem(S, src_index))
|
362
|
+
src_index += step
|
363
|
+
sig_off()
|
364
|
+
|
365
|
+
|
366
|
+
cdef mp_size_t biseq_contains(biseq_t S1, biseq_t S2, mp_size_t start) except -2:
|
367
|
+
"""
|
368
|
+
Test if the bounded integer sequence ``S1[start:]`` contains a
|
369
|
+
sub-sequence ``S2``.
|
370
|
+
|
371
|
+
INPUT:
|
372
|
+
|
373
|
+
- ``S1``, ``S2`` -- two bounded integer sequences
|
374
|
+
- ``start`` -- integer; start index
|
375
|
+
|
376
|
+
OUTPUT:
|
377
|
+
|
378
|
+
The smallest index ``i >= start`` such that ``S1[i:]`` starts with
|
379
|
+
``S2``, or ``-1`` if ``S1[start:]`` does not contain ``S2``.
|
380
|
+
|
381
|
+
ASSUMPTION:
|
382
|
+
|
383
|
+
- The two sequences must have equivalent bounds, i.e., the items on the
|
384
|
+
sequences must fit into the same number of bits. This condition is not
|
385
|
+
tested.
|
386
|
+
"""
|
387
|
+
if S2.length == 0:
|
388
|
+
return start
|
389
|
+
cdef mp_size_t index
|
390
|
+
sig_on()
|
391
|
+
for index from start <= index <= S1.length-S2.length:
|
392
|
+
if mpn_equal_bits_shifted(S2.data.bits, S1.data.bits,
|
393
|
+
S2.length * S2.itembitsize,
|
394
|
+
index * S2.itembitsize):
|
395
|
+
sig_off()
|
396
|
+
return index
|
397
|
+
sig_off()
|
398
|
+
return -1
|
399
|
+
|
400
|
+
cdef mp_size_t biseq_startswith_tail(biseq_t S1, biseq_t S2, mp_size_t start) except -2:
|
401
|
+
"""
|
402
|
+
Return the smallest index ``i`` such that the bounded integer sequence
|
403
|
+
``S1`` starts with the sequence ``S2[i:]``, where ``start <= i <
|
404
|
+
S2.length``.
|
405
|
+
|
406
|
+
INPUT:
|
407
|
+
|
408
|
+
- ``S1``, ``S2`` -- two bounded integer sequences
|
409
|
+
- ``start`` -- integer; start index
|
410
|
+
|
411
|
+
OUTPUT:
|
412
|
+
|
413
|
+
The smallest index ``i >= start`` such that ``S1`` starts with ``S2[i:],
|
414
|
+
or ``-1`` if no such ``i < S2.length`` exists.
|
415
|
+
|
416
|
+
ASSUMPTION:
|
417
|
+
|
418
|
+
- The two sequences must have equivalent bounds, i.e., the items on the
|
419
|
+
sequences must fit into the same number of bits. This condition is not
|
420
|
+
tested.
|
421
|
+
"""
|
422
|
+
# Increase start if S1 is too short to contain S2[start:]
|
423
|
+
if S1.length < S2.length - start:
|
424
|
+
start = S2.length - S1.length
|
425
|
+
cdef mp_size_t index
|
426
|
+
sig_on()
|
427
|
+
for index from start <= index < S2.length:
|
428
|
+
if mpn_equal_bits_shifted(S1.data.bits, S2.data.bits,
|
429
|
+
(S2.length - index) * S2.itembitsize,
|
430
|
+
index * S2.itembitsize):
|
431
|
+
sig_off()
|
432
|
+
return index
|
433
|
+
sig_off()
|
434
|
+
return -1
|
435
|
+
|
436
|
+
|
437
|
+
###########################################
|
438
|
+
# A cdef class that wraps the above, and
|
439
|
+
# behaves like a tuple
|
440
|
+
|
441
|
+
from sage.rings.integer cimport smallInteger
|
442
|
+
|
443
|
+
|
444
|
+
cdef class BoundedIntegerSequence:
|
445
|
+
"""
|
446
|
+
A sequence of nonnegative uniformly bounded integers.
|
447
|
+
|
448
|
+
INPUT:
|
449
|
+
|
450
|
+
- ``bound`` -- nonnegative integer. When zero, a :exc:`ValueError`
|
451
|
+
will be raised. Otherwise, the given bound is replaced by the
|
452
|
+
power of two that is at least the given bound.
|
453
|
+
- ``data`` -- list of integers
|
454
|
+
|
455
|
+
EXAMPLES:
|
456
|
+
|
457
|
+
We showcase the similarities and differences between bounded integer
|
458
|
+
sequences and lists respectively tuples.
|
459
|
+
|
460
|
+
To distinguish from tuples or lists, we use pointed brackets for the
|
461
|
+
string representation of bounded integer sequences::
|
462
|
+
|
463
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
464
|
+
sage: S = BoundedIntegerSequence(21, [2, 7, 20]); S
|
465
|
+
<2, 7, 20>
|
466
|
+
|
467
|
+
Each bounded integer sequence has a bound that is a power of two, such
|
468
|
+
that all its item are less than this bound::
|
469
|
+
|
470
|
+
sage: S.bound()
|
471
|
+
32
|
472
|
+
sage: BoundedIntegerSequence(16, [2, 7, 20])
|
473
|
+
Traceback (most recent call last):
|
474
|
+
...
|
475
|
+
OverflowError: list item 20 larger than 15
|
476
|
+
|
477
|
+
Bounded integer sequences are iterable, and we see that we can recover the
|
478
|
+
originally given list::
|
479
|
+
|
480
|
+
sage: L = [randint(0,31) for i in range(5000)]
|
481
|
+
sage: S = BoundedIntegerSequence(32, L)
|
482
|
+
sage: list(L) == L
|
483
|
+
True
|
484
|
+
|
485
|
+
Getting items and slicing works in the same way as for lists::
|
486
|
+
|
487
|
+
sage: n = randint(0,4999)
|
488
|
+
sage: S[n] == L[n]
|
489
|
+
True
|
490
|
+
sage: m = randint(0,1000)
|
491
|
+
sage: n = randint(3000,4500)
|
492
|
+
sage: s = randint(1, 7)
|
493
|
+
sage: list(S[m:n:s]) == L[m:n:s]
|
494
|
+
True
|
495
|
+
sage: list(S[n:m:-s]) == L[n:m:-s]
|
496
|
+
True
|
497
|
+
|
498
|
+
The :meth:`index` method works different for bounded integer sequences and
|
499
|
+
tuples or lists. If one asks for the index of an item, the behaviour is
|
500
|
+
the same. But we can also ask for the index of a sub-sequence::
|
501
|
+
|
502
|
+
sage: L.index(L[200]) == S.index(L[200])
|
503
|
+
True
|
504
|
+
sage: S.index(S[100:2000]) # random
|
505
|
+
100
|
506
|
+
|
507
|
+
Similarly, containment tests work for both items and sub-sequences::
|
508
|
+
|
509
|
+
sage: S[200] in S
|
510
|
+
True
|
511
|
+
sage: S[200:400] in S
|
512
|
+
True
|
513
|
+
sage: S[200]+S.bound() in S
|
514
|
+
False
|
515
|
+
|
516
|
+
Bounded integer sequences are immutable, and thus copies are
|
517
|
+
identical. This is the same for tuples, but of course not for lists::
|
518
|
+
|
519
|
+
sage: T = tuple(S)
|
520
|
+
sage: copy(T) is T
|
521
|
+
True
|
522
|
+
sage: copy(S) is S
|
523
|
+
True
|
524
|
+
sage: copy(L) is L
|
525
|
+
False
|
526
|
+
|
527
|
+
Concatenation works in the same way for lists, tuples and bounded
|
528
|
+
integer sequences::
|
529
|
+
|
530
|
+
sage: M = [randint(0,31) for i in range(5000)]
|
531
|
+
sage: T = BoundedIntegerSequence(32, M)
|
532
|
+
sage: list(S+T)==L+M
|
533
|
+
True
|
534
|
+
sage: list(T+S)==M+L
|
535
|
+
True
|
536
|
+
sage: (T+S == S+T) == (M+L == L+M)
|
537
|
+
True
|
538
|
+
|
539
|
+
However, comparison works different for lists and bounded integer
|
540
|
+
sequences. Bounded integer sequences are first compared by bound, then by
|
541
|
+
length, and eventually by *reverse* lexicographical ordering::
|
542
|
+
|
543
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
544
|
+
sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20])
|
545
|
+
sage: S < T # compare by bound, not length
|
546
|
+
True
|
547
|
+
sage: T < S
|
548
|
+
False
|
549
|
+
sage: S.bound() < T.bound()
|
550
|
+
True
|
551
|
+
sage: len(S) > len(T)
|
552
|
+
True
|
553
|
+
|
554
|
+
::
|
555
|
+
|
556
|
+
sage: T = BoundedIntegerSequence(21, [0,0,0,0,0,0,0,0])
|
557
|
+
sage: S < T # compare by length, not lexicographically
|
558
|
+
True
|
559
|
+
sage: T < S
|
560
|
+
False
|
561
|
+
sage: list(T) < list(S)
|
562
|
+
True
|
563
|
+
sage: len(T) > len(S)
|
564
|
+
True
|
565
|
+
|
566
|
+
::
|
567
|
+
|
568
|
+
sage: T = BoundedIntegerSequence(21, [4,1,5,2,8,20,9])
|
569
|
+
sage: T > S # compare by reverse lexicographic ordering...
|
570
|
+
True
|
571
|
+
sage: S > T
|
572
|
+
False
|
573
|
+
sage: len(S) == len(T)
|
574
|
+
True
|
575
|
+
sage: list(S) > list(T) # direct lexicographic ordering is different
|
576
|
+
True
|
577
|
+
|
578
|
+
TESTS:
|
579
|
+
|
580
|
+
We test against various corner cases::
|
581
|
+
|
582
|
+
sage: BoundedIntegerSequence(16, [2, 7, -20])
|
583
|
+
Traceback (most recent call last):
|
584
|
+
...
|
585
|
+
OverflowError: can...t convert negative value to size_t
|
586
|
+
sage: BoundedIntegerSequence(1, [0, 0, 0])
|
587
|
+
<0, 0, 0>
|
588
|
+
sage: BoundedIntegerSequence(1, [0, 1, 0])
|
589
|
+
Traceback (most recent call last):
|
590
|
+
...
|
591
|
+
OverflowError: list item 1 larger than 0
|
592
|
+
sage: BoundedIntegerSequence(0, [0, 1, 0])
|
593
|
+
Traceback (most recent call last):
|
594
|
+
...
|
595
|
+
ValueError: positive bound expected
|
596
|
+
sage: BoundedIntegerSequence(2, [])
|
597
|
+
<>
|
598
|
+
sage: BoundedIntegerSequence(2, []) == BoundedIntegerSequence(4, []) # The bounds differ
|
599
|
+
False
|
600
|
+
sage: BoundedIntegerSequence(16, [2, 7, 4])[1:1]
|
601
|
+
<>
|
602
|
+
"""
|
603
|
+
def __cinit__(self, *args, **kwds):
|
604
|
+
"""
|
605
|
+
Allocate memory for underlying data.
|
606
|
+
|
607
|
+
INPUT:
|
608
|
+
|
609
|
+
- ``bound`` -- nonnegative integer
|
610
|
+
- ``data`` -- ignored
|
611
|
+
|
612
|
+
.. WARNING::
|
613
|
+
|
614
|
+
If ``bound=0`` then no allocation is done. Hence, this should
|
615
|
+
only be done internally, when calling :meth:`__new__` without :meth:`__init__`.
|
616
|
+
|
617
|
+
EXAMPLES::
|
618
|
+
|
619
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
620
|
+
sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest
|
621
|
+
<4, 1, 6, 2, 7, 20, 9>
|
622
|
+
"""
|
623
|
+
# In __init__, we'll raise an error if the bound is 0.
|
624
|
+
self.data.data.bits = NULL
|
625
|
+
|
626
|
+
def __dealloc__(self):
|
627
|
+
"""
|
628
|
+
Free the memory from underlying data.
|
629
|
+
|
630
|
+
EXAMPLES::
|
631
|
+
|
632
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
633
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
634
|
+
sage: del S # indirect doctest
|
635
|
+
"""
|
636
|
+
biseq_dealloc(self.data)
|
637
|
+
|
638
|
+
def __init__(self, bound, data):
|
639
|
+
"""
|
640
|
+
INPUT:
|
641
|
+
|
642
|
+
- ``bound`` -- positive integer; the given bound is replaced by
|
643
|
+
the next power of two that is greater than the given bound
|
644
|
+
|
645
|
+
- ``data`` -- list of nonnegative integers; all less than
|
646
|
+
``bound``
|
647
|
+
|
648
|
+
EXAMPLES::
|
649
|
+
|
650
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
651
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
652
|
+
sage: S = BoundedIntegerSequence(57, L) # indirect doctest
|
653
|
+
sage: list(S) == L
|
654
|
+
True
|
655
|
+
sage: S = BoundedIntegerSequence(11, [4,1,6,2,7,4,9]); S
|
656
|
+
<4, 1, 6, 2, 7, 4, 9>
|
657
|
+
sage: S.bound()
|
658
|
+
16
|
659
|
+
|
660
|
+
Non-positive bounds or bounds which are too large result in errors::
|
661
|
+
|
662
|
+
sage: BoundedIntegerSequence(-1, L)
|
663
|
+
Traceback (most recent call last):
|
664
|
+
...
|
665
|
+
ValueError: positive bound expected
|
666
|
+
sage: BoundedIntegerSequence(0, L)
|
667
|
+
Traceback (most recent call last):
|
668
|
+
...
|
669
|
+
ValueError: positive bound expected
|
670
|
+
sage: BoundedIntegerSequence(2^64+1, L)
|
671
|
+
Traceback (most recent call last):
|
672
|
+
...
|
673
|
+
OverflowError: ... int too large to convert...
|
674
|
+
|
675
|
+
We are testing the corner case of the maximal possible bound::
|
676
|
+
|
677
|
+
sage: S = BoundedIntegerSequence(2*(sys.maxsize+1), [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10])
|
678
|
+
sage: S
|
679
|
+
<8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10>
|
680
|
+
|
681
|
+
Items that are too large::
|
682
|
+
|
683
|
+
sage: BoundedIntegerSequence(100, [2^256])
|
684
|
+
Traceback (most recent call last):
|
685
|
+
...
|
686
|
+
OverflowError: ... int too large to convert...
|
687
|
+
sage: BoundedIntegerSequence(100, [100])
|
688
|
+
Traceback (most recent call last):
|
689
|
+
...
|
690
|
+
OverflowError: list item 100 larger than 99
|
691
|
+
|
692
|
+
Bounds that are too large::
|
693
|
+
|
694
|
+
sage: BoundedIntegerSequence(2^256, [200])
|
695
|
+
Traceback (most recent call last):
|
696
|
+
...
|
697
|
+
OverflowError: ... int too large to convert...
|
698
|
+
"""
|
699
|
+
if bound <= 0:
|
700
|
+
raise ValueError("positive bound expected")
|
701
|
+
biseq_init_list(self.data, data, bound-1)
|
702
|
+
|
703
|
+
def __copy__(self):
|
704
|
+
"""
|
705
|
+
:class:`BoundedIntegerSequence` is immutable, copying returns ``self``.
|
706
|
+
|
707
|
+
EXAMPLES::
|
708
|
+
|
709
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
710
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
711
|
+
sage: copy(S) is S
|
712
|
+
True
|
713
|
+
"""
|
714
|
+
return self
|
715
|
+
|
716
|
+
def __reduce__(self):
|
717
|
+
"""
|
718
|
+
Pickling of :class:`BoundedIntegerSequence`.
|
719
|
+
|
720
|
+
EXAMPLES::
|
721
|
+
|
722
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
723
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
724
|
+
sage: S = BoundedIntegerSequence(32, L)
|
725
|
+
sage: loads(dumps(S)) == S # indirect doctest
|
726
|
+
True
|
727
|
+
|
728
|
+
TESTS:
|
729
|
+
|
730
|
+
The discussion at :issue:`15820` explains why the following is a good test::
|
731
|
+
|
732
|
+
sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3])
|
733
|
+
sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0])
|
734
|
+
sage: loads(dumps(X+S))
|
735
|
+
<4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0>
|
736
|
+
sage: loads(dumps(X+S)) == X+S
|
737
|
+
True
|
738
|
+
sage: T = BoundedIntegerSequence(21, [0,4,0,1,0,6,0,2,0,7,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
|
739
|
+
sage: T[1::2]
|
740
|
+
<4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0>
|
741
|
+
sage: T[1::2] == X+S
|
742
|
+
True
|
743
|
+
sage: loads(dumps(X[1::2])) == X[1::2]
|
744
|
+
True
|
745
|
+
"""
|
746
|
+
return NewBISEQ, biseq_pickle(self.data)
|
747
|
+
|
748
|
+
def __len__(self):
|
749
|
+
"""
|
750
|
+
EXAMPLES::
|
751
|
+
|
752
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
753
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
754
|
+
sage: S = BoundedIntegerSequence(57, L) # indirect doctest
|
755
|
+
sage: len(S) == len(L)
|
756
|
+
True
|
757
|
+
"""
|
758
|
+
return self.data.length
|
759
|
+
|
760
|
+
def __bool__(self):
|
761
|
+
"""
|
762
|
+
A bounded integer sequence is nonzero if and only if its length is nonzero.
|
763
|
+
|
764
|
+
EXAMPLES::
|
765
|
+
|
766
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
767
|
+
sage: S = BoundedIntegerSequence(13, [0,0,0])
|
768
|
+
sage: bool(S)
|
769
|
+
True
|
770
|
+
sage: bool(S[1:1])
|
771
|
+
False
|
772
|
+
"""
|
773
|
+
return self.data.length!=0
|
774
|
+
|
775
|
+
def __repr__(self):
|
776
|
+
"""
|
777
|
+
String representation.
|
778
|
+
|
779
|
+
To distinguish it from Python tuples or lists, we use pointed brackets
|
780
|
+
as delimiters.
|
781
|
+
|
782
|
+
EXAMPLES::
|
783
|
+
|
784
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
785
|
+
sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9]) # indirect doctest
|
786
|
+
<4, 1, 6, 2, 7, 20, 9>
|
787
|
+
sage: BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])
|
788
|
+
<0, 0, 0, 0>
|
789
|
+
"""
|
790
|
+
return "<" + ", ".join(str(x) for x in self) + ">"
|
791
|
+
|
792
|
+
def bound(self):
|
793
|
+
"""
|
794
|
+
Return the bound of this bounded integer sequence.
|
795
|
+
|
796
|
+
All items of this sequence are nonnegative integers less than the
|
797
|
+
returned bound. The bound is a power of two.
|
798
|
+
|
799
|
+
EXAMPLES::
|
800
|
+
|
801
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
802
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
803
|
+
sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9])
|
804
|
+
sage: S.bound()
|
805
|
+
32
|
806
|
+
sage: T.bound()
|
807
|
+
64
|
808
|
+
"""
|
809
|
+
return smallInteger(1) << self.data.itembitsize
|
810
|
+
|
811
|
+
def __iter__(self):
|
812
|
+
"""
|
813
|
+
EXAMPLES::
|
814
|
+
|
815
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
816
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
817
|
+
sage: S = BoundedIntegerSequence(27, L)
|
818
|
+
sage: list(S) == L # indirect doctest
|
819
|
+
True
|
820
|
+
|
821
|
+
TESTS::
|
822
|
+
|
823
|
+
sage: list(BoundedIntegerSequence(1, []))
|
824
|
+
[]
|
825
|
+
|
826
|
+
The discussion at :issue:`15820` explains why this is a good test::
|
827
|
+
|
828
|
+
sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0])
|
829
|
+
sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3])
|
830
|
+
sage: list(X)
|
831
|
+
[4, 1, 6, 2, 7, 2, 3]
|
832
|
+
sage: list(X+S)
|
833
|
+
[4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0]
|
834
|
+
sage: list(BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0]))
|
835
|
+
[0, 0, 0, 0]
|
836
|
+
"""
|
837
|
+
cdef mp_size_t index
|
838
|
+
for index in range(self.data.length):
|
839
|
+
yield biseq_getitem_py(self.data, index)
|
840
|
+
|
841
|
+
def __getitem__(self, index):
|
842
|
+
"""
|
843
|
+
Get single items or slices.
|
844
|
+
|
845
|
+
EXAMPLES::
|
846
|
+
|
847
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
848
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
849
|
+
sage: S[2]
|
850
|
+
6
|
851
|
+
sage: S[1::2]
|
852
|
+
<1, 2, 20>
|
853
|
+
sage: S[-1::-2]
|
854
|
+
<9, 7, 6, 4>
|
855
|
+
|
856
|
+
TESTS::
|
857
|
+
|
858
|
+
sage: S = BoundedIntegerSequence(10^8, list(range(9)))
|
859
|
+
sage: S[-1]
|
860
|
+
8
|
861
|
+
sage: S[8]
|
862
|
+
8
|
863
|
+
sage: S[9]
|
864
|
+
Traceback (most recent call last):
|
865
|
+
...
|
866
|
+
IndexError: index out of range
|
867
|
+
sage: S[-10]
|
868
|
+
Traceback (most recent call last):
|
869
|
+
...
|
870
|
+
IndexError: index out of range
|
871
|
+
sage: S[2^63]
|
872
|
+
Traceback (most recent call last):
|
873
|
+
...
|
874
|
+
OverflowError: ... int too large to convert to ...
|
875
|
+
|
876
|
+
::
|
877
|
+
|
878
|
+
sage: S[-1::-2]
|
879
|
+
<8, 6, 4, 2, 0>
|
880
|
+
sage: S[1::2]
|
881
|
+
<1, 3, 5, 7>
|
882
|
+
|
883
|
+
::
|
884
|
+
|
885
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
886
|
+
sage: S = BoundedIntegerSequence(27, L)
|
887
|
+
sage: S[1234] == L[1234]
|
888
|
+
True
|
889
|
+
sage: list(S[100:2000:3]) == L[100:2000:3]
|
890
|
+
True
|
891
|
+
sage: list(S[3000:10:-7]) == L[3000:10:-7]
|
892
|
+
True
|
893
|
+
sage: S[:] == S
|
894
|
+
True
|
895
|
+
sage: S[:] is S
|
896
|
+
True
|
897
|
+
|
898
|
+
::
|
899
|
+
|
900
|
+
sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0])
|
901
|
+
sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3])
|
902
|
+
sage: (X+S)[6]
|
903
|
+
3
|
904
|
+
sage: (X+S)[10]
|
905
|
+
0
|
906
|
+
sage: (X+S)[12:]
|
907
|
+
<0, 0>
|
908
|
+
|
909
|
+
::
|
910
|
+
|
911
|
+
sage: S[2:2] == X[4:2]
|
912
|
+
True
|
913
|
+
|
914
|
+
::
|
915
|
+
|
916
|
+
sage: S = BoundedIntegerSequence(6, [3, 5, 3, 1, 5, 2, 2, 5, 3, 3, 4])
|
917
|
+
sage: S[10]
|
918
|
+
4
|
919
|
+
|
920
|
+
::
|
921
|
+
|
922
|
+
sage: B = BoundedIntegerSequence(27, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10])
|
923
|
+
sage: B[8:]
|
924
|
+
<17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10>
|
925
|
+
|
926
|
+
::
|
927
|
+
|
928
|
+
sage: B1 = BoundedIntegerSequence(8, [0,7])
|
929
|
+
sage: B2 = BoundedIntegerSequence(8, [2,1,4])
|
930
|
+
sage: B1[0:1]+B2
|
931
|
+
<0, 2, 1, 4>
|
932
|
+
"""
|
933
|
+
cdef BoundedIntegerSequence out
|
934
|
+
cdef Py_ssize_t start, stop, step, slicelength
|
935
|
+
if isinstance(index, slice):
|
936
|
+
PySlice_GetIndicesEx(index, self.data.length, &start, &stop, &step, &slicelength)
|
937
|
+
if start==0 and stop==self.data.length and step==1:
|
938
|
+
return self
|
939
|
+
out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None)
|
940
|
+
biseq_init_slice(out.data, self.data, start, stop, step)
|
941
|
+
return out
|
942
|
+
cdef Py_ssize_t ind
|
943
|
+
try:
|
944
|
+
ind = index
|
945
|
+
except TypeError:
|
946
|
+
raise TypeError("Sequence index must be integer or slice")
|
947
|
+
if ind < 0:
|
948
|
+
ind += self.data.length
|
949
|
+
if ind < 0 or ind >= self.data.length:
|
950
|
+
raise IndexError("index out of range")
|
951
|
+
return biseq_getitem_py(self.data, ind)
|
952
|
+
|
953
|
+
def __contains__(self, other):
|
954
|
+
"""
|
955
|
+
Tells whether this bounded integer sequence contains an item or a sub-sequence.
|
956
|
+
|
957
|
+
EXAMPLES::
|
958
|
+
|
959
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
960
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
961
|
+
sage: 6 in S
|
962
|
+
True
|
963
|
+
sage: BoundedIntegerSequence(21, [2, 7, 20]) in S
|
964
|
+
True
|
965
|
+
|
966
|
+
The bound of the sequences matters::
|
967
|
+
|
968
|
+
sage: BoundedIntegerSequence(51, [2, 7, 20]) in S
|
969
|
+
False
|
970
|
+
|
971
|
+
::
|
972
|
+
|
973
|
+
sage: 6+S.bound() in S
|
974
|
+
False
|
975
|
+
sage: S.index(6+S.bound())
|
976
|
+
Traceback (most recent call last):
|
977
|
+
...
|
978
|
+
ValueError: 38 is not in sequence
|
979
|
+
|
980
|
+
TESTS:
|
981
|
+
|
982
|
+
The discussion at :issue:`15820` explains why the following are good tests::
|
983
|
+
|
984
|
+
sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3])
|
985
|
+
sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0])
|
986
|
+
sage: loads(dumps(X+S))
|
987
|
+
<4, 1, 6, 2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0>
|
988
|
+
sage: loads(dumps(X+S)) == X+S
|
989
|
+
True
|
990
|
+
sage: T = BoundedIntegerSequence(21, [0,4,0,1,0,6,0,2,0,7,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
|
991
|
+
sage: T[3::2]==(X+S)[1:]
|
992
|
+
True
|
993
|
+
sage: T[3::2] in X+S
|
994
|
+
True
|
995
|
+
sage: T = BoundedIntegerSequence(21, [0,4,0,1,0,6,0,2,0,7,0,2,0,3,0,0,0,16,0,0,0,0,0,0,0,0,0,0])
|
996
|
+
sage: T[3::2] in (X+S)
|
997
|
+
False
|
998
|
+
|
999
|
+
::
|
1000
|
+
|
1001
|
+
sage: S1 = BoundedIntegerSequence(4, [1,3])
|
1002
|
+
sage: S2 = BoundedIntegerSequence(4, [0])
|
1003
|
+
sage: S2 in S1
|
1004
|
+
False
|
1005
|
+
|
1006
|
+
::
|
1007
|
+
|
1008
|
+
sage: B = BoundedIntegerSequence(27, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10])
|
1009
|
+
sage: B.index(B[8:])
|
1010
|
+
8
|
1011
|
+
|
1012
|
+
::
|
1013
|
+
|
1014
|
+
sage: -1 in B
|
1015
|
+
False
|
1016
|
+
"""
|
1017
|
+
if not isinstance(other, BoundedIntegerSequence):
|
1018
|
+
try:
|
1019
|
+
return biseq_index(self.data, other, 0) >= 0
|
1020
|
+
except OverflowError:
|
1021
|
+
return False
|
1022
|
+
cdef BoundedIntegerSequence right = other
|
1023
|
+
if self.data.itembitsize!=right.data.itembitsize:
|
1024
|
+
return False
|
1025
|
+
return biseq_contains(self.data, right.data, 0) >= 0
|
1026
|
+
|
1027
|
+
cpdef list list(self):
|
1028
|
+
"""
|
1029
|
+
Convert this bounded integer sequence to a list.
|
1030
|
+
|
1031
|
+
NOTE:
|
1032
|
+
|
1033
|
+
A conversion to a list is also possible by iterating over the
|
1034
|
+
sequence.
|
1035
|
+
|
1036
|
+
EXAMPLES::
|
1037
|
+
|
1038
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1039
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
1040
|
+
sage: S = BoundedIntegerSequence(32, L)
|
1041
|
+
sage: S.list() == list(S) == L
|
1042
|
+
True
|
1043
|
+
|
1044
|
+
The discussion at :issue:`15820` explains why the following is a good test::
|
1045
|
+
|
1046
|
+
sage: (BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])).list()
|
1047
|
+
[0, 0, 0, 0]
|
1048
|
+
"""
|
1049
|
+
cdef mp_size_t i
|
1050
|
+
return [biseq_getitem_py(self.data, i) for i in range(self.data.length)]
|
1051
|
+
|
1052
|
+
cpdef bint startswith(self, BoundedIntegerSequence other) noexcept:
|
1053
|
+
"""
|
1054
|
+
Tells whether ``self`` starts with a given bounded integer sequence
|
1055
|
+
|
1056
|
+
EXAMPLES::
|
1057
|
+
|
1058
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1059
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
1060
|
+
sage: S = BoundedIntegerSequence(27, L)
|
1061
|
+
sage: L0 = L[:1000]
|
1062
|
+
sage: T = BoundedIntegerSequence(27, L0)
|
1063
|
+
sage: S.startswith(T)
|
1064
|
+
True
|
1065
|
+
sage: L0[-1] = (L0[-1] + 1) % 27
|
1066
|
+
sage: T = BoundedIntegerSequence(27, L0)
|
1067
|
+
sage: S.startswith(T)
|
1068
|
+
False
|
1069
|
+
sage: L0[-1] = (L0[-1] - 1) % 27
|
1070
|
+
sage: L0[0] = (L0[0] + 1) % 27
|
1071
|
+
sage: T = BoundedIntegerSequence(27, L0)
|
1072
|
+
sage: S.startswith(T)
|
1073
|
+
False
|
1074
|
+
sage: L0[0] = (L0[0] - 1) % 27
|
1075
|
+
|
1076
|
+
The bounds of the sequences must be compatible, or :meth:`startswith`
|
1077
|
+
returns ``False``::
|
1078
|
+
|
1079
|
+
sage: T = BoundedIntegerSequence(51, L0)
|
1080
|
+
sage: S.startswith(T)
|
1081
|
+
False
|
1082
|
+
"""
|
1083
|
+
if self.data.itembitsize != other.data.itembitsize:
|
1084
|
+
return False
|
1085
|
+
return biseq_startswith(self.data, other.data)
|
1086
|
+
|
1087
|
+
def index(self, other):
|
1088
|
+
"""
|
1089
|
+
The index of a given item or sub-sequence of ``self``.
|
1090
|
+
|
1091
|
+
EXAMPLES::
|
1092
|
+
|
1093
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1094
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,6,20,9,0])
|
1095
|
+
sage: S.index(6)
|
1096
|
+
2
|
1097
|
+
sage: S.index(5)
|
1098
|
+
Traceback (most recent call last):
|
1099
|
+
...
|
1100
|
+
ValueError: 5 is not in sequence
|
1101
|
+
sage: S.index(BoundedIntegerSequence(21, [6, 2, 6]))
|
1102
|
+
2
|
1103
|
+
sage: S.index(BoundedIntegerSequence(21, [6, 2, 7]))
|
1104
|
+
Traceback (most recent call last):
|
1105
|
+
...
|
1106
|
+
ValueError: not a sub-sequence
|
1107
|
+
|
1108
|
+
The bound of (sub-)sequences matters::
|
1109
|
+
|
1110
|
+
sage: S.index(BoundedIntegerSequence(51, [6, 2, 6]))
|
1111
|
+
Traceback (most recent call last):
|
1112
|
+
...
|
1113
|
+
ValueError: not a sub-sequence
|
1114
|
+
sage: S.index(0)
|
1115
|
+
7
|
1116
|
+
sage: S.index(S.bound())
|
1117
|
+
Traceback (most recent call last):
|
1118
|
+
...
|
1119
|
+
ValueError: 32 is not in sequence
|
1120
|
+
|
1121
|
+
TESTS::
|
1122
|
+
|
1123
|
+
sage: S = BoundedIntegerSequence(10^9, [2, 2, 2, 1, 2, 4, 3, 3, 3, 2, 2, 0])
|
1124
|
+
sage: S[11]
|
1125
|
+
0
|
1126
|
+
sage: S.index(0)
|
1127
|
+
11
|
1128
|
+
|
1129
|
+
::
|
1130
|
+
|
1131
|
+
sage: S.index(-3)
|
1132
|
+
Traceback (most recent call last):
|
1133
|
+
...
|
1134
|
+
ValueError: -3 is not in sequence
|
1135
|
+
sage: S.index(2^100)
|
1136
|
+
Traceback (most recent call last):
|
1137
|
+
...
|
1138
|
+
ValueError: 1267650600228229401496703205376 is not in sequence
|
1139
|
+
sage: S.index("hello")
|
1140
|
+
Traceback (most recent call last):
|
1141
|
+
...
|
1142
|
+
TypeError: an integer is required
|
1143
|
+
"""
|
1144
|
+
cdef mp_size_t out
|
1145
|
+
if not isinstance(other, BoundedIntegerSequence):
|
1146
|
+
try:
|
1147
|
+
out = biseq_index(self.data, other, 0)
|
1148
|
+
except OverflowError:
|
1149
|
+
out = -1
|
1150
|
+
if out >= 0:
|
1151
|
+
return out
|
1152
|
+
raise ValueError("{!r} is not in sequence".format(other))
|
1153
|
+
|
1154
|
+
cdef BoundedIntegerSequence right = other
|
1155
|
+
if self.data.itembitsize != right.data.itembitsize:
|
1156
|
+
out = -1
|
1157
|
+
else:
|
1158
|
+
out = biseq_contains(self.data, right.data, 0)
|
1159
|
+
if out >= 0:
|
1160
|
+
return out
|
1161
|
+
raise ValueError("not a sub-sequence")
|
1162
|
+
|
1163
|
+
def __add__(self, other):
|
1164
|
+
"""
|
1165
|
+
Concatenation of bounded integer sequences.
|
1166
|
+
|
1167
|
+
NOTE:
|
1168
|
+
|
1169
|
+
There is no coercion happening, as bounded integer sequences are not
|
1170
|
+
considered to be elements of an object.
|
1171
|
+
|
1172
|
+
EXAMPLES::
|
1173
|
+
|
1174
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1175
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
1176
|
+
sage: T = BoundedIntegerSequence(21, [4,1,6,2,8,15])
|
1177
|
+
sage: S+T
|
1178
|
+
<4, 1, 6, 2, 7, 20, 9, 4, 1, 6, 2, 8, 15>
|
1179
|
+
sage: T+S
|
1180
|
+
<4, 1, 6, 2, 8, 15, 4, 1, 6, 2, 7, 20, 9>
|
1181
|
+
sage: S in S+T
|
1182
|
+
True
|
1183
|
+
sage: T in S+T
|
1184
|
+
True
|
1185
|
+
sage: BoundedIntegerSequence(21, [4,1,6,2,7,20,9,4]) in S+T
|
1186
|
+
True
|
1187
|
+
sage: T+list(S)
|
1188
|
+
Traceback (most recent call last):
|
1189
|
+
...
|
1190
|
+
TypeError: Cannot convert list to sage.data_structures.bounded_integer_sequences.BoundedIntegerSequence
|
1191
|
+
sage: T+None
|
1192
|
+
Traceback (most recent call last):
|
1193
|
+
...
|
1194
|
+
TypeError: cannot concatenate bounded integer sequence and None
|
1195
|
+
|
1196
|
+
TESTS:
|
1197
|
+
|
1198
|
+
The discussion at :issue:`15820` explains why the following are good tests::
|
1199
|
+
|
1200
|
+
sage: BoundedIntegerSequence(21, [0,0]) + BoundedIntegerSequence(21, [0,0])
|
1201
|
+
<0, 0, 0, 0>
|
1202
|
+
sage: B1 = BoundedIntegerSequence(2^30, [10^9+1, 10^9+2])
|
1203
|
+
sage: B2 = BoundedIntegerSequence(2^30, [10^9+3, 10^9+4])
|
1204
|
+
sage: B1 + B2
|
1205
|
+
<1000000001, 1000000002, 1000000003, 1000000004>
|
1206
|
+
"""
|
1207
|
+
cdef BoundedIntegerSequence myself, right, out
|
1208
|
+
if other is None or self is None:
|
1209
|
+
raise TypeError('cannot concatenate bounded integer sequence and None')
|
1210
|
+
myself = self # may result in a type error
|
1211
|
+
right = other # --"--
|
1212
|
+
if right.data.itembitsize != myself.data.itembitsize:
|
1213
|
+
raise ValueError("can only concatenate bounded integer sequences of compatible bounds")
|
1214
|
+
out = BoundedIntegerSequence.__new__(BoundedIntegerSequence, 0, None)
|
1215
|
+
biseq_init_concat(out.data, myself.data, right.data)
|
1216
|
+
return out
|
1217
|
+
|
1218
|
+
cpdef BoundedIntegerSequence maximal_overlap(self, BoundedIntegerSequence other):
|
1219
|
+
"""
|
1220
|
+
Return ``self``'s maximal trailing sub-sequence that ``other`` starts with.
|
1221
|
+
|
1222
|
+
Return ``None`` if there is no overlap.
|
1223
|
+
|
1224
|
+
EXAMPLES::
|
1225
|
+
|
1226
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1227
|
+
sage: X = BoundedIntegerSequence(21, [4,1,6,2,7,2,3])
|
1228
|
+
sage: S = BoundedIntegerSequence(21, [0,0,0,0,0,0,0])
|
1229
|
+
sage: T = BoundedIntegerSequence(21, [2,7,2,3,0,0,0,0,0,0,0,1])
|
1230
|
+
sage: (X+S).maximal_overlap(T)
|
1231
|
+
<2, 7, 2, 3, 0, 0, 0, 0, 0, 0, 0>
|
1232
|
+
sage: print((X+S).maximal_overlap(BoundedIntegerSequence(21, [2,7,2,3,0,0,0,0,0,1])))
|
1233
|
+
None
|
1234
|
+
sage: (X+S).maximal_overlap(BoundedIntegerSequence(21, [0,0]))
|
1235
|
+
<0, 0>
|
1236
|
+
sage: B1 = BoundedIntegerSequence(4,[1,2,3,2,3,2,3])
|
1237
|
+
sage: B2 = BoundedIntegerSequence(4,[2,3,2,3,2,3,1])
|
1238
|
+
sage: B1.maximal_overlap(B2)
|
1239
|
+
<2, 3, 2, 3, 2, 3>
|
1240
|
+
"""
|
1241
|
+
cdef mp_size_t i = biseq_startswith_tail(other.data, self.data, 0)
|
1242
|
+
if i==-1:
|
1243
|
+
return None
|
1244
|
+
return self[i:]
|
1245
|
+
|
1246
|
+
def __richcmp__(self, other, op):
|
1247
|
+
"""
|
1248
|
+
Comparison of bounded integer sequences.
|
1249
|
+
|
1250
|
+
We compare, in this order:
|
1251
|
+
|
1252
|
+
- The bound of ``self`` and ``other``
|
1253
|
+
|
1254
|
+
- The length of ``self`` and ``other``
|
1255
|
+
|
1256
|
+
- Reverse lexicographical ordering, i.e., the sequences' items
|
1257
|
+
are compared starting with the last item.
|
1258
|
+
|
1259
|
+
EXAMPLES:
|
1260
|
+
|
1261
|
+
Comparison by bound::
|
1262
|
+
|
1263
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1264
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
1265
|
+
sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9])
|
1266
|
+
sage: S < T
|
1267
|
+
True
|
1268
|
+
sage: T < S
|
1269
|
+
False
|
1270
|
+
sage: list(T) == list(S)
|
1271
|
+
True
|
1272
|
+
|
1273
|
+
Comparison by length::
|
1274
|
+
|
1275
|
+
sage: T = BoundedIntegerSequence(21, [0,0,0,0,0,0,0,0])
|
1276
|
+
sage: S < T
|
1277
|
+
True
|
1278
|
+
sage: T < S
|
1279
|
+
False
|
1280
|
+
sage: list(T) < list(S)
|
1281
|
+
True
|
1282
|
+
sage: len(T) > len(S)
|
1283
|
+
True
|
1284
|
+
|
1285
|
+
Comparison by *reverse* lexicographical ordering::
|
1286
|
+
|
1287
|
+
sage: T = BoundedIntegerSequence(21, [4,1,5,2,8,20,9])
|
1288
|
+
sage: T > S
|
1289
|
+
True
|
1290
|
+
sage: S > T
|
1291
|
+
False
|
1292
|
+
sage: list(S)> list(T)
|
1293
|
+
True
|
1294
|
+
"""
|
1295
|
+
cdef BoundedIntegerSequence right
|
1296
|
+
cdef BoundedIntegerSequence left
|
1297
|
+
if other is None or self is None:
|
1298
|
+
return NotImplemented
|
1299
|
+
try:
|
1300
|
+
right = other
|
1301
|
+
left = self
|
1302
|
+
except TypeError:
|
1303
|
+
return NotImplemented
|
1304
|
+
return biseq_richcmp(left.data, right.data, op)
|
1305
|
+
|
1306
|
+
def __hash__(self):
|
1307
|
+
"""
|
1308
|
+
The hash takes into account the content and the bound of the sequence.
|
1309
|
+
|
1310
|
+
EXAMPLES::
|
1311
|
+
|
1312
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1313
|
+
sage: S = BoundedIntegerSequence(21, [4,1,6,2,7,20,9])
|
1314
|
+
sage: T = BoundedIntegerSequence(51, [4,1,6,2,7,20,9])
|
1315
|
+
sage: S == T
|
1316
|
+
False
|
1317
|
+
sage: list(S) == list(T)
|
1318
|
+
True
|
1319
|
+
sage: S.bound() == T.bound()
|
1320
|
+
False
|
1321
|
+
sage: hash(S) == hash(T)
|
1322
|
+
False
|
1323
|
+
sage: T = BoundedIntegerSequence(31, [4,1,6,2,7,20,9])
|
1324
|
+
sage: T.bound() == S.bound()
|
1325
|
+
True
|
1326
|
+
sage: hash(S) == hash(T)
|
1327
|
+
True
|
1328
|
+
"""
|
1329
|
+
cdef Py_hash_t h = biseq_hash(self.data)
|
1330
|
+
if h == -1:
|
1331
|
+
return 0
|
1332
|
+
return h
|
1333
|
+
|
1334
|
+
cpdef BoundedIntegerSequence NewBISEQ(tuple bitset_data, mp_bitcnt_t itembitsize, mp_size_t length):
|
1335
|
+
"""
|
1336
|
+
Helper function for unpickling of :class:`BoundedIntegerSequence`.
|
1337
|
+
|
1338
|
+
EXAMPLES::
|
1339
|
+
|
1340
|
+
sage: from sage.data_structures.bounded_integer_sequences import BoundedIntegerSequence
|
1341
|
+
sage: L = [randint(0,26) for i in range(5000)]
|
1342
|
+
sage: S = BoundedIntegerSequence(32, L)
|
1343
|
+
sage: loads(dumps(S)) == S # indirect doctest
|
1344
|
+
True
|
1345
|
+
|
1346
|
+
TESTS:
|
1347
|
+
|
1348
|
+
We test a corner case::
|
1349
|
+
|
1350
|
+
sage: S = BoundedIntegerSequence(8,[])
|
1351
|
+
sage: S
|
1352
|
+
<>
|
1353
|
+
sage: loads(dumps(S)) == S
|
1354
|
+
True
|
1355
|
+
|
1356
|
+
And another one::
|
1357
|
+
|
1358
|
+
sage: S = BoundedIntegerSequence(2*sys.maxsize, [8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10])
|
1359
|
+
sage: loads(dumps(S))
|
1360
|
+
<8, 8, 26, 18, 18, 8, 22, 4, 17, 22, 22, 7, 12, 4, 1, 7, 21, 7, 10, 10>
|
1361
|
+
"""
|
1362
|
+
cdef BoundedIntegerSequence out = BoundedIntegerSequence.__new__(BoundedIntegerSequence)
|
1363
|
+
biseq_unpickle(out.data, bitset_data, itembitsize, length)
|
1364
|
+
return out
|
1365
|
+
|
1366
|
+
|
1367
|
+
def _biseq_stresstest():
|
1368
|
+
"""
|
1369
|
+
This function creates many bounded integer sequences and manipulates them
|
1370
|
+
in various ways, in order to try to detect random memory corruptions.
|
1371
|
+
|
1372
|
+
This runs forever and must be interrupted (this means that
|
1373
|
+
interrupting is also checked).
|
1374
|
+
|
1375
|
+
TESTS::
|
1376
|
+
|
1377
|
+
sage: from sage.data_structures.bounded_integer_sequences import _biseq_stresstest
|
1378
|
+
sage: from sage.doctest.util import ensure_interruptible_after
|
1379
|
+
sage: with ensure_interruptible_after(1): _biseq_stresstest() # long time
|
1380
|
+
"""
|
1381
|
+
cdef int branch
|
1382
|
+
cdef Py_ssize_t x, y, z
|
1383
|
+
from sage.misc.prandom import randint
|
1384
|
+
cdef list L = [BoundedIntegerSequence(6, [randint(0, 5) for z in range(randint(4, 10))]) for y in range(100)]
|
1385
|
+
cdef BoundedIntegerSequence S, T
|
1386
|
+
while True:
|
1387
|
+
branch = randint(0, 4)
|
1388
|
+
if branch == 0:
|
1389
|
+
L[randint(0, 99)] = L[randint(0, 99)] + L[randint(0, 99)]
|
1390
|
+
elif branch == 1:
|
1391
|
+
x = randint(0, 99)
|
1392
|
+
if len(L[x]):
|
1393
|
+
y = randint(0, len(L[x]) - 1)
|
1394
|
+
z = randint(y, len(L[x]) - 1)
|
1395
|
+
L[randint(0, 99)] = L[x][y:z]
|
1396
|
+
else:
|
1397
|
+
L[x] = BoundedIntegerSequence(6, [randint(0, 5) for z in range(randint(4, 10))])
|
1398
|
+
elif branch == 2:
|
1399
|
+
t = list(L[randint(0, 99)])
|
1400
|
+
t = repr(L[randint(0, 99)])
|
1401
|
+
t = L[randint(0, 99)].list()
|
1402
|
+
elif branch == 3:
|
1403
|
+
x = randint(0, 99)
|
1404
|
+
if len(L[x]):
|
1405
|
+
y = randint(0, len(L[x])-1)
|
1406
|
+
t = L[x][y]
|
1407
|
+
try:
|
1408
|
+
t = L[x].index(t)
|
1409
|
+
except ValueError:
|
1410
|
+
raise ValueError("{} should be in {} (bound {}) at position {}".format(t, L[x], L[x].bound(), y))
|
1411
|
+
else:
|
1412
|
+
L[x] = BoundedIntegerSequence(6, [randint(0, 5) for z in range(randint(4, 10))])
|
1413
|
+
elif branch == 4:
|
1414
|
+
S = L[randint(0, 99)]
|
1415
|
+
T = L[randint(0, 99)]
|
1416
|
+
biseq_startswith(S.data, T.data)
|
1417
|
+
biseq_contains(S.data, T.data, 0)
|
1418
|
+
biseq_startswith_tail(S.data, T.data, 0)
|