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
sage/matrix/matrix1.pyx
ADDED
|
@@ -0,0 +1,2851 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
"""
|
|
3
|
+
Base class for matrices, part 1
|
|
4
|
+
|
|
5
|
+
For design documentation see :mod:`sage.matrix.docs`.
|
|
6
|
+
|
|
7
|
+
TESTS::
|
|
8
|
+
|
|
9
|
+
sage: A = Matrix(GF(5), 3, 3, srange(9))
|
|
10
|
+
sage: TestSuite(A).run()
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# ***************************************************************************
|
|
14
|
+
# Copyright (C) 2005, 2006 William Stein <wstein@gmail.com>
|
|
15
|
+
#
|
|
16
|
+
# This program is free software: you can redistribute it and/or modify
|
|
17
|
+
# it under the terms of the GNU General Public License as published by
|
|
18
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
19
|
+
# (at your option) any later version.
|
|
20
|
+
# https://www.gnu.org/licenses/
|
|
21
|
+
# ***************************************************************************
|
|
22
|
+
|
|
23
|
+
from cpython.sequence cimport PySequence_Fast
|
|
24
|
+
|
|
25
|
+
import sage.modules.free_module
|
|
26
|
+
from sage.structure.coerce cimport coercion_model
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
cdef class Matrix(Matrix0):
|
|
30
|
+
###################################################
|
|
31
|
+
# Coercion to Various Systems
|
|
32
|
+
###################################################
|
|
33
|
+
|
|
34
|
+
def _pari_init_(self):
|
|
35
|
+
"""
|
|
36
|
+
Return a string defining a GP representation of ``self``.
|
|
37
|
+
|
|
38
|
+
EXAMPLES::
|
|
39
|
+
|
|
40
|
+
sage: R.<x> = QQ['x']
|
|
41
|
+
sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a
|
|
42
|
+
[ x + 1 2/3]
|
|
43
|
+
[1/2*x^2 x^3 + 1]
|
|
44
|
+
sage: b = gp(a); b # indirect doctest # needs sage.libs.pari
|
|
45
|
+
[x + 1, 2/3; 1/2*x^2, x^3 + 1]
|
|
46
|
+
sage: a.determinant()
|
|
47
|
+
x^4 + x^3 - 1/3*x^2 + x + 1
|
|
48
|
+
sage: b.matdet() # needs sage.libs.pari
|
|
49
|
+
x^4 + x^3 - 1/3*x^2 + x + 1
|
|
50
|
+
"""
|
|
51
|
+
w = self.list()
|
|
52
|
+
cdef Py_ssize_t nr, nc, i, j
|
|
53
|
+
nr = self._nrows
|
|
54
|
+
nc = self._ncols
|
|
55
|
+
v = []
|
|
56
|
+
for i from 0 <= i < nr:
|
|
57
|
+
tmp = []
|
|
58
|
+
for j from 0 <= j < nc:
|
|
59
|
+
tmp.append(w[i * nc + j]._pari_init_())
|
|
60
|
+
v.append(','.join(tmp))
|
|
61
|
+
return 'Mat([%s])' % (';'.join(v))
|
|
62
|
+
|
|
63
|
+
def __pari__(self):
|
|
64
|
+
"""
|
|
65
|
+
Return the Pari matrix corresponding to ``self``.
|
|
66
|
+
|
|
67
|
+
EXAMPLES::
|
|
68
|
+
|
|
69
|
+
sage: R.<x> = QQ['x']
|
|
70
|
+
sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a
|
|
71
|
+
[ x + 1 2/3]
|
|
72
|
+
[1/2*x^2 x^3 + 1]
|
|
73
|
+
sage: b = pari(a); b # indirect doctest # needs sage.libs.pari
|
|
74
|
+
[x + 1, 2/3; 1/2*x^2, x^3 + 1]
|
|
75
|
+
sage: a.determinant()
|
|
76
|
+
x^4 + x^3 - 1/3*x^2 + x + 1
|
|
77
|
+
sage: b.matdet() # needs sage.libs.pari
|
|
78
|
+
x^4 + x^3 - 1/3*x^2 + x + 1
|
|
79
|
+
|
|
80
|
+
This function preserves precision for entries of inexact type (e.g.
|
|
81
|
+
reals)::
|
|
82
|
+
|
|
83
|
+
sage: R = RealField(4) # 4 bits of precision
|
|
84
|
+
sage: a = matrix(R, 2, [1, 2, 3, 1]); a
|
|
85
|
+
[1.0 2.0]
|
|
86
|
+
[3.0 1.0]
|
|
87
|
+
sage: b = pari(a); b # needs sage.libs.pari
|
|
88
|
+
[1.000000000, 2.000000000; 3.000000000, 1.000000000] # 32-bit
|
|
89
|
+
[1.00000000000000, 2.00000000000000; 3.00000000000000, 1.00000000000000] # 64-bit
|
|
90
|
+
"""
|
|
91
|
+
from sage.libs.pari import pari
|
|
92
|
+
return pari.matrix(self._nrows, self._ncols, self._list())
|
|
93
|
+
|
|
94
|
+
def _gap_init_(self):
|
|
95
|
+
"""
|
|
96
|
+
Return a string defining a gap representation of ``self``.
|
|
97
|
+
|
|
98
|
+
EXAMPLES::
|
|
99
|
+
|
|
100
|
+
sage: # needs sage.libs.gap
|
|
101
|
+
sage: A = MatrixSpace(QQ,3,3)([0,1,2,3,4,5,6,7,8])
|
|
102
|
+
sage: g = gap(A) # indirect doctest
|
|
103
|
+
sage: g
|
|
104
|
+
[ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ]
|
|
105
|
+
sage: g.CharacteristicPolynomial()
|
|
106
|
+
x_1^3-12*x_1^2-18*x_1
|
|
107
|
+
sage: A.characteristic_polynomial() # needs sage.libs.pari
|
|
108
|
+
x^3 - 12*x^2 - 18*x
|
|
109
|
+
sage: matrix(QQ, g) == A
|
|
110
|
+
True
|
|
111
|
+
|
|
112
|
+
Particularly difficult is the case of matrices over cyclotomic
|
|
113
|
+
fields and general number fields. See :issue:`5618` and :issue:`8909`::
|
|
114
|
+
|
|
115
|
+
sage: # needs sage.libs.gap sage.rings.number_field
|
|
116
|
+
sage: K.<zeta> = CyclotomicField(8)
|
|
117
|
+
sage: A = MatrixSpace(K, 2, 2)([0, 1+zeta, 2*zeta, 3])
|
|
118
|
+
sage: g = gap(A); g
|
|
119
|
+
[ [ 0, 1+E(8) ], [ 2*E(8), 3 ] ]
|
|
120
|
+
sage: matrix(K, g) == A
|
|
121
|
+
True
|
|
122
|
+
sage: g.IsMatrix()
|
|
123
|
+
true
|
|
124
|
+
|
|
125
|
+
sage: # needs sage.libs.gap sage.rings.number_field
|
|
126
|
+
sage: x = polygen(ZZ, 'x')
|
|
127
|
+
sage: L.<tau> = NumberField(x^3 - 2)
|
|
128
|
+
sage: A = MatrixSpace(L, 2, 2)([0, 1+tau, 2*tau, 3])
|
|
129
|
+
sage: g = gap(A); g
|
|
130
|
+
[ [ !0, tau+1 ], [ 2*tau, !3 ] ]
|
|
131
|
+
sage: matrix(L, g) == A
|
|
132
|
+
True
|
|
133
|
+
"""
|
|
134
|
+
cdef Py_ssize_t i, j
|
|
135
|
+
v = []
|
|
136
|
+
for i from 0 <= i < self._nrows:
|
|
137
|
+
tmp = []
|
|
138
|
+
for j from 0 <= j < self._ncols:
|
|
139
|
+
tmp.append(self.get_unsafe(i, j)._gap_init_())
|
|
140
|
+
v.append('[%s]' % (','.join(tmp)))
|
|
141
|
+
# It is needed to multiply with 'One(...)', because
|
|
142
|
+
# otherwise the result would not be a gap matrix
|
|
143
|
+
return '[%s]*One(%s)' % (','.join(v),
|
|
144
|
+
sage.interfaces.gap.gap(self.base_ring()).name())
|
|
145
|
+
|
|
146
|
+
def _libgap_(self):
|
|
147
|
+
"""
|
|
148
|
+
Construct a LibGAP matrix.
|
|
149
|
+
|
|
150
|
+
INPUT:
|
|
151
|
+
|
|
152
|
+
- ``M`` -- a matrix
|
|
153
|
+
|
|
154
|
+
OUTPUT:
|
|
155
|
+
|
|
156
|
+
A GAP matrix, that is, a list of lists with entries over a
|
|
157
|
+
common ring.
|
|
158
|
+
|
|
159
|
+
EXAMPLES::
|
|
160
|
+
|
|
161
|
+
sage: libgap(identity_matrix(ZZ, 2)) # needs sage.libs.gap
|
|
162
|
+
[ [ 1, 0 ], [ 0, 1 ] ]
|
|
163
|
+
sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # needs sage.libs.gap
|
|
164
|
+
[ [ Z(3)^0, Z(3) ], [ 0*Z(3), Z(3)^0 ] ]
|
|
165
|
+
"""
|
|
166
|
+
from sage.libs.gap.libgap import libgap
|
|
167
|
+
return libgap._construct_matrix(self)
|
|
168
|
+
|
|
169
|
+
def _fricas_init_(self):
|
|
170
|
+
"""
|
|
171
|
+
Return a FriCAS string representation of this matrix.
|
|
172
|
+
|
|
173
|
+
EXAMPLES::
|
|
174
|
+
|
|
175
|
+
sage: M = matrix(ZZ,2,range(4))
|
|
176
|
+
sage: fricas(M) # optional - fricas
|
|
177
|
+
+0 1+
|
|
178
|
+
| |
|
|
179
|
+
+2 3+
|
|
180
|
+
|
|
181
|
+
::
|
|
182
|
+
|
|
183
|
+
sage: M = matrix(QQ,3,[1,2,3,4/3,5/3,6/4,7,8,9])
|
|
184
|
+
sage: fricas(M).sage().parent() # optional - fricas
|
|
185
|
+
Full MatrixSpace of 3 by 3 dense matrices over Rational Field
|
|
186
|
+
|
|
187
|
+
::
|
|
188
|
+
|
|
189
|
+
sage: P.<x> = ZZ[]
|
|
190
|
+
sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5])
|
|
191
|
+
sage: fricas(M) # optional - fricas
|
|
192
|
+
+ 2 +
|
|
193
|
+
|- 9 x - 2 x + 2 x - 1 |
|
|
194
|
+
| |
|
|
195
|
+
| 2 2 |
|
|
196
|
+
+ x + 8 x - 3 x + 5+
|
|
197
|
+
|
|
198
|
+
::
|
|
199
|
+
|
|
200
|
+
sage: y = var('y') # needs sage.symbolic
|
|
201
|
+
sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic
|
|
202
|
+
sage: M == fricas(M).sage() # optional - fricas # needs sage.symbolic
|
|
203
|
+
True
|
|
204
|
+
"""
|
|
205
|
+
s = ','.join('[' + ','.join(cf._fricas_init_() for cf in row) + ']'
|
|
206
|
+
for row in self.rows())
|
|
207
|
+
R = self.base_ring()
|
|
208
|
+
try:
|
|
209
|
+
R._fricas_()
|
|
210
|
+
except TypeError:
|
|
211
|
+
return "matrix([%s])" % s
|
|
212
|
+
return "matrix([%s])$Matrix(%s)" % (s, R._fricas_init_())
|
|
213
|
+
|
|
214
|
+
def _giac_init_(self):
|
|
215
|
+
"""
|
|
216
|
+
Return a Giac string representation of this matrix.
|
|
217
|
+
|
|
218
|
+
EXAMPLES::
|
|
219
|
+
|
|
220
|
+
sage: M = matrix(ZZ, 2, range(4))
|
|
221
|
+
sage: giac(M) # needs giac
|
|
222
|
+
[[0,1],[2,3]]
|
|
223
|
+
|
|
224
|
+
sage: M = matrix(QQ, 3, [1,2,3, 4/3,5/3,6/4, 7,8,9])
|
|
225
|
+
sage: giac(M) # needs giac
|
|
226
|
+
[[1,2,3],[4/3,5/3,3/2],[7,8,9]]
|
|
227
|
+
|
|
228
|
+
sage: P.<x> = ZZ[]
|
|
229
|
+
sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5])
|
|
230
|
+
sage: giac(M) # needs giac
|
|
231
|
+
[[-9*sageVARx^2-2*sageVARx+2,sageVARx-1],[sageVARx^2+8*sageVARx,-3*sageVARx^2+5]]
|
|
232
|
+
|
|
233
|
+
sage: y = var('y') # needs sage.symbolic
|
|
234
|
+
sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic
|
|
235
|
+
sage: giac(M).det().sage() # needs giac sage.symbolic
|
|
236
|
+
(y^2*dilog(y) + y*dilog(y)*sin(y) - y + 4)/y
|
|
237
|
+
"""
|
|
238
|
+
s = ','.join('[' + ','.join(cf._giac_init_() for cf in row) + ']'
|
|
239
|
+
for row in self.rows())
|
|
240
|
+
return "([%s])" % s
|
|
241
|
+
|
|
242
|
+
def _maxima_init_(self):
|
|
243
|
+
"""
|
|
244
|
+
Return a string representation of this matrix in Maxima.
|
|
245
|
+
|
|
246
|
+
EXAMPLES::
|
|
247
|
+
|
|
248
|
+
sage: m = matrix(3,range(9)); m
|
|
249
|
+
[0 1 2]
|
|
250
|
+
[3 4 5]
|
|
251
|
+
[6 7 8]
|
|
252
|
+
sage: m._maxima_init_() # needs sage.symbolic
|
|
253
|
+
'matrix([0,1,2],[3,4,5],[6,7,8])'
|
|
254
|
+
sage: a = maxima(m); a # needs sage.symbolic
|
|
255
|
+
matrix([0,1,2],[3,4,5],[6,7,8])
|
|
256
|
+
sage: a.charpoly('x').expand() # needs sage.symbolic
|
|
257
|
+
...-x^3...+12*x^2+18*x
|
|
258
|
+
sage: m.charpoly()
|
|
259
|
+
x^3 - 12*x^2 - 18*x
|
|
260
|
+
"""
|
|
261
|
+
cdef Py_ssize_t i, j
|
|
262
|
+
v = []
|
|
263
|
+
for i from 0 <= i < self._nrows:
|
|
264
|
+
tmp = []
|
|
265
|
+
for j from 0 <= j < self._ncols:
|
|
266
|
+
tmp.append(self.get_unsafe(i, j)._maxima_init_())
|
|
267
|
+
v.append('[%s]' % (','.join(tmp)))
|
|
268
|
+
return 'matrix(%s)' % (','.join(v))
|
|
269
|
+
|
|
270
|
+
def _mathematica_init_(self):
|
|
271
|
+
"""
|
|
272
|
+
Return Mathematica string representation of this matrix.
|
|
273
|
+
|
|
274
|
+
EXAMPLES::
|
|
275
|
+
|
|
276
|
+
sage: A = MatrixSpace(QQ,3)([1,2,3,4/3,5/3,6/4,7,8,9])
|
|
277
|
+
sage: g = mathematica(A); g # optional - mathematica
|
|
278
|
+
{{1, 2, 3}, {4/3, 5/3, 3/2}, {7, 8, 9}}
|
|
279
|
+
sage: A._mathematica_init_() # needs sage.symbolic
|
|
280
|
+
'{{1/1, 2/1, 3/1}, {4/3, 5/3, 3/2}, {7/1, 8/1, 9/1}}'
|
|
281
|
+
|
|
282
|
+
::
|
|
283
|
+
|
|
284
|
+
sage: A = matrix([[1,2],[3,4]])
|
|
285
|
+
sage: g = mathematica(A); g # optional - mathematica
|
|
286
|
+
{{1, 2}, {3, 4}}
|
|
287
|
+
|
|
288
|
+
::
|
|
289
|
+
|
|
290
|
+
sage: a = matrix([[pi, sin(x)], [cos(x), 1/e]]); a # needs sage.symbolic
|
|
291
|
+
[ pi sin(x)]
|
|
292
|
+
[cos(x) e^(-1)]
|
|
293
|
+
sage: a._mathematica_init_() # needs sage.symbolic
|
|
294
|
+
'{{Pi, Sin[x]}, {Cos[x], Exp[-1]}}'
|
|
295
|
+
"""
|
|
296
|
+
return '{' + ', '.join(v._mathematica_init_() for v in self.rows()) + '}'
|
|
297
|
+
|
|
298
|
+
def _magma_init_(self, magma) -> str:
|
|
299
|
+
r"""
|
|
300
|
+
Return a string that evaluates in the given Magma session to this
|
|
301
|
+
matrix.
|
|
302
|
+
|
|
303
|
+
EXAMPLES:
|
|
304
|
+
|
|
305
|
+
We first coerce a square matrix. ::
|
|
306
|
+
|
|
307
|
+
sage: # optional - magma
|
|
308
|
+
sage: A = MatrixSpace(QQ,3)([1,2,3,4/3,5/3,6/4,7,8,9])
|
|
309
|
+
sage: B = magma(A); B # indirect doctest
|
|
310
|
+
[ 1 2 3]
|
|
311
|
+
[4/3 5/3 3/2]
|
|
312
|
+
[ 7 8 9]
|
|
313
|
+
sage: B.Type()
|
|
314
|
+
AlgMatElt
|
|
315
|
+
sage: B.Parent()
|
|
316
|
+
Full Matrix Algebra of degree 3 over Rational Field
|
|
317
|
+
|
|
318
|
+
We coerce a non-square matrix over
|
|
319
|
+
`\ZZ/8\ZZ`. ::
|
|
320
|
+
|
|
321
|
+
sage: # optional - magma
|
|
322
|
+
sage: A = MatrixSpace(Integers(8),2,3)([-1,2,3,4,4,-2])
|
|
323
|
+
sage: B = magma(A); B
|
|
324
|
+
[7 2 3]
|
|
325
|
+
[4 4 6]
|
|
326
|
+
sage: B.Type()
|
|
327
|
+
ModMatRngElt
|
|
328
|
+
sage: B.Parent()
|
|
329
|
+
Full RMatrixSpace of 2 by 3 matrices over IntegerRing(8)
|
|
330
|
+
|
|
331
|
+
sage: R.<x,y> = QQ[]
|
|
332
|
+
sage: A = MatrixSpace(R,2,2)([x+y,x-1,y+5,x*y])
|
|
333
|
+
sage: B = magma(A); B # optional - magma
|
|
334
|
+
[x + y x - 1]
|
|
335
|
+
[y + 5 x*y]
|
|
336
|
+
|
|
337
|
+
sage: R.<x,y> = ZZ[]
|
|
338
|
+
sage: A = MatrixSpace(R,2,2)([x+y,x-1,y+5,x*y])
|
|
339
|
+
sage: B = magma(A); B # optional - magma
|
|
340
|
+
[x + y x - 1]
|
|
341
|
+
[y + 5 x*y]
|
|
342
|
+
|
|
343
|
+
We coerce a matrix over a cyclotomic field, where the generator
|
|
344
|
+
must be named during the coercion. ::
|
|
345
|
+
|
|
346
|
+
sage: # optional - magma, needs sage.rings.number_field
|
|
347
|
+
sage: K = CyclotomicField(9); z = K.0
|
|
348
|
+
sage: M = matrix(K, 3, 3, [0,1,3,z,z**4,z-1,z**17,1,0]); M
|
|
349
|
+
[ 0 1 3]
|
|
350
|
+
[ zeta9 zeta9^4 zeta9 - 1]
|
|
351
|
+
[-zeta9^5 - zeta9^2 1 0]
|
|
352
|
+
sage: magma(M)
|
|
353
|
+
[ 0 1 3]
|
|
354
|
+
[ zeta9 zeta9^4 zeta9 - 1]
|
|
355
|
+
[-zeta9^5 - zeta9^2 1 0]
|
|
356
|
+
sage: magma(M**2) == magma(M)**2
|
|
357
|
+
True
|
|
358
|
+
|
|
359
|
+
One sparse matrix::
|
|
360
|
+
|
|
361
|
+
sage: M = matrix(QQ,2,2,[4,6,55,0],sparse=True)
|
|
362
|
+
sage: T = magma(M); T # optional - magma
|
|
363
|
+
Sparse matrix with 2 rows and 2 columns over Rational Field
|
|
364
|
+
sage: T.Determinant() # optional - magma
|
|
365
|
+
-330
|
|
366
|
+
"""
|
|
367
|
+
if self.is_sparse():
|
|
368
|
+
R = magma(self.base_ring())
|
|
369
|
+
s = "SparseMatrix({}, {}, {}, ["
|
|
370
|
+
s = s.format(R.name(), self.nrows(), self.ncols())
|
|
371
|
+
entries = ("<{}, {}, {}>".format(ij[0] + 1, ij[1] + 1,
|
|
372
|
+
mij._magma_init_(magma))
|
|
373
|
+
for ij, mij in self.dict().items())
|
|
374
|
+
return s + ', '.join(entries) + "])"
|
|
375
|
+
else:
|
|
376
|
+
P = magma(self.parent())
|
|
377
|
+
v = [x._magma_init_(magma) for x in self.list()]
|
|
378
|
+
return '%s![%s]' % (P.name(), ','.join(v))
|
|
379
|
+
|
|
380
|
+
def _maple_init_(self):
|
|
381
|
+
"""
|
|
382
|
+
Return a Maple string representation of this matrix.
|
|
383
|
+
|
|
384
|
+
EXAMPLES::
|
|
385
|
+
|
|
386
|
+
sage: M = matrix(ZZ,2,range(4))
|
|
387
|
+
sage: maple(M) # optional - maple
|
|
388
|
+
Matrix(2, 2, [[0,1],[2,3]])
|
|
389
|
+
|
|
390
|
+
sage: M = matrix(QQ,3,[1,2,3,4/3,5/3,6/4,7,8,9])
|
|
391
|
+
sage: maple(M) # optional - maple
|
|
392
|
+
Matrix(3, 3, [[1,2,3],[4/3,5/3,3/2],[7,8,9]])
|
|
393
|
+
|
|
394
|
+
sage: P.<x> = ZZ[]
|
|
395
|
+
sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5])
|
|
396
|
+
sage: maple(M) # optional - maple
|
|
397
|
+
Matrix(2, 2, [[-9*x^2-2*x+2,x-1],[x^2+8*x,-3*x^2+5]])
|
|
398
|
+
|
|
399
|
+
sage: y = var('y') # needs sage.symbolic
|
|
400
|
+
sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic
|
|
401
|
+
sage: M == maple(M).sage() # optional - maple # needs sage.symbolic
|
|
402
|
+
True
|
|
403
|
+
"""
|
|
404
|
+
s = ','.join('[' + ','.join(cf._maple_init_() for cf in row) + ']'
|
|
405
|
+
for row in self.rows())
|
|
406
|
+
return "Matrix(%s,%s,[%s])" % (self.nrows(), self.ncols(), s)
|
|
407
|
+
|
|
408
|
+
def _polymake_(self, polymake=None):
|
|
409
|
+
"""
|
|
410
|
+
Try to coerce this matrix to a polymake matrix.
|
|
411
|
+
|
|
412
|
+
EXAMPLES::
|
|
413
|
+
|
|
414
|
+
sage: M = matrix(ZZ,2,range(4))
|
|
415
|
+
sage: polymake(M) # optional - jupymake
|
|
416
|
+
0 1
|
|
417
|
+
2 3
|
|
418
|
+
sage: K.<sqrt5> = QuadraticField(5) # needs sage.rings.number_field
|
|
419
|
+
sage: M = matrix(K, [[1, 2], [sqrt5, 3]]) # needs sage.rings.number_field
|
|
420
|
+
sage: polymake(M) # optional - jupymake # needs sage.rings.number_field
|
|
421
|
+
1 2
|
|
422
|
+
0+1r5 3
|
|
423
|
+
"""
|
|
424
|
+
P = polymake(self.parent())
|
|
425
|
+
return polymake.new_object(P, [list(r) for r in self.rows(copy=False)])
|
|
426
|
+
|
|
427
|
+
def _singular_(self, singular=None):
|
|
428
|
+
"""
|
|
429
|
+
Try to coerce this matrix to a singular matrix.
|
|
430
|
+
"""
|
|
431
|
+
if singular is None:
|
|
432
|
+
from sage.interfaces.singular import singular as singular_default
|
|
433
|
+
singular = singular_default
|
|
434
|
+
try:
|
|
435
|
+
self.base_ring()._singular_(singular)
|
|
436
|
+
except (NotImplementedError, AttributeError):
|
|
437
|
+
raise TypeError("Cannot coerce to Singular")
|
|
438
|
+
|
|
439
|
+
return singular.matrix(self.nrows(), self.ncols(),
|
|
440
|
+
singular(self.list()))
|
|
441
|
+
|
|
442
|
+
def _macaulay2_(self, macaulay2=None):
|
|
443
|
+
"""
|
|
444
|
+
EXAMPLES::
|
|
445
|
+
|
|
446
|
+
sage: m = matrix(ZZ, [[1,2],[3,4]])
|
|
447
|
+
sage: macaulay2(m) # indirect doctest # optional - macaulay2
|
|
448
|
+
| 1 2 |
|
|
449
|
+
| 3 4 |
|
|
450
|
+
|
|
451
|
+
::
|
|
452
|
+
|
|
453
|
+
sage: R.<x,y> = QQ[]
|
|
454
|
+
sage: m = matrix([[x,y],[1+x,1+y]])
|
|
455
|
+
sage: macaulay2(m) # optional - macaulay2
|
|
456
|
+
| x y |
|
|
457
|
+
| x+1 y+1 |
|
|
458
|
+
|
|
459
|
+
TESTS:
|
|
460
|
+
|
|
461
|
+
Entries of the matrix get promoted to the base ring (:issue:`28566`)::
|
|
462
|
+
|
|
463
|
+
sage: R.<x,y> = QQ[]
|
|
464
|
+
sage: m = macaulay2(matrix(R, [[1, 2], [3, 4]])) # optional - macaulay2
|
|
465
|
+
sage: m.ring()._operator('===', R).sage() # optional - macaulay2
|
|
466
|
+
True
|
|
467
|
+
|
|
468
|
+
Check that degenerate matrix dimensions are handled correctly
|
|
469
|
+
(:issue:`28591`)::
|
|
470
|
+
|
|
471
|
+
sage: macaulay2(matrix(QQ, 2, 0)).numrows() # optional - macaulay2
|
|
472
|
+
2
|
|
473
|
+
sage: macaulay2(matrix(QQ, 0, 2)).numcols() # optional - macaulay2
|
|
474
|
+
2
|
|
475
|
+
"""
|
|
476
|
+
if macaulay2 is None:
|
|
477
|
+
from sage.interfaces.macaulay2 import macaulay2 as m2_default
|
|
478
|
+
macaulay2 = m2_default
|
|
479
|
+
if not self.nrows():
|
|
480
|
+
return (macaulay2(self.base_ring())
|
|
481
|
+
.matrix('toList(%s:{})' % self.ncols()).transpose())
|
|
482
|
+
entries = [list(row) for row in self]
|
|
483
|
+
return macaulay2(self.base_ring()).matrix(entries)
|
|
484
|
+
|
|
485
|
+
def _scilab_init_(self):
|
|
486
|
+
"""
|
|
487
|
+
Return a string defining a Scilab representation of ``self``.
|
|
488
|
+
|
|
489
|
+
EXAMPLES::
|
|
490
|
+
|
|
491
|
+
sage: a = matrix([[1,2,3],[4,5,6],[7,8,9]]); a
|
|
492
|
+
[1 2 3]
|
|
493
|
+
[4 5 6]
|
|
494
|
+
[7 8 9]
|
|
495
|
+
sage: a._scilab_init_() # needs sage.libs.pari
|
|
496
|
+
'[1,2,3;4,5,6;7,8,9]'
|
|
497
|
+
|
|
498
|
+
AUTHORS:
|
|
499
|
+
|
|
500
|
+
- Ronan Paixao (2008-12-12)
|
|
501
|
+
"""
|
|
502
|
+
w = self.list()
|
|
503
|
+
cdef Py_ssize_t nr, nc, i, j
|
|
504
|
+
nr = self._nrows
|
|
505
|
+
nc = self._ncols
|
|
506
|
+
v = []
|
|
507
|
+
for i from 0 <= i < nr:
|
|
508
|
+
tmp = []
|
|
509
|
+
for j from 0 <= j < nc:
|
|
510
|
+
tmp.append(w[i * nc + j]._pari_init_())
|
|
511
|
+
v.append(','.join(tmp))
|
|
512
|
+
return '[%s]' % (';'.join(v))
|
|
513
|
+
|
|
514
|
+
def _scilab_(self, scilab=None):
|
|
515
|
+
"""
|
|
516
|
+
Create a ScilabElement object based on ``self`` and returns it.
|
|
517
|
+
|
|
518
|
+
EXAMPLES::
|
|
519
|
+
|
|
520
|
+
sage: a = matrix([[1,2,3],[4,5,6],[7,8,9]]); a
|
|
521
|
+
[1 2 3]
|
|
522
|
+
[4 5 6]
|
|
523
|
+
[7 8 9]
|
|
524
|
+
sage: b = scilab(a); b # indirect doctest # optional - scilab
|
|
525
|
+
1. 2. 3.
|
|
526
|
+
4. 5. 6.
|
|
527
|
+
7. 8. 9.
|
|
528
|
+
|
|
529
|
+
AUTHORS:
|
|
530
|
+
|
|
531
|
+
- Ronan Paixao (2008-12-12)
|
|
532
|
+
"""
|
|
533
|
+
return scilab(self._scilab_init_())
|
|
534
|
+
|
|
535
|
+
def _sympy_(self):
|
|
536
|
+
r"""
|
|
537
|
+
Return a SymPy matrix corresponding to ``self``.
|
|
538
|
+
|
|
539
|
+
OUTPUT:
|
|
540
|
+
|
|
541
|
+
- An instance of either an ``ImmutableMatrix`` or ``ImmutableSparseMatrix``,
|
|
542
|
+
regardless of whether ``self`` is mutable or not.
|
|
543
|
+
|
|
544
|
+
EXAMPLES::
|
|
545
|
+
|
|
546
|
+
sage: A = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); A
|
|
547
|
+
[1 2 3]
|
|
548
|
+
[4 5 6]
|
|
549
|
+
[7 8 9]
|
|
550
|
+
sage: sA = A._sympy_(); sA # needs sympy
|
|
551
|
+
Matrix([
|
|
552
|
+
[1, 2, 3],
|
|
553
|
+
[4, 5, 6],
|
|
554
|
+
[7, 8, 9]])
|
|
555
|
+
sage: type(sA) # needs sympy
|
|
556
|
+
<class 'sympy.matrices.immutable.ImmutableDenseMatrix'>
|
|
557
|
+
|
|
558
|
+
sage: I = MatrixSpace(QQ, 5, 5, sparse=True).identity_matrix()
|
|
559
|
+
sage: sI = I._sympy_(); sI # needs sympy
|
|
560
|
+
Matrix([
|
|
561
|
+
[1, 0, 0, 0, 0],
|
|
562
|
+
[0, 1, 0, 0, 0],
|
|
563
|
+
[0, 0, 1, 0, 0],
|
|
564
|
+
[0, 0, 0, 1, 0],
|
|
565
|
+
[0, 0, 0, 0, 1]])
|
|
566
|
+
sage: type(sI) # needs sympy
|
|
567
|
+
<class 'sympy.matrices.immutable.ImmutableSparseMatrix'>
|
|
568
|
+
|
|
569
|
+
If ``self`` was immutable, then converting the result to Sage gives
|
|
570
|
+
back ``self``::
|
|
571
|
+
|
|
572
|
+
sage: immA = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], immutable=True)
|
|
573
|
+
sage: immA._sympy_()._sage_() is immA # needs sympy
|
|
574
|
+
True
|
|
575
|
+
|
|
576
|
+
If ``self`` was mutable, then converting back to Sage creates a new matrix::
|
|
577
|
+
|
|
578
|
+
sage: sA._sage_() is A # needs sympy sage.symbolic
|
|
579
|
+
False
|
|
580
|
+
sage: sA._sage_() == A # needs sympy sage.symbolic
|
|
581
|
+
True
|
|
582
|
+
|
|
583
|
+
Symbolic matrices are supported::
|
|
584
|
+
|
|
585
|
+
sage: # needs sympy sage.symbolic
|
|
586
|
+
sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M
|
|
587
|
+
[ sin(x) cos(x)]
|
|
588
|
+
[-cos(x) sin(x)]
|
|
589
|
+
sage: sM = M._sympy_(); sM
|
|
590
|
+
Matrix([
|
|
591
|
+
[ sin(x), cos(x)],
|
|
592
|
+
[-cos(x), sin(x)]])
|
|
593
|
+
sage: sM.subs(x, pi/4)
|
|
594
|
+
Matrix([
|
|
595
|
+
[ sqrt(2)/2, sqrt(2)/2],
|
|
596
|
+
[-sqrt(2)/2, sqrt(2)/2]])
|
|
597
|
+
|
|
598
|
+
TESTS:
|
|
599
|
+
|
|
600
|
+
Dense 0-column/0-row matrices::
|
|
601
|
+
|
|
602
|
+
sage: ZeroCol = matrix(QQ, 3, 0, sparse=False); ZeroCol
|
|
603
|
+
[]
|
|
604
|
+
sage: sZeroCol = ZeroCol._sympy_(); sZeroCol # needs sympy
|
|
605
|
+
Matrix(3, 0, [])
|
|
606
|
+
|
|
607
|
+
sage: ZeroRow = matrix(QQ, 0, 2, sparse=False); ZeroRow
|
|
608
|
+
[]
|
|
609
|
+
sage: sZeroRow = ZeroRow._sympy_(); sZeroRow # needs sympy
|
|
610
|
+
Matrix(0, 2, [])
|
|
611
|
+
"""
|
|
612
|
+
from sage.interfaces.sympy import sympy_init
|
|
613
|
+
sympy_init()
|
|
614
|
+
from sympy.matrices import ImmutableMatrix, ImmutableSparseMatrix
|
|
615
|
+
if self.is_sparse():
|
|
616
|
+
matrix = ImmutableSparseMatrix(self.nrows(), self.ncols(),
|
|
617
|
+
self.dict(copy=False))
|
|
618
|
+
else:
|
|
619
|
+
if not self.nrows() or not self.ncols():
|
|
620
|
+
matrix = ImmutableMatrix(self.nrows(), self.ncols(), ())
|
|
621
|
+
else:
|
|
622
|
+
matrix = ImmutableMatrix(self.rows())
|
|
623
|
+
if self.is_immutable():
|
|
624
|
+
matrix._sage_object = self
|
|
625
|
+
return matrix
|
|
626
|
+
|
|
627
|
+
def _sage_input_(self, sib, coerce):
|
|
628
|
+
r"""
|
|
629
|
+
Produce an expression which will reproduce this value when evaluated.
|
|
630
|
+
|
|
631
|
+
EXAMPLES::
|
|
632
|
+
|
|
633
|
+
sage: sage_input(matrix(QQ, 3, 3, [5..13])/7, verify=True)
|
|
634
|
+
# Verified
|
|
635
|
+
matrix(QQ, [[5/7, 6/7, 1], [8/7, 9/7, 10/7], [11/7, 12/7, 13/7]])
|
|
636
|
+
sage: M = MatrixSpace(GF(5), 50, 50, sparse=True).random_element(density=0.002)
|
|
637
|
+
sage: input = sage_input(M, verify=True)
|
|
638
|
+
sage: sage_eval(input) == M
|
|
639
|
+
True
|
|
640
|
+
sage: from sage.misc.sage_input import SageInputBuilder
|
|
641
|
+
sage: matrix(RDF, [[3, 1], [4, 1]])._sage_input_(SageInputBuilder(), False)
|
|
642
|
+
{call: {atomic:matrix}({atomic:RDF}, {list: ({list: ({atomic:3}, {atomic:1})}, {list: ({atomic:4}, {atomic:1})})})}
|
|
643
|
+
sage: matrix(ZZ, 50, 50, {(9,17):1})._sage_input_(SageInputBuilder(), False)
|
|
644
|
+
{call: {atomic:matrix}({atomic:ZZ}, {atomic:50}, {atomic:50}, {dict: {{atomic:(9,17)}:{atomic:1}}})}
|
|
645
|
+
|
|
646
|
+
TESTS::
|
|
647
|
+
|
|
648
|
+
sage: sage_input(matrix(RR, 0, 3, []), verify=True)
|
|
649
|
+
# Verified
|
|
650
|
+
matrix(RR, 0, 3)
|
|
651
|
+
sage: sage_input(matrix(RR, 3, 0, []), verify=True)
|
|
652
|
+
# Verified
|
|
653
|
+
matrix(RR, 3, 0)
|
|
654
|
+
sage: sage_input(matrix(RR, 0, 0, []), verify=True)
|
|
655
|
+
# Verified
|
|
656
|
+
matrix(RR, 0, 0)
|
|
657
|
+
"""
|
|
658
|
+
if self.is_sparse():
|
|
659
|
+
entries = list(self.dict().items())
|
|
660
|
+
entries.sort()
|
|
661
|
+
# We hand-format the keys to get rid of the space that would
|
|
662
|
+
# normally follow the comma
|
|
663
|
+
entries = [(sib.name('(%d,%d)' % k), sib(v, 2))
|
|
664
|
+
for k, v in entries]
|
|
665
|
+
return sib.name('matrix')(self.base_ring(),
|
|
666
|
+
sib.int(self.nrows()),
|
|
667
|
+
sib.int(self.ncols()),
|
|
668
|
+
sib.dict(entries))
|
|
669
|
+
elif self.nrows() == 0 or self.ncols() == 0:
|
|
670
|
+
return sib.name('matrix')(self.base_ring(),
|
|
671
|
+
sib.int(self.nrows()),
|
|
672
|
+
sib.int(self.ncols()))
|
|
673
|
+
else:
|
|
674
|
+
entries = [[sib(v, 2) for v in row] for row in self.rows()]
|
|
675
|
+
return sib.name('matrix')(self.base_ring(), entries)
|
|
676
|
+
|
|
677
|
+
def numpy(self, dtype=None, copy=True):
|
|
678
|
+
"""
|
|
679
|
+
Return the Numpy matrix associated to this matrix.
|
|
680
|
+
|
|
681
|
+
INPUT:
|
|
682
|
+
|
|
683
|
+
- ``dtype`` -- the desired data-type for the array. If not given,
|
|
684
|
+
then the type will be determined as the minimum type required
|
|
685
|
+
to hold the objects in the sequence.
|
|
686
|
+
|
|
687
|
+
- ``copy`` -- if `self` is already an `ndarray`, then this flag
|
|
688
|
+
determines whether the data is copied (the default), or whether
|
|
689
|
+
a view is constructed.
|
|
690
|
+
|
|
691
|
+
EXAMPLES::
|
|
692
|
+
|
|
693
|
+
sage: # needs numpy
|
|
694
|
+
sage: a = matrix(3, range(12))
|
|
695
|
+
sage: a.numpy()
|
|
696
|
+
array([[ 0, 1, 2, 3],
|
|
697
|
+
[ 4, 5, 6, 7],
|
|
698
|
+
[ 8, 9, 10, 11]])
|
|
699
|
+
sage: a.numpy('f')
|
|
700
|
+
array([[ 0., 1., 2., 3.],
|
|
701
|
+
[ 4., 5., 6., 7.],
|
|
702
|
+
[ 8., 9., 10., 11.]], dtype=float32)
|
|
703
|
+
sage: a.numpy('d')
|
|
704
|
+
array([[ 0., 1., 2., 3.],
|
|
705
|
+
[ 4., 5., 6., 7.],
|
|
706
|
+
[ 8., 9., 10., 11.]])
|
|
707
|
+
sage: a.numpy('B')
|
|
708
|
+
array([[ 0, 1, 2, 3],
|
|
709
|
+
[ 4, 5, 6, 7],
|
|
710
|
+
[ 8, 9, 10, 11]], dtype=uint8)
|
|
711
|
+
|
|
712
|
+
Type ``numpy.typecodes`` for a list of the possible
|
|
713
|
+
typecodes::
|
|
714
|
+
|
|
715
|
+
sage: import numpy # needs numpy
|
|
716
|
+
sage: numpy.typecodes.items() # needs numpy # random
|
|
717
|
+
[('All', '?bhilqpBHILQPefdgFDGSUVOMm'), ('AllFloat', 'efdgFDG'),
|
|
718
|
+
...
|
|
719
|
+
|
|
720
|
+
For instance, you can see possibilities for real floating point numbers::
|
|
721
|
+
|
|
722
|
+
sage: numpy.typecodes['Float'] # needs numpy
|
|
723
|
+
'efdg'
|
|
724
|
+
|
|
725
|
+
Alternatively, numpy automatically calls this function (via
|
|
726
|
+
the magic :meth:`__array__` method) to convert Sage matrices
|
|
727
|
+
to numpy arrays::
|
|
728
|
+
|
|
729
|
+
sage: # needs numpy
|
|
730
|
+
sage: import numpy
|
|
731
|
+
sage: b = numpy.array(a); b
|
|
732
|
+
array([[ 0, 1, 2, 3],
|
|
733
|
+
[ 4, 5, 6, 7],
|
|
734
|
+
[ 8, 9, 10, 11]])
|
|
735
|
+
sage: b.dtype
|
|
736
|
+
dtype('int32') # 32-bit
|
|
737
|
+
dtype('int64') # 64-bit
|
|
738
|
+
sage: b.shape
|
|
739
|
+
(3, 4)
|
|
740
|
+
"""
|
|
741
|
+
import numpy
|
|
742
|
+
A = numpy.matrix(self.list(), dtype=dtype, copy=copy)
|
|
743
|
+
return numpy.resize(A, (self.nrows(), self.ncols()))
|
|
744
|
+
|
|
745
|
+
def _mpmath_(self, prec=None, rounding=None):
|
|
746
|
+
"""
|
|
747
|
+
Return a ``mpmath`` matrix.
|
|
748
|
+
|
|
749
|
+
INPUT: See :meth:`sage.structure.element.Element._mpmath_`.
|
|
750
|
+
|
|
751
|
+
EXAMPLES::
|
|
752
|
+
|
|
753
|
+
sage: # needs mpmath sage.symbolic
|
|
754
|
+
sage: m = matrix(SR, 2, 2, [1, 2, 3, pi])
|
|
755
|
+
sage: from mpmath import mp
|
|
756
|
+
sage: mp.dps = 30
|
|
757
|
+
sage: mp.matrix(m) # not tested (doesn't work yet)
|
|
758
|
+
sage: m._mpmath_(mp.prec)
|
|
759
|
+
matrix(
|
|
760
|
+
[['1.0', '2.0'],
|
|
761
|
+
['3.0', '3.14159265358979323846264338328']])
|
|
762
|
+
"""
|
|
763
|
+
if prec is None:
|
|
764
|
+
R = self.base_ring()
|
|
765
|
+
try:
|
|
766
|
+
prec = R.precision()
|
|
767
|
+
except AttributeError:
|
|
768
|
+
prec = 53
|
|
769
|
+
from mpmath import mp
|
|
770
|
+
return mp.matrix([[item._mpmath_(prec, rounding) for item in row] for row in self])
|
|
771
|
+
|
|
772
|
+
# Define the magic "__array__" function so that numpy.array(m) can convert
|
|
773
|
+
# a matrix m to a numpy array.
|
|
774
|
+
# See http://docs.scipy.org/doc/numpy/user/c-info.how-to-extend.html#converting-an-arbitrary-sequence-object
|
|
775
|
+
__array__ = numpy
|
|
776
|
+
|
|
777
|
+
###################################################
|
|
778
|
+
# Construction functions
|
|
779
|
+
###################################################
|
|
780
|
+
|
|
781
|
+
def matrix_over_field(self):
|
|
782
|
+
"""
|
|
783
|
+
Return copy of this matrix, but with entries viewed as elements of
|
|
784
|
+
the fraction field of the base ring (assuming it is defined).
|
|
785
|
+
|
|
786
|
+
EXAMPLES::
|
|
787
|
+
|
|
788
|
+
sage: A = MatrixSpace(IntegerRing(),2)([1,2,3,4])
|
|
789
|
+
sage: B = A.matrix_over_field()
|
|
790
|
+
sage: B
|
|
791
|
+
[1 2]
|
|
792
|
+
[3 4]
|
|
793
|
+
sage: B.parent()
|
|
794
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
795
|
+
"""
|
|
796
|
+
return self.change_ring(self.base_ring().fraction_field())
|
|
797
|
+
|
|
798
|
+
def lift(self):
|
|
799
|
+
"""
|
|
800
|
+
Return lift of ``self`` to the covering ring of the base ring R,
|
|
801
|
+
which is by definition the ring returned by calling
|
|
802
|
+
cover_ring() on R, or just R itself if the cover_ring method
|
|
803
|
+
is not defined.
|
|
804
|
+
|
|
805
|
+
EXAMPLES::
|
|
806
|
+
|
|
807
|
+
sage: M = Matrix(Integers(7), 2, 2, [5, 9, 13, 15]); M
|
|
808
|
+
[5 2]
|
|
809
|
+
[6 1]
|
|
810
|
+
sage: M.lift()
|
|
811
|
+
[5 2]
|
|
812
|
+
[6 1]
|
|
813
|
+
sage: parent(M.lift())
|
|
814
|
+
Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
|
|
815
|
+
|
|
816
|
+
The field QQ doesn't have a cover_ring method::
|
|
817
|
+
|
|
818
|
+
sage: hasattr(QQ, 'cover_ring')
|
|
819
|
+
False
|
|
820
|
+
|
|
821
|
+
So lifting a matrix over QQ gives back the same exact matrix.
|
|
822
|
+
|
|
823
|
+
::
|
|
824
|
+
|
|
825
|
+
sage: B = matrix(QQ, 2, [1..4])
|
|
826
|
+
sage: B.lift()
|
|
827
|
+
[1 2]
|
|
828
|
+
[3 4]
|
|
829
|
+
sage: B.lift() is B
|
|
830
|
+
True
|
|
831
|
+
"""
|
|
832
|
+
if hasattr(self._base_ring, 'cover_ring'):
|
|
833
|
+
S = self._base_ring.cover_ring()
|
|
834
|
+
if S is not self._base_ring:
|
|
835
|
+
return self.change_ring(S)
|
|
836
|
+
return self
|
|
837
|
+
|
|
838
|
+
def lift_centered(self):
|
|
839
|
+
"""
|
|
840
|
+
Apply the lift_centered method to every entry of ``self``.
|
|
841
|
+
|
|
842
|
+
OUTPUT:
|
|
843
|
+
|
|
844
|
+
If ``self`` is a matrix over the Integers mod `n`, this method returns the
|
|
845
|
+
unique matrix `m` such that `m` is congruent to ``self`` mod `n` and for
|
|
846
|
+
every entry `m[i,j]` we have `-n/2 < m[i,j] \\leq n/2`. If the
|
|
847
|
+
coefficient ring does not have a cover_ring method, return ``self``.
|
|
848
|
+
|
|
849
|
+
EXAMPLES::
|
|
850
|
+
|
|
851
|
+
sage: M = Matrix(Integers(8), 2, 4, range(8)); M
|
|
852
|
+
[0 1 2 3]
|
|
853
|
+
[4 5 6 7]
|
|
854
|
+
sage: L = M.lift_centered(); L
|
|
855
|
+
[ 0 1 2 3]
|
|
856
|
+
[ 4 -3 -2 -1]
|
|
857
|
+
sage: parent(L)
|
|
858
|
+
Full MatrixSpace of 2 by 4 dense matrices over Integer Ring
|
|
859
|
+
|
|
860
|
+
The returned matrix is congruent to M modulo 8.::
|
|
861
|
+
|
|
862
|
+
sage: L.mod(8)
|
|
863
|
+
[0 1 2 3]
|
|
864
|
+
[4 5 6 7]
|
|
865
|
+
|
|
866
|
+
The field QQ doesn't have a cover_ring method::
|
|
867
|
+
|
|
868
|
+
sage: hasattr(QQ, 'cover_ring')
|
|
869
|
+
False
|
|
870
|
+
|
|
871
|
+
So lifting a matrix over QQ gives back the same exact matrix.
|
|
872
|
+
|
|
873
|
+
::
|
|
874
|
+
|
|
875
|
+
sage: B = matrix(QQ, 2, [1..4])
|
|
876
|
+
sage: B.lift_centered()
|
|
877
|
+
[1 2]
|
|
878
|
+
[3 4]
|
|
879
|
+
sage: B.lift_centered() is B
|
|
880
|
+
True
|
|
881
|
+
"""
|
|
882
|
+
try:
|
|
883
|
+
S = self._base_ring.cover_ring()
|
|
884
|
+
if S is not self._base_ring:
|
|
885
|
+
return self.parent().change_ring(S)([v.lift_centered() for v in self])
|
|
886
|
+
except AttributeError:
|
|
887
|
+
pass
|
|
888
|
+
return self
|
|
889
|
+
|
|
890
|
+
#############################################################################################
|
|
891
|
+
# rows, columns, sparse_rows, sparse_columns, dense_rows, dense_columns, row, column
|
|
892
|
+
#############################################################################################
|
|
893
|
+
cpdef row_ambient_module(self, base_ring=None, sparse=None):
|
|
894
|
+
r"""
|
|
895
|
+
Return the free module that contains the rows of the matrix.
|
|
896
|
+
|
|
897
|
+
EXAMPLES::
|
|
898
|
+
|
|
899
|
+
sage: M = matrix(Zmod(5), 2, 3)
|
|
900
|
+
sage: M.row_ambient_module()
|
|
901
|
+
Vector space of dimension 3 over Ring of integers modulo 5
|
|
902
|
+
sage: M.row(1).parent() == M.row_ambient_module()
|
|
903
|
+
True
|
|
904
|
+
|
|
905
|
+
sage: M = Matrix(ZZ, 3, 4)
|
|
906
|
+
sage: M.row_ambient_module()
|
|
907
|
+
Ambient free module of rank 4 over the principal ideal domain Integer Ring
|
|
908
|
+
sage: M.row_ambient_module(QQ)
|
|
909
|
+
Vector space of dimension 4 over Rational Field
|
|
910
|
+
|
|
911
|
+
sage: M = Matrix(QQ, 4, 5)
|
|
912
|
+
sage: M.row_ambient_module()
|
|
913
|
+
Vector space of dimension 5 over Rational Field
|
|
914
|
+
sage: M.row_ambient_module(ZZ)
|
|
915
|
+
Ambient free module of rank 5 over the principal ideal domain Integer Ring
|
|
916
|
+
"""
|
|
917
|
+
if base_ring is not None or sparse is not None:
|
|
918
|
+
if base_ring is None:
|
|
919
|
+
base_ring = self._base_ring
|
|
920
|
+
if sparse is None:
|
|
921
|
+
sparse = self.is_sparse_c()
|
|
922
|
+
if base_ring is self._base_ring and sparse == self.is_sparse_c():
|
|
923
|
+
return self.row_ambient_module()
|
|
924
|
+
return sage.modules.free_module.FreeModule(base_ring, self._ncols, sparse=sparse)
|
|
925
|
+
|
|
926
|
+
x = self.fetch('row_ambient_module')
|
|
927
|
+
if x is not None:
|
|
928
|
+
return x
|
|
929
|
+
x = sage.modules.free_module.FreeModule(self._base_ring, self._ncols,
|
|
930
|
+
sparse=self.is_sparse_c())
|
|
931
|
+
self.cache('row_ambient_module', x)
|
|
932
|
+
return x
|
|
933
|
+
|
|
934
|
+
def _row_ambient_module(self, base_ring=None):
|
|
935
|
+
r"""
|
|
936
|
+
TESTS::
|
|
937
|
+
|
|
938
|
+
sage: M = matrix(Zmod(5), 2, 3)
|
|
939
|
+
sage: M._row_ambient_module()
|
|
940
|
+
doctest:warning
|
|
941
|
+
...
|
|
942
|
+
DeprecationWarning: the method _row_ambient_module is deprecated use row_ambient_module (without underscore) instead
|
|
943
|
+
See https://github.com/sagemath/sage/issues/32984 for details.
|
|
944
|
+
Vector space of dimension 3 over Ring of integers modulo 5
|
|
945
|
+
"""
|
|
946
|
+
from sage.misc.superseded import deprecation
|
|
947
|
+
deprecation(32984, 'the method _row_ambient_module is deprecated use row_ambient_module (without underscore) instead')
|
|
948
|
+
return self.row_ambient_module(base_ring)
|
|
949
|
+
|
|
950
|
+
cpdef column_ambient_module(self, base_ring=None, sparse=None):
|
|
951
|
+
r"""
|
|
952
|
+
Return the free module that contains the columns of the matrix.
|
|
953
|
+
|
|
954
|
+
EXAMPLES::
|
|
955
|
+
|
|
956
|
+
sage: M = matrix(Zmod(5), 2, 3)
|
|
957
|
+
sage: M.column_ambient_module()
|
|
958
|
+
Vector space of dimension 2 over Ring of integers modulo 5
|
|
959
|
+
sage: M.column(1).parent() == M.column_ambient_module()
|
|
960
|
+
True
|
|
961
|
+
|
|
962
|
+
sage: M = Matrix(ZZ, 3, 4)
|
|
963
|
+
sage: M.column_ambient_module()
|
|
964
|
+
Ambient free module of rank 3 over the principal ideal domain Integer Ring
|
|
965
|
+
sage: M.column_ambient_module(QQ)
|
|
966
|
+
Vector space of dimension 3 over Rational Field
|
|
967
|
+
|
|
968
|
+
sage: M = Matrix(QQ, 4, 5)
|
|
969
|
+
sage: M.column_ambient_module()
|
|
970
|
+
Vector space of dimension 4 over Rational Field
|
|
971
|
+
sage: M.column_ambient_module(ZZ)
|
|
972
|
+
Ambient free module of rank 4 over the principal ideal domain Integer Ring
|
|
973
|
+
"""
|
|
974
|
+
if base_ring is not None or sparse is not None:
|
|
975
|
+
if base_ring is None:
|
|
976
|
+
base_ring = self._base_ring
|
|
977
|
+
if sparse is None:
|
|
978
|
+
sparse = self.is_sparse_c()
|
|
979
|
+
if base_ring is self._base_ring and sparse == self.is_sparse_c():
|
|
980
|
+
return self.column_ambient_module()
|
|
981
|
+
return sage.modules.free_module.FreeModule(base_ring, self._nrows, sparse=sparse)
|
|
982
|
+
|
|
983
|
+
x = self.fetch('column_ambient_module')
|
|
984
|
+
if x is not None:
|
|
985
|
+
return x
|
|
986
|
+
x = sage.modules.free_module.FreeModule(self._base_ring, self._nrows,
|
|
987
|
+
sparse=self.is_sparse_c())
|
|
988
|
+
self.cache('column_ambient_module', x)
|
|
989
|
+
return x
|
|
990
|
+
|
|
991
|
+
def _column_ambient_module(self):
|
|
992
|
+
r"""
|
|
993
|
+
TESTS::
|
|
994
|
+
|
|
995
|
+
sage: M = matrix(Zmod(5), 2, 3)
|
|
996
|
+
sage: M._column_ambient_module()
|
|
997
|
+
doctest:warning
|
|
998
|
+
...
|
|
999
|
+
DeprecationWarning: the method _column_ambient_module is deprecated use column_ambient_module (without underscore) instead
|
|
1000
|
+
See https://github.com/sagemath/sage/issues/32984 for details.
|
|
1001
|
+
Vector space of dimension 2 over Ring of integers modulo 5
|
|
1002
|
+
"""
|
|
1003
|
+
from sage.misc.superseded import deprecation
|
|
1004
|
+
deprecation(32984, 'the method _column_ambient_module is deprecated use column_ambient_module (without underscore) instead')
|
|
1005
|
+
return self.column_ambient_module()
|
|
1006
|
+
|
|
1007
|
+
def columns(self, copy=True):
|
|
1008
|
+
r"""
|
|
1009
|
+
Return a list of the columns of ``self``.
|
|
1010
|
+
|
|
1011
|
+
INPUT:
|
|
1012
|
+
|
|
1013
|
+
- ``copy`` -- boolean (default: ``True``); if ``True``, return a copy of the list
|
|
1014
|
+
of columns which is safe to change
|
|
1015
|
+
|
|
1016
|
+
If ``self`` is a sparse matrix, columns are returned as sparse vectors,
|
|
1017
|
+
otherwise returned vectors are dense.
|
|
1018
|
+
|
|
1019
|
+
EXAMPLES::
|
|
1020
|
+
|
|
1021
|
+
sage: matrix(3, [1..9]).columns()
|
|
1022
|
+
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
|
|
1023
|
+
sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).columns() # needs sage.symbolic
|
|
1024
|
+
[(1.41421356237310, 2.71828182845905), (3.14159265358979, 0.000000000000000)]
|
|
1025
|
+
sage: matrix(RR, 0, 2, []).columns()
|
|
1026
|
+
[(), ()]
|
|
1027
|
+
sage: matrix(RR, 2, 0, []).columns()
|
|
1028
|
+
[]
|
|
1029
|
+
sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # needs sage.symbolic
|
|
1030
|
+
sage: parent(m.columns()[0]) # needs sage.symbolic
|
|
1031
|
+
Sparse vector space of dimension 3 over Real Field with 53 bits of precision
|
|
1032
|
+
|
|
1033
|
+
Sparse matrices produce sparse columns. ::
|
|
1034
|
+
|
|
1035
|
+
sage: A = matrix(QQ, 2, range(4), sparse=True)
|
|
1036
|
+
sage: v = A.columns()[0]
|
|
1037
|
+
sage: v.is_sparse()
|
|
1038
|
+
True
|
|
1039
|
+
|
|
1040
|
+
TESTS::
|
|
1041
|
+
|
|
1042
|
+
sage: A = matrix(QQ, 4, range(16))
|
|
1043
|
+
sage: A.columns('junk')
|
|
1044
|
+
Traceback (most recent call last):
|
|
1045
|
+
...
|
|
1046
|
+
ValueError: 'copy' must be ``True`` or False, not junk
|
|
1047
|
+
"""
|
|
1048
|
+
if copy not in [True, False]:
|
|
1049
|
+
msg = "'copy' must be ``True`` or False, not {0}"
|
|
1050
|
+
raise ValueError(msg.format(copy))
|
|
1051
|
+
x = self.fetch('columns')
|
|
1052
|
+
if x is not None:
|
|
1053
|
+
if copy:
|
|
1054
|
+
return list(x)
|
|
1055
|
+
return x
|
|
1056
|
+
if self.is_sparse():
|
|
1057
|
+
columns = self.sparse_columns(copy=copy)
|
|
1058
|
+
else:
|
|
1059
|
+
columns = self.dense_columns(copy=copy)
|
|
1060
|
+
self.cache('columns', columns)
|
|
1061
|
+
if copy:
|
|
1062
|
+
return list(columns)
|
|
1063
|
+
return columns
|
|
1064
|
+
|
|
1065
|
+
def rows(self, copy=True):
|
|
1066
|
+
r"""
|
|
1067
|
+
Return a list of the rows of ``self``.
|
|
1068
|
+
|
|
1069
|
+
INPUT:
|
|
1070
|
+
|
|
1071
|
+
- ``copy`` -- boolean (default: ``True``); if ``True``, return a copy of the list
|
|
1072
|
+
of rows which is safe to change
|
|
1073
|
+
|
|
1074
|
+
If ``self`` is a sparse matrix, rows are returned as sparse vectors,
|
|
1075
|
+
otherwise returned vectors are dense.
|
|
1076
|
+
|
|
1077
|
+
EXAMPLES::
|
|
1078
|
+
|
|
1079
|
+
sage: matrix(3, [1..9]).rows()
|
|
1080
|
+
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
|
|
1081
|
+
sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).rows() # needs sage.symbolic
|
|
1082
|
+
[(1.41421356237310, 3.14159265358979), (2.71828182845905, 0.000000000000000)]
|
|
1083
|
+
sage: matrix(RR, 0, 2, []).rows()
|
|
1084
|
+
[]
|
|
1085
|
+
sage: matrix(RR, 2, 0, []).rows()
|
|
1086
|
+
[(), ()]
|
|
1087
|
+
sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # needs sage.symbolic
|
|
1088
|
+
sage: parent(m.rows()[0]) # needs sage.symbolic
|
|
1089
|
+
Sparse vector space of dimension 3 over Real Field with 53 bits of precision
|
|
1090
|
+
|
|
1091
|
+
Sparse matrices produce sparse rows. ::
|
|
1092
|
+
|
|
1093
|
+
sage: A = matrix(QQ, 2, range(4), sparse=True)
|
|
1094
|
+
sage: v = A.rows()[0]
|
|
1095
|
+
sage: v.is_sparse()
|
|
1096
|
+
True
|
|
1097
|
+
|
|
1098
|
+
TESTS::
|
|
1099
|
+
|
|
1100
|
+
sage: A = matrix(QQ, 4, range(16))
|
|
1101
|
+
sage: A.rows('junk')
|
|
1102
|
+
Traceback (most recent call last):
|
|
1103
|
+
...
|
|
1104
|
+
ValueError: 'copy' must be ``True`` or False, not junk
|
|
1105
|
+
"""
|
|
1106
|
+
if copy not in [True, False]:
|
|
1107
|
+
msg = "'copy' must be ``True`` or False, not {0}"
|
|
1108
|
+
raise ValueError(msg.format(copy))
|
|
1109
|
+
x = self.fetch('rows')
|
|
1110
|
+
if x is not None:
|
|
1111
|
+
if copy:
|
|
1112
|
+
return list(x)
|
|
1113
|
+
return x
|
|
1114
|
+
if self.is_sparse():
|
|
1115
|
+
rows = self.sparse_rows(copy=copy)
|
|
1116
|
+
else:
|
|
1117
|
+
rows = self.dense_rows(copy=copy)
|
|
1118
|
+
self.cache('rows', rows)
|
|
1119
|
+
if copy:
|
|
1120
|
+
return list(rows)
|
|
1121
|
+
return rows
|
|
1122
|
+
|
|
1123
|
+
def dense_columns(self, copy=True):
|
|
1124
|
+
"""
|
|
1125
|
+
Return list of the dense columns of ``self``.
|
|
1126
|
+
|
|
1127
|
+
INPUT:
|
|
1128
|
+
|
|
1129
|
+
- ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can
|
|
1130
|
+
modify it safely
|
|
1131
|
+
|
|
1132
|
+
EXAMPLES:
|
|
1133
|
+
|
|
1134
|
+
An example over the integers::
|
|
1135
|
+
|
|
1136
|
+
sage: a = matrix(3, 3, range(9)); a
|
|
1137
|
+
[0 1 2]
|
|
1138
|
+
[3 4 5]
|
|
1139
|
+
[6 7 8]
|
|
1140
|
+
sage: a.dense_columns()
|
|
1141
|
+
[(0, 3, 6), (1, 4, 7), (2, 5, 8)]
|
|
1142
|
+
|
|
1143
|
+
We do an example over a polynomial ring::
|
|
1144
|
+
|
|
1145
|
+
sage: R.<x> = QQ[]
|
|
1146
|
+
sage: a = matrix(R, 2, [x,x^2, 2/3*x,1+x^5]); a
|
|
1147
|
+
[ x x^2]
|
|
1148
|
+
[ 2/3*x x^5 + 1]
|
|
1149
|
+
sage: a.dense_columns()
|
|
1150
|
+
[(x, 2/3*x), (x^2, x^5 + 1)]
|
|
1151
|
+
sage: a = matrix(R, 2, [x,x^2, 2/3*x,1+x^5], sparse=True)
|
|
1152
|
+
sage: c = a.dense_columns(); c
|
|
1153
|
+
[(x, 2/3*x), (x^2, x^5 + 1)]
|
|
1154
|
+
sage: parent(c[1])
|
|
1155
|
+
Ambient free module of rank 2 over the principal ideal domain
|
|
1156
|
+
Univariate Polynomial Ring in x over Rational Field
|
|
1157
|
+
|
|
1158
|
+
TESTS:
|
|
1159
|
+
|
|
1160
|
+
Check that the returned rows are immutable as per :issue:`14874`::
|
|
1161
|
+
|
|
1162
|
+
sage: m = Mat(ZZ, 3, 3)(range(9))
|
|
1163
|
+
sage: v = m.dense_columns()
|
|
1164
|
+
sage: [x.is_mutable() for x in v]
|
|
1165
|
+
[False, False, False]
|
|
1166
|
+
"""
|
|
1167
|
+
x = self.fetch('dense_columns')
|
|
1168
|
+
if x is not None:
|
|
1169
|
+
if copy:
|
|
1170
|
+
return list(x)
|
|
1171
|
+
return x
|
|
1172
|
+
cdef Py_ssize_t i
|
|
1173
|
+
A = self if self.is_dense() else self.dense_matrix()
|
|
1174
|
+
C = [A.column(i) for i in range(self._ncols)]
|
|
1175
|
+
|
|
1176
|
+
# Make the vectors immutable since we are caching them
|
|
1177
|
+
for x in C:
|
|
1178
|
+
x.set_immutable()
|
|
1179
|
+
|
|
1180
|
+
# cache result
|
|
1181
|
+
self.cache('dense_columns', C)
|
|
1182
|
+
if copy:
|
|
1183
|
+
return list(C)
|
|
1184
|
+
else:
|
|
1185
|
+
return C
|
|
1186
|
+
|
|
1187
|
+
def dense_rows(self, copy=True):
|
|
1188
|
+
"""
|
|
1189
|
+
Return list of the dense rows of ``self``.
|
|
1190
|
+
|
|
1191
|
+
INPUT:
|
|
1192
|
+
|
|
1193
|
+
- ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can
|
|
1194
|
+
modify it safely (note that the individual vectors in the copy
|
|
1195
|
+
should not be modified since they are mutable!)
|
|
1196
|
+
|
|
1197
|
+
EXAMPLES::
|
|
1198
|
+
|
|
1199
|
+
sage: m = matrix(3, range(9)); m
|
|
1200
|
+
[0 1 2]
|
|
1201
|
+
[3 4 5]
|
|
1202
|
+
[6 7 8]
|
|
1203
|
+
sage: v = m.dense_rows(); v
|
|
1204
|
+
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
|
|
1205
|
+
sage: v is m.dense_rows()
|
|
1206
|
+
False
|
|
1207
|
+
sage: m.dense_rows(copy=False) is m.dense_rows(copy=False)
|
|
1208
|
+
True
|
|
1209
|
+
sage: m[0,0] = 10
|
|
1210
|
+
sage: m.dense_rows()
|
|
1211
|
+
[(10, 1, 2), (3, 4, 5), (6, 7, 8)]
|
|
1212
|
+
|
|
1213
|
+
TESTS:
|
|
1214
|
+
|
|
1215
|
+
Check that the returned rows are immutable as per :issue:`14874`::
|
|
1216
|
+
|
|
1217
|
+
sage: m = Mat(ZZ, 3, 3)(range(9))
|
|
1218
|
+
sage: v = m.dense_rows()
|
|
1219
|
+
sage: [x.is_mutable() for x in v]
|
|
1220
|
+
[False, False, False]
|
|
1221
|
+
"""
|
|
1222
|
+
x = self.fetch('dense_rows')
|
|
1223
|
+
if x is not None:
|
|
1224
|
+
if copy:
|
|
1225
|
+
return list(x)
|
|
1226
|
+
return x
|
|
1227
|
+
|
|
1228
|
+
cdef Py_ssize_t i
|
|
1229
|
+
A = self if self.is_dense() else self.dense_matrix()
|
|
1230
|
+
R = [A.row(i) for i in range(self._nrows)]
|
|
1231
|
+
|
|
1232
|
+
# Make the vectors immutable since we are caching them
|
|
1233
|
+
for x in R:
|
|
1234
|
+
x.set_immutable()
|
|
1235
|
+
|
|
1236
|
+
# cache result
|
|
1237
|
+
self.cache('dense_rows', R)
|
|
1238
|
+
if copy:
|
|
1239
|
+
return list(R)
|
|
1240
|
+
else:
|
|
1241
|
+
return R
|
|
1242
|
+
|
|
1243
|
+
def sparse_columns(self, copy=True):
|
|
1244
|
+
r"""
|
|
1245
|
+
Return a list of the columns of ``self`` as sparse vectors (or free module elements).
|
|
1246
|
+
|
|
1247
|
+
INPUT:
|
|
1248
|
+
|
|
1249
|
+
- ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can
|
|
1250
|
+
modify it safely
|
|
1251
|
+
|
|
1252
|
+
EXAMPLES::
|
|
1253
|
+
|
|
1254
|
+
sage: a = matrix(2, 3, range(6)); a
|
|
1255
|
+
[0 1 2]
|
|
1256
|
+
[3 4 5]
|
|
1257
|
+
sage: v = a.sparse_columns(); v
|
|
1258
|
+
[(0, 3), (1, 4), (2, 5)]
|
|
1259
|
+
sage: v[1].is_sparse()
|
|
1260
|
+
True
|
|
1261
|
+
|
|
1262
|
+
TESTS:
|
|
1263
|
+
|
|
1264
|
+
Columns of sparse matrices having no columns were fixed on :issue:`10714`::
|
|
1265
|
+
|
|
1266
|
+
sage: m = matrix(10, 0, sparse=True)
|
|
1267
|
+
sage: m.ncols()
|
|
1268
|
+
0
|
|
1269
|
+
sage: m.columns()
|
|
1270
|
+
[]
|
|
1271
|
+
|
|
1272
|
+
Check that the returned columns are immutable as per :issue:`14874`::
|
|
1273
|
+
|
|
1274
|
+
sage: m = Mat(ZZ, 3, 3, sparse=True)(range(9))
|
|
1275
|
+
sage: v = m.sparse_columns()
|
|
1276
|
+
sage: [x.is_mutable() for x in v]
|
|
1277
|
+
[False, False, False]
|
|
1278
|
+
"""
|
|
1279
|
+
x = self.fetch('sparse_columns')
|
|
1280
|
+
if x is not None:
|
|
1281
|
+
if copy:
|
|
1282
|
+
return list(x)
|
|
1283
|
+
return x
|
|
1284
|
+
|
|
1285
|
+
cdef Py_ssize_t i, j
|
|
1286
|
+
C = []
|
|
1287
|
+
if self._ncols > 0:
|
|
1288
|
+
F = sage.modules.free_module.FreeModule(self._base_ring, self._nrows, sparse=True)
|
|
1289
|
+
|
|
1290
|
+
k = 0
|
|
1291
|
+
entries = {}
|
|
1292
|
+
for i, j in self.nonzero_positions(copy=False, column_order=True):
|
|
1293
|
+
if j > k:
|
|
1294
|
+
# new column -- emit vector
|
|
1295
|
+
while len(C) < k:
|
|
1296
|
+
C.append(F(0))
|
|
1297
|
+
C.append(F(entries, coerce=False, copy=False, check=False))
|
|
1298
|
+
entries = {}
|
|
1299
|
+
k = j
|
|
1300
|
+
entries[i] = self.get_unsafe(i, j)
|
|
1301
|
+
|
|
1302
|
+
# finish up
|
|
1303
|
+
while len(C) < k:
|
|
1304
|
+
C.append(F(0))
|
|
1305
|
+
C.append(F(entries, coerce=False, copy=False, check=False))
|
|
1306
|
+
while len(C) < self._ncols:
|
|
1307
|
+
C.append(F(0))
|
|
1308
|
+
|
|
1309
|
+
# Make the vectors immutable since we are caching them
|
|
1310
|
+
for x in C:
|
|
1311
|
+
x.set_immutable()
|
|
1312
|
+
|
|
1313
|
+
# cache and return result
|
|
1314
|
+
self.cache('sparse_columns', C)
|
|
1315
|
+
if copy:
|
|
1316
|
+
return list(C)
|
|
1317
|
+
else:
|
|
1318
|
+
return C
|
|
1319
|
+
|
|
1320
|
+
def sparse_rows(self, copy=True):
|
|
1321
|
+
r"""
|
|
1322
|
+
Return a list of the rows of ``self`` as sparse vectors (or free module elements).
|
|
1323
|
+
|
|
1324
|
+
INPUT:
|
|
1325
|
+
|
|
1326
|
+
- ``copy`` -- boolean (default: ``True``); if ``True``, return a copy so you can
|
|
1327
|
+
modify it safely
|
|
1328
|
+
|
|
1329
|
+
EXAMPLES::
|
|
1330
|
+
|
|
1331
|
+
sage: m = Mat(ZZ, 3, 3, sparse=True)(range(9)); m
|
|
1332
|
+
[0 1 2]
|
|
1333
|
+
[3 4 5]
|
|
1334
|
+
[6 7 8]
|
|
1335
|
+
sage: v = m.sparse_rows(); v
|
|
1336
|
+
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
|
|
1337
|
+
sage: m.sparse_rows(copy=False) is m.sparse_rows(copy=False)
|
|
1338
|
+
True
|
|
1339
|
+
sage: v[1].is_sparse()
|
|
1340
|
+
True
|
|
1341
|
+
sage: m[0,0] = 10
|
|
1342
|
+
sage: m.sparse_rows()
|
|
1343
|
+
[(10, 1, 2), (3, 4, 5), (6, 7, 8)]
|
|
1344
|
+
|
|
1345
|
+
TESTS:
|
|
1346
|
+
|
|
1347
|
+
Rows of sparse matrices having no rows were fixed on :issue:`10714`::
|
|
1348
|
+
|
|
1349
|
+
sage: m = matrix(0, 10, sparse=True)
|
|
1350
|
+
sage: m.nrows()
|
|
1351
|
+
0
|
|
1352
|
+
sage: m.rows()
|
|
1353
|
+
[]
|
|
1354
|
+
|
|
1355
|
+
Check that the returned rows are immutable as per :issue:`14874`::
|
|
1356
|
+
|
|
1357
|
+
sage: m = Mat(ZZ, 3, 3, sparse=True)(range(9))
|
|
1358
|
+
sage: v = m.sparse_rows()
|
|
1359
|
+
sage: [x.is_mutable() for x in v]
|
|
1360
|
+
[False, False, False]
|
|
1361
|
+
"""
|
|
1362
|
+
x = self.fetch('sparse_rows')
|
|
1363
|
+
if x is not None:
|
|
1364
|
+
if copy:
|
|
1365
|
+
return list(x)
|
|
1366
|
+
return x
|
|
1367
|
+
|
|
1368
|
+
cdef Py_ssize_t i, j
|
|
1369
|
+
R = []
|
|
1370
|
+
if self._nrows > 0:
|
|
1371
|
+
F = sage.modules.free_module.FreeModule(self._base_ring, self._ncols, sparse=True)
|
|
1372
|
+
|
|
1373
|
+
k = 0
|
|
1374
|
+
entries = {}
|
|
1375
|
+
for i, j in self.nonzero_positions(copy=False):
|
|
1376
|
+
if i > k:
|
|
1377
|
+
# new row -- emit vector
|
|
1378
|
+
while len(R) < k:
|
|
1379
|
+
R.append(F(0))
|
|
1380
|
+
R.append(F(entries, coerce=False, copy=False, check=False))
|
|
1381
|
+
entries = {}
|
|
1382
|
+
k = i
|
|
1383
|
+
entries[j] = self.get_unsafe(i, j)
|
|
1384
|
+
|
|
1385
|
+
# finish up
|
|
1386
|
+
while len(R) < k:
|
|
1387
|
+
R.append(F(0))
|
|
1388
|
+
R.append(F(entries, coerce=False, copy=False, check=False))
|
|
1389
|
+
while len(R) < self._nrows:
|
|
1390
|
+
R.append(F(0))
|
|
1391
|
+
|
|
1392
|
+
# Make the vectors immutable since we are caching them
|
|
1393
|
+
for x in R:
|
|
1394
|
+
x.set_immutable()
|
|
1395
|
+
|
|
1396
|
+
# cache and return result
|
|
1397
|
+
self.cache('sparse_rows', R)
|
|
1398
|
+
if copy:
|
|
1399
|
+
return list(R)
|
|
1400
|
+
else:
|
|
1401
|
+
return R
|
|
1402
|
+
|
|
1403
|
+
def column(self, Py_ssize_t i, from_list=False):
|
|
1404
|
+
"""
|
|
1405
|
+
Return the ``i``-th column of this matrix as a vector.
|
|
1406
|
+
|
|
1407
|
+
This column is a dense vector if and only if the matrix is a dense
|
|
1408
|
+
matrix.
|
|
1409
|
+
|
|
1410
|
+
INPUT:
|
|
1411
|
+
|
|
1412
|
+
- ``i`` -- integer
|
|
1413
|
+
|
|
1414
|
+
- ``from_list`` -- boolean (default: ``False``); if ``True``, returns the
|
|
1415
|
+
``i``-th element of ``self.columns()`` (see :func:`columns()`),
|
|
1416
|
+
which may be faster, but requires building a list of all
|
|
1417
|
+
columns the first time it is called after an entry of the
|
|
1418
|
+
matrix is changed.
|
|
1419
|
+
|
|
1420
|
+
EXAMPLES::
|
|
1421
|
+
|
|
1422
|
+
sage: a = matrix(2, 3, range(6)); a
|
|
1423
|
+
[0 1 2]
|
|
1424
|
+
[3 4 5]
|
|
1425
|
+
sage: a.column(1)
|
|
1426
|
+
(1, 4)
|
|
1427
|
+
|
|
1428
|
+
If the column is negative, it wraps around, just like with list
|
|
1429
|
+
indexing, e.g., -1 gives the right-most column::
|
|
1430
|
+
|
|
1431
|
+
sage: a.column(-1)
|
|
1432
|
+
(2, 5)
|
|
1433
|
+
|
|
1434
|
+
TESTS::
|
|
1435
|
+
|
|
1436
|
+
sage: a = matrix(2, 3, range(6)); a
|
|
1437
|
+
[0 1 2]
|
|
1438
|
+
[3 4 5]
|
|
1439
|
+
sage: a.column(3)
|
|
1440
|
+
Traceback (most recent call last):
|
|
1441
|
+
...
|
|
1442
|
+
IndexError: column index out of range
|
|
1443
|
+
sage: a.column(-4)
|
|
1444
|
+
Traceback (most recent call last):
|
|
1445
|
+
...
|
|
1446
|
+
IndexError: column index out of range
|
|
1447
|
+
"""
|
|
1448
|
+
if self._ncols == 0:
|
|
1449
|
+
raise IndexError("matrix has no columns")
|
|
1450
|
+
if i >= self._ncols or i < -self._ncols:
|
|
1451
|
+
raise IndexError("column index out of range")
|
|
1452
|
+
i = i % self._ncols
|
|
1453
|
+
if i < 0:
|
|
1454
|
+
i = i + self._ncols
|
|
1455
|
+
if from_list:
|
|
1456
|
+
return self.columns(copy=False)[i]
|
|
1457
|
+
cdef Py_ssize_t j
|
|
1458
|
+
V = self.column_ambient_module()
|
|
1459
|
+
tmp = [self.get_unsafe(j, i) for j in range(self._nrows)]
|
|
1460
|
+
return V(tmp, coerce=False, copy=False, check=False)
|
|
1461
|
+
|
|
1462
|
+
def row(self, Py_ssize_t i, from_list=False):
|
|
1463
|
+
"""
|
|
1464
|
+
Return the ``i``-th row of this matrix as a vector.
|
|
1465
|
+
|
|
1466
|
+
This row is a dense vector if and only if the matrix is a dense
|
|
1467
|
+
matrix.
|
|
1468
|
+
|
|
1469
|
+
INPUT:
|
|
1470
|
+
|
|
1471
|
+
- ``i`` -- integer
|
|
1472
|
+
|
|
1473
|
+
- ``from_list`` -- boolean (default: ``False``); if ``True``, returns the
|
|
1474
|
+
``i``-th element of ``self.rows()`` (see :func:`rows`), which
|
|
1475
|
+
may be faster, but requires building a list of all rows the
|
|
1476
|
+
first time it is called after an entry of the matrix is
|
|
1477
|
+
changed.
|
|
1478
|
+
|
|
1479
|
+
EXAMPLES::
|
|
1480
|
+
|
|
1481
|
+
sage: a = matrix(2, 3, range(6)); a
|
|
1482
|
+
[0 1 2]
|
|
1483
|
+
[3 4 5]
|
|
1484
|
+
sage: a.row(0)
|
|
1485
|
+
(0, 1, 2)
|
|
1486
|
+
sage: a.row(1)
|
|
1487
|
+
(3, 4, 5)
|
|
1488
|
+
sage: a.row(-1) # last row
|
|
1489
|
+
(3, 4, 5)
|
|
1490
|
+
|
|
1491
|
+
TESTS::
|
|
1492
|
+
|
|
1493
|
+
sage: a = matrix(2, 3, range(6)); a
|
|
1494
|
+
[0 1 2]
|
|
1495
|
+
[3 4 5]
|
|
1496
|
+
sage: a.row(2)
|
|
1497
|
+
Traceback (most recent call last):
|
|
1498
|
+
...
|
|
1499
|
+
IndexError: row index out of range
|
|
1500
|
+
sage: a.row(-3)
|
|
1501
|
+
Traceback (most recent call last):
|
|
1502
|
+
...
|
|
1503
|
+
IndexError: row index out of range
|
|
1504
|
+
"""
|
|
1505
|
+
if self._nrows == 0:
|
|
1506
|
+
raise IndexError("matrix has no rows")
|
|
1507
|
+
if i >= self._nrows or i < -self._nrows:
|
|
1508
|
+
raise IndexError("row index out of range")
|
|
1509
|
+
i = i % self._nrows
|
|
1510
|
+
if i < 0:
|
|
1511
|
+
i = i + self._nrows
|
|
1512
|
+
if from_list:
|
|
1513
|
+
return self.rows(copy=False)[i]
|
|
1514
|
+
cdef Py_ssize_t j
|
|
1515
|
+
V = self.row_ambient_module()
|
|
1516
|
+
tmp = [self.get_unsafe(i, j) for j in range(self._ncols)]
|
|
1517
|
+
return V(tmp, coerce=False, copy=False, check=False)
|
|
1518
|
+
|
|
1519
|
+
###########################################################################
|
|
1520
|
+
# Building matrices out of other matrices, rows, or columns
|
|
1521
|
+
###########################################################################
|
|
1522
|
+
|
|
1523
|
+
def stack(self, bottom, subdivide=False):
|
|
1524
|
+
r"""
|
|
1525
|
+
Return a new matrix formed by appending the matrix (or vector)
|
|
1526
|
+
``bottom`` below ``self``::
|
|
1527
|
+
|
|
1528
|
+
[ self ]
|
|
1529
|
+
[ bottom ]
|
|
1530
|
+
|
|
1531
|
+
INPUT:
|
|
1532
|
+
|
|
1533
|
+
- ``bottom`` -- a matrix, vector or free module element, whose
|
|
1534
|
+
dimensions are compatible with ``self``
|
|
1535
|
+
|
|
1536
|
+
- ``subdivide`` -- (default: ``False``) request the resulting
|
|
1537
|
+
matrix to have a new subdivision, separating ``self`` from ``bottom``
|
|
1538
|
+
|
|
1539
|
+
OUTPUT:
|
|
1540
|
+
|
|
1541
|
+
A new matrix formed by appending ``bottom`` beneath ``self``.
|
|
1542
|
+
If ``bottom`` is a vector (or free module element) then in this context
|
|
1543
|
+
it is appropriate to consider it as a row vector. (The code first
|
|
1544
|
+
converts a vector to a 1-row matrix.)
|
|
1545
|
+
|
|
1546
|
+
If ``subdivide`` is ``True`` then any row subdivisions for
|
|
1547
|
+
the two matrices are preserved, and a new subdivision is added
|
|
1548
|
+
between ``self`` and ``bottom``. If the column divisions are
|
|
1549
|
+
identical, then they are preserved, otherwise they are discarded.
|
|
1550
|
+
When ``subdivide`` is ``False`` there is no subdivision information
|
|
1551
|
+
in the result.
|
|
1552
|
+
|
|
1553
|
+
.. warning::
|
|
1554
|
+
|
|
1555
|
+
If ``subdivide`` is ``True`` then unequal column subdivisions
|
|
1556
|
+
will be discarded, since it would be ambiguous how to interpret
|
|
1557
|
+
them. If the subdivision behavior is not what you need,
|
|
1558
|
+
you can manage subdivisions yourself with methods like
|
|
1559
|
+
:meth:`~sage.matrix.matrix2.Matrix.subdivisions`
|
|
1560
|
+
and
|
|
1561
|
+
:meth:`~sage.matrix.matrix2.Matrix.subdivide`.
|
|
1562
|
+
You might also find :func:`~sage.matrix.constructor.block_matrix`
|
|
1563
|
+
or
|
|
1564
|
+
:func:`~sage.matrix.constructor.block_diagonal_matrix`
|
|
1565
|
+
useful and simpler in some instances.
|
|
1566
|
+
|
|
1567
|
+
EXAMPLES:
|
|
1568
|
+
|
|
1569
|
+
Stacking with a matrix. ::
|
|
1570
|
+
|
|
1571
|
+
sage: A = matrix(QQ, 4, 3, range(12))
|
|
1572
|
+
sage: B = matrix(QQ, 3, 3, range(9))
|
|
1573
|
+
sage: A.stack(B)
|
|
1574
|
+
[ 0 1 2]
|
|
1575
|
+
[ 3 4 5]
|
|
1576
|
+
[ 6 7 8]
|
|
1577
|
+
[ 9 10 11]
|
|
1578
|
+
[ 0 1 2]
|
|
1579
|
+
[ 3 4 5]
|
|
1580
|
+
[ 6 7 8]
|
|
1581
|
+
|
|
1582
|
+
Stacking with a vector. ::
|
|
1583
|
+
|
|
1584
|
+
sage: A = matrix(QQ, 3, 2, [0, 2, 4, 6, 8, 10])
|
|
1585
|
+
sage: v = vector(QQ, 2, [100, 200])
|
|
1586
|
+
sage: A.stack(v)
|
|
1587
|
+
[ 0 2]
|
|
1588
|
+
[ 4 6]
|
|
1589
|
+
[ 8 10]
|
|
1590
|
+
[100 200]
|
|
1591
|
+
|
|
1592
|
+
Errors are raised if the sizes are incompatible. ::
|
|
1593
|
+
|
|
1594
|
+
sage: A = matrix(RR, [[1, 2],[3, 4]])
|
|
1595
|
+
sage: B = matrix(RR, [[10, 20, 30], [40, 50, 60]])
|
|
1596
|
+
sage: A.stack(B)
|
|
1597
|
+
Traceback (most recent call last):
|
|
1598
|
+
...
|
|
1599
|
+
TypeError: number of columns must be the same, not 2 and 3
|
|
1600
|
+
|
|
1601
|
+
sage: v = vector(RR, [100, 200, 300])
|
|
1602
|
+
sage: A.stack(v)
|
|
1603
|
+
Traceback (most recent call last):
|
|
1604
|
+
...
|
|
1605
|
+
TypeError: number of columns must be the same, not 2 and 3
|
|
1606
|
+
|
|
1607
|
+
Setting ``subdivide`` to ``True`` will, in its simplest form,
|
|
1608
|
+
add a subdivision between ``self`` and ``bottom``. ::
|
|
1609
|
+
|
|
1610
|
+
sage: A = matrix(QQ, 2, 5, range(10))
|
|
1611
|
+
sage: B = matrix(QQ, 3, 5, range(15))
|
|
1612
|
+
sage: A.stack(B, subdivide=True)
|
|
1613
|
+
[ 0 1 2 3 4]
|
|
1614
|
+
[ 5 6 7 8 9]
|
|
1615
|
+
[--------------]
|
|
1616
|
+
[ 0 1 2 3 4]
|
|
1617
|
+
[ 5 6 7 8 9]
|
|
1618
|
+
[10 11 12 13 14]
|
|
1619
|
+
|
|
1620
|
+
Row subdivisions are preserved by stacking, and enriched,
|
|
1621
|
+
if subdivisions are requested. (So multiple stackings can
|
|
1622
|
+
be recorded.) ::
|
|
1623
|
+
|
|
1624
|
+
sage: A = matrix(QQ, 2, 4, range(8))
|
|
1625
|
+
sage: A.subdivide([1], None)
|
|
1626
|
+
sage: B = matrix(QQ, 3, 4, range(12))
|
|
1627
|
+
sage: B.subdivide([2], None)
|
|
1628
|
+
sage: A.stack(B, subdivide=True)
|
|
1629
|
+
[ 0 1 2 3]
|
|
1630
|
+
[-----------]
|
|
1631
|
+
[ 4 5 6 7]
|
|
1632
|
+
[-----------]
|
|
1633
|
+
[ 0 1 2 3]
|
|
1634
|
+
[ 4 5 6 7]
|
|
1635
|
+
[-----------]
|
|
1636
|
+
[ 8 9 10 11]
|
|
1637
|
+
|
|
1638
|
+
Column subdivisions can be preserved, but only if they are identical.
|
|
1639
|
+
Otherwise, this information is discarded and must be managed
|
|
1640
|
+
separately. ::
|
|
1641
|
+
|
|
1642
|
+
sage: A = matrix(QQ, 2, 5, range(10))
|
|
1643
|
+
sage: A.subdivide(None, [2,4])
|
|
1644
|
+
sage: B = matrix(QQ, 3, 5, range(15))
|
|
1645
|
+
sage: B.subdivide(None, [2,4])
|
|
1646
|
+
sage: A.stack(B, subdivide=True)
|
|
1647
|
+
[ 0 1| 2 3| 4]
|
|
1648
|
+
[ 5 6| 7 8| 9]
|
|
1649
|
+
[-----+-----+--]
|
|
1650
|
+
[ 0 1| 2 3| 4]
|
|
1651
|
+
[ 5 6| 7 8| 9]
|
|
1652
|
+
[10 11|12 13|14]
|
|
1653
|
+
|
|
1654
|
+
sage: A.subdivide(None, [1,2])
|
|
1655
|
+
sage: A.stack(B, subdivide=True)
|
|
1656
|
+
[ 0 1 2 3 4]
|
|
1657
|
+
[ 5 6 7 8 9]
|
|
1658
|
+
[--------------]
|
|
1659
|
+
[ 0 1 2 3 4]
|
|
1660
|
+
[ 5 6 7 8 9]
|
|
1661
|
+
[10 11 12 13 14]
|
|
1662
|
+
|
|
1663
|
+
The base ring of the result is the common parent for the base
|
|
1664
|
+
rings of ``self`` and ``bottom``. In particular, the parent for
|
|
1665
|
+
``A.stack(B)`` and ``B.stack(A)`` should be equal::
|
|
1666
|
+
|
|
1667
|
+
sage: A = matrix(QQ, 1, 2, [1,2])
|
|
1668
|
+
sage: B = matrix(RR, 1, 2, [sin(1.1), sin(2.2)])
|
|
1669
|
+
sage: C = A.stack(B); C
|
|
1670
|
+
[ 1.00000000000000 2.00000000000000]
|
|
1671
|
+
[0.891207360061435 0.808496403819590]
|
|
1672
|
+
sage: C.parent()
|
|
1673
|
+
Full MatrixSpace of 2 by 2 dense matrices
|
|
1674
|
+
over Real Field with 53 bits of precision
|
|
1675
|
+
|
|
1676
|
+
sage: D = B.stack(A); D
|
|
1677
|
+
[0.891207360061435 0.808496403819590]
|
|
1678
|
+
[ 1.00000000000000 2.00000000000000]
|
|
1679
|
+
sage: D.parent()
|
|
1680
|
+
Full MatrixSpace of 2 by 2 dense matrices
|
|
1681
|
+
over Real Field with 53 bits of precision
|
|
1682
|
+
|
|
1683
|
+
::
|
|
1684
|
+
|
|
1685
|
+
sage: R.<y> = PolynomialRing(ZZ)
|
|
1686
|
+
sage: A = matrix(QQ, 1, 2, [1, 2/3])
|
|
1687
|
+
sage: B = matrix(R, 1, 2, [y, y^2])
|
|
1688
|
+
|
|
1689
|
+
sage: C = A.stack(B); C
|
|
1690
|
+
[ 1 2/3]
|
|
1691
|
+
[ y y^2]
|
|
1692
|
+
sage: C.parent()
|
|
1693
|
+
Full MatrixSpace of 2 by 2 dense matrices over
|
|
1694
|
+
Univariate Polynomial Ring in y over Rational Field
|
|
1695
|
+
|
|
1696
|
+
Stacking a dense matrix atop a sparse one returns a sparse
|
|
1697
|
+
matrix::
|
|
1698
|
+
|
|
1699
|
+
sage: M = Matrix(ZZ, 2, 3, range(6), sparse=False)
|
|
1700
|
+
sage: N = diagonal_matrix([10,11,12], sparse=True)
|
|
1701
|
+
sage: P = M.stack(N); P
|
|
1702
|
+
[ 0 1 2]
|
|
1703
|
+
[ 3 4 5]
|
|
1704
|
+
[10 0 0]
|
|
1705
|
+
[ 0 11 0]
|
|
1706
|
+
[ 0 0 12]
|
|
1707
|
+
sage: P.is_sparse()
|
|
1708
|
+
True
|
|
1709
|
+
sage: P = N.stack(M); P
|
|
1710
|
+
[10 0 0]
|
|
1711
|
+
[ 0 11 0]
|
|
1712
|
+
[ 0 0 12]
|
|
1713
|
+
[ 0 1 2]
|
|
1714
|
+
[ 3 4 5]
|
|
1715
|
+
sage: P.is_sparse()
|
|
1716
|
+
True
|
|
1717
|
+
|
|
1718
|
+
One can stack matrices over different rings (:issue:`16399`). ::
|
|
1719
|
+
|
|
1720
|
+
sage: M = Matrix(ZZ, 2, 3, range(6))
|
|
1721
|
+
sage: N = Matrix(QQ, 1, 3, [10,11,12])
|
|
1722
|
+
sage: M.stack(N)
|
|
1723
|
+
[ 0 1 2]
|
|
1724
|
+
[ 3 4 5]
|
|
1725
|
+
[10 11 12]
|
|
1726
|
+
sage: N.stack(M)
|
|
1727
|
+
[10 11 12]
|
|
1728
|
+
[ 0 1 2]
|
|
1729
|
+
[ 3 4 5]
|
|
1730
|
+
|
|
1731
|
+
TESTS:
|
|
1732
|
+
|
|
1733
|
+
A legacy test from the original implementation. ::
|
|
1734
|
+
|
|
1735
|
+
sage: M = Matrix(QQ, 2, 3, range(6))
|
|
1736
|
+
sage: N = Matrix(QQ, 1, 3, [10,11,12])
|
|
1737
|
+
sage: M.stack(N)
|
|
1738
|
+
[ 0 1 2]
|
|
1739
|
+
[ 3 4 5]
|
|
1740
|
+
[10 11 12]
|
|
1741
|
+
|
|
1742
|
+
Non-matrices fail gracefully::
|
|
1743
|
+
|
|
1744
|
+
sage: M.stack(polygen(QQ))
|
|
1745
|
+
Traceback (most recent call last):
|
|
1746
|
+
...
|
|
1747
|
+
TypeError: a matrix must be stacked with another matrix or a vector
|
|
1748
|
+
|
|
1749
|
+
AUTHORS:
|
|
1750
|
+
|
|
1751
|
+
- Rob Beezer (2011-03-19): rewritten to mirror code for :meth:`augment`
|
|
1752
|
+
|
|
1753
|
+
- Jeroen Demeyer (2015-01-06): refactor, see :issue:`16399`.
|
|
1754
|
+
Put all boilerplate in one place (here) and put the actual
|
|
1755
|
+
type-dependent implementation in ``_stack_impl``.
|
|
1756
|
+
"""
|
|
1757
|
+
cdef Matrix other
|
|
1758
|
+
if isinstance(bottom, Matrix):
|
|
1759
|
+
other = <Matrix>bottom
|
|
1760
|
+
else:
|
|
1761
|
+
if hasattr(bottom, '_vector_'):
|
|
1762
|
+
bottom = bottom.row()
|
|
1763
|
+
else:
|
|
1764
|
+
raise TypeError('a matrix must be stacked with '
|
|
1765
|
+
'another matrix or a vector')
|
|
1766
|
+
other = <Matrix?>bottom
|
|
1767
|
+
|
|
1768
|
+
if self._ncols != other._ncols:
|
|
1769
|
+
raise TypeError("number of columns must be the same, not %s and %s" %
|
|
1770
|
+
(self.ncols(), bottom.ncols()))
|
|
1771
|
+
|
|
1772
|
+
top_ring = self._base_ring
|
|
1773
|
+
bottom_ring = other._base_ring
|
|
1774
|
+
if top_ring is not bottom_ring:
|
|
1775
|
+
R = coercion_model.common_parent(top_ring, bottom_ring)
|
|
1776
|
+
if top_ring is not R:
|
|
1777
|
+
self = self.change_ring(R)
|
|
1778
|
+
if bottom_ring is not R:
|
|
1779
|
+
other = other.change_ring(R)
|
|
1780
|
+
|
|
1781
|
+
if type(self) is not type(other):
|
|
1782
|
+
# If one of the matrices is sparse, return a sparse matrix
|
|
1783
|
+
if self.is_sparse_c() and not other.is_sparse_c():
|
|
1784
|
+
other = other.sparse_matrix()
|
|
1785
|
+
elif other.is_sparse_c() and not self.is_sparse_c():
|
|
1786
|
+
self = self.sparse_matrix()
|
|
1787
|
+
|
|
1788
|
+
Z = self._stack_impl(other)
|
|
1789
|
+
if subdivide:
|
|
1790
|
+
Z._subdivide_on_stack(self, other)
|
|
1791
|
+
return Z
|
|
1792
|
+
|
|
1793
|
+
cdef _stack_impl(self, bottom):
|
|
1794
|
+
"""
|
|
1795
|
+
Implementation of :meth:`stack`.
|
|
1796
|
+
|
|
1797
|
+
Assume that ``self`` and ``other`` are compatible in the sense
|
|
1798
|
+
that they have the same base ring and that both are either
|
|
1799
|
+
dense or sparse.
|
|
1800
|
+
"""
|
|
1801
|
+
cdef Matrix other = <Matrix>bottom
|
|
1802
|
+
cdef Matrix Z
|
|
1803
|
+
Z = self.new_matrix(nrows=self._nrows + other._nrows, ncols=self._ncols)
|
|
1804
|
+
|
|
1805
|
+
cdef Py_ssize_t r, c
|
|
1806
|
+
cdef Py_ssize_t nr = self._nrows
|
|
1807
|
+
for r in range(self._nrows):
|
|
1808
|
+
for c in range(self._ncols):
|
|
1809
|
+
Z.set_unsafe(r, c, self.get_unsafe(r, c))
|
|
1810
|
+
for r in range(other._nrows):
|
|
1811
|
+
for c in range(other._ncols):
|
|
1812
|
+
Z.set_unsafe(r + nr, c, other.get_unsafe(r, c))
|
|
1813
|
+
|
|
1814
|
+
return Z
|
|
1815
|
+
|
|
1816
|
+
def augment(self, right, subdivide=False):
|
|
1817
|
+
r"""
|
|
1818
|
+
Return a new matrix formed by appending the matrix (or vector)
|
|
1819
|
+
``right`` on the right side of ``self``.
|
|
1820
|
+
|
|
1821
|
+
INPUT:
|
|
1822
|
+
|
|
1823
|
+
- ``right`` -- a matrix, vector or free module element, whose
|
|
1824
|
+
dimensions are compatible with ``self``
|
|
1825
|
+
|
|
1826
|
+
- ``subdivide`` -- (default: ``False``) request the resulting
|
|
1827
|
+
matrix to have a new subdivision, separating ``self`` from
|
|
1828
|
+
``right``.
|
|
1829
|
+
|
|
1830
|
+
OUTPUT:
|
|
1831
|
+
|
|
1832
|
+
A new matrix formed by appending ``right`` onto the right side
|
|
1833
|
+
of ``self``. If ``right`` is a vector (or free module element)
|
|
1834
|
+
then in this context it is appropriate to consider it as a
|
|
1835
|
+
column vector. (The code first converts a vector to a 1-column
|
|
1836
|
+
matrix.)
|
|
1837
|
+
|
|
1838
|
+
If ``subdivide`` is ``True`` then any column subdivisions for
|
|
1839
|
+
the two matrices are preserved, and a new subdivision is added
|
|
1840
|
+
between ``self`` and ``right``. If the row divisions are
|
|
1841
|
+
identical, then they are preserved, otherwise they are
|
|
1842
|
+
discarded. When ``subdivide`` is ``False`` there is no
|
|
1843
|
+
subdivision information in the result.
|
|
1844
|
+
|
|
1845
|
+
.. warning::
|
|
1846
|
+
If ``subdivide`` is ``True`` then unequal row subdivisions
|
|
1847
|
+
will be discarded, since it would be ambiguous how to
|
|
1848
|
+
interpret them. If the subdivision behavior is not what you
|
|
1849
|
+
need, you can manage subdivisions yourself with methods like
|
|
1850
|
+
:meth:`~sage.matrix.matrix2.Matrix.get_subdivisions` and
|
|
1851
|
+
:meth:`~sage.matrix.matrix2.Matrix.subdivide`. You might
|
|
1852
|
+
also find :func:`~sage.matrix.constructor.block_matrix` or
|
|
1853
|
+
:func:`~sage.matrix.constructor.block_diagonal_matrix`
|
|
1854
|
+
useful and simpler in some instances.
|
|
1855
|
+
|
|
1856
|
+
EXAMPLES:
|
|
1857
|
+
|
|
1858
|
+
Augmenting with a matrix. ::
|
|
1859
|
+
|
|
1860
|
+
sage: A = matrix(QQ, 3, range(12))
|
|
1861
|
+
sage: B = matrix(QQ, 3, range(9))
|
|
1862
|
+
sage: A.augment(B)
|
|
1863
|
+
[ 0 1 2 3 0 1 2]
|
|
1864
|
+
[ 4 5 6 7 3 4 5]
|
|
1865
|
+
[ 8 9 10 11 6 7 8]
|
|
1866
|
+
|
|
1867
|
+
Augmenting with a vector. ::
|
|
1868
|
+
|
|
1869
|
+
sage: A = matrix(QQ, 2, [0, 2, 4, 6, 8, 10])
|
|
1870
|
+
sage: v = vector(QQ, 2, [100, 200])
|
|
1871
|
+
sage: A.augment(v)
|
|
1872
|
+
[ 0 2 4 100]
|
|
1873
|
+
[ 6 8 10 200]
|
|
1874
|
+
|
|
1875
|
+
Errors are raised if the sizes are incompatible. ::
|
|
1876
|
+
|
|
1877
|
+
sage: A = matrix(RR, [[1, 2],[3, 4]])
|
|
1878
|
+
sage: B = matrix(RR, [[10, 20], [30, 40], [50, 60]])
|
|
1879
|
+
sage: A.augment(B)
|
|
1880
|
+
Traceback (most recent call last):
|
|
1881
|
+
...
|
|
1882
|
+
TypeError: number of rows must be the same, 2 != 3
|
|
1883
|
+
|
|
1884
|
+
sage: v = vector(RR, [100, 200, 300])
|
|
1885
|
+
sage: A.augment(v)
|
|
1886
|
+
Traceback (most recent call last):
|
|
1887
|
+
...
|
|
1888
|
+
TypeError: number of rows must be the same, 2 != 3
|
|
1889
|
+
|
|
1890
|
+
Setting ``subdivide`` to ``True`` will, in its simplest form,
|
|
1891
|
+
add a subdivision between ``self`` and ``right``. ::
|
|
1892
|
+
|
|
1893
|
+
sage: A = matrix(QQ, 3, range(12))
|
|
1894
|
+
sage: B = matrix(QQ, 3, range(15))
|
|
1895
|
+
sage: A.augment(B, subdivide=True)
|
|
1896
|
+
[ 0 1 2 3| 0 1 2 3 4]
|
|
1897
|
+
[ 4 5 6 7| 5 6 7 8 9]
|
|
1898
|
+
[ 8 9 10 11|10 11 12 13 14]
|
|
1899
|
+
|
|
1900
|
+
Column subdivisions are preserved by augmentation, and enriched,
|
|
1901
|
+
if subdivisions are requested. (So multiple augmentations can
|
|
1902
|
+
be recorded.) ::
|
|
1903
|
+
|
|
1904
|
+
sage: A = matrix(QQ, 3, range(6))
|
|
1905
|
+
sage: A.subdivide(None, [1])
|
|
1906
|
+
sage: B = matrix(QQ, 3, range(9))
|
|
1907
|
+
sage: B.subdivide(None, [2])
|
|
1908
|
+
sage: A.augment(B, subdivide=True)
|
|
1909
|
+
[0|1|0 1|2]
|
|
1910
|
+
[2|3|3 4|5]
|
|
1911
|
+
[4|5|6 7|8]
|
|
1912
|
+
|
|
1913
|
+
Row subdivisions can be preserved, but only if they are
|
|
1914
|
+
identical. Otherwise, this information is discarded and must be
|
|
1915
|
+
managed separately. ::
|
|
1916
|
+
|
|
1917
|
+
sage: A = matrix(QQ, 3, range(6))
|
|
1918
|
+
sage: A.subdivide([1,3], None)
|
|
1919
|
+
sage: B = matrix(QQ, 3, range(9))
|
|
1920
|
+
sage: B.subdivide([1,3], None)
|
|
1921
|
+
sage: A.augment(B, subdivide=True)
|
|
1922
|
+
[0 1|0 1 2]
|
|
1923
|
+
[---+-----]
|
|
1924
|
+
[2 3|3 4 5]
|
|
1925
|
+
[4 5|6 7 8]
|
|
1926
|
+
[---+-----]
|
|
1927
|
+
|
|
1928
|
+
sage: A.subdivide([1,2], None)
|
|
1929
|
+
sage: A.augment(B, subdivide=True)
|
|
1930
|
+
[0 1|0 1 2]
|
|
1931
|
+
[2 3|3 4 5]
|
|
1932
|
+
[4 5|6 7 8]
|
|
1933
|
+
|
|
1934
|
+
The result retains the base ring of ``self`` by coercing the
|
|
1935
|
+
elements of ``right`` into the base ring of ``self``. ::
|
|
1936
|
+
|
|
1937
|
+
sage: A = matrix(QQ, 2, [1,2])
|
|
1938
|
+
sage: B = matrix(RR, 2, [sin(1.1), sin(2.2)])
|
|
1939
|
+
sage: C = A.augment(B); C # needs sage.symbolic
|
|
1940
|
+
[ 1 183017397/205358938]
|
|
1941
|
+
[ 2 106580492/131825561]
|
|
1942
|
+
sage: C.parent() # needs sage.symbolic
|
|
1943
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
1944
|
+
|
|
1945
|
+
sage: D = B.augment(A); D
|
|
1946
|
+
[0.89120736006... 1.00000000000000]
|
|
1947
|
+
[0.80849640381... 2.00000000000000]
|
|
1948
|
+
sage: D.parent()
|
|
1949
|
+
Full MatrixSpace of 2 by 2 dense matrices
|
|
1950
|
+
over Real Field with 53 bits of precision
|
|
1951
|
+
|
|
1952
|
+
Sometimes it is not possible to coerce into the base ring of
|
|
1953
|
+
``self``. A solution is to change the base ring of ``self`` to
|
|
1954
|
+
a more expansive ring. Here we mix the rationals with a ring of
|
|
1955
|
+
polynomials with rational coefficients. ::
|
|
1956
|
+
|
|
1957
|
+
sage: R.<y> = PolynomialRing(QQ)
|
|
1958
|
+
sage: A = matrix(QQ, 1, [1,2])
|
|
1959
|
+
sage: B = matrix(R, 1, [y, y^2])
|
|
1960
|
+
|
|
1961
|
+
sage: C = B.augment(A); C
|
|
1962
|
+
[ y y^2 1 2]
|
|
1963
|
+
sage: C.parent()
|
|
1964
|
+
Full MatrixSpace of 1 by 4 dense matrices over
|
|
1965
|
+
Univariate Polynomial Ring in y over Rational Field
|
|
1966
|
+
|
|
1967
|
+
sage: D = A.augment(B)
|
|
1968
|
+
Traceback (most recent call last):
|
|
1969
|
+
...
|
|
1970
|
+
TypeError: y is not a constant polynomial
|
|
1971
|
+
|
|
1972
|
+
sage: E = A.change_ring(R)
|
|
1973
|
+
sage: F = E.augment(B); F
|
|
1974
|
+
[ 1 2 y y^2]
|
|
1975
|
+
sage: F.parent()
|
|
1976
|
+
Full MatrixSpace of 1 by 4 dense matrices over
|
|
1977
|
+
Univariate Polynomial Ring in y over Rational Field
|
|
1978
|
+
|
|
1979
|
+
AUTHORS:
|
|
1980
|
+
|
|
1981
|
+
- Naqi Jaffery (2006-01-24): examples
|
|
1982
|
+
- Rob Beezer (2010-12-07): vector argument, docstring, subdivisions
|
|
1983
|
+
"""
|
|
1984
|
+
from sage.matrix.constructor import matrix
|
|
1985
|
+
|
|
1986
|
+
if not isinstance(right, sage.matrix.matrix1.Matrix):
|
|
1987
|
+
if hasattr(right, '_vector_'):
|
|
1988
|
+
right = right.column()
|
|
1989
|
+
else:
|
|
1990
|
+
raise TypeError("a matrix must be augmented with another matrix, "
|
|
1991
|
+
"or a vector")
|
|
1992
|
+
|
|
1993
|
+
cdef Matrix other
|
|
1994
|
+
other = right
|
|
1995
|
+
|
|
1996
|
+
if self._nrows != other._nrows:
|
|
1997
|
+
raise TypeError('number of rows must be the same, '
|
|
1998
|
+
'{0} != {1}'.format(self._nrows, other._nrows))
|
|
1999
|
+
if not (self._base_ring is other.base_ring()):
|
|
2000
|
+
other = other.change_ring(self._base_ring)
|
|
2001
|
+
|
|
2002
|
+
cdef Matrix Z
|
|
2003
|
+
Z = self.new_matrix(ncols=self._ncols + other._ncols)
|
|
2004
|
+
|
|
2005
|
+
cdef Py_ssize_t r, c
|
|
2006
|
+
for r from 0 <= r < self._nrows:
|
|
2007
|
+
for c from 0 <= c < self._ncols:
|
|
2008
|
+
Z.set_unsafe(r, c, self.get_unsafe(r, c))
|
|
2009
|
+
nc = self.ncols()
|
|
2010
|
+
|
|
2011
|
+
for r from 0 <= r < other._nrows:
|
|
2012
|
+
for c from 0 <= c < other._ncols:
|
|
2013
|
+
Z.set_unsafe(r, c + nc, other.get_unsafe(r, c))
|
|
2014
|
+
|
|
2015
|
+
if subdivide:
|
|
2016
|
+
Z._subdivide_on_augment(self, other)
|
|
2017
|
+
|
|
2018
|
+
return Z
|
|
2019
|
+
|
|
2020
|
+
def matrix_from_columns(self, columns):
|
|
2021
|
+
"""
|
|
2022
|
+
Return the matrix constructed from ``self`` using columns with indices
|
|
2023
|
+
in the columns list.
|
|
2024
|
+
|
|
2025
|
+
EXAMPLES::
|
|
2026
|
+
|
|
2027
|
+
sage: M = MatrixSpace(Integers(8), 3, 3)
|
|
2028
|
+
sage: A = M(range(9)); A
|
|
2029
|
+
[0 1 2]
|
|
2030
|
+
[3 4 5]
|
|
2031
|
+
[6 7 0]
|
|
2032
|
+
sage: A.matrix_from_columns([2,1])
|
|
2033
|
+
[2 1]
|
|
2034
|
+
[5 4]
|
|
2035
|
+
[0 7]
|
|
2036
|
+
"""
|
|
2037
|
+
columns = PySequence_Fast(columns, "columns is not iterable")
|
|
2038
|
+
cdef Py_ssize_t ncols = len(columns)
|
|
2039
|
+
|
|
2040
|
+
# Construct new matrix
|
|
2041
|
+
cdef Matrix A = self.new_matrix(ncols=ncols)
|
|
2042
|
+
cdef Py_ssize_t i, j, col
|
|
2043
|
+
for j, col in enumerate(columns):
|
|
2044
|
+
if col < 0 or col >= self._ncols:
|
|
2045
|
+
raise IndexError("column index out of range")
|
|
2046
|
+
for i in range(self._nrows):
|
|
2047
|
+
A.set_unsafe(i, j, self.get_unsafe(i, col))
|
|
2048
|
+
return A
|
|
2049
|
+
|
|
2050
|
+
def delete_columns(self, dcols, check=True):
|
|
2051
|
+
"""
|
|
2052
|
+
Return the matrix constructed from deleting the columns with indices in the ``dcols`` list.
|
|
2053
|
+
|
|
2054
|
+
INPUT:
|
|
2055
|
+
|
|
2056
|
+
- ``dcols`` -- list of indices of columns to be deleted from ``self``
|
|
2057
|
+
- ``check`` -- boolean (default: ``True``); check whether any index in
|
|
2058
|
+
``dcols`` is out of range
|
|
2059
|
+
|
|
2060
|
+
.. SEEALSO::
|
|
2061
|
+
|
|
2062
|
+
The methods :meth:`delete_rows` and :meth:`matrix_from_columns`
|
|
2063
|
+
are related.
|
|
2064
|
+
|
|
2065
|
+
EXAMPLES::
|
|
2066
|
+
|
|
2067
|
+
sage: A = Matrix(3, 4, range(12)); A
|
|
2068
|
+
[ 0 1 2 3]
|
|
2069
|
+
[ 4 5 6 7]
|
|
2070
|
+
[ 8 9 10 11]
|
|
2071
|
+
sage: A.delete_columns([0,2])
|
|
2072
|
+
[ 1 3]
|
|
2073
|
+
[ 5 7]
|
|
2074
|
+
[ 9 11]
|
|
2075
|
+
|
|
2076
|
+
``dcols`` can be a tuple. But only the underlying set of indices matters. ::
|
|
2077
|
+
|
|
2078
|
+
sage: A.delete_columns((2,0,2))
|
|
2079
|
+
[ 1 3]
|
|
2080
|
+
[ 5 7]
|
|
2081
|
+
[ 9 11]
|
|
2082
|
+
|
|
2083
|
+
The default is to check whether any index in ``dcols`` is out of range. ::
|
|
2084
|
+
|
|
2085
|
+
sage: A.delete_columns([-1,2,4])
|
|
2086
|
+
Traceback (most recent call last):
|
|
2087
|
+
...
|
|
2088
|
+
IndexError: [-1, 4] contains invalid indices
|
|
2089
|
+
sage: A.delete_columns([-1,2,4], check=False)
|
|
2090
|
+
[ 0 1 3]
|
|
2091
|
+
[ 4 5 7]
|
|
2092
|
+
[ 8 9 11]
|
|
2093
|
+
|
|
2094
|
+
TESTS:
|
|
2095
|
+
|
|
2096
|
+
The list of indices is checked. ::
|
|
2097
|
+
|
|
2098
|
+
sage: A.delete_columns("junk")
|
|
2099
|
+
Traceback (most recent call last):
|
|
2100
|
+
...
|
|
2101
|
+
IndexError: ['j', 'k', 'n', 'u'] contains invalid indices
|
|
2102
|
+
|
|
2103
|
+
AUTHORS:
|
|
2104
|
+
|
|
2105
|
+
- Wai Yan Pong (2012-03-05)
|
|
2106
|
+
"""
|
|
2107
|
+
if not isinstance(dcols, (list, tuple)):
|
|
2108
|
+
dcols = list(dcols)
|
|
2109
|
+
|
|
2110
|
+
cdef list cols, diff_cols
|
|
2111
|
+
|
|
2112
|
+
if check:
|
|
2113
|
+
diff_cols = sorted(set(dcols).difference(set(range(self._ncols))))
|
|
2114
|
+
if diff_cols:
|
|
2115
|
+
raise IndexError("{d} contains invalid indices".format(d=diff_cols))
|
|
2116
|
+
cols = [k for k in range(self._ncols) if k not in dcols]
|
|
2117
|
+
return self.matrix_from_columns(cols)
|
|
2118
|
+
|
|
2119
|
+
def matrix_from_rows(self, rows):
|
|
2120
|
+
"""
|
|
2121
|
+
Return the matrix constructed from ``self`` using rows with indices in
|
|
2122
|
+
the rows list.
|
|
2123
|
+
|
|
2124
|
+
EXAMPLES::
|
|
2125
|
+
|
|
2126
|
+
sage: M = MatrixSpace(Integers(8), 3, 3)
|
|
2127
|
+
sage: A = M(range(9)); A
|
|
2128
|
+
[0 1 2]
|
|
2129
|
+
[3 4 5]
|
|
2130
|
+
[6 7 0]
|
|
2131
|
+
sage: A.matrix_from_rows([2,1])
|
|
2132
|
+
[6 7 0]
|
|
2133
|
+
[3 4 5]
|
|
2134
|
+
"""
|
|
2135
|
+
rows = PySequence_Fast(rows, "rows is not iterable")
|
|
2136
|
+
cdef Py_ssize_t nrows = len(rows)
|
|
2137
|
+
|
|
2138
|
+
# Construct new matrix
|
|
2139
|
+
cdef Matrix A = self.new_matrix(nrows=nrows)
|
|
2140
|
+
cdef Py_ssize_t i, j, row
|
|
2141
|
+
for i, row in enumerate(rows):
|
|
2142
|
+
if row < 0 or row >= self._nrows:
|
|
2143
|
+
raise IndexError("row index out of range")
|
|
2144
|
+
for j in range(self._ncols):
|
|
2145
|
+
A.set_unsafe(i, j, self.get_unsafe(row, j))
|
|
2146
|
+
return A
|
|
2147
|
+
|
|
2148
|
+
def delete_rows(self, drows, check=True):
|
|
2149
|
+
"""
|
|
2150
|
+
Return the matrix constructed from deleting the rows with indices in the ``drows`` list.
|
|
2151
|
+
|
|
2152
|
+
INPUT:
|
|
2153
|
+
|
|
2154
|
+
- ``drows`` -- list of indices of rows to be deleted from ``self``
|
|
2155
|
+
- ``check`` -- boolean (default: ``True``); whether to check if any
|
|
2156
|
+
index in ``drows`` is out of range
|
|
2157
|
+
|
|
2158
|
+
.. SEEALSO::
|
|
2159
|
+
|
|
2160
|
+
The methods :meth:`delete_columns` and :meth:`matrix_from_rows`
|
|
2161
|
+
are related.
|
|
2162
|
+
|
|
2163
|
+
EXAMPLES::
|
|
2164
|
+
|
|
2165
|
+
sage: A = Matrix(4, 3, range(12)); A
|
|
2166
|
+
[ 0 1 2]
|
|
2167
|
+
[ 3 4 5]
|
|
2168
|
+
[ 6 7 8]
|
|
2169
|
+
[ 9 10 11]
|
|
2170
|
+
sage: A.delete_rows([0,2])
|
|
2171
|
+
[ 3 4 5]
|
|
2172
|
+
[ 9 10 11]
|
|
2173
|
+
|
|
2174
|
+
``drows`` can be a tuple. But only the underlying set of indices matters. ::
|
|
2175
|
+
|
|
2176
|
+
sage: A.delete_rows((2,0,2))
|
|
2177
|
+
[ 3 4 5]
|
|
2178
|
+
[ 9 10 11]
|
|
2179
|
+
|
|
2180
|
+
The default is to check whether the any index in ``drows`` is out of range. ::
|
|
2181
|
+
|
|
2182
|
+
sage: A.delete_rows([-1,2,4])
|
|
2183
|
+
Traceback (most recent call last):
|
|
2184
|
+
...
|
|
2185
|
+
IndexError: [-1, 4] contains invalid indices
|
|
2186
|
+
sage: A.delete_rows([-1,2,4], check=False)
|
|
2187
|
+
[ 0 1 2]
|
|
2188
|
+
[ 3 4 5]
|
|
2189
|
+
[ 9 10 11]
|
|
2190
|
+
|
|
2191
|
+
TESTS:
|
|
2192
|
+
|
|
2193
|
+
The list of indices is checked. ::
|
|
2194
|
+
|
|
2195
|
+
sage: A.delete_rows("junk")
|
|
2196
|
+
Traceback (most recent call last):
|
|
2197
|
+
...
|
|
2198
|
+
IndexError: ['j', 'k', 'n', 'u'] contains invalid indices
|
|
2199
|
+
|
|
2200
|
+
AUTHORS
|
|
2201
|
+
|
|
2202
|
+
- Wai Yan Pong (2012-03-05)
|
|
2203
|
+
"""
|
|
2204
|
+
if not isinstance(drows, (list, tuple)):
|
|
2205
|
+
drows = list(drows)
|
|
2206
|
+
|
|
2207
|
+
cdef list rows, diff_rows
|
|
2208
|
+
|
|
2209
|
+
if check:
|
|
2210
|
+
diff_rows = sorted(set(drows).difference(set(range(self._nrows))))
|
|
2211
|
+
if diff_rows:
|
|
2212
|
+
raise IndexError("{d} contains invalid indices".format(d=diff_rows))
|
|
2213
|
+
rows = [k for k in range(self._nrows) if k not in drows]
|
|
2214
|
+
return self.matrix_from_rows(rows)
|
|
2215
|
+
|
|
2216
|
+
def matrix_from_rows_and_columns(self, rows, columns):
|
|
2217
|
+
"""
|
|
2218
|
+
Return the matrix constructed from ``self`` from the given rows and
|
|
2219
|
+
columns.
|
|
2220
|
+
|
|
2221
|
+
EXAMPLES::
|
|
2222
|
+
|
|
2223
|
+
sage: M = MatrixSpace(Integers(8), 3, 3)
|
|
2224
|
+
sage: A = M(range(9)); A
|
|
2225
|
+
[0 1 2]
|
|
2226
|
+
[3 4 5]
|
|
2227
|
+
[6 7 0]
|
|
2228
|
+
sage: A.matrix_from_rows_and_columns([1], [0,2])
|
|
2229
|
+
[3 5]
|
|
2230
|
+
sage: A.matrix_from_rows_and_columns([1,2], [1,2])
|
|
2231
|
+
[4 5]
|
|
2232
|
+
[7 0]
|
|
2233
|
+
|
|
2234
|
+
Note that row and column indices can be reordered or repeated::
|
|
2235
|
+
|
|
2236
|
+
sage: A.matrix_from_rows_and_columns([2,1], [2,1])
|
|
2237
|
+
[0 7]
|
|
2238
|
+
[5 4]
|
|
2239
|
+
|
|
2240
|
+
For example here we take from row 1 columns 2 then 0 twice, and do
|
|
2241
|
+
this 3 times::
|
|
2242
|
+
|
|
2243
|
+
sage: A.matrix_from_rows_and_columns([1,1,1], [2,0,0])
|
|
2244
|
+
[5 3 3]
|
|
2245
|
+
[5 3 3]
|
|
2246
|
+
[5 3 3]
|
|
2247
|
+
|
|
2248
|
+
AUTHORS:
|
|
2249
|
+
|
|
2250
|
+
- Jaap Spies (2006-02-18)
|
|
2251
|
+
|
|
2252
|
+
- Didier Deshommes: some Pyrex speedups implemented
|
|
2253
|
+
"""
|
|
2254
|
+
rows = PySequence_Fast(rows, "rows is not iterable")
|
|
2255
|
+
columns = PySequence_Fast(columns, "columns is not iterable")
|
|
2256
|
+
|
|
2257
|
+
cdef Py_ssize_t ncols = len(columns)
|
|
2258
|
+
cdef Py_ssize_t nrows = len(rows)
|
|
2259
|
+
|
|
2260
|
+
# Check whether column indices are valid
|
|
2261
|
+
cdef Py_ssize_t i, j, row, col
|
|
2262
|
+
for col in columns:
|
|
2263
|
+
if col < 0 or col >= self._ncols:
|
|
2264
|
+
raise IndexError("column index out of range")
|
|
2265
|
+
|
|
2266
|
+
# Construct new matrix
|
|
2267
|
+
cdef Matrix A = self.new_matrix(nrows=nrows, ncols=ncols)
|
|
2268
|
+
for i, row in enumerate(rows):
|
|
2269
|
+
if row < 0 or row >= self._nrows:
|
|
2270
|
+
raise IndexError("row index out of range")
|
|
2271
|
+
for j, col in enumerate(columns):
|
|
2272
|
+
A.set_unsafe(i, j, self.get_unsafe(row, col))
|
|
2273
|
+
return A
|
|
2274
|
+
|
|
2275
|
+
def submatrix(self, Py_ssize_t row=0, Py_ssize_t col=0,
|
|
2276
|
+
Py_ssize_t nrows=-1, Py_ssize_t ncols=-1):
|
|
2277
|
+
"""
|
|
2278
|
+
Return the matrix constructed from ``self`` using the specified
|
|
2279
|
+
range of rows and columns.
|
|
2280
|
+
|
|
2281
|
+
INPUT:
|
|
2282
|
+
|
|
2283
|
+
- ``row``, ``col`` -- index of the starting row and column (indices
|
|
2284
|
+
start at zero)
|
|
2285
|
+
|
|
2286
|
+
- ``nrows``, ``ncols`` -- (optional) number of rows and columns to
|
|
2287
|
+
take. If not provided, take all rows below and all columns to
|
|
2288
|
+
the right of the starting entry.
|
|
2289
|
+
|
|
2290
|
+
.. SEEALSO::
|
|
2291
|
+
|
|
2292
|
+
The functions :func:`matrix_from_rows`,
|
|
2293
|
+
:func:`matrix_from_columns`, and
|
|
2294
|
+
:func:`matrix_from_rows_and_columns` allow one to select
|
|
2295
|
+
arbitrary subsets of rows and/or columns.
|
|
2296
|
+
|
|
2297
|
+
EXAMPLES:
|
|
2298
|
+
|
|
2299
|
+
Take the `3 \\times 3` submatrix starting from entry (1,1) in a
|
|
2300
|
+
`4 \\times 4` matrix::
|
|
2301
|
+
|
|
2302
|
+
sage: m = matrix(4, [1..16])
|
|
2303
|
+
sage: m.submatrix(1, 1)
|
|
2304
|
+
[ 6 7 8]
|
|
2305
|
+
[10 11 12]
|
|
2306
|
+
[14 15 16]
|
|
2307
|
+
|
|
2308
|
+
Same thing, except take only two rows::
|
|
2309
|
+
|
|
2310
|
+
sage: m.submatrix(1, 1, 2)
|
|
2311
|
+
[ 6 7 8]
|
|
2312
|
+
[10 11 12]
|
|
2313
|
+
|
|
2314
|
+
And now take only one column::
|
|
2315
|
+
|
|
2316
|
+
sage: m.submatrix(1, 1, 2, 1)
|
|
2317
|
+
[ 6]
|
|
2318
|
+
[10]
|
|
2319
|
+
|
|
2320
|
+
You can take zero rows or columns if you want::
|
|
2321
|
+
|
|
2322
|
+
sage: m.submatrix(1, 1, 0)
|
|
2323
|
+
[]
|
|
2324
|
+
sage: parent(m.submatrix(1, 1, 0))
|
|
2325
|
+
Full MatrixSpace of 0 by 3 dense matrices over Integer Ring
|
|
2326
|
+
"""
|
|
2327
|
+
if nrows == -1:
|
|
2328
|
+
nrows = self._nrows - row
|
|
2329
|
+
if ncols == -1:
|
|
2330
|
+
ncols = self._ncols - col
|
|
2331
|
+
return self.matrix_from_rows_and_columns(range(row, row + nrows),
|
|
2332
|
+
range(col, col + ncols))
|
|
2333
|
+
|
|
2334
|
+
def set_row(self, row, v):
|
|
2335
|
+
r"""
|
|
2336
|
+
Set the entries of row ``row`` to the entries of ``v``.
|
|
2337
|
+
|
|
2338
|
+
INPUT:
|
|
2339
|
+
|
|
2340
|
+
- ``row`` -- index of row to be set
|
|
2341
|
+
|
|
2342
|
+
- ``v`` -- list or vector of the new entries
|
|
2343
|
+
|
|
2344
|
+
OUTPUT:
|
|
2345
|
+
|
|
2346
|
+
Changes the matrix in-place, so there is no output.
|
|
2347
|
+
|
|
2348
|
+
EXAMPLES:
|
|
2349
|
+
|
|
2350
|
+
New entries may be contained in a vector.::
|
|
2351
|
+
|
|
2352
|
+
sage: A = matrix(QQ, 5, range(25))
|
|
2353
|
+
sage: u = vector(QQ, [0, -1, -2, -3, -4])
|
|
2354
|
+
sage: A.set_row(2, u)
|
|
2355
|
+
sage: A
|
|
2356
|
+
[ 0 1 2 3 4]
|
|
2357
|
+
[ 5 6 7 8 9]
|
|
2358
|
+
[ 0 -1 -2 -3 -4]
|
|
2359
|
+
[15 16 17 18 19]
|
|
2360
|
+
[20 21 22 23 24]
|
|
2361
|
+
|
|
2362
|
+
New entries may be in any sort of list.::
|
|
2363
|
+
|
|
2364
|
+
sage: A = matrix([[1, 2], [3, 4]]); A
|
|
2365
|
+
[1 2]
|
|
2366
|
+
[3 4]
|
|
2367
|
+
sage: A.set_row(0, [0, 0]); A
|
|
2368
|
+
[0 0]
|
|
2369
|
+
[3 4]
|
|
2370
|
+
sage: A.set_row(1, (0, 0)); A
|
|
2371
|
+
[0 0]
|
|
2372
|
+
[0 0]
|
|
2373
|
+
|
|
2374
|
+
TESTS::
|
|
2375
|
+
|
|
2376
|
+
sage: A = matrix([[1, 2], [3, 4]])
|
|
2377
|
+
sage: A.set_row(2, [0, 0]); A
|
|
2378
|
+
Traceback (most recent call last):
|
|
2379
|
+
...
|
|
2380
|
+
ValueError: row number must be between 0 and 1 (inclusive), not 2
|
|
2381
|
+
|
|
2382
|
+
sage: A.set_row(0, [0, 0, 0])
|
|
2383
|
+
Traceback (most recent call last):
|
|
2384
|
+
...
|
|
2385
|
+
ValueError: list of new entries must be of length 2 (not 3)
|
|
2386
|
+
|
|
2387
|
+
sage: A = matrix(2, [1, 2, 3, 4])
|
|
2388
|
+
sage: A.set_row(0, [1/3, 1]); A
|
|
2389
|
+
Traceback (most recent call last):
|
|
2390
|
+
...
|
|
2391
|
+
TypeError: Cannot set row with Rational Field elements over Integer Ring, use change_ring first.
|
|
2392
|
+
"""
|
|
2393
|
+
if len(v) != self._ncols:
|
|
2394
|
+
msg = "list of new entries must be of length {0} (not {1})"
|
|
2395
|
+
raise ValueError(msg.format(self._ncols, len(v)))
|
|
2396
|
+
if (row < 0) or (row >= self._nrows):
|
|
2397
|
+
msg = "row number must be between 0 and {0} (inclusive), not {1}"
|
|
2398
|
+
raise ValueError(msg.format(self._nrows - 1, row))
|
|
2399
|
+
|
|
2400
|
+
try:
|
|
2401
|
+
for j in range(self._ncols):
|
|
2402
|
+
self[row, j] = v[j]
|
|
2403
|
+
except TypeError:
|
|
2404
|
+
msg = "Cannot set row with {0} elements over {1}, use change_ring first."
|
|
2405
|
+
raise TypeError(msg.format(v[j].parent(), self.base_ring()))
|
|
2406
|
+
|
|
2407
|
+
def set_column(self, col, v):
|
|
2408
|
+
r"""
|
|
2409
|
+
Set the entries of column ``col`` to the entries of ``v``.
|
|
2410
|
+
|
|
2411
|
+
INPUT:
|
|
2412
|
+
|
|
2413
|
+
- ``col`` -- index of column to be set
|
|
2414
|
+
|
|
2415
|
+
- ``v`` -- list or vector of the new entries
|
|
2416
|
+
|
|
2417
|
+
OUTPUT:
|
|
2418
|
+
|
|
2419
|
+
Changes the matrix in-place, so there is no output.
|
|
2420
|
+
|
|
2421
|
+
EXAMPLES:
|
|
2422
|
+
|
|
2423
|
+
New entries may be contained in a vector.::
|
|
2424
|
+
|
|
2425
|
+
sage: A = matrix(QQ, 5, range(25))
|
|
2426
|
+
sage: u = vector(QQ, [0, -1, -2, -3, -4])
|
|
2427
|
+
sage: A.set_column(2, u)
|
|
2428
|
+
sage: A
|
|
2429
|
+
[ 0 1 0 3 4]
|
|
2430
|
+
[ 5 6 -1 8 9]
|
|
2431
|
+
[10 11 -2 13 14]
|
|
2432
|
+
[15 16 -3 18 19]
|
|
2433
|
+
[20 21 -4 23 24]
|
|
2434
|
+
|
|
2435
|
+
New entries may be in any sort of list.::
|
|
2436
|
+
|
|
2437
|
+
sage: A = matrix([[1, 2], [3, 4]]); A
|
|
2438
|
+
[1 2]
|
|
2439
|
+
[3 4]
|
|
2440
|
+
sage: A.set_column(0, [0, 0]); A
|
|
2441
|
+
[0 2]
|
|
2442
|
+
[0 4]
|
|
2443
|
+
sage: A.set_column(1, (0, 0)); A
|
|
2444
|
+
[0 0]
|
|
2445
|
+
[0 0]
|
|
2446
|
+
|
|
2447
|
+
TESTS::
|
|
2448
|
+
|
|
2449
|
+
sage: A = matrix([[1, 2], [3, 4]])
|
|
2450
|
+
sage: A.set_column(2, [0, 0]); A
|
|
2451
|
+
Traceback (most recent call last):
|
|
2452
|
+
...
|
|
2453
|
+
ValueError: column number must be between 0 and 1 (inclusive), not 2
|
|
2454
|
+
|
|
2455
|
+
sage: A.set_column(0, [0, 0, 0])
|
|
2456
|
+
Traceback (most recent call last):
|
|
2457
|
+
...
|
|
2458
|
+
ValueError: list of new entries must be of length 2 (not 3)
|
|
2459
|
+
|
|
2460
|
+
sage: A = matrix(2, [1, 2, 3, 4])
|
|
2461
|
+
sage: A.set_column(0, [1/4, 1]); A
|
|
2462
|
+
Traceback (most recent call last):
|
|
2463
|
+
...
|
|
2464
|
+
TypeError: Cannot set column with Rational Field elements
|
|
2465
|
+
over Integer Ring, use change_ring first.
|
|
2466
|
+
"""
|
|
2467
|
+
if len(v) != self._nrows:
|
|
2468
|
+
msg = "list of new entries must be of length {0} (not {1})"
|
|
2469
|
+
raise ValueError(msg.format(self._nrows, len(v)))
|
|
2470
|
+
if (col < 0) or (col >= self._ncols):
|
|
2471
|
+
msg = "column number must be between 0 and {0} (inclusive), not {1}"
|
|
2472
|
+
raise ValueError(msg.format(self._ncols - 1, col))
|
|
2473
|
+
|
|
2474
|
+
try:
|
|
2475
|
+
for i in range(self._nrows):
|
|
2476
|
+
self[i, col] = v[i]
|
|
2477
|
+
except TypeError:
|
|
2478
|
+
msg = "Cannot set column with {0} elements over {1}, use change_ring first."
|
|
2479
|
+
raise TypeError(msg.format(v[i].parent(), self.base_ring()))
|
|
2480
|
+
|
|
2481
|
+
def zero_pattern_matrix(self, ring=None):
|
|
2482
|
+
"""
|
|
2483
|
+
Return a matrix that contains one for corresponding zero entries.
|
|
2484
|
+
|
|
2485
|
+
All other entries are zero.
|
|
2486
|
+
|
|
2487
|
+
INPUT:
|
|
2488
|
+
|
|
2489
|
+
- ``ring`` -- (optional); base ring of the output; default is ``ZZ``
|
|
2490
|
+
|
|
2491
|
+
OUTPUT:
|
|
2492
|
+
|
|
2493
|
+
A new dense matrix with same dimensions as ``self``
|
|
2494
|
+
and with base ring ``ring``.
|
|
2495
|
+
|
|
2496
|
+
EXAMPLES::
|
|
2497
|
+
|
|
2498
|
+
sage: M = Matrix(ZZ, 2, [1,2,-2,0])
|
|
2499
|
+
sage: M.zero_pattern_matrix()
|
|
2500
|
+
[0 0]
|
|
2501
|
+
[0 1]
|
|
2502
|
+
|
|
2503
|
+
sage: M = Matrix(QQ, 2, [1,2/3,-2,0])
|
|
2504
|
+
sage: M.zero_pattern_matrix()
|
|
2505
|
+
[0 0]
|
|
2506
|
+
[0 1]
|
|
2507
|
+
|
|
2508
|
+
Default base ring for the output is ``ZZ``::
|
|
2509
|
+
|
|
2510
|
+
sage: M.zero_pattern_matrix().base_ring()
|
|
2511
|
+
Integer Ring
|
|
2512
|
+
|
|
2513
|
+
Specify a different base ring for the output::
|
|
2514
|
+
|
|
2515
|
+
sage: M.zero_pattern_matrix(GF(2)).base_ring()
|
|
2516
|
+
Finite Field of size 2
|
|
2517
|
+
|
|
2518
|
+
Examples for different base rings for ``self``::
|
|
2519
|
+
|
|
2520
|
+
sage: M = Matrix(Zmod(8), 3, 2, [2, 3, 9, 8, 1, 0]); M
|
|
2521
|
+
[2 3]
|
|
2522
|
+
[1 0]
|
|
2523
|
+
[1 0]
|
|
2524
|
+
sage: M.zero_pattern_matrix()
|
|
2525
|
+
[0 0]
|
|
2526
|
+
[0 1]
|
|
2527
|
+
[0 1]
|
|
2528
|
+
|
|
2529
|
+
::
|
|
2530
|
+
|
|
2531
|
+
sage: W.<a> = CyclotomicField(100) # needs sage.rings.number_field
|
|
2532
|
+
sage: M = Matrix(2, 3, [a, a/2, 0, a^2, a^100-1, a^2 - a]); M # needs sage.rings.number_field
|
|
2533
|
+
[ a 1/2*a 0]
|
|
2534
|
+
[ a^2 0 a^2 - a]
|
|
2535
|
+
sage: M.zero_pattern_matrix() # needs sage.rings.number_field
|
|
2536
|
+
[0 0 1]
|
|
2537
|
+
[0 1 0]
|
|
2538
|
+
|
|
2539
|
+
::
|
|
2540
|
+
|
|
2541
|
+
sage: # needs sage.rings.finite_rings
|
|
2542
|
+
sage: K.<a> = GF(2^4)
|
|
2543
|
+
sage: l = [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1,
|
|
2544
|
+
....: a + 1, a^2, a^3 + a + 1, a^3 + a, a^3 + a]
|
|
2545
|
+
sage: M = Matrix(K, 3, 4, l); M
|
|
2546
|
+
[ a^2 + 1 a^3 + 1 0 0]
|
|
2547
|
+
[ a a^3 + a + 1 a + 1 a + 1]
|
|
2548
|
+
[ a^2 a^3 + a + 1 a^3 + a a^3 + a]
|
|
2549
|
+
sage: M.zero_pattern_matrix()
|
|
2550
|
+
[0 0 1 1]
|
|
2551
|
+
[0 0 0 0]
|
|
2552
|
+
[0 0 0 0]
|
|
2553
|
+
|
|
2554
|
+
::
|
|
2555
|
+
|
|
2556
|
+
sage: # needs sage.rings.finite_rings
|
|
2557
|
+
sage: K.<a> = GF(25)
|
|
2558
|
+
sage: M = Matrix(K, 2, 3, [0, 2, 3, 5, a, a^2])
|
|
2559
|
+
sage: M
|
|
2560
|
+
[ 0 2 3]
|
|
2561
|
+
[ 0 a a + 3]
|
|
2562
|
+
sage: M.zero_pattern_matrix()
|
|
2563
|
+
[1 0 0]
|
|
2564
|
+
[1 0 0]
|
|
2565
|
+
|
|
2566
|
+
.. NOTE::
|
|
2567
|
+
|
|
2568
|
+
This method can be optimized by improving
|
|
2569
|
+
:meth:`get_is_zero_unsafe` for derived matrix classes.
|
|
2570
|
+
"""
|
|
2571
|
+
if ring is None:
|
|
2572
|
+
from sage.rings.integer_ring import ZZ
|
|
2573
|
+
ring = ZZ
|
|
2574
|
+
|
|
2575
|
+
cdef object one = ring.one()
|
|
2576
|
+
cdef Py_ssize_t i, j
|
|
2577
|
+
|
|
2578
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
2579
|
+
MZ = MatrixSpace(ring, self._nrows, self._ncols, sparse=False)
|
|
2580
|
+
cdef Matrix M = MZ(ring.zero())
|
|
2581
|
+
|
|
2582
|
+
for i from 0 <= i < self._nrows:
|
|
2583
|
+
for j from 0 <= j < self._ncols:
|
|
2584
|
+
if self.get_is_zero_unsafe(i, j):
|
|
2585
|
+
M.set_unsafe(i, j, one)
|
|
2586
|
+
return M
|
|
2587
|
+
|
|
2588
|
+
######################################################################
|
|
2589
|
+
# Change of representation between dense and sparse.
|
|
2590
|
+
######################################################################
|
|
2591
|
+
|
|
2592
|
+
def dense_matrix(self):
|
|
2593
|
+
"""
|
|
2594
|
+
If this matrix is sparse, return a dense matrix with the same
|
|
2595
|
+
entries. If this matrix is dense, return this matrix (not a copy).
|
|
2596
|
+
|
|
2597
|
+
.. NOTE::
|
|
2598
|
+
|
|
2599
|
+
The definition of "dense" and "sparse" in Sage have nothing to
|
|
2600
|
+
do with the number of nonzero entries. Sparse and dense are
|
|
2601
|
+
properties of the underlying representation of the matrix.
|
|
2602
|
+
|
|
2603
|
+
EXAMPLES::
|
|
2604
|
+
|
|
2605
|
+
sage: A = MatrixSpace(QQ,2, sparse=True)([1,2,0,1])
|
|
2606
|
+
sage: A.is_sparse()
|
|
2607
|
+
True
|
|
2608
|
+
sage: B = A.dense_matrix()
|
|
2609
|
+
sage: B.is_sparse()
|
|
2610
|
+
False
|
|
2611
|
+
sage: A == B
|
|
2612
|
+
True
|
|
2613
|
+
sage: B.dense_matrix() is B
|
|
2614
|
+
True
|
|
2615
|
+
sage: A*B
|
|
2616
|
+
[1 4]
|
|
2617
|
+
[0 1]
|
|
2618
|
+
sage: A.parent()
|
|
2619
|
+
Full MatrixSpace of 2 by 2 sparse matrices over Rational Field
|
|
2620
|
+
sage: B.parent()
|
|
2621
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
2622
|
+
|
|
2623
|
+
In Sage, the product of a sparse and a dense matrix is always
|
|
2624
|
+
dense::
|
|
2625
|
+
|
|
2626
|
+
sage: (A*B).parent()
|
|
2627
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
2628
|
+
sage: (B*A).parent()
|
|
2629
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
2630
|
+
|
|
2631
|
+
TESTS:
|
|
2632
|
+
|
|
2633
|
+
Make sure that subdivisions are preserved when switching
|
|
2634
|
+
between dense and sparse matrices::
|
|
2635
|
+
|
|
2636
|
+
sage: a = matrix(ZZ, 3, range(9))
|
|
2637
|
+
sage: a.subdivide([1,2],2)
|
|
2638
|
+
sage: a.subdivisions()
|
|
2639
|
+
([1, 2], [2])
|
|
2640
|
+
sage: b = a.sparse_matrix().dense_matrix()
|
|
2641
|
+
sage: b.subdivisions()
|
|
2642
|
+
([1, 2], [2])
|
|
2643
|
+
|
|
2644
|
+
Ensure we can compute the correct dense matrix even if the
|
|
2645
|
+
dict items are ETuples (see :issue:`17658`)::
|
|
2646
|
+
|
|
2647
|
+
sage: from sage.rings.polynomial.polydict import ETuple
|
|
2648
|
+
sage: matrix(GF(5^2, "z"), {ETuple((1, 1)): 2}).dense_matrix() # needs sage.rings.finite_rings
|
|
2649
|
+
[0 0]
|
|
2650
|
+
[0 2]
|
|
2651
|
+
"""
|
|
2652
|
+
if self.is_dense():
|
|
2653
|
+
return self
|
|
2654
|
+
cdef Matrix A
|
|
2655
|
+
A = self.new_matrix(self._nrows, self._ncols, self,
|
|
2656
|
+
coerce=False, sparse=False)
|
|
2657
|
+
if self._subdivisions is not None:
|
|
2658
|
+
A.subdivide(self.subdivisions())
|
|
2659
|
+
return A
|
|
2660
|
+
|
|
2661
|
+
def sparse_matrix(self):
|
|
2662
|
+
"""
|
|
2663
|
+
If this matrix is dense, return a sparse matrix with the same
|
|
2664
|
+
entries. If this matrix is sparse, return this matrix (not a
|
|
2665
|
+
copy).
|
|
2666
|
+
|
|
2667
|
+
.. NOTE::
|
|
2668
|
+
|
|
2669
|
+
The definition of "dense" and "sparse" in Sage have nothing
|
|
2670
|
+
to do with the number of nonzero entries. Sparse and dense are
|
|
2671
|
+
properties of the underlying representation of the matrix.
|
|
2672
|
+
|
|
2673
|
+
EXAMPLES::
|
|
2674
|
+
|
|
2675
|
+
sage: A = MatrixSpace(QQ,2, sparse=False)([1,2,0,1])
|
|
2676
|
+
sage: A.is_sparse()
|
|
2677
|
+
False
|
|
2678
|
+
sage: B = A.sparse_matrix()
|
|
2679
|
+
sage: B.is_sparse()
|
|
2680
|
+
True
|
|
2681
|
+
sage: A == B
|
|
2682
|
+
True
|
|
2683
|
+
sage: B.sparse_matrix() is B
|
|
2684
|
+
True
|
|
2685
|
+
sage: A*B
|
|
2686
|
+
[1 4]
|
|
2687
|
+
[0 1]
|
|
2688
|
+
sage: A.parent()
|
|
2689
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
2690
|
+
sage: B.parent()
|
|
2691
|
+
Full MatrixSpace of 2 by 2 sparse matrices over Rational Field
|
|
2692
|
+
sage: (A*B).parent()
|
|
2693
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
2694
|
+
sage: (B*A).parent()
|
|
2695
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
2696
|
+
"""
|
|
2697
|
+
if self.is_sparse():
|
|
2698
|
+
return self
|
|
2699
|
+
A = self.new_matrix(self._nrows, self._ncols, self,
|
|
2700
|
+
coerce=False, sparse=True)
|
|
2701
|
+
if self._subdivisions is not None:
|
|
2702
|
+
A.subdivide(self.subdivisions())
|
|
2703
|
+
return A
|
|
2704
|
+
|
|
2705
|
+
def matrix_space(self, nrows=None, ncols=None, sparse=None):
|
|
2706
|
+
"""
|
|
2707
|
+
Return the ambient matrix space of ``self``.
|
|
2708
|
+
|
|
2709
|
+
INPUT:
|
|
2710
|
+
|
|
2711
|
+
- ``nrows``, ``ncols`` -- (optional) number of rows and columns in
|
|
2712
|
+
returned matrix space
|
|
2713
|
+
|
|
2714
|
+
- ``sparse`` -- whether the returned matrix space uses sparse or
|
|
2715
|
+
dense matrices
|
|
2716
|
+
|
|
2717
|
+
EXAMPLES::
|
|
2718
|
+
|
|
2719
|
+
sage: m = matrix(3, [1..9])
|
|
2720
|
+
sage: m.matrix_space()
|
|
2721
|
+
Full MatrixSpace of 3 by 3 dense matrices over Integer Ring
|
|
2722
|
+
sage: m.matrix_space(ncols=2)
|
|
2723
|
+
Full MatrixSpace of 3 by 2 dense matrices over Integer Ring
|
|
2724
|
+
sage: m.matrix_space(1)
|
|
2725
|
+
Full MatrixSpace of 1 by 3 dense matrices over Integer Ring
|
|
2726
|
+
sage: m.matrix_space(1, 2, True)
|
|
2727
|
+
Full MatrixSpace of 1 by 2 sparse matrices over Integer Ring
|
|
2728
|
+
|
|
2729
|
+
sage: M = MatrixSpace(QQ, 3, implementation='generic')
|
|
2730
|
+
sage: m = M.an_element()
|
|
2731
|
+
sage: m.matrix_space() # needs sage.libs.flint
|
|
2732
|
+
Full MatrixSpace of 3 by 3 dense matrices over Rational Field
|
|
2733
|
+
(using Matrix_generic_dense)
|
|
2734
|
+
sage: m.matrix_space(nrows=2, ncols=12) # needs sage.libs.flint
|
|
2735
|
+
Full MatrixSpace of 2 by 12 dense matrices over Rational Field
|
|
2736
|
+
(using Matrix_generic_dense)
|
|
2737
|
+
sage: m.matrix_space(nrows=2, sparse=True)
|
|
2738
|
+
Full MatrixSpace of 2 by 3 sparse matrices over Rational Field
|
|
2739
|
+
"""
|
|
2740
|
+
if nrows is None:
|
|
2741
|
+
nrows = self._nrows
|
|
2742
|
+
if ncols is None:
|
|
2743
|
+
ncols = self._ncols
|
|
2744
|
+
if sparse is None:
|
|
2745
|
+
sparse = self.is_sparse()
|
|
2746
|
+
|
|
2747
|
+
base_ring = self._base_ring
|
|
2748
|
+
|
|
2749
|
+
if nrows == self._nrows and ncols == self._ncols and sparse == self.is_sparse():
|
|
2750
|
+
return self._parent
|
|
2751
|
+
else:
|
|
2752
|
+
if sparse == self.is_sparse():
|
|
2753
|
+
implementation = self.__class__
|
|
2754
|
+
else:
|
|
2755
|
+
implementation = None
|
|
2756
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
2757
|
+
return MatrixSpace(base_ring, nrows, ncols, sparse, implementation)
|
|
2758
|
+
|
|
2759
|
+
def new_matrix(self, nrows=None, ncols=None, entries=None,
|
|
2760
|
+
coerce=True, copy=True, sparse=None):
|
|
2761
|
+
"""
|
|
2762
|
+
Create a matrix in the parent of this matrix with the given number
|
|
2763
|
+
of rows, columns, etc. The default parameters are the same as for
|
|
2764
|
+
``self``.
|
|
2765
|
+
|
|
2766
|
+
INPUT:
|
|
2767
|
+
|
|
2768
|
+
These three variables get sent to :func:`matrix_space`:
|
|
2769
|
+
|
|
2770
|
+
- ``nrows``, ``ncols`` -- number of rows and columns in returned
|
|
2771
|
+
matrix. If not specified, defaults to ``None`` and will give a
|
|
2772
|
+
matrix of the same size as ``self``.
|
|
2773
|
+
- ``sparse`` -- whether returned matrix is sparse or not. Defaults
|
|
2774
|
+
to same value as self
|
|
2775
|
+
|
|
2776
|
+
The remaining three variables (``coerce``, ``entries``, and
|
|
2777
|
+
``copy``) are used by
|
|
2778
|
+
:func:`sage.matrix.matrix_space.MatrixSpace` to construct the
|
|
2779
|
+
new matrix.
|
|
2780
|
+
|
|
2781
|
+
.. warning::
|
|
2782
|
+
|
|
2783
|
+
This function called with no arguments returns the zero
|
|
2784
|
+
matrix of the same dimension and sparseness of ``self``.
|
|
2785
|
+
|
|
2786
|
+
EXAMPLES::
|
|
2787
|
+
|
|
2788
|
+
sage: A = matrix(ZZ,2,2,[1,2,3,4]); A
|
|
2789
|
+
[1 2]
|
|
2790
|
+
[3 4]
|
|
2791
|
+
sage: A.new_matrix()
|
|
2792
|
+
[0 0]
|
|
2793
|
+
[0 0]
|
|
2794
|
+
sage: A.new_matrix(1,1)
|
|
2795
|
+
[0]
|
|
2796
|
+
sage: A.new_matrix(3,3).parent()
|
|
2797
|
+
Full MatrixSpace of 3 by 3 dense matrices over Integer Ring
|
|
2798
|
+
|
|
2799
|
+
::
|
|
2800
|
+
|
|
2801
|
+
sage: A = matrix(RR,2,3,[1.1,2.2,3.3,4.4,5.5,6.6]); A
|
|
2802
|
+
[1.10000000000000 2.20000000000000 3.30000000000000]
|
|
2803
|
+
[4.40000000000000 5.50000000000000 6.60000000000000]
|
|
2804
|
+
sage: A.new_matrix()
|
|
2805
|
+
[0.000000000000000 0.000000000000000 0.000000000000000]
|
|
2806
|
+
[0.000000000000000 0.000000000000000 0.000000000000000]
|
|
2807
|
+
sage: A.new_matrix().parent()
|
|
2808
|
+
Full MatrixSpace of 2 by 3 dense matrices
|
|
2809
|
+
over Real Field with 53 bits of precision
|
|
2810
|
+
|
|
2811
|
+
::
|
|
2812
|
+
|
|
2813
|
+
sage: M = MatrixSpace(ZZ, 2, 3, implementation='generic')
|
|
2814
|
+
sage: m = M.an_element()
|
|
2815
|
+
sage: m.new_matrix().parent() # needs sage.libs.flint
|
|
2816
|
+
Full MatrixSpace of 2 by 3 dense matrices over Integer Ring
|
|
2817
|
+
(using Matrix_generic_dense)
|
|
2818
|
+
sage: m.new_matrix(3,3).parent() # needs sage.libs.flint
|
|
2819
|
+
Full MatrixSpace of 3 by 3 dense matrices over Integer Ring
|
|
2820
|
+
(using Matrix_generic_dense)
|
|
2821
|
+
sage: m.new_matrix(3,3, sparse=True).parent()
|
|
2822
|
+
Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring
|
|
2823
|
+
"""
|
|
2824
|
+
if (sparse is None or self.is_sparse() == sparse):
|
|
2825
|
+
if self._nrows == nrows and self._ncols == ncols:
|
|
2826
|
+
return self._parent(entries, coerce=coerce, copy=copy)
|
|
2827
|
+
elif self._nrows == ncols and self._ncols == nrows:
|
|
2828
|
+
return self._parent.transposed(entries, coerce=coerce, copy=copy)
|
|
2829
|
+
return self.matrix_space(nrows, ncols, sparse)(entries, coerce=coerce, copy=copy)
|
|
2830
|
+
|
|
2831
|
+
def block_sum(self, Matrix other):
|
|
2832
|
+
"""
|
|
2833
|
+
Return the block matrix that has ``self`` and ``other`` on the diagonal::
|
|
2834
|
+
|
|
2835
|
+
[ self 0 ]
|
|
2836
|
+
[ 0 other ]
|
|
2837
|
+
|
|
2838
|
+
EXAMPLES::
|
|
2839
|
+
|
|
2840
|
+
sage: A = matrix(QQ[['t']], 2, range(1, 5))
|
|
2841
|
+
sage: A.block_sum(100*A)
|
|
2842
|
+
[ 1 2 0 0]
|
|
2843
|
+
[ 3 4 0 0]
|
|
2844
|
+
[ 0 0 100 200]
|
|
2845
|
+
[ 0 0 300 400]
|
|
2846
|
+
"""
|
|
2847
|
+
if not isinstance(other, Matrix):
|
|
2848
|
+
raise TypeError("other must be a Matrix")
|
|
2849
|
+
top = self.augment(self.new_matrix(ncols=other._ncols))
|
|
2850
|
+
bottom = other.new_matrix(ncols=self._ncols).augment(other)
|
|
2851
|
+
return top.stack(bottom)
|