passagemath-flint 10.6.1rc10__cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
- passagemath_flint-10.6.1rc10.dist-info/RECORD +361 -0
- passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
- passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
- passagemath_flint.libs/libflint-aecb9cc5.so.21.0.0 +0 -0
- passagemath_flint.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
- passagemath_flint.libs/libgfortran-8f1e9814.so.5.0.0 +0 -0
- passagemath_flint.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_flint.libs/libgsl-cda90e79.so.28.0.0 +0 -0
- passagemath_flint.libs/libmpfi-e3c25853.so.0.0.0 +0 -0
- passagemath_flint.libs/libmpfr-82690d50.so.6.2.1 +0 -0
- passagemath_flint.libs/libntl-74e7d9a3.so.44.0.1 +0 -0
- passagemath_flint.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_flint.libs/libquadmath-828275a7.so.0.0.0 +0 -0
- sage/all__sagemath_flint.py +29 -0
- sage/combinat/all__sagemath_flint.py +1 -0
- sage/combinat/posets/all__sagemath_flint.py +1 -0
- sage/combinat/posets/hasse_cython_flint.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython_flint.pyx +194 -0
- sage/data_structures/all__sagemath_flint.py +1 -0
- sage/data_structures/bounded_integer_sequences.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/data_structures/bounded_integer_sequences.pxd +62 -0
- sage/data_structures/bounded_integer_sequences.pyx +1418 -0
- sage/graphs/all__sagemath_flint.py +1 -0
- sage/graphs/chrompoly.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/graphs/chrompoly.pyx +555 -0
- sage/graphs/matchpoly.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/graphs/matchpoly.pyx +412 -0
- sage/libs/all__sagemath_flint.py +17 -0
- sage/libs/arb/__init__.py +1 -0
- sage/libs/arb/acb.pxd +154 -0
- sage/libs/arb/acb_calc.pxd +9 -0
- sage/libs/arb/acb_elliptic.pxd +25 -0
- sage/libs/arb/acb_hypgeom.pxd +74 -0
- sage/libs/arb/acb_mat.pxd +62 -0
- sage/libs/arb/acb_modular.pxd +17 -0
- sage/libs/arb/acb_poly.pxd +216 -0
- sage/libs/arb/arb.pxd +240 -0
- sage/libs/arb/arb_fmpz_poly.pxd +21 -0
- sage/libs/arb/arb_hypgeom.pxd +83 -0
- sage/libs/arb/arb_wrap.h +34 -0
- sage/libs/arb/arf.pxd +131 -0
- sage/libs/arb/arith.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/arb/arith.pyx +87 -0
- sage/libs/arb/bernoulli.pxd +6 -0
- sage/libs/arb/mag.pxd +77 -0
- sage/libs/arb/types.pxd +37 -0
- sage/libs/flint/__init__.py +1 -0
- sage/libs/flint/acb.pxd +270 -0
- sage/libs/flint/acb_calc.pxd +22 -0
- sage/libs/flint/acb_dft.pxd +51 -0
- sage/libs/flint/acb_dirichlet.pxd +112 -0
- sage/libs/flint/acb_elliptic.pxd +42 -0
- sage/libs/flint/acb_hypgeom.pxd +169 -0
- sage/libs/flint/acb_macros.pxd +9 -0
- sage/libs/flint/acb_mat.pxd +136 -0
- sage/libs/flint/acb_mat_macros.pxd +10 -0
- sage/libs/flint/acb_modular.pxd +62 -0
- sage/libs/flint/acb_poly.pxd +251 -0
- sage/libs/flint/acb_poly_macros.pxd +8 -0
- sage/libs/flint/acb_theta.pxd +124 -0
- sage/libs/flint/acf.pxd +32 -0
- sage/libs/flint/aprcl.pxd +84 -0
- sage/libs/flint/arb.pxd +382 -0
- sage/libs/flint/arb_calc.pxd +31 -0
- sage/libs/flint/arb_fmpz_poly.pxd +34 -0
- sage/libs/flint/arb_fpwrap.pxd +215 -0
- sage/libs/flint/arb_hypgeom.pxd +147 -0
- sage/libs/flint/arb_macros.pxd +9 -0
- sage/libs/flint/arb_mat.pxd +140 -0
- sage/libs/flint/arb_mat_macros.pxd +10 -0
- sage/libs/flint/arb_poly.pxd +237 -0
- sage/libs/flint/arf.pxd +167 -0
- sage/libs/flint/arith.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/arith.pxd +76 -0
- sage/libs/flint/arith.pyx +77 -0
- sage/libs/flint/arith_sage.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/arith_sage.pyx +308 -0
- sage/libs/flint/bernoulli.pxd +28 -0
- sage/libs/flint/bool_mat.pxd +52 -0
- sage/libs/flint/ca.pxd +203 -0
- sage/libs/flint/ca_ext.pxd +34 -0
- sage/libs/flint/ca_field.pxd +32 -0
- sage/libs/flint/ca_mat.pxd +117 -0
- sage/libs/flint/ca_poly.pxd +104 -0
- sage/libs/flint/ca_vec.pxd +46 -0
- sage/libs/flint/calcium.pxd +27 -0
- sage/libs/flint/d_mat.pxd +39 -0
- sage/libs/flint/d_vec.pxd +32 -0
- sage/libs/flint/dirichlet.pxd +57 -0
- sage/libs/flint/dlog.pxd +53 -0
- sage/libs/flint/double_extras.pxd +24 -0
- sage/libs/flint/double_interval.pxd +36 -0
- sage/libs/flint/fexpr.pxd +104 -0
- sage/libs/flint/fexpr_builtin.pxd +20 -0
- sage/libs/flint/fft.pxd +66 -0
- sage/libs/flint/flint.pxd +36 -0
- sage/libs/flint/flint_ntl_wrap.h +35 -0
- sage/libs/flint/flint_sage.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/flint_sage.pyx +163 -0
- sage/libs/flint/flint_wrap.h +190 -0
- sage/libs/flint/fmpq.pxd +137 -0
- sage/libs/flint/fmpq_mat.pxd +105 -0
- sage/libs/flint/fmpq_mat_macros.pxd +10 -0
- sage/libs/flint/fmpq_mpoly.pxd +165 -0
- sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
- sage/libs/flint/fmpq_poly.pxd +241 -0
- sage/libs/flint/fmpq_poly_macros.pxd +9 -0
- sage/libs/flint/fmpq_poly_sage.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpq_poly_sage.pxd +31 -0
- sage/libs/flint/fmpq_poly_sage.pyx +48 -0
- sage/libs/flint/fmpq_vec.pxd +27 -0
- sage/libs/flint/fmpz.pxd +256 -0
- sage/libs/flint/fmpz_extras.pxd +32 -0
- sage/libs/flint/fmpz_factor.pxd +42 -0
- sage/libs/flint/fmpz_factor_sage.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_factor_sage.pxd +4 -0
- sage/libs/flint/fmpz_factor_sage.pyx +29 -0
- sage/libs/flint/fmpz_lll.pxd +49 -0
- sage/libs/flint/fmpz_macros.pxd +8 -0
- sage/libs/flint/fmpz_mat.pxd +184 -0
- sage/libs/flint/fmpz_mat_macros.pxd +10 -0
- sage/libs/flint/fmpz_mod.pxd +46 -0
- sage/libs/flint/fmpz_mod_mat.pxd +71 -0
- sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
- sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fmpz_mod_poly.pxd +249 -0
- sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
- sage/libs/flint/fmpz_mod_vec.pxd +27 -0
- sage/libs/flint/fmpz_mpoly.pxd +224 -0
- sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
- sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
- sage/libs/flint/fmpz_poly.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly.pxd +407 -0
- sage/libs/flint/fmpz_poly.pyx +19 -0
- sage/libs/flint/fmpz_poly_factor.pxd +33 -0
- sage/libs/flint/fmpz_poly_macros.pxd +8 -0
- sage/libs/flint/fmpz_poly_mat.pxd +71 -0
- sage/libs/flint/fmpz_poly_q.pxd +55 -0
- sage/libs/flint/fmpz_poly_sage.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/fmpz_poly_sage.pxd +20 -0
- sage/libs/flint/fmpz_poly_sage.pyx +500 -0
- sage/libs/flint/fmpz_vec.pxd +80 -0
- sage/libs/flint/fmpzi.pxd +52 -0
- sage/libs/flint/fq.pxd +97 -0
- sage/libs/flint/fq_default.pxd +84 -0
- sage/libs/flint/fq_default_mat.pxd +70 -0
- sage/libs/flint/fq_default_poly.pxd +97 -0
- sage/libs/flint/fq_default_poly_factor.pxd +39 -0
- sage/libs/flint/fq_embed.pxd +28 -0
- sage/libs/flint/fq_mat.pxd +83 -0
- sage/libs/flint/fq_nmod.pxd +95 -0
- sage/libs/flint/fq_nmod_embed.pxd +28 -0
- sage/libs/flint/fq_nmod_mat.pxd +83 -0
- sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
- sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/fq_nmod_poly.pxd +202 -0
- sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
- sage/libs/flint/fq_nmod_vec.pxd +33 -0
- sage/libs/flint/fq_poly.pxd +204 -0
- sage/libs/flint/fq_poly_factor.pxd +47 -0
- sage/libs/flint/fq_vec.pxd +33 -0
- sage/libs/flint/fq_zech.pxd +99 -0
- sage/libs/flint/fq_zech_embed.pxd +28 -0
- sage/libs/flint/fq_zech_mat.pxd +78 -0
- sage/libs/flint/fq_zech_poly.pxd +198 -0
- sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
- sage/libs/flint/fq_zech_vec.pxd +33 -0
- sage/libs/flint/gr.pxd +174 -0
- sage/libs/flint/gr_generic.pxd +215 -0
- sage/libs/flint/gr_mat.pxd +161 -0
- sage/libs/flint/gr_mpoly.pxd +68 -0
- sage/libs/flint/gr_poly.pxd +276 -0
- sage/libs/flint/gr_special.pxd +237 -0
- sage/libs/flint/gr_vec.pxd +120 -0
- sage/libs/flint/hypgeom.pxd +24 -0
- sage/libs/flint/long_extras.pxd +23 -0
- sage/libs/flint/mag.pxd +131 -0
- sage/libs/flint/mag_macros.pxd +8 -0
- sage/libs/flint/mpf_mat.pxd +36 -0
- sage/libs/flint/mpf_vec.pxd +34 -0
- sage/libs/flint/mpfr_mat.pxd +27 -0
- sage/libs/flint/mpfr_vec.pxd +25 -0
- sage/libs/flint/mpn_extras.pxd +41 -0
- sage/libs/flint/mpoly.pxd +72 -0
- sage/libs/flint/nf.pxd +19 -0
- sage/libs/flint/nf_elem.pxd +74 -0
- sage/libs/flint/nmod.pxd +35 -0
- sage/libs/flint/nmod_mat.pxd +104 -0
- sage/libs/flint/nmod_mpoly.pxd +144 -0
- sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
- sage/libs/flint/nmod_poly.pxd +339 -0
- sage/libs/flint/nmod_poly_factor.pxd +44 -0
- sage/libs/flint/nmod_poly_linkage.pxi +710 -0
- sage/libs/flint/nmod_poly_mat.pxd +76 -0
- sage/libs/flint/nmod_vec.pxd +40 -0
- sage/libs/flint/ntl_interface.pxd +17 -0
- sage/libs/flint/padic.pxd +93 -0
- sage/libs/flint/padic_mat.pxd +64 -0
- sage/libs/flint/padic_poly.pxd +88 -0
- sage/libs/flint/partitions.pxd +23 -0
- sage/libs/flint/perm.pxd +26 -0
- sage/libs/flint/profiler.pxd +24 -0
- sage/libs/flint/qadic.pxd +77 -0
- sage/libs/flint/qfb.pxd +44 -0
- sage/libs/flint/qqbar.pxd +172 -0
- sage/libs/flint/qsieve.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve.pxd +41 -0
- sage/libs/flint/qsieve.pyx +21 -0
- sage/libs/flint/qsieve_sage.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/qsieve_sage.pyx +67 -0
- sage/libs/flint/thread_pool.pxd +25 -0
- sage/libs/flint/types.pxd +2076 -0
- sage/libs/flint/ulong_extras.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras.pxd +141 -0
- sage/libs/flint/ulong_extras.pyx +21 -0
- sage/libs/flint/ulong_extras_sage.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/libs/flint/ulong_extras_sage.pyx +21 -0
- sage/matrix/all__sagemath_flint.py +1 -0
- sage/matrix/change_ring.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/change_ring.pyx +43 -0
- sage/matrix/matrix_complex_ball_dense.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_complex_ball_dense.pxd +14 -0
- sage/matrix/matrix_complex_ball_dense.pyx +973 -0
- sage/matrix/matrix_cyclo_dense.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_cyclo_dense.pxd +16 -0
- sage/matrix/matrix_cyclo_dense.pyx +1761 -0
- sage/matrix/matrix_integer_dense.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_dense.pxd +32 -0
- sage/matrix/matrix_integer_dense.pyx +5801 -0
- sage/matrix/matrix_integer_dense_hnf.py +1294 -0
- sage/matrix/matrix_integer_dense_saturation.py +346 -0
- sage/matrix/matrix_integer_sparse.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_sparse.pxd +9 -0
- sage/matrix/matrix_integer_sparse.pyx +1090 -0
- sage/matrix/matrix_rational_dense.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_dense.pxd +23 -0
- sage/matrix/matrix_rational_dense.pyx +2995 -0
- sage/matrix/matrix_rational_sparse.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_sparse.pxd +11 -0
- sage/matrix/matrix_rational_sparse.pyx +789 -0
- sage/matrix/misc_flint.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/matrix/misc_flint.pyx +109 -0
- sage/modular/all__sagemath_flint.py +1 -0
- sage/modular/modform/all__sagemath_flint.py +1 -0
- sage/modular/modform/eis_series_cython.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/modular/modform/eis_series_cython.pyx +226 -0
- sage/modular/modsym/all__sagemath_flint.py +1 -0
- sage/modular/modsym/apply.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/modular/modsym/apply.pxd +6 -0
- sage/modular/modsym/apply.pyx +113 -0
- sage/modular/modsym/heilbronn.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/modular/modsym/heilbronn.pyx +966 -0
- sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
- sage/modular/pollack_stevens/dist.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/modular/pollack_stevens/dist.pxd +38 -0
- sage/modular/pollack_stevens/dist.pyx +1439 -0
- sage/quivers/algebra.py +691 -0
- sage/quivers/algebra_elements.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/quivers/algebra_elements.pxd +97 -0
- sage/quivers/algebra_elements.pxi +1324 -0
- sage/quivers/algebra_elements.pyx +1424 -0
- sage/quivers/all.py +1 -0
- sage/quivers/ar_quiver.py +917 -0
- sage/quivers/homspace.py +640 -0
- sage/quivers/morphism.py +1282 -0
- sage/quivers/path_semigroup.py +1155 -0
- sage/quivers/paths.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/quivers/paths.pxd +13 -0
- sage/quivers/paths.pyx +809 -0
- sage/quivers/representation.py +2975 -0
- sage/rings/all__sagemath_flint.py +37 -0
- sage/rings/cif.py +4 -0
- sage/rings/complex_arb.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_arb.pxd +29 -0
- sage/rings/complex_arb.pyx +5176 -0
- sage/rings/complex_interval.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_interval.pxd +30 -0
- sage/rings/complex_interval.pyx +2475 -0
- sage/rings/complex_interval_field.py +711 -0
- sage/rings/convert/all.py +1 -0
- sage/rings/convert/mpfi.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/convert/mpfi.pxd +6 -0
- sage/rings/convert/mpfi.pyx +576 -0
- sage/rings/factorint_flint.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/factorint_flint.pyx +99 -0
- sage/rings/fraction_field_FpT.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/fraction_field_FpT.pxd +28 -0
- sage/rings/fraction_field_FpT.pyx +2043 -0
- sage/rings/imaginary_unit.py +5 -0
- sage/rings/monomials.py +73 -0
- sage/rings/number_field/S_unit_solver.py +2870 -0
- sage/rings/number_field/all__sagemath_flint.py +7 -0
- sage/rings/number_field/bdd_height.py +664 -0
- sage/rings/number_field/class_group.py +762 -0
- sage/rings/number_field/galois_group.py +1307 -0
- sage/rings/number_field/homset.py +612 -0
- sage/rings/number_field/maps.py +687 -0
- sage/rings/number_field/morphism.py +272 -0
- sage/rings/number_field/number_field.py +12820 -0
- sage/rings/number_field/number_field_element.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element.pxd +59 -0
- sage/rings/number_field/number_field_element.pyx +5735 -0
- sage/rings/number_field/number_field_element_quadratic.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
- sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
- sage/rings/number_field/number_field_ideal_rel.py +925 -0
- sage/rings/number_field/number_field_morphisms.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/number_field/number_field_morphisms.pyx +781 -0
- sage/rings/number_field/number_field_rel.py +2734 -0
- sage/rings/number_field/order.py +2981 -0
- sage/rings/number_field/order_ideal.py +804 -0
- sage/rings/number_field/selmer_group.py +715 -0
- sage/rings/number_field/small_primes_of_degree_one.py +242 -0
- sage/rings/number_field/splitting_field.py +606 -0
- sage/rings/number_field/structure.py +380 -0
- sage/rings/number_field/unit_group.py +721 -0
- sage/rings/padics/all__sagemath_flint.py +3 -0
- sage/rings/polynomial/all__sagemath_flint.py +1 -0
- sage/rings/polynomial/complex_roots.py +312 -0
- sage/rings/polynomial/evaluation_flint.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/evaluation_flint.pxd +7 -0
- sage/rings/polynomial/evaluation_flint.pyx +68 -0
- sage/rings/polynomial/hilbert.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/hilbert.pyx +602 -0
- sage/rings/polynomial/polynomial_complex_arb.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
- sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
- sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
- sage/rings/polynomial/polynomial_number_field.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_number_field.pyx +345 -0
- sage/rings/polynomial/polynomial_rational_flint.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
- sage/rings/polynomial/polynomial_zmod_flint.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
- sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
- sage/rings/polynomial/real_roots.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/real_roots.pxd +81 -0
- sage/rings/polynomial/real_roots.pyx +4704 -0
- sage/rings/polynomial/refine_root.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/refine_root.pyx +142 -0
- sage/rings/polynomial/weil/all.py +4 -0
- sage/rings/polynomial/weil/power_sums.h +46 -0
- sage/rings/polynomial/weil/weil_polynomials.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
- sage/rings/qqbar.py +9025 -0
- sage/rings/real_arb.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/real_arb.pxd +21 -0
- sage/rings/real_arb.pyx +4065 -0
- sage/rings/real_interval_absolute.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/real_interval_absolute.pyx +1073 -0
- sage/rings/real_mpfi.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/rings/real_mpfi.pyx +5428 -0
- sage/schemes/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.cpython-312-x86_64-linux-gnu.so +0 -0
- sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
- sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,1155 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-flint
|
2
|
+
# sage.doctest: needs sage.graphs
|
3
|
+
"""
|
4
|
+
Path Semigroups
|
5
|
+
"""
|
6
|
+
|
7
|
+
# ****************************************************************************
|
8
|
+
# Copyright (C) 2012 Jim Stark <jstarx@gmail.com>
|
9
|
+
# 2013 Simon King <simon.king@uni-jena.de>
|
10
|
+
#
|
11
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
12
|
+
#
|
13
|
+
# This code is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
15
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
16
|
+
#
|
17
|
+
# See the GNU General Public License for more details; the full text
|
18
|
+
# is available at:
|
19
|
+
#
|
20
|
+
# https://www.gnu.org/licenses/
|
21
|
+
# ****************************************************************************
|
22
|
+
|
23
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
24
|
+
from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
|
25
|
+
from sage.categories.monoids import Monoids
|
26
|
+
from sage.categories.semigroups import Semigroups
|
27
|
+
from sage.misc.cachefunc import cached_method
|
28
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
29
|
+
from sage.rings.integer import Integer
|
30
|
+
from sage.rings.integer_ring import ZZ
|
31
|
+
from sage.structure.parent import Parent
|
32
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
33
|
+
|
34
|
+
from .paths import QuiverPath
|
35
|
+
from .representation import QuiverRep
|
36
|
+
|
37
|
+
#########################
|
38
|
+
# Some auxiliary function to create generating functions to count paths.
|
39
|
+
|
40
|
+
|
41
|
+
class PathSemigroup(UniqueRepresentation, Parent):
|
42
|
+
r"""
|
43
|
+
The partial semigroup that is given by the directed paths of a quiver,
|
44
|
+
subject to concatenation.
|
45
|
+
|
46
|
+
See :mod:`~sage.quivers.representation` for a definition of this
|
47
|
+
semigroup and of the notion of a path in a quiver.
|
48
|
+
|
49
|
+
Note that a *partial semigroup* here is defined as a set `G` with a
|
50
|
+
partial binary operation `G \times G \to G \cup \{\mbox{None}\}`,
|
51
|
+
which is written infix as a `*` sign and satisfies associativity in
|
52
|
+
the following sense: If `a`, `b` and `c` are three elements of `G`,
|
53
|
+
and if one of the products `(a*b)*c` and `a*(b*c)` exists, then so
|
54
|
+
does the other and the two products are equal. A partial semigroup
|
55
|
+
is not required to have a neutral element (and this one usually has
|
56
|
+
no such element).
|
57
|
+
|
58
|
+
EXAMPLES::
|
59
|
+
|
60
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
|
61
|
+
sage: S = Q.path_semigroup()
|
62
|
+
sage: S
|
63
|
+
Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices
|
64
|
+
sage: S.variable_names()
|
65
|
+
('e_1', 'e_2', 'e_3', 'a', 'b', 'c', 'd')
|
66
|
+
sage: S.gens()
|
67
|
+
(e_1, e_2, e_3, a, b, c, d)
|
68
|
+
sage: S.category()
|
69
|
+
Category of finite enumerated semigroups
|
70
|
+
|
71
|
+
In the test suite, we skip the associativity test, as in this example the
|
72
|
+
paths used for testing cannot be concatenated::
|
73
|
+
|
74
|
+
sage: TestSuite(S).run(skip=['_test_associativity'])
|
75
|
+
|
76
|
+
If there is only a single vertex, the partial semigroup is a monoid. If
|
77
|
+
the underlying quiver has cycles or loops, then the (partial) semigroup
|
78
|
+
only is an infinite enumerated set. This time, there is no need to skip
|
79
|
+
tests::
|
80
|
+
|
81
|
+
sage: Q = DiGraph({1:{1:['a', 'b', 'c', 'd']}})
|
82
|
+
sage: M = Q.path_semigroup()
|
83
|
+
sage: M
|
84
|
+
Monoid formed by the directed paths of Looped multi-digraph on 1 vertex
|
85
|
+
sage: M.category()
|
86
|
+
Category of infinite enumerated monoids
|
87
|
+
sage: TestSuite(M).run()
|
88
|
+
"""
|
89
|
+
Element = QuiverPath
|
90
|
+
|
91
|
+
@staticmethod
|
92
|
+
def __classcall__(cls, Q):
|
93
|
+
"""
|
94
|
+
Normalize the arguments passed to the constructor.
|
95
|
+
|
96
|
+
The normalization consists of making an immutable copy of ``Q``
|
97
|
+
that is made weighted.
|
98
|
+
|
99
|
+
INPUT:
|
100
|
+
|
101
|
+
- ``Q`` -- a :class:`~sage.graphs.digraph.DiGraph`
|
102
|
+
|
103
|
+
TESTS::
|
104
|
+
|
105
|
+
sage: G1 = DiGraph({1:{2:['a']}})
|
106
|
+
sage: G2 = DiGraph({1:{2:['b']}})
|
107
|
+
sage: P1 = G1.path_semigroup()
|
108
|
+
sage: P2 = G2.path_semigroup()
|
109
|
+
sage: G1 == G2 # equality of unweighted graphs ignores edge labels
|
110
|
+
True
|
111
|
+
sage: P1.quiver() == P2.quiver() # edge labels no longer ignored
|
112
|
+
False
|
113
|
+
sage: P1 == P2
|
114
|
+
False
|
115
|
+
"""
|
116
|
+
# If self is immutable and weighted, then the copy is really cheap:
|
117
|
+
# __copy__ just returns self.
|
118
|
+
Q = Q.copy(immutable=True, weighted=True)
|
119
|
+
return super().__classcall__(cls, Q)
|
120
|
+
|
121
|
+
def __init__(self, Q):
|
122
|
+
"""
|
123
|
+
Initialize ``self``.
|
124
|
+
|
125
|
+
INPUT:
|
126
|
+
|
127
|
+
- ``Q`` -- a :class:`~sage.graphs.digraph.DiGraph`
|
128
|
+
|
129
|
+
EXAMPLES:
|
130
|
+
|
131
|
+
Note that usually a path semigroup is created using
|
132
|
+
:meth:`sage.graphs.digraph.DiGraph.path_semigroup`. Here, we
|
133
|
+
demonstrate the direct construction::
|
134
|
+
|
135
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}, immutable=True)
|
136
|
+
sage: from sage.quivers.path_semigroup import PathSemigroup
|
137
|
+
sage: P = PathSemigroup(Q)
|
138
|
+
sage: P is DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}).path_semigroup() # indirect doctest
|
139
|
+
True
|
140
|
+
sage: P
|
141
|
+
Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices
|
142
|
+
|
143
|
+
While hardly of any use, it is possible to construct the path
|
144
|
+
semigroup of an empty quiver (it is, of course, empty)::
|
145
|
+
|
146
|
+
sage: D = DiGraph({})
|
147
|
+
sage: A = D.path_semigroup(); A
|
148
|
+
Partial semigroup formed by the directed paths of Digraph on 0 vertices
|
149
|
+
sage: A.list()
|
150
|
+
[]
|
151
|
+
|
152
|
+
.. TODO::
|
153
|
+
|
154
|
+
When the graph has more than one edge, the proper category would be
|
155
|
+
a "partial semigroup" or a "semigroupoid" but definitely not a
|
156
|
+
semigroup!
|
157
|
+
"""
|
158
|
+
#########
|
159
|
+
# Verify that the graph labels are acceptable for this implementation
|
160
|
+
# Check that edges are labelled with nonempty strings and do not begin
|
161
|
+
# with 'e_' or contain '*'
|
162
|
+
labels = Q.edge_labels()
|
163
|
+
if len(set(labels)) != len(labels):
|
164
|
+
raise ValueError("edge labels of the digraph must be unique")
|
165
|
+
for x in labels:
|
166
|
+
if not isinstance(x, str) or x == '':
|
167
|
+
raise ValueError("edge labels of the digraph must be nonempty strings")
|
168
|
+
if x[0:2] == 'e_':
|
169
|
+
raise ValueError("edge labels of the digraph must not begin with 'e_'")
|
170
|
+
if x.find('*') != -1:
|
171
|
+
raise ValueError("edge labels of the digraph must not contain '*'")
|
172
|
+
|
173
|
+
# Check validity of input: vertices have to be labelled 1,2,3,... and
|
174
|
+
# edge labels must be unique
|
175
|
+
for v in Q:
|
176
|
+
if not isinstance(v, (Integer, int)):
|
177
|
+
raise ValueError("vertices of the digraph must be labelled by integers")
|
178
|
+
|
179
|
+
# Determine the category which this (partial) semigroup belongs to
|
180
|
+
if Q.is_directed_acyclic():
|
181
|
+
cat = FiniteEnumeratedSets()
|
182
|
+
else:
|
183
|
+
cat = InfiniteEnumeratedSets()
|
184
|
+
self._sorted_edges = tuple(sorted(Q.edges(sort=True), key=lambda x: x[2]))
|
185
|
+
self._labels = tuple([x[2] for x in self._sorted_edges])
|
186
|
+
self._label_index = {s[2]: i for i, s in enumerate(self._sorted_edges)}
|
187
|
+
self._nb_arrows = max(len(self._sorted_edges), 1)
|
188
|
+
names = ['e_{0}'.format(v) for v in Q.vertex_iterator()]
|
189
|
+
names += list(self._labels)
|
190
|
+
self._quiver = Q
|
191
|
+
if Q.num_verts() == 1:
|
192
|
+
cat = cat.join([cat, Monoids()])
|
193
|
+
else:
|
194
|
+
cat = cat.join([cat, Semigroups()])
|
195
|
+
Parent.__init__(self, names=names, category=cat)
|
196
|
+
|
197
|
+
def _repr_(self):
|
198
|
+
"""
|
199
|
+
String representation.
|
200
|
+
|
201
|
+
EXAMPLES::
|
202
|
+
|
203
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
|
204
|
+
sage: Q.path_semigroup()
|
205
|
+
Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices
|
206
|
+
sage: Q = DiGraph({1:{1:['a','b', 'c', 'd']}})
|
207
|
+
sage: Q.path_semigroup()
|
208
|
+
Monoid formed by the directed paths of Looped multi-digraph on 1 vertex
|
209
|
+
"""
|
210
|
+
if self._quiver.num_verts() != 1:
|
211
|
+
return "Partial semigroup formed by the directed paths of {}".format(self._quiver)
|
212
|
+
return "Monoid formed by the directed paths of {}".format(self._quiver)
|
213
|
+
|
214
|
+
def _coerce_map_from_(self, other):
|
215
|
+
"""
|
216
|
+
A coercion from `A` to `B` exists if the underlying quiver
|
217
|
+
of `A` is a sub-quiver of the underlying quiver of `B` (preserving
|
218
|
+
names).
|
219
|
+
|
220
|
+
EXAMPLES::
|
221
|
+
|
222
|
+
sage: Q1 = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
|
223
|
+
sage: Q2 = DiGraph({1:{2:['a'], 3:['c']}})
|
224
|
+
sage: Q3 = DiGraph({1:{2:['a','x'], 3:['c']}, 3:{1:['d']}})
|
225
|
+
sage: P1 = Q1.path_semigroup()
|
226
|
+
sage: P2 = Q2.path_semigroup()
|
227
|
+
sage: P3 = Q3.path_semigroup()
|
228
|
+
sage: P1.has_coerce_map_from(P2) # indirect doctest
|
229
|
+
True
|
230
|
+
sage: P1.has_coerce_map_from(P3)
|
231
|
+
False
|
232
|
+
sage: d = P1([(3,1,'d')]); d
|
233
|
+
d
|
234
|
+
sage: c = P2([(1,3,'c')]); c
|
235
|
+
c
|
236
|
+
sage: c.parent() is P1
|
237
|
+
False
|
238
|
+
sage: c in P1 # indirect doctest
|
239
|
+
True
|
240
|
+
sage: d*c # indirect doctest
|
241
|
+
d*c
|
242
|
+
sage: (d*c).parent() is P1
|
243
|
+
True
|
244
|
+
sage: c3 = P3([(1,3,'c')]); c3
|
245
|
+
c
|
246
|
+
sage: c3 in P1 # indirect doctest
|
247
|
+
False
|
248
|
+
sage: d*c3
|
249
|
+
Traceback (most recent call last):
|
250
|
+
...
|
251
|
+
TypeError: unsupported operand parent(s) for *:
|
252
|
+
'Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices'
|
253
|
+
and 'Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices'
|
254
|
+
"""
|
255
|
+
if not isinstance(other, PathSemigroup):
|
256
|
+
return
|
257
|
+
# This is what we would like to do:
|
258
|
+
# return other.quiver().is_subgraph(self._quiver, induced=False)
|
259
|
+
# However, this is deprecated for non-induced subgraphs
|
260
|
+
# of directed multi-graphs.
|
261
|
+
#
|
262
|
+
# We ignore the deprecation and do what the deprecated method is doing
|
263
|
+
# internally, directly using the backend to make things faster.
|
264
|
+
sQ = self._quiver._backend
|
265
|
+
oQ = other.quiver()._backend
|
266
|
+
if sQ.num_verts() < oQ.num_verts():
|
267
|
+
return False
|
268
|
+
if any(not sQ.has_vertex(v) for v in oQ.iterator_verts(None)):
|
269
|
+
return False
|
270
|
+
return all(sQ.has_edge(*e) for e in oQ.iterator_out_edges(oQ.iterator_verts(None), True))
|
271
|
+
|
272
|
+
def _element_constructor_(self, data, check=True):
|
273
|
+
"""
|
274
|
+
The accepted data are:
|
275
|
+
|
276
|
+
- the integer ``1``, which returns the first idempotent,
|
277
|
+
- a list, whose only item is a tuple ``(v,v)`` for a vertex ``v``,
|
278
|
+
- a list of edge labels,
|
279
|
+
- a single edge label,
|
280
|
+
- a list of triples ``(v, w, s)`` that are edges of the underlying quiver, or
|
281
|
+
- an element of another path semigroup.
|
282
|
+
|
283
|
+
EXAMPLES::
|
284
|
+
|
285
|
+
sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
|
286
|
+
sage: P(1)
|
287
|
+
e_1
|
288
|
+
sage: P([(3,3)])
|
289
|
+
e_3
|
290
|
+
sage: P(['c','d'])
|
291
|
+
c*d
|
292
|
+
sage: P('c')
|
293
|
+
c
|
294
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d'], 2:['e']}}).path_semigroup()
|
295
|
+
sage: Q([(1,3,'c'), (3,1,'d'), (1,2,'b')])
|
296
|
+
c*d*b
|
297
|
+
sage: Q(P(['c','d']))
|
298
|
+
c*d
|
299
|
+
|
300
|
+
A :exc:`TypeError` or a :exc:`ValueError` is raised appropriately
|
301
|
+
if the input is wrong::
|
302
|
+
|
303
|
+
sage: G = DiGraph([(0,0,'a'), (0,1,'b'), (1,0,'c')], loops=True)
|
304
|
+
sage: P = G.path_semigroup()
|
305
|
+
|
306
|
+
sage: P([(0,0)])
|
307
|
+
e_0
|
308
|
+
sage: P([(2,2)])
|
309
|
+
Traceback (most recent call last):
|
310
|
+
...
|
311
|
+
ValueError: startpoint 2 should belong to [0, 1]
|
312
|
+
sage: P([(0,1,'a'),(1,0,'b')])
|
313
|
+
Traceback (most recent call last):
|
314
|
+
...
|
315
|
+
ValueError: (0, 1, 'a') is not an edge
|
316
|
+
sage: P('d')
|
317
|
+
Traceback (most recent call last):
|
318
|
+
...
|
319
|
+
ValueError: data='d' is not the label of an edge
|
320
|
+
sage: P([(0,0,'a'),(0,1,2,3)])
|
321
|
+
Traceback (most recent call last):
|
322
|
+
...
|
323
|
+
ValueError: each edge must be a triple, got (0, 1, 2, 3)
|
324
|
+
sage: P(18)
|
325
|
+
Traceback (most recent call last):
|
326
|
+
...
|
327
|
+
TypeError: data=18 is not valid. A path must be initialized from
|
328
|
+
either a tuple or a list
|
329
|
+
"""
|
330
|
+
L = self._label_index
|
331
|
+
E = self._sorted_edges
|
332
|
+
if isinstance(data, QuiverPath):
|
333
|
+
if data.parent() is self:
|
334
|
+
return data
|
335
|
+
start = data.initial_vertex()
|
336
|
+
end = data.terminal_vertex()
|
337
|
+
edge_index = {e: i for i, e in enumerate(E)}
|
338
|
+
path = [edge_index.get(e) for e in data]
|
339
|
+
elif not data:
|
340
|
+
raise ValueError("no data given to define this path")
|
341
|
+
elif data == 1:
|
342
|
+
start = end = next(self._quiver.vertex_iterator())
|
343
|
+
path = []
|
344
|
+
elif isinstance(data, str): # one edge
|
345
|
+
i = L.get(data, None)
|
346
|
+
if i is None:
|
347
|
+
raise ValueError("data={!r} is not the label of an edge".format(data))
|
348
|
+
start, end, _ = E[i]
|
349
|
+
path = [i]
|
350
|
+
elif not isinstance(data, (tuple, list)):
|
351
|
+
raise TypeError("data={} is not valid. A path must be initialized from either a tuple or a list".format(data))
|
352
|
+
elif isinstance(data[0], str): # a list of labels
|
353
|
+
start = L.get(data[0])
|
354
|
+
if start is None:
|
355
|
+
raise ValueError("data[0]={!r} is not the label of an edge".format(data[0]))
|
356
|
+
start = E[start][0]
|
357
|
+
end = L.get(data[-1])
|
358
|
+
if end is None:
|
359
|
+
raise ValueError("data[-1]={!r} is not the label of an edge".format(data[-1]))
|
360
|
+
end = E[end][1]
|
361
|
+
path = [L.get(e) for e in data]
|
362
|
+
elif len(data) == 1 and len(data[0]) == 2: # an idempotent
|
363
|
+
start = data[0][0]
|
364
|
+
end = data[0][1]
|
365
|
+
path = []
|
366
|
+
else: # a list of edges
|
367
|
+
if any(len(x) != 3 for x in data):
|
368
|
+
x = next(x for x in data if len(x) != 3)
|
369
|
+
raise ValueError("each edge must be a triple, got {}".format(x))
|
370
|
+
start = data[0][0]
|
371
|
+
end = data[-1][1]
|
372
|
+
edge_index = {e: i for i, e in enumerate(E)}
|
373
|
+
path = [edge_index.get(e) for e in data]
|
374
|
+
|
375
|
+
if check:
|
376
|
+
Q = self._quiver
|
377
|
+
if start is None or start not in Q:
|
378
|
+
raise ValueError("startpoint {} should belong to {}".format(start, Q.vertices(sort=False)))
|
379
|
+
if end is None or end not in Q:
|
380
|
+
raise ValueError("endpoint {} should belong to {}".format(end, Q.vertices(sort=False)))
|
381
|
+
if not path:
|
382
|
+
if start != end:
|
383
|
+
raise ValueError("start and endpoint of a path of length 0 must coincide")
|
384
|
+
else:
|
385
|
+
if any(x is None for x in path):
|
386
|
+
i = next((i for i, x in enumerate(path) if x is None))
|
387
|
+
raise ValueError("{} is not an edge".format(data[i]))
|
388
|
+
for n in range(1, len(path)):
|
389
|
+
e0 = E[path[n - 1]][1]
|
390
|
+
e1 = E[path[n]][0]
|
391
|
+
if e0 != e1:
|
392
|
+
raise ValueError("edge {} ends at {}, but edge {} starts at {}".format(
|
393
|
+
E[path[n - 1]][2], e0, E[path[n]][2], e1))
|
394
|
+
if E[path[0]][0] != start:
|
395
|
+
raise ValueError("first edge should start at vertex {}".format(start))
|
396
|
+
if E[path[-1]][1] != end:
|
397
|
+
raise ValueError("last edge should end at vertex {}".format(end))
|
398
|
+
|
399
|
+
return self.element_class(self, start, end, path)
|
400
|
+
|
401
|
+
@cached_method
|
402
|
+
def arrows(self):
|
403
|
+
"""
|
404
|
+
Return the elements corresponding to edges of the underlying quiver.
|
405
|
+
|
406
|
+
EXAMPLES::
|
407
|
+
|
408
|
+
sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
|
409
|
+
sage: P.arrows()
|
410
|
+
(a, b, c, d)
|
411
|
+
"""
|
412
|
+
return tuple(self.element_class(self, e[0], e[1], [i])
|
413
|
+
for i, e in enumerate(self._sorted_edges))
|
414
|
+
|
415
|
+
@cached_method
|
416
|
+
def idempotents(self):
|
417
|
+
"""
|
418
|
+
Return the idempotents corresponding to the vertices of the
|
419
|
+
underlying quiver.
|
420
|
+
|
421
|
+
EXAMPLES::
|
422
|
+
|
423
|
+
sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
|
424
|
+
sage: P.idempotents()
|
425
|
+
(e_1, e_2, e_3)
|
426
|
+
"""
|
427
|
+
return tuple(self.element_class(self, v, v, [])
|
428
|
+
for v in self._quiver.vertex_iterator())
|
429
|
+
|
430
|
+
def ngens(self):
|
431
|
+
"""
|
432
|
+
Return the number of generators (:meth:`arrows` and
|
433
|
+
:meth:`idempotents`).
|
434
|
+
|
435
|
+
EXAMPLES::
|
436
|
+
|
437
|
+
sage: F = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
|
438
|
+
sage: F.ngens()
|
439
|
+
7
|
440
|
+
"""
|
441
|
+
Q = self._quiver
|
442
|
+
return Q.num_verts() + Q.num_edges()
|
443
|
+
|
444
|
+
@cached_method
|
445
|
+
def gen(self, i):
|
446
|
+
"""
|
447
|
+
Return generator number `i`.
|
448
|
+
|
449
|
+
INPUT:
|
450
|
+
|
451
|
+
- ``i`` -- integer
|
452
|
+
|
453
|
+
OUTPUT:
|
454
|
+
|
455
|
+
An idempotent, if `i` is smaller than the number of vertices,
|
456
|
+
or an arrow otherwise.
|
457
|
+
|
458
|
+
EXAMPLES::
|
459
|
+
|
460
|
+
sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
|
461
|
+
sage: P.1 # indirect doctest
|
462
|
+
e_2
|
463
|
+
sage: P.idempotents()[1]
|
464
|
+
e_2
|
465
|
+
sage: P.5
|
466
|
+
c
|
467
|
+
sage: P.gens()[5]
|
468
|
+
c
|
469
|
+
"""
|
470
|
+
return self.gens()[i]
|
471
|
+
|
472
|
+
@cached_method
|
473
|
+
def gens(self) -> tuple:
|
474
|
+
"""
|
475
|
+
Return the tuple of generators.
|
476
|
+
|
477
|
+
.. NOTE::
|
478
|
+
|
479
|
+
This coincides with the sum of the output of
|
480
|
+
:meth:`idempotents` and :meth:`arrows`.
|
481
|
+
|
482
|
+
EXAMPLES::
|
483
|
+
|
484
|
+
sage: P = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}}).path_semigroup()
|
485
|
+
sage: P.gens()
|
486
|
+
(e_1, e_2, e_3, a, b, c, d)
|
487
|
+
sage: P.gens() == P.idempotents() + P.arrows()
|
488
|
+
True
|
489
|
+
"""
|
490
|
+
return self.idempotents() + self.arrows()
|
491
|
+
|
492
|
+
def is_finite(self) -> bool:
|
493
|
+
"""
|
494
|
+
This partial semigroup is finite if and only if the underlying
|
495
|
+
quiver is acyclic.
|
496
|
+
|
497
|
+
EXAMPLES::
|
498
|
+
|
499
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
|
500
|
+
sage: Q.path_semigroup().is_finite()
|
501
|
+
True
|
502
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
|
503
|
+
sage: Q.path_semigroup().is_finite()
|
504
|
+
False
|
505
|
+
"""
|
506
|
+
return self._quiver.is_directed_acyclic() and not self._quiver.has_loops()
|
507
|
+
|
508
|
+
def __len__(self):
|
509
|
+
"""
|
510
|
+
EXAMPLES::
|
511
|
+
|
512
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
|
513
|
+
sage: F = Q.path_semigroup()
|
514
|
+
sage: len(F)
|
515
|
+
9
|
516
|
+
sage: list(F)
|
517
|
+
[e_1, e_2, e_3, a, b, c, d, a*d, b*d]
|
518
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
|
519
|
+
sage: F = Q.path_semigroup()
|
520
|
+
sage: len(F)
|
521
|
+
Traceback (most recent call last):
|
522
|
+
...
|
523
|
+
ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
|
524
|
+
"""
|
525
|
+
return len(self.all_paths())
|
526
|
+
|
527
|
+
def cardinality(self):
|
528
|
+
"""
|
529
|
+
EXAMPLES::
|
530
|
+
|
531
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
|
532
|
+
sage: F = Q.path_semigroup()
|
533
|
+
sage: F.cardinality()
|
534
|
+
9
|
535
|
+
sage: A = F.algebra(QQ)
|
536
|
+
sage: list(A.basis())
|
537
|
+
[e_1, e_2, e_3, a, b, c, d, a*d, b*d]
|
538
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
|
539
|
+
sage: F = Q.path_semigroup()
|
540
|
+
sage: F.cardinality()
|
541
|
+
+Infinity
|
542
|
+
sage: A = F.algebra(QQ)
|
543
|
+
sage: list(A.basis())
|
544
|
+
Traceback (most recent call last):
|
545
|
+
...
|
546
|
+
ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
|
547
|
+
"""
|
548
|
+
from sage.rings.integer_ring import ZZ
|
549
|
+
if self._quiver.is_directed_acyclic() and not self._quiver.has_loops():
|
550
|
+
return ZZ(len(self))
|
551
|
+
from sage.rings.infinity import Infinity
|
552
|
+
return Infinity
|
553
|
+
|
554
|
+
def __iter__(self):
|
555
|
+
"""
|
556
|
+
Iterate over the elements of ``self``, i.e., over quiver paths.
|
557
|
+
|
558
|
+
EXAMPLES::
|
559
|
+
|
560
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
|
561
|
+
sage: P = Q.path_semigroup()
|
562
|
+
sage: list(P)
|
563
|
+
[e_1, e_2, e_3, a, b, c, d, a*d, b*d]
|
564
|
+
|
565
|
+
The elements are sorted by length. Of course, the list of elements
|
566
|
+
is infinite for quivers with cycles. ::
|
567
|
+
|
568
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
|
569
|
+
sage: P = Q.path_semigroup()
|
570
|
+
sage: P.is_finite()
|
571
|
+
False
|
572
|
+
sage: list(P)
|
573
|
+
Traceback (most recent call last):
|
574
|
+
...
|
575
|
+
ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
|
576
|
+
|
577
|
+
However, one can iterate::
|
578
|
+
|
579
|
+
sage: counter = 0
|
580
|
+
sage: for p in P:
|
581
|
+
....: counter += 1
|
582
|
+
....: print(p)
|
583
|
+
....: if counter==20:
|
584
|
+
....: break
|
585
|
+
e_1
|
586
|
+
e_2
|
587
|
+
e_3
|
588
|
+
a
|
589
|
+
b
|
590
|
+
d
|
591
|
+
c
|
592
|
+
a*d
|
593
|
+
b*d
|
594
|
+
d*c
|
595
|
+
c*a
|
596
|
+
c*b
|
597
|
+
a*d*c
|
598
|
+
b*d*c
|
599
|
+
d*c*a
|
600
|
+
d*c*b
|
601
|
+
c*a*d
|
602
|
+
c*b*d
|
603
|
+
a*d*c*a
|
604
|
+
a*d*c*b
|
605
|
+
"""
|
606
|
+
d = 0
|
607
|
+
length_d_available = True
|
608
|
+
while length_d_available:
|
609
|
+
length_d_available = False
|
610
|
+
for v in self._quiver.vertex_iterator():
|
611
|
+
for w in self.iter_paths_by_length_and_startpoint(d, v):
|
612
|
+
length_d_available = True
|
613
|
+
yield w
|
614
|
+
d += 1
|
615
|
+
|
616
|
+
def iter_paths_by_length_and_startpoint(self, d, v):
|
617
|
+
"""
|
618
|
+
An iterator over quiver paths with a fixed length and start point.
|
619
|
+
|
620
|
+
INPUT:
|
621
|
+
|
622
|
+
- ``d`` -- integer; the path length
|
623
|
+
- ``v`` -- a vertex; start point of the paths
|
624
|
+
|
625
|
+
EXAMPLES::
|
626
|
+
|
627
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
|
628
|
+
sage: P = Q.path_semigroup()
|
629
|
+
sage: P.is_finite()
|
630
|
+
False
|
631
|
+
sage: list(P.iter_paths_by_length_and_startpoint(4,1))
|
632
|
+
[a*d*c*a, a*d*c*b, b*d*c*a, b*d*c*b]
|
633
|
+
sage: list(P.iter_paths_by_length_and_startpoint(5,1))
|
634
|
+
[a*d*c*a*d, a*d*c*b*d, b*d*c*a*d, b*d*c*b*d]
|
635
|
+
sage: list(P.iter_paths_by_length_and_startpoint(5,2))
|
636
|
+
[d*c*a*d*c, d*c*b*d*c]
|
637
|
+
|
638
|
+
TESTS::
|
639
|
+
|
640
|
+
sage: Q = DiGraph({1:{1:['a','b', 'c', 'd']}})
|
641
|
+
sage: P = Q.path_semigroup()
|
642
|
+
sage: list(P.iter_paths_by_length_and_startpoint(2,1))
|
643
|
+
[a*a,
|
644
|
+
a*b,
|
645
|
+
a*c,
|
646
|
+
a*d,
|
647
|
+
b*a,
|
648
|
+
b*b,
|
649
|
+
b*c,
|
650
|
+
b*d,
|
651
|
+
c*a,
|
652
|
+
c*b,
|
653
|
+
c*c,
|
654
|
+
c*d,
|
655
|
+
d*a,
|
656
|
+
d*b,
|
657
|
+
d*c,
|
658
|
+
d*d]
|
659
|
+
sage: len(list(P.iter_paths_by_length_and_startpoint(2,1)))
|
660
|
+
16
|
661
|
+
"""
|
662
|
+
# iterate over length d paths starting at vertex v
|
663
|
+
if not d >= 0:
|
664
|
+
raise ValueError("path length must be a nonnegative integer")
|
665
|
+
if v not in self._quiver:
|
666
|
+
raise ValueError("the starting point {} is not a vertex of the underlying quiver".format(v))
|
667
|
+
if not d:
|
668
|
+
yield self.element_class(self, v, v, [])
|
669
|
+
else:
|
670
|
+
for w in self.iter_paths_by_length_and_startpoint(d - 1, v):
|
671
|
+
for a in self._quiver._backend.iterator_out_edges([w.terminal_vertex()], True):
|
672
|
+
yield self(list(w) + [a], check=False)
|
673
|
+
|
674
|
+
def iter_paths_by_length_and_endpoint(self, d, v):
|
675
|
+
"""
|
676
|
+
An iterator over quiver paths with a fixed length and end point.
|
677
|
+
|
678
|
+
INPUT:
|
679
|
+
|
680
|
+
- ``d`` -- integer; the path length
|
681
|
+
- ``v`` -- a vertex; end point of the paths
|
682
|
+
|
683
|
+
EXAMPLES::
|
684
|
+
|
685
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
|
686
|
+
sage: F = Q.path_semigroup()
|
687
|
+
sage: F.is_finite()
|
688
|
+
False
|
689
|
+
sage: list(F.iter_paths_by_length_and_endpoint(4,1))
|
690
|
+
[c*a*d*c, c*b*d*c]
|
691
|
+
sage: list(F.iter_paths_by_length_and_endpoint(5,1))
|
692
|
+
[d*c*a*d*c, d*c*b*d*c]
|
693
|
+
sage: list(F.iter_paths_by_length_and_endpoint(5,2))
|
694
|
+
[c*a*d*c*a, c*b*d*c*a, c*a*d*c*b, c*b*d*c*b]
|
695
|
+
"""
|
696
|
+
# iterate over length d paths ending at vertex v
|
697
|
+
if not d >= 0:
|
698
|
+
raise ValueError("path length must be a nonnegative integer")
|
699
|
+
if v not in self._quiver:
|
700
|
+
raise ValueError("the starting point {} is not a vertex of the underlying quiver".format(v))
|
701
|
+
if not d:
|
702
|
+
yield self.element_class(self, v, v, [])
|
703
|
+
else:
|
704
|
+
for w in self.iter_paths_by_length_and_endpoint(d - 1, v):
|
705
|
+
for a in self._quiver._backend.iterator_in_edges([w.initial_vertex()], True):
|
706
|
+
yield self([a] + list(w), check=False)
|
707
|
+
|
708
|
+
def quiver(self):
|
709
|
+
"""
|
710
|
+
Return the underlying quiver (i.e., digraph) of this path semigroup.
|
711
|
+
|
712
|
+
.. NOTE::
|
713
|
+
|
714
|
+
The returned digraph always is an immutable copy of the originally
|
715
|
+
given digraph that is made weighted.
|
716
|
+
|
717
|
+
EXAMPLES::
|
718
|
+
|
719
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}},
|
720
|
+
....: weighted=False)
|
721
|
+
sage: F = Q.path_semigroup()
|
722
|
+
sage: F.quiver() == Q
|
723
|
+
False
|
724
|
+
sage: Q.weighted(True)
|
725
|
+
sage: F.quiver() == Q
|
726
|
+
True
|
727
|
+
"""
|
728
|
+
return self._quiver
|
729
|
+
|
730
|
+
@cached_method
|
731
|
+
def reverse(self):
|
732
|
+
"""
|
733
|
+
The path semigroup of the reverse quiver.
|
734
|
+
|
735
|
+
EXAMPLES::
|
736
|
+
|
737
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
|
738
|
+
sage: F = Q.path_semigroup()
|
739
|
+
sage: F.reverse() is Q.reverse().path_semigroup()
|
740
|
+
True
|
741
|
+
"""
|
742
|
+
return self._quiver.reverse().path_semigroup()
|
743
|
+
|
744
|
+
def algebra(self, k, order='negdegrevlex'):
|
745
|
+
"""
|
746
|
+
Return the path algebra of the underlying quiver.
|
747
|
+
|
748
|
+
INPUT:
|
749
|
+
|
750
|
+
- ``k`` -- a commutative ring
|
751
|
+
|
752
|
+
- ``order`` -- (optional) string, one of ``'negdegrevlex'`` (default),
|
753
|
+
``'degrevlex'``, ``'negdeglex'`` or ``'deglex'``, defining the
|
754
|
+
monomial order to be used
|
755
|
+
|
756
|
+
.. NOTE::
|
757
|
+
|
758
|
+
Monomial orders that are not degree orders are not supported.
|
759
|
+
|
760
|
+
EXAMPLES::
|
761
|
+
|
762
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['d']}, 3:{1:['c']}})
|
763
|
+
sage: P = Q.path_semigroup()
|
764
|
+
sage: P.algebra(GF(3))
|
765
|
+
Path algebra of Multi-digraph on 3 vertices over Finite Field of size 3
|
766
|
+
|
767
|
+
Now some example with different monomial orderings::
|
768
|
+
|
769
|
+
sage: P1 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'))
|
770
|
+
sage: P2 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='degrevlex')
|
771
|
+
sage: P3 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='negdeglex')
|
772
|
+
sage: P4 = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'), order='deglex')
|
773
|
+
sage: P1.order_string()
|
774
|
+
'negdegrevlex'
|
775
|
+
sage: sage_eval('(x+2*z+1)^3', P1.gens_dict())
|
776
|
+
e_1 + z + 3*x + 2*z*z + x*z + z*x + 3*x*x + 3*z*z*z + 4*x*z*z + 4*z*x*z + 2*x*x*z + 4*z*z*x + 2*x*z*x + 2*z*x*x + x*x*x
|
777
|
+
sage: sage_eval('(x+2*z+1)^3', P2.gens_dict())
|
778
|
+
3*z*z*z + 4*x*z*z + 4*z*x*z + 2*x*x*z + 4*z*z*x + 2*x*z*x + 2*z*x*x + x*x*x + 2*z*z + x*z + z*x + 3*x*x + z + 3*x + e_1
|
779
|
+
sage: sage_eval('(x+2*z+1)^3', P3.gens_dict())
|
780
|
+
e_1 + z + 3*x + 2*z*z + z*x + x*z + 3*x*x + 3*z*z*z + 4*z*z*x + 4*z*x*z + 2*z*x*x + 4*x*z*z + 2*x*z*x + 2*x*x*z + x*x*x
|
781
|
+
sage: sage_eval('(x+2*z+1)^3', P4.gens_dict())
|
782
|
+
3*z*z*z + 4*z*z*x + 4*z*x*z + 2*z*x*x + 4*x*z*z + 2*x*z*x + 2*x*x*z + x*x*x + 2*z*z + z*x + x*z + 3*x*x + z + 3*x + e_1
|
783
|
+
"""
|
784
|
+
from sage.quivers.algebra import PathAlgebra
|
785
|
+
return PathAlgebra(k, self, order)
|
786
|
+
|
787
|
+
###########################################################################
|
788
|
+
# #
|
789
|
+
# REPRESENTATION THEORETIC FUNCTIONS #
|
790
|
+
# These functions involve the representation theory of quivers. #
|
791
|
+
# #
|
792
|
+
###########################################################################
|
793
|
+
|
794
|
+
def representation(self, k, *args, **kwds):
|
795
|
+
"""
|
796
|
+
Return a representation of the quiver.
|
797
|
+
|
798
|
+
For more information see the
|
799
|
+
:class:`~sage.quivers.representation.QuiverRep` documentation.
|
800
|
+
|
801
|
+
TESTS::
|
802
|
+
|
803
|
+
sage: Q = DiGraph({1:{3:['a']}, 2:{3:['b']}}).path_semigroup()
|
804
|
+
sage: spaces = {1: QQ^2, 2: QQ^3, 3: QQ^2}
|
805
|
+
sage: maps = {(1, 3, 'a'): (QQ^2).Hom(QQ^2).identity(), (2, 3, 'b'): [[1, 0], [0, 0], [0, 0]]}
|
806
|
+
sage: M = Q.representation(QQ, spaces, maps)
|
807
|
+
sage: M
|
808
|
+
Representation with dimension vector (2, 3, 2)
|
809
|
+
"""
|
810
|
+
return QuiverRep(k, self, *args, **kwds)
|
811
|
+
|
812
|
+
def S(self, k, vertex):
|
813
|
+
"""
|
814
|
+
Return the simple module over `k` at the given vertex
|
815
|
+
``vertex``.
|
816
|
+
|
817
|
+
This module is literally simple only when `k` is a field.
|
818
|
+
|
819
|
+
INPUT:
|
820
|
+
|
821
|
+
- ``k`` -- the base ring of the representation
|
822
|
+
|
823
|
+
- ``vertex`` -- integer; a vertex of the quiver
|
824
|
+
|
825
|
+
OUTPUT: :class:`~sage.quivers.representation.QuiverRep`; the simple
|
826
|
+
module at ``vertex`` with base ring `k`
|
827
|
+
|
828
|
+
EXAMPLES::
|
829
|
+
|
830
|
+
sage: P = DiGraph({1:{2:['a','b']}, 2:{3:['c','d']}}).path_semigroup()
|
831
|
+
sage: S1 = P.S(GF(3), 1)
|
832
|
+
sage: P.S(ZZ, 3).dimension_vector()
|
833
|
+
(0, 0, 1)
|
834
|
+
sage: P.S(ZZ, 1).dimension_vector()
|
835
|
+
(1, 0, 0)
|
836
|
+
|
837
|
+
The vertex given must be a vertex of the quiver::
|
838
|
+
|
839
|
+
sage: P.S(QQ, 4)
|
840
|
+
Traceback (most recent call last):
|
841
|
+
...
|
842
|
+
ValueError: must specify a valid vertex of the quiver
|
843
|
+
"""
|
844
|
+
if vertex not in self._quiver:
|
845
|
+
raise ValueError("must specify a valid vertex of the quiver")
|
846
|
+
|
847
|
+
# This is the module with k at the given vertex and zero elsewhere. As
|
848
|
+
# all maps are zero we only need to specify that the given vertex has
|
849
|
+
# dimension 1 and the constructor will zero out everything else.
|
850
|
+
return QuiverRep(k, self, {vertex: 1})
|
851
|
+
|
852
|
+
simple = S
|
853
|
+
|
854
|
+
def P(self, k, vertex):
|
855
|
+
"""
|
856
|
+
Return the indecomposable projective module over `k` at the given
|
857
|
+
vertex ``vertex``.
|
858
|
+
|
859
|
+
This module is literally indecomposable only when `k` is a field.
|
860
|
+
|
861
|
+
INPUT:
|
862
|
+
|
863
|
+
- ``k`` -- the base ring of the representation
|
864
|
+
|
865
|
+
- ``vertex`` -- integer; a vertex of the quiver
|
866
|
+
|
867
|
+
OUTPUT: :class:`~sage.quivers.representation.QuiverRep`, the
|
868
|
+
indecomposable projective module at ``vertex`` with base ring `k`
|
869
|
+
|
870
|
+
EXAMPLES::
|
871
|
+
|
872
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['c','d']}}).path_semigroup()
|
873
|
+
sage: P2 = Q.P(GF(3), 2)
|
874
|
+
sage: Q.P(ZZ, 3).dimension_vector()
|
875
|
+
(0, 0, 1)
|
876
|
+
sage: Q.P(ZZ, 1).dimension_vector()
|
877
|
+
(1, 2, 4)
|
878
|
+
|
879
|
+
The vertex given must be a vertex of the quiver::
|
880
|
+
|
881
|
+
sage: Q.P(QQ, 4)
|
882
|
+
Traceback (most recent call last):
|
883
|
+
...
|
884
|
+
ValueError: must specify a valid vertex of the quiver
|
885
|
+
"""
|
886
|
+
if vertex not in self._quiver:
|
887
|
+
raise ValueError("must specify a valid vertex of the quiver")
|
888
|
+
return QuiverRep(k, self, [[(vertex, vertex)]], option='paths')
|
889
|
+
|
890
|
+
projective = P
|
891
|
+
|
892
|
+
def I(self, k, vertex):
|
893
|
+
"""
|
894
|
+
Return the indecomposable injective module over `k` at the
|
895
|
+
given vertex ``vertex``.
|
896
|
+
|
897
|
+
This module is literally indecomposable only when `k` is a field.
|
898
|
+
|
899
|
+
INPUT:
|
900
|
+
|
901
|
+
- ``k`` -- the base ring of the representation
|
902
|
+
|
903
|
+
- ``vertex`` -- integer; a vertex of the quiver
|
904
|
+
|
905
|
+
OUTPUT:
|
906
|
+
|
907
|
+
- :class:`~sage.quivers.representation.QuiverRep`, the indecomposable
|
908
|
+
injective module at vertex ``vertex`` with base ring `k`
|
909
|
+
|
910
|
+
EXAMPLES::
|
911
|
+
|
912
|
+
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['c','d']}}).path_semigroup()
|
913
|
+
sage: I2 = Q.I(GF(3), 2)
|
914
|
+
sage: Q.I(ZZ, 3).dimension_vector()
|
915
|
+
(4, 2, 1)
|
916
|
+
sage: Q.I(ZZ, 1).dimension_vector()
|
917
|
+
(1, 0, 0)
|
918
|
+
|
919
|
+
The vertex given must be a vertex of the quiver::
|
920
|
+
|
921
|
+
sage: Q.I(QQ, 4)
|
922
|
+
Traceback (most recent call last):
|
923
|
+
...
|
924
|
+
ValueError: must specify a valid vertex of the quiver
|
925
|
+
"""
|
926
|
+
if vertex not in self._quiver:
|
927
|
+
raise ValueError("must specify a valid vertex of the quiver")
|
928
|
+
return QuiverRep(k, self, [[(vertex, vertex)]], option='dual paths')
|
929
|
+
|
930
|
+
injective = I
|
931
|
+
|
932
|
+
def free_module(self, k):
|
933
|
+
"""
|
934
|
+
Return a free module of rank `1` over ``kP``, where `P` is
|
935
|
+
``self``. (In other words, the regular representation.)
|
936
|
+
|
937
|
+
INPUT:
|
938
|
+
|
939
|
+
- ``k`` -- ring; the base ring of the representation
|
940
|
+
|
941
|
+
OUTPUT:
|
942
|
+
|
943
|
+
- :class:`~sage.quivers.representation.QuiverRep_with_path_basis`, the
|
944
|
+
path algebra considered as a right module over itself.
|
945
|
+
|
946
|
+
EXAMPLES::
|
947
|
+
|
948
|
+
sage: Q = DiGraph({1:{2:['a', 'b'], 3: ['c', 'd']}, 2:{3:['e']}}).path_semigroup()
|
949
|
+
sage: Q.free_module(GF(3)).dimension_vector()
|
950
|
+
(1, 3, 6)
|
951
|
+
"""
|
952
|
+
return QuiverRep(k, self, [[(v, v)] for v in self._quiver], option='paths')
|
953
|
+
|
954
|
+
@lazy_attribute
|
955
|
+
def _poincare_series(self):
|
956
|
+
r"""
|
957
|
+
The Poincaré series matrix of this path semigroup.
|
958
|
+
|
959
|
+
The coefficient `(i,j)` of the matrix is a generating function for the
|
960
|
+
number of paths from vertex number `i` to vertex number `j`.
|
961
|
+
|
962
|
+
EXAMPLES::
|
963
|
+
|
964
|
+
sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']}, 2:{0:['e'],2:['f']}}).path_semigroup()
|
965
|
+
sage: S._poincare_series
|
966
|
+
[ (-t + 1)/(-2*t^2 - t + 1) t/(-2*t^2 - t + 1) t/(-2*t^2 - t + 1)]
|
967
|
+
[ t/(-2*t^2 - t + 1) (t^2 + t - 1)/(-2*t^3 + t^2 + 2*t - 1) -t^2/(-2*t^3 + t^2 + 2*t - 1)]
|
968
|
+
[ t/(-2*t^2 - t + 1) -t^2/(-2*t^3 + t^2 + 2*t - 1) (-t^2 - t + 1)/(2*t^3 - t^2 - 2*t + 1)]
|
969
|
+
|
970
|
+
Let us check that the result is plausible. We study the paths from
|
971
|
+
vertex `1` to vertex `2`. The number of paths sorted by length are
|
972
|
+
given by the power series expansion of the corresponding matrix
|
973
|
+
entry::
|
974
|
+
|
975
|
+
sage: P = PowerSeriesRing(ZZ, 't', default_prec=10)
|
976
|
+
sage: P(S._poincare_series[1,2].numerator())/P(S._poincare_series[1,2].denominator())
|
977
|
+
t^2 + 2*t^3 + 5*t^4 + 10*t^5 + 21*t^6 + 42*t^7 + 85*t^8 + 170*t^9 + 341*t^10 + 682*t^11 + O(t^12)
|
978
|
+
|
979
|
+
For comparison, we list the paths that start at `1` and end at `2`, by
|
980
|
+
length, and see that the Poincaré series matrix predicts the correct
|
981
|
+
numbers::
|
982
|
+
|
983
|
+
sage: [p for p in S.iter_paths_by_length_and_startpoint(1,1) if p.terminal_vertex()==2]
|
984
|
+
[]
|
985
|
+
sage: [p for p in S.iter_paths_by_length_and_startpoint(2,1) if p.terminal_vertex()==2]
|
986
|
+
[c*b]
|
987
|
+
sage: [p for p in S.iter_paths_by_length_and_startpoint(3,1) if p.terminal_vertex()==2]
|
988
|
+
[c*b*f, d*c*b]
|
989
|
+
sage: [p for p in S.iter_paths_by_length_and_startpoint(4,1) if p.terminal_vertex()==2]
|
990
|
+
[c*a*c*b, c*b*e*b, c*b*f*f, d*c*b*f, d*d*c*b]
|
991
|
+
sage: len([p for p in S.iter_paths_by_length_and_startpoint(5,1) if p.terminal_vertex()==2])
|
992
|
+
10
|
993
|
+
sage: len([p for p in S.iter_paths_by_length_and_startpoint(10,1) if p.terminal_vertex()==2])
|
994
|
+
341
|
995
|
+
"""
|
996
|
+
P = ZZ['t']
|
997
|
+
t = P.gen()
|
998
|
+
M = self._quiver.adjacency_matrix()
|
999
|
+
out = ~(1 - M * t)
|
1000
|
+
out.set_immutable()
|
1001
|
+
return out
|
1002
|
+
|
1003
|
+
def all_paths(self, start=None, end=None):
|
1004
|
+
"""
|
1005
|
+
List of all paths between a pair of vertices ``(start, end)``.
|
1006
|
+
|
1007
|
+
INPUT:
|
1008
|
+
|
1009
|
+
- ``start`` -- integer or ``None`` (default: ``None``); the initial
|
1010
|
+
vertex of the paths in the output; if ``None`` is given then
|
1011
|
+
the initial vertex is arbitrary.
|
1012
|
+
- ``end`` -- integer or ``None`` (default: ``None``); the terminal
|
1013
|
+
vertex of the paths in the output; if ``None`` is given then
|
1014
|
+
the terminal vertex is arbitrary
|
1015
|
+
|
1016
|
+
OUTPUT: list of paths, excluding the invalid path
|
1017
|
+
|
1018
|
+
.. TODO::
|
1019
|
+
|
1020
|
+
This currently does not work for quivers with cycles, even if
|
1021
|
+
there are only finitely many paths from ``start`` to ``end``.
|
1022
|
+
|
1023
|
+
.. NOTE::
|
1024
|
+
|
1025
|
+
If there are multiple edges between two vertices, the method
|
1026
|
+
:meth:`sage.graphs.digraph.all_paths` will not differentiate
|
1027
|
+
between them. But this method, which is not for digraphs but for
|
1028
|
+
their path semigroup associated with them, will.
|
1029
|
+
|
1030
|
+
EXAMPLES::
|
1031
|
+
|
1032
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}})
|
1033
|
+
sage: F = Q.path_semigroup()
|
1034
|
+
sage: F.all_paths(1, 3)
|
1035
|
+
[a*d, b*d, c]
|
1036
|
+
|
1037
|
+
If ``start=end`` then we expect only the trivial path at that vertex::
|
1038
|
+
|
1039
|
+
sage: F.all_paths(1, 1)
|
1040
|
+
[e_1]
|
1041
|
+
|
1042
|
+
The empty list is returned if there are no paths between the
|
1043
|
+
given vertices::
|
1044
|
+
|
1045
|
+
sage: F.all_paths(3, 1)
|
1046
|
+
[]
|
1047
|
+
|
1048
|
+
If ``end=None`` then all edge paths beginning at ``start`` are
|
1049
|
+
returned, including the trivial path::
|
1050
|
+
|
1051
|
+
sage: F.all_paths(2)
|
1052
|
+
[e_2, d]
|
1053
|
+
|
1054
|
+
If ``start=None`` then all edge paths ending at ``end`` are
|
1055
|
+
returned, including the trivial path. Note that the two edges
|
1056
|
+
from vertex 1 to vertex 2 count as two different edge paths::
|
1057
|
+
|
1058
|
+
sage: F.all_paths(None, 2)
|
1059
|
+
[a, b, e_2]
|
1060
|
+
sage: F.all_paths(end=2)
|
1061
|
+
[a, b, e_2]
|
1062
|
+
|
1063
|
+
If ``start=end=None`` then all edge paths are returned, including
|
1064
|
+
trivial paths::
|
1065
|
+
|
1066
|
+
sage: F.all_paths()
|
1067
|
+
[e_1, a, b, a*d, b*d, c, e_2, d, e_3]
|
1068
|
+
|
1069
|
+
The vertex given must be a vertex of the quiver::
|
1070
|
+
|
1071
|
+
sage: F.all_paths(1, 4)
|
1072
|
+
Traceback (most recent call last):
|
1073
|
+
...
|
1074
|
+
ValueError: the end vertex 4 is not a vertex of the quiver
|
1075
|
+
|
1076
|
+
If the underlying quiver is cyclic, a :exc:`ValueError`
|
1077
|
+
is raised::
|
1078
|
+
|
1079
|
+
sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 3:{1:['d']}})
|
1080
|
+
sage: F = Q.path_semigroup()
|
1081
|
+
sage: F.all_paths()
|
1082
|
+
Traceback (most recent call last):
|
1083
|
+
...
|
1084
|
+
ValueError: the underlying quiver has cycles, thus, there may be an infinity of directed paths
|
1085
|
+
|
1086
|
+
TESTS:
|
1087
|
+
|
1088
|
+
We check a single edge with a multi-character label::
|
1089
|
+
|
1090
|
+
sage: Q = DiGraph([[1,2,'abc']])
|
1091
|
+
sage: PQ = Q.path_semigroup()
|
1092
|
+
sage: PQ.all_paths(1,2)
|
1093
|
+
[abc]
|
1094
|
+
|
1095
|
+
An example with multiple edges::
|
1096
|
+
|
1097
|
+
sage: Q = DiGraph([[1,2,'abc'], [1,2,'def']], multiedges=True)
|
1098
|
+
sage: PQ = Q.path_semigroup()
|
1099
|
+
sage: PQ.all_paths(1,2)
|
1100
|
+
[abc, def]
|
1101
|
+
"""
|
1102
|
+
# Check that given arguments are vertices
|
1103
|
+
if start is not None and start not in self._quiver:
|
1104
|
+
raise ValueError("the start vertex {} is not a vertex of the quiver".format(start))
|
1105
|
+
if end is not None and end not in self._quiver:
|
1106
|
+
raise ValueError("the end vertex {} is not a vertex of the quiver".format(end))
|
1107
|
+
|
1108
|
+
# Handle quivers with cycles
|
1109
|
+
Q = self._quiver
|
1110
|
+
if not (Q.is_directed_acyclic()):
|
1111
|
+
raise ValueError("the underlying quiver has cycles, thus, there may be an infinity of directed paths")
|
1112
|
+
|
1113
|
+
# Handle start=None
|
1114
|
+
if start is None:
|
1115
|
+
results = []
|
1116
|
+
for v in Q:
|
1117
|
+
results += self.all_paths(v, end)
|
1118
|
+
return results
|
1119
|
+
|
1120
|
+
# Handle end=None
|
1121
|
+
if end is None:
|
1122
|
+
results = []
|
1123
|
+
for v in Q:
|
1124
|
+
results += self.all_paths(start, v)
|
1125
|
+
return results
|
1126
|
+
|
1127
|
+
# Handle the trivial case
|
1128
|
+
if start == end:
|
1129
|
+
return [self.element_class(self, start, end, [])]
|
1130
|
+
|
1131
|
+
# This function will recursively convert a path given in terms of
|
1132
|
+
# vertices to a list of QuiverPaths.
|
1133
|
+
def _v_to_e(path):
|
1134
|
+
if len(path) == 1:
|
1135
|
+
return [self.element_class(self, path[0], path[0], [])]
|
1136
|
+
paths = []
|
1137
|
+
ell = Q.edge_label(path[0], path[1])
|
1138
|
+
if isinstance(ell, str):
|
1139
|
+
for b in _v_to_e(path[1:]):
|
1140
|
+
paths.append(self([(path[0], path[1], ell)]
|
1141
|
+
+ list(b), check=False))
|
1142
|
+
else:
|
1143
|
+
for a in ell:
|
1144
|
+
for b in _v_to_e(path[1:]):
|
1145
|
+
paths.append(self([(path[0], path[1], a)]
|
1146
|
+
+ list(b), check=False))
|
1147
|
+
return paths
|
1148
|
+
|
1149
|
+
# For each vertex path we append the resulting edge paths
|
1150
|
+
result = []
|
1151
|
+
for path in Q.all_paths(start, end):
|
1152
|
+
result += _v_to_e(path)
|
1153
|
+
|
1154
|
+
# The result is all paths from start to end
|
1155
|
+
return result
|