passagemath-modules 10.6.31rc3__cp314-cp314-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +5 -0
- passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_modules.libs/libgfortran-67378ab2.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-28992bcb.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-23768756.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-7897025b.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-e34bb864.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-503f0c35.3.29.so +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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-aarch64-linux-musl.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-aarch64-linux-musl.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.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-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-aarch64-linux-musl.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-aarch64-linux-musl.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-aarch64-linux-musl.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,1745 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
r"""
|
|
3
|
+
Morphisms defined by a matrix
|
|
4
|
+
|
|
5
|
+
A matrix morphism is a morphism that is defined by multiplication
|
|
6
|
+
by a matrix. Elements of domain must either have a method
|
|
7
|
+
``vector()`` that returns a vector that the defining
|
|
8
|
+
matrix can hit from the left, or be coercible into vector space of
|
|
9
|
+
appropriate dimension.
|
|
10
|
+
|
|
11
|
+
EXAMPLES::
|
|
12
|
+
|
|
13
|
+
sage: from sage.modules.matrix_morphism import MatrixMorphism, is_MatrixMorphism
|
|
14
|
+
sage: V = QQ^3
|
|
15
|
+
sage: T = End(V)
|
|
16
|
+
sage: M = MatrixSpace(QQ,3)
|
|
17
|
+
sage: I = M.identity_matrix()
|
|
18
|
+
sage: m = MatrixMorphism(T, I); m
|
|
19
|
+
Morphism defined by the matrix
|
|
20
|
+
[1 0 0]
|
|
21
|
+
[0 1 0]
|
|
22
|
+
[0 0 1]
|
|
23
|
+
sage: m.charpoly('x') # needs sage.libs.pari
|
|
24
|
+
x^3 - 3*x^2 + 3*x - 1
|
|
25
|
+
sage: m.base_ring()
|
|
26
|
+
Rational Field
|
|
27
|
+
sage: m.det()
|
|
28
|
+
1
|
|
29
|
+
sage: m.fcp('x') # needs sage.libs.pari
|
|
30
|
+
(x - 1)^3
|
|
31
|
+
sage: m.matrix()
|
|
32
|
+
[1 0 0]
|
|
33
|
+
[0 1 0]
|
|
34
|
+
[0 0 1]
|
|
35
|
+
sage: m.rank()
|
|
36
|
+
3
|
|
37
|
+
sage: m.trace()
|
|
38
|
+
3
|
|
39
|
+
|
|
40
|
+
AUTHOR:
|
|
41
|
+
|
|
42
|
+
- William Stein: initial versions
|
|
43
|
+
|
|
44
|
+
- David Joyner (2005-12-17): added examples
|
|
45
|
+
|
|
46
|
+
- William Stein (2005-01-07): added __reduce__
|
|
47
|
+
|
|
48
|
+
- Craig Citro (2008-03-18): refactored MatrixMorphism class
|
|
49
|
+
|
|
50
|
+
- Rob Beezer (2011-07-15): additional methods, bug fixes, documentation
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
import sage.categories.morphism
|
|
54
|
+
import sage.categories.homset
|
|
55
|
+
from sage.categories.finite_dimensional_modules_with_basis import FiniteDimensionalModulesWithBasis
|
|
56
|
+
from sage.structure.all import Sequence, parent
|
|
57
|
+
from sage.structure.richcmp import richcmp, op_NE, op_EQ
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def is_MatrixMorphism(x):
|
|
61
|
+
"""
|
|
62
|
+
Return ``True`` if x is a Matrix morphism of free modules.
|
|
63
|
+
|
|
64
|
+
This function is deprecated.
|
|
65
|
+
|
|
66
|
+
EXAMPLES::
|
|
67
|
+
|
|
68
|
+
sage: V = ZZ^2; phi = V.hom([3*V.0, 2*V.1])
|
|
69
|
+
sage: sage.modules.matrix_morphism.is_MatrixMorphism(phi)
|
|
70
|
+
doctest:warning...
|
|
71
|
+
DeprecationWarning: is_MatrixMorphism is deprecated;
|
|
72
|
+
use isinstance(..., MatrixMorphism_abstract) or categories instead
|
|
73
|
+
See https://github.com/sagemath/sage/issues/37731 for details.
|
|
74
|
+
True
|
|
75
|
+
sage: sage.modules.matrix_morphism.is_MatrixMorphism(3)
|
|
76
|
+
False
|
|
77
|
+
"""
|
|
78
|
+
from sage.misc.superseded import deprecation
|
|
79
|
+
deprecation(37731,
|
|
80
|
+
"is_MatrixMorphism is deprecated; "
|
|
81
|
+
"use isinstance(..., MatrixMorphism_abstract) or categories instead")
|
|
82
|
+
return isinstance(x, MatrixMorphism_abstract)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class MatrixMorphism_abstract(sage.categories.morphism.Morphism):
|
|
86
|
+
|
|
87
|
+
# Copy in methods that delegate to self.matrix.
|
|
88
|
+
# This is needed because MatrixMorphism_abstract is subclassed
|
|
89
|
+
# for use with parents that are merely set up as additive abelian groups,
|
|
90
|
+
# but not as ZZ-modules; see sage.modular.abvar.
|
|
91
|
+
|
|
92
|
+
characteristic_polynomial = charpoly = FiniteDimensionalModulesWithBasis.Homsets.Endset.ElementMethods.characteristic_polynomial
|
|
93
|
+
det = determinant = FiniteDimensionalModulesWithBasis.Homsets.Endset.ElementMethods.determinant
|
|
94
|
+
fcp = FiniteDimensionalModulesWithBasis.Homsets.Endset.ElementMethods.fcp
|
|
95
|
+
trace = FiniteDimensionalModulesWithBasis.Homsets.Endset.ElementMethods.trace
|
|
96
|
+
|
|
97
|
+
def __init__(self, parent, side='left'):
|
|
98
|
+
"""
|
|
99
|
+
INPUT:
|
|
100
|
+
|
|
101
|
+
- ``parent`` -- a homspace
|
|
102
|
+
|
|
103
|
+
- ``A`` -- matrix
|
|
104
|
+
|
|
105
|
+
EXAMPLES::
|
|
106
|
+
|
|
107
|
+
sage: from sage.modules.matrix_morphism import MatrixMorphism
|
|
108
|
+
sage: T = End(ZZ^3)
|
|
109
|
+
sage: M = MatrixSpace(ZZ,3)
|
|
110
|
+
sage: I = M.identity_matrix()
|
|
111
|
+
sage: A = MatrixMorphism(T, I)
|
|
112
|
+
sage: loads(A.dumps()) == A
|
|
113
|
+
True
|
|
114
|
+
"""
|
|
115
|
+
if not isinstance(parent, sage.categories.homset.Homset):
|
|
116
|
+
raise TypeError("parent must be a Hom space")
|
|
117
|
+
if side not in ["left", "right"]:
|
|
118
|
+
raise ValueError("the argument side must be either 'left' or 'right'")
|
|
119
|
+
self._side = side
|
|
120
|
+
sage.categories.morphism.Morphism.__init__(self, parent)
|
|
121
|
+
|
|
122
|
+
def _richcmp_(self, other, op):
|
|
123
|
+
"""
|
|
124
|
+
Rich comparison of morphisms.
|
|
125
|
+
|
|
126
|
+
EXAMPLES::
|
|
127
|
+
|
|
128
|
+
sage: V = ZZ^2
|
|
129
|
+
sage: phi = V.hom([3*V.0, 2*V.1])
|
|
130
|
+
sage: psi = V.hom([5*V.0, 5*V.1])
|
|
131
|
+
sage: id = V.hom([V.0, V.1])
|
|
132
|
+
sage: phi == phi
|
|
133
|
+
True
|
|
134
|
+
sage: phi == psi
|
|
135
|
+
False
|
|
136
|
+
sage: psi == End(V)(5)
|
|
137
|
+
True
|
|
138
|
+
sage: psi == 5 * id
|
|
139
|
+
True
|
|
140
|
+
sage: psi == 5 # no coercion
|
|
141
|
+
False
|
|
142
|
+
sage: id == End(V).identity()
|
|
143
|
+
True
|
|
144
|
+
"""
|
|
145
|
+
if not isinstance(other, MatrixMorphism) or op not in (op_EQ, op_NE):
|
|
146
|
+
# Generic comparison
|
|
147
|
+
return sage.categories.morphism.Morphism._richcmp_(self, other, op)
|
|
148
|
+
return richcmp(self.matrix(), other.matrix(), op)
|
|
149
|
+
|
|
150
|
+
def _call_(self, x):
|
|
151
|
+
"""
|
|
152
|
+
Evaluate this matrix morphism at an element of the domain.
|
|
153
|
+
|
|
154
|
+
.. NOTE::
|
|
155
|
+
|
|
156
|
+
Coercion is done in the generic :meth:`__call__` method,
|
|
157
|
+
which calls this method.
|
|
158
|
+
|
|
159
|
+
EXAMPLES::
|
|
160
|
+
|
|
161
|
+
sage: V = QQ^3; W = QQ^2
|
|
162
|
+
sage: H = Hom(V, W); H
|
|
163
|
+
Set of Morphisms (Linear Transformations) from
|
|
164
|
+
Vector space of dimension 3 over Rational Field to
|
|
165
|
+
Vector space of dimension 2 over Rational Field
|
|
166
|
+
sage: phi = H(matrix(QQ, 3, 2, range(6))); phi
|
|
167
|
+
Vector space morphism represented by the matrix:
|
|
168
|
+
[0 1]
|
|
169
|
+
[2 3]
|
|
170
|
+
[4 5]
|
|
171
|
+
Domain: Vector space of dimension 3 over Rational Field
|
|
172
|
+
Codomain: Vector space of dimension 2 over Rational Field
|
|
173
|
+
sage: phi(V.0)
|
|
174
|
+
(0, 1)
|
|
175
|
+
sage: phi(V([1, 2, 3]))
|
|
176
|
+
(16, 22)
|
|
177
|
+
|
|
178
|
+
Last, we have a situation where coercion occurs::
|
|
179
|
+
|
|
180
|
+
sage: U = V.span([[3,2,1]])
|
|
181
|
+
sage: U.0
|
|
182
|
+
(1, 2/3, 1/3)
|
|
183
|
+
sage: phi(2*U.0)
|
|
184
|
+
(16/3, 28/3)
|
|
185
|
+
|
|
186
|
+
TESTS::
|
|
187
|
+
|
|
188
|
+
sage: V = QQ^3; W = span([[1,2,3],[-1,2,5/3]], QQ)
|
|
189
|
+
sage: phi = V.hom(matrix(QQ,3,[1..9]))
|
|
190
|
+
|
|
191
|
+
We compute the image of some elements::
|
|
192
|
+
|
|
193
|
+
sage: phi(V.0) #indirect doctest
|
|
194
|
+
(1, 2, 3)
|
|
195
|
+
sage: phi(V.1)
|
|
196
|
+
(4, 5, 6)
|
|
197
|
+
sage: phi(V.0 - 1/4*V.1)
|
|
198
|
+
(0, 3/4, 3/2)
|
|
199
|
+
|
|
200
|
+
We restrict ``phi`` to ``W`` and compute the image of an element::
|
|
201
|
+
|
|
202
|
+
sage: psi = phi.restrict_domain(W)
|
|
203
|
+
sage: psi(W.0) == phi(W.0)
|
|
204
|
+
True
|
|
205
|
+
sage: psi(W.1) == phi(W.1)
|
|
206
|
+
True
|
|
207
|
+
"""
|
|
208
|
+
try:
|
|
209
|
+
if parent(x) is not self.domain():
|
|
210
|
+
x = self.domain()(x)
|
|
211
|
+
except TypeError:
|
|
212
|
+
raise TypeError("%s must be coercible into %s" % (x, self.domain()))
|
|
213
|
+
if self.domain().is_ambient():
|
|
214
|
+
x = x.element()
|
|
215
|
+
else:
|
|
216
|
+
x = self.domain().coordinate_vector(x)
|
|
217
|
+
C = self.codomain()
|
|
218
|
+
if self.side() == "left":
|
|
219
|
+
v = x.change_ring(C.base_ring()) * self.matrix()
|
|
220
|
+
else:
|
|
221
|
+
v = self.matrix() * x.change_ring(C.base_ring())
|
|
222
|
+
if not C.is_ambient():
|
|
223
|
+
v = C.linear_combination_of_basis(v)
|
|
224
|
+
# The call method of parents uses (coercion) morphisms.
|
|
225
|
+
# Hence, in order to avoid recursion, we call the element
|
|
226
|
+
# constructor directly; after all, we already know the
|
|
227
|
+
# coordinates.
|
|
228
|
+
return C._element_constructor_(v)
|
|
229
|
+
|
|
230
|
+
def _call_with_args(self, x, args=(), kwds={}):
|
|
231
|
+
"""
|
|
232
|
+
Like :meth:`_call_`, but takes optional and keyword arguments.
|
|
233
|
+
|
|
234
|
+
EXAMPLES::
|
|
235
|
+
|
|
236
|
+
sage: # needs sage.rings.real_mpfr sage.symbolic
|
|
237
|
+
sage: V = RR^2
|
|
238
|
+
sage: f = V.hom(V.gens())
|
|
239
|
+
sage: f._matrix *= I # f is now invalid
|
|
240
|
+
sage: f((1, 0))
|
|
241
|
+
Traceback (most recent call last):
|
|
242
|
+
...
|
|
243
|
+
TypeError: Unable to coerce entries (=[1.00000000000000*I, 0.000000000000000])
|
|
244
|
+
to coefficients in Real Field with 53 bits of precision
|
|
245
|
+
sage: f((1, 0), coerce=False)
|
|
246
|
+
(1.00000000000000*I, 0.000000000000000)
|
|
247
|
+
"""
|
|
248
|
+
if self.domain().is_ambient():
|
|
249
|
+
x = x.element()
|
|
250
|
+
else:
|
|
251
|
+
x = self.domain().coordinate_vector(x)
|
|
252
|
+
C = self.codomain()
|
|
253
|
+
v = x.change_ring(C.base_ring()) * self.matrix()
|
|
254
|
+
if not C.is_ambient():
|
|
255
|
+
v = C.linear_combination_of_basis(v)
|
|
256
|
+
# The call method of parents uses (coercion) morphisms.
|
|
257
|
+
# Hence, in order to avoid recursion, we call the element
|
|
258
|
+
# constructor directly; after all, we already know the
|
|
259
|
+
# coordinates.
|
|
260
|
+
return C._element_constructor_(v, *args, **kwds)
|
|
261
|
+
|
|
262
|
+
def __invert__(self):
|
|
263
|
+
"""
|
|
264
|
+
Invert this matrix morphism.
|
|
265
|
+
|
|
266
|
+
EXAMPLES::
|
|
267
|
+
|
|
268
|
+
sage: V = QQ^2; phi = V.hom([3*V.0, 2*V.1])
|
|
269
|
+
sage: phi^(-1)
|
|
270
|
+
Vector space morphism represented by the matrix:
|
|
271
|
+
[1/3 0]
|
|
272
|
+
[ 0 1/2]
|
|
273
|
+
Domain: Vector space of dimension 2 over Rational Field
|
|
274
|
+
Codomain: Vector space of dimension 2 over Rational Field
|
|
275
|
+
|
|
276
|
+
Check that a certain non-invertible morphism isn't invertible::
|
|
277
|
+
|
|
278
|
+
sage: V = ZZ^2; phi = V.hom([3*V.0, 2*V.1])
|
|
279
|
+
sage: phi^(-1)
|
|
280
|
+
Traceback (most recent call last):
|
|
281
|
+
...
|
|
282
|
+
ZeroDivisionError: matrix morphism not invertible
|
|
283
|
+
"""
|
|
284
|
+
try:
|
|
285
|
+
B = ~(self.matrix())
|
|
286
|
+
except ZeroDivisionError:
|
|
287
|
+
raise ZeroDivisionError("matrix morphism not invertible")
|
|
288
|
+
try:
|
|
289
|
+
return self.parent().reversed()(B, side=self.side())
|
|
290
|
+
except TypeError:
|
|
291
|
+
raise ZeroDivisionError("matrix morphism not invertible")
|
|
292
|
+
|
|
293
|
+
def side(self):
|
|
294
|
+
"""
|
|
295
|
+
Return the side of vectors acted on, relative to the matrix.
|
|
296
|
+
|
|
297
|
+
EXAMPLES::
|
|
298
|
+
|
|
299
|
+
sage: m = matrix(2, [1, 1, 0, 1])
|
|
300
|
+
sage: V = ZZ^2
|
|
301
|
+
sage: h1 = V.hom(m); h2 = V.hom(m, side='right')
|
|
302
|
+
sage: h1.side()
|
|
303
|
+
'left'
|
|
304
|
+
sage: h1([1, 0])
|
|
305
|
+
(1, 1)
|
|
306
|
+
sage: h2.side()
|
|
307
|
+
'right'
|
|
308
|
+
sage: h2([1, 0])
|
|
309
|
+
(1, 0)
|
|
310
|
+
"""
|
|
311
|
+
return self._side
|
|
312
|
+
|
|
313
|
+
def side_switch(self):
|
|
314
|
+
"""
|
|
315
|
+
Return the same morphism, acting on vectors on the opposite side.
|
|
316
|
+
|
|
317
|
+
EXAMPLES::
|
|
318
|
+
|
|
319
|
+
sage: m = matrix(2, [1,1,0,1]); m
|
|
320
|
+
[1 1]
|
|
321
|
+
[0 1]
|
|
322
|
+
sage: V = ZZ^2
|
|
323
|
+
sage: h = V.hom(m); h.side()
|
|
324
|
+
'left'
|
|
325
|
+
sage: h2 = h.side_switch(); h2
|
|
326
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
327
|
+
[1 0]
|
|
328
|
+
[1 1]
|
|
329
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
330
|
+
Codomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
331
|
+
sage: h2.side()
|
|
332
|
+
'right'
|
|
333
|
+
sage: h2.side_switch().matrix()
|
|
334
|
+
[1 1]
|
|
335
|
+
[0 1]
|
|
336
|
+
"""
|
|
337
|
+
side = "left" if self.side() == "right" else "right"
|
|
338
|
+
return self.parent()(self.matrix().transpose(), side=side)
|
|
339
|
+
|
|
340
|
+
def inverse(self):
|
|
341
|
+
r"""
|
|
342
|
+
Return the inverse of this matrix morphism, if the inverse exists.
|
|
343
|
+
|
|
344
|
+
This raises a :exc:`ZeroDivisionError` if the inverse does not exist.
|
|
345
|
+
|
|
346
|
+
EXAMPLES:
|
|
347
|
+
|
|
348
|
+
An invertible morphism created as a restriction of
|
|
349
|
+
a non-invertible morphism, and which has an unequal
|
|
350
|
+
domain and codomain. ::
|
|
351
|
+
|
|
352
|
+
sage: V = QQ^4
|
|
353
|
+
sage: W = QQ^3
|
|
354
|
+
sage: m = matrix(QQ, [[2, 0, 3], [-6, 1, 4], [1, 2, -4], [1, 0, 1]])
|
|
355
|
+
sage: phi = V.hom(m, W)
|
|
356
|
+
sage: rho = phi.restrict_domain(V.span([V.0, V.3]))
|
|
357
|
+
sage: zeta = rho.restrict_codomain(W.span([W.0, W.2]))
|
|
358
|
+
sage: x = vector(QQ, [2, 0, 0, -7])
|
|
359
|
+
sage: y = zeta(x); y
|
|
360
|
+
(-3, 0, -1)
|
|
361
|
+
sage: inv = zeta.inverse(); inv
|
|
362
|
+
Vector space morphism represented by the matrix:
|
|
363
|
+
[-1 3]
|
|
364
|
+
[ 1 -2]
|
|
365
|
+
Domain: Vector space of degree 3 and dimension 2 over Rational Field
|
|
366
|
+
Basis matrix:
|
|
367
|
+
[1 0 0]
|
|
368
|
+
[0 0 1]
|
|
369
|
+
Codomain: Vector space of degree 4 and dimension 2 over Rational Field
|
|
370
|
+
Basis matrix:
|
|
371
|
+
[1 0 0 0]
|
|
372
|
+
[0 0 0 1]
|
|
373
|
+
sage: inv(y) == x
|
|
374
|
+
True
|
|
375
|
+
|
|
376
|
+
An example of an invertible morphism between modules,
|
|
377
|
+
(rather than between vector spaces). ::
|
|
378
|
+
|
|
379
|
+
sage: M = ZZ^4
|
|
380
|
+
sage: p = matrix(ZZ, [[ 0, -1, 1, -2],
|
|
381
|
+
....: [ 1, -3, 2, -3],
|
|
382
|
+
....: [ 0, 4, -3, 4],
|
|
383
|
+
....: [-2, 8, -4, 3]])
|
|
384
|
+
sage: phi = M.hom(p, M)
|
|
385
|
+
sage: x = vector(ZZ, [1, -3, 5, -2])
|
|
386
|
+
sage: y = phi(x); y
|
|
387
|
+
(1, 12, -12, 21)
|
|
388
|
+
sage: rho = phi.inverse(); rho
|
|
389
|
+
Free module morphism defined by the matrix
|
|
390
|
+
[ -5 3 -1 1]
|
|
391
|
+
[ -9 4 -3 2]
|
|
392
|
+
[-20 8 -7 4]
|
|
393
|
+
[ -6 2 -2 1]
|
|
394
|
+
Domain: Ambient free module of rank 4 over the principal ideal domain ...
|
|
395
|
+
Codomain: Ambient free module of rank 4 over the principal ideal domain ...
|
|
396
|
+
sage: rho(y) == x
|
|
397
|
+
True
|
|
398
|
+
|
|
399
|
+
A non-invertible morphism, despite having an appropriate
|
|
400
|
+
domain and codomain. ::
|
|
401
|
+
|
|
402
|
+
sage: V = QQ^2
|
|
403
|
+
sage: m = matrix(QQ, [[1, 2], [20, 40]])
|
|
404
|
+
sage: phi = V.hom(m, V)
|
|
405
|
+
sage: phi.is_bijective()
|
|
406
|
+
False
|
|
407
|
+
sage: phi.inverse()
|
|
408
|
+
Traceback (most recent call last):
|
|
409
|
+
...
|
|
410
|
+
ZeroDivisionError: matrix morphism not invertible
|
|
411
|
+
|
|
412
|
+
The matrix representation of this morphism is invertible
|
|
413
|
+
over the rationals, but not over the integers, thus the
|
|
414
|
+
morphism is not invertible as a map between modules.
|
|
415
|
+
It is easy to notice from the definition that every
|
|
416
|
+
vector of the image will have a second entry that
|
|
417
|
+
is an even integer. ::
|
|
418
|
+
|
|
419
|
+
sage: V = ZZ^2
|
|
420
|
+
sage: q = matrix(ZZ, [[1, 2], [3, 4]])
|
|
421
|
+
sage: phi = V.hom(q, V)
|
|
422
|
+
sage: phi.matrix().change_ring(QQ).inverse()
|
|
423
|
+
[ -2 1]
|
|
424
|
+
[ 3/2 -1/2]
|
|
425
|
+
sage: phi.is_bijective()
|
|
426
|
+
False
|
|
427
|
+
sage: phi.image()
|
|
428
|
+
Free module of degree 2 and rank 2 over Integer Ring
|
|
429
|
+
Echelon basis matrix:
|
|
430
|
+
[1 0]
|
|
431
|
+
[0 2]
|
|
432
|
+
sage: phi.lift(vector(ZZ, [1, 1]))
|
|
433
|
+
Traceback (most recent call last):
|
|
434
|
+
...
|
|
435
|
+
ValueError: element is not in the image
|
|
436
|
+
sage: phi.inverse()
|
|
437
|
+
Traceback (most recent call last):
|
|
438
|
+
...
|
|
439
|
+
ZeroDivisionError: matrix morphism not invertible
|
|
440
|
+
|
|
441
|
+
The unary invert operator (~, tilde, "wiggle") is synonymous
|
|
442
|
+
with the ``inverse()`` method (and a lot easier to type). ::
|
|
443
|
+
|
|
444
|
+
sage: V = QQ^2
|
|
445
|
+
sage: r = matrix(QQ, [[4, 3], [-2, 5]])
|
|
446
|
+
sage: phi = V.hom(r, V)
|
|
447
|
+
sage: rho = phi.inverse()
|
|
448
|
+
sage: zeta = ~phi
|
|
449
|
+
sage: rho.is_equal_function(zeta)
|
|
450
|
+
True
|
|
451
|
+
|
|
452
|
+
TESTS::
|
|
453
|
+
|
|
454
|
+
sage: V = QQ^2
|
|
455
|
+
sage: W = QQ^3
|
|
456
|
+
sage: U = W.span([W.0, W.1])
|
|
457
|
+
sage: m = matrix(QQ, [[2, 1], [3, 4]])
|
|
458
|
+
sage: phi = V.hom(m, U)
|
|
459
|
+
sage: inv = phi.inverse()
|
|
460
|
+
sage: (inv*phi).is_identity()
|
|
461
|
+
True
|
|
462
|
+
sage: (phi*inv).is_identity()
|
|
463
|
+
True
|
|
464
|
+
"""
|
|
465
|
+
return ~self
|
|
466
|
+
|
|
467
|
+
def __rmul__(self, left):
|
|
468
|
+
"""
|
|
469
|
+
EXAMPLES::
|
|
470
|
+
|
|
471
|
+
sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1])
|
|
472
|
+
sage: 2*phi
|
|
473
|
+
Free module morphism defined by the matrix
|
|
474
|
+
[2 2]
|
|
475
|
+
[0 4]...
|
|
476
|
+
sage: phi*2
|
|
477
|
+
Free module morphism defined by the matrix
|
|
478
|
+
[2 2]
|
|
479
|
+
[0 4]...
|
|
480
|
+
"""
|
|
481
|
+
R = self.base_ring()
|
|
482
|
+
return self.parent()(R(left) * self.matrix(), side=self.side())
|
|
483
|
+
|
|
484
|
+
def __mul__(self, right):
|
|
485
|
+
r"""
|
|
486
|
+
Composition of morphisms, denoted by \*.
|
|
487
|
+
|
|
488
|
+
EXAMPLES::
|
|
489
|
+
|
|
490
|
+
sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1])
|
|
491
|
+
sage: phi*phi
|
|
492
|
+
Free module morphism defined by the matrix
|
|
493
|
+
[1 3]
|
|
494
|
+
[0 4]
|
|
495
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
496
|
+
Codomain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
497
|
+
|
|
498
|
+
sage: V = QQ^3
|
|
499
|
+
sage: E = V.endomorphism_ring()
|
|
500
|
+
sage: phi = E(Matrix(QQ,3,range(9))) ; phi
|
|
501
|
+
Vector space morphism represented by the matrix:
|
|
502
|
+
[0 1 2]
|
|
503
|
+
[3 4 5]
|
|
504
|
+
[6 7 8]
|
|
505
|
+
Domain: Vector space of dimension 3 over Rational Field
|
|
506
|
+
Codomain: Vector space of dimension 3 over Rational Field
|
|
507
|
+
sage: phi*phi
|
|
508
|
+
Vector space morphism represented by the matrix:
|
|
509
|
+
[ 15 18 21]
|
|
510
|
+
[ 42 54 66]
|
|
511
|
+
[ 69 90 111]
|
|
512
|
+
Domain: Vector space of dimension 3 over Rational Field
|
|
513
|
+
Codomain: Vector space of dimension 3 over Rational Field
|
|
514
|
+
sage: phi.matrix()**2
|
|
515
|
+
[ 15 18 21]
|
|
516
|
+
[ 42 54 66]
|
|
517
|
+
[ 69 90 111]
|
|
518
|
+
|
|
519
|
+
::
|
|
520
|
+
|
|
521
|
+
sage: W = QQ**4
|
|
522
|
+
sage: E_VW = V.Hom(W)
|
|
523
|
+
sage: psi = E_VW(Matrix(QQ,3,4,range(12))) ; psi
|
|
524
|
+
Vector space morphism represented by the matrix:
|
|
525
|
+
[ 0 1 2 3]
|
|
526
|
+
[ 4 5 6 7]
|
|
527
|
+
[ 8 9 10 11]
|
|
528
|
+
Domain: Vector space of dimension 3 over Rational Field
|
|
529
|
+
Codomain: Vector space of dimension 4 over Rational Field
|
|
530
|
+
sage: psi*phi
|
|
531
|
+
Vector space morphism represented by the matrix:
|
|
532
|
+
[ 20 23 26 29]
|
|
533
|
+
[ 56 68 80 92]
|
|
534
|
+
[ 92 113 134 155]
|
|
535
|
+
Domain: Vector space of dimension 3 over Rational Field
|
|
536
|
+
Codomain: Vector space of dimension 4 over Rational Field
|
|
537
|
+
sage: phi*psi
|
|
538
|
+
Traceback (most recent call last):
|
|
539
|
+
...
|
|
540
|
+
TypeError: Incompatible composition of morphisms: domain of left morphism must be codomain of right.
|
|
541
|
+
sage: phi.matrix()*psi.matrix()
|
|
542
|
+
[ 20 23 26 29]
|
|
543
|
+
[ 56 68 80 92]
|
|
544
|
+
[ 92 113 134 155]
|
|
545
|
+
|
|
546
|
+
Composite maps can be formed with matrix morphisms::
|
|
547
|
+
|
|
548
|
+
sage: # needs sage.rings.number_field
|
|
549
|
+
sage: x = polygen(ZZ, 'x')
|
|
550
|
+
sage: K.<a> = NumberField(x^2 + 23)
|
|
551
|
+
sage: V, VtoK, KtoV = K.vector_space()
|
|
552
|
+
sage: f = V.hom([V.0 - V.1, V.0 + V.1])*KtoV; f
|
|
553
|
+
Composite map:
|
|
554
|
+
From: Number Field in a with defining polynomial x^2 + 23
|
|
555
|
+
To: Vector space of dimension 2 over Rational Field
|
|
556
|
+
Defn: Isomorphism map:
|
|
557
|
+
From: Number Field in a with defining polynomial x^2 + 23
|
|
558
|
+
To: Vector space of dimension 2 over Rational Field
|
|
559
|
+
then
|
|
560
|
+
Vector space morphism represented by the matrix:
|
|
561
|
+
[ 1 -1]
|
|
562
|
+
[ 1 1]
|
|
563
|
+
Domain: Vector space of dimension 2 over Rational Field
|
|
564
|
+
Codomain: Vector space of dimension 2 over Rational Field
|
|
565
|
+
sage: f(a)
|
|
566
|
+
(1, 1)
|
|
567
|
+
sage: V.hom([V.0 - V.1, V.0 + V.1], side='right')*KtoV
|
|
568
|
+
Composite map:
|
|
569
|
+
From: Number Field in a with defining polynomial x^2 + 23
|
|
570
|
+
To: Vector space of dimension 2 over Rational Field
|
|
571
|
+
Defn: Isomorphism map:
|
|
572
|
+
From: Number Field in a with defining polynomial x^2 + 23
|
|
573
|
+
To: Vector space of dimension 2 over Rational Field
|
|
574
|
+
then
|
|
575
|
+
Vector space morphism represented as left-multiplication by the matrix:
|
|
576
|
+
[ 1 1]
|
|
577
|
+
[-1 1]
|
|
578
|
+
Domain: Vector space of dimension 2 over Rational Field
|
|
579
|
+
Codomain: Vector space of dimension 2 over Rational Field
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
We can test interaction between morphisms with different ``side``::
|
|
583
|
+
|
|
584
|
+
sage: V = ZZ^2
|
|
585
|
+
sage: m = matrix(2, [1,1,0,1])
|
|
586
|
+
sage: hl = V.hom(m)
|
|
587
|
+
sage: hr = V.hom(m, side='right')
|
|
588
|
+
sage: hl * hl
|
|
589
|
+
Free module morphism defined by the matrix
|
|
590
|
+
[1 2]
|
|
591
|
+
[0 1]...
|
|
592
|
+
sage: hl * hr
|
|
593
|
+
Free module morphism defined by the matrix
|
|
594
|
+
[1 1]
|
|
595
|
+
[1 2]...
|
|
596
|
+
sage: hl * hl.side_switch()
|
|
597
|
+
Free module morphism defined by the matrix
|
|
598
|
+
[1 2]
|
|
599
|
+
[0 1]...
|
|
600
|
+
sage: hr * hl
|
|
601
|
+
Free module morphism defined by the matrix
|
|
602
|
+
[2 1]
|
|
603
|
+
[1 1]...
|
|
604
|
+
sage: hl * hl
|
|
605
|
+
Free module morphism defined by the matrix
|
|
606
|
+
[1 2]
|
|
607
|
+
[0 1]...
|
|
608
|
+
sage: hr / hl
|
|
609
|
+
Free module morphism defined by the matrix
|
|
610
|
+
[ 0 -1]
|
|
611
|
+
[ 1 1]...
|
|
612
|
+
sage: hr / hr.side_switch()
|
|
613
|
+
Free module morphism defined by the matrix
|
|
614
|
+
[1 0]
|
|
615
|
+
[0 1]...
|
|
616
|
+
sage: hl / hl
|
|
617
|
+
Free module morphism defined by the matrix
|
|
618
|
+
[1 0]
|
|
619
|
+
[0 1]...
|
|
620
|
+
sage: hr / hr
|
|
621
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
622
|
+
[1 0]
|
|
623
|
+
[0 1]...
|
|
624
|
+
|
|
625
|
+
.. WARNING::
|
|
626
|
+
|
|
627
|
+
Matrix morphisms can be defined by either left or right-multiplication.
|
|
628
|
+
The composite morphism always applies the morphism on the right of \* first.
|
|
629
|
+
The matrix of the composite morphism of two morphisms given by
|
|
630
|
+
right-multiplication is not the morphism given by the product of their
|
|
631
|
+
respective matrices.
|
|
632
|
+
If the two morphisms act on different sides, then the side of the resulting
|
|
633
|
+
morphism is the default one.
|
|
634
|
+
"""
|
|
635
|
+
if not isinstance(right, MatrixMorphism):
|
|
636
|
+
if isinstance(right, (sage.categories.morphism.Morphism, sage.categories.map.Map)):
|
|
637
|
+
return sage.categories.map.Map.__mul__(self, right)
|
|
638
|
+
R = self.base_ring()
|
|
639
|
+
return self.parent()(self.matrix() * R(right))
|
|
640
|
+
H = right.domain().Hom(self.codomain())
|
|
641
|
+
if self.domain() != right.codomain():
|
|
642
|
+
raise TypeError("Incompatible composition of morphisms: domain of left morphism must be codomain of right.")
|
|
643
|
+
if self.side() == "left":
|
|
644
|
+
if right.side() == "left":
|
|
645
|
+
return H(right.matrix() * self.matrix(), side=self.side())
|
|
646
|
+
else:
|
|
647
|
+
return H(right.matrix().transpose() * self.matrix(), side=self.side())
|
|
648
|
+
else:
|
|
649
|
+
if right.side() == "right":
|
|
650
|
+
return H(self.matrix() * right.matrix(), side=self.side())
|
|
651
|
+
else:
|
|
652
|
+
return H(right.matrix() * self.matrix().transpose(), side='left')
|
|
653
|
+
|
|
654
|
+
def __add__(self, right):
|
|
655
|
+
"""
|
|
656
|
+
Sum of morphisms, denoted by +.
|
|
657
|
+
|
|
658
|
+
EXAMPLES::
|
|
659
|
+
|
|
660
|
+
sage: phi = (ZZ**2).endomorphism_ring()(Matrix(ZZ,2,[2..5])) ; phi
|
|
661
|
+
Free module morphism defined by the matrix
|
|
662
|
+
[2 3]
|
|
663
|
+
[4 5]
|
|
664
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
665
|
+
Codomain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
666
|
+
sage: phi + 3
|
|
667
|
+
Free module morphism defined by the matrix
|
|
668
|
+
[5 3]
|
|
669
|
+
[4 8]
|
|
670
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
671
|
+
Codomain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
672
|
+
sage: phi + phi
|
|
673
|
+
Free module morphism defined by the matrix
|
|
674
|
+
[ 4 6]
|
|
675
|
+
[ 8 10]
|
|
676
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
677
|
+
Codomain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
678
|
+
sage: psi = (ZZ**3).endomorphism_ring()(Matrix(ZZ,3,[22..30])) ; psi
|
|
679
|
+
Free module morphism defined by the matrix
|
|
680
|
+
[22 23 24]
|
|
681
|
+
[25 26 27]
|
|
682
|
+
[28 29 30]
|
|
683
|
+
Domain: Ambient free module of rank 3 over the principal ideal domain ...
|
|
684
|
+
Codomain: Ambient free module of rank 3 over the principal ideal domain ...
|
|
685
|
+
sage: phi + psi
|
|
686
|
+
Traceback (most recent call last):
|
|
687
|
+
...
|
|
688
|
+
ValueError: inconsistent number of rows: should be 2 but got 3
|
|
689
|
+
|
|
690
|
+
::
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
sage: V = ZZ^2
|
|
694
|
+
sage: m = matrix(2, [1,1,0,1])
|
|
695
|
+
sage: hl = V.hom(m)
|
|
696
|
+
sage: hr = V.hom(m, side='right')
|
|
697
|
+
sage: hl + hl
|
|
698
|
+
Free module morphism defined by the matrix
|
|
699
|
+
[2 2]
|
|
700
|
+
[0 2]...
|
|
701
|
+
sage: hr + hr
|
|
702
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
703
|
+
[2 2]
|
|
704
|
+
[0 2]...
|
|
705
|
+
sage: hr + hl
|
|
706
|
+
Free module morphism defined by the matrix
|
|
707
|
+
[2 1]
|
|
708
|
+
[1 2]...
|
|
709
|
+
sage: hl + hr
|
|
710
|
+
Free module morphism defined by the matrix
|
|
711
|
+
[2 1]
|
|
712
|
+
[1 2]...
|
|
713
|
+
|
|
714
|
+
.. WARNING::
|
|
715
|
+
|
|
716
|
+
If the two morphisms do not share the same ``side`` attribute, then
|
|
717
|
+
the resulting morphism will be defined with the default value.
|
|
718
|
+
"""
|
|
719
|
+
# TODO: move over to any coercion model!
|
|
720
|
+
if not isinstance(right, MatrixMorphism):
|
|
721
|
+
R = self.base_ring()
|
|
722
|
+
return self.parent()(self.matrix() + R(right))
|
|
723
|
+
if not right.parent() == self.parent():
|
|
724
|
+
right = self.parent()(right, side=right.side())
|
|
725
|
+
if self.side() == "left":
|
|
726
|
+
if right.side() == "left":
|
|
727
|
+
return self.parent()(self.matrix() + right.matrix(), side=self.side())
|
|
728
|
+
elif right.side() == "right":
|
|
729
|
+
return self.parent()(self.matrix() + right.matrix().transpose(), side='left')
|
|
730
|
+
if self.side() == "right":
|
|
731
|
+
if right.side() == "right":
|
|
732
|
+
return self.parent()(self.matrix() + right.matrix(), side=self.side())
|
|
733
|
+
elif right.side() == "left":
|
|
734
|
+
return self.parent()(self.matrix().transpose() + right.matrix(), side='left')
|
|
735
|
+
|
|
736
|
+
def __neg__(self):
|
|
737
|
+
"""
|
|
738
|
+
EXAMPLES::
|
|
739
|
+
|
|
740
|
+
sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1])
|
|
741
|
+
sage: -phi
|
|
742
|
+
Free module morphism defined by the matrix
|
|
743
|
+
[-1 -1]
|
|
744
|
+
[ 0 -2]...
|
|
745
|
+
sage: phi2 = phi.side_switch(); -phi2
|
|
746
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
747
|
+
[-1 0]
|
|
748
|
+
[-1 -2]...
|
|
749
|
+
"""
|
|
750
|
+
return self.parent()(-self.matrix(), side=self.side())
|
|
751
|
+
|
|
752
|
+
def __sub__(self, other):
|
|
753
|
+
"""
|
|
754
|
+
EXAMPLES::
|
|
755
|
+
|
|
756
|
+
sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1])
|
|
757
|
+
sage: phi - phi
|
|
758
|
+
Free module morphism defined by the matrix
|
|
759
|
+
[0 0]
|
|
760
|
+
[0 0]...
|
|
761
|
+
|
|
762
|
+
::
|
|
763
|
+
|
|
764
|
+
sage: V = ZZ^2
|
|
765
|
+
sage: m = matrix(2, [1,1,0,1])
|
|
766
|
+
sage: hl = V.hom(m)
|
|
767
|
+
sage: hr = V.hom(m, side='right')
|
|
768
|
+
sage: hl - hr
|
|
769
|
+
Free module morphism defined by the matrix
|
|
770
|
+
[ 0 1]
|
|
771
|
+
[-1 0]...
|
|
772
|
+
sage: hl - hl
|
|
773
|
+
Free module morphism defined by the matrix
|
|
774
|
+
[0 0]
|
|
775
|
+
[0 0]...
|
|
776
|
+
sage: hr - hr
|
|
777
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
778
|
+
[0 0]
|
|
779
|
+
[0 0]...
|
|
780
|
+
sage: hr-hl
|
|
781
|
+
Free module morphism defined by the matrix
|
|
782
|
+
[ 0 -1]
|
|
783
|
+
[ 1 0]...
|
|
784
|
+
|
|
785
|
+
.. WARNING::
|
|
786
|
+
|
|
787
|
+
If the two morphisms do not share the same ``side`` attribute, then
|
|
788
|
+
the resulting morphism will be defined with the default value.
|
|
789
|
+
"""
|
|
790
|
+
# TODO: move over to any coercion model!
|
|
791
|
+
if not isinstance(other, MatrixMorphism):
|
|
792
|
+
R = self.base_ring()
|
|
793
|
+
return self.parent()(self.matrix() - R(other), side=self.side())
|
|
794
|
+
if not other.parent() == self.parent():
|
|
795
|
+
other = self.parent()(other, side=other.side())
|
|
796
|
+
if self.side() == "left":
|
|
797
|
+
if other.side() == "left":
|
|
798
|
+
return self.parent()(self.matrix() - other.matrix(), side=self.side())
|
|
799
|
+
elif other.side() == "right":
|
|
800
|
+
return self.parent()(self.matrix() - other.matrix().transpose(), side='left')
|
|
801
|
+
if self.side() == "right":
|
|
802
|
+
if other.side() == "right":
|
|
803
|
+
return self.parent()(self.matrix() - other.matrix(), side=self.side())
|
|
804
|
+
elif other.side() == "left":
|
|
805
|
+
return self.parent()(self.matrix().transpose() - other.matrix(), side='left')
|
|
806
|
+
|
|
807
|
+
def base_ring(self):
|
|
808
|
+
"""
|
|
809
|
+
Return the base ring of ``self``, that is, the ring over which ``self``
|
|
810
|
+
is given by a matrix.
|
|
811
|
+
|
|
812
|
+
EXAMPLES::
|
|
813
|
+
|
|
814
|
+
sage: sage.modules.matrix_morphism.MatrixMorphism((ZZ**2).endomorphism_ring(), Matrix(ZZ,2,[3..6])).base_ring()
|
|
815
|
+
Integer Ring
|
|
816
|
+
"""
|
|
817
|
+
return self.domain().base_ring()
|
|
818
|
+
|
|
819
|
+
def decomposition(self, *args, **kwds):
|
|
820
|
+
"""
|
|
821
|
+
Return decomposition of this endomorphism, i.e., sequence of
|
|
822
|
+
subspaces obtained by finding invariant subspaces of ``self``.
|
|
823
|
+
|
|
824
|
+
See the documentation for ``self.matrix().decomposition`` for more
|
|
825
|
+
details. All inputs to this function are passed onto the
|
|
826
|
+
matrix one.
|
|
827
|
+
|
|
828
|
+
EXAMPLES::
|
|
829
|
+
|
|
830
|
+
sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1])
|
|
831
|
+
sage: phi.decomposition() # needs sage.libs.pari
|
|
832
|
+
[Free module of degree 2 and rank 1 over Integer Ring
|
|
833
|
+
Echelon basis matrix:
|
|
834
|
+
[0 1],
|
|
835
|
+
Free module of degree 2 and rank 1 over Integer Ring
|
|
836
|
+
Echelon basis matrix:
|
|
837
|
+
[ 1 -1]]
|
|
838
|
+
sage: phi2 = V.hom(phi.matrix(), side='right')
|
|
839
|
+
sage: phi2.decomposition() # needs sage.libs.pari
|
|
840
|
+
[Free module of degree 2 and rank 1 over Integer Ring
|
|
841
|
+
Echelon basis matrix:
|
|
842
|
+
[1 1],
|
|
843
|
+
Free module of degree 2 and rank 1 over Integer Ring
|
|
844
|
+
Echelon basis matrix:
|
|
845
|
+
[1 0]]
|
|
846
|
+
"""
|
|
847
|
+
if not self.is_endomorphism():
|
|
848
|
+
raise ArithmeticError("matrix morphism must be an endomorphism")
|
|
849
|
+
D = self.domain()
|
|
850
|
+
if self.side() == "left":
|
|
851
|
+
E = self.matrix().decomposition(*args, **kwds)
|
|
852
|
+
else:
|
|
853
|
+
E = self.matrix().transpose().decomposition(*args, **kwds)
|
|
854
|
+
if D.is_ambient():
|
|
855
|
+
return Sequence([D.submodule(V, check=False) for V, _ in E],
|
|
856
|
+
cr=True, check=False)
|
|
857
|
+
else:
|
|
858
|
+
B = D.basis_matrix()
|
|
859
|
+
R = D.base_ring()
|
|
860
|
+
return Sequence([D.submodule((V.basis_matrix() * B).row_module(R),
|
|
861
|
+
check=False) for V, _ in E],
|
|
862
|
+
cr=True, check=False)
|
|
863
|
+
|
|
864
|
+
def kernel(self):
|
|
865
|
+
"""
|
|
866
|
+
Compute the kernel of this morphism.
|
|
867
|
+
|
|
868
|
+
EXAMPLES::
|
|
869
|
+
|
|
870
|
+
sage: V = VectorSpace(QQ, 3)
|
|
871
|
+
sage: id = V.Hom(V)(identity_matrix(QQ,3))
|
|
872
|
+
sage: null = V.Hom(V)(0*identity_matrix(QQ,3))
|
|
873
|
+
sage: id.kernel()
|
|
874
|
+
Vector space of degree 3 and dimension 0 over Rational Field
|
|
875
|
+
Basis matrix:
|
|
876
|
+
[]
|
|
877
|
+
sage: phi = V.Hom(V)(matrix(QQ, 3, range(9)))
|
|
878
|
+
sage: phi.kernel()
|
|
879
|
+
Vector space of degree 3 and dimension 1 over Rational Field
|
|
880
|
+
Basis matrix:
|
|
881
|
+
[ 1 -2 1]
|
|
882
|
+
sage: hom(CC^2, CC^2, matrix(CC, [[1,0], [0,1]])).kernel()
|
|
883
|
+
Vector space of degree 2 and dimension 0 over Complex Field with 53 bits of precision
|
|
884
|
+
Basis matrix:
|
|
885
|
+
[]
|
|
886
|
+
sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m
|
|
887
|
+
[1 0 0]
|
|
888
|
+
[1 0 0]
|
|
889
|
+
[0 0 1]
|
|
890
|
+
sage: f1 = V.hom(m)
|
|
891
|
+
sage: f2 = V.hom(m, side='right')
|
|
892
|
+
sage: f1.kernel()
|
|
893
|
+
Vector space of degree 3 and dimension 1 over Rational Field
|
|
894
|
+
Basis matrix:
|
|
895
|
+
[ 1 -1 0]
|
|
896
|
+
sage: f2.kernel()
|
|
897
|
+
Vector space of degree 3 and dimension 1 over Rational Field
|
|
898
|
+
Basis matrix:
|
|
899
|
+
[0 1 0]
|
|
900
|
+
"""
|
|
901
|
+
if self.side() == "left":
|
|
902
|
+
V = self.matrix().left_kernel()
|
|
903
|
+
else:
|
|
904
|
+
V = self.matrix().right_kernel()
|
|
905
|
+
D = self.domain()
|
|
906
|
+
if not D.is_ambient():
|
|
907
|
+
# Transform V to ambient space
|
|
908
|
+
# This is a matrix multiply: we take the linear combinations of the basis for
|
|
909
|
+
# D given by the elements of the basis for V.
|
|
910
|
+
B = V.basis_matrix() * D.basis_matrix()
|
|
911
|
+
V = B.row_module(D.base_ring())
|
|
912
|
+
return self.domain().submodule(V, check=False)
|
|
913
|
+
|
|
914
|
+
def image(self):
|
|
915
|
+
"""
|
|
916
|
+
Compute the image of this morphism.
|
|
917
|
+
|
|
918
|
+
EXAMPLES::
|
|
919
|
+
|
|
920
|
+
sage: V = VectorSpace(QQ, 3)
|
|
921
|
+
sage: phi = V.Hom(V)(matrix(QQ, 3, range(9)))
|
|
922
|
+
sage: phi.image()
|
|
923
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
924
|
+
Basis matrix:
|
|
925
|
+
[ 1 0 -1]
|
|
926
|
+
[ 0 1 2]
|
|
927
|
+
sage: hom(GF(7)^3, GF(7)^2, zero_matrix(GF(7), 3, 2)).image()
|
|
928
|
+
Vector space of degree 2 and dimension 0 over Finite Field of size 7
|
|
929
|
+
Basis matrix:
|
|
930
|
+
[]
|
|
931
|
+
sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m
|
|
932
|
+
[1 0 0]
|
|
933
|
+
[1 0 0]
|
|
934
|
+
[0 0 1]
|
|
935
|
+
sage: f1 = V.hom(m)
|
|
936
|
+
sage: f2 = V.hom(m, side='right')
|
|
937
|
+
sage: f1.image()
|
|
938
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
939
|
+
Basis matrix:
|
|
940
|
+
[1 0 0]
|
|
941
|
+
[0 0 1]
|
|
942
|
+
sage: f2.image()
|
|
943
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
944
|
+
Basis matrix:
|
|
945
|
+
[1 1 0]
|
|
946
|
+
[0 0 1]
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
Compute the image of the identity map on a ZZ-submodule::
|
|
950
|
+
|
|
951
|
+
sage: V = (ZZ^2).span([[1,2], [3,4]])
|
|
952
|
+
sage: phi = V.Hom(V)(identity_matrix(ZZ,2))
|
|
953
|
+
sage: phi(V.0) == V.0
|
|
954
|
+
True
|
|
955
|
+
sage: phi(V.1) == V.1
|
|
956
|
+
True
|
|
957
|
+
sage: phi.image()
|
|
958
|
+
Free module of degree 2 and rank 2 over Integer Ring
|
|
959
|
+
Echelon basis matrix:
|
|
960
|
+
[1 0]
|
|
961
|
+
[0 2]
|
|
962
|
+
sage: phi.image() == V
|
|
963
|
+
True
|
|
964
|
+
"""
|
|
965
|
+
if self.side() == 'left':
|
|
966
|
+
V = self.matrix().row_space()
|
|
967
|
+
else:
|
|
968
|
+
V = self.matrix().column_space()
|
|
969
|
+
C = self.codomain()
|
|
970
|
+
if not C.is_ambient():
|
|
971
|
+
# Transform V to ambient space
|
|
972
|
+
# This is a matrix multiply: we take the linear combinations of the basis for
|
|
973
|
+
# D given by the elements of the basis for V.
|
|
974
|
+
B = V.basis_matrix() * C.basis_matrix()
|
|
975
|
+
V = B.row_module(self.domain().base_ring())
|
|
976
|
+
return self.codomain().submodule(V, check=False)
|
|
977
|
+
|
|
978
|
+
def matrix(self):
|
|
979
|
+
"""
|
|
980
|
+
EXAMPLES::
|
|
981
|
+
|
|
982
|
+
sage: V = ZZ^2; phi = V.hom(V.basis())
|
|
983
|
+
sage: phi.matrix()
|
|
984
|
+
[1 0]
|
|
985
|
+
[0 1]
|
|
986
|
+
sage: sage.modules.matrix_morphism.MatrixMorphism_abstract.matrix(phi)
|
|
987
|
+
Traceback (most recent call last):
|
|
988
|
+
...
|
|
989
|
+
NotImplementedError: this method must be overridden in the extension class
|
|
990
|
+
"""
|
|
991
|
+
raise NotImplementedError("this method must be overridden in the extension class")
|
|
992
|
+
|
|
993
|
+
def _matrix_(self):
|
|
994
|
+
"""
|
|
995
|
+
EXAMPLES:
|
|
996
|
+
|
|
997
|
+
Check that this works with the :func:`matrix` function
|
|
998
|
+
(:issue:`16844`)::
|
|
999
|
+
|
|
1000
|
+
sage: H = Hom(ZZ^2, ZZ^3)
|
|
1001
|
+
sage: x = H.an_element()
|
|
1002
|
+
sage: matrix(x)
|
|
1003
|
+
[0 0 0]
|
|
1004
|
+
[0 0 0]
|
|
1005
|
+
|
|
1006
|
+
TESTS:
|
|
1007
|
+
|
|
1008
|
+
``matrix(x)`` is immutable::
|
|
1009
|
+
|
|
1010
|
+
sage: H = Hom(QQ^3, QQ^2)
|
|
1011
|
+
sage: phi = H(matrix(QQ, 3, 2, list(reversed(range(6))))); phi
|
|
1012
|
+
Vector space morphism represented by the matrix:
|
|
1013
|
+
[5 4]
|
|
1014
|
+
[3 2]
|
|
1015
|
+
[1 0]
|
|
1016
|
+
Domain: Vector space of dimension 3 over Rational Field
|
|
1017
|
+
Codomain: Vector space of dimension 2 over Rational Field
|
|
1018
|
+
sage: A = phi.matrix()
|
|
1019
|
+
sage: A[1, 1] = 19
|
|
1020
|
+
Traceback (most recent call last):
|
|
1021
|
+
...
|
|
1022
|
+
ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).
|
|
1023
|
+
"""
|
|
1024
|
+
return self.matrix()
|
|
1025
|
+
|
|
1026
|
+
def rank(self):
|
|
1027
|
+
r"""
|
|
1028
|
+
Return the rank of the matrix representing this morphism.
|
|
1029
|
+
|
|
1030
|
+
EXAMPLES::
|
|
1031
|
+
|
|
1032
|
+
sage: V = ZZ^2; phi = V.hom(V.basis())
|
|
1033
|
+
sage: phi.rank()
|
|
1034
|
+
2
|
|
1035
|
+
sage: V = ZZ^2; phi = V.hom([V.0, V.0])
|
|
1036
|
+
sage: phi.rank()
|
|
1037
|
+
1
|
|
1038
|
+
"""
|
|
1039
|
+
return self.matrix().rank()
|
|
1040
|
+
|
|
1041
|
+
def nullity(self):
|
|
1042
|
+
r"""
|
|
1043
|
+
Return the nullity of the matrix representing this morphism, which is the
|
|
1044
|
+
dimension of its kernel.
|
|
1045
|
+
|
|
1046
|
+
EXAMPLES::
|
|
1047
|
+
|
|
1048
|
+
sage: V = ZZ^2; phi = V.hom(V.basis())
|
|
1049
|
+
sage: phi.nullity()
|
|
1050
|
+
0
|
|
1051
|
+
sage: V = ZZ^2; phi = V.hom([V.0, V.0])
|
|
1052
|
+
sage: phi.nullity()
|
|
1053
|
+
1
|
|
1054
|
+
|
|
1055
|
+
::
|
|
1056
|
+
|
|
1057
|
+
sage: m = matrix(2, [1, 2])
|
|
1058
|
+
sage: V = ZZ^2
|
|
1059
|
+
sage: h1 = V.hom(m)
|
|
1060
|
+
sage: h1.nullity()
|
|
1061
|
+
1
|
|
1062
|
+
sage: W = ZZ^1
|
|
1063
|
+
sage: h2 = W.hom(m, side='right')
|
|
1064
|
+
sage: h2.nullity()
|
|
1065
|
+
0
|
|
1066
|
+
"""
|
|
1067
|
+
if self.side() == "left":
|
|
1068
|
+
return self._matrix.left_nullity()
|
|
1069
|
+
else:
|
|
1070
|
+
return self._matrix.right_nullity()
|
|
1071
|
+
|
|
1072
|
+
def is_bijective(self) -> bool:
|
|
1073
|
+
r"""
|
|
1074
|
+
Tell whether ``self`` is bijective.
|
|
1075
|
+
|
|
1076
|
+
EXAMPLES:
|
|
1077
|
+
|
|
1078
|
+
Two morphisms that are obviously not bijective, simply on
|
|
1079
|
+
considerations of the dimensions. However, each fullfills
|
|
1080
|
+
half of the requirements to be a bijection. ::
|
|
1081
|
+
|
|
1082
|
+
sage: V1 = QQ^2
|
|
1083
|
+
sage: V2 = QQ^3
|
|
1084
|
+
sage: m = matrix(QQ, [[1, 2, 3], [4, 5, 6]])
|
|
1085
|
+
sage: phi = V1.hom(m, V2)
|
|
1086
|
+
sage: phi.is_injective()
|
|
1087
|
+
True
|
|
1088
|
+
sage: phi.is_bijective()
|
|
1089
|
+
False
|
|
1090
|
+
sage: rho = V2.hom(m.transpose(), V1)
|
|
1091
|
+
sage: rho.is_surjective()
|
|
1092
|
+
True
|
|
1093
|
+
sage: rho.is_bijective()
|
|
1094
|
+
False
|
|
1095
|
+
|
|
1096
|
+
We construct a simple bijection between two one-dimensional
|
|
1097
|
+
vector spaces. ::
|
|
1098
|
+
|
|
1099
|
+
sage: V1 = QQ^3
|
|
1100
|
+
sage: V2 = QQ^2
|
|
1101
|
+
sage: phi = V1.hom(matrix(QQ, [[1, 2], [3, 4], [5, 6]]), V2)
|
|
1102
|
+
sage: x = vector(QQ, [1, -1, 4])
|
|
1103
|
+
sage: y = phi(x); y
|
|
1104
|
+
(18, 22)
|
|
1105
|
+
sage: rho = phi.restrict_domain(V1.span([x]))
|
|
1106
|
+
sage: zeta = rho.restrict_codomain(V2.span([y]))
|
|
1107
|
+
sage: zeta.is_bijective()
|
|
1108
|
+
True
|
|
1109
|
+
|
|
1110
|
+
AUTHOR:
|
|
1111
|
+
|
|
1112
|
+
- Rob Beezer (2011-06-28)
|
|
1113
|
+
"""
|
|
1114
|
+
return self.is_injective() and self.is_surjective()
|
|
1115
|
+
|
|
1116
|
+
def is_identity(self) -> bool:
|
|
1117
|
+
r"""
|
|
1118
|
+
Determine if this morphism is an identity function or not.
|
|
1119
|
+
|
|
1120
|
+
EXAMPLES:
|
|
1121
|
+
|
|
1122
|
+
A homomorphism that cannot possibly be the identity
|
|
1123
|
+
due to an unequal domain and codomain. ::
|
|
1124
|
+
|
|
1125
|
+
sage: V = QQ^3
|
|
1126
|
+
sage: W = QQ^2
|
|
1127
|
+
sage: m = matrix(QQ, [[1, 2], [3, 4], [5, 6]])
|
|
1128
|
+
sage: phi = V.hom(m, W)
|
|
1129
|
+
sage: phi.is_identity()
|
|
1130
|
+
False
|
|
1131
|
+
|
|
1132
|
+
A bijection, but not the identity. ::
|
|
1133
|
+
|
|
1134
|
+
sage: V = QQ^3
|
|
1135
|
+
sage: n = matrix(QQ, [[3, 1, -8], [5, -4, 6], [1, 1, -5]])
|
|
1136
|
+
sage: phi = V.hom(n, V)
|
|
1137
|
+
sage: phi.is_bijective()
|
|
1138
|
+
True
|
|
1139
|
+
sage: phi.is_identity()
|
|
1140
|
+
False
|
|
1141
|
+
|
|
1142
|
+
A restriction that is the identity. ::
|
|
1143
|
+
|
|
1144
|
+
sage: V = QQ^3
|
|
1145
|
+
sage: p = matrix(QQ, [[1, 0, 0], [5, 8, 3], [0, 0, 1]])
|
|
1146
|
+
sage: phi = V.hom(p, V)
|
|
1147
|
+
sage: rho = phi.restrict(V.span([V.0, V.2]))
|
|
1148
|
+
sage: rho.is_identity()
|
|
1149
|
+
True
|
|
1150
|
+
|
|
1151
|
+
An identity linear transformation that is defined with a
|
|
1152
|
+
domain and codomain with wildly different bases, so that the
|
|
1153
|
+
matrix representation is not simply the identity matrix. ::
|
|
1154
|
+
|
|
1155
|
+
sage: A = matrix(QQ, [[1, 1, 0], [2, 3, -4], [2, 4, -7]])
|
|
1156
|
+
sage: B = matrix(QQ, [[2, 7, -2], [-1, -3, 1], [-1, -6, 2]])
|
|
1157
|
+
sage: U = (QQ^3).subspace_with_basis(A.rows())
|
|
1158
|
+
sage: V = (QQ^3).subspace_with_basis(B.rows())
|
|
1159
|
+
sage: H = Hom(U, V)
|
|
1160
|
+
sage: id = lambda x: x
|
|
1161
|
+
sage: phi = H(id)
|
|
1162
|
+
sage: phi([203, -179, 34])
|
|
1163
|
+
(203, -179, 34)
|
|
1164
|
+
sage: phi.matrix()
|
|
1165
|
+
[ 1 0 1]
|
|
1166
|
+
[ -9 -18 -2]
|
|
1167
|
+
[-17 -31 -5]
|
|
1168
|
+
sage: phi.is_identity()
|
|
1169
|
+
True
|
|
1170
|
+
|
|
1171
|
+
TESTS::
|
|
1172
|
+
|
|
1173
|
+
sage: V = QQ^10
|
|
1174
|
+
sage: H = Hom(V, V)
|
|
1175
|
+
sage: id = H.identity()
|
|
1176
|
+
sage: id.is_identity()
|
|
1177
|
+
True
|
|
1178
|
+
|
|
1179
|
+
AUTHOR:
|
|
1180
|
+
|
|
1181
|
+
- Rob Beezer (2011-06-28)
|
|
1182
|
+
"""
|
|
1183
|
+
if self.domain() != self.codomain():
|
|
1184
|
+
return False
|
|
1185
|
+
# testing for the identity matrix will only work for
|
|
1186
|
+
# endomorphisms which have the same basis for domain and codomain
|
|
1187
|
+
# so we test equality on a basis, which is sufficient
|
|
1188
|
+
return all(self(u) == u for u in self.domain().basis())
|
|
1189
|
+
|
|
1190
|
+
def is_zero(self) -> bool:
|
|
1191
|
+
r"""
|
|
1192
|
+
Determine if this morphism is a zero function or not.
|
|
1193
|
+
|
|
1194
|
+
EXAMPLES:
|
|
1195
|
+
|
|
1196
|
+
A zero morphism created from a function. ::
|
|
1197
|
+
|
|
1198
|
+
sage: V = ZZ^5
|
|
1199
|
+
sage: W = ZZ^3
|
|
1200
|
+
sage: z = lambda x: zero_vector(ZZ, 3)
|
|
1201
|
+
sage: phi = V.hom(z, W)
|
|
1202
|
+
sage: phi.is_zero()
|
|
1203
|
+
True
|
|
1204
|
+
|
|
1205
|
+
An image list that just barely makes a nonzero morphism. ::
|
|
1206
|
+
|
|
1207
|
+
sage: V = ZZ^4
|
|
1208
|
+
sage: W = ZZ^6
|
|
1209
|
+
sage: z = zero_vector(ZZ, 6)
|
|
1210
|
+
sage: images = [z, z, W.5, z]
|
|
1211
|
+
sage: phi = V.hom(images, W)
|
|
1212
|
+
sage: phi.is_zero()
|
|
1213
|
+
False
|
|
1214
|
+
|
|
1215
|
+
TESTS::
|
|
1216
|
+
|
|
1217
|
+
sage: V = QQ^10
|
|
1218
|
+
sage: W = QQ^3
|
|
1219
|
+
sage: H = Hom(V, W)
|
|
1220
|
+
sage: rho = H.zero()
|
|
1221
|
+
sage: rho.is_zero()
|
|
1222
|
+
True
|
|
1223
|
+
|
|
1224
|
+
AUTHOR:
|
|
1225
|
+
|
|
1226
|
+
- Rob Beezer (2011-07-15)
|
|
1227
|
+
"""
|
|
1228
|
+
# any nonzero entry in any matrix representation
|
|
1229
|
+
# disqualifies the morphism as having totally zero outputs
|
|
1230
|
+
return self._matrix.is_zero()
|
|
1231
|
+
|
|
1232
|
+
def is_equal_function(self, other) -> bool:
|
|
1233
|
+
r"""
|
|
1234
|
+
Determine if two morphisms are equal functions.
|
|
1235
|
+
|
|
1236
|
+
INPUT:
|
|
1237
|
+
|
|
1238
|
+
- ``other`` -- a morphism to compare with ``self``
|
|
1239
|
+
|
|
1240
|
+
OUTPUT:
|
|
1241
|
+
|
|
1242
|
+
Returns ``True`` precisely when the two morphisms have
|
|
1243
|
+
equal domains and codomains (as sets) and produce identical
|
|
1244
|
+
output when given the same input. Otherwise returns ``False``.
|
|
1245
|
+
|
|
1246
|
+
This is useful when ``self`` and ``other`` may have different
|
|
1247
|
+
representations.
|
|
1248
|
+
|
|
1249
|
+
Sage's default comparison of matrix morphisms requires the
|
|
1250
|
+
domains to have the same bases and the codomains to have the
|
|
1251
|
+
same bases, and then compares the matrix representations.
|
|
1252
|
+
This notion of equality is more permissive (it will
|
|
1253
|
+
return ``True`` "more often"), but is more correct
|
|
1254
|
+
mathematically.
|
|
1255
|
+
|
|
1256
|
+
EXAMPLES:
|
|
1257
|
+
|
|
1258
|
+
Three morphisms defined by combinations of different
|
|
1259
|
+
bases for the domain and codomain and different functions.
|
|
1260
|
+
Two are equal, the third is different from both of the others. ::
|
|
1261
|
+
|
|
1262
|
+
sage: B = matrix(QQ, [[-3, 5, -4, 2],
|
|
1263
|
+
....: [-1, 2, -1, 4],
|
|
1264
|
+
....: [ 4, -6, 5, -1],
|
|
1265
|
+
....: [-5, 7, -6, 1]])
|
|
1266
|
+
sage: U = (QQ^4).subspace_with_basis(B.rows())
|
|
1267
|
+
sage: C = matrix(QQ, [[-1, -6, -4],
|
|
1268
|
+
....: [ 3, -5, 6],
|
|
1269
|
+
....: [ 1, 2, 3]])
|
|
1270
|
+
sage: V = (QQ^3).subspace_with_basis(C.rows())
|
|
1271
|
+
sage: H = Hom(U, V)
|
|
1272
|
+
|
|
1273
|
+
sage: D = matrix(QQ, [[-7, -2, -5, 2],
|
|
1274
|
+
....: [-5, 1, -4, -8],
|
|
1275
|
+
....: [ 1, -1, 1, 4],
|
|
1276
|
+
....: [-4, -1, -3, 1]])
|
|
1277
|
+
sage: X = (QQ^4).subspace_with_basis(D.rows())
|
|
1278
|
+
sage: E = matrix(QQ, [[ 4, -1, 4],
|
|
1279
|
+
....: [ 5, -4, -5],
|
|
1280
|
+
....: [-1, 0, -2]])
|
|
1281
|
+
sage: Y = (QQ^3).subspace_with_basis(E.rows())
|
|
1282
|
+
sage: K = Hom(X, Y)
|
|
1283
|
+
|
|
1284
|
+
sage: f = lambda x: vector(QQ, [x[0]+x[1], 2*x[1]-4*x[2], 5*x[3]])
|
|
1285
|
+
sage: g = lambda x: vector(QQ, [x[0]-x[2], 2*x[1]-4*x[2], 5*x[3]])
|
|
1286
|
+
|
|
1287
|
+
sage: rho = H(f)
|
|
1288
|
+
sage: phi = K(f)
|
|
1289
|
+
sage: zeta = H(g)
|
|
1290
|
+
|
|
1291
|
+
sage: rho.is_equal_function(phi)
|
|
1292
|
+
True
|
|
1293
|
+
sage: phi.is_equal_function(rho)
|
|
1294
|
+
True
|
|
1295
|
+
sage: zeta.is_equal_function(rho)
|
|
1296
|
+
False
|
|
1297
|
+
sage: phi.is_equal_function(zeta)
|
|
1298
|
+
False
|
|
1299
|
+
|
|
1300
|
+
TESTS::
|
|
1301
|
+
|
|
1302
|
+
sage: H = Hom(ZZ^2, ZZ^2)
|
|
1303
|
+
sage: phi = H(matrix(ZZ, 2, range(4)))
|
|
1304
|
+
sage: phi.is_equal_function('junk')
|
|
1305
|
+
Traceback (most recent call last):
|
|
1306
|
+
...
|
|
1307
|
+
TypeError: can only compare to a matrix morphism, not junk
|
|
1308
|
+
|
|
1309
|
+
AUTHOR:
|
|
1310
|
+
|
|
1311
|
+
- Rob Beezer (2011-07-15)
|
|
1312
|
+
"""
|
|
1313
|
+
if not isinstance(other, MatrixMorphism_abstract):
|
|
1314
|
+
msg = 'can only compare to a matrix morphism, not {0}'
|
|
1315
|
+
raise TypeError(msg.format(other))
|
|
1316
|
+
if self.domain() != other.domain():
|
|
1317
|
+
return False
|
|
1318
|
+
if self.codomain() != other.codomain():
|
|
1319
|
+
return False
|
|
1320
|
+
# check agreement on any basis of the domain
|
|
1321
|
+
return all(self(u) == other(u) for u in self.domain().basis())
|
|
1322
|
+
|
|
1323
|
+
def restrict_domain(self, sub):
|
|
1324
|
+
"""
|
|
1325
|
+
Restrict this matrix morphism to a subspace sub of the domain. The
|
|
1326
|
+
subspace sub should have a basis() method and elements of the basis
|
|
1327
|
+
should be coercible into domain.
|
|
1328
|
+
|
|
1329
|
+
The resulting morphism has the same codomain as before, but a new
|
|
1330
|
+
domain.
|
|
1331
|
+
|
|
1332
|
+
EXAMPLES::
|
|
1333
|
+
|
|
1334
|
+
sage: V = ZZ^2; phi = V.hom([3*V.0, 2*V.1])
|
|
1335
|
+
sage: phi.restrict_domain(V.span([V.0]))
|
|
1336
|
+
Free module morphism defined by the matrix
|
|
1337
|
+
[3 0]
|
|
1338
|
+
Domain: Free module of degree 2 and rank 1 over Integer Ring
|
|
1339
|
+
Echelon ...
|
|
1340
|
+
Codomain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
1341
|
+
sage: phi.restrict_domain(V.span([V.1]))
|
|
1342
|
+
Free module morphism defined by the matrix
|
|
1343
|
+
[0 2]...
|
|
1344
|
+
sage: m = matrix(2, range(1,5))
|
|
1345
|
+
sage: f1 = V.hom(m); f2 = V.hom(m, side='right')
|
|
1346
|
+
sage: SV = V.span([V.0])
|
|
1347
|
+
sage: f1.restrict_domain(SV)
|
|
1348
|
+
Free module morphism defined by the matrix
|
|
1349
|
+
[1 2]...
|
|
1350
|
+
sage: f2.restrict_domain(SV)
|
|
1351
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
1352
|
+
[1]
|
|
1353
|
+
[3]...
|
|
1354
|
+
"""
|
|
1355
|
+
D = self.domain()
|
|
1356
|
+
if hasattr(D, 'coordinate_module'):
|
|
1357
|
+
# We only have to do this in case the module supports
|
|
1358
|
+
# alternative basis. Some modules do, some modules don't.
|
|
1359
|
+
V = D.coordinate_module(sub)
|
|
1360
|
+
else:
|
|
1361
|
+
V = sub.free_module()
|
|
1362
|
+
if self.side() == "right":
|
|
1363
|
+
A = self.matrix().transpose().restrict_domain(V).transpose()
|
|
1364
|
+
else:
|
|
1365
|
+
A = self.matrix().restrict_domain(V)
|
|
1366
|
+
H = sub.Hom(self.codomain())
|
|
1367
|
+
try:
|
|
1368
|
+
return H(A, side=self.side())
|
|
1369
|
+
except Exception:
|
|
1370
|
+
return H(A)
|
|
1371
|
+
|
|
1372
|
+
def restrict_codomain(self, sub):
|
|
1373
|
+
"""
|
|
1374
|
+
Restrict this matrix morphism to a subspace sub of the codomain.
|
|
1375
|
+
|
|
1376
|
+
The resulting morphism has the same domain as before, but a new
|
|
1377
|
+
codomain.
|
|
1378
|
+
|
|
1379
|
+
EXAMPLES::
|
|
1380
|
+
|
|
1381
|
+
sage: V = ZZ^2; phi = V.hom([4*(V.0+V.1),0])
|
|
1382
|
+
sage: W = V.span([2*(V.0+V.1)])
|
|
1383
|
+
sage: phi
|
|
1384
|
+
Free module morphism defined by the matrix
|
|
1385
|
+
[4 4]
|
|
1386
|
+
[0 0]
|
|
1387
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
1388
|
+
Codomain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
1389
|
+
sage: psi = phi.restrict_codomain(W); psi
|
|
1390
|
+
Free module morphism defined by the matrix
|
|
1391
|
+
[2]
|
|
1392
|
+
[0]
|
|
1393
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain ...
|
|
1394
|
+
Codomain: Free module of degree 2 and rank 1 over Integer Ring
|
|
1395
|
+
Echelon ...
|
|
1396
|
+
sage: phi2 = phi.side_switch(); phi2.restrict_codomain(W)
|
|
1397
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
1398
|
+
[2 0]
|
|
1399
|
+
Domain: Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
1400
|
+
Codomain: Free module of degree 2 and rank 1 over Integer Ring
|
|
1401
|
+
Echelon ...
|
|
1402
|
+
|
|
1403
|
+
An example in which the codomain equals the full ambient space, but
|
|
1404
|
+
with a different basis::
|
|
1405
|
+
|
|
1406
|
+
sage: V = QQ^2
|
|
1407
|
+
sage: W = V.span_of_basis([[1,2],[3,4]])
|
|
1408
|
+
sage: phi = V.hom(matrix(QQ,2,[1,0,2,0]),W)
|
|
1409
|
+
sage: phi.matrix()
|
|
1410
|
+
[1 0]
|
|
1411
|
+
[2 0]
|
|
1412
|
+
sage: phi(V.0)
|
|
1413
|
+
(1, 2)
|
|
1414
|
+
sage: phi(V.1)
|
|
1415
|
+
(2, 4)
|
|
1416
|
+
sage: X = V.span([[1,2]]); X
|
|
1417
|
+
Vector space of degree 2 and dimension 1 over Rational Field
|
|
1418
|
+
Basis matrix:
|
|
1419
|
+
[1 2]
|
|
1420
|
+
sage: phi(V.0) in X
|
|
1421
|
+
True
|
|
1422
|
+
sage: phi(V.1) in X
|
|
1423
|
+
True
|
|
1424
|
+
sage: psi = phi.restrict_codomain(X); psi
|
|
1425
|
+
Vector space morphism represented by the matrix:
|
|
1426
|
+
[1]
|
|
1427
|
+
[2]
|
|
1428
|
+
Domain: Vector space of dimension 2 over Rational Field
|
|
1429
|
+
Codomain: Vector space of degree 2 and dimension 1 over Rational Field
|
|
1430
|
+
Basis matrix:
|
|
1431
|
+
[1 2]
|
|
1432
|
+
sage: psi(V.0)
|
|
1433
|
+
(1, 2)
|
|
1434
|
+
sage: psi(V.1)
|
|
1435
|
+
(2, 4)
|
|
1436
|
+
sage: psi(V.0).parent() is X
|
|
1437
|
+
True
|
|
1438
|
+
"""
|
|
1439
|
+
H = self.domain().Hom(sub)
|
|
1440
|
+
C = self.codomain()
|
|
1441
|
+
if hasattr(C, 'coordinate_module'):
|
|
1442
|
+
# We only have to do this in case the module supports
|
|
1443
|
+
# alternative basis. Some modules do, some modules don't.
|
|
1444
|
+
V = C.coordinate_module(sub)
|
|
1445
|
+
else:
|
|
1446
|
+
V = sub.free_module()
|
|
1447
|
+
try:
|
|
1448
|
+
if self.side() == "right":
|
|
1449
|
+
return H(self.matrix().transpose().restrict_codomain(V).transpose(), side='right')
|
|
1450
|
+
else:
|
|
1451
|
+
return H(self.matrix().restrict_codomain(V))
|
|
1452
|
+
except Exception:
|
|
1453
|
+
return H(self.matrix().restrict_codomain(V))
|
|
1454
|
+
|
|
1455
|
+
def restrict(self, sub):
|
|
1456
|
+
"""
|
|
1457
|
+
Restrict this matrix morphism to a subspace sub of the domain.
|
|
1458
|
+
|
|
1459
|
+
The codomain and domain of the resulting matrix are both sub.
|
|
1460
|
+
|
|
1461
|
+
EXAMPLES::
|
|
1462
|
+
|
|
1463
|
+
sage: V = ZZ^2; phi = V.hom([3*V.0, 2*V.1])
|
|
1464
|
+
sage: phi.restrict(V.span([V.0]))
|
|
1465
|
+
Free module morphism defined by the matrix
|
|
1466
|
+
[3]
|
|
1467
|
+
Domain: Free module of degree 2 and rank 1 over Integer Ring
|
|
1468
|
+
Echelon ...
|
|
1469
|
+
Codomain: Free module of degree 2 and rank 1 over Integer Ring
|
|
1470
|
+
Echelon ...
|
|
1471
|
+
|
|
1472
|
+
sage: V = (QQ^2).span_of_basis([[1,2], [3,4]])
|
|
1473
|
+
sage: phi = V.hom([V.0 + V.1, 2*V.1])
|
|
1474
|
+
sage: phi(V.1) == 2*V.1
|
|
1475
|
+
True
|
|
1476
|
+
sage: W = span([V.1])
|
|
1477
|
+
sage: phi(W)
|
|
1478
|
+
Vector space of degree 2 and dimension 1 over Rational Field
|
|
1479
|
+
Basis matrix:
|
|
1480
|
+
[ 1 4/3]
|
|
1481
|
+
sage: psi = phi.restrict(W); psi
|
|
1482
|
+
Vector space morphism represented by the matrix:
|
|
1483
|
+
[2]
|
|
1484
|
+
Domain: Vector space of degree 2 and dimension 1 over Rational Field
|
|
1485
|
+
Basis matrix:
|
|
1486
|
+
[ 1 4/3]
|
|
1487
|
+
Codomain: Vector space of degree 2 and dimension 1 over Rational Field
|
|
1488
|
+
Basis matrix:
|
|
1489
|
+
[ 1 4/3]
|
|
1490
|
+
sage: psi.domain() == W
|
|
1491
|
+
True
|
|
1492
|
+
sage: psi(W.0) == 2*W.0
|
|
1493
|
+
True
|
|
1494
|
+
|
|
1495
|
+
::
|
|
1496
|
+
|
|
1497
|
+
sage: V = ZZ^3
|
|
1498
|
+
sage: h1 = V.hom([V.0, V.1+V.2, -V.1+V.2])
|
|
1499
|
+
sage: h2 = h1.side_switch()
|
|
1500
|
+
sage: SV = V.span([2*V.1,2*V.2])
|
|
1501
|
+
sage: h1.restrict(SV)
|
|
1502
|
+
Free module morphism defined by the matrix
|
|
1503
|
+
[ 1 1]
|
|
1504
|
+
[-1 1]
|
|
1505
|
+
Domain: Free module of degree 3 and rank 2 over Integer Ring
|
|
1506
|
+
Echelon basis matrix:
|
|
1507
|
+
[0 2 0]
|
|
1508
|
+
[0 0 2]
|
|
1509
|
+
Codomain: Free module of degree 3 and rank 2 over Integer Ring
|
|
1510
|
+
Echelon basis matrix:
|
|
1511
|
+
[0 2 0]
|
|
1512
|
+
[0 0 2]
|
|
1513
|
+
sage: h2.restrict(SV)
|
|
1514
|
+
Free module morphism defined as left-multiplication by the matrix
|
|
1515
|
+
[ 1 -1]
|
|
1516
|
+
[ 1 1]
|
|
1517
|
+
Domain: Free module of degree 3 and rank 2 over Integer Ring
|
|
1518
|
+
Echelon basis matrix:
|
|
1519
|
+
[0 2 0]
|
|
1520
|
+
[0 0 2]
|
|
1521
|
+
Codomain: Free module of degree 3 and rank 2 over Integer Ring
|
|
1522
|
+
Echelon basis matrix:
|
|
1523
|
+
[0 2 0]
|
|
1524
|
+
[0 0 2]
|
|
1525
|
+
"""
|
|
1526
|
+
if not self.is_endomorphism():
|
|
1527
|
+
raise ArithmeticError("matrix morphism must be an endomorphism")
|
|
1528
|
+
D = self.domain()
|
|
1529
|
+
C = self.codomain()
|
|
1530
|
+
if D is not C and (D.basis() != C.basis()):
|
|
1531
|
+
# Tricky case when two bases for same space
|
|
1532
|
+
return self.restrict_domain(sub).restrict_codomain(sub)
|
|
1533
|
+
if hasattr(D, 'coordinate_module'):
|
|
1534
|
+
# We only have to do this in case the module supports
|
|
1535
|
+
# alternative basis. Some modules do, some modules don't.
|
|
1536
|
+
V = D.coordinate_module(sub)
|
|
1537
|
+
else:
|
|
1538
|
+
V = sub.free_module()
|
|
1539
|
+
if self.side() == "right":
|
|
1540
|
+
A = self.matrix().transpose().restrict(V).transpose()
|
|
1541
|
+
else:
|
|
1542
|
+
A = self.matrix().restrict(V)
|
|
1543
|
+
H = sage.categories.homset.End(sub, self.domain().category())
|
|
1544
|
+
return H(A, side=self.side())
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
class MatrixMorphism(MatrixMorphism_abstract):
|
|
1548
|
+
"""
|
|
1549
|
+
A morphism defined by a matrix.
|
|
1550
|
+
|
|
1551
|
+
INPUT:
|
|
1552
|
+
|
|
1553
|
+
- ``parent`` -- a homspace
|
|
1554
|
+
|
|
1555
|
+
- ``A`` -- matrix or a :class:`MatrixMorphism_abstract` instance
|
|
1556
|
+
|
|
1557
|
+
- ``copy_matrix`` -- boolean (default: ``True``); make an immutable copy of
|
|
1558
|
+
the matrix ``A`` if it is mutable. If ``False``, then this makes
|
|
1559
|
+
``A`` immutable.
|
|
1560
|
+
"""
|
|
1561
|
+
def __init__(self, parent, A, copy_matrix=True, side='left'):
|
|
1562
|
+
"""
|
|
1563
|
+
Initialize ``self``.
|
|
1564
|
+
|
|
1565
|
+
EXAMPLES::
|
|
1566
|
+
|
|
1567
|
+
sage: from sage.modules.matrix_morphism import MatrixMorphism
|
|
1568
|
+
sage: T = End(ZZ^3)
|
|
1569
|
+
sage: M = MatrixSpace(ZZ, 3)
|
|
1570
|
+
sage: I = M.identity_matrix()
|
|
1571
|
+
sage: A = MatrixMorphism(T, I)
|
|
1572
|
+
sage: loads(A.dumps()) == A
|
|
1573
|
+
True
|
|
1574
|
+
"""
|
|
1575
|
+
if parent is None:
|
|
1576
|
+
raise ValueError("no parent given when creating this matrix morphism")
|
|
1577
|
+
if isinstance(A, MatrixMorphism_abstract):
|
|
1578
|
+
A = A.matrix()
|
|
1579
|
+
if side == "left":
|
|
1580
|
+
if A.nrows() != parent.domain().rank():
|
|
1581
|
+
raise ArithmeticError("number of rows of matrix (={}) must equal rank of domain (={})".format(A.nrows(), parent.domain().rank()))
|
|
1582
|
+
if A.ncols() != parent.codomain().rank():
|
|
1583
|
+
raise ArithmeticError("number of columns of matrix (={}) must equal rank of codomain (={})".format(A.ncols(), parent.codomain().rank()))
|
|
1584
|
+
if side == "right":
|
|
1585
|
+
if A.nrows() != parent.codomain().rank():
|
|
1586
|
+
raise ArithmeticError("number of rows of matrix (={}) must equal rank of codomain (={})".format(A.nrows(), parent.domain().rank()))
|
|
1587
|
+
if A.ncols() != parent.domain().rank():
|
|
1588
|
+
raise ArithmeticError("number of columns of matrix (={}) must equal rank of domain (={})".format(A.ncols(), parent.codomain().rank()))
|
|
1589
|
+
if A.is_mutable():
|
|
1590
|
+
if copy_matrix:
|
|
1591
|
+
from copy import copy
|
|
1592
|
+
A = copy(A)
|
|
1593
|
+
A.set_immutable()
|
|
1594
|
+
self._matrix = A
|
|
1595
|
+
MatrixMorphism_abstract.__init__(self, parent, side)
|
|
1596
|
+
|
|
1597
|
+
def matrix(self, side=None):
|
|
1598
|
+
r"""
|
|
1599
|
+
Return a matrix that defines this morphism.
|
|
1600
|
+
|
|
1601
|
+
INPUT:
|
|
1602
|
+
|
|
1603
|
+
- ``side`` -- (default: ``None``) the side of the matrix
|
|
1604
|
+
where a vector is placed to effect the morphism (function)
|
|
1605
|
+
|
|
1606
|
+
OUTPUT:
|
|
1607
|
+
|
|
1608
|
+
A matrix which represents the morphism, relative to bases
|
|
1609
|
+
for the domain and codomain. If the modules are provided
|
|
1610
|
+
with user bases, then the representation is relative to
|
|
1611
|
+
these bases.
|
|
1612
|
+
|
|
1613
|
+
Internally, Sage represents a matrix morphism with the
|
|
1614
|
+
matrix multiplying a row vector placed to the left of the
|
|
1615
|
+
matrix. If the option ``side='right'`` is used, then a
|
|
1616
|
+
matrix is returned that acts on a vector to the right of
|
|
1617
|
+
the matrix. These two matrices are just transposes of
|
|
1618
|
+
each other and the difference is just a preference for
|
|
1619
|
+
the style of representation.
|
|
1620
|
+
|
|
1621
|
+
EXAMPLES::
|
|
1622
|
+
|
|
1623
|
+
sage: V = ZZ^2; W = ZZ^3
|
|
1624
|
+
sage: m = column_matrix([3*V.0 - 5*V.1, 4*V.0 + 2*V.1, V.0 + V.1])
|
|
1625
|
+
sage: phi = V.hom(m, W)
|
|
1626
|
+
sage: phi.matrix()
|
|
1627
|
+
[ 3 4 1]
|
|
1628
|
+
[-5 2 1]
|
|
1629
|
+
|
|
1630
|
+
sage: phi.matrix(side='right')
|
|
1631
|
+
[ 3 -5]
|
|
1632
|
+
[ 4 2]
|
|
1633
|
+
[ 1 1]
|
|
1634
|
+
|
|
1635
|
+
TESTS::
|
|
1636
|
+
|
|
1637
|
+
sage: V = ZZ^2
|
|
1638
|
+
sage: phi = V.hom([3*V.0, 2*V.1])
|
|
1639
|
+
sage: phi.matrix(side='junk')
|
|
1640
|
+
Traceback (most recent call last):
|
|
1641
|
+
...
|
|
1642
|
+
ValueError: side must be 'left' or 'right', not junk
|
|
1643
|
+
"""
|
|
1644
|
+
if side not in ['left', 'right', None]:
|
|
1645
|
+
raise ValueError("side must be 'left' or 'right', not {}".format(side))
|
|
1646
|
+
if side == self.side() or side is None:
|
|
1647
|
+
return self._matrix
|
|
1648
|
+
return self._matrix.transpose()
|
|
1649
|
+
|
|
1650
|
+
def is_injective(self) -> bool:
|
|
1651
|
+
"""
|
|
1652
|
+
Tell whether ``self`` is injective.
|
|
1653
|
+
|
|
1654
|
+
EXAMPLES::
|
|
1655
|
+
|
|
1656
|
+
sage: V1 = QQ^2
|
|
1657
|
+
sage: V2 = QQ^3
|
|
1658
|
+
sage: phi = V1.hom(Matrix([[1,2,3], [4,5,6]]),V2)
|
|
1659
|
+
sage: phi.is_injective()
|
|
1660
|
+
True
|
|
1661
|
+
sage: psi = V2.hom(Matrix([[1,2], [3,4], [5,6]]),V1)
|
|
1662
|
+
sage: psi.is_injective()
|
|
1663
|
+
False
|
|
1664
|
+
|
|
1665
|
+
AUTHOR:
|
|
1666
|
+
|
|
1667
|
+
-- Simon King (2010-05)
|
|
1668
|
+
"""
|
|
1669
|
+
if self.side() == 'left':
|
|
1670
|
+
ker = self._matrix.left_kernel()
|
|
1671
|
+
else:
|
|
1672
|
+
ker = self._matrix.right_kernel()
|
|
1673
|
+
return ker.dimension() == 0
|
|
1674
|
+
|
|
1675
|
+
def is_surjective(self) -> bool:
|
|
1676
|
+
r"""
|
|
1677
|
+
Tell whether ``self`` is surjective.
|
|
1678
|
+
|
|
1679
|
+
EXAMPLES::
|
|
1680
|
+
|
|
1681
|
+
sage: V1 = QQ^2
|
|
1682
|
+
sage: V2 = QQ^3
|
|
1683
|
+
sage: phi = V1.hom(Matrix([[1,2,3], [4,5,6]]), V2)
|
|
1684
|
+
sage: phi.is_surjective()
|
|
1685
|
+
False
|
|
1686
|
+
sage: psi = V2.hom(Matrix([[1,2], [3,4], [5,6]]), V1)
|
|
1687
|
+
sage: psi.is_surjective()
|
|
1688
|
+
True
|
|
1689
|
+
|
|
1690
|
+
An example over a PID that is not `\ZZ`. ::
|
|
1691
|
+
|
|
1692
|
+
sage: R.<x> = PolynomialRing(QQ)
|
|
1693
|
+
sage: A = R^2
|
|
1694
|
+
sage: B = R^2
|
|
1695
|
+
sage: H = A.hom([B([x^2 - 1, 1]), B([x^2, 1])])
|
|
1696
|
+
sage: H.image()
|
|
1697
|
+
Free module of degree 2 and rank 2 over Univariate Polynomial Ring in x over Rational Field
|
|
1698
|
+
Echelon basis matrix:
|
|
1699
|
+
[ 1 0]
|
|
1700
|
+
[ 0 -1]
|
|
1701
|
+
sage: H.is_surjective()
|
|
1702
|
+
True
|
|
1703
|
+
|
|
1704
|
+
This tests if :issue:`11552` is fixed. ::
|
|
1705
|
+
|
|
1706
|
+
sage: V = ZZ^2
|
|
1707
|
+
sage: m = matrix(ZZ, [[1,2], [0,2]])
|
|
1708
|
+
sage: phi = V.hom(m, V)
|
|
1709
|
+
sage: phi.lift(vector(ZZ, [0, 1]))
|
|
1710
|
+
Traceback (most recent call last):
|
|
1711
|
+
...
|
|
1712
|
+
ValueError: element is not in the image
|
|
1713
|
+
sage: phi.is_surjective()
|
|
1714
|
+
False
|
|
1715
|
+
|
|
1716
|
+
AUTHORS:
|
|
1717
|
+
|
|
1718
|
+
- Simon King (2010-05)
|
|
1719
|
+
- Rob Beezer (2011-06-28)
|
|
1720
|
+
"""
|
|
1721
|
+
# Testing equality of free modules over PIDs is unreliable
|
|
1722
|
+
# see Issue #11579 for explanation and status
|
|
1723
|
+
# We test if image equals codomain with two inclusions
|
|
1724
|
+
# reverse inclusion of below is trivially true
|
|
1725
|
+
return self.codomain().is_submodule(self.image())
|
|
1726
|
+
|
|
1727
|
+
def _repr_(self):
|
|
1728
|
+
r"""
|
|
1729
|
+
Return string representation of this matrix morphism.
|
|
1730
|
+
|
|
1731
|
+
This will typically be overloaded in a derived class.
|
|
1732
|
+
|
|
1733
|
+
EXAMPLES::
|
|
1734
|
+
|
|
1735
|
+
sage: V = ZZ^2; phi = V.hom([3*V.0, 2*V.1])
|
|
1736
|
+
sage: sage.modules.matrix_morphism.MatrixMorphism._repr_(phi)
|
|
1737
|
+
'Morphism defined by the matrix\n[3 0]\n[0 2]'
|
|
1738
|
+
|
|
1739
|
+
sage: phi._repr_()
|
|
1740
|
+
'Free module morphism defined by the matrix\n[3 0]\n[0 2]\nDomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring\nCodomain: Ambient free module of rank 2 over the principal ideal domain Integer Ring'
|
|
1741
|
+
"""
|
|
1742
|
+
rep = "Morphism defined by the matrix\n{}".format(self.matrix())
|
|
1743
|
+
if self._side == 'right':
|
|
1744
|
+
rep += " acting by multiplication on the left"
|
|
1745
|
+
return rep
|