passagemath-modules 10.6.31rc3__cp314-cp314-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.
Potentially problematic release.
This version of passagemath-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31rc3.dist-info/RECORD +807 -0
- passagemath_modules-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-cda90e79.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-7f678fcf.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-82690d50.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_modules.libs/libquadmath-2284e583.so.0.0.0 +0 -0
- sage/algebras/all__sagemath_modules.py +20 -0
- sage/algebras/catalog.py +148 -0
- sage/algebras/clifford_algebra.py +3107 -0
- sage/algebras/clifford_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/clifford_algebra_element.pxd +16 -0
- sage/algebras/clifford_algebra_element.pyx +997 -0
- sage/algebras/commutative_dga.py +4252 -0
- sage/algebras/exterior_algebra_groebner.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/exterior_algebra_groebner.pxd +55 -0
- sage/algebras/exterior_algebra_groebner.pyx +727 -0
- sage/algebras/finite_dimensional_algebras/all.py +2 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
- sage/algebras/finite_gca.py +528 -0
- sage/algebras/group_algebra.py +232 -0
- sage/algebras/lie_algebras/abelian.py +197 -0
- sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
- sage/algebras/lie_algebras/all.py +25 -0
- sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
- sage/algebras/lie_algebras/bch.py +177 -0
- sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
- sage/algebras/lie_algebras/bgg_resolution.py +232 -0
- sage/algebras/lie_algebras/center_uea.py +767 -0
- sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
- sage/algebras/lie_algebras/examples.py +683 -0
- sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
- sage/algebras/lie_algebras/heisenberg.py +820 -0
- sage/algebras/lie_algebras/lie_algebra.py +1562 -0
- sage/algebras/lie_algebras/lie_algebra_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
- sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
- sage/algebras/lie_algebras/morphism.py +661 -0
- sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
- sage/algebras/lie_algebras/onsager.py +1324 -0
- sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
- sage/algebras/lie_algebras/quotient.py +462 -0
- sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
- sage/algebras/lie_algebras/representation.py +1040 -0
- sage/algebras/lie_algebras/structure_coefficients.py +459 -0
- sage/algebras/lie_algebras/subalgebra.py +967 -0
- sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
- sage/algebras/lie_algebras/verma_module.py +1630 -0
- sage/algebras/lie_algebras/virasoro.py +1186 -0
- sage/algebras/octonion_algebra.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/algebras/octonion_algebra.pxd +20 -0
- sage/algebras/octonion_algebra.pyx +987 -0
- sage/algebras/orlik_solomon.py +907 -0
- sage/algebras/orlik_terao.py +779 -0
- sage/algebras/steenrod/all.py +7 -0
- sage/algebras/steenrod/steenrod_algebra.py +4258 -0
- sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
- sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
- sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
- sage/algebras/weyl_algebra.py +1126 -0
- sage/all__sagemath_modules.py +62 -0
- sage/calculus/all__sagemath_modules.py +19 -0
- sage/calculus/expr.py +205 -0
- sage/calculus/integration.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/riemann.pyx +1521 -0
- sage/calculus/test_sympy.py +201 -0
- sage/calculus/transforms/all.py +7 -0
- sage/calculus/transforms/dft.py +844 -0
- sage/calculus/transforms/dwt.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/calculus/transforms/fft.pxd +12 -0
- sage/calculus/transforms/fft.pyx +487 -0
- sage/calculus/wester.py +662 -0
- sage/coding/abstract_code.py +1108 -0
- sage/coding/ag_code.py +868 -0
- sage/coding/ag_code_decoders.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/coding/ag_code_decoders.pyx +2639 -0
- sage/coding/all.py +15 -0
- sage/coding/bch_code.py +494 -0
- sage/coding/binary_code.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/coding/binary_code.pxd +124 -0
- sage/coding/binary_code.pyx +4139 -0
- sage/coding/bounds_catalog.py +43 -0
- sage/coding/channel.py +819 -0
- sage/coding/channels_catalog.py +29 -0
- sage/coding/code_bounds.py +755 -0
- sage/coding/code_constructions.py +804 -0
- sage/coding/codes_catalog.py +111 -0
- sage/coding/cyclic_code.py +1329 -0
- sage/coding/databases.py +316 -0
- sage/coding/decoder.py +373 -0
- sage/coding/decoders_catalog.py +88 -0
- sage/coding/delsarte_bounds.py +709 -0
- sage/coding/encoder.py +390 -0
- sage/coding/encoders_catalog.py +64 -0
- sage/coding/extended_code.py +468 -0
- sage/coding/gabidulin_code.py +1058 -0
- sage/coding/golay_code.py +404 -0
- sage/coding/goppa_code.py +441 -0
- sage/coding/grs_code.py +2371 -0
- sage/coding/guava.py +107 -0
- sage/coding/guruswami_sudan/all.py +1 -0
- sage/coding/guruswami_sudan/gs_decoder.py +897 -0
- sage/coding/guruswami_sudan/interpolation.py +409 -0
- sage/coding/guruswami_sudan/utils.py +176 -0
- sage/coding/hamming_code.py +176 -0
- sage/coding/information_set_decoder.py +1032 -0
- sage/coding/kasami_codes.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/coding/kasami_codes.pyx +351 -0
- sage/coding/linear_code.py +3067 -0
- sage/coding/linear_code_no_metric.py +1354 -0
- sage/coding/linear_rank_metric.py +961 -0
- sage/coding/parity_check_code.py +353 -0
- sage/coding/punctured_code.py +719 -0
- sage/coding/reed_muller_code.py +999 -0
- sage/coding/self_dual_codes.py +942 -0
- sage/coding/source_coding/all.py +2 -0
- sage/coding/source_coding/huffman.py +553 -0
- sage/coding/subfield_subcode.py +423 -0
- sage/coding/two_weight_db.py +399 -0
- sage/combinat/all__sagemath_modules.py +7 -0
- sage/combinat/cartesian_product.py +347 -0
- sage/combinat/family.py +11 -0
- sage/combinat/free_module.py +1977 -0
- sage/combinat/root_system/all.py +147 -0
- sage/combinat/root_system/ambient_space.py +527 -0
- sage/combinat/root_system/associahedron.py +471 -0
- sage/combinat/root_system/braid_move_calculator.py +143 -0
- sage/combinat/root_system/braid_orbit.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/combinat/root_system/braid_orbit.pyx +144 -0
- sage/combinat/root_system/branching_rules.py +2301 -0
- sage/combinat/root_system/cartan_matrix.py +1245 -0
- sage/combinat/root_system/cartan_type.py +3069 -0
- sage/combinat/root_system/coxeter_group.py +162 -0
- sage/combinat/root_system/coxeter_matrix.py +1261 -0
- sage/combinat/root_system/coxeter_type.py +681 -0
- sage/combinat/root_system/dynkin_diagram.py +900 -0
- sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
- sage/combinat/root_system/fundamental_group.py +795 -0
- sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
- sage/combinat/root_system/integrable_representations.py +1227 -0
- sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
- sage/combinat/root_system/pieri_factors.py +1147 -0
- sage/combinat/root_system/plot.py +1615 -0
- sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
- sage/combinat/root_system/root_lattice_realizations.py +4628 -0
- sage/combinat/root_system/root_space.py +487 -0
- sage/combinat/root_system/root_system.py +882 -0
- sage/combinat/root_system/type_A.py +348 -0
- sage/combinat/root_system/type_A_affine.py +227 -0
- sage/combinat/root_system/type_A_infinity.py +241 -0
- sage/combinat/root_system/type_B.py +347 -0
- sage/combinat/root_system/type_BC_affine.py +287 -0
- sage/combinat/root_system/type_B_affine.py +216 -0
- sage/combinat/root_system/type_C.py +317 -0
- sage/combinat/root_system/type_C_affine.py +188 -0
- sage/combinat/root_system/type_D.py +357 -0
- sage/combinat/root_system/type_D_affine.py +208 -0
- sage/combinat/root_system/type_E.py +641 -0
- sage/combinat/root_system/type_E_affine.py +231 -0
- sage/combinat/root_system/type_F.py +387 -0
- sage/combinat/root_system/type_F_affine.py +137 -0
- sage/combinat/root_system/type_G.py +293 -0
- sage/combinat/root_system/type_G_affine.py +132 -0
- sage/combinat/root_system/type_H.py +105 -0
- sage/combinat/root_system/type_I.py +110 -0
- sage/combinat/root_system/type_Q.py +150 -0
- sage/combinat/root_system/type_affine.py +509 -0
- sage/combinat/root_system/type_dual.py +704 -0
- sage/combinat/root_system/type_folded.py +301 -0
- sage/combinat/root_system/type_marked.py +748 -0
- sage/combinat/root_system/type_reducible.py +601 -0
- sage/combinat/root_system/type_relabel.py +730 -0
- sage/combinat/root_system/type_super_A.py +837 -0
- sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
- sage/combinat/root_system/weight_space.py +639 -0
- sage/combinat/root_system/weyl_characters.py +2238 -0
- sage/crypto/__init__.py +4 -0
- sage/crypto/all.py +28 -0
- sage/crypto/block_cipher/all.py +7 -0
- sage/crypto/block_cipher/des.py +1065 -0
- sage/crypto/block_cipher/miniaes.py +2171 -0
- sage/crypto/block_cipher/present.py +909 -0
- sage/crypto/block_cipher/sdes.py +1527 -0
- sage/crypto/boolean_function.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/crypto/boolean_function.pxd +10 -0
- sage/crypto/boolean_function.pyx +1487 -0
- sage/crypto/cipher.py +78 -0
- sage/crypto/classical.py +3668 -0
- sage/crypto/classical_cipher.py +569 -0
- sage/crypto/cryptosystem.py +387 -0
- sage/crypto/key_exchange/all.py +7 -0
- sage/crypto/key_exchange/catalog.py +24 -0
- sage/crypto/key_exchange/diffie_hellman.py +323 -0
- sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
- sage/crypto/lattice.py +312 -0
- sage/crypto/lfsr.py +295 -0
- sage/crypto/lwe.py +840 -0
- sage/crypto/mq/__init__.py +4 -0
- sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
- sage/crypto/mq/rijndael_gf.py +2345 -0
- sage/crypto/mq/sbox.py +7 -0
- sage/crypto/mq/sr.py +3344 -0
- sage/crypto/public_key/all.py +5 -0
- sage/crypto/public_key/blum_goldwasser.py +776 -0
- sage/crypto/sbox.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/crypto/sbox.pyx +2090 -0
- sage/crypto/sboxes.py +2090 -0
- sage/crypto/stream.py +390 -0
- sage/crypto/stream_cipher.py +297 -0
- sage/crypto/util.py +519 -0
- sage/ext/all__sagemath_modules.py +1 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_modules.py +2 -0
- sage/ext/interpreters/wrapper_cc.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_cc.pxd +30 -0
- sage/ext/interpreters/wrapper_cc.pyx +252 -0
- sage/ext/interpreters/wrapper_cdf.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_cdf.pxd +26 -0
- sage/ext/interpreters/wrapper_cdf.pyx +245 -0
- sage/ext/interpreters/wrapper_rdf.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_rdf.pxd +23 -0
- sage/ext/interpreters/wrapper_rdf.pyx +221 -0
- sage/ext/interpreters/wrapper_rr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/ext/interpreters/wrapper_rr.pxd +28 -0
- sage/ext/interpreters/wrapper_rr.pyx +335 -0
- sage/geometry/all__sagemath_modules.py +5 -0
- sage/geometry/toric_lattice.py +1745 -0
- sage/geometry/toric_lattice_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/geometry/toric_lattice_element.pyx +432 -0
- sage/groups/abelian_gps/abelian_group.py +1925 -0
- sage/groups/abelian_gps/abelian_group_element.py +164 -0
- sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
- sage/groups/abelian_gps/dual_abelian_group.py +421 -0
- sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
- sage/groups/abelian_gps/element_base.py +341 -0
- sage/groups/abelian_gps/values.py +488 -0
- sage/groups/additive_abelian/additive_abelian_group.py +476 -0
- sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
- sage/groups/additive_abelian/all.py +4 -0
- sage/groups/additive_abelian/qmodnz.py +231 -0
- sage/groups/additive_abelian/qmodnz_element.py +349 -0
- sage/groups/affine_gps/affine_group.py +535 -0
- sage/groups/affine_gps/all.py +1 -0
- sage/groups/affine_gps/catalog.py +17 -0
- sage/groups/affine_gps/euclidean_group.py +246 -0
- sage/groups/affine_gps/group_element.py +562 -0
- sage/groups/all__sagemath_modules.py +12 -0
- sage/groups/galois_group.py +479 -0
- sage/groups/matrix_gps/all.py +4 -0
- sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
- sage/groups/matrix_gps/catalog.py +26 -0
- sage/groups/matrix_gps/coxeter_group.py +927 -0
- sage/groups/matrix_gps/finitely_generated.py +487 -0
- sage/groups/matrix_gps/group_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/groups/matrix_gps/group_element.pxd +11 -0
- sage/groups/matrix_gps/group_element.pyx +431 -0
- sage/groups/matrix_gps/linear.py +440 -0
- sage/groups/matrix_gps/matrix_group.py +617 -0
- sage/groups/matrix_gps/named_group.py +296 -0
- sage/groups/matrix_gps/orthogonal.py +544 -0
- sage/groups/matrix_gps/symplectic.py +251 -0
- sage/groups/matrix_gps/unitary.py +436 -0
- sage/groups/misc_gps/all__sagemath_modules.py +1 -0
- sage/groups/misc_gps/argument_groups.py +1905 -0
- sage/groups/misc_gps/imaginary_groups.py +479 -0
- sage/groups/perm_gps/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
- sage/homology/algebraic_topological_model.py +595 -0
- sage/homology/all.py +2 -0
- sage/homology/all__sagemath_modules.py +8 -0
- sage/homology/chain_complex.py +2148 -0
- sage/homology/chain_complex_homspace.py +165 -0
- sage/homology/chain_complex_morphism.py +629 -0
- sage/homology/chain_homotopy.py +604 -0
- sage/homology/chains.py +653 -0
- sage/homology/free_resolution.py +923 -0
- sage/homology/graded_resolution.py +567 -0
- sage/homology/hochschild_complex.py +756 -0
- sage/homology/homology_group.py +188 -0
- sage/homology/homology_morphism.py +422 -0
- sage/homology/homology_vector_space_with_basis.py +1454 -0
- sage/homology/koszul_complex.py +169 -0
- sage/homology/matrix_utils.py +205 -0
- sage/libs/all__sagemath_modules.py +1 -0
- sage/libs/gsl/__init__.py +1 -0
- sage/libs/gsl/airy.pxd +56 -0
- sage/libs/gsl/all.pxd +66 -0
- sage/libs/gsl/array.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/gsl/array.pxd +5 -0
- sage/libs/gsl/array.pyx +102 -0
- sage/libs/gsl/bessel.pxd +208 -0
- sage/libs/gsl/blas.pxd +116 -0
- sage/libs/gsl/blas_types.pxd +34 -0
- sage/libs/gsl/block.pxd +52 -0
- sage/libs/gsl/chebyshev.pxd +37 -0
- sage/libs/gsl/clausen.pxd +12 -0
- sage/libs/gsl/combination.pxd +47 -0
- sage/libs/gsl/complex.pxd +151 -0
- sage/libs/gsl/coulomb.pxd +30 -0
- sage/libs/gsl/coupling.pxd +21 -0
- sage/libs/gsl/dawson.pxd +12 -0
- sage/libs/gsl/debye.pxd +24 -0
- sage/libs/gsl/dilog.pxd +14 -0
- sage/libs/gsl/eigen.pxd +46 -0
- sage/libs/gsl/elementary.pxd +12 -0
- sage/libs/gsl/ellint.pxd +48 -0
- sage/libs/gsl/elljac.pxd +8 -0
- sage/libs/gsl/erf.pxd +32 -0
- sage/libs/gsl/errno.pxd +26 -0
- sage/libs/gsl/exp.pxd +44 -0
- sage/libs/gsl/expint.pxd +44 -0
- sage/libs/gsl/fermi_dirac.pxd +44 -0
- sage/libs/gsl/fft.pxd +121 -0
- sage/libs/gsl/fit.pxd +50 -0
- sage/libs/gsl/gamma.pxd +94 -0
- sage/libs/gsl/gegenbauer.pxd +26 -0
- sage/libs/gsl/histogram.pxd +176 -0
- sage/libs/gsl/hyperg.pxd +52 -0
- sage/libs/gsl/integration.pxd +69 -0
- sage/libs/gsl/interp.pxd +109 -0
- sage/libs/gsl/laguerre.pxd +24 -0
- sage/libs/gsl/lambert.pxd +16 -0
- sage/libs/gsl/legendre.pxd +90 -0
- sage/libs/gsl/linalg.pxd +185 -0
- sage/libs/gsl/log.pxd +26 -0
- sage/libs/gsl/math.pxd +43 -0
- sage/libs/gsl/matrix.pxd +143 -0
- sage/libs/gsl/matrix_complex.pxd +130 -0
- sage/libs/gsl/min.pxd +67 -0
- sage/libs/gsl/monte.pxd +56 -0
- sage/libs/gsl/ntuple.pxd +32 -0
- sage/libs/gsl/odeiv.pxd +70 -0
- sage/libs/gsl/permutation.pxd +78 -0
- sage/libs/gsl/poly.pxd +40 -0
- sage/libs/gsl/pow_int.pxd +12 -0
- sage/libs/gsl/psi.pxd +28 -0
- sage/libs/gsl/qrng.pxd +29 -0
- sage/libs/gsl/random.pxd +257 -0
- sage/libs/gsl/rng.pxd +100 -0
- sage/libs/gsl/roots.pxd +72 -0
- sage/libs/gsl/sort.pxd +36 -0
- sage/libs/gsl/statistics.pxd +59 -0
- sage/libs/gsl/sum.pxd +55 -0
- sage/libs/gsl/synchrotron.pxd +16 -0
- sage/libs/gsl/transport.pxd +24 -0
- sage/libs/gsl/trig.pxd +58 -0
- sage/libs/gsl/types.pxd +137 -0
- sage/libs/gsl/vector.pxd +101 -0
- sage/libs/gsl/vector_complex.pxd +83 -0
- sage/libs/gsl/wavelet.pxd +49 -0
- sage/libs/gsl/zeta.pxd +28 -0
- sage/libs/mpc/__init__.pxd +114 -0
- sage/libs/mpc/types.pxd +28 -0
- sage/libs/mpfr/__init__.pxd +299 -0
- sage/libs/mpfr/types.pxd +26 -0
- sage/libs/mpmath/__init__.py +1 -0
- sage/libs/mpmath/all.py +27 -0
- sage/libs/mpmath/all__sagemath_modules.py +1 -0
- sage/libs/mpmath/utils.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/action.pxd +26 -0
- sage/matrix/action.pyx +596 -0
- sage/matrix/all.py +9 -0
- sage/matrix/args.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/args.pxd +144 -0
- sage/matrix/args.pyx +1668 -0
- sage/matrix/benchmark.py +1258 -0
- sage/matrix/berlekamp_massey.py +95 -0
- sage/matrix/compute_J_ideal.py +926 -0
- sage/matrix/constructor.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_cdv.pxd +4 -0
- sage/matrix/matrix_cdv.pyx +93 -0
- sage/matrix/matrix_complex_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_complex_double_dense.pxd +5 -0
- sage/matrix/matrix_complex_double_dense.pyx +98 -0
- sage/matrix/matrix_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_dense.pxd +5 -0
- sage/matrix/matrix_dense.pyx +343 -0
- sage/matrix/matrix_domain_dense.pxd +5 -0
- sage/matrix/matrix_domain_sparse.pxd +5 -0
- sage/matrix/matrix_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_double_dense.pxd +7 -0
- sage/matrix/matrix_double_dense.pyx +3906 -0
- sage/matrix/matrix_double_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_double_sparse.pxd +6 -0
- sage/matrix/matrix_double_sparse.pyx +248 -0
- sage/matrix/matrix_generic_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_generic_dense.pxd +7 -0
- sage/matrix/matrix_generic_dense.pyx +354 -0
- sage/matrix/matrix_generic_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_generic_sparse.pxd +7 -0
- sage/matrix/matrix_generic_sparse.pyx +461 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
- sage/matrix/matrix_misc.py +313 -0
- sage/matrix/matrix_numpy_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_numpy_dense.pxd +14 -0
- sage/matrix/matrix_numpy_dense.pyx +450 -0
- sage/matrix/matrix_numpy_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
- sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
- sage/matrix/matrix_polynomial_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_polynomial_dense.pxd +5 -0
- sage/matrix/matrix_polynomial_dense.pyx +5341 -0
- sage/matrix/matrix_real_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_real_double_dense.pxd +7 -0
- sage/matrix/matrix_real_double_dense.pyx +122 -0
- sage/matrix/matrix_space.py +2848 -0
- sage/matrix/matrix_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/misc_mpfr.pyx +80 -0
- sage/matrix/operation_table.py +1182 -0
- sage/matrix/special.py +3666 -0
- sage/matrix/strassen.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matrix/strassen.pyx +851 -0
- sage/matrix/symplectic_basis.py +541 -0
- sage/matrix/template.pxd +6 -0
- sage/matrix/tests.py +71 -0
- sage/matroids/advanced.py +77 -0
- sage/matroids/all.py +13 -0
- sage/matroids/basis_exchange_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/basis_exchange_matroid.pxd +96 -0
- sage/matroids/basis_exchange_matroid.pyx +2344 -0
- sage/matroids/basis_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/basis_matroid.pxd +45 -0
- sage/matroids/basis_matroid.pyx +1217 -0
- sage/matroids/catalog.py +44 -0
- sage/matroids/chow_ring.py +473 -0
- sage/matroids/chow_ring_ideal.py +849 -0
- sage/matroids/circuit_closures_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/circuit_closures_matroid.pxd +16 -0
- sage/matroids/circuit_closures_matroid.pyx +559 -0
- sage/matroids/circuits_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/circuits_matroid.pxd +38 -0
- sage/matroids/circuits_matroid.pyx +947 -0
- sage/matroids/constructor.py +1086 -0
- sage/matroids/database_collections.py +365 -0
- sage/matroids/database_matroids.py +5338 -0
- sage/matroids/dual_matroid.py +583 -0
- sage/matroids/extension.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/flats_matroid.pxd +28 -0
- sage/matroids/flats_matroid.pyx +715 -0
- sage/matroids/gammoid.py +600 -0
- sage/matroids/graphic_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/matroid.pxd +243 -0
- sage/matroids/matroid.pyx +8759 -0
- sage/matroids/matroids_catalog.py +190 -0
- sage/matroids/matroids_plot_helpers.py +890 -0
- sage/matroids/minor_matroid.py +480 -0
- sage/matroids/minorfix.h +9 -0
- sage/matroids/named_matroids.py +5 -0
- sage/matroids/rank_matroid.py +268 -0
- sage/matroids/set_system.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/matroids/unpickling.pyx +843 -0
- sage/matroids/utilities.py +809 -0
- sage/misc/all__sagemath_modules.py +20 -0
- sage/misc/c3.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/misc/c3.pyx +238 -0
- sage/misc/compat.py +87 -0
- sage/misc/element_with_label.py +173 -0
- sage/misc/func_persist.py +79 -0
- sage/misc/pickle_old.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/misc/pickle_old.pyx +19 -0
- sage/misc/proof.py +7 -0
- sage/misc/replace_dot_all.py +472 -0
- sage/misc/sagedoc_conf.py +168 -0
- sage/misc/sphinxify.py +167 -0
- sage/misc/test_class_pickling.py +85 -0
- sage/modules/all.py +42 -0
- sage/modules/complex_double_vector.py +25 -0
- sage/modules/diamond_cutting.py +380 -0
- sage/modules/fg_pid/all.py +1 -0
- sage/modules/fg_pid/fgp_element.py +456 -0
- sage/modules/fg_pid/fgp_module.py +2091 -0
- sage/modules/fg_pid/fgp_morphism.py +550 -0
- sage/modules/filtered_vector_space.py +1271 -0
- sage/modules/finite_submodule_iter.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/finite_submodule_iter.pxd +27 -0
- sage/modules/finite_submodule_iter.pyx +452 -0
- sage/modules/fp_graded/all.py +1 -0
- sage/modules/fp_graded/element.py +346 -0
- sage/modules/fp_graded/free_element.py +298 -0
- sage/modules/fp_graded/free_homspace.py +53 -0
- sage/modules/fp_graded/free_module.py +1060 -0
- sage/modules/fp_graded/free_morphism.py +217 -0
- sage/modules/fp_graded/homspace.py +563 -0
- sage/modules/fp_graded/module.py +1340 -0
- sage/modules/fp_graded/morphism.py +1990 -0
- sage/modules/fp_graded/steenrod/all.py +1 -0
- sage/modules/fp_graded/steenrod/homspace.py +65 -0
- sage/modules/fp_graded/steenrod/module.py +477 -0
- sage/modules/fp_graded/steenrod/morphism.py +404 -0
- sage/modules/fp_graded/steenrod/profile.py +241 -0
- sage/modules/free_module.py +8447 -0
- sage/modules/free_module_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/free_module_element.pxd +22 -0
- sage/modules/free_module_element.pyx +5445 -0
- sage/modules/free_module_homspace.py +369 -0
- sage/modules/free_module_integer.py +896 -0
- sage/modules/free_module_morphism.py +823 -0
- sage/modules/free_module_pseudohomspace.py +352 -0
- sage/modules/free_module_pseudomorphism.py +578 -0
- sage/modules/free_quadratic_module.py +1706 -0
- sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
- sage/modules/matrix_morphism.py +1745 -0
- sage/modules/misc.py +103 -0
- sage/modules/module_functors.py +192 -0
- sage/modules/multi_filtered_vector_space.py +719 -0
- sage/modules/ore_module.py +2208 -0
- sage/modules/ore_module_element.py +178 -0
- sage/modules/ore_module_homspace.py +147 -0
- sage/modules/ore_module_morphism.py +968 -0
- sage/modules/quotient_module.py +699 -0
- sage/modules/real_double_vector.py +22 -0
- sage/modules/submodule.py +255 -0
- sage/modules/tensor_operations.py +567 -0
- sage/modules/torsion_quadratic_module.py +1352 -0
- sage/modules/tutorial_free_modules.py +248 -0
- sage/modules/vector_complex_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_complex_double_dense.pxd +6 -0
- sage/modules/vector_complex_double_dense.pyx +117 -0
- sage/modules/vector_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_double_dense.pxd +6 -0
- sage/modules/vector_double_dense.pyx +604 -0
- sage/modules/vector_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_integer_dense.pxd +15 -0
- sage/modules/vector_integer_dense.pyx +361 -0
- sage/modules/vector_integer_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_integer_sparse.pxd +29 -0
- sage/modules/vector_integer_sparse.pyx +406 -0
- sage/modules/vector_modn_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_modn_dense.pxd +12 -0
- sage/modules/vector_modn_dense.pyx +394 -0
- sage/modules/vector_modn_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_modn_sparse.pxd +21 -0
- sage/modules/vector_modn_sparse.pyx +298 -0
- sage/modules/vector_numpy_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_numpy_dense.pxd +15 -0
- sage/modules/vector_numpy_dense.pyx +304 -0
- sage/modules/vector_numpy_integer_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_numpy_integer_dense.pxd +7 -0
- sage/modules/vector_numpy_integer_dense.pyx +54 -0
- sage/modules/vector_rational_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_rational_dense.pxd +15 -0
- sage/modules/vector_rational_dense.pyx +387 -0
- sage/modules/vector_rational_sparse.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_rational_sparse.pxd +30 -0
- sage/modules/vector_rational_sparse.pyx +413 -0
- sage/modules/vector_real_double_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_real_double_dense.pxd +6 -0
- sage/modules/vector_real_double_dense.pyx +126 -0
- sage/modules/vector_space_homspace.py +430 -0
- sage/modules/vector_space_morphism.py +989 -0
- sage/modules/with_basis/all.py +15 -0
- sage/modules/with_basis/cell_module.py +494 -0
- sage/modules/with_basis/indexed_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/modules/with_basis/indexed_element.pxd +13 -0
- sage/modules/with_basis/indexed_element.pyx +1058 -0
- sage/modules/with_basis/invariant.py +1075 -0
- sage/modules/with_basis/morphism.py +1636 -0
- sage/modules/with_basis/representation.py +2939 -0
- sage/modules/with_basis/subquotient.py +685 -0
- sage/numerical/all__sagemath_modules.py +6 -0
- sage/numerical/gauss_legendre.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/numerical/gauss_legendre.pyx +381 -0
- sage/numerical/optimize.py +910 -0
- sage/probability/all.py +10 -0
- sage/probability/probability_distribution.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/probability/probability_distribution.pyx +1242 -0
- sage/probability/random_variable.py +411 -0
- sage/quadratic_forms/all.py +4 -0
- sage/quadratic_forms/all__sagemath_modules.py +15 -0
- sage/quadratic_forms/binary_qf.py +2042 -0
- sage/quadratic_forms/bqf_class_group.py +748 -0
- sage/quadratic_forms/constructions.py +93 -0
- sage/quadratic_forms/count_local_2.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/quadratic_forms/count_local_2.pyx +365 -0
- sage/quadratic_forms/extras.py +195 -0
- sage/quadratic_forms/quadratic_form.py +1753 -0
- sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
- sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
- sage/quadratic_forms/quadratic_form__evaluate.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
- sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
- sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
- sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
- sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
- sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
- sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
- sage/quadratic_forms/quadratic_form__theta.py +352 -0
- sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
- sage/quadratic_forms/random_quadraticform.py +209 -0
- sage/quadratic_forms/ternary.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/quadratic_forms/ternary.pyx +1154 -0
- sage/quadratic_forms/ternary_qf.py +2027 -0
- sage/rings/all__sagemath_modules.py +28 -0
- sage/rings/asymptotic/all__sagemath_modules.py +1 -0
- sage/rings/asymptotic/misc.py +1252 -0
- sage/rings/cc.py +4 -0
- sage/rings/cfinite_sequence.py +1306 -0
- sage/rings/complex_conversion.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/complex_mpfr.pxd +18 -0
- sage/rings/complex_mpfr.pyx +3602 -0
- sage/rings/derivation.py +2334 -0
- sage/rings/finite_rings/all__sagemath_modules.py +1 -0
- sage/rings/finite_rings/maps_finite_field.py +191 -0
- sage/rings/function_field/all__sagemath_modules.py +8 -0
- sage/rings/function_field/derivations.py +102 -0
- sage/rings/function_field/derivations_rational.py +132 -0
- sage/rings/function_field/differential.py +853 -0
- sage/rings/function_field/divisor.py +1107 -0
- sage/rings/function_field/drinfeld_modules/action.py +199 -0
- sage/rings/function_field/drinfeld_modules/all.py +1 -0
- sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
- sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
- sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
- sage/rings/function_field/drinfeld_modules/homset.py +420 -0
- sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
- sage/rings/function_field/hermite_form_polynomial.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/function_field/khuri_makdisi.pyx +935 -0
- sage/rings/invariants/all.py +4 -0
- sage/rings/invariants/invariant_theory.py +4597 -0
- sage/rings/invariants/reconstruction.py +395 -0
- sage/rings/polynomial/all__sagemath_modules.py +17 -0
- sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
- sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
- sage/rings/polynomial/ore_function_element.py +952 -0
- sage/rings/polynomial/ore_function_field.py +1028 -0
- sage/rings/polynomial/ore_polynomial_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
- sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
- sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
- sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
- sage/rings/polynomial/skew_polynomial_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
- sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
- sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
- sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
- sage/rings/polynomial/skew_polynomial_ring.py +908 -0
- sage/rings/real_double_element_gsl.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/real_double_element_gsl.pxd +8 -0
- sage/rings/real_double_element_gsl.pyx +794 -0
- sage/rings/real_field.py +58 -0
- sage/rings/real_mpfr.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension_conversion.pxd +16 -0
- sage/rings/ring_extension_conversion.pyx +462 -0
- sage/rings/ring_extension_element.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension_element.pxd +21 -0
- sage/rings/ring_extension_element.pyx +1635 -0
- sage/rings/ring_extension_homset.py +64 -0
- sage/rings/ring_extension_morphism.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/rings/ring_extension_morphism.pxd +35 -0
- sage/rings/ring_extension_morphism.pyx +920 -0
- sage/schemes/all__sagemath_modules.py +1 -0
- sage/schemes/projective/all__sagemath_modules.py +1 -0
- sage/schemes/projective/coherent_sheaf.py +300 -0
- sage/schemes/projective/cohomology.py +510 -0
- sage/stats/all.py +15 -0
- sage/stats/basic_stats.py +489 -0
- sage/stats/distributions/all.py +7 -0
- sage/stats/distributions/catalog.py +34 -0
- sage/stats/distributions/dgs.h +50 -0
- sage/stats/distributions/dgs.pxd +111 -0
- sage/stats/distributions/dgs_bern.h +400 -0
- sage/stats/distributions/dgs_gauss.h +614 -0
- sage/stats/distributions/dgs_misc.h +104 -0
- sage/stats/distributions/discrete_gaussian_integer.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
- sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
- sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
- sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
- sage/stats/hmm/all.py +15 -0
- sage/stats/hmm/chmm.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/intlist.pxd +14 -0
- sage/stats/intlist.pyx +588 -0
- sage/stats/r.py +49 -0
- sage/stats/time_series.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,1990 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
# sage.doctest: needs sage.combinat
|
|
3
|
+
r"""
|
|
4
|
+
Homomorphisms of finitely presented graded modules
|
|
5
|
+
|
|
6
|
+
AUTHORS:
|
|
7
|
+
|
|
8
|
+
- Robert R. Bruner, Michael J. Catanzaro (2012): Initial version.
|
|
9
|
+
- Sverre Lunoee--Nielsen and Koen van Woerden (2019-11-29): Updated the
|
|
10
|
+
original software to Sage version 8.9.
|
|
11
|
+
- Sverre Lunoee--Nielsen (2020-07-01): Refactored the code and added
|
|
12
|
+
new documentation and tests.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# *****************************************************************************
|
|
16
|
+
# Copyright (C) 2011 Robert R. Bruner <rrb@math.wayne.edu>
|
|
17
|
+
# and Michael J. Catanzaro <mike@math.wayne.edu>
|
|
18
|
+
#
|
|
19
|
+
# This program is free software: you can redistribute it and/or modify
|
|
20
|
+
# it under the terms of the GNU General Public License as published by
|
|
21
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
22
|
+
# (at your option) any later version.
|
|
23
|
+
# https://www.gnu.org/licenses/
|
|
24
|
+
# ****************************************************************************
|
|
25
|
+
|
|
26
|
+
from inspect import isfunction
|
|
27
|
+
|
|
28
|
+
from sage.categories.homset import End, Hom
|
|
29
|
+
from sage.categories.morphism import Morphism
|
|
30
|
+
from sage.misc.cachefunc import cached_method, cached_function
|
|
31
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
|
32
|
+
from sage.rings.infinity import infinity
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _create_relations_matrix(module, relations, source_degs, target_degs):
|
|
36
|
+
r"""
|
|
37
|
+
The action by the given relations can be written as multiplication by
|
|
38
|
+
the matrix `R = (r_{ij})_{i,j}` where each entry is an algebra element and
|
|
39
|
+
each row in the matrix contains the coefficients of a single relation.
|
|
40
|
+
|
|
41
|
+
For a given source degree, `n`, the multiplication by `r_{ij}` restricts to
|
|
42
|
+
a linear transformation `M_n\to M_{n + \deg(r_{ij})}`. This function returns
|
|
43
|
+
the matrix of linear transformations gotten by restricting `R` to the given
|
|
44
|
+
source degrees.
|
|
45
|
+
|
|
46
|
+
INPUT:
|
|
47
|
+
|
|
48
|
+
- ``module`` -- the module where the relations acts
|
|
49
|
+
- ``relations`` -- list of lists of algebra coefficients defining the
|
|
50
|
+
matrix `R`
|
|
51
|
+
- ``source_degs`` -- list of integer degrees; its length should be
|
|
52
|
+
equal to the number of columns of `R`
|
|
53
|
+
- ``target_degs`` -- list of integer degrees; its length should be
|
|
54
|
+
equal to the number of rows of `R`
|
|
55
|
+
|
|
56
|
+
Furthermore must the degrees given by the input satisfy the following::
|
|
57
|
+
|
|
58
|
+
source_degs[j] + deg(r[i,j]) = target_degs[i]
|
|
59
|
+
|
|
60
|
+
for all `i, j`.
|
|
61
|
+
|
|
62
|
+
OUTPUT:
|
|
63
|
+
|
|
64
|
+
- ``block_matrix`` -- list of lists representing a matrix of linear
|
|
65
|
+
transformations `(T_{ij})`. Each transformtion `T_{ij}` is the linear map
|
|
66
|
+
representing multiplication by the coefficient `r_{ij}` restricted to
|
|
67
|
+
the module elements of degree ``source_degs[j]``.
|
|
68
|
+
- ``R`` -- a matrix representing ``block_matrix`` as a single linear
|
|
69
|
+
transformation
|
|
70
|
+
|
|
71
|
+
TESTS::
|
|
72
|
+
|
|
73
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
74
|
+
sage: from sage.modules.fp_graded.morphism import _create_relations_matrix
|
|
75
|
+
sage: A = SteenrodAlgebra(p=2)
|
|
76
|
+
sage: M = FPModule(A, [0], [[0]])
|
|
77
|
+
sage: blocks, R = _create_relations_matrix(M, [[Sq(2)]], [4], [6])
|
|
78
|
+
|
|
79
|
+
sage: blocks
|
|
80
|
+
[[Vector space morphism represented by the matrix:
|
|
81
|
+
[0 1 0]
|
|
82
|
+
[0 1 1]
|
|
83
|
+
Domain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
|
|
84
|
+
V: Vector space of dimension 2 over Finite Field of size 2
|
|
85
|
+
W: Vector space of degree 2 and dimension 0 over Finite Field of size 2
|
|
86
|
+
Basis matrix:
|
|
87
|
+
[]
|
|
88
|
+
Codomain: Vector space quotient V/W of dimension 3 over Finite Field of size 2 where
|
|
89
|
+
V: Vector space of dimension 3 over Finite Field of size 2
|
|
90
|
+
W: Vector space of degree 3 and dimension 0 over Finite Field of size 2
|
|
91
|
+
Basis matrix:
|
|
92
|
+
[]]]
|
|
93
|
+
|
|
94
|
+
sage: R
|
|
95
|
+
[0 0]
|
|
96
|
+
[1 1]
|
|
97
|
+
[0 1]
|
|
98
|
+
"""
|
|
99
|
+
from sage.matrix.constructor import matrix
|
|
100
|
+
|
|
101
|
+
if not relations:
|
|
102
|
+
raise ValueError('no relations given, can not build matrix')
|
|
103
|
+
|
|
104
|
+
# Create the block matrix of linear transformations.
|
|
105
|
+
block_matrix = []
|
|
106
|
+
for i, r_i in enumerate(relations):
|
|
107
|
+
row = []
|
|
108
|
+
target_space = module.vector_presentation(target_degs[i])
|
|
109
|
+
|
|
110
|
+
for j, r_ij in enumerate(r_i):
|
|
111
|
+
|
|
112
|
+
values = []
|
|
113
|
+
for b in module.basis_elements(source_degs[j]):
|
|
114
|
+
w = r_ij * b
|
|
115
|
+
values.append(
|
|
116
|
+
target_space.zero() if w.is_zero() else w.vector_presentation())
|
|
117
|
+
|
|
118
|
+
row.append(
|
|
119
|
+
Hom(module.vector_presentation(source_degs[j]), target_space)(values))
|
|
120
|
+
|
|
121
|
+
block_matrix.append(row)
|
|
122
|
+
|
|
123
|
+
# Deal with the case of zero dimensional matrices first.
|
|
124
|
+
total_source_dim = 0
|
|
125
|
+
for el in block_matrix[0]:
|
|
126
|
+
total_source_dim += el.domain().dimension()
|
|
127
|
+
total_target_dim = 0
|
|
128
|
+
for row in block_matrix:
|
|
129
|
+
total_target_dim += row[0].codomain().dimension()
|
|
130
|
+
if total_source_dim == 0:
|
|
131
|
+
return block_matrix, matrix(total_target_dim, 0)
|
|
132
|
+
elif total_target_dim == 0:
|
|
133
|
+
return block_matrix, matrix(0, total_source_dim)
|
|
134
|
+
|
|
135
|
+
# Create a matrix from the matrix of linear transformations.
|
|
136
|
+
entries = []
|
|
137
|
+
for j, block in enumerate(block_matrix[0]):
|
|
138
|
+
for n in range(block.domain().dimension()):
|
|
139
|
+
column = []
|
|
140
|
+
for i in range(len(block_matrix)):
|
|
141
|
+
lin_trans = block_matrix[i][j]
|
|
142
|
+
column += lin_trans(lin_trans.domain().basis()[n])
|
|
143
|
+
entries.append(column)
|
|
144
|
+
|
|
145
|
+
return block_matrix, matrix(module.base_ring().base_ring(), entries).transpose()
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class FPModuleMorphism(Morphism):
|
|
149
|
+
r"""
|
|
150
|
+
Create a homomorphism between finitely presented graded modules.
|
|
151
|
+
|
|
152
|
+
INPUT:
|
|
153
|
+
|
|
154
|
+
- ``parent`` -- a homspace of finitely presented graded modules
|
|
155
|
+
- ``values`` -- list of elements in the codomain; each element
|
|
156
|
+
corresponds to a module generator in the domain
|
|
157
|
+
- ``check`` -- boolean (default: ``True``); if ``True``, check
|
|
158
|
+
that the morphism is well-defined
|
|
159
|
+
|
|
160
|
+
TESTS::
|
|
161
|
+
|
|
162
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
163
|
+
|
|
164
|
+
Trying to map the generators of a non-free module into a
|
|
165
|
+
free module::
|
|
166
|
+
|
|
167
|
+
sage: A = SteenrodAlgebra(2)
|
|
168
|
+
sage: F = FPModule(A, [2,3])
|
|
169
|
+
sage: Q = FPModule(A, [2,3], relations=[[Sq(6), Sq(5)]])
|
|
170
|
+
sage: v1 = Q((Sq(1), 0))
|
|
171
|
+
sage: v2 = Q((0, 1))
|
|
172
|
+
sage: m = Hom(F, Q)( (v1, v2) )
|
|
173
|
+
Traceback (most recent call last):
|
|
174
|
+
...
|
|
175
|
+
ValueError: ill-defined homomorphism: degrees do not match
|
|
176
|
+
|
|
177
|
+
Trying to map the generators of a non-free module into a
|
|
178
|
+
free module::
|
|
179
|
+
|
|
180
|
+
sage: w = Hom(Q, F)( (F((1, 0)), F((0, 1))) )
|
|
181
|
+
Traceback (most recent call last):
|
|
182
|
+
...
|
|
183
|
+
ValueError: relation Sq(6)*g[2] + Sq(5)*g[3] is not sent to zero
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
def __init__(self, parent, values, check=True):
|
|
187
|
+
r"""
|
|
188
|
+
Create a homomorphism between finitely presented graded modules.
|
|
189
|
+
|
|
190
|
+
OUTPUT:
|
|
191
|
+
|
|
192
|
+
A module homomorphism defined by sending the generator
|
|
193
|
+
with index `i` to the corresponding element in ``values``.
|
|
194
|
+
|
|
195
|
+
TESTS::
|
|
196
|
+
|
|
197
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
198
|
+
sage: A2 = SteenrodAlgebra(2, profile=(3,2,1))
|
|
199
|
+
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
|
|
200
|
+
sage: M = FPModule(A2, [0], relations=[[Sq(1)]])
|
|
201
|
+
sage: N = FPModule(A2, [0], relations=[[Sq(4)],[Sq(1)]])
|
|
202
|
+
sage: f = Hom(M,N)([A2.Sq(3)*N.generator(0)])
|
|
203
|
+
sage: TestSuite(f).run()
|
|
204
|
+
"""
|
|
205
|
+
from .homspace import FPModuleHomspace
|
|
206
|
+
|
|
207
|
+
if not isinstance(parent, FPModuleHomspace):
|
|
208
|
+
raise TypeError('parent (=%s) must be a fp module hom space' % parent)
|
|
209
|
+
|
|
210
|
+
# Get the values.
|
|
211
|
+
C = parent.codomain()
|
|
212
|
+
D = parent.domain()
|
|
213
|
+
if isfunction(values):
|
|
214
|
+
values = [C(values(g)) for g in D.generators()]
|
|
215
|
+
elif not values:
|
|
216
|
+
values = len(D.generator_degrees()) * [C.zero()]
|
|
217
|
+
else:
|
|
218
|
+
values = [C(a) for a in values]
|
|
219
|
+
|
|
220
|
+
# Check the homomorphism is well defined.
|
|
221
|
+
if len(D.generator_degrees()) != len(values):
|
|
222
|
+
raise ValueError('the number of values must equal the number of '
|
|
223
|
+
'generators in the domain; invalid argument: %s' % values)
|
|
224
|
+
|
|
225
|
+
self._values = tuple(values)
|
|
226
|
+
|
|
227
|
+
# Call the base class constructor.
|
|
228
|
+
Morphism.__init__(self, parent)
|
|
229
|
+
|
|
230
|
+
# Check that the homomorphism is well defined.
|
|
231
|
+
if check:
|
|
232
|
+
self._free_morphism
|
|
233
|
+
for relation in parent.domain().relations():
|
|
234
|
+
# The relation is an element in the free part of the domain.
|
|
235
|
+
img = self._free_morphism(relation)
|
|
236
|
+
if parent.codomain()(img):
|
|
237
|
+
raise ValueError('relation %s is not sent to zero' % relation)
|
|
238
|
+
|
|
239
|
+
@lazy_attribute
|
|
240
|
+
def _free_morphism(self):
|
|
241
|
+
"""
|
|
242
|
+
Return the lifted morphism between free modules.
|
|
243
|
+
|
|
244
|
+
TESTS::
|
|
245
|
+
|
|
246
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
247
|
+
sage: A2 = SteenrodAlgebra(2, profile=(3,2,1))
|
|
248
|
+
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
|
|
249
|
+
sage: M = FPModule(A2, [0], relations=[[Sq(1)]])
|
|
250
|
+
sage: N = FPModule(A2, [0], relations=[[Sq(4)],[Sq(1)]])
|
|
251
|
+
sage: f = Hom(M,N)([A2.Sq(3)*N.generator(0)])
|
|
252
|
+
sage: f._free_morphism
|
|
253
|
+
Module endomorphism of Free graded left module on 1 generator
|
|
254
|
+
over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
|
|
255
|
+
Defn: g[0] |--> Sq(3)*g[0]
|
|
256
|
+
"""
|
|
257
|
+
P = self.parent()
|
|
258
|
+
from sage.modules.fp_graded.free_module import FreeGradedModule
|
|
259
|
+
if isinstance(P.codomain(), FreeGradedModule):
|
|
260
|
+
Homspace = Hom(P.domain()._j.codomain(), P.codomain())
|
|
261
|
+
return Homspace(self._values)
|
|
262
|
+
Homspace = Hom(P.domain()._j.codomain(), P.codomain()._j.codomain())
|
|
263
|
+
return Homspace([v.lift_to_free() for v in self._values])
|
|
264
|
+
|
|
265
|
+
def change_ring(self, algebra):
|
|
266
|
+
r"""
|
|
267
|
+
Change the base ring of ``self``.
|
|
268
|
+
|
|
269
|
+
INPUT:
|
|
270
|
+
|
|
271
|
+
- ``algebra`` -- a graded algebra
|
|
272
|
+
|
|
273
|
+
EXAMPLES::
|
|
274
|
+
|
|
275
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
276
|
+
sage: A2 = SteenrodAlgebra(2, profile=(3,2,1))
|
|
277
|
+
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
|
|
278
|
+
sage: M = FPModule(A2, [0], relations=[[Sq(1)]])
|
|
279
|
+
sage: N = FPModule(A2, [0], relations=[[Sq(4)],[Sq(1)]])
|
|
280
|
+
|
|
281
|
+
sage: f = Hom(M,N)([A2.Sq(3)*N.generator(0)]); f
|
|
282
|
+
Module morphism:
|
|
283
|
+
From: Finitely presented left module on 1 generator and 1 relation over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
|
|
284
|
+
To: Finitely presented left module on 1 generator and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
|
|
285
|
+
Defn: g[0] |--> Sq(3)*g[0]
|
|
286
|
+
|
|
287
|
+
sage: f.base_ring()
|
|
288
|
+
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
|
|
289
|
+
|
|
290
|
+
sage: g = f.change_ring(A3)
|
|
291
|
+
sage: g.base_ring()
|
|
292
|
+
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
|
|
293
|
+
"""
|
|
294
|
+
new_codomain = self.codomain().change_ring(algebra)
|
|
295
|
+
# We have to change the ring for the values, too:
|
|
296
|
+
new_values = [new_codomain([algebra(a)
|
|
297
|
+
for a in v.dense_coefficient_list()])
|
|
298
|
+
for v in self._values]
|
|
299
|
+
return Hom(self.domain().change_ring(algebra), new_codomain)(new_values)
|
|
300
|
+
|
|
301
|
+
def degree(self):
|
|
302
|
+
r"""
|
|
303
|
+
The degree of ``self``.
|
|
304
|
+
|
|
305
|
+
OUTPUT: the integer degree of ``self``
|
|
306
|
+
|
|
307
|
+
EXAMPLES::
|
|
308
|
+
|
|
309
|
+
sage: from sage.modules.fp_graded.module import *
|
|
310
|
+
sage: A = SteenrodAlgebra(2)
|
|
311
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
312
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
313
|
+
sage: homspace = Hom(M, N)
|
|
314
|
+
|
|
315
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
316
|
+
sage: f = homspace(values)
|
|
317
|
+
sage: f.degree()
|
|
318
|
+
7
|
|
319
|
+
|
|
320
|
+
The trivial homomorphism has no degree::
|
|
321
|
+
|
|
322
|
+
sage: homspace.zero().degree()
|
|
323
|
+
Traceback (most recent call last):
|
|
324
|
+
...
|
|
325
|
+
ValueError: the zero morphism does not have a well-defined degree
|
|
326
|
+
|
|
327
|
+
TESTS::
|
|
328
|
+
|
|
329
|
+
sage: M = FPModule(SteenrodAlgebra(p=2), [7])
|
|
330
|
+
sage: N = FPModule(SteenrodAlgebra(p=2), [0], relations=[[Sq(1)]])
|
|
331
|
+
sage: f = Hom(M,N)([Sq(1)*N.generator(0)])
|
|
332
|
+
sage: f == Hom(M,N).zero()
|
|
333
|
+
True
|
|
334
|
+
sage: f.degree()
|
|
335
|
+
Traceback (most recent call last):
|
|
336
|
+
...
|
|
337
|
+
ValueError: the zero morphism does not have a well-defined degree
|
|
338
|
+
"""
|
|
339
|
+
if self.is_zero():
|
|
340
|
+
# The zero morphism has no degree.
|
|
341
|
+
raise ValueError("the zero morphism does not have a well-defined degree")
|
|
342
|
+
return self._free_morphism.degree()
|
|
343
|
+
|
|
344
|
+
def values(self):
|
|
345
|
+
r"""
|
|
346
|
+
The values under ``self`` of the module generators of the domain module.
|
|
347
|
+
|
|
348
|
+
OUTPUT: a sequence of module elements of the codomain
|
|
349
|
+
|
|
350
|
+
EXAMPLES::
|
|
351
|
+
|
|
352
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
353
|
+
sage: A = SteenrodAlgebra(2)
|
|
354
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
355
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
356
|
+
sage: homspace = Hom(M, N)
|
|
357
|
+
|
|
358
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
359
|
+
sage: f = homspace(values)
|
|
360
|
+
|
|
361
|
+
sage: f.values()
|
|
362
|
+
(Sq(5)*g[2], Sq(3,1)*g[2])
|
|
363
|
+
|
|
364
|
+
sage: homspace.zero().values()
|
|
365
|
+
(0, 0)
|
|
366
|
+
|
|
367
|
+
sage: homspace = Hom(A.free_graded_module((0,1)), A.free_graded_module((2,)))
|
|
368
|
+
sage: N = homspace.codomain()
|
|
369
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
370
|
+
sage: f = homspace(values)
|
|
371
|
+
sage: f.values()
|
|
372
|
+
(Sq(5)*g[2], Sq(3,1)*g[2])
|
|
373
|
+
sage: homspace.zero().values()
|
|
374
|
+
(0, 0)
|
|
375
|
+
"""
|
|
376
|
+
return self._values
|
|
377
|
+
|
|
378
|
+
def _richcmp_(self, other, op):
|
|
379
|
+
r"""
|
|
380
|
+
Compare ``self`` to ``other``.
|
|
381
|
+
|
|
382
|
+
EXAMPLES::
|
|
383
|
+
|
|
384
|
+
sage: from sage.modules.fp_graded.module import *
|
|
385
|
+
sage: A = SteenrodAlgebra(2)
|
|
386
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
387
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
388
|
+
sage: homspace = Hom(M, N)
|
|
389
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
390
|
+
sage: f = homspace(values)
|
|
391
|
+
sage: f._richcmp_(f, op=2)
|
|
392
|
+
True
|
|
393
|
+
sage: f._richcmp_(f, op=3)
|
|
394
|
+
False
|
|
395
|
+
|
|
396
|
+
sage: homspace = Hom(A.free_graded_module((0,1)), A.free_graded_module((2,)))
|
|
397
|
+
sage: N = homspace.codomain()
|
|
398
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
399
|
+
sage: f = homspace(values)
|
|
400
|
+
sage: f._richcmp_(f, op=2)
|
|
401
|
+
True
|
|
402
|
+
sage: f._richcmp_(f, op=3)
|
|
403
|
+
False
|
|
404
|
+
"""
|
|
405
|
+
try:
|
|
406
|
+
same = (self - other).is_zero()
|
|
407
|
+
except ValueError:
|
|
408
|
+
return False
|
|
409
|
+
|
|
410
|
+
# Equality
|
|
411
|
+
if op == 2:
|
|
412
|
+
return same
|
|
413
|
+
|
|
414
|
+
# Non-equality
|
|
415
|
+
if op == 3:
|
|
416
|
+
return not same
|
|
417
|
+
|
|
418
|
+
return False
|
|
419
|
+
|
|
420
|
+
def __add__(self, g):
|
|
421
|
+
r"""
|
|
422
|
+
The pointwise sum of ``self`` and ``g``.
|
|
423
|
+
|
|
424
|
+
Pointwise addition of two homomorphisms `f` and `g` with the same domain
|
|
425
|
+
and codomain is given by the formula `(f+g)(x) = f(x) + g(x)` for
|
|
426
|
+
every `x` in the domain of `f`.
|
|
427
|
+
|
|
428
|
+
INPUT:
|
|
429
|
+
|
|
430
|
+
- ``g`` -- a homomorphism with the same domain and codomain as ``self``
|
|
431
|
+
|
|
432
|
+
EXAMPLES::
|
|
433
|
+
|
|
434
|
+
sage: from sage.modules.fp_graded.module import *
|
|
435
|
+
sage: A = SteenrodAlgebra(2)
|
|
436
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
437
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
438
|
+
sage: v = N.generator(0)
|
|
439
|
+
sage: homspace = Hom(M, N)
|
|
440
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
441
|
+
sage: f = homspace(values)
|
|
442
|
+
sage: ff = f + f
|
|
443
|
+
sage: ff.is_zero()
|
|
444
|
+
True
|
|
445
|
+
sage: ff + f == f
|
|
446
|
+
True
|
|
447
|
+
|
|
448
|
+
sage: N = A.free_graded_module((2,))
|
|
449
|
+
sage: v = N.generator(0)
|
|
450
|
+
sage: homspace = Hom(A.free_graded_module((0,1)), N)
|
|
451
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
452
|
+
sage: f = homspace(values)
|
|
453
|
+
sage: ff = f + f
|
|
454
|
+
sage: ff.is_zero()
|
|
455
|
+
True
|
|
456
|
+
sage: ff + f == f
|
|
457
|
+
True
|
|
458
|
+
sage: ff = f + f
|
|
459
|
+
sage: ff.is_zero()
|
|
460
|
+
True
|
|
461
|
+
"""
|
|
462
|
+
if self.domain() != g.domain():
|
|
463
|
+
raise ValueError('morphisms do not have the same domain')
|
|
464
|
+
elif self.codomain() != g.codomain():
|
|
465
|
+
raise ValueError('morphisms do not have the same codomain')
|
|
466
|
+
if self.is_zero():
|
|
467
|
+
return g
|
|
468
|
+
if g.is_zero():
|
|
469
|
+
return self
|
|
470
|
+
if self.degree() and g.degree() and self.degree() != g.degree():
|
|
471
|
+
raise ValueError('morphisms do not have the same degree')
|
|
472
|
+
|
|
473
|
+
v = [self(x) + g(x) for x in self.domain().generators()]
|
|
474
|
+
|
|
475
|
+
return self.parent()(v)
|
|
476
|
+
|
|
477
|
+
def __neg__(self):
|
|
478
|
+
r"""
|
|
479
|
+
The additive inverse of ``self`` with respect to the group
|
|
480
|
+
structure given by pointwise sum.
|
|
481
|
+
|
|
482
|
+
EXAMPLES::
|
|
483
|
+
|
|
484
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
485
|
+
sage: A = SteenrodAlgebra(2)
|
|
486
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
487
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
488
|
+
sage: v = N.generator(0)
|
|
489
|
+
sage: homspace = Hom(M, N)
|
|
490
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
491
|
+
sage: f = homspace(values)
|
|
492
|
+
sage: f_neg = -f; f_neg
|
|
493
|
+
Module morphism:
|
|
494
|
+
From: Finitely presented left module on 2 generators and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
495
|
+
To: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
496
|
+
Defn: g[0] |--> Sq(5)*g[2]
|
|
497
|
+
g[1] |--> Sq(3,1)*g[2]
|
|
498
|
+
sage: (f + f_neg).is_zero()
|
|
499
|
+
True
|
|
500
|
+
|
|
501
|
+
sage: N = A.free_graded_module((2,))
|
|
502
|
+
sage: v = N.generator(0)
|
|
503
|
+
sage: homspace = Hom(A.free_graded_module((0,1)), N)
|
|
504
|
+
sage: N = homspace.codomain()
|
|
505
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
506
|
+
sage: f = homspace(values)
|
|
507
|
+
sage: f_neg = -f; f_neg
|
|
508
|
+
Module morphism:
|
|
509
|
+
From: Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
|
|
510
|
+
To: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
|
|
511
|
+
Defn: g[0] |--> Sq(5)*g[2]
|
|
512
|
+
g[1] |--> Sq(3,1)*g[2]
|
|
513
|
+
sage: (f + f_neg).is_zero()
|
|
514
|
+
True
|
|
515
|
+
"""
|
|
516
|
+
return self.parent()([-x for x in self._values])
|
|
517
|
+
|
|
518
|
+
def __sub__(self, g):
|
|
519
|
+
r"""
|
|
520
|
+
The difference between ``self`` and ``g`` with
|
|
521
|
+
respect to the group structure given by pointwise sum.
|
|
522
|
+
|
|
523
|
+
EXAMPLES::
|
|
524
|
+
|
|
525
|
+
sage: from sage.modules.fp_graded.module import *
|
|
526
|
+
sage: A = SteenrodAlgebra(2)
|
|
527
|
+
sage: M = FPModule(A, [0])
|
|
528
|
+
sage: N = FPModule(A, [0], [[Sq(4)]])
|
|
529
|
+
sage: f = Hom(M, N)( [Sq(3)*N.generator(0)] )
|
|
530
|
+
sage: g = Hom(M, N)( [Sq(0,1)*N.generator(0)] )
|
|
531
|
+
sage: f - g
|
|
532
|
+
Module morphism:
|
|
533
|
+
From: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
|
|
534
|
+
To: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
535
|
+
Defn: g[0] |--> (Sq(0,1)+Sq(3))*g[0]
|
|
536
|
+
|
|
537
|
+
sage: f = Hom(M, N)( [Sq(4)*N.generator(0)] ) # the zero map
|
|
538
|
+
sage: g = Hom(M, N)( [Sq(1,1)*N.generator(0)] )
|
|
539
|
+
sage: f - g
|
|
540
|
+
Module morphism:
|
|
541
|
+
From: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
|
|
542
|
+
To: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
543
|
+
Defn: g[0] |--> Sq(1,1)*g[0]
|
|
544
|
+
|
|
545
|
+
sage: N = A.free_graded_module((2,))
|
|
546
|
+
sage: v = N.generator(0)
|
|
547
|
+
sage: homspace = Hom(A.free_graded_module((0,1)), N)
|
|
548
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
549
|
+
sage: f = homspace(values)
|
|
550
|
+
sage: values2 = [Sq(5)*v, Sq(3,1)*v]
|
|
551
|
+
sage: g = homspace(values2)
|
|
552
|
+
sage: f - g == 0
|
|
553
|
+
True
|
|
554
|
+
"""
|
|
555
|
+
return self.__add__(g.__neg__())
|
|
556
|
+
|
|
557
|
+
def __mul__(self, g):
|
|
558
|
+
r"""
|
|
559
|
+
The composition of ``g`` followed by ``self``.
|
|
560
|
+
|
|
561
|
+
EXAMPLES::
|
|
562
|
+
|
|
563
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
564
|
+
sage: A = SteenrodAlgebra(2)
|
|
565
|
+
sage: M = FPModule(A, [0], [[Sq(1,2)]])
|
|
566
|
+
sage: N = FPModule(A, [0], [[Sq(2,2)]])
|
|
567
|
+
sage: f = Hom(M, N)( [Sq(2)*N.generator(0)] )
|
|
568
|
+
sage: g = Hom(N, M)( [Sq(2,2)*M.generator(0)] )
|
|
569
|
+
sage: fg = f * g; fg
|
|
570
|
+
Module endomorphism of Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
571
|
+
Defn: g[0] |--> (Sq(0,1,1)+Sq(1,3)+Sq(3,0,1))*g[0]
|
|
572
|
+
sage: fg.is_endomorphism()
|
|
573
|
+
True
|
|
574
|
+
|
|
575
|
+
sage: M = A.free_graded_module((0,1))
|
|
576
|
+
sage: N = A.free_graded_module((2,))
|
|
577
|
+
sage: v = N.generator(0)
|
|
578
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
579
|
+
sage: f = Hom(M, N)(values)
|
|
580
|
+
sage: values2 = [Sq(2)*M.generator(0)]
|
|
581
|
+
sage: g = Hom(N, M)(values2)
|
|
582
|
+
sage: fg = f * g; fg
|
|
583
|
+
Module endomorphism of Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
|
|
584
|
+
Defn: g[2] |--> (Sq(4,1)+Sq(7))*g[2]
|
|
585
|
+
sage: fg.is_endomorphism()
|
|
586
|
+
True
|
|
587
|
+
|
|
588
|
+
TESTS::
|
|
589
|
+
|
|
590
|
+
sage: from sage.modules.fp_graded.free_module import *
|
|
591
|
+
sage: A = SteenrodAlgebra(2)
|
|
592
|
+
sage: M = FPModule(A, (0,1))
|
|
593
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
594
|
+
sage: f = Hom(M, N)(values)
|
|
595
|
+
sage: f * f
|
|
596
|
+
Traceback (most recent call last):
|
|
597
|
+
...
|
|
598
|
+
ValueError: morphisms not composable
|
|
599
|
+
|
|
600
|
+
sage: M = A.free_graded_module((0,1))
|
|
601
|
+
sage: N = A.free_graded_module((2,))
|
|
602
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
603
|
+
sage: f = Hom(M, N)(values)
|
|
604
|
+
sage: f * f
|
|
605
|
+
Traceback (most recent call last):
|
|
606
|
+
...
|
|
607
|
+
ValueError: morphisms not composable
|
|
608
|
+
"""
|
|
609
|
+
if self.parent().domain() != g.parent().codomain():
|
|
610
|
+
raise ValueError('morphisms not composable')
|
|
611
|
+
homset = Hom(g.parent().domain(), self.parent().codomain())
|
|
612
|
+
return homset([self(g(x)) for x in g.domain().generators()])
|
|
613
|
+
|
|
614
|
+
@cached_method
|
|
615
|
+
def is_zero(self) -> bool:
|
|
616
|
+
r"""
|
|
617
|
+
Decide if ``self`` is the zero homomorphism.
|
|
618
|
+
|
|
619
|
+
OUTPUT: the boolean value ``True`` if ``self`` is trivial and ``False`` otherwise
|
|
620
|
+
|
|
621
|
+
EXAMPLES::
|
|
622
|
+
|
|
623
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
624
|
+
sage: A = SteenrodAlgebra(2)
|
|
625
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
626
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
627
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
628
|
+
|
|
629
|
+
sage: f = Hom(M, N)(values)
|
|
630
|
+
sage: f.is_zero()
|
|
631
|
+
False
|
|
632
|
+
|
|
633
|
+
sage: (f-f).is_zero()
|
|
634
|
+
True
|
|
635
|
+
|
|
636
|
+
sage: M = A.free_graded_module((0,1))
|
|
637
|
+
sage: N = A.free_graded_module((2,))
|
|
638
|
+
sage: v = N.generator(0)
|
|
639
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
640
|
+
sage: f = Hom(M, N)(values)
|
|
641
|
+
sage: f.is_zero()
|
|
642
|
+
False
|
|
643
|
+
sage: (f-f).is_zero()
|
|
644
|
+
True
|
|
645
|
+
"""
|
|
646
|
+
return all(x.is_zero() for x in self._values)
|
|
647
|
+
|
|
648
|
+
__bool__ = is_zero
|
|
649
|
+
|
|
650
|
+
@cached_method
|
|
651
|
+
def is_identity(self) -> bool:
|
|
652
|
+
r"""
|
|
653
|
+
Decide if ``self`` is the identity endomorphism.
|
|
654
|
+
|
|
655
|
+
EXAMPLES::
|
|
656
|
+
|
|
657
|
+
sage: from sage.modules.fp_graded.module import *
|
|
658
|
+
sage: A = SteenrodAlgebra(2)
|
|
659
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
660
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
661
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
662
|
+
|
|
663
|
+
sage: f = Hom(M, N)(values)
|
|
664
|
+
sage: f.is_identity()
|
|
665
|
+
False
|
|
666
|
+
|
|
667
|
+
sage: one = Hom(M, M)(M.generators()); one
|
|
668
|
+
Module endomorphism of Finitely presented left module on 2 generators and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
669
|
+
Defn: g[0] |--> g[0]
|
|
670
|
+
g[1] |--> g[1]
|
|
671
|
+
|
|
672
|
+
sage: one.is_identity()
|
|
673
|
+
True
|
|
674
|
+
|
|
675
|
+
sage: M = A.free_graded_module((0,1))
|
|
676
|
+
sage: N = A.free_graded_module((2,))
|
|
677
|
+
sage: v = N.generator(0)
|
|
678
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
679
|
+
sage: f = Hom(M, N)(values)
|
|
680
|
+
sage: f.is_identity()
|
|
681
|
+
False
|
|
682
|
+
sage: one = Hom(M, M)(M.generators()); one
|
|
683
|
+
Module endomorphism of Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
|
|
684
|
+
Defn: g[0] |--> g[0]
|
|
685
|
+
g[1] |--> g[1]
|
|
686
|
+
sage: one.is_identity()
|
|
687
|
+
True
|
|
688
|
+
"""
|
|
689
|
+
return (self.parent().is_endomorphism_set()
|
|
690
|
+
and self.parent().identity() == self)
|
|
691
|
+
|
|
692
|
+
def __call__(self, x):
|
|
693
|
+
r"""
|
|
694
|
+
Evaluate the homomorphism at the given domain element ``x``.
|
|
695
|
+
|
|
696
|
+
INPUT:
|
|
697
|
+
|
|
698
|
+
- ``x`` -- an element of the domain of the homomorphism
|
|
699
|
+
|
|
700
|
+
OUTPUT:
|
|
701
|
+
|
|
702
|
+
The module element of the codomain which is the value of ``x``
|
|
703
|
+
under this homomorphism.
|
|
704
|
+
|
|
705
|
+
EXAMPLES::
|
|
706
|
+
|
|
707
|
+
sage: from sage.modules.fp_graded.module import *
|
|
708
|
+
sage: A = SteenrodAlgebra(2)
|
|
709
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
710
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
711
|
+
|
|
712
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
713
|
+
sage: f = Hom(M, N)(values)
|
|
714
|
+
|
|
715
|
+
sage: f.__call__(M.generator(0))
|
|
716
|
+
Sq(5)*g[2]
|
|
717
|
+
|
|
718
|
+
sage: f.__call__(M.generator(1))
|
|
719
|
+
Sq(3,1)*g[2]
|
|
720
|
+
"""
|
|
721
|
+
if x.parent() != self.domain():
|
|
722
|
+
raise ValueError('cannot evaluate morphism on element not in domain')
|
|
723
|
+
|
|
724
|
+
return self.codomain()(self._free_morphism(x.lift_to_free()))
|
|
725
|
+
|
|
726
|
+
def _repr_type(self):
|
|
727
|
+
"""
|
|
728
|
+
TESTS::
|
|
729
|
+
|
|
730
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
731
|
+
sage: A2 = SteenrodAlgebra(2, profile=(3,2,1))
|
|
732
|
+
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
|
|
733
|
+
sage: M = FPModule(A2, [0], relations=[[Sq(1)]])
|
|
734
|
+
sage: N = FPModule(A2, [0], relations=[[Sq(4)],[Sq(1)]])
|
|
735
|
+
sage: f = Hom(M,N)([A2.Sq(3)*N.generator(0)])
|
|
736
|
+
sage: f._repr_type()
|
|
737
|
+
'Module'
|
|
738
|
+
"""
|
|
739
|
+
return "Module"
|
|
740
|
+
|
|
741
|
+
def _repr_defn(self):
|
|
742
|
+
"""
|
|
743
|
+
TESTS::
|
|
744
|
+
|
|
745
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
746
|
+
sage: A2 = SteenrodAlgebra(2, profile=(3,2,1))
|
|
747
|
+
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
|
|
748
|
+
sage: M = FPModule(A2, [0], relations=[[Sq(1)]])
|
|
749
|
+
sage: N = FPModule(A2, [0], relations=[[Sq(4)],[Sq(1)]])
|
|
750
|
+
sage: f = Hom(M,N)([A2.Sq(3)*N.generator(0)])
|
|
751
|
+
sage: f._repr_defn()
|
|
752
|
+
'g[0] |--> Sq(3)*g[0]'
|
|
753
|
+
|
|
754
|
+
sage: A = SteenrodAlgebra(2)
|
|
755
|
+
sage: F1 = A.free_graded_module((4,5), names='b')
|
|
756
|
+
sage: F2 = A.free_graded_module((3,4), names='c')
|
|
757
|
+
sage: H = Hom(F1, F2)
|
|
758
|
+
sage: f = H((F2((Sq(4), 0)), F2((0, Sq(4)))))
|
|
759
|
+
sage: print(f._repr_defn())
|
|
760
|
+
b[4] |--> Sq(4)*c[3]
|
|
761
|
+
b[5] |--> Sq(4)*c[4]
|
|
762
|
+
"""
|
|
763
|
+
s = '\n'.join(['%s |--> %s' % (x, y) for (x, y) in
|
|
764
|
+
zip(self.domain().generators(), self._values)])
|
|
765
|
+
return s
|
|
766
|
+
|
|
767
|
+
@cached_method
|
|
768
|
+
def vector_presentation(self, n):
|
|
769
|
+
r"""
|
|
770
|
+
Return the restriction of ``self`` to the domain module elements
|
|
771
|
+
of degree ``n``.
|
|
772
|
+
|
|
773
|
+
The restriction of a nonzero module homomorphism to the free module
|
|
774
|
+
of module elements of degree `n` is a linear function into the free
|
|
775
|
+
module of elements of degree `n+d` belonging to the codomain.
|
|
776
|
+
Here `d` is the degree of this homomorphism.
|
|
777
|
+
|
|
778
|
+
When this homomorphism is zero, it has no well defined degree so the
|
|
779
|
+
function cannot be presented since we do not know the degree of its
|
|
780
|
+
codomain. In this case, an error is raised.
|
|
781
|
+
|
|
782
|
+
INPUT:
|
|
783
|
+
|
|
784
|
+
- ``n`` -- integer degree
|
|
785
|
+
|
|
786
|
+
OUTPUT:
|
|
787
|
+
|
|
788
|
+
A linear function of finite dimensional free modules over the
|
|
789
|
+
ground ring of the algebra for this module. The domain is isomorphic
|
|
790
|
+
to the free module of domain elements of degree ``n`` of ``self``
|
|
791
|
+
via the choice of basis given by
|
|
792
|
+
:meth:`~sage.modules.fp_graded.free_module.FreeGradedModule.basis_elements`.
|
|
793
|
+
If the morphism is zero, an error is raised.
|
|
794
|
+
|
|
795
|
+
.. SEEALSO::
|
|
796
|
+
|
|
797
|
+
* :meth:`sage.modules.fp_graded.module.FPModule.vector_presentation`
|
|
798
|
+
* :meth:`sage.modules.fp_graded.module.FPModule.basis_elements`
|
|
799
|
+
* :meth:`sage.modules.fp_graded.free_module.FreeGradedModule.vector_presentation`
|
|
800
|
+
* :meth:`sage.modules.fp_graded.free_module.FreeGradedModule.basis_elements`
|
|
801
|
+
|
|
802
|
+
EXAMPLES::
|
|
803
|
+
|
|
804
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
805
|
+
sage: A = SteenrodAlgebra(2)
|
|
806
|
+
sage: M = FPModule(A, [0,1], [[Sq(2), Sq(1)]])
|
|
807
|
+
sage: N = FPModule(A, [2], [[Sq(4)]])
|
|
808
|
+
sage: values = [Sq(5)*N.generator(0), Sq(3,1)*N.generator(0)]
|
|
809
|
+
sage: f = Hom(M, N)(values)
|
|
810
|
+
sage: f.vector_presentation(0)
|
|
811
|
+
Vector space morphism represented by the matrix:
|
|
812
|
+
[0]
|
|
813
|
+
Domain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
|
|
814
|
+
V: Vector space of dimension 1 over Finite Field of size 2
|
|
815
|
+
W: Vector space of degree 1 and dimension 0 over Finite Field of size 2
|
|
816
|
+
Basis matrix:
|
|
817
|
+
[]
|
|
818
|
+
Codomain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
|
|
819
|
+
V: Vector space of dimension 2 over Finite Field of size 2
|
|
820
|
+
W: Vector space of degree 2 and dimension 1 over Finite Field of size 2
|
|
821
|
+
Basis matrix:
|
|
822
|
+
[0 1]
|
|
823
|
+
sage: f.vector_presentation(1)
|
|
824
|
+
Vector space morphism represented by the matrix:
|
|
825
|
+
[0 0]
|
|
826
|
+
[0 1]
|
|
827
|
+
Domain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
|
|
828
|
+
V: Vector space of dimension 2 over Finite Field of size 2
|
|
829
|
+
W: Vector space of degree 2 and dimension 0 over Finite Field of size 2
|
|
830
|
+
Basis matrix:
|
|
831
|
+
[]
|
|
832
|
+
Codomain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
|
|
833
|
+
V: Vector space of dimension 3 over Finite Field of size 2
|
|
834
|
+
W: Vector space of degree 3 and dimension 1 over Finite Field of size 2
|
|
835
|
+
Basis matrix:
|
|
836
|
+
[0 1 1]
|
|
837
|
+
sage: f.vector_presentation(2)
|
|
838
|
+
Vector space morphism represented by the matrix:
|
|
839
|
+
[0 0]
|
|
840
|
+
Domain: Vector space quotient V/W of dimension 1 over Finite Field of size 2 where
|
|
841
|
+
V: Vector space of dimension 2 over Finite Field of size 2
|
|
842
|
+
W: Vector space of degree 2 and dimension 1 over Finite Field of size 2
|
|
843
|
+
Basis matrix:
|
|
844
|
+
[1 1]
|
|
845
|
+
Codomain: Vector space quotient V/W of dimension 2 over Finite Field of size 2 where
|
|
846
|
+
V: Vector space of dimension 4 over Finite Field of size 2
|
|
847
|
+
W: Vector space of degree 4 and dimension 2 over Finite Field of size 2
|
|
848
|
+
Basis matrix:
|
|
849
|
+
[0 0 1 0]
|
|
850
|
+
[0 0 0 1]
|
|
851
|
+
|
|
852
|
+
sage: M = A.free_graded_module((0,1))
|
|
853
|
+
sage: N = A.free_graded_module((2,))
|
|
854
|
+
sage: v = N.generator(0)
|
|
855
|
+
sage: values = [Sq(5)*v, Sq(3,1)*v]
|
|
856
|
+
sage: f = Hom(M, N)(values)
|
|
857
|
+
sage: f.vector_presentation(0)
|
|
858
|
+
Vector space morphism represented by the matrix:
|
|
859
|
+
[0 1]
|
|
860
|
+
Domain: Vector space of dimension 1 over Finite Field of size 2
|
|
861
|
+
Codomain: Vector space of dimension 2 over Finite Field of size 2
|
|
862
|
+
sage: f.vector_presentation(1)
|
|
863
|
+
Vector space morphism represented by the matrix:
|
|
864
|
+
[0 0 0]
|
|
865
|
+
[0 1 0]
|
|
866
|
+
Domain: Vector space of dimension 2 over Finite Field of size 2
|
|
867
|
+
Codomain: Vector space of dimension 3 over Finite Field of size 2
|
|
868
|
+
sage: f.vector_presentation(2)
|
|
869
|
+
Vector space morphism represented by the matrix:
|
|
870
|
+
[0 0 1 1]
|
|
871
|
+
[0 0 0 0]
|
|
872
|
+
Domain: Vector space of dimension 2 over Finite Field of size 2
|
|
873
|
+
Codomain: Vector space of dimension 4 over Finite Field of size 2
|
|
874
|
+
|
|
875
|
+
TESTS::
|
|
876
|
+
|
|
877
|
+
sage: F = FPModule(A, [0])
|
|
878
|
+
sage: Q = FPModule(A, [0], [[Sq(2)]])
|
|
879
|
+
sage: z = Hom(F, Q)([Sq(2)*Q.generator(0)])
|
|
880
|
+
sage: z.is_zero()
|
|
881
|
+
True
|
|
882
|
+
sage: z.vector_presentation(0)
|
|
883
|
+
Traceback (most recent call last):
|
|
884
|
+
...
|
|
885
|
+
ValueError: the zero map has no vector presentation
|
|
886
|
+
"""
|
|
887
|
+
# The trivial map has no degree, so we can not create the codomain
|
|
888
|
+
# of the linear transformation.
|
|
889
|
+
if self.is_zero():
|
|
890
|
+
raise ValueError("the zero map has no vector presentation")
|
|
891
|
+
|
|
892
|
+
D_n = self.domain().vector_presentation(n)
|
|
893
|
+
C_n = self.codomain().vector_presentation(self.degree() + n)
|
|
894
|
+
|
|
895
|
+
values = [self(e) for e in self.domain().basis_elements(n)]
|
|
896
|
+
|
|
897
|
+
return Hom(D_n, C_n)([C_n.zero() if e.is_zero() else e.vector_presentation()
|
|
898
|
+
for e in values])
|
|
899
|
+
|
|
900
|
+
def solve(self, x):
|
|
901
|
+
r"""
|
|
902
|
+
Return an element in the inverse image of ``x``.
|
|
903
|
+
|
|
904
|
+
INPUT:
|
|
905
|
+
|
|
906
|
+
- ``x`` -- an element of the codomain of this morphism
|
|
907
|
+
|
|
908
|
+
OUTPUT:
|
|
909
|
+
|
|
910
|
+
An element of the domain which maps to ``x`` under this morphism
|
|
911
|
+
or ``None`` if ``x`` was not in the image of this morphism.
|
|
912
|
+
|
|
913
|
+
EXAMPLES::
|
|
914
|
+
|
|
915
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
916
|
+
sage: A = SteenrodAlgebra(2)
|
|
917
|
+
sage: M = FPModule(A, [0], [[Sq(3)]])
|
|
918
|
+
sage: N = FPModule(A, [0], [[Sq(2,2)]])
|
|
919
|
+
sage: f = Hom(M, N)( [Sq(2)*N.generator(0)] )
|
|
920
|
+
sage: y = Sq(1,1)*N.generator(0); y
|
|
921
|
+
Sq(1,1)*g[0]
|
|
922
|
+
sage: x = f.solve(y); x
|
|
923
|
+
Sq(2)*g[0]
|
|
924
|
+
sage: y == f(x)
|
|
925
|
+
True
|
|
926
|
+
|
|
927
|
+
Trying to lift an element which is not in the image results
|
|
928
|
+
in a ``None`` value::
|
|
929
|
+
|
|
930
|
+
sage: z = f.solve(Sq(1)*N.generator(0))
|
|
931
|
+
sage: z is None
|
|
932
|
+
True
|
|
933
|
+
|
|
934
|
+
TESTS::
|
|
935
|
+
|
|
936
|
+
sage: f.solve(Sq(2,2)*M.generator(0))
|
|
937
|
+
Traceback (most recent call last):
|
|
938
|
+
...
|
|
939
|
+
ValueError: the given element is not in the codomain of this homomorphism
|
|
940
|
+
"""
|
|
941
|
+
if x.parent() != self.codomain():
|
|
942
|
+
raise ValueError('the given element is not in the codomain of this homomorphism')
|
|
943
|
+
|
|
944
|
+
# The zero element lifts over all morphisms.
|
|
945
|
+
if x.is_zero():
|
|
946
|
+
return self.domain().zero()
|
|
947
|
+
|
|
948
|
+
# Handle the trivial homomorphism since it does not have a well defined
|
|
949
|
+
# degree.
|
|
950
|
+
if self.is_zero():
|
|
951
|
+
return None
|
|
952
|
+
|
|
953
|
+
# Handle the case where both morphism and element are non-trivial.
|
|
954
|
+
n = x.degree() - self.degree()
|
|
955
|
+
f_n = self.vector_presentation(n)
|
|
956
|
+
|
|
957
|
+
v = x.vector_presentation()
|
|
958
|
+
|
|
959
|
+
# Return None if ``x`` cannot be lifted.
|
|
960
|
+
if v not in f_n.image():
|
|
961
|
+
return None
|
|
962
|
+
|
|
963
|
+
u = f_n.matrix().solve_left(v)
|
|
964
|
+
return self.domain().element_from_coordinates(u, n)
|
|
965
|
+
|
|
966
|
+
def lift(self, f, verbose=False):
|
|
967
|
+
r"""
|
|
968
|
+
Return a lift of this homomorphism over the given homomorphism ``f``.
|
|
969
|
+
|
|
970
|
+
INPUT:
|
|
971
|
+
|
|
972
|
+
- ``f`` -- a homomorphism with codomain equal to the codomain of ``self``
|
|
973
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
974
|
+
|
|
975
|
+
OUTPUT:
|
|
976
|
+
|
|
977
|
+
A homomorphism `g` with the property that ``self`` equals `f \circ g`.
|
|
978
|
+
If no lift exist, ``None`` is returned.
|
|
979
|
+
|
|
980
|
+
ALGORITHM:
|
|
981
|
+
|
|
982
|
+
Let `s` be this homomorphism with `L` the domain of `s`.
|
|
983
|
+
Choose `x_1, \ldots, x_N` such that `f(x_i) = s(g_i)`,
|
|
984
|
+
where the `g_i`'s are the module generators of `L`.
|
|
985
|
+
|
|
986
|
+
The linear function sending `g_i` to `x_i` for every `i` is well
|
|
987
|
+
defined if and only if the vector `x = (x_1, \ldots, x_N)` lies
|
|
988
|
+
in the nullspace of the coefficient matrix `R = (r_{ij})` given
|
|
989
|
+
by the relations of `L`.
|
|
990
|
+
|
|
991
|
+
Let `k \in \ker(f)` solve the matrix equation:
|
|
992
|
+
|
|
993
|
+
.. MATH::
|
|
994
|
+
|
|
995
|
+
R \cdot k = R \cdot x.
|
|
996
|
+
|
|
997
|
+
Define a module homomorphism by sending the generators of `L` to
|
|
998
|
+
`x_1 - k_1, \ldots, x_N - k_N`. This is well defined, and is also a
|
|
999
|
+
lift of this homomorphism over `f`.
|
|
1000
|
+
|
|
1001
|
+
Note that it does not matter how we choose the initial elements `x_i`:
|
|
1002
|
+
If `x'` is another choice then `x' - x\in \ker(f)` and
|
|
1003
|
+
`R\cdot k = R\cdot x` if and only if `R\cdot (k + x' - x) = R\cdot x'`.
|
|
1004
|
+
|
|
1005
|
+
EXAMPLES::
|
|
1006
|
+
|
|
1007
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1008
|
+
sage: A = SteenrodAlgebra(2)
|
|
1009
|
+
|
|
1010
|
+
Lifting a map from a free module is always possible::
|
|
1011
|
+
|
|
1012
|
+
sage: M = FPModule(A, [0], [[Sq(3)]])
|
|
1013
|
+
sage: N = FPModule(A, [0], [[Sq(2,2)]])
|
|
1014
|
+
sage: F = FPModule(A, [0])
|
|
1015
|
+
sage: f = Hom(M,N)([Sq(2)*N.generator(0)])
|
|
1016
|
+
sage: k = Hom(F,N)([Sq(1)*Sq(2)*N.generator(0)])
|
|
1017
|
+
sage: f_ = k.lift(f)
|
|
1018
|
+
sage: f*f_ == k
|
|
1019
|
+
True
|
|
1020
|
+
sage: f_
|
|
1021
|
+
Module morphism:
|
|
1022
|
+
From: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
|
|
1023
|
+
To: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1024
|
+
Defn: g[0] |--> Sq(1)*g[0]
|
|
1025
|
+
|
|
1026
|
+
A split projection::
|
|
1027
|
+
|
|
1028
|
+
sage: A_plus_HZ = FPModule(A, [0,0], [[0, Sq(1)]])
|
|
1029
|
+
sage: HZ = FPModule(A, [0], [[Sq(1)]])
|
|
1030
|
+
sage: q = Hom(A_plus_HZ, HZ)([HZ([1]), HZ([1])])
|
|
1031
|
+
sage: # We can construct a splitting of `q` manually:
|
|
1032
|
+
sage: split = Hom(HZ,A_plus_HZ)([A_plus_HZ.generator(1)])
|
|
1033
|
+
sage: (q*split).is_identity()
|
|
1034
|
+
True
|
|
1035
|
+
|
|
1036
|
+
Thus, lifting the identity homomorphism over `q` should be possible::
|
|
1037
|
+
|
|
1038
|
+
sage: one = Hom(HZ,HZ).identity()
|
|
1039
|
+
sage: j = one.lift(q); j
|
|
1040
|
+
Module morphism:
|
|
1041
|
+
From: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1042
|
+
To: Finitely presented left module on 2 generators and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1043
|
+
Defn: g[0] |--> g[0, 1]
|
|
1044
|
+
sage: q*j
|
|
1045
|
+
Module endomorphism of Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1046
|
+
Defn: g[0] |--> g[0]
|
|
1047
|
+
|
|
1048
|
+
Lifting over the inclusion of the image sub module::
|
|
1049
|
+
|
|
1050
|
+
sage: A = SteenrodAlgebra(2)
|
|
1051
|
+
sage: M = FPModule(A, [0], relations=[[Sq(0,1)]])
|
|
1052
|
+
sage: f = Hom(M,M)([Sq(2)*M.generator(0)])
|
|
1053
|
+
sage: im = f.image(top_dim=10)
|
|
1054
|
+
sage: f.lift(im)
|
|
1055
|
+
Module morphism:
|
|
1056
|
+
From: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1057
|
+
To: Finitely presented left module on 1 generator and 2 relations over mod 2 Steenrod algebra, milnor basis
|
|
1058
|
+
Defn: g[0] |--> g[2]
|
|
1059
|
+
|
|
1060
|
+
When a lift cannot be found, the ``None`` value is returned. By
|
|
1061
|
+
setting the verbose argument to ``True``, an explanation of why
|
|
1062
|
+
the lifting failed will be displayed::
|
|
1063
|
+
|
|
1064
|
+
sage: F2 = FPModule(A, [0,0])
|
|
1065
|
+
sage: non_surjection = Hom(F2, F2)([F2([1, 0]), F2([0, 0])])
|
|
1066
|
+
sage: lift = Hom(F2, F2).identity().lift(non_surjection, verbose=True)
|
|
1067
|
+
The generators of the domain of this homomorphism do not map into
|
|
1068
|
+
the image of the homomorphism we are lifting over.
|
|
1069
|
+
sage: lift is None
|
|
1070
|
+
True
|
|
1071
|
+
|
|
1072
|
+
TESTS::
|
|
1073
|
+
|
|
1074
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1075
|
+
sage: A = SteenrodAlgebra(2)
|
|
1076
|
+
sage: # The trivial map often involved in corner cases..
|
|
1077
|
+
sage: trivial_map = Hom(FPModule(A, [0]), FPModule(A, [])).zero()
|
|
1078
|
+
sage: trivial_map.lift(trivial_map) == 0
|
|
1079
|
+
True
|
|
1080
|
+
|
|
1081
|
+
sage: F = FPModule(A, [0])
|
|
1082
|
+
sage: HZ = FPModule(A, [0], relations=[[Sq(1)]])
|
|
1083
|
+
sage: f = Hom(F,HZ)(HZ.generators())
|
|
1084
|
+
sage: split = Hom(HZ, HZ).identity().lift(f, verbose=True)
|
|
1085
|
+
The homomorphism cannot be lifted in any way such that the relations
|
|
1086
|
+
of the domain are respected: matrix equation has no solutions
|
|
1087
|
+
sage: split is None
|
|
1088
|
+
True
|
|
1089
|
+
|
|
1090
|
+
sage: Hom(F, F).identity().lift(f, verbose=true)
|
|
1091
|
+
Traceback (most recent call last):
|
|
1092
|
+
...
|
|
1093
|
+
ValueError: the codomains of this homomorphism and the homomorphism
|
|
1094
|
+
we are lifting over are different
|
|
1095
|
+
|
|
1096
|
+
sage: f.lift(Hom(HZ, HZ).zero(), verbose=True)
|
|
1097
|
+
This homomorphism cannot lift over a trivial homomorphism since
|
|
1098
|
+
it is non-trivial.
|
|
1099
|
+
|
|
1100
|
+
sage: Ap = SteenrodAlgebra(p=2, profile=(2,2,2,1))
|
|
1101
|
+
sage: Hko = FPModule(Ap, [0], [[Sq(2)], [Sq(1)]])
|
|
1102
|
+
sage: f = Hom(Hko, Hko)([(Ap.Sq(0,0,3) + Ap.Sq(0,2,0,1))*Hko.generator(0)])
|
|
1103
|
+
sage: f*f == 0
|
|
1104
|
+
True
|
|
1105
|
+
sage: k = f.kernel_inclusion() # long time
|
|
1106
|
+
sage: f.lift(k) # long time
|
|
1107
|
+
Module morphism:
|
|
1108
|
+
From: Finitely presented left module on 1 generator and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [2, 2, 2, 1]
|
|
1109
|
+
To: Finitely presented left module on 3 generators and 12 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [2, 2, 2, 1]
|
|
1110
|
+
Defn: g[0] |--> Sq(1)*g[20]
|
|
1111
|
+
|
|
1112
|
+
Corner cases involving trivial maps::
|
|
1113
|
+
|
|
1114
|
+
sage: M = FPModule(A, [1])
|
|
1115
|
+
sage: M1 = FPModule(A, [0])
|
|
1116
|
+
sage: M2 = FPModule(A, [0], [[Sq(1)]])
|
|
1117
|
+
sage: q = Hom(M1, M2)([M2.generator(0)])
|
|
1118
|
+
sage: z = Hom(M, M2).zero()
|
|
1119
|
+
sage: lift = z.lift(q)
|
|
1120
|
+
sage: lift.domain() is M and lift.codomain() is M1
|
|
1121
|
+
True
|
|
1122
|
+
|
|
1123
|
+
.. SEEALSO::
|
|
1124
|
+
|
|
1125
|
+
:meth:`split`
|
|
1126
|
+
"""
|
|
1127
|
+
from sage.modules.free_module_element import vector
|
|
1128
|
+
|
|
1129
|
+
# self
|
|
1130
|
+
# L -------> N
|
|
1131
|
+
# \ ^
|
|
1132
|
+
# \ |
|
|
1133
|
+
# lift \ | f
|
|
1134
|
+
# \ |
|
|
1135
|
+
# _| |
|
|
1136
|
+
# M
|
|
1137
|
+
L = self.domain()
|
|
1138
|
+
N = self.codomain()
|
|
1139
|
+
M = f.domain()
|
|
1140
|
+
|
|
1141
|
+
# It is an error to call this function with incompatible arguments.
|
|
1142
|
+
if f.codomain() is not N:
|
|
1143
|
+
raise ValueError('the codomains of this homomorphism and the homomorphism '
|
|
1144
|
+
'we are lifting over are different')
|
|
1145
|
+
|
|
1146
|
+
# The trivial map lifts over any other map.
|
|
1147
|
+
if self.is_zero():
|
|
1148
|
+
return Hom(L, M).zero()
|
|
1149
|
+
|
|
1150
|
+
# A non-trivial map never lifts over the trivial map.
|
|
1151
|
+
if f.is_zero():
|
|
1152
|
+
if verbose:
|
|
1153
|
+
print('This homomorphism cannot lift over a trivial homomorphism'
|
|
1154
|
+
' since it is non-trivial.')
|
|
1155
|
+
return None
|
|
1156
|
+
|
|
1157
|
+
xs = [f.solve(self(g)) for g in L.generators()]
|
|
1158
|
+
|
|
1159
|
+
# If some of the generators are not in the image of f, there is no
|
|
1160
|
+
# hope finding a lift.
|
|
1161
|
+
if None in xs:
|
|
1162
|
+
if verbose:
|
|
1163
|
+
print('The generators of the domain of this homomorphism do '
|
|
1164
|
+
'not map into the image of the homomorphism we are lifting over.')
|
|
1165
|
+
return None
|
|
1166
|
+
|
|
1167
|
+
# If L is free there are no relations to take into consideration.
|
|
1168
|
+
if not L.has_relations():
|
|
1169
|
+
return Hom(L, M)(xs)
|
|
1170
|
+
|
|
1171
|
+
# The degree of the lifted map f_.
|
|
1172
|
+
lift_deg = self.degree() - f.degree()
|
|
1173
|
+
|
|
1174
|
+
# Compute the kernel of f. The equations we will solve will live in
|
|
1175
|
+
# this submodule.
|
|
1176
|
+
iK = f.kernel_inclusion(top_dim=max([r.degree() + lift_deg for r in L.relations()]))
|
|
1177
|
+
|
|
1178
|
+
source_degs = [g.degree() + lift_deg for g in L.generators()]
|
|
1179
|
+
target_degs = [r.degree() + lift_deg for r in L.relations()]
|
|
1180
|
+
|
|
1181
|
+
# Act on the liftings xs by the relations.
|
|
1182
|
+
ys = []
|
|
1183
|
+
K = iK.domain()
|
|
1184
|
+
all_zero = True
|
|
1185
|
+
|
|
1186
|
+
for r in L.relations():
|
|
1187
|
+
target_degree = r.degree() + lift_deg
|
|
1188
|
+
|
|
1189
|
+
y = iK.solve(sum([c * x for c, x in zip(r.dense_coefficient_list(), xs)]))
|
|
1190
|
+
if y is None:
|
|
1191
|
+
if verbose:
|
|
1192
|
+
print('The homomorphism cannot be lifted in any '
|
|
1193
|
+
'way such that the relations of the domain are '
|
|
1194
|
+
'respected.')
|
|
1195
|
+
return None
|
|
1196
|
+
|
|
1197
|
+
if y.is_zero():
|
|
1198
|
+
dim = K.vector_presentation(target_degree).dimension()
|
|
1199
|
+
ys += dim * [0] # The zero vector of the appropriate dimension.
|
|
1200
|
+
else:
|
|
1201
|
+
all_zero = False
|
|
1202
|
+
ys += list(y.vector_presentation())
|
|
1203
|
+
|
|
1204
|
+
# If the initial guess already fits the relations, we are done.
|
|
1205
|
+
if all_zero:
|
|
1206
|
+
return Hom(L, M)(xs)
|
|
1207
|
+
|
|
1208
|
+
block_matrix, R = _create_relations_matrix(
|
|
1209
|
+
K, [r.dense_coefficient_list() for r in L.relations()], source_degs, target_degs)
|
|
1210
|
+
|
|
1211
|
+
try:
|
|
1212
|
+
solution = R.solve_right(vector(ys))
|
|
1213
|
+
except ValueError as error:
|
|
1214
|
+
if str(error) == 'matrix equation has no solutions':
|
|
1215
|
+
if verbose:
|
|
1216
|
+
print('The homomorphism cannot be lifted in any '
|
|
1217
|
+
'way such that the relations of the domain '
|
|
1218
|
+
'are respected: %s' % error)
|
|
1219
|
+
|
|
1220
|
+
return None
|
|
1221
|
+
else:
|
|
1222
|
+
raise ValueError(error)
|
|
1223
|
+
|
|
1224
|
+
# Interpret the solution vector as a vector in the direct sum
|
|
1225
|
+
# $ K_1\oplus K_2\oplus \ldots \oplus K_n $.
|
|
1226
|
+
n = 0
|
|
1227
|
+
for j, source_degree in enumerate(source_degs):
|
|
1228
|
+
|
|
1229
|
+
source_dimension = block_matrix[0][j].domain().dimension()
|
|
1230
|
+
|
|
1231
|
+
w = K.element_from_coordinates(
|
|
1232
|
+
solution[n:n + source_dimension], source_degree)
|
|
1233
|
+
|
|
1234
|
+
# Subtract the solution w_i from our initial choice of lift
|
|
1235
|
+
# for the generator g_i.
|
|
1236
|
+
xs[j] -= iK(w)
|
|
1237
|
+
|
|
1238
|
+
n += source_degree
|
|
1239
|
+
|
|
1240
|
+
return Hom(L, M)(xs)
|
|
1241
|
+
|
|
1242
|
+
def split(self, verbose=False):
|
|
1243
|
+
r"""
|
|
1244
|
+
Return a split of ``self``.
|
|
1245
|
+
|
|
1246
|
+
INPUT:
|
|
1247
|
+
|
|
1248
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
1249
|
+
|
|
1250
|
+
OUTPUT:
|
|
1251
|
+
|
|
1252
|
+
A homomorphism with the property that the composite homomorphism
|
|
1253
|
+
`S \circ f = id`, where `S` is ``self``, is The identity homomorphism
|
|
1254
|
+
If no such split exist, ``None`` is returned.
|
|
1255
|
+
|
|
1256
|
+
EXAMPLES::
|
|
1257
|
+
|
|
1258
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1259
|
+
sage: A = SteenrodAlgebra(2)
|
|
1260
|
+
sage: M = FPModule(A, [0,0], [[0, Sq(1)]])
|
|
1261
|
+
sage: N = FPModule(A, [0], [[Sq(1)]])
|
|
1262
|
+
sage: p = Hom(M, N)([N.generator(0), N.generator(0)])
|
|
1263
|
+
sage: s = p.split(); s
|
|
1264
|
+
Module morphism:
|
|
1265
|
+
From: Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1266
|
+
To: Finitely presented left module on 2 generators and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1267
|
+
Defn: g[0] |--> g[0, 1]
|
|
1268
|
+
sage: # Verify that `s` is a splitting:
|
|
1269
|
+
sage: p*s
|
|
1270
|
+
Module endomorphism of Finitely presented left module on 1 generator and 1 relation over mod 2 Steenrod algebra, milnor basis
|
|
1271
|
+
Defn: g[0] |--> g[0]
|
|
1272
|
+
|
|
1273
|
+
TESTS::
|
|
1274
|
+
|
|
1275
|
+
sage: F = FPModule(A, [0])
|
|
1276
|
+
sage: N = FPModule(A, [0], [[Sq(1)]])
|
|
1277
|
+
sage: p = Hom(F, N)([N.generator(0)])
|
|
1278
|
+
sage: p.split(verbose=True) is None
|
|
1279
|
+
The homomorphism cannot be lifted in any way such that the relations
|
|
1280
|
+
of the domain are respected: matrix equation has no solutions
|
|
1281
|
+
True
|
|
1282
|
+
|
|
1283
|
+
.. SEEALSO::
|
|
1284
|
+
|
|
1285
|
+
:meth:`lift`
|
|
1286
|
+
"""
|
|
1287
|
+
one = End(self.codomain()).identity()
|
|
1288
|
+
return one.lift(self, verbose)
|
|
1289
|
+
|
|
1290
|
+
def homology(self, f, top_dim=None, verbose=False):
|
|
1291
|
+
r"""
|
|
1292
|
+
Compute the sub-quotient module of `H(self, f) =
|
|
1293
|
+
\ker(self)/\operatorname{im}(f)` in a range of degrees.
|
|
1294
|
+
|
|
1295
|
+
For a pair of composable morphisms `f: M\to N` and `g: N \to Q` of
|
|
1296
|
+
finitely presented modules, the homology module is a finitely
|
|
1297
|
+
presented quotient of the kernel sub module `\ker(g) \subset N`.
|
|
1298
|
+
|
|
1299
|
+
INPUT:
|
|
1300
|
+
|
|
1301
|
+
- ``f`` -- a homomorphism with codomain equal to the domain of ``self``
|
|
1302
|
+
and image contained in the kernel of this homomorphism
|
|
1303
|
+
- ``top_dim`` -- integer (optional); used by this function to stop the
|
|
1304
|
+
computation at the given degree
|
|
1305
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
1306
|
+
|
|
1307
|
+
OUTPUT:
|
|
1308
|
+
|
|
1309
|
+
A quotient homomorphism `\ker(self) \to H`, where `H` is isomorphic
|
|
1310
|
+
to `H(self, f)` in degrees less than or equal to ``top_dim``.
|
|
1311
|
+
|
|
1312
|
+
.. NOTE::
|
|
1313
|
+
|
|
1314
|
+
If the algebra for this module is finite, then no ``top_dim`` needs
|
|
1315
|
+
to be specified in order to ensure that this function terminates.
|
|
1316
|
+
|
|
1317
|
+
EXAMPLES::
|
|
1318
|
+
|
|
1319
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1320
|
+
sage: A = SteenrodAlgebra(2, profile=(3,2,1))
|
|
1321
|
+
sage: M = FPModule(A, [0], [[Sq(3)]])
|
|
1322
|
+
sage: N = FPModule(A, [0], [[Sq(2,2)]])
|
|
1323
|
+
sage: F = FPModule(A, [0])
|
|
1324
|
+
sage: f = Hom(M,N)([A.Sq(2)*N.generator(0)])
|
|
1325
|
+
sage: g = Hom(F, M)([A.Sq(4)*A.Sq(1,2)*M.generator(0)])
|
|
1326
|
+
sage: ho = f.homology(g)
|
|
1327
|
+
sage: ho.codomain()
|
|
1328
|
+
Finitely presented left module on 1 generator and 5 relations over
|
|
1329
|
+
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
|
|
1330
|
+
sage: ho.codomain().is_trivial()
|
|
1331
|
+
False
|
|
1332
|
+
"""
|
|
1333
|
+
k = self.kernel_inclusion(top_dim, verbose)
|
|
1334
|
+
f_ = f.lift(k)
|
|
1335
|
+
if f_ is None:
|
|
1336
|
+
raise ValueError('the image of the given homomorphism is not contained '
|
|
1337
|
+
'in the kernel of this homomorphism; the homology is '
|
|
1338
|
+
'therefore not defined for this pair of maps')
|
|
1339
|
+
|
|
1340
|
+
return f_.cokernel_projection()
|
|
1341
|
+
|
|
1342
|
+
def suspension(self, t):
|
|
1343
|
+
r"""
|
|
1344
|
+
The suspension of this morphism by the given degree ``t``.
|
|
1345
|
+
|
|
1346
|
+
INPUT:
|
|
1347
|
+
|
|
1348
|
+
- ``t`` -- integer by which the morphism is suspended
|
|
1349
|
+
|
|
1350
|
+
OUTPUT: the morphism which is the suspension of ``self`` by the degree ``t``
|
|
1351
|
+
|
|
1352
|
+
EXAMPLES::
|
|
1353
|
+
|
|
1354
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1355
|
+
sage: A = SteenrodAlgebra(2)
|
|
1356
|
+
sage: F1 = FPModule(A, [4,5])
|
|
1357
|
+
sage: F2 = FPModule(A, [5])
|
|
1358
|
+
|
|
1359
|
+
sage: f = Hom(F1, F2)( ( F2([Sq(4)]), F2([Sq(5)]) ) ); f
|
|
1360
|
+
Module morphism:
|
|
1361
|
+
From: Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
|
|
1362
|
+
To: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
|
|
1363
|
+
Defn: g[4] |--> Sq(4)*g[5]
|
|
1364
|
+
g[5] |--> Sq(5)*g[5]
|
|
1365
|
+
|
|
1366
|
+
sage: e1 = F1([1, 0])
|
|
1367
|
+
sage: e2 = F1([0, 1])
|
|
1368
|
+
sage: f(e1)
|
|
1369
|
+
Sq(4)*g[5]
|
|
1370
|
+
sage: f(e2)
|
|
1371
|
+
Sq(5)*g[5]
|
|
1372
|
+
|
|
1373
|
+
sage: sf = f.suspension(4); sf
|
|
1374
|
+
Module morphism:
|
|
1375
|
+
From: Free graded left module on 2 generators over mod 2 Steenrod algebra, milnor basis
|
|
1376
|
+
To: Free graded left module on 1 generator over mod 2 Steenrod algebra, milnor basis
|
|
1377
|
+
Defn: g[8] |--> Sq(4)*g[9]
|
|
1378
|
+
g[9] |--> Sq(5)*g[9]
|
|
1379
|
+
|
|
1380
|
+
sage: sf.domain() is f.domain().suspension(4)
|
|
1381
|
+
True
|
|
1382
|
+
|
|
1383
|
+
sage: sf.codomain() is f.codomain().suspension(4)
|
|
1384
|
+
True
|
|
1385
|
+
"""
|
|
1386
|
+
if t == 0:
|
|
1387
|
+
return self
|
|
1388
|
+
|
|
1389
|
+
D = self.domain().suspension(t)
|
|
1390
|
+
C = self.codomain().suspension(t)
|
|
1391
|
+
return Hom(D, C)([C(x.lift_to_free().dense_coefficient_list())
|
|
1392
|
+
for x in self._values])
|
|
1393
|
+
|
|
1394
|
+
def cokernel_projection(self):
|
|
1395
|
+
r"""
|
|
1396
|
+
Return the map to the cokernel of ``self``.
|
|
1397
|
+
|
|
1398
|
+
OUTPUT:
|
|
1399
|
+
|
|
1400
|
+
The natural projection from the codomain of this homomorphism
|
|
1401
|
+
to its cokernel.
|
|
1402
|
+
|
|
1403
|
+
EXAMPLES::
|
|
1404
|
+
|
|
1405
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1406
|
+
sage: A1 = SteenrodAlgebra(2, profile=(2,1))
|
|
1407
|
+
sage: M = FPModule(A1, [0], [[Sq(2)]])
|
|
1408
|
+
sage: F = FPModule(A1, [0])
|
|
1409
|
+
|
|
1410
|
+
sage: r = Hom(F, M)([A1.Sq(1)*M.generator(0)])
|
|
1411
|
+
sage: co = r.cokernel_projection(); co
|
|
1412
|
+
Module morphism:
|
|
1413
|
+
From: Finitely presented left module on 1 generator and 1 relation over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [2, 1]
|
|
1414
|
+
To: Finitely presented left module on 1 generator and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [2, 1]
|
|
1415
|
+
Defn: g[0] |--> g[0]
|
|
1416
|
+
|
|
1417
|
+
sage: co.domain().is_trivial()
|
|
1418
|
+
False
|
|
1419
|
+
"""
|
|
1420
|
+
new_relations = ([x.dense_coefficient_list()
|
|
1421
|
+
for x in self.codomain().relations()] +
|
|
1422
|
+
[x.dense_coefficient_list() for x in self._values])
|
|
1423
|
+
|
|
1424
|
+
try:
|
|
1425
|
+
FPModule = self.base_ring()._fp_graded_module_class
|
|
1426
|
+
except AttributeError:
|
|
1427
|
+
from .module import FPModule
|
|
1428
|
+
|
|
1429
|
+
coker = FPModule(self.base_ring(),
|
|
1430
|
+
self.codomain().generator_degrees(),
|
|
1431
|
+
relations=tuple(new_relations))
|
|
1432
|
+
|
|
1433
|
+
projection = Hom(self.codomain(), coker)(coker.generators())
|
|
1434
|
+
|
|
1435
|
+
return projection
|
|
1436
|
+
|
|
1437
|
+
def kernel_inclusion(self, top_dim=None, verbose=False):
|
|
1438
|
+
r"""
|
|
1439
|
+
Return the kernel of ``self``.
|
|
1440
|
+
|
|
1441
|
+
INPUT:
|
|
1442
|
+
|
|
1443
|
+
- ``top_dim`` -- integer (optional); used by this function to stop the
|
|
1444
|
+
computation at the given degree
|
|
1445
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
1446
|
+
|
|
1447
|
+
OUTPUT:
|
|
1448
|
+
|
|
1449
|
+
A homomorphism into `\ker(self)` which is an isomorphism in
|
|
1450
|
+
degrees less than or equal to ``top_dim``.
|
|
1451
|
+
|
|
1452
|
+
.. NOTE::
|
|
1453
|
+
|
|
1454
|
+
If the algebra for this module is finite, then no ``top_dim`` needs
|
|
1455
|
+
to be specified in order to ensure that this function terminates.
|
|
1456
|
+
|
|
1457
|
+
EXAMPLES::
|
|
1458
|
+
|
|
1459
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1460
|
+
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
|
|
1461
|
+
sage: F = FPModule(A3, [1,3]);
|
|
1462
|
+
sage: L = FPModule(A3, [2,3], [[Sq(2),Sq(1)], [0,Sq(2)]]);
|
|
1463
|
+
sage: H = Hom(F, L);
|
|
1464
|
+
|
|
1465
|
+
sage: H([L((A3.Sq(1), 1)), L((0, A3.Sq(2)))]).kernel_inclusion() # long time
|
|
1466
|
+
Module morphism:
|
|
1467
|
+
From: Finitely presented left module on 2 generators and 1 relation over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
|
|
1468
|
+
To: Free graded left module on 2 generators over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
|
|
1469
|
+
Defn: g[3] |--> g[3]
|
|
1470
|
+
g[4] |--> Sq(0,1)*g[1]
|
|
1471
|
+
|
|
1472
|
+
sage: M = FPModule(A3, [0,7], [[Sq(1), 0], [Sq(2), 0], [Sq(4), 0], [Sq(8), Sq(1)], [0, Sq(7)], [0, Sq(0,1,1)+Sq(4,2)]])
|
|
1473
|
+
sage: F2 = FPModule(A3, [0], [[Sq(1)], [Sq(2)], [Sq(4)], [Sq(8)], [Sq(15)]])
|
|
1474
|
+
sage: H = Hom(M, F2)
|
|
1475
|
+
sage: f = H([F2([1]), F2([0])])
|
|
1476
|
+
|
|
1477
|
+
sage: K = f.kernel_inclusion(verbose=True, top_dim=17)
|
|
1478
|
+
1. Computing the generators of the kernel presentation:
|
|
1479
|
+
Resolving the kernel in the range of dimensions [0, 17]:
|
|
1480
|
+
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.
|
|
1481
|
+
2. Computing the relations of the kernel presentation:
|
|
1482
|
+
Computing using the profile:
|
|
1483
|
+
(4, 3, 2, 1)
|
|
1484
|
+
Resolving the kernel in the range of dimensions [7, 17]:
|
|
1485
|
+
7 8 9 10 11 12 13 14 15 16 17.
|
|
1486
|
+
|
|
1487
|
+
sage: K.domain().generators()
|
|
1488
|
+
(g[7],)
|
|
1489
|
+
sage: K.domain().relations()
|
|
1490
|
+
((Sq(0,1)+Sq(3))*g[7],
|
|
1491
|
+
(Sq(0,0,1)+Sq(1,2)+Sq(4,1))*g[7],
|
|
1492
|
+
Sq(9)*g[7],
|
|
1493
|
+
(Sq(0,1,1)+Sq(4,2))*g[7])
|
|
1494
|
+
|
|
1495
|
+
sage: K
|
|
1496
|
+
Module morphism:
|
|
1497
|
+
From: Finitely presented left module on 1 generator and 4 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
|
|
1498
|
+
To: Finitely presented left module on 2 generators and 6 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
|
|
1499
|
+
Defn: g[7] |--> g[7]
|
|
1500
|
+
"""
|
|
1501
|
+
if verbose:
|
|
1502
|
+
print('1. Computing the generators of the kernel presentation:')
|
|
1503
|
+
j0 = self._resolve_kernel(top_dim, verbose)
|
|
1504
|
+
if verbose:
|
|
1505
|
+
print('2. Computing the relations of the kernel presentation:')
|
|
1506
|
+
j1 = j0._resolve_kernel(top_dim, verbose)
|
|
1507
|
+
|
|
1508
|
+
# Create a module isomorphic to the ker(self).
|
|
1509
|
+
K = j1.fp_module()
|
|
1510
|
+
|
|
1511
|
+
# Return an injection of K into the domain of self such that
|
|
1512
|
+
# its image equals ker(self).
|
|
1513
|
+
return Hom(K, j0.codomain())(j0._values)
|
|
1514
|
+
|
|
1515
|
+
def image(self, top_dim=None, verbose=False):
|
|
1516
|
+
r"""
|
|
1517
|
+
Compute the image of ``self``.
|
|
1518
|
+
|
|
1519
|
+
INPUT:
|
|
1520
|
+
|
|
1521
|
+
- ``top_dim`` -- integer (optional); used by this function to stop the
|
|
1522
|
+
computation at the given degree
|
|
1523
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
1524
|
+
|
|
1525
|
+
OUTPUT:
|
|
1526
|
+
|
|
1527
|
+
A homomorphism into `\operatorname{im}(self)` that is an
|
|
1528
|
+
isomorphism in degrees less than or equal to ``top_dim``
|
|
1529
|
+
|
|
1530
|
+
.. NOTE::
|
|
1531
|
+
|
|
1532
|
+
If the algebra for this module is finite, then no ``top_dim``
|
|
1533
|
+
needs to be specified in order to ensure that this function
|
|
1534
|
+
terminates.
|
|
1535
|
+
|
|
1536
|
+
EXAMPLES::
|
|
1537
|
+
|
|
1538
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1539
|
+
sage: A3 = SteenrodAlgebra(2, profile=(4,3,2,1))
|
|
1540
|
+
sage: F = FPModule(A3, [1,3]);
|
|
1541
|
+
sage: L = FPModule(A3, [2,3], [[Sq(2),Sq(1)], [0,Sq(2)]]);
|
|
1542
|
+
sage: H = Hom(F, L);
|
|
1543
|
+
|
|
1544
|
+
sage: H([L((A3.Sq(1), 1)), L((0, A3.Sq(2)))]).image() # long time
|
|
1545
|
+
Module morphism:
|
|
1546
|
+
From: Finitely presented left module on 1 generator and 1 relation over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
|
|
1547
|
+
To: Finitely presented left module on 2 generators and 2 relations over sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [4, 3, 2, 1]
|
|
1548
|
+
Defn: g[3] |--> Sq(1)*g[2] + g[3]
|
|
1549
|
+
|
|
1550
|
+
sage: M = FPModule(A3, [0,7], [[Sq(1), 0], [Sq(2), 0], [Sq(4), 0], [Sq(8), Sq(1)], [0, Sq(7)], [0, Sq(0,1,1)+Sq(4,2)]])
|
|
1551
|
+
sage: F2 = FPModule(A3, [0], [[Sq(1)], [Sq(2)], [Sq(4)], [Sq(8)], [Sq(15)]])
|
|
1552
|
+
sage: H = Hom(M, F2)
|
|
1553
|
+
sage: f = H([F2([1]), F2([0])])
|
|
1554
|
+
sage: K = f.image(verbose=True, top_dim=17)
|
|
1555
|
+
1. Computing the generators of the image presentation:
|
|
1556
|
+
Resolving the image in the range of dimensions [0, 17]:
|
|
1557
|
+
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.
|
|
1558
|
+
2. Computing the relations of the image presentation:
|
|
1559
|
+
Computing using the profile:
|
|
1560
|
+
(4, 3, 2, 1)
|
|
1561
|
+
Resolving the kernel in the range of dimensions [0, 17]:
|
|
1562
|
+
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17.
|
|
1563
|
+
|
|
1564
|
+
sage: K.is_injective() # long time
|
|
1565
|
+
True
|
|
1566
|
+
sage: K.domain().generator_degrees()
|
|
1567
|
+
(0,)
|
|
1568
|
+
sage: K.domain().relations()
|
|
1569
|
+
(Sq(1)*g[0], Sq(2)*g[0], Sq(4)*g[0], Sq(8)*g[0])
|
|
1570
|
+
sage: K.domain().is_trivial()
|
|
1571
|
+
False
|
|
1572
|
+
"""
|
|
1573
|
+
if verbose:
|
|
1574
|
+
print('1. Computing the generators of the image presentation:')
|
|
1575
|
+
j0 = self._resolve_image(top_dim, verbose)
|
|
1576
|
+
if verbose:
|
|
1577
|
+
print('2. Computing the relations of the image presentation:')
|
|
1578
|
+
j1 = j0._resolve_kernel(top_dim, verbose)
|
|
1579
|
+
|
|
1580
|
+
# Create a module isomorphic to the im(self).
|
|
1581
|
+
I = j1.fp_module()
|
|
1582
|
+
|
|
1583
|
+
# Return an injection of I into the codomain of self such that
|
|
1584
|
+
# its image equals im(self)
|
|
1585
|
+
return Hom(I, j0.codomain())(j0._values)
|
|
1586
|
+
|
|
1587
|
+
def is_injective(self, top_dim=None, verbose=False) -> bool:
|
|
1588
|
+
r"""
|
|
1589
|
+
Return ``True`` if and only if ``self`` has a trivial kernel.
|
|
1590
|
+
|
|
1591
|
+
INPUT:
|
|
1592
|
+
|
|
1593
|
+
- ``top_dim`` -- integer (optional); used by this function to stop the
|
|
1594
|
+
computation at the given degree
|
|
1595
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
1596
|
+
|
|
1597
|
+
EXAMPLES::
|
|
1598
|
+
|
|
1599
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1600
|
+
sage: A = SteenrodAlgebra(2)
|
|
1601
|
+
|
|
1602
|
+
sage: K = FPModule(A, [2], [[Sq(2)]])
|
|
1603
|
+
sage: HZ = FPModule(A, [0], [[Sq(1)]])
|
|
1604
|
+
|
|
1605
|
+
sage: f = Hom(K, HZ)([Sq(2)*HZ([1])])
|
|
1606
|
+
sage: f.is_injective(top_dim=23)
|
|
1607
|
+
True
|
|
1608
|
+
|
|
1609
|
+
TESTS::
|
|
1610
|
+
|
|
1611
|
+
sage: Z = FPModule(A, [])
|
|
1612
|
+
sage: Hom(Z, HZ).zero().is_injective(top_dim=8)
|
|
1613
|
+
True
|
|
1614
|
+
"""
|
|
1615
|
+
j0 = self._resolve_kernel(top_dim, verbose)
|
|
1616
|
+
return j0.domain().is_trivial()
|
|
1617
|
+
|
|
1618
|
+
def is_surjective(self) -> bool:
|
|
1619
|
+
r"""
|
|
1620
|
+
Return ``True`` if and only if ``self`` has a trivial cokernel.
|
|
1621
|
+
|
|
1622
|
+
EXAMPLES::
|
|
1623
|
+
|
|
1624
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1625
|
+
sage: A = SteenrodAlgebra(2)
|
|
1626
|
+
sage: F = FPModule(A, [0])
|
|
1627
|
+
|
|
1628
|
+
sage: f = Hom(F,F)([Sq(1)*F.generator(0)])
|
|
1629
|
+
sage: f.is_surjective()
|
|
1630
|
+
False
|
|
1631
|
+
|
|
1632
|
+
TESTS::
|
|
1633
|
+
|
|
1634
|
+
sage: Z = FPModule(A, [])
|
|
1635
|
+
sage: Hom(F, Z).zero().is_surjective()
|
|
1636
|
+
True
|
|
1637
|
+
"""
|
|
1638
|
+
return self.cokernel_projection().is_zero()
|
|
1639
|
+
|
|
1640
|
+
def _resolve_kernel(self, top_dim=None, verbose=False):
|
|
1641
|
+
r"""
|
|
1642
|
+
Resolve the kernel of ``self`` by a free module.
|
|
1643
|
+
|
|
1644
|
+
INPUT:
|
|
1645
|
+
|
|
1646
|
+
- ``top_dim`` -- integer (optional); used by this function to stop the
|
|
1647
|
+
computation at the given degree
|
|
1648
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
1649
|
+
|
|
1650
|
+
OUTPUT:
|
|
1651
|
+
|
|
1652
|
+
A homomorphism `j: F \rightarrow D`, where `D` is the domain of
|
|
1653
|
+
``self`` and `F` is free and such that `\ker(self) = \operatorname{im}(j)`
|
|
1654
|
+
in all degrees less than or equal to ``top_dim``.
|
|
1655
|
+
|
|
1656
|
+
.. NOTE::
|
|
1657
|
+
|
|
1658
|
+
If the algebra for this module is finite dimensional, then no
|
|
1659
|
+
``top_dim`` needs to be specified in order to ensure that
|
|
1660
|
+
this function terminates.
|
|
1661
|
+
|
|
1662
|
+
TESTS::
|
|
1663
|
+
|
|
1664
|
+
sage: # needs sage.libs.flint
|
|
1665
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1666
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
1667
|
+
sage: F = s.free_graded_module([0,0])
|
|
1668
|
+
sage: L = FPModule(s, [0,0], [[s[3],s[2,1]], [0,s[2]]])
|
|
1669
|
+
sage: f = Hom(F, L)([L([s[2], 0]), L([0, s[2]])])
|
|
1670
|
+
sage: f._resolve_kernel() # long time
|
|
1671
|
+
Traceback (most recent call last):
|
|
1672
|
+
...
|
|
1673
|
+
ValueError: a top dimension must be specified for this calculation to terminate
|
|
1674
|
+
sage: f._resolve_kernel(top_dim=10)
|
|
1675
|
+
Module morphism:
|
|
1676
|
+
From: Free graded left module on 2 generators over Symmetric Functions over Rational Field in the Schur basis
|
|
1677
|
+
To: Free graded left module on 2 generators over Symmetric Functions over Rational Field in the Schur basis
|
|
1678
|
+
Defn: s[]*g[0] |--> s[]*g[0, 1]
|
|
1679
|
+
s[]*g[3] |--> s[3]*g[0, 0]
|
|
1680
|
+
"""
|
|
1681
|
+
# Let
|
|
1682
|
+
#
|
|
1683
|
+
# 1) `j` be a homomorphism into `\ker(self)`, and
|
|
1684
|
+
# 2) 'n' be an integer.
|
|
1685
|
+
#
|
|
1686
|
+
# The induction loop starts each iteration assuming that `j` is onto
|
|
1687
|
+
# the kernel in degrees below `n`. Each iteration of the loop then
|
|
1688
|
+
# extends the map `j` minimally so that `j_n` becomes onto the kernel.
|
|
1689
|
+
#
|
|
1690
|
+
# This induction step is then repeated for all `n \leq` ``top_dim``.
|
|
1691
|
+
#
|
|
1692
|
+
|
|
1693
|
+
domain = self.domain()
|
|
1694
|
+
R = self.base_ring()
|
|
1695
|
+
|
|
1696
|
+
if self.is_zero():
|
|
1697
|
+
# Epsilon: F_0 -> M
|
|
1698
|
+
F_0 = R.free_graded_module(domain.generator_degrees())
|
|
1699
|
+
epsilon = Hom(F_0, domain)(tuple(domain.generators()))
|
|
1700
|
+
return epsilon
|
|
1701
|
+
|
|
1702
|
+
# Create the trivial module F_ to start with.
|
|
1703
|
+
F_ = R.free_graded_module(())
|
|
1704
|
+
j = Hom(F_, domain).zero()
|
|
1705
|
+
|
|
1706
|
+
dim = domain.connectivity()
|
|
1707
|
+
if dim == infinity:
|
|
1708
|
+
if verbose:
|
|
1709
|
+
print('The domain of the morphism is trivial, so there is nothing to resolve.')
|
|
1710
|
+
return j
|
|
1711
|
+
|
|
1712
|
+
if not R.dimension() < infinity:
|
|
1713
|
+
limit = infinity
|
|
1714
|
+
else:
|
|
1715
|
+
limit = _top_dim(R) + max(domain.generator_degrees())
|
|
1716
|
+
|
|
1717
|
+
if top_dim is not None:
|
|
1718
|
+
limit = min(top_dim, limit)
|
|
1719
|
+
|
|
1720
|
+
if limit == infinity:
|
|
1721
|
+
raise ValueError('a top dimension must be specified for this calculation to terminate')
|
|
1722
|
+
|
|
1723
|
+
if verbose:
|
|
1724
|
+
if dim > limit:
|
|
1725
|
+
print('The dimension range is empty: [%d, %d]' % (dim, limit))
|
|
1726
|
+
else:
|
|
1727
|
+
print('Resolving the kernel in the range of dimensions [%d, %d]:' % (dim, limit), end='')
|
|
1728
|
+
|
|
1729
|
+
# The induction loop.
|
|
1730
|
+
for n in range(dim, limit + 1):
|
|
1731
|
+
|
|
1732
|
+
if verbose:
|
|
1733
|
+
print(' %d' % n, end='')
|
|
1734
|
+
|
|
1735
|
+
# We have taken care of the case when self is zero, so the
|
|
1736
|
+
# vector presentation exists.
|
|
1737
|
+
self_n = self.vector_presentation(n)
|
|
1738
|
+
kernel_n = self_n.kernel()
|
|
1739
|
+
|
|
1740
|
+
if not kernel_n:
|
|
1741
|
+
continue
|
|
1742
|
+
|
|
1743
|
+
generator_degrees = tuple(x.degree() for x in F_.generators())
|
|
1744
|
+
|
|
1745
|
+
if j.is_zero():
|
|
1746
|
+
# The map j is not onto in degree `n` of the kernel.
|
|
1747
|
+
new_generator_degrees = kernel_n.rank() * (n,)
|
|
1748
|
+
F_ = R.free_graded_module(generator_degrees + new_generator_degrees)
|
|
1749
|
+
|
|
1750
|
+
new_values = tuple([
|
|
1751
|
+
domain.element_from_coordinates(q, n) for q in kernel_n.basis()])
|
|
1752
|
+
|
|
1753
|
+
else:
|
|
1754
|
+
Q_n = kernel_n.quotient(j.vector_presentation(n).image())
|
|
1755
|
+
|
|
1756
|
+
if not Q_n.rank():
|
|
1757
|
+
continue
|
|
1758
|
+
|
|
1759
|
+
# The map j is not onto in degree `n` of the kernel.
|
|
1760
|
+
new_generator_degrees = Q_n.rank() * (n,)
|
|
1761
|
+
F_ = R.free_graded_module(generator_degrees + new_generator_degrees)
|
|
1762
|
+
|
|
1763
|
+
new_values = tuple([
|
|
1764
|
+
domain.element_from_coordinates(Q_n.lift(q), n) for q in Q_n.basis()])
|
|
1765
|
+
|
|
1766
|
+
# Create a new homomorphism which is surjective onto the kernel
|
|
1767
|
+
# in all degrees less than, and including `n`.
|
|
1768
|
+
j = Hom(F_, domain)(j._values + new_values)
|
|
1769
|
+
|
|
1770
|
+
if verbose:
|
|
1771
|
+
print('.')
|
|
1772
|
+
return j
|
|
1773
|
+
|
|
1774
|
+
def _resolve_image(self, top_dim=None, verbose=False):
|
|
1775
|
+
r"""
|
|
1776
|
+
Resolve the image of ``self`` by a free module.
|
|
1777
|
+
|
|
1778
|
+
INPUT:
|
|
1779
|
+
|
|
1780
|
+
- ``top_dim`` -- integer (optional); used by this function to stop the
|
|
1781
|
+
computation at the given degree
|
|
1782
|
+
- ``verbose`` -- boolean (default: ``False``); enable progress messages
|
|
1783
|
+
|
|
1784
|
+
OUTPUT:
|
|
1785
|
+
|
|
1786
|
+
A homomorphism `j: F \rightarrow C` where `C` is the codomain
|
|
1787
|
+
of ``self``, where `F` is free, and
|
|
1788
|
+
`\operatorname{im}(self) = \operatorname{im}(j)` in all degrees less
|
|
1789
|
+
than or equal to ``top_dim``.
|
|
1790
|
+
|
|
1791
|
+
.. NOTE::
|
|
1792
|
+
|
|
1793
|
+
If the algebra for this module is finite, then no ``top_dim`` needs
|
|
1794
|
+
to be specified in order to ensure that this function terminates.
|
|
1795
|
+
|
|
1796
|
+
TESTS::
|
|
1797
|
+
|
|
1798
|
+
sage: # needs sage.libs.flint
|
|
1799
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1800
|
+
sage: s = SymmetricFunctions(QQ).s()
|
|
1801
|
+
sage: F = s.free_graded_module([0,0])
|
|
1802
|
+
sage: L = FPModule(s, [0,0], [[s[3],s[2,1]], [0,s[2]]])
|
|
1803
|
+
sage: f = Hom(F, L)([L([s[2], 0]), L([0, s[2]])])
|
|
1804
|
+
sage: f._resolve_image()
|
|
1805
|
+
Traceback (most recent call last):
|
|
1806
|
+
...
|
|
1807
|
+
ValueError: a top dimension must be specified for this calculation to terminate
|
|
1808
|
+
sage: f._resolve_image(top_dim=10)
|
|
1809
|
+
Module morphism:
|
|
1810
|
+
From: Free graded left module on 1 generator over Symmetric Functions over Rational Field in the Schur basis
|
|
1811
|
+
To: Finitely presented left module on 2 generators and 2 relations over Symmetric Functions over Rational Field in the Schur basis
|
|
1812
|
+
Defn: s[]*g[2] |--> s[2]*g[0, 0]
|
|
1813
|
+
"""
|
|
1814
|
+
# Let
|
|
1815
|
+
#
|
|
1816
|
+
# 1) `j` be a homomorphism into `\im(self)`, and
|
|
1817
|
+
# 2) 'n' be an integer.
|
|
1818
|
+
#
|
|
1819
|
+
# The induction loop starts each iteration assuming that `j` is onto
|
|
1820
|
+
# the image in degrees below `n`. Each iteration of the loop then
|
|
1821
|
+
# extends the map `j` minimally so that `j_n` becomes onto the image.
|
|
1822
|
+
#
|
|
1823
|
+
# This induction step is then repeated for all `n \leq` ``top_dim``.
|
|
1824
|
+
#
|
|
1825
|
+
|
|
1826
|
+
# Create the trivial module F_ to start with.
|
|
1827
|
+
R = self.base_ring()
|
|
1828
|
+
codomain = self.codomain()
|
|
1829
|
+
F_ = R.free_graded_module(())
|
|
1830
|
+
j = Hom(F_, codomain).zero()
|
|
1831
|
+
|
|
1832
|
+
dim = self.codomain().connectivity()
|
|
1833
|
+
if dim == infinity:
|
|
1834
|
+
if verbose:
|
|
1835
|
+
print('The codomain of the morphism is trivial, so there is nothing to resolve.')
|
|
1836
|
+
return j
|
|
1837
|
+
|
|
1838
|
+
try:
|
|
1839
|
+
self_degree = self.degree()
|
|
1840
|
+
except ValueError:
|
|
1841
|
+
if verbose:
|
|
1842
|
+
print('The homomorphism is trivial, so there is nothing to resolve.')
|
|
1843
|
+
return j
|
|
1844
|
+
|
|
1845
|
+
degree_values = [0] + [v.degree() for v in self._values if v]
|
|
1846
|
+
limit = (infinity if not R.dimension() < infinity else
|
|
1847
|
+
(_top_dim(R) + max(degree_values)))
|
|
1848
|
+
|
|
1849
|
+
if top_dim is not None:
|
|
1850
|
+
limit = min(top_dim, limit)
|
|
1851
|
+
|
|
1852
|
+
if limit == infinity:
|
|
1853
|
+
raise ValueError('a top dimension must be specified for this calculation to terminate')
|
|
1854
|
+
|
|
1855
|
+
if verbose:
|
|
1856
|
+
if dim > limit:
|
|
1857
|
+
print('The dimension range is empty: [%d, %d]' % (dim, limit))
|
|
1858
|
+
else:
|
|
1859
|
+
print('Resolving the image in the range of dimensions [%d, %d]:' % (dim, limit), end='')
|
|
1860
|
+
|
|
1861
|
+
for n in range(dim, limit + 1):
|
|
1862
|
+
|
|
1863
|
+
if verbose:
|
|
1864
|
+
print(' %d' % n, end='')
|
|
1865
|
+
|
|
1866
|
+
self_n = self.vector_presentation(n - self_degree)
|
|
1867
|
+
image_n = self_n.image()
|
|
1868
|
+
|
|
1869
|
+
if image_n.dimension() == 0:
|
|
1870
|
+
continue
|
|
1871
|
+
|
|
1872
|
+
generator_degrees = tuple(x.degree() for x in F_.generators())
|
|
1873
|
+
if j.is_zero():
|
|
1874
|
+
# The map j is not onto in degree `n` of the image.
|
|
1875
|
+
new_generator_degrees = image_n.rank() * (n,)
|
|
1876
|
+
F_ = R.free_graded_module(generator_degrees + new_generator_degrees)
|
|
1877
|
+
|
|
1878
|
+
new_values = tuple([
|
|
1879
|
+
self.codomain().element_from_coordinates(q, n) for q in image_n.basis()])
|
|
1880
|
+
|
|
1881
|
+
else:
|
|
1882
|
+
|
|
1883
|
+
j_n = j.vector_presentation(n)
|
|
1884
|
+
Q_n = image_n.quotient(j_n.image())
|
|
1885
|
+
|
|
1886
|
+
if Q_n.dimension() == 0:
|
|
1887
|
+
continue
|
|
1888
|
+
|
|
1889
|
+
# The map j is not onto in degree `n` of the image.
|
|
1890
|
+
new_generator_degrees = Q_n.rank() * (n,)
|
|
1891
|
+
F_ = R.free_graded_module(generator_degrees + new_generator_degrees)
|
|
1892
|
+
|
|
1893
|
+
new_values = tuple([
|
|
1894
|
+
self.codomain().element_from_coordinates(Q_n.lift(q), n) for q in Q_n.basis()])
|
|
1895
|
+
|
|
1896
|
+
# Create a new homomorphism which is surjective onto the image
|
|
1897
|
+
# in all degrees less than, and including `n`.
|
|
1898
|
+
j = Hom(F_, self.codomain())(j._values + new_values)
|
|
1899
|
+
|
|
1900
|
+
if verbose:
|
|
1901
|
+
print('.')
|
|
1902
|
+
return j
|
|
1903
|
+
|
|
1904
|
+
def fp_module(self):
|
|
1905
|
+
r"""
|
|
1906
|
+
Create a finitely presented module from ``self``.
|
|
1907
|
+
|
|
1908
|
+
OUTPUT:
|
|
1909
|
+
|
|
1910
|
+
The finitely presented module having presentation equal to ``self``
|
|
1911
|
+
as long as the domain and codomain are free.
|
|
1912
|
+
|
|
1913
|
+
EXAMPLES:
|
|
1914
|
+
|
|
1915
|
+
We construct examples with free modules that are presented
|
|
1916
|
+
with a redundant relation::
|
|
1917
|
+
|
|
1918
|
+
sage: from sage.modules.fp_graded.module import FPModule
|
|
1919
|
+
sage: A = SteenrodAlgebra(2)
|
|
1920
|
+
sage: F1 = FPModule(A, (2,), [[0]])
|
|
1921
|
+
sage: F2 = FPModule(A, (0,), [[0]])
|
|
1922
|
+
sage: v = F2([Sq(2)])
|
|
1923
|
+
sage: pres = Hom(F1, F2)([v])
|
|
1924
|
+
sage: M = pres.fp_module(); M
|
|
1925
|
+
Finitely presented left module on 1 generator and 1 relation over
|
|
1926
|
+
mod 2 Steenrod algebra, milnor basis
|
|
1927
|
+
sage: M.generator_degrees()
|
|
1928
|
+
(0,)
|
|
1929
|
+
sage: M.relations()
|
|
1930
|
+
(Sq(2)*g[0],)
|
|
1931
|
+
|
|
1932
|
+
sage: F2 = A.free_graded_module((0,))
|
|
1933
|
+
sage: v = F2([Sq(2)])
|
|
1934
|
+
sage: pres = Hom(F1, F2)([v])
|
|
1935
|
+
sage: M = pres.fp_module(); M
|
|
1936
|
+
Finitely presented left module on 1 generator and 1 relation over
|
|
1937
|
+
mod 2 Steenrod algebra, milnor basis
|
|
1938
|
+
sage: M.generator_degrees()
|
|
1939
|
+
(0,)
|
|
1940
|
+
sage: M.relations()
|
|
1941
|
+
(Sq(2)*g[0],)
|
|
1942
|
+
|
|
1943
|
+
sage: F3 = FPModule(A, (0,), [[Sq(4)]])
|
|
1944
|
+
sage: v = F3([Sq(2)])
|
|
1945
|
+
sage: pres = Hom(F1, F3)([v])
|
|
1946
|
+
sage: pres.fp_module()
|
|
1947
|
+
Traceback (most recent call last):
|
|
1948
|
+
...
|
|
1949
|
+
ValueError: this is not a morphism between free modules
|
|
1950
|
+
"""
|
|
1951
|
+
if self.domain().has_relations() or self.codomain().has_relations():
|
|
1952
|
+
raise ValueError("this is not a morphism between free modules")
|
|
1953
|
+
try:
|
|
1954
|
+
FPModule = self.base_ring()._fp_graded_module_class
|
|
1955
|
+
except AttributeError:
|
|
1956
|
+
from .module import FPModule
|
|
1957
|
+
return FPModule(self.base_ring(),
|
|
1958
|
+
self.codomain().generator_degrees(),
|
|
1959
|
+
tuple([r.dense_coefficient_list() for r in self._values]))
|
|
1960
|
+
|
|
1961
|
+
|
|
1962
|
+
@cached_function
|
|
1963
|
+
def _top_dim(algebra):
|
|
1964
|
+
r"""
|
|
1965
|
+
The top dimension of ``algebra``.
|
|
1966
|
+
|
|
1967
|
+
This returns infinity if the algebra is infinite-dimensional. If
|
|
1968
|
+
the algebra has a ``top_class`` method, then it is used in the
|
|
1969
|
+
computation; otherwise the computation may be slow.
|
|
1970
|
+
|
|
1971
|
+
EXAMPLES::
|
|
1972
|
+
|
|
1973
|
+
sage: from sage.modules.fp_graded.morphism import _top_dim
|
|
1974
|
+
sage: E.<x,y,z> = ExteriorAlgebra(QQ)
|
|
1975
|
+
sage: _top_dim(E)
|
|
1976
|
+
3
|
|
1977
|
+
|
|
1978
|
+
sage: _top_dim(SteenrodAlgebra(2, profile=(3,2,1)))
|
|
1979
|
+
23
|
|
1980
|
+
"""
|
|
1981
|
+
if not algebra.dimension() < infinity:
|
|
1982
|
+
return infinity
|
|
1983
|
+
try:
|
|
1984
|
+
alg_top_dim = algebra.top_class().degree()
|
|
1985
|
+
except AttributeError:
|
|
1986
|
+
# This could be very slow, but it should handle the case
|
|
1987
|
+
# when the algebra is finite-dimensional but has no
|
|
1988
|
+
# top_class method, e.g., exterior algebras.
|
|
1989
|
+
alg_top_dim = max(a.degree() for a in algebra.basis())
|
|
1990
|
+
return alg_top_dim
|